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 11aa43c215SJeff Kirsher #include "qlcnic.h" 1202feda17SRajesh Borundia #include "qlcnic_sriov.h" 13a15ebd37SHimanshu Madhani #include "qlcnic_hw.h" 14aa43c215SJeff Kirsher 15aa43c215SJeff Kirsher #include <linux/swab.h> 16aa43c215SJeff Kirsher #include <linux/dma-mapping.h> 1713159183SSony Chacko #include <linux/if_vlan.h> 18aa43c215SJeff Kirsher #include <net/ip.h> 19aa43c215SJeff Kirsher #include <linux/ipv6.h> 20aa43c215SJeff Kirsher #include <linux/inetdevice.h> 21aa43c215SJeff Kirsher #include <linux/aer.h> 22aa43c215SJeff Kirsher #include <linux/log2.h> 2347caf255SStephen Rothwell #include <linux/pci.h> 24aa43c215SJeff Kirsher 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; 529fd13331SHimanshu Madhani MODULE_PARM_DESC(load_fw_file, "Load firmware from (0=flash, 1=file)"); 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 8413159183SSony Chacko static u32 qlcnic_vlan_tx_check(struct qlcnic_adapter *adapter) 8513159183SSony Chacko { 8613159183SSony Chacko struct qlcnic_hardware_context *ahw = adapter->ahw; 8713159183SSony Chacko 8813159183SSony Chacko if (adapter->pdev->device == PCI_DEVICE_ID_QLOGIC_QLE824X) 8913159183SSony Chacko return ahw->capabilities & QLCNIC_FW_CAPABILITY_FVLANTX; 9013159183SSony Chacko else 9113159183SSony Chacko return 1; 9213159183SSony Chacko } 9313159183SSony Chacko 94aa43c215SJeff Kirsher /* PCI Device ID Table */ 95aa43c215SJeff Kirsher #define ENTRY(device) \ 96aa43c215SJeff Kirsher {PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, (device)), \ 97aa43c215SJeff Kirsher .class = PCI_CLASS_NETWORK_ETHERNET << 8, .class_mask = ~0} 98aa43c215SJeff Kirsher 99aa43c215SJeff Kirsher static DEFINE_PCI_DEVICE_TABLE(qlcnic_pci_tbl) = { 100aa43c215SJeff Kirsher ENTRY(PCI_DEVICE_ID_QLOGIC_QLE824X), 10113159183SSony Chacko ENTRY(PCI_DEVICE_ID_QLOGIC_QLE834X), 102f8468331SRajesh Borundia ENTRY(PCI_DEVICE_ID_QLOGIC_VF_QLE834X), 10315ca140fSManish Chopra ENTRY(PCI_DEVICE_ID_QLOGIC_QLE844X), 10415ca140fSManish Chopra ENTRY(PCI_DEVICE_ID_QLOGIC_VF_QLE844X), 105aa43c215SJeff Kirsher {0,} 106aa43c215SJeff Kirsher }; 107aa43c215SJeff Kirsher 108aa43c215SJeff Kirsher MODULE_DEVICE_TABLE(pci, qlcnic_pci_tbl); 109aa43c215SJeff Kirsher 110aa43c215SJeff Kirsher 1115ad6ff9dSSony Chacko inline void qlcnic_update_cmd_producer(struct qlcnic_host_tx_ring *tx_ring) 112aa43c215SJeff Kirsher { 113aa43c215SJeff Kirsher writel(tx_ring->producer, tx_ring->crb_cmd_producer); 114aa43c215SJeff Kirsher } 115aa43c215SJeff Kirsher 116aa43c215SJeff Kirsher static const u32 msi_tgt_status[8] = { 117aa43c215SJeff Kirsher ISR_INT_TARGET_STATUS, ISR_INT_TARGET_STATUS_F1, 118aa43c215SJeff Kirsher ISR_INT_TARGET_STATUS_F2, ISR_INT_TARGET_STATUS_F3, 119aa43c215SJeff Kirsher ISR_INT_TARGET_STATUS_F4, ISR_INT_TARGET_STATUS_F5, 120aa43c215SJeff Kirsher ISR_INT_TARGET_STATUS_F6, ISR_INT_TARGET_STATUS_F7 121aa43c215SJeff Kirsher }; 122aa43c215SJeff Kirsher 1237e2cf4feSSony Chacko static const u32 qlcnic_reg_tbl[] = { 1247e2cf4feSSony Chacko 0x1B20A8, /* PEG_HALT_STAT1 */ 1257e2cf4feSSony Chacko 0x1B20AC, /* PEG_HALT_STAT2 */ 1267e2cf4feSSony Chacko 0x1B20B0, /* FW_HEARTBEAT */ 1277e2cf4feSSony Chacko 0x1B2100, /* LOCK ID */ 1287e2cf4feSSony Chacko 0x1B2128, /* FW_CAPABILITIES */ 1297e2cf4feSSony Chacko 0x1B2138, /* drv active */ 1307e2cf4feSSony Chacko 0x1B2140, /* dev state */ 1317e2cf4feSSony Chacko 0x1B2144, /* drv state */ 1327e2cf4feSSony Chacko 0x1B2148, /* drv scratch */ 1337e2cf4feSSony Chacko 0x1B214C, /* dev partition info */ 1347e2cf4feSSony Chacko 0x1B2174, /* drv idc ver */ 1357e2cf4feSSony Chacko 0x1B2150, /* fw version major */ 1367e2cf4feSSony Chacko 0x1B2154, /* fw version minor */ 1377e2cf4feSSony Chacko 0x1B2158, /* fw version sub */ 1387e2cf4feSSony Chacko 0x1B219C, /* npar state */ 1397e2cf4feSSony Chacko 0x1B21FC, /* FW_IMG_VALID */ 1407e2cf4feSSony Chacko 0x1B2250, /* CMD_PEG_STATE */ 1417e2cf4feSSony Chacko 0x1B233C, /* RCV_PEG_STATE */ 1427e2cf4feSSony Chacko 0x1B23B4, /* ASIC TEMP */ 1437e2cf4feSSony Chacko 0x1B216C, /* FW api */ 1447e2cf4feSSony Chacko 0x1B2170, /* drv op mode */ 1457e2cf4feSSony Chacko 0x13C010, /* flash lock */ 1467e2cf4feSSony Chacko 0x13C014, /* flash unlock */ 1477e2cf4feSSony Chacko }; 1487e2cf4feSSony Chacko 14922999798SSony Chacko static const struct qlcnic_board_info qlcnic_boards[] = { 150e386cd4aSHimanshu Madhani { PCI_VENDOR_ID_QLOGIC, 15115ca140fSManish Chopra PCI_DEVICE_ID_QLOGIC_QLE844X, 15215ca140fSManish Chopra 0x0, 15315ca140fSManish Chopra 0x0, 15415ca140fSManish Chopra "8400 series 10GbE Converged Network Adapter (TCP/IP Networking)" }, 15515ca140fSManish Chopra { PCI_VENDOR_ID_QLOGIC, 156e386cd4aSHimanshu Madhani PCI_DEVICE_ID_QLOGIC_QLE834X, 157e386cd4aSHimanshu Madhani PCI_VENDOR_ID_QLOGIC, 158e386cd4aSHimanshu Madhani 0x24e, 159e386cd4aSHimanshu Madhani "8300 Series Dual Port 10GbE Converged Network Adapter " 160e386cd4aSHimanshu Madhani "(TCP/IP Networking)" }, 161e386cd4aSHimanshu Madhani { PCI_VENDOR_ID_QLOGIC, 162e386cd4aSHimanshu Madhani PCI_DEVICE_ID_QLOGIC_QLE834X, 163e386cd4aSHimanshu Madhani PCI_VENDOR_ID_QLOGIC, 164e386cd4aSHimanshu Madhani 0x243, 165e386cd4aSHimanshu Madhani "8300 Series Single Port 10GbE Converged Network Adapter " 166e386cd4aSHimanshu Madhani "(TCP/IP Networking)" }, 167e386cd4aSHimanshu Madhani { PCI_VENDOR_ID_QLOGIC, 168e386cd4aSHimanshu Madhani PCI_DEVICE_ID_QLOGIC_QLE834X, 169e386cd4aSHimanshu Madhani PCI_VENDOR_ID_QLOGIC, 170e386cd4aSHimanshu Madhani 0x24a, 171e386cd4aSHimanshu Madhani "8300 Series Dual Port 10GbE Converged Network Adapter " 172e386cd4aSHimanshu Madhani "(TCP/IP Networking)" }, 173e386cd4aSHimanshu Madhani { PCI_VENDOR_ID_QLOGIC, 174e386cd4aSHimanshu Madhani PCI_DEVICE_ID_QLOGIC_QLE834X, 175e386cd4aSHimanshu Madhani PCI_VENDOR_ID_QLOGIC, 176e386cd4aSHimanshu Madhani 0x246, 177e386cd4aSHimanshu Madhani "8300 Series Dual Port 10GbE Converged Network Adapter " 178e386cd4aSHimanshu Madhani "(TCP/IP Networking)" }, 179e386cd4aSHimanshu Madhani { PCI_VENDOR_ID_QLOGIC, 180e386cd4aSHimanshu Madhani PCI_DEVICE_ID_QLOGIC_QLE834X, 181e386cd4aSHimanshu Madhani PCI_VENDOR_ID_QLOGIC, 182e386cd4aSHimanshu Madhani 0x252, 183e386cd4aSHimanshu Madhani "8300 Series Dual Port 10GbE Converged Network Adapter " 184e386cd4aSHimanshu Madhani "(TCP/IP Networking)" }, 185e386cd4aSHimanshu Madhani { PCI_VENDOR_ID_QLOGIC, 186e386cd4aSHimanshu Madhani PCI_DEVICE_ID_QLOGIC_QLE834X, 187e386cd4aSHimanshu Madhani PCI_VENDOR_ID_QLOGIC, 188e386cd4aSHimanshu Madhani 0x26e, 189e386cd4aSHimanshu Madhani "8300 Series Dual Port 10GbE Converged Network Adapter " 190e386cd4aSHimanshu Madhani "(TCP/IP Networking)" }, 191e386cd4aSHimanshu Madhani { PCI_VENDOR_ID_QLOGIC, 192e386cd4aSHimanshu Madhani PCI_DEVICE_ID_QLOGIC_QLE834X, 193e386cd4aSHimanshu Madhani PCI_VENDOR_ID_QLOGIC, 194e386cd4aSHimanshu Madhani 0x260, 195e386cd4aSHimanshu Madhani "8300 Series Dual Port 10GbE Converged Network Adapter " 196e386cd4aSHimanshu Madhani "(TCP/IP Networking)" }, 197e386cd4aSHimanshu Madhani { PCI_VENDOR_ID_QLOGIC, 198e386cd4aSHimanshu Madhani PCI_DEVICE_ID_QLOGIC_QLE834X, 199e386cd4aSHimanshu Madhani PCI_VENDOR_ID_QLOGIC, 200e386cd4aSHimanshu Madhani 0x266, 201e386cd4aSHimanshu Madhani "8300 Series Single Port 10GbE Converged Network Adapter " 202e386cd4aSHimanshu Madhani "(TCP/IP Networking)" }, 203e386cd4aSHimanshu Madhani { PCI_VENDOR_ID_QLOGIC, 204e386cd4aSHimanshu Madhani PCI_DEVICE_ID_QLOGIC_QLE834X, 205e386cd4aSHimanshu Madhani PCI_VENDOR_ID_QLOGIC, 206e386cd4aSHimanshu Madhani 0x269, 207e386cd4aSHimanshu Madhani "8300 Series Dual Port 10GbE Converged Network Adapter " 208e386cd4aSHimanshu Madhani "(TCP/IP Networking)" }, 209e386cd4aSHimanshu Madhani { PCI_VENDOR_ID_QLOGIC, 210e386cd4aSHimanshu Madhani PCI_DEVICE_ID_QLOGIC_QLE834X, 211e386cd4aSHimanshu Madhani PCI_VENDOR_ID_QLOGIC, 212e386cd4aSHimanshu Madhani 0x271, 213e386cd4aSHimanshu Madhani "8300 Series Dual Port 10GbE Converged Network Adapter " 214e386cd4aSHimanshu Madhani "(TCP/IP Networking)" }, 215e386cd4aSHimanshu Madhani { PCI_VENDOR_ID_QLOGIC, 216e386cd4aSHimanshu Madhani PCI_DEVICE_ID_QLOGIC_QLE834X, 217e386cd4aSHimanshu Madhani 0x0, 0x0, "8300 Series 1/10GbE Controller" }, 218e386cd4aSHimanshu Madhani { PCI_VENDOR_ID_QLOGIC, 219e386cd4aSHimanshu Madhani PCI_DEVICE_ID_QLOGIC_QLE824X, 220e386cd4aSHimanshu Madhani PCI_VENDOR_ID_QLOGIC, 221e386cd4aSHimanshu Madhani 0x203, 22222999798SSony Chacko "8200 Series Single Port 10GbE Converged Network Adapter" 22322999798SSony Chacko "(TCP/IP Networking)" }, 224e386cd4aSHimanshu Madhani { PCI_VENDOR_ID_QLOGIC, 225e386cd4aSHimanshu Madhani PCI_DEVICE_ID_QLOGIC_QLE824X, 226e386cd4aSHimanshu Madhani PCI_VENDOR_ID_QLOGIC, 227e386cd4aSHimanshu Madhani 0x207, 22822999798SSony Chacko "8200 Series Dual Port 10GbE Converged Network Adapter" 22922999798SSony Chacko "(TCP/IP Networking)" }, 230e386cd4aSHimanshu Madhani { PCI_VENDOR_ID_QLOGIC, 231e386cd4aSHimanshu Madhani PCI_DEVICE_ID_QLOGIC_QLE824X, 232e386cd4aSHimanshu Madhani PCI_VENDOR_ID_QLOGIC, 233e386cd4aSHimanshu Madhani 0x20b, 23422999798SSony Chacko "3200 Series Dual Port 10Gb Intelligent Ethernet Adapter" }, 235e386cd4aSHimanshu Madhani { PCI_VENDOR_ID_QLOGIC, 236e386cd4aSHimanshu Madhani PCI_DEVICE_ID_QLOGIC_QLE824X, 237e386cd4aSHimanshu Madhani PCI_VENDOR_ID_QLOGIC, 238e386cd4aSHimanshu Madhani 0x20c, 23922999798SSony Chacko "3200 Series Quad Port 1Gb Intelligent Ethernet Adapter" }, 240e386cd4aSHimanshu Madhani { PCI_VENDOR_ID_QLOGIC, 241e386cd4aSHimanshu Madhani PCI_DEVICE_ID_QLOGIC_QLE824X, 242e386cd4aSHimanshu Madhani PCI_VENDOR_ID_QLOGIC, 243e386cd4aSHimanshu Madhani 0x20f, 24422999798SSony Chacko "3200 Series Single Port 10Gb Intelligent Ethernet Adapter" }, 245e386cd4aSHimanshu Madhani { PCI_VENDOR_ID_QLOGIC, 246e386cd4aSHimanshu Madhani PCI_DEVICE_ID_QLOGIC_QLE824X, 247e386cd4aSHimanshu Madhani 0x103c, 0x3733, 24822999798SSony Chacko "NC523SFP 10Gb 2-port Server Adapter" }, 249e386cd4aSHimanshu Madhani { PCI_VENDOR_ID_QLOGIC, 250e386cd4aSHimanshu Madhani PCI_DEVICE_ID_QLOGIC_QLE824X, 251e386cd4aSHimanshu Madhani 0x103c, 0x3346, 25222999798SSony Chacko "CN1000Q Dual Port Converged Network Adapter" }, 253e386cd4aSHimanshu Madhani { PCI_VENDOR_ID_QLOGIC, 254e386cd4aSHimanshu Madhani PCI_DEVICE_ID_QLOGIC_QLE824X, 255e386cd4aSHimanshu Madhani PCI_VENDOR_ID_QLOGIC, 256e386cd4aSHimanshu Madhani 0x210, 25722999798SSony Chacko "QME8242-k 10GbE Dual Port Mezzanine Card" }, 258e386cd4aSHimanshu Madhani { PCI_VENDOR_ID_QLOGIC, 259e386cd4aSHimanshu Madhani PCI_DEVICE_ID_QLOGIC_QLE824X, 260e386cd4aSHimanshu Madhani 0x0, 0x0, "cLOM8214 1/10GbE Controller" }, 26122999798SSony Chacko }; 26222999798SSony Chacko 26322999798SSony Chacko #define NUM_SUPPORTED_BOARDS ARRAY_SIZE(qlcnic_boards) 26422999798SSony Chacko 265aa43c215SJeff Kirsher static const 266aa43c215SJeff Kirsher struct qlcnic_legacy_intr_set legacy_intr[] = QLCNIC_LEGACY_INTR_CONFIG; 267aa43c215SJeff Kirsher 268c70001a9SSony Chacko int qlcnic_alloc_sds_rings(struct qlcnic_recv_context *recv_ctx, int count) 269aa43c215SJeff Kirsher { 270aa43c215SJeff Kirsher int size = sizeof(struct qlcnic_host_sds_ring) * count; 271aa43c215SJeff Kirsher 272aa43c215SJeff Kirsher recv_ctx->sds_rings = kzalloc(size, GFP_KERNEL); 273aa43c215SJeff Kirsher 274aa43c215SJeff Kirsher return recv_ctx->sds_rings == NULL; 275aa43c215SJeff Kirsher } 276aa43c215SJeff Kirsher 277c70001a9SSony Chacko void qlcnic_free_sds_rings(struct qlcnic_recv_context *recv_ctx) 278aa43c215SJeff Kirsher { 279aa43c215SJeff Kirsher if (recv_ctx->sds_rings != NULL) 280aa43c215SJeff Kirsher kfree(recv_ctx->sds_rings); 281aa43c215SJeff Kirsher 282aa43c215SJeff Kirsher recv_ctx->sds_rings = NULL; 283aa43c215SJeff Kirsher } 284aa43c215SJeff Kirsher 285f8468331SRajesh Borundia int qlcnic_read_mac_addr(struct qlcnic_adapter *adapter) 286aa43c215SJeff Kirsher { 287aa43c215SJeff Kirsher struct net_device *netdev = adapter->netdev; 288aa43c215SJeff Kirsher struct pci_dev *pdev = adapter->pdev; 28907a251c8SShahed Shaikh u8 mac_addr[ETH_ALEN]; 29007a251c8SShahed Shaikh int ret; 291aa43c215SJeff Kirsher 29207a251c8SShahed Shaikh ret = qlcnic_get_mac_address(adapter, mac_addr, 29307a251c8SShahed Shaikh adapter->ahw->pci_func); 29407a251c8SShahed Shaikh if (ret) 29507a251c8SShahed Shaikh return ret; 296aa43c215SJeff Kirsher 297aa43c215SJeff Kirsher memcpy(netdev->dev_addr, mac_addr, ETH_ALEN); 298aa43c215SJeff Kirsher memcpy(adapter->mac_addr, netdev->dev_addr, netdev->addr_len); 299aa43c215SJeff Kirsher 300aa43c215SJeff Kirsher /* set station address */ 301aa43c215SJeff Kirsher 302aaeb6cdfSJiri Pirko if (!is_valid_ether_addr(netdev->dev_addr)) 303aa43c215SJeff Kirsher dev_warn(&pdev->dev, "Bad MAC address %pM.\n", 304aa43c215SJeff Kirsher netdev->dev_addr); 305aa43c215SJeff Kirsher 306aa43c215SJeff Kirsher return 0; 307aa43c215SJeff Kirsher } 308aa43c215SJeff Kirsher 309cffe52f3SManish Chopra static void qlcnic_delete_adapter_mac(struct qlcnic_adapter *adapter) 310cffe52f3SManish Chopra { 311cffe52f3SManish Chopra struct qlcnic_mac_list_s *cur; 312cffe52f3SManish Chopra struct list_head *head; 313cffe52f3SManish Chopra 314cffe52f3SManish Chopra list_for_each(head, &adapter->mac_list) { 315cffe52f3SManish Chopra cur = list_entry(head, struct qlcnic_mac_list_s, list); 316cffe52f3SManish Chopra if (!memcmp(adapter->mac_addr, cur->mac_addr, ETH_ALEN)) { 317cffe52f3SManish Chopra qlcnic_sre_macaddr_change(adapter, cur->mac_addr, 318cffe52f3SManish Chopra 0, QLCNIC_MAC_DEL); 319cffe52f3SManish Chopra list_del(&cur->list); 320cffe52f3SManish Chopra kfree(cur); 321cffe52f3SManish Chopra return; 322cffe52f3SManish Chopra } 323cffe52f3SManish Chopra } 324cffe52f3SManish Chopra } 325cffe52f3SManish Chopra 326aa43c215SJeff Kirsher static int qlcnic_set_mac(struct net_device *netdev, void *p) 327aa43c215SJeff Kirsher { 328aa43c215SJeff Kirsher struct qlcnic_adapter *adapter = netdev_priv(netdev); 329aa43c215SJeff Kirsher struct sockaddr *addr = p; 330aa43c215SJeff Kirsher 3317cb03b23SRajesh Borundia if (qlcnic_sriov_vf_check(adapter)) 3327cb03b23SRajesh Borundia return -EINVAL; 3337cb03b23SRajesh Borundia 334aa43c215SJeff Kirsher if ((adapter->flags & QLCNIC_MAC_OVERRIDE_DISABLED)) 335aa43c215SJeff Kirsher return -EOPNOTSUPP; 336aa43c215SJeff Kirsher 337aa43c215SJeff Kirsher if (!is_valid_ether_addr(addr->sa_data)) 33813159183SSony Chacko return -EINVAL; 339aa43c215SJeff Kirsher 340cffe52f3SManish Chopra if (!memcmp(adapter->mac_addr, addr->sa_data, ETH_ALEN)) 341cffe52f3SManish Chopra return 0; 342cffe52f3SManish Chopra 343aa43c215SJeff Kirsher if (test_bit(__QLCNIC_DEV_UP, &adapter->state)) { 344aa43c215SJeff Kirsher netif_device_detach(netdev); 345aa43c215SJeff Kirsher qlcnic_napi_disable(adapter); 346aa43c215SJeff Kirsher } 347aa43c215SJeff Kirsher 348cffe52f3SManish Chopra qlcnic_delete_adapter_mac(adapter); 349aa43c215SJeff Kirsher memcpy(adapter->mac_addr, addr->sa_data, netdev->addr_len); 350aa43c215SJeff Kirsher memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len); 351aa43c215SJeff Kirsher qlcnic_set_multi(adapter->netdev); 352aa43c215SJeff Kirsher 353aa43c215SJeff Kirsher if (test_bit(__QLCNIC_DEV_UP, &adapter->state)) { 354aa43c215SJeff Kirsher netif_device_attach(netdev); 355aa43c215SJeff Kirsher qlcnic_napi_enable(adapter); 356aa43c215SJeff Kirsher } 357aa43c215SJeff Kirsher return 0; 358aa43c215SJeff Kirsher } 359aa43c215SJeff Kirsher 3601690be63SVlad Yasevich static int qlcnic_fdb_del(struct ndmsg *ndm, struct nlattr *tb[], 3611690be63SVlad Yasevich struct net_device *netdev, const unsigned char *addr) 362fe1adc6bSJitendra Kalsaria { 363fe1adc6bSJitendra Kalsaria struct qlcnic_adapter *adapter = netdev_priv(netdev); 364fe1adc6bSJitendra Kalsaria int err = -EOPNOTSUPP; 365fe1adc6bSJitendra Kalsaria 3663e5c112fSVlad Yasevich if (!adapter->fdb_mac_learn) 3673e5c112fSVlad Yasevich return ndo_dflt_fdb_del(ndm, tb, netdev, addr); 368fe1adc6bSJitendra Kalsaria 369fe1adc6bSJitendra Kalsaria if (adapter->flags & QLCNIC_ESWITCH_ENABLED) { 37052e493d0SJitendra Kalsaria if (is_unicast_ether_addr(addr)) { 37152e493d0SJitendra Kalsaria err = dev_uc_del(netdev, addr); 37252e493d0SJitendra Kalsaria if (!err) 373fe1adc6bSJitendra Kalsaria err = qlcnic_nic_del_mac(adapter, addr); 37452e493d0SJitendra Kalsaria } else if (is_multicast_ether_addr(addr)) { 375fe1adc6bSJitendra Kalsaria err = dev_mc_del(netdev, addr); 37652e493d0SJitendra Kalsaria } else { 377fe1adc6bSJitendra Kalsaria err = -EINVAL; 378fe1adc6bSJitendra Kalsaria } 37952e493d0SJitendra Kalsaria } 380fe1adc6bSJitendra Kalsaria return err; 381fe1adc6bSJitendra Kalsaria } 382fe1adc6bSJitendra Kalsaria 383fe1adc6bSJitendra Kalsaria static int qlcnic_fdb_add(struct ndmsg *ndm, struct nlattr *tb[], 384fe1adc6bSJitendra Kalsaria struct net_device *netdev, 385fe1adc6bSJitendra Kalsaria const unsigned char *addr, u16 flags) 386fe1adc6bSJitendra Kalsaria { 387fe1adc6bSJitendra Kalsaria struct qlcnic_adapter *adapter = netdev_priv(netdev); 388fe1adc6bSJitendra Kalsaria int err = 0; 389fe1adc6bSJitendra Kalsaria 3903e5c112fSVlad Yasevich if (!adapter->fdb_mac_learn) 3913e5c112fSVlad Yasevich return ndo_dflt_fdb_add(ndm, tb, netdev, addr, flags); 392fe1adc6bSJitendra Kalsaria 393fe1adc6bSJitendra Kalsaria if (!(adapter->flags & QLCNIC_ESWITCH_ENABLED)) { 394fe1adc6bSJitendra Kalsaria pr_info("%s: FDB e-switch is not enabled\n", __func__); 395fe1adc6bSJitendra Kalsaria return -EOPNOTSUPP; 396fe1adc6bSJitendra Kalsaria } 397fe1adc6bSJitendra Kalsaria 398fe1adc6bSJitendra Kalsaria if (ether_addr_equal(addr, adapter->mac_addr)) 399fe1adc6bSJitendra Kalsaria return err; 400fe1adc6bSJitendra Kalsaria 40152e493d0SJitendra Kalsaria if (is_unicast_ether_addr(addr)) { 40252e493d0SJitendra Kalsaria if (netdev_uc_count(netdev) < adapter->ahw->max_uc_count) 40352e493d0SJitendra Kalsaria err = dev_uc_add_excl(netdev, addr); 404fe1adc6bSJitendra Kalsaria else 40552e493d0SJitendra Kalsaria err = -ENOMEM; 40652e493d0SJitendra Kalsaria } else if (is_multicast_ether_addr(addr)) { 40752e493d0SJitendra Kalsaria err = dev_mc_add_excl(netdev, addr); 40852e493d0SJitendra Kalsaria } else { 409fe1adc6bSJitendra Kalsaria err = -EINVAL; 41052e493d0SJitendra Kalsaria } 411fe1adc6bSJitendra Kalsaria 412fe1adc6bSJitendra Kalsaria return err; 413fe1adc6bSJitendra Kalsaria } 414fe1adc6bSJitendra Kalsaria 415fe1adc6bSJitendra Kalsaria static int qlcnic_fdb_dump(struct sk_buff *skb, struct netlink_callback *ncb, 416fe1adc6bSJitendra Kalsaria struct net_device *netdev, int idx) 417fe1adc6bSJitendra Kalsaria { 418fe1adc6bSJitendra Kalsaria struct qlcnic_adapter *adapter = netdev_priv(netdev); 419fe1adc6bSJitendra Kalsaria 4203e5c112fSVlad Yasevich if (!adapter->fdb_mac_learn) 4213e5c112fSVlad Yasevich return ndo_dflt_fdb_dump(skb, ncb, netdev, idx); 422fe1adc6bSJitendra Kalsaria 423fe1adc6bSJitendra Kalsaria if (adapter->flags & QLCNIC_ESWITCH_ENABLED) 424fe1adc6bSJitendra Kalsaria idx = ndo_dflt_fdb_dump(skb, ncb, netdev, idx); 425fe1adc6bSJitendra Kalsaria 426fe1adc6bSJitendra Kalsaria return idx; 427fe1adc6bSJitendra Kalsaria } 428fe1adc6bSJitendra Kalsaria 4297e2cf4feSSony Chacko static void qlcnic_82xx_cancel_idc_work(struct qlcnic_adapter *adapter) 4307e2cf4feSSony Chacko { 4317e2cf4feSSony Chacko while (test_and_set_bit(__QLCNIC_RESETTING, &adapter->state)) 4327e2cf4feSSony Chacko usleep_range(10000, 11000); 4337e2cf4feSSony Chacko 43466451615SSucheta Chakraborty if (!adapter->fw_work.work.func) 43566451615SSucheta Chakraborty return; 43666451615SSucheta Chakraborty 4377e2cf4feSSony Chacko cancel_delayed_work_sync(&adapter->fw_work); 4387e2cf4feSSony Chacko } 4397e2cf4feSSony Chacko 44007a251c8SShahed Shaikh static int qlcnic_get_phys_port_id(struct net_device *netdev, 44107a251c8SShahed Shaikh struct netdev_phys_port_id *ppid) 44207a251c8SShahed Shaikh { 44307a251c8SShahed Shaikh struct qlcnic_adapter *adapter = netdev_priv(netdev); 44407a251c8SShahed Shaikh struct qlcnic_hardware_context *ahw = adapter->ahw; 44507a251c8SShahed Shaikh 44607a251c8SShahed Shaikh if (!(adapter->flags & QLCNIC_HAS_PHYS_PORT_ID)) 44707a251c8SShahed Shaikh return -EOPNOTSUPP; 44807a251c8SShahed Shaikh 44907a251c8SShahed Shaikh ppid->id_len = sizeof(ahw->phys_port_id); 45007a251c8SShahed Shaikh memcpy(ppid->id, ahw->phys_port_id, ppid->id_len); 45107a251c8SShahed Shaikh 45207a251c8SShahed Shaikh return 0; 45307a251c8SShahed Shaikh } 45407a251c8SShahed Shaikh 455aa43c215SJeff Kirsher static const struct net_device_ops qlcnic_netdev_ops = { 456aa43c215SJeff Kirsher .ndo_open = qlcnic_open, 457aa43c215SJeff Kirsher .ndo_stop = qlcnic_close, 458aa43c215SJeff Kirsher .ndo_start_xmit = qlcnic_xmit_frame, 459aa43c215SJeff Kirsher .ndo_get_stats = qlcnic_get_stats, 460aa43c215SJeff Kirsher .ndo_validate_addr = eth_validate_addr, 461afc4b13dSJiri Pirko .ndo_set_rx_mode = qlcnic_set_multi, 462aa43c215SJeff Kirsher .ndo_set_mac_address = qlcnic_set_mac, 463aa43c215SJeff Kirsher .ndo_change_mtu = qlcnic_change_mtu, 464aa43c215SJeff Kirsher .ndo_fix_features = qlcnic_fix_features, 465aa43c215SJeff Kirsher .ndo_set_features = qlcnic_set_features, 466aa43c215SJeff Kirsher .ndo_tx_timeout = qlcnic_tx_timeout, 467aa43c215SJeff Kirsher .ndo_vlan_rx_add_vid = qlcnic_vlan_rx_add, 468aa43c215SJeff Kirsher .ndo_vlan_rx_kill_vid = qlcnic_vlan_rx_del, 469fe1adc6bSJitendra Kalsaria .ndo_fdb_add = qlcnic_fdb_add, 470fe1adc6bSJitendra Kalsaria .ndo_fdb_del = qlcnic_fdb_del, 471fe1adc6bSJitendra Kalsaria .ndo_fdb_dump = qlcnic_fdb_dump, 47207a251c8SShahed Shaikh .ndo_get_phys_port_id = qlcnic_get_phys_port_id, 473aa43c215SJeff Kirsher #ifdef CONFIG_NET_POLL_CONTROLLER 474aa43c215SJeff Kirsher .ndo_poll_controller = qlcnic_poll_controller, 475aa43c215SJeff Kirsher #endif 4764000e7a7SRajesh Borundia #ifdef CONFIG_QLCNIC_SRIOV 4774000e7a7SRajesh Borundia .ndo_set_vf_mac = qlcnic_sriov_set_vf_mac, 4784000e7a7SRajesh Borundia .ndo_set_vf_tx_rate = qlcnic_sriov_set_vf_tx_rate, 4794000e7a7SRajesh Borundia .ndo_get_vf_config = qlcnic_sriov_get_vf_config, 48091b7282bSRajesh Borundia .ndo_set_vf_vlan = qlcnic_sriov_set_vf_vlan, 481a80be5a5SRajesh Borundia .ndo_set_vf_spoofchk = qlcnic_sriov_set_vf_spoofchk, 4824000e7a7SRajesh Borundia #endif 483aa43c215SJeff Kirsher }; 484aa43c215SJeff Kirsher 485b43e5ee7SSucheta Chakraborty static const struct net_device_ops qlcnic_netdev_failed_ops = { 486b43e5ee7SSucheta Chakraborty .ndo_open = qlcnic_open, 487b43e5ee7SSucheta Chakraborty }; 488b43e5ee7SSucheta Chakraborty 489aa43c215SJeff Kirsher static struct qlcnic_nic_template qlcnic_ops = { 490aa43c215SJeff Kirsher .config_bridged_mode = qlcnic_config_bridged_mode, 4917e2cf4feSSony Chacko .config_led = qlcnic_82xx_config_led, 4927e2cf4feSSony Chacko .start_firmware = qlcnic_82xx_start_firmware, 4937e2cf4feSSony Chacko .request_reset = qlcnic_82xx_dev_request_reset, 4947e2cf4feSSony Chacko .cancel_idc_work = qlcnic_82xx_cancel_idc_work, 4957e2cf4feSSony Chacko .napi_add = qlcnic_82xx_napi_add, 4964be41e92SSony Chacko .napi_del = qlcnic_82xx_napi_del, 4977e2cf4feSSony Chacko .config_ipaddr = qlcnic_82xx_config_ipaddr, 498486a5bc7SRajesh Borundia .shutdown = qlcnic_82xx_shutdown, 499486a5bc7SRajesh Borundia .resume = qlcnic_82xx_resume, 5007e2cf4feSSony Chacko .clear_legacy_intr = qlcnic_82xx_clear_legacy_intr, 501aa43c215SJeff Kirsher }; 502aa43c215SJeff Kirsher 5037e2cf4feSSony Chacko struct qlcnic_nic_template qlcnic_vf_ops = { 504aa43c215SJeff Kirsher .config_bridged_mode = qlcnicvf_config_bridged_mode, 505aa43c215SJeff Kirsher .config_led = qlcnicvf_config_led, 506aa43c215SJeff Kirsher .start_firmware = qlcnicvf_start_firmware 507aa43c215SJeff Kirsher }; 508aa43c215SJeff Kirsher 5097e2cf4feSSony Chacko static struct qlcnic_hardware_ops qlcnic_hw_ops = { 5107e2cf4feSSony Chacko .read_crb = qlcnic_82xx_read_crb, 5117e2cf4feSSony Chacko .write_crb = qlcnic_82xx_write_crb, 5127e2cf4feSSony Chacko .read_reg = qlcnic_82xx_hw_read_wx_2M, 5137e2cf4feSSony Chacko .write_reg = qlcnic_82xx_hw_write_wx_2M, 5147e2cf4feSSony Chacko .get_mac_address = qlcnic_82xx_get_mac_address, 5157e2cf4feSSony Chacko .setup_intr = qlcnic_82xx_setup_intr, 5167e2cf4feSSony Chacko .alloc_mbx_args = qlcnic_82xx_alloc_mbx_args, 5177e2cf4feSSony Chacko .mbx_cmd = qlcnic_82xx_issue_cmd, 5187e2cf4feSSony Chacko .get_func_no = qlcnic_82xx_get_func_no, 5197e2cf4feSSony Chacko .api_lock = qlcnic_82xx_api_lock, 5207e2cf4feSSony Chacko .api_unlock = qlcnic_82xx_api_unlock, 5217e2cf4feSSony Chacko .add_sysfs = qlcnic_82xx_add_sysfs, 5227e2cf4feSSony Chacko .remove_sysfs = qlcnic_82xx_remove_sysfs, 5237e2cf4feSSony Chacko .process_lb_rcv_ring_diag = qlcnic_82xx_process_rcv_ring_diag, 5247e2cf4feSSony Chacko .create_rx_ctx = qlcnic_82xx_fw_cmd_create_rx_ctx, 5257e2cf4feSSony Chacko .create_tx_ctx = qlcnic_82xx_fw_cmd_create_tx_ctx, 5267cb03b23SRajesh Borundia .del_rx_ctx = qlcnic_82xx_fw_cmd_del_rx_ctx, 5277cb03b23SRajesh Borundia .del_tx_ctx = qlcnic_82xx_fw_cmd_del_tx_ctx, 5287e2cf4feSSony Chacko .setup_link_event = qlcnic_82xx_linkevent_request, 5297e2cf4feSSony Chacko .get_nic_info = qlcnic_82xx_get_nic_info, 5307e2cf4feSSony Chacko .get_pci_info = qlcnic_82xx_get_pci_info, 5317e2cf4feSSony Chacko .set_nic_info = qlcnic_82xx_set_nic_info, 5327e2cf4feSSony Chacko .change_macvlan = qlcnic_82xx_sre_macaddr_change, 5337e2cf4feSSony Chacko .napi_enable = qlcnic_82xx_napi_enable, 5347e2cf4feSSony Chacko .napi_disable = qlcnic_82xx_napi_disable, 5357e2cf4feSSony Chacko .config_intr_coal = qlcnic_82xx_config_intr_coalesce, 5367e2cf4feSSony Chacko .config_rss = qlcnic_82xx_config_rss, 5377e2cf4feSSony Chacko .config_hw_lro = qlcnic_82xx_config_hw_lro, 5387e2cf4feSSony Chacko .config_loopback = qlcnic_82xx_set_lb_mode, 5397e2cf4feSSony Chacko .clear_loopback = qlcnic_82xx_clear_lb_mode, 5407e2cf4feSSony Chacko .config_promisc_mode = qlcnic_82xx_nic_set_promisc, 5417e2cf4feSSony Chacko .change_l2_filter = qlcnic_82xx_change_filter, 5427e2cf4feSSony Chacko .get_board_info = qlcnic_82xx_get_board_info, 54352e493d0SJitendra Kalsaria .set_mac_filter_count = qlcnic_82xx_set_mac_filter_count, 54491b7282bSRajesh Borundia .free_mac_list = qlcnic_82xx_free_mac_list, 54507a251c8SShahed Shaikh .read_phys_port_id = qlcnic_82xx_read_phys_port_id, 5464460f2e8SPratik Pujar .io_error_detected = qlcnic_82xx_io_error_detected, 5474460f2e8SPratik Pujar .io_slot_reset = qlcnic_82xx_io_slot_reset, 5484460f2e8SPratik Pujar .io_resume = qlcnic_82xx_io_resume, 5497e2cf4feSSony Chacko }; 5507e2cf4feSSony Chacko 55134e8c406SHimanshu Madhani static int qlcnic_check_multi_tx_capability(struct qlcnic_adapter *adapter) 552012ec812SHimanshu Madhani { 553012ec812SHimanshu Madhani struct qlcnic_hardware_context *ahw = adapter->ahw; 554012ec812SHimanshu Madhani 55534e8c406SHimanshu Madhani if (qlcnic_82xx_check(adapter) && 556012ec812SHimanshu Madhani (ahw->extra_capability[0] & QLCNIC_FW_CAPABILITY_2_MULTI_TX)) { 55734e8c406SHimanshu Madhani test_and_set_bit(__QLCNIC_MULTI_TX_UNIQUE, &adapter->state); 55834e8c406SHimanshu Madhani return 0; 559012ec812SHimanshu Madhani } else { 56034e8c406SHimanshu Madhani return 1; 561012ec812SHimanshu Madhani } 562012ec812SHimanshu Madhani } 563012ec812SHimanshu Madhani 56434e8c406SHimanshu Madhani static int qlcnic_max_rings(struct qlcnic_adapter *adapter, u8 ring_cnt, 56534e8c406SHimanshu Madhani int queue_type) 56634e8c406SHimanshu Madhani { 56734e8c406SHimanshu Madhani int num_rings, max_rings = QLCNIC_MAX_SDS_RINGS; 56834e8c406SHimanshu Madhani 56934e8c406SHimanshu Madhani if (queue_type == QLCNIC_RX_QUEUE) 57034e8c406SHimanshu Madhani max_rings = adapter->max_sds_rings; 57134e8c406SHimanshu Madhani else if (queue_type == QLCNIC_TX_QUEUE) 57234e8c406SHimanshu Madhani max_rings = adapter->max_tx_rings; 57334e8c406SHimanshu Madhani 57434e8c406SHimanshu Madhani num_rings = rounddown_pow_of_two(min_t(int, num_online_cpus(), 57534e8c406SHimanshu Madhani max_rings)); 57634e8c406SHimanshu Madhani 57734e8c406SHimanshu Madhani if (ring_cnt > num_rings) 57834e8c406SHimanshu Madhani return num_rings; 57934e8c406SHimanshu Madhani else 58034e8c406SHimanshu Madhani return ring_cnt; 58134e8c406SHimanshu Madhani } 58234e8c406SHimanshu Madhani 58334e8c406SHimanshu Madhani void qlcnic_set_tx_ring_count(struct qlcnic_adapter *adapter, u8 tx_cnt) 58434e8c406SHimanshu Madhani { 58534e8c406SHimanshu Madhani /* 83xx adapter does not have max_tx_rings intialized in probe */ 58634e8c406SHimanshu Madhani if (adapter->max_tx_rings) 58734e8c406SHimanshu Madhani adapter->drv_tx_rings = qlcnic_max_rings(adapter, tx_cnt, 58834e8c406SHimanshu Madhani QLCNIC_TX_QUEUE); 58934e8c406SHimanshu Madhani else 59034e8c406SHimanshu Madhani adapter->drv_tx_rings = tx_cnt; 59134e8c406SHimanshu Madhani 59234e8c406SHimanshu Madhani dev_info(&adapter->pdev->dev, "Set %d Tx rings\n", 59334e8c406SHimanshu Madhani adapter->drv_tx_rings); 59434e8c406SHimanshu Madhani } 59534e8c406SHimanshu Madhani 59634e8c406SHimanshu Madhani void qlcnic_set_sds_ring_count(struct qlcnic_adapter *adapter, u8 rx_cnt) 59734e8c406SHimanshu Madhani { 59834e8c406SHimanshu Madhani /* 83xx adapter does not have max_sds_rings intialized in probe */ 59934e8c406SHimanshu Madhani if (adapter->max_sds_rings) 60034e8c406SHimanshu Madhani adapter->drv_sds_rings = qlcnic_max_rings(adapter, rx_cnt, 60134e8c406SHimanshu Madhani QLCNIC_RX_QUEUE); 60234e8c406SHimanshu Madhani else 60334e8c406SHimanshu Madhani adapter->drv_sds_rings = rx_cnt; 60434e8c406SHimanshu Madhani 60534e8c406SHimanshu Madhani dev_info(&adapter->pdev->dev, "Set %d SDS rings\n", 60634e8c406SHimanshu Madhani adapter->drv_sds_rings); 60734e8c406SHimanshu Madhani } 60834e8c406SHimanshu Madhani 6097f966452SSony Chacko int qlcnic_enable_msix(struct qlcnic_adapter *adapter, u32 num_msix) 610aa43c215SJeff Kirsher { 611aa43c215SJeff Kirsher struct pci_dev *pdev = adapter->pdev; 61234e8c406SHimanshu Madhani int drv_tx_rings, drv_sds_rings, tx_vector; 61313159183SSony Chacko int err = -1, i; 614da6c8063SRajesh Borundia 615da6c8063SRajesh Borundia if (adapter->flags & QLCNIC_TX_INTR_SHARED) { 61634e8c406SHimanshu Madhani drv_tx_rings = 0; 617da6c8063SRajesh Borundia tx_vector = 0; 618da6c8063SRajesh Borundia } else { 61934e8c406SHimanshu Madhani drv_tx_rings = adapter->drv_tx_rings; 620da6c8063SRajesh Borundia tx_vector = 1; 621da6c8063SRajesh Borundia } 62213159183SSony Chacko 62313159183SSony Chacko if (!adapter->msix_entries) { 62413159183SSony Chacko adapter->msix_entries = kcalloc(num_msix, 62513159183SSony Chacko sizeof(struct msix_entry), 62613159183SSony Chacko GFP_KERNEL); 627b2adaca9SJoe Perches if (!adapter->msix_entries) 62813159183SSony Chacko return -ENOMEM; 62913159183SSony Chacko } 630aa43c215SJeff Kirsher 63134e8c406SHimanshu Madhani adapter->drv_sds_rings = QLCNIC_SINGLE_RING; 632aa43c215SJeff Kirsher adapter->flags &= ~(QLCNIC_MSI_ENABLED | QLCNIC_MSIX_ENABLED); 633aa43c215SJeff Kirsher 63479788450SSony Chacko if (adapter->ahw->msix_supported) { 635aa43c215SJeff Kirsher enable_msix: 63613159183SSony Chacko for (i = 0; i < num_msix; i++) 63713159183SSony Chacko adapter->msix_entries[i].entry = i; 638aa43c215SJeff Kirsher err = pci_enable_msix(pdev, adapter->msix_entries, num_msix); 639aa43c215SJeff Kirsher if (err == 0) { 640aa43c215SJeff Kirsher adapter->flags |= QLCNIC_MSIX_ENABLED; 64113159183SSony Chacko if (qlcnic_83xx_check(adapter)) { 64213159183SSony Chacko adapter->ahw->num_msix = num_msix; 64313159183SSony Chacko /* subtract mail box and tx ring vectors */ 64434e8c406SHimanshu Madhani adapter->drv_sds_rings = num_msix - 64534e8c406SHimanshu Madhani drv_tx_rings - 1; 64613159183SSony Chacko } else { 647012ec812SHimanshu Madhani adapter->ahw->num_msix = num_msix; 648012ec812SHimanshu Madhani if (qlcnic_check_multi_tx(adapter) && 649c2c5e3a0SHimanshu Madhani !adapter->ahw->diag_test && 65034e8c406SHimanshu Madhani (adapter->drv_tx_rings > 1)) 65134e8c406SHimanshu Madhani drv_sds_rings = num_msix - drv_tx_rings; 652012ec812SHimanshu Madhani else 65334e8c406SHimanshu Madhani drv_sds_rings = num_msix; 654012ec812SHimanshu Madhani 65534e8c406SHimanshu Madhani adapter->drv_sds_rings = drv_sds_rings; 65613159183SSony Chacko } 657aa43c215SJeff Kirsher dev_info(&pdev->dev, "using msi-x interrupts\n"); 658aa43c215SJeff Kirsher return err; 65913159183SSony Chacko } else if (err > 0) { 66013159183SSony Chacko dev_info(&pdev->dev, 66113159183SSony Chacko "Unable to allocate %d MSI-X interrupt vectors\n", 66213159183SSony Chacko num_msix); 66313159183SSony Chacko if (qlcnic_83xx_check(adapter)) { 664da6c8063SRajesh Borundia if (err < (QLC_83XX_MINIMUM_VECTOR - tx_vector)) 66513159183SSony Chacko return err; 66634e8c406SHimanshu Madhani err -= drv_tx_rings + 1; 667aa43c215SJeff Kirsher num_msix = rounddown_pow_of_two(err); 66834e8c406SHimanshu Madhani num_msix += drv_tx_rings + 1; 66913159183SSony Chacko } else { 67013159183SSony Chacko num_msix = rounddown_pow_of_two(err); 671012ec812SHimanshu Madhani if (qlcnic_check_multi_tx(adapter)) 67234e8c406SHimanshu Madhani num_msix += drv_tx_rings; 67313159183SSony Chacko } 67413159183SSony Chacko 67513159183SSony Chacko if (num_msix) { 67613159183SSony Chacko dev_info(&pdev->dev, 677dce056cbSManish Chopra "Trying to allocate %d MSI-X interrupt vectors\n", 67813159183SSony Chacko num_msix); 679aa43c215SJeff Kirsher goto enable_msix; 680aa43c215SJeff Kirsher } 68113159183SSony Chacko } else { 682dce056cbSManish Chopra dev_info(&pdev->dev, 683dce056cbSManish Chopra "Unable to allocate %d MSI-X interrupt vectors\n", 68413159183SSony Chacko num_msix); 685aa43c215SJeff Kirsher } 68613159183SSony Chacko } 68713159183SSony Chacko 688aa43c215SJeff Kirsher return err; 689aa43c215SJeff Kirsher } 690aa43c215SJeff Kirsher 6919a97e705SManish chopra static int qlcnic_enable_msi_legacy(struct qlcnic_adapter *adapter) 692aa43c215SJeff Kirsher { 6939a97e705SManish chopra int err = 0; 69415087c2bSSony Chacko u32 offset, mask_reg; 695aa43c215SJeff Kirsher const struct qlcnic_legacy_intr_set *legacy_intrp; 69615087c2bSSony Chacko struct qlcnic_hardware_context *ahw = adapter->ahw; 697aa43c215SJeff Kirsher struct pci_dev *pdev = adapter->pdev; 698aa43c215SJeff Kirsher 699099f7aa7SSony Chacko if (qlcnic_use_msi && !pci_enable_msi(pdev)) { 700aa43c215SJeff Kirsher adapter->flags |= QLCNIC_MSI_ENABLED; 70115087c2bSSony Chacko offset = msi_tgt_status[adapter->ahw->pci_func]; 70215087c2bSSony Chacko adapter->tgt_status_reg = qlcnic_get_ioaddr(adapter->ahw, 70315087c2bSSony Chacko offset); 704aa43c215SJeff Kirsher dev_info(&pdev->dev, "using msi interrupts\n"); 705aa43c215SJeff Kirsher adapter->msix_entries[0].vector = pdev->irq; 7069a97e705SManish chopra return err; 707aa43c215SJeff Kirsher } 708012ec812SHimanshu Madhani 7099a97e705SManish chopra if (qlcnic_use_msi || qlcnic_use_msi_x) 7109a97e705SManish chopra return -EOPNOTSUPP; 711aa43c215SJeff Kirsher 712aa43c215SJeff Kirsher legacy_intrp = &legacy_intr[adapter->ahw->pci_func]; 71379788450SSony Chacko adapter->ahw->int_vec_bit = legacy_intrp->int_vec_bit; 71415087c2bSSony Chacko offset = legacy_intrp->tgt_status_reg; 71515087c2bSSony Chacko adapter->tgt_status_reg = qlcnic_get_ioaddr(ahw, offset); 71615087c2bSSony Chacko mask_reg = legacy_intrp->tgt_mask_reg; 71715087c2bSSony Chacko adapter->tgt_mask_reg = qlcnic_get_ioaddr(ahw, mask_reg); 71815087c2bSSony Chacko adapter->isr_int_vec = qlcnic_get_ioaddr(ahw, ISR_INT_VECTOR); 71915087c2bSSony Chacko adapter->crb_int_state_reg = qlcnic_get_ioaddr(ahw, ISR_INT_STATE_REG); 720aa43c215SJeff Kirsher dev_info(&pdev->dev, "using legacy interrupts\n"); 721aa43c215SJeff Kirsher adapter->msix_entries[0].vector = pdev->irq; 7229a97e705SManish chopra return err; 723aa43c215SJeff Kirsher } 724aa43c215SJeff Kirsher 72534e8c406SHimanshu Madhani int qlcnic_82xx_setup_intr(struct qlcnic_adapter *adapter) 726aa43c215SJeff Kirsher { 7279a97e705SManish chopra int num_msix, err = 0; 728aa43c215SJeff Kirsher 72934e8c406SHimanshu Madhani num_msix = adapter->drv_sds_rings; 7307e2cf4feSSony Chacko 73134e8c406SHimanshu Madhani if (qlcnic_check_multi_tx(adapter)) 73234e8c406SHimanshu Madhani num_msix += adapter->drv_tx_rings; 733aa43c215SJeff Kirsher 7347e2cf4feSSony Chacko err = qlcnic_enable_msix(adapter, num_msix); 735012ec812SHimanshu Madhani if (err == -ENOMEM) 7367e2cf4feSSony Chacko return err; 737aa43c215SJeff Kirsher 738012ec812SHimanshu Madhani if (!(adapter->flags & QLCNIC_MSIX_ENABLED)) { 739012ec812SHimanshu Madhani qlcnic_disable_multi_tx(adapter); 740012ec812SHimanshu Madhani 7419a97e705SManish chopra err = qlcnic_enable_msi_legacy(adapter); 7429a97e705SManish chopra if (!err) 7439a97e705SManish chopra return err; 744012ec812SHimanshu Madhani } 7459a97e705SManish chopra 746012ec812SHimanshu Madhani return 0; 747012ec812SHimanshu Madhani } 748012ec812SHimanshu Madhani 749012ec812SHimanshu Madhani int qlcnic_82xx_mq_intrpt(struct qlcnic_adapter *adapter, int op_type) 750012ec812SHimanshu Madhani { 751012ec812SHimanshu Madhani struct qlcnic_hardware_context *ahw = adapter->ahw; 752012ec812SHimanshu Madhani int err, i; 753012ec812SHimanshu Madhani 754012ec812SHimanshu Madhani if (qlcnic_check_multi_tx(adapter) && 755c2c5e3a0SHimanshu Madhani !ahw->diag_test && 756012ec812SHimanshu Madhani (adapter->flags & QLCNIC_MSIX_ENABLED)) { 757012ec812SHimanshu Madhani ahw->intr_tbl = vzalloc(ahw->num_msix * 758012ec812SHimanshu Madhani sizeof(struct qlcnic_intrpt_config)); 759012ec812SHimanshu Madhani if (!ahw->intr_tbl) 760012ec812SHimanshu Madhani return -ENOMEM; 761012ec812SHimanshu Madhani 762012ec812SHimanshu Madhani for (i = 0; i < ahw->num_msix; i++) { 763012ec812SHimanshu Madhani ahw->intr_tbl[i].type = QLCNIC_INTRPT_MSIX; 764012ec812SHimanshu Madhani ahw->intr_tbl[i].id = i; 765012ec812SHimanshu Madhani ahw->intr_tbl[i].src = 0; 766012ec812SHimanshu Madhani } 767012ec812SHimanshu Madhani 768012ec812SHimanshu Madhani err = qlcnic_82xx_config_intrpt(adapter, 1); 769012ec812SHimanshu Madhani if (err) 770012ec812SHimanshu Madhani dev_err(&adapter->pdev->dev, 771012ec812SHimanshu Madhani "Failed to configure Interrupt for %d vector\n", 772012ec812SHimanshu Madhani ahw->num_msix); 773012ec812SHimanshu Madhani return err; 774012ec812SHimanshu Madhani } 775012ec812SHimanshu Madhani 776012ec812SHimanshu Madhani return 0; 777aa43c215SJeff Kirsher } 77813159183SSony Chacko 779319ecf12SSony Chacko void qlcnic_teardown_intr(struct qlcnic_adapter *adapter) 780aa43c215SJeff Kirsher { 781aa43c215SJeff Kirsher if (adapter->flags & QLCNIC_MSIX_ENABLED) 782aa43c215SJeff Kirsher pci_disable_msix(adapter->pdev); 783aa43c215SJeff Kirsher if (adapter->flags & QLCNIC_MSI_ENABLED) 784aa43c215SJeff Kirsher pci_disable_msi(adapter->pdev); 78513159183SSony Chacko 78613159183SSony Chacko kfree(adapter->msix_entries); 78713159183SSony Chacko adapter->msix_entries = NULL; 78813159183SSony Chacko 78913159183SSony Chacko if (adapter->ahw->intr_tbl) { 79013159183SSony Chacko vfree(adapter->ahw->intr_tbl); 79113159183SSony Chacko adapter->ahw->intr_tbl = NULL; 79213159183SSony Chacko } 793aa43c215SJeff Kirsher } 794aa43c215SJeff Kirsher 795f1a094a8SRajesh Borundia static void qlcnic_cleanup_pci_map(struct qlcnic_hardware_context *ahw) 796aa43c215SJeff Kirsher { 797f1a094a8SRajesh Borundia if (ahw->pci_base0 != NULL) 798f1a094a8SRajesh Borundia iounmap(ahw->pci_base0); 799aa43c215SJeff Kirsher } 800aa43c215SJeff Kirsher 8017e2cf4feSSony Chacko static int qlcnic_get_act_pci_func(struct qlcnic_adapter *adapter) 8027e2cf4feSSony Chacko { 8037e2cf4feSSony Chacko struct qlcnic_pci_info *pci_info; 8047e2cf4feSSony Chacko int ret; 8057e2cf4feSSony Chacko 8067e2cf4feSSony Chacko if (!(adapter->flags & QLCNIC_ESWITCH_ENABLED)) { 8077e2cf4feSSony Chacko switch (adapter->ahw->port_type) { 8087e2cf4feSSony Chacko case QLCNIC_GBE: 8097e2cf4feSSony Chacko adapter->ahw->act_pci_func = QLCNIC_NIU_MAX_GBE_PORTS; 8107e2cf4feSSony Chacko break; 8117e2cf4feSSony Chacko case QLCNIC_XGBE: 8127e2cf4feSSony Chacko adapter->ahw->act_pci_func = QLCNIC_NIU_MAX_XG_PORTS; 8137e2cf4feSSony Chacko break; 8147e2cf4feSSony Chacko } 8157e2cf4feSSony Chacko return 0; 8167e2cf4feSSony Chacko } 8177e2cf4feSSony Chacko 8187e2cf4feSSony Chacko if (adapter->ahw->op_mode == QLCNIC_MGMT_FUNC) 8197e2cf4feSSony Chacko return 0; 8207e2cf4feSSony Chacko 8217e2cf4feSSony Chacko pci_info = kcalloc(QLCNIC_MAX_PCI_FUNC, sizeof(*pci_info), GFP_KERNEL); 8227e2cf4feSSony Chacko if (!pci_info) 8237e2cf4feSSony Chacko return -ENOMEM; 8247e2cf4feSSony Chacko 8257e2cf4feSSony Chacko ret = qlcnic_get_pci_info(adapter, pci_info); 8267e2cf4feSSony Chacko kfree(pci_info); 8277e2cf4feSSony Chacko return ret; 8287e2cf4feSSony Chacko } 829d71170fbSSony Chacko 83035dafcb0SSony Chacko static bool qlcnic_port_eswitch_cfg_capability(struct qlcnic_adapter *adapter) 83135dafcb0SSony Chacko { 83235dafcb0SSony Chacko bool ret = false; 83335dafcb0SSony Chacko 83435dafcb0SSony Chacko if (qlcnic_84xx_check(adapter)) { 83535dafcb0SSony Chacko ret = true; 83635dafcb0SSony Chacko } else if (qlcnic_83xx_check(adapter)) { 83735dafcb0SSony Chacko if (adapter->ahw->extra_capability[0] & 83835dafcb0SSony Chacko QLCNIC_FW_CAPABILITY_2_PER_PORT_ESWITCH_CFG) 83935dafcb0SSony Chacko ret = true; 84035dafcb0SSony Chacko else 84135dafcb0SSony Chacko ret = false; 84235dafcb0SSony Chacko } 84335dafcb0SSony Chacko 84435dafcb0SSony Chacko return ret; 84535dafcb0SSony Chacko } 84635dafcb0SSony Chacko 847d71170fbSSony Chacko int qlcnic_init_pci_info(struct qlcnic_adapter *adapter) 848aa43c215SJeff Kirsher { 849aa43c215SJeff Kirsher struct qlcnic_pci_info *pci_info; 8504c776aadSSony Chacko int i, id = 0, ret = 0, j = 0; 851bff57d8eSSony Chacko u16 act_pci_func; 852aa43c215SJeff Kirsher u8 pfn; 853aa43c215SJeff Kirsher 854aa43c215SJeff Kirsher pci_info = kcalloc(QLCNIC_MAX_PCI_FUNC, sizeof(*pci_info), GFP_KERNEL); 855aa43c215SJeff Kirsher if (!pci_info) 856aa43c215SJeff Kirsher return -ENOMEM; 857aa43c215SJeff Kirsher 858bff57d8eSSony Chacko ret = qlcnic_get_pci_info(adapter, pci_info); 859bff57d8eSSony Chacko if (ret) 860bff57d8eSSony Chacko goto err_pci_info; 861bff57d8eSSony Chacko 862bff57d8eSSony Chacko act_pci_func = adapter->ahw->act_pci_func; 863bff57d8eSSony Chacko 864aa43c215SJeff Kirsher adapter->npars = kzalloc(sizeof(struct qlcnic_npar_info) * 865bff57d8eSSony Chacko act_pci_func, GFP_KERNEL); 866aa43c215SJeff Kirsher if (!adapter->npars) { 867aa43c215SJeff Kirsher ret = -ENOMEM; 868aa43c215SJeff Kirsher goto err_pci_info; 869aa43c215SJeff Kirsher } 870aa43c215SJeff Kirsher 871aa43c215SJeff Kirsher adapter->eswitch = kzalloc(sizeof(struct qlcnic_eswitch) * 872aa43c215SJeff Kirsher QLCNIC_NIU_MAX_XG_PORTS, GFP_KERNEL); 873aa43c215SJeff Kirsher if (!adapter->eswitch) { 874aa43c215SJeff Kirsher ret = -ENOMEM; 875aa43c215SJeff Kirsher goto err_npars; 876aa43c215SJeff Kirsher } 877aa43c215SJeff Kirsher 878aa43c215SJeff Kirsher for (i = 0; i < QLCNIC_MAX_PCI_FUNC; i++) { 879aa43c215SJeff Kirsher pfn = pci_info[i].id; 880bff57d8eSSony Chacko 8810f6efff9SDan Carpenter if (pfn >= QLCNIC_MAX_PCI_FUNC) { 882aa43c215SJeff Kirsher ret = QL_STATUS_INVALID_PARAM; 883aa43c215SJeff Kirsher goto err_eswitch; 884aa43c215SJeff Kirsher } 885bff57d8eSSony Chacko 886bff57d8eSSony Chacko if (!pci_info[i].active || 887bff57d8eSSony Chacko (pci_info[i].type != QLCNIC_TYPE_NIC)) 888bff57d8eSSony Chacko continue; 889bff57d8eSSony Chacko 89035dafcb0SSony Chacko if (qlcnic_port_eswitch_cfg_capability(adapter)) { 8914c776aadSSony Chacko if (!qlcnic_83xx_set_port_eswitch_status(adapter, pfn, 8924c776aadSSony Chacko &id)) 89335dafcb0SSony Chacko adapter->npars[j].eswitch_status = true; 89435dafcb0SSony Chacko else 89535dafcb0SSony Chacko continue; 89635dafcb0SSony Chacko } else { 89735dafcb0SSony Chacko adapter->npars[j].eswitch_status = true; 89835dafcb0SSony Chacko } 89935dafcb0SSony Chacko 900bff57d8eSSony Chacko adapter->npars[j].pci_func = pfn; 901bff57d8eSSony Chacko adapter->npars[j].active = (u8)pci_info[i].active; 902bff57d8eSSony Chacko adapter->npars[j].type = (u8)pci_info[i].type; 903bff57d8eSSony Chacko adapter->npars[j].phy_port = (u8)pci_info[i].default_port; 904bff57d8eSSony Chacko adapter->npars[j].min_bw = pci_info[i].tx_min_bw; 905bff57d8eSSony Chacko adapter->npars[j].max_bw = pci_info[i].tx_max_bw; 90635dafcb0SSony Chacko 9079e630955SSucheta Chakraborty memcpy(&adapter->npars[j].mac, &pci_info[i].mac, ETH_ALEN); 908bff57d8eSSony Chacko j++; 909aa43c215SJeff Kirsher } 910aa43c215SJeff Kirsher 9114c776aadSSony Chacko /* Update eSwitch status for adapters without per port eSwitch 9124c776aadSSony Chacko * configuration capability 9134c776aadSSony Chacko */ 9144c776aadSSony Chacko if (!qlcnic_port_eswitch_cfg_capability(adapter)) { 91535dafcb0SSony Chacko for (i = 0; i < QLCNIC_NIU_MAX_XG_PORTS; i++) 916aa43c215SJeff Kirsher adapter->eswitch[i].flags |= QLCNIC_SWITCH_ENABLE; 91713159183SSony Chacko } 918aa43c215SJeff Kirsher 919aa43c215SJeff Kirsher kfree(pci_info); 920aa43c215SJeff Kirsher return 0; 921aa43c215SJeff Kirsher 922aa43c215SJeff Kirsher err_eswitch: 923aa43c215SJeff Kirsher kfree(adapter->eswitch); 924aa43c215SJeff Kirsher adapter->eswitch = NULL; 925aa43c215SJeff Kirsher err_npars: 926aa43c215SJeff Kirsher kfree(adapter->npars); 927aa43c215SJeff Kirsher adapter->npars = NULL; 928aa43c215SJeff Kirsher err_pci_info: 929aa43c215SJeff Kirsher kfree(pci_info); 930aa43c215SJeff Kirsher 931aa43c215SJeff Kirsher return ret; 932aa43c215SJeff Kirsher } 933aa43c215SJeff Kirsher 934aa43c215SJeff Kirsher static int 935aa43c215SJeff Kirsher qlcnic_set_function_modes(struct qlcnic_adapter *adapter) 936aa43c215SJeff Kirsher { 937aa43c215SJeff Kirsher u8 id; 9387e8fd003SShahed Shaikh int ret; 939aa43c215SJeff Kirsher u32 data = QLCNIC_MGMT_FUNC; 940bff57d8eSSony Chacko struct qlcnic_hardware_context *ahw = adapter->ahw; 941aa43c215SJeff Kirsher 942aa43c215SJeff Kirsher ret = qlcnic_api_lock(adapter); 943aa43c215SJeff Kirsher if (ret) 944aa43c215SJeff Kirsher goto err_lock; 945aa43c215SJeff Kirsher 9467e8fd003SShahed Shaikh id = ahw->pci_func; 947a15ebd37SHimanshu Madhani data = QLC_SHARED_REG_RD32(adapter, QLCNIC_DRV_OP_MODE); 9487e8fd003SShahed Shaikh data = (data & ~QLC_DEV_SET_DRV(0xf, id)) | 9497e8fd003SShahed Shaikh QLC_DEV_SET_DRV(QLCNIC_MGMT_FUNC, id); 950a15ebd37SHimanshu Madhani QLC_SHARED_REG_WR32(adapter, QLCNIC_DRV_OP_MODE, data); 951aa43c215SJeff Kirsher qlcnic_api_unlock(adapter); 952aa43c215SJeff Kirsher err_lock: 953aa43c215SJeff Kirsher return ret; 954aa43c215SJeff Kirsher } 955aa43c215SJeff Kirsher 95613159183SSony Chacko static void qlcnic_check_vf(struct qlcnic_adapter *adapter, 95713159183SSony Chacko const struct pci_device_id *ent) 958aa43c215SJeff Kirsher { 959aa43c215SJeff Kirsher u32 op_mode, priv_level; 960aa43c215SJeff Kirsher 961aa43c215SJeff Kirsher /* Determine FW API version */ 96213159183SSony Chacko adapter->ahw->fw_hal_version = QLC_SHARED_REG_RD32(adapter, 963aa43c215SJeff Kirsher QLCNIC_FW_API); 964aa43c215SJeff Kirsher 965aa43c215SJeff Kirsher /* Find PCI function number */ 96613159183SSony Chacko qlcnic_get_func_no(adapter); 967aa43c215SJeff Kirsher 968aa43c215SJeff Kirsher /* Determine function privilege level */ 96913159183SSony Chacko op_mode = QLC_SHARED_REG_RD32(adapter, QLCNIC_DRV_OP_MODE); 970aa43c215SJeff Kirsher if (op_mode == QLC_DEV_DRV_DEFAULT) 971aa43c215SJeff Kirsher priv_level = QLCNIC_MGMT_FUNC; 972aa43c215SJeff Kirsher else 973aa43c215SJeff Kirsher priv_level = QLC_DEV_GET_DRV(op_mode, adapter->ahw->pci_func); 974aa43c215SJeff Kirsher 975aa43c215SJeff Kirsher if (priv_level == QLCNIC_NON_PRIV_FUNC) { 97679788450SSony Chacko adapter->ahw->op_mode = QLCNIC_NON_PRIV_FUNC; 977aa43c215SJeff Kirsher dev_info(&adapter->pdev->dev, 978aa43c215SJeff Kirsher "HAL Version: %d Non Privileged function\n", 97979788450SSony Chacko adapter->ahw->fw_hal_version); 980aa43c215SJeff Kirsher adapter->nic_ops = &qlcnic_vf_ops; 981aa43c215SJeff Kirsher } else 982aa43c215SJeff Kirsher adapter->nic_ops = &qlcnic_ops; 983aa43c215SJeff Kirsher } 984aa43c215SJeff Kirsher 98515087c2bSSony Chacko #define QLCNIC_82XX_BAR0_LENGTH 0x00200000UL 98613159183SSony Chacko #define QLCNIC_83XX_BAR0_LENGTH 0x4000 98715087c2bSSony Chacko static void qlcnic_get_bar_length(u32 dev_id, ulong *bar) 988aa43c215SJeff Kirsher { 98915087c2bSSony Chacko switch (dev_id) { 99015087c2bSSony Chacko case PCI_DEVICE_ID_QLOGIC_QLE824X: 99115087c2bSSony Chacko *bar = QLCNIC_82XX_BAR0_LENGTH; 99215087c2bSSony Chacko break; 99313159183SSony Chacko case PCI_DEVICE_ID_QLOGIC_QLE834X: 99415ca140fSManish Chopra case PCI_DEVICE_ID_QLOGIC_QLE844X: 995f8468331SRajesh Borundia case PCI_DEVICE_ID_QLOGIC_VF_QLE834X: 99615ca140fSManish Chopra case PCI_DEVICE_ID_QLOGIC_VF_QLE844X: 99713159183SSony Chacko *bar = QLCNIC_83XX_BAR0_LENGTH; 99813159183SSony Chacko break; 99915087c2bSSony Chacko default: 100015087c2bSSony Chacko *bar = 0; 100115087c2bSSony Chacko } 100215087c2bSSony Chacko } 100315087c2bSSony Chacko 100415087c2bSSony Chacko static int qlcnic_setup_pci_map(struct pci_dev *pdev, 100515087c2bSSony Chacko struct qlcnic_hardware_context *ahw) 100615087c2bSSony Chacko { 100715087c2bSSony Chacko u32 offset; 1008aa43c215SJeff Kirsher void __iomem *mem_ptr0 = NULL; 100915087c2bSSony Chacko unsigned long mem_len, pci_len0 = 0, bar0_len; 1010aa43c215SJeff Kirsher 1011aa43c215SJeff Kirsher /* remap phys address */ 1012aa43c215SJeff Kirsher mem_len = pci_resource_len(pdev, 0); 1013aa43c215SJeff Kirsher 101415087c2bSSony Chacko qlcnic_get_bar_length(pdev->device, &bar0_len); 101515087c2bSSony Chacko if (mem_len >= bar0_len) { 1016aa43c215SJeff Kirsher 1017aa43c215SJeff Kirsher mem_ptr0 = pci_ioremap_bar(pdev, 0); 1018aa43c215SJeff Kirsher if (mem_ptr0 == NULL) { 1019aa43c215SJeff Kirsher dev_err(&pdev->dev, "failed to map PCI bar 0\n"); 1020aa43c215SJeff Kirsher return -EIO; 1021aa43c215SJeff Kirsher } 1022aa43c215SJeff Kirsher pci_len0 = mem_len; 1023aa43c215SJeff Kirsher } else { 1024aa43c215SJeff Kirsher return -EIO; 1025aa43c215SJeff Kirsher } 1026aa43c215SJeff Kirsher 1027f8468331SRajesh Borundia dev_info(&pdev->dev, "%dKB memory map\n", (int)(mem_len >> 10)); 10287e2cf4feSSony Chacko 102915087c2bSSony Chacko ahw->pci_base0 = mem_ptr0; 103015087c2bSSony Chacko ahw->pci_len0 = pci_len0; 103115087c2bSSony Chacko offset = QLCNIC_PCIX_PS_REG(PCIX_OCM_WINDOW_REG(ahw->pci_func)); 103215087c2bSSony Chacko qlcnic_get_ioaddr(ahw, offset); 1033aa43c215SJeff Kirsher 1034aa43c215SJeff Kirsher return 0; 1035aa43c215SJeff Kirsher } 1036aa43c215SJeff Kirsher 103760dcbcb0SManish Chopra static bool qlcnic_validate_subsystem_id(struct qlcnic_adapter *adapter, 10382343f06aSManish Chopra int index) 10392343f06aSManish Chopra { 10402343f06aSManish Chopra struct pci_dev *pdev = adapter->pdev; 10412343f06aSManish Chopra unsigned short subsystem_vendor; 10422343f06aSManish Chopra bool ret = true; 10432343f06aSManish Chopra 10442343f06aSManish Chopra subsystem_vendor = pdev->subsystem_vendor; 10452343f06aSManish Chopra 10462343f06aSManish Chopra if (pdev->device == PCI_DEVICE_ID_QLOGIC_QLE824X || 10472343f06aSManish Chopra pdev->device == PCI_DEVICE_ID_QLOGIC_QLE834X) { 10482343f06aSManish Chopra if (qlcnic_boards[index].sub_vendor == subsystem_vendor && 10492343f06aSManish Chopra qlcnic_boards[index].sub_device == pdev->subsystem_device) 10502343f06aSManish Chopra ret = true; 10512343f06aSManish Chopra else 10522343f06aSManish Chopra ret = false; 10532343f06aSManish Chopra } 10542343f06aSManish Chopra 10552343f06aSManish Chopra return ret; 10562343f06aSManish Chopra } 10572343f06aSManish Chopra 105822999798SSony Chacko static void qlcnic_get_board_name(struct qlcnic_adapter *adapter, char *name) 1059aa43c215SJeff Kirsher { 1060aa43c215SJeff Kirsher struct pci_dev *pdev = adapter->pdev; 1061aa43c215SJeff Kirsher int i, found = 0; 1062aa43c215SJeff Kirsher 1063aa43c215SJeff Kirsher for (i = 0; i < NUM_SUPPORTED_BOARDS; ++i) { 1064aa43c215SJeff Kirsher if (qlcnic_boards[i].vendor == pdev->vendor && 1065aa43c215SJeff Kirsher qlcnic_boards[i].device == pdev->device && 10662343f06aSManish Chopra qlcnic_validate_subsystem_id(adapter, i)) { 1067aa43c215SJeff Kirsher found = 1; 1068aa43c215SJeff Kirsher break; 1069aa43c215SJeff Kirsher } 1070aa43c215SJeff Kirsher } 1071aa43c215SJeff Kirsher 1072aa43c215SJeff Kirsher if (!found) 1073aa43c215SJeff Kirsher sprintf(name, "%pM Gigabit Ethernet", adapter->mac_addr); 10742343f06aSManish Chopra else 10752343f06aSManish Chopra sprintf(name, "%pM: %s" , adapter->mac_addr, 10762343f06aSManish Chopra qlcnic_boards[i].short_name); 1077aa43c215SJeff Kirsher } 1078aa43c215SJeff Kirsher 1079aa43c215SJeff Kirsher static void 1080aa43c215SJeff Kirsher qlcnic_check_options(struct qlcnic_adapter *adapter) 1081aa43c215SJeff Kirsher { 1082a15ebd37SHimanshu Madhani int err; 1083aa43c215SJeff Kirsher u32 fw_major, fw_minor, fw_build, prev_fw_version; 1084aa43c215SJeff Kirsher struct pci_dev *pdev = adapter->pdev; 1085a15ebd37SHimanshu Madhani struct qlcnic_hardware_context *ahw = adapter->ahw; 1086a15ebd37SHimanshu Madhani struct qlcnic_fw_dump *fw_dump = &ahw->fw_dump; 1087aa43c215SJeff Kirsher 1088aa43c215SJeff Kirsher prev_fw_version = adapter->fw_version; 1089aa43c215SJeff Kirsher 1090a15ebd37SHimanshu Madhani fw_major = QLC_SHARED_REG_RD32(adapter, QLCNIC_FW_VERSION_MAJOR); 1091a15ebd37SHimanshu Madhani fw_minor = QLC_SHARED_REG_RD32(adapter, QLCNIC_FW_VERSION_MINOR); 1092a15ebd37SHimanshu Madhani fw_build = QLC_SHARED_REG_RD32(adapter, QLCNIC_FW_VERSION_SUB); 1093aa43c215SJeff Kirsher 1094aa43c215SJeff Kirsher adapter->fw_version = QLCNIC_VERSION_CODE(fw_major, fw_minor, fw_build); 1095aa43c215SJeff Kirsher 1096a15ebd37SHimanshu Madhani err = qlcnic_get_board_info(adapter); 1097a15ebd37SHimanshu Madhani if (err) { 1098a15ebd37SHimanshu Madhani dev_err(&pdev->dev, "Error getting board config info.\n"); 1099a15ebd37SHimanshu Madhani return; 1100a15ebd37SHimanshu Madhani } 1101a15ebd37SHimanshu Madhani if (ahw->op_mode != QLCNIC_NON_PRIV_FUNC) { 1102aa43c215SJeff Kirsher if (fw_dump->tmpl_hdr == NULL || 1103aa43c215SJeff Kirsher adapter->fw_version > prev_fw_version) { 1104aa43c215SJeff Kirsher if (fw_dump->tmpl_hdr) 1105aa43c215SJeff Kirsher vfree(fw_dump->tmpl_hdr); 1106aa43c215SJeff Kirsher if (!qlcnic_fw_cmd_get_minidump_temp(adapter)) 1107aa43c215SJeff Kirsher dev_info(&pdev->dev, 1108aa43c215SJeff Kirsher "Supports FW dump capability\n"); 1109aa43c215SJeff Kirsher } 1110aa43c215SJeff Kirsher } 1111aa43c215SJeff Kirsher 111213159183SSony Chacko dev_info(&pdev->dev, "Driver v%s, firmware v%d.%d.%d\n", 111313159183SSony Chacko QLCNIC_LINUX_VERSIONID, fw_major, fw_minor, fw_build); 111413159183SSony Chacko 1115aa43c215SJeff Kirsher if (adapter->ahw->port_type == QLCNIC_XGBE) { 1116aa43c215SJeff Kirsher if (adapter->flags & QLCNIC_ESWITCH_ENABLED) { 1117aa43c215SJeff Kirsher adapter->num_rxd = DEFAULT_RCV_DESCRIPTORS_VF; 1118aa43c215SJeff Kirsher adapter->max_rxd = MAX_RCV_DESCRIPTORS_VF; 1119aa43c215SJeff Kirsher } else { 1120aa43c215SJeff Kirsher adapter->num_rxd = DEFAULT_RCV_DESCRIPTORS_10G; 1121aa43c215SJeff Kirsher adapter->max_rxd = MAX_RCV_DESCRIPTORS_10G; 1122aa43c215SJeff Kirsher } 1123aa43c215SJeff Kirsher 1124aa43c215SJeff Kirsher adapter->num_jumbo_rxd = MAX_JUMBO_RCV_DESCRIPTORS_10G; 1125aa43c215SJeff Kirsher adapter->max_jumbo_rxd = MAX_JUMBO_RCV_DESCRIPTORS_10G; 1126aa43c215SJeff Kirsher 1127aa43c215SJeff Kirsher } else if (adapter->ahw->port_type == QLCNIC_GBE) { 1128aa43c215SJeff Kirsher adapter->num_rxd = DEFAULT_RCV_DESCRIPTORS_1G; 1129aa43c215SJeff Kirsher adapter->num_jumbo_rxd = MAX_JUMBO_RCV_DESCRIPTORS_1G; 1130aa43c215SJeff Kirsher adapter->max_jumbo_rxd = MAX_JUMBO_RCV_DESCRIPTORS_1G; 1131aa43c215SJeff Kirsher adapter->max_rxd = MAX_RCV_DESCRIPTORS_1G; 1132aa43c215SJeff Kirsher } 1133aa43c215SJeff Kirsher 1134099f7aa7SSony Chacko adapter->ahw->msix_supported = !!qlcnic_use_msi_x; 1135aa43c215SJeff Kirsher 1136aa43c215SJeff Kirsher adapter->num_txd = MAX_CMD_DESCRIPTORS; 1137aa43c215SJeff Kirsher 1138aa43c215SJeff Kirsher adapter->max_rds_rings = MAX_RDS_RINGS; 1139aa43c215SJeff Kirsher } 1140aa43c215SJeff Kirsher 1141aa43c215SJeff Kirsher static int 1142aa43c215SJeff Kirsher qlcnic_initialize_nic(struct qlcnic_adapter *adapter) 1143aa43c215SJeff Kirsher { 1144aa43c215SJeff Kirsher struct qlcnic_info nic_info; 11454bd8e738SHimanshu Madhani int err = 0; 1146aa43c215SJeff Kirsher 1147bff57d8eSSony Chacko memset(&nic_info, 0, sizeof(struct qlcnic_info)); 1148aa43c215SJeff Kirsher err = qlcnic_get_nic_info(adapter, &nic_info, adapter->ahw->pci_func); 1149aa43c215SJeff Kirsher if (err) 1150aa43c215SJeff Kirsher return err; 1151aa43c215SJeff Kirsher 115279788450SSony Chacko adapter->ahw->physical_port = (u8)nic_info.phys_port; 115379788450SSony Chacko adapter->ahw->switch_mode = nic_info.switch_mode; 115479788450SSony Chacko adapter->ahw->max_tx_ques = nic_info.max_tx_ques; 115579788450SSony Chacko adapter->ahw->max_rx_ques = nic_info.max_rx_ques; 115679788450SSony Chacko adapter->ahw->capabilities = nic_info.capabilities; 1157776e7bdeSShahed Shaikh 1158776e7bdeSShahed Shaikh if (adapter->ahw->capabilities & QLCNIC_FW_CAPABILITY_MORE_CAPS) { 1159776e7bdeSShahed Shaikh u32 temp; 11604bd8e738SHimanshu Madhani temp = QLCRD32(adapter, CRB_FW_CAPABILITIES_2, &err); 11614bd8e738SHimanshu Madhani if (err == -EIO) 11624bd8e738SHimanshu Madhani return err; 1163db131786SPratik Pujar adapter->ahw->extra_capability[0] = temp; 1164d6994ca7SShahed Shaikh } else { 1165d6994ca7SShahed Shaikh adapter->ahw->extra_capability[0] = 0; 1166776e7bdeSShahed Shaikh } 1167d6994ca7SShahed Shaikh 116879788450SSony Chacko adapter->ahw->max_mac_filters = nic_info.max_mac_filters; 116979788450SSony Chacko adapter->ahw->max_mtu = nic_info.max_mtu; 1170aa43c215SJeff Kirsher 117134e8c406SHimanshu Madhani if (adapter->ahw->capabilities & BIT_6) { 1172aa43c215SJeff Kirsher adapter->flags |= QLCNIC_ESWITCH_ENABLED; 117334e8c406SHimanshu Madhani adapter->ahw->nic_mode = QLCNIC_VNIC_MODE; 117434e8c406SHimanshu Madhani adapter->max_tx_rings = QLCNIC_MAX_HW_VNIC_TX_RINGS; 117534e8c406SHimanshu Madhani adapter->max_sds_rings = QLCNIC_MAX_VNIC_SDS_RINGS; 117634e8c406SHimanshu Madhani 117734e8c406SHimanshu Madhani dev_info(&adapter->pdev->dev, "vNIC mode enabled.\n"); 117834e8c406SHimanshu Madhani } else { 117934e8c406SHimanshu Madhani adapter->ahw->nic_mode = QLCNIC_DEFAULT_MODE; 118034e8c406SHimanshu Madhani adapter->max_tx_rings = QLCNIC_MAX_HW_TX_RINGS; 1181f9566265SHimanshu Madhani adapter->max_sds_rings = QLCNIC_MAX_SDS_RINGS; 1182aa43c215SJeff Kirsher adapter->flags &= ~QLCNIC_ESWITCH_ENABLED; 118334e8c406SHimanshu Madhani } 1184aa43c215SJeff Kirsher 1185aa43c215SJeff Kirsher return err; 1186aa43c215SJeff Kirsher } 1187aa43c215SJeff Kirsher 1188ec079a07SSony Chacko void qlcnic_set_vlan_config(struct qlcnic_adapter *adapter, 1189aa43c215SJeff Kirsher struct qlcnic_esw_func_cfg *esw_cfg) 1190aa43c215SJeff Kirsher { 1191aa43c215SJeff Kirsher if (esw_cfg->discard_tagged) 1192aa43c215SJeff Kirsher adapter->flags &= ~QLCNIC_TAGGING_ENABLED; 1193aa43c215SJeff Kirsher else 1194aa43c215SJeff Kirsher adapter->flags |= QLCNIC_TAGGING_ENABLED; 1195aa43c215SJeff Kirsher 119691b7282bSRajesh Borundia if (esw_cfg->vlan_id) { 119791b7282bSRajesh Borundia adapter->rx_pvid = esw_cfg->vlan_id; 119891b7282bSRajesh Borundia adapter->tx_pvid = esw_cfg->vlan_id; 119991b7282bSRajesh Borundia } else { 120091b7282bSRajesh Borundia adapter->rx_pvid = 0; 120191b7282bSRajesh Borundia adapter->tx_pvid = 0; 120291b7282bSRajesh Borundia } 1203aa43c215SJeff Kirsher } 1204aa43c215SJeff Kirsher 12058e586137SJiri Pirko static int 120680d5c368SPatrick McHardy qlcnic_vlan_rx_add(struct net_device *netdev, __be16 proto, u16 vid) 1207aa43c215SJeff Kirsher { 1208aa43c215SJeff Kirsher struct qlcnic_adapter *adapter = netdev_priv(netdev); 120991b7282bSRajesh Borundia int err; 121091b7282bSRajesh Borundia 121191b7282bSRajesh Borundia if (qlcnic_sriov_vf_check(adapter)) { 121291b7282bSRajesh Borundia err = qlcnic_sriov_cfg_vf_guest_vlan(adapter, vid, 1); 121391b7282bSRajesh Borundia if (err) { 121491b7282bSRajesh Borundia netdev_err(netdev, 121591b7282bSRajesh Borundia "Cannot add VLAN filter for VLAN id %d, err=%d", 121691b7282bSRajesh Borundia vid, err); 121791b7282bSRajesh Borundia return err; 121891b7282bSRajesh Borundia } 121991b7282bSRajesh Borundia } 122091b7282bSRajesh Borundia 1221aa43c215SJeff Kirsher set_bit(vid, adapter->vlans); 12228e586137SJiri Pirko return 0; 1223aa43c215SJeff Kirsher } 1224aa43c215SJeff Kirsher 12258e586137SJiri Pirko static int 122680d5c368SPatrick McHardy qlcnic_vlan_rx_del(struct net_device *netdev, __be16 proto, u16 vid) 1227aa43c215SJeff Kirsher { 1228aa43c215SJeff Kirsher struct qlcnic_adapter *adapter = netdev_priv(netdev); 122991b7282bSRajesh Borundia int err; 123091b7282bSRajesh Borundia 123191b7282bSRajesh Borundia if (qlcnic_sriov_vf_check(adapter)) { 123291b7282bSRajesh Borundia err = qlcnic_sriov_cfg_vf_guest_vlan(adapter, vid, 0); 123391b7282bSRajesh Borundia if (err) { 123491b7282bSRajesh Borundia netdev_err(netdev, 123591b7282bSRajesh Borundia "Cannot delete VLAN filter for VLAN id %d, err=%d", 123691b7282bSRajesh Borundia vid, err); 123791b7282bSRajesh Borundia return err; 123891b7282bSRajesh Borundia } 123991b7282bSRajesh Borundia } 1240aa43c215SJeff Kirsher 1241aa43c215SJeff Kirsher qlcnic_restore_indev_addr(netdev, NETDEV_DOWN); 1242aa43c215SJeff Kirsher clear_bit(vid, adapter->vlans); 12438e586137SJiri Pirko return 0; 1244aa43c215SJeff Kirsher } 1245aa43c215SJeff Kirsher 1246ec079a07SSony Chacko void qlcnic_set_eswitch_port_features(struct qlcnic_adapter *adapter, 1247aa43c215SJeff Kirsher struct qlcnic_esw_func_cfg *esw_cfg) 1248aa43c215SJeff Kirsher { 1249aa43c215SJeff Kirsher adapter->flags &= ~(QLCNIC_MACSPOOF | QLCNIC_MAC_OVERRIDE_DISABLED | 1250aa43c215SJeff Kirsher QLCNIC_PROMISC_DISABLED); 1251aa43c215SJeff Kirsher 1252aa43c215SJeff Kirsher if (esw_cfg->mac_anti_spoof) 1253aa43c215SJeff Kirsher adapter->flags |= QLCNIC_MACSPOOF; 1254aa43c215SJeff Kirsher 1255aa43c215SJeff Kirsher if (!esw_cfg->mac_override) 1256aa43c215SJeff Kirsher adapter->flags |= QLCNIC_MAC_OVERRIDE_DISABLED; 1257aa43c215SJeff Kirsher 1258aa43c215SJeff Kirsher if (!esw_cfg->promisc_mode) 1259aa43c215SJeff Kirsher adapter->flags |= QLCNIC_PROMISC_DISABLED; 1260aa43c215SJeff Kirsher } 1261aa43c215SJeff Kirsher 1262d71170fbSSony Chacko int qlcnic_set_eswitch_port_config(struct qlcnic_adapter *adapter) 1263aa43c215SJeff Kirsher { 1264aa43c215SJeff Kirsher struct qlcnic_esw_func_cfg esw_cfg; 1265aa43c215SJeff Kirsher 1266aa43c215SJeff Kirsher if (!(adapter->flags & QLCNIC_ESWITCH_ENABLED)) 1267aa43c215SJeff Kirsher return 0; 1268aa43c215SJeff Kirsher 1269aa43c215SJeff Kirsher esw_cfg.pci_func = adapter->ahw->pci_func; 1270aa43c215SJeff Kirsher if (qlcnic_get_eswitch_port_config(adapter, &esw_cfg)) 1271aa43c215SJeff Kirsher return -EIO; 1272aa43c215SJeff Kirsher qlcnic_set_vlan_config(adapter, &esw_cfg); 1273aa43c215SJeff Kirsher qlcnic_set_eswitch_port_features(adapter, &esw_cfg); 1274147a9088SShahed Shaikh qlcnic_set_netdev_features(adapter, &esw_cfg); 1275aa43c215SJeff Kirsher 1276aa43c215SJeff Kirsher return 0; 1277aa43c215SJeff Kirsher } 1278aa43c215SJeff Kirsher 1279147a9088SShahed Shaikh void qlcnic_set_netdev_features(struct qlcnic_adapter *adapter, 1280aa43c215SJeff Kirsher struct qlcnic_esw_func_cfg *esw_cfg) 1281aa43c215SJeff Kirsher { 1282aa43c215SJeff Kirsher struct net_device *netdev = adapter->netdev; 1283aa43c215SJeff Kirsher 128413159183SSony Chacko if (qlcnic_83xx_check(adapter)) 128513159183SSony Chacko return; 128613159183SSony Chacko 1287147a9088SShahed Shaikh adapter->offload_flags = esw_cfg->offload_flags; 1288147a9088SShahed Shaikh adapter->flags |= QLCNIC_APP_CHANGED_FLAGS; 1289147a9088SShahed Shaikh netdev_update_features(netdev); 1290147a9088SShahed Shaikh adapter->flags &= ~QLCNIC_APP_CHANGED_FLAGS; 1291aa43c215SJeff Kirsher } 1292aa43c215SJeff Kirsher 1293aa43c215SJeff Kirsher static int 1294aa43c215SJeff Kirsher qlcnic_check_eswitch_mode(struct qlcnic_adapter *adapter) 1295aa43c215SJeff Kirsher { 1296aa43c215SJeff Kirsher u32 op_mode, priv_level; 1297aa43c215SJeff Kirsher int err = 0; 1298aa43c215SJeff Kirsher 1299aa43c215SJeff Kirsher err = qlcnic_initialize_nic(adapter); 1300aa43c215SJeff Kirsher if (err) 1301aa43c215SJeff Kirsher return err; 1302aa43c215SJeff Kirsher 1303aa43c215SJeff Kirsher if (adapter->flags & QLCNIC_ADAPTER_INITIALIZED) 1304aa43c215SJeff Kirsher return 0; 1305aa43c215SJeff Kirsher 130613159183SSony Chacko op_mode = QLC_SHARED_REG_RD32(adapter, QLCNIC_DRV_OP_MODE); 1307aa43c215SJeff Kirsher priv_level = QLC_DEV_GET_DRV(op_mode, adapter->ahw->pci_func); 1308aa43c215SJeff Kirsher 1309aa43c215SJeff Kirsher if (op_mode == QLC_DEV_DRV_DEFAULT) 1310aa43c215SJeff Kirsher priv_level = QLCNIC_MGMT_FUNC; 1311aa43c215SJeff Kirsher else 1312aa43c215SJeff Kirsher priv_level = QLC_DEV_GET_DRV(op_mode, adapter->ahw->pci_func); 1313aa43c215SJeff Kirsher 1314aa43c215SJeff Kirsher if (adapter->flags & QLCNIC_ESWITCH_ENABLED) { 1315aa43c215SJeff Kirsher if (priv_level == QLCNIC_MGMT_FUNC) { 131679788450SSony Chacko adapter->ahw->op_mode = QLCNIC_MGMT_FUNC; 1317aa43c215SJeff Kirsher err = qlcnic_init_pci_info(adapter); 1318aa43c215SJeff Kirsher if (err) 1319aa43c215SJeff Kirsher return err; 1320aa43c215SJeff Kirsher /* Set privilege level for other functions */ 1321aa43c215SJeff Kirsher qlcnic_set_function_modes(adapter); 1322aa43c215SJeff Kirsher dev_info(&adapter->pdev->dev, 1323aa43c215SJeff Kirsher "HAL Version: %d, Management function\n", 132479788450SSony Chacko adapter->ahw->fw_hal_version); 1325aa43c215SJeff Kirsher } else if (priv_level == QLCNIC_PRIV_FUNC) { 132679788450SSony Chacko adapter->ahw->op_mode = QLCNIC_PRIV_FUNC; 1327aa43c215SJeff Kirsher dev_info(&adapter->pdev->dev, 1328aa43c215SJeff Kirsher "HAL Version: %d, Privileged function\n", 132979788450SSony Chacko adapter->ahw->fw_hal_version); 1330aa43c215SJeff Kirsher } 133134e8c406SHimanshu Madhani } else { 133234e8c406SHimanshu Madhani adapter->ahw->nic_mode = QLCNIC_DEFAULT_MODE; 1333aa43c215SJeff Kirsher } 1334aa43c215SJeff Kirsher 1335aa43c215SJeff Kirsher adapter->flags |= QLCNIC_ADAPTER_INITIALIZED; 1336aa43c215SJeff Kirsher 1337aa43c215SJeff Kirsher return err; 1338aa43c215SJeff Kirsher } 1339aa43c215SJeff Kirsher 1340d71170fbSSony Chacko int qlcnic_set_default_offload_settings(struct qlcnic_adapter *adapter) 1341aa43c215SJeff Kirsher { 1342aa43c215SJeff Kirsher struct qlcnic_esw_func_cfg esw_cfg; 1343aa43c215SJeff Kirsher struct qlcnic_npar_info *npar; 1344aa43c215SJeff Kirsher u8 i; 1345aa43c215SJeff Kirsher 1346aa43c215SJeff Kirsher if (adapter->need_fw_reset) 1347aa43c215SJeff Kirsher return 0; 1348aa43c215SJeff Kirsher 1349bff57d8eSSony Chacko for (i = 0; i < adapter->ahw->act_pci_func; i++) { 135035dafcb0SSony Chacko if (!adapter->npars[i].eswitch_status) 135135dafcb0SSony Chacko continue; 135235dafcb0SSony Chacko 1353aa43c215SJeff Kirsher memset(&esw_cfg, 0, sizeof(struct qlcnic_esw_func_cfg)); 1354bff57d8eSSony Chacko esw_cfg.pci_func = adapter->npars[i].pci_func; 1355aa43c215SJeff Kirsher esw_cfg.mac_override = BIT_0; 1356aa43c215SJeff Kirsher esw_cfg.promisc_mode = BIT_0; 1357bff57d8eSSony Chacko if (qlcnic_82xx_check(adapter)) { 1358bff57d8eSSony Chacko esw_cfg.offload_flags = BIT_0; 1359bff57d8eSSony Chacko if (QLCNIC_IS_TSO_CAPABLE(adapter)) 1360aa43c215SJeff Kirsher esw_cfg.offload_flags |= (BIT_1 | BIT_2); 1361bff57d8eSSony Chacko } 1362aa43c215SJeff Kirsher if (qlcnic_config_switch_port(adapter, &esw_cfg)) 1363aa43c215SJeff Kirsher return -EIO; 1364aa43c215SJeff Kirsher npar = &adapter->npars[i]; 1365aa43c215SJeff Kirsher npar->pvid = esw_cfg.vlan_id; 1366aa43c215SJeff Kirsher npar->mac_override = esw_cfg.mac_override; 1367aa43c215SJeff Kirsher npar->mac_anti_spoof = esw_cfg.mac_anti_spoof; 1368aa43c215SJeff Kirsher npar->discard_tagged = esw_cfg.discard_tagged; 1369aa43c215SJeff Kirsher npar->promisc_mode = esw_cfg.promisc_mode; 1370aa43c215SJeff Kirsher npar->offload_flags = esw_cfg.offload_flags; 1371aa43c215SJeff Kirsher } 1372aa43c215SJeff Kirsher 1373aa43c215SJeff Kirsher return 0; 1374aa43c215SJeff Kirsher } 1375aa43c215SJeff Kirsher 137613159183SSony Chacko 1377aa43c215SJeff Kirsher static int 1378aa43c215SJeff Kirsher qlcnic_reset_eswitch_config(struct qlcnic_adapter *adapter, 1379aa43c215SJeff Kirsher struct qlcnic_npar_info *npar, int pci_func) 1380aa43c215SJeff Kirsher { 1381aa43c215SJeff Kirsher struct qlcnic_esw_func_cfg esw_cfg; 1382aa43c215SJeff Kirsher esw_cfg.op_mode = QLCNIC_PORT_DEFAULTS; 1383aa43c215SJeff Kirsher esw_cfg.pci_func = pci_func; 1384aa43c215SJeff Kirsher esw_cfg.vlan_id = npar->pvid; 1385aa43c215SJeff Kirsher esw_cfg.mac_override = npar->mac_override; 1386aa43c215SJeff Kirsher esw_cfg.discard_tagged = npar->discard_tagged; 1387aa43c215SJeff Kirsher esw_cfg.mac_anti_spoof = npar->mac_anti_spoof; 1388aa43c215SJeff Kirsher esw_cfg.offload_flags = npar->offload_flags; 1389aa43c215SJeff Kirsher esw_cfg.promisc_mode = npar->promisc_mode; 1390aa43c215SJeff Kirsher if (qlcnic_config_switch_port(adapter, &esw_cfg)) 1391aa43c215SJeff Kirsher return -EIO; 1392aa43c215SJeff Kirsher 1393aa43c215SJeff Kirsher esw_cfg.op_mode = QLCNIC_ADD_VLAN; 1394aa43c215SJeff Kirsher if (qlcnic_config_switch_port(adapter, &esw_cfg)) 1395aa43c215SJeff Kirsher return -EIO; 1396aa43c215SJeff Kirsher 1397aa43c215SJeff Kirsher return 0; 1398aa43c215SJeff Kirsher } 1399aa43c215SJeff Kirsher 1400d71170fbSSony Chacko int qlcnic_reset_npar_config(struct qlcnic_adapter *adapter) 1401aa43c215SJeff Kirsher { 1402aa43c215SJeff Kirsher int i, err; 1403aa43c215SJeff Kirsher struct qlcnic_npar_info *npar; 1404aa43c215SJeff Kirsher struct qlcnic_info nic_info; 1405bff57d8eSSony Chacko u8 pci_func; 1406aa43c215SJeff Kirsher 1407bff57d8eSSony Chacko if (qlcnic_82xx_check(adapter)) 1408aa43c215SJeff Kirsher if (!adapter->need_fw_reset) 1409aa43c215SJeff Kirsher return 0; 1410aa43c215SJeff Kirsher 1411aa43c215SJeff Kirsher /* Set the NPAR config data after FW reset */ 1412bff57d8eSSony Chacko for (i = 0; i < adapter->ahw->act_pci_func; i++) { 1413aa43c215SJeff Kirsher npar = &adapter->npars[i]; 1414bff57d8eSSony Chacko pci_func = npar->pci_func; 141535dafcb0SSony Chacko if (!adapter->npars[i].eswitch_status) 141635dafcb0SSony Chacko continue; 141735dafcb0SSony Chacko 1418bff57d8eSSony Chacko memset(&nic_info, 0, sizeof(struct qlcnic_info)); 141913159183SSony Chacko err = qlcnic_get_nic_info(adapter, &nic_info, pci_func); 1420aa43c215SJeff Kirsher if (err) 1421aa43c215SJeff Kirsher return err; 1422aa43c215SJeff Kirsher nic_info.min_tx_bw = npar->min_bw; 1423aa43c215SJeff Kirsher nic_info.max_tx_bw = npar->max_bw; 1424aa43c215SJeff Kirsher err = qlcnic_set_nic_info(adapter, &nic_info); 1425aa43c215SJeff Kirsher if (err) 1426aa43c215SJeff Kirsher return err; 1427aa43c215SJeff Kirsher 1428aa43c215SJeff Kirsher if (npar->enable_pm) { 1429aa43c215SJeff Kirsher err = qlcnic_config_port_mirroring(adapter, 1430bff57d8eSSony Chacko npar->dest_npar, 1, 1431bff57d8eSSony Chacko pci_func); 1432aa43c215SJeff Kirsher if (err) 1433aa43c215SJeff Kirsher return err; 1434aa43c215SJeff Kirsher } 1435bff57d8eSSony Chacko err = qlcnic_reset_eswitch_config(adapter, npar, pci_func); 1436aa43c215SJeff Kirsher if (err) 1437aa43c215SJeff Kirsher return err; 1438aa43c215SJeff Kirsher } 1439aa43c215SJeff Kirsher return 0; 1440aa43c215SJeff Kirsher } 1441aa43c215SJeff Kirsher 1442aa43c215SJeff Kirsher static int qlcnic_check_npar_opertional(struct qlcnic_adapter *adapter) 1443aa43c215SJeff Kirsher { 1444aa43c215SJeff Kirsher u8 npar_opt_timeo = QLCNIC_DEV_NPAR_OPER_TIMEO; 1445aa43c215SJeff Kirsher u32 npar_state; 1446aa43c215SJeff Kirsher 144779788450SSony Chacko if (adapter->ahw->op_mode == QLCNIC_MGMT_FUNC) 1448aa43c215SJeff Kirsher return 0; 1449aa43c215SJeff Kirsher 1450a15ebd37SHimanshu Madhani npar_state = QLC_SHARED_REG_RD32(adapter, 1451a15ebd37SHimanshu Madhani QLCNIC_CRB_DEV_NPAR_STATE); 1452aa43c215SJeff Kirsher while (npar_state != QLCNIC_DEV_NPAR_OPER && --npar_opt_timeo) { 1453aa43c215SJeff Kirsher msleep(1000); 1454a15ebd37SHimanshu Madhani npar_state = QLC_SHARED_REG_RD32(adapter, 1455a15ebd37SHimanshu Madhani QLCNIC_CRB_DEV_NPAR_STATE); 1456aa43c215SJeff Kirsher } 1457aa43c215SJeff Kirsher if (!npar_opt_timeo) { 1458aa43c215SJeff Kirsher dev_err(&adapter->pdev->dev, 14598a168ca7SMasanari Iida "Waiting for NPAR state to operational timeout\n"); 1460aa43c215SJeff Kirsher return -EIO; 1461aa43c215SJeff Kirsher } 1462aa43c215SJeff Kirsher return 0; 1463aa43c215SJeff Kirsher } 1464aa43c215SJeff Kirsher 1465aa43c215SJeff Kirsher static int 1466aa43c215SJeff Kirsher qlcnic_set_mgmt_operations(struct qlcnic_adapter *adapter) 1467aa43c215SJeff Kirsher { 1468aa43c215SJeff Kirsher int err; 1469aa43c215SJeff Kirsher 1470aa43c215SJeff Kirsher if (!(adapter->flags & QLCNIC_ESWITCH_ENABLED) || 147179788450SSony Chacko adapter->ahw->op_mode != QLCNIC_MGMT_FUNC) 1472aa43c215SJeff Kirsher return 0; 1473aa43c215SJeff Kirsher 1474aa43c215SJeff Kirsher err = qlcnic_set_default_offload_settings(adapter); 1475aa43c215SJeff Kirsher if (err) 1476aa43c215SJeff Kirsher return err; 1477aa43c215SJeff Kirsher 1478aa43c215SJeff Kirsher err = qlcnic_reset_npar_config(adapter); 1479aa43c215SJeff Kirsher if (err) 1480aa43c215SJeff Kirsher return err; 1481aa43c215SJeff Kirsher 1482aa43c215SJeff Kirsher qlcnic_dev_set_npar_ready(adapter); 1483aa43c215SJeff Kirsher 1484aa43c215SJeff Kirsher return err; 1485aa43c215SJeff Kirsher } 1486aa43c215SJeff Kirsher 14877e2cf4feSSony Chacko int qlcnic_82xx_start_firmware(struct qlcnic_adapter *adapter) 1488aa43c215SJeff Kirsher { 1489aa43c215SJeff Kirsher int err; 1490aa43c215SJeff Kirsher 1491aa43c215SJeff Kirsher err = qlcnic_can_start_firmware(adapter); 1492aa43c215SJeff Kirsher if (err < 0) 1493aa43c215SJeff Kirsher return err; 1494aa43c215SJeff Kirsher else if (!err) 1495aa43c215SJeff Kirsher goto check_fw_status; 1496aa43c215SJeff Kirsher 1497099f7aa7SSony Chacko if (qlcnic_load_fw_file) 1498aa43c215SJeff Kirsher qlcnic_request_firmware(adapter); 1499aa43c215SJeff Kirsher else { 1500aa43c215SJeff Kirsher err = qlcnic_check_flash_fw_ver(adapter); 1501aa43c215SJeff Kirsher if (err) 1502aa43c215SJeff Kirsher goto err_out; 1503aa43c215SJeff Kirsher 150479788450SSony Chacko adapter->ahw->fw_type = QLCNIC_FLASH_ROMIMAGE; 1505aa43c215SJeff Kirsher } 1506aa43c215SJeff Kirsher 1507aa43c215SJeff Kirsher err = qlcnic_need_fw_reset(adapter); 1508aa43c215SJeff Kirsher if (err == 0) 1509aa43c215SJeff Kirsher goto check_fw_status; 1510aa43c215SJeff Kirsher 1511aa43c215SJeff Kirsher err = qlcnic_pinit_from_rom(adapter); 1512aa43c215SJeff Kirsher if (err) 1513aa43c215SJeff Kirsher goto err_out; 1514aa43c215SJeff Kirsher 1515aa43c215SJeff Kirsher err = qlcnic_load_firmware(adapter); 1516aa43c215SJeff Kirsher if (err) 1517aa43c215SJeff Kirsher goto err_out; 1518aa43c215SJeff Kirsher 1519aa43c215SJeff Kirsher qlcnic_release_firmware(adapter); 1520aa43c215SJeff Kirsher QLCWR32(adapter, CRB_DRIVER_VERSION, QLCNIC_DRIVER_VERSION); 1521aa43c215SJeff Kirsher 1522aa43c215SJeff Kirsher check_fw_status: 1523aa43c215SJeff Kirsher err = qlcnic_check_fw_status(adapter); 1524aa43c215SJeff Kirsher if (err) 1525aa43c215SJeff Kirsher goto err_out; 1526aa43c215SJeff Kirsher 1527a15ebd37SHimanshu Madhani QLC_SHARED_REG_WR32(adapter, QLCNIC_CRB_DEV_STATE, QLCNIC_DEV_READY); 1528aa43c215SJeff Kirsher qlcnic_idc_debug_info(adapter, 1); 1529aa43c215SJeff Kirsher err = qlcnic_check_eswitch_mode(adapter); 1530aa43c215SJeff Kirsher if (err) { 1531aa43c215SJeff Kirsher dev_err(&adapter->pdev->dev, 1532aa43c215SJeff Kirsher "Memory allocation failed for eswitch\n"); 1533aa43c215SJeff Kirsher goto err_out; 1534aa43c215SJeff Kirsher } 1535aa43c215SJeff Kirsher err = qlcnic_set_mgmt_operations(adapter); 1536aa43c215SJeff Kirsher if (err) 1537aa43c215SJeff Kirsher goto err_out; 1538aa43c215SJeff Kirsher 1539aa43c215SJeff Kirsher qlcnic_check_options(adapter); 1540aa43c215SJeff Kirsher adapter->need_fw_reset = 0; 1541aa43c215SJeff Kirsher 1542aa43c215SJeff Kirsher qlcnic_release_firmware(adapter); 1543aa43c215SJeff Kirsher return 0; 1544aa43c215SJeff Kirsher 1545aa43c215SJeff Kirsher err_out: 1546a15ebd37SHimanshu Madhani QLC_SHARED_REG_WR32(adapter, QLCNIC_CRB_DEV_STATE, QLCNIC_DEV_FAILED); 1547aa43c215SJeff Kirsher dev_err(&adapter->pdev->dev, "Device state set to failed\n"); 1548aa43c215SJeff Kirsher 1549aa43c215SJeff Kirsher qlcnic_release_firmware(adapter); 1550aa43c215SJeff Kirsher return err; 1551aa43c215SJeff Kirsher } 1552aa43c215SJeff Kirsher 1553aa43c215SJeff Kirsher static int 1554aa43c215SJeff Kirsher qlcnic_request_irq(struct qlcnic_adapter *adapter) 1555aa43c215SJeff Kirsher { 1556aa43c215SJeff Kirsher irq_handler_t handler; 1557aa43c215SJeff Kirsher struct qlcnic_host_sds_ring *sds_ring; 155813159183SSony Chacko struct qlcnic_host_tx_ring *tx_ring; 1559ddb2e174SHimanshu Madhani int err, ring, num_sds_rings; 1560aa43c215SJeff Kirsher 1561aa43c215SJeff Kirsher unsigned long flags = 0; 1562aa43c215SJeff Kirsher struct net_device *netdev = adapter->netdev; 1563aa43c215SJeff Kirsher struct qlcnic_recv_context *recv_ctx = adapter->recv_ctx; 1564aa43c215SJeff Kirsher 156579788450SSony Chacko if (adapter->ahw->diag_test == QLCNIC_INTERRUPT_TEST) { 156613159183SSony Chacko if (qlcnic_82xx_check(adapter)) 1567aa43c215SJeff Kirsher handler = qlcnic_tmp_intr; 1568c2534384SManish Chopra else 1569c2534384SManish Chopra handler = qlcnic_83xx_tmp_intr; 1570aa43c215SJeff Kirsher if (!QLCNIC_IS_MSI_FAMILY(adapter)) 1571aa43c215SJeff Kirsher flags |= IRQF_SHARED; 1572aa43c215SJeff Kirsher 1573aa43c215SJeff Kirsher } else { 1574aa43c215SJeff Kirsher if (adapter->flags & QLCNIC_MSIX_ENABLED) 1575aa43c215SJeff Kirsher handler = qlcnic_msix_intr; 1576aa43c215SJeff Kirsher else if (adapter->flags & QLCNIC_MSI_ENABLED) 1577aa43c215SJeff Kirsher handler = qlcnic_msi_intr; 1578aa43c215SJeff Kirsher else { 1579aa43c215SJeff Kirsher flags |= IRQF_SHARED; 1580ac166700SHimanshu Madhani if (qlcnic_82xx_check(adapter)) 1581aa43c215SJeff Kirsher handler = qlcnic_intr; 1582ac166700SHimanshu Madhani else 1583ac166700SHimanshu Madhani handler = qlcnic_83xx_intr; 1584aa43c215SJeff Kirsher } 1585aa43c215SJeff Kirsher } 1586aa43c215SJeff Kirsher adapter->irq = netdev->irq; 1587aa43c215SJeff Kirsher 158813159183SSony Chacko if (adapter->ahw->diag_test != QLCNIC_LOOPBACK_TEST) { 1589ac166700SHimanshu Madhani if (qlcnic_82xx_check(adapter) || 1590ac166700SHimanshu Madhani (qlcnic_83xx_check(adapter) && 1591ac166700SHimanshu Madhani (adapter->flags & QLCNIC_MSIX_ENABLED))) { 159234e8c406SHimanshu Madhani num_sds_rings = adapter->drv_sds_rings; 1593ddb2e174SHimanshu Madhani for (ring = 0; ring < num_sds_rings; ring++) { 1594aa43c215SJeff Kirsher sds_ring = &recv_ctx->sds_rings[ring]; 1595ddb2e174SHimanshu Madhani if (qlcnic_82xx_check(adapter) && 1596012ec812SHimanshu Madhani !qlcnic_check_multi_tx(adapter) && 1597aa2a8034SHimanshu Madhani (ring == (num_sds_rings - 1))) { 1598aa2a8034SHimanshu Madhani if (!(adapter->flags & 1599aa2a8034SHimanshu Madhani QLCNIC_MSIX_ENABLED)) 1600ddb2e174SHimanshu Madhani snprintf(sds_ring->name, 1601ddb2e174SHimanshu Madhani sizeof(sds_ring->name), 1602aa2a8034SHimanshu Madhani "qlcnic"); 1603ddb2e174SHimanshu Madhani else 1604ddb2e174SHimanshu Madhani snprintf(sds_ring->name, 1605ddb2e174SHimanshu Madhani sizeof(sds_ring->name), 1606aa2a8034SHimanshu Madhani "%s-tx-0-rx-%d", 1607ddb2e174SHimanshu Madhani netdev->name, ring); 1608aa2a8034SHimanshu Madhani } else { 1609aa2a8034SHimanshu Madhani snprintf(sds_ring->name, 1610aa2a8034SHimanshu Madhani sizeof(sds_ring->name), 1611aa2a8034SHimanshu Madhani "%s-rx-%d", 1612aa2a8034SHimanshu Madhani netdev->name, ring); 1613aa2a8034SHimanshu Madhani } 161413159183SSony Chacko err = request_irq(sds_ring->irq, handler, flags, 161513159183SSony Chacko sds_ring->name, sds_ring); 1616aa43c215SJeff Kirsher if (err) 1617aa43c215SJeff Kirsher return err; 1618aa43c215SJeff Kirsher } 1619ac166700SHimanshu Madhani } 1620012ec812SHimanshu Madhani if ((qlcnic_82xx_check(adapter) && 1621012ec812SHimanshu Madhani qlcnic_check_multi_tx(adapter)) || 1622012ec812SHimanshu Madhani (qlcnic_83xx_check(adapter) && 1623da6c8063SRajesh Borundia (adapter->flags & QLCNIC_MSIX_ENABLED) && 1624012ec812SHimanshu Madhani !(adapter->flags & QLCNIC_TX_INTR_SHARED))) { 162513159183SSony Chacko handler = qlcnic_msix_tx_intr; 162634e8c406SHimanshu Madhani for (ring = 0; ring < adapter->drv_tx_rings; 162713159183SSony Chacko ring++) { 162813159183SSony Chacko tx_ring = &adapter->tx_ring[ring]; 1629ddb2e174SHimanshu Madhani snprintf(tx_ring->name, sizeof(tx_ring->name), 1630aa2a8034SHimanshu Madhani "%s-tx-%d", netdev->name, ring); 163113159183SSony Chacko err = request_irq(tx_ring->irq, handler, flags, 163213159183SSony Chacko tx_ring->name, tx_ring); 163313159183SSony Chacko if (err) 163413159183SSony Chacko return err; 163513159183SSony Chacko } 163613159183SSony Chacko } 163713159183SSony Chacko } 1638aa43c215SJeff Kirsher return 0; 1639aa43c215SJeff Kirsher } 1640aa43c215SJeff Kirsher 1641aa43c215SJeff Kirsher static void 1642aa43c215SJeff Kirsher qlcnic_free_irq(struct qlcnic_adapter *adapter) 1643aa43c215SJeff Kirsher { 1644aa43c215SJeff Kirsher int ring; 1645aa43c215SJeff Kirsher struct qlcnic_host_sds_ring *sds_ring; 164613159183SSony Chacko struct qlcnic_host_tx_ring *tx_ring; 1647aa43c215SJeff Kirsher 1648aa43c215SJeff Kirsher struct qlcnic_recv_context *recv_ctx = adapter->recv_ctx; 1649aa43c215SJeff Kirsher 165013159183SSony Chacko if (adapter->ahw->diag_test != QLCNIC_LOOPBACK_TEST) { 1651ac166700SHimanshu Madhani if (qlcnic_82xx_check(adapter) || 1652ac166700SHimanshu Madhani (qlcnic_83xx_check(adapter) && 1653ac166700SHimanshu Madhani (adapter->flags & QLCNIC_MSIX_ENABLED))) { 165434e8c406SHimanshu Madhani for (ring = 0; ring < adapter->drv_sds_rings; ring++) { 1655aa43c215SJeff Kirsher sds_ring = &recv_ctx->sds_rings[ring]; 1656aa43c215SJeff Kirsher free_irq(sds_ring->irq, sds_ring); 1657aa43c215SJeff Kirsher } 1658ac166700SHimanshu Madhani } 1659012ec812SHimanshu Madhani if ((qlcnic_83xx_check(adapter) && 1660012ec812SHimanshu Madhani !(adapter->flags & QLCNIC_TX_INTR_SHARED)) || 1661012ec812SHimanshu Madhani (qlcnic_82xx_check(adapter) && 1662012ec812SHimanshu Madhani qlcnic_check_multi_tx(adapter))) { 166334e8c406SHimanshu Madhani for (ring = 0; ring < adapter->drv_tx_rings; 166413159183SSony Chacko ring++) { 166513159183SSony Chacko tx_ring = &adapter->tx_ring[ring]; 166613159183SSony Chacko if (tx_ring->irq) 166713159183SSony Chacko free_irq(tx_ring->irq, tx_ring); 166813159183SSony Chacko } 166913159183SSony Chacko } 167013159183SSony Chacko } 1671aa43c215SJeff Kirsher } 1672aa43c215SJeff Kirsher 167399e85879SShahed Shaikh static void qlcnic_get_lro_mss_capability(struct qlcnic_adapter *adapter) 167499e85879SShahed Shaikh { 167599e85879SShahed Shaikh u32 capab = 0; 167699e85879SShahed Shaikh 167799e85879SShahed Shaikh if (qlcnic_82xx_check(adapter)) { 1678db131786SPratik Pujar if (adapter->ahw->extra_capability[0] & 167999e85879SShahed Shaikh QLCNIC_FW_CAPABILITY_2_LRO_MAX_TCP_SEG) 168099e85879SShahed Shaikh adapter->flags |= QLCNIC_FW_LRO_MSS_CAP; 168199e85879SShahed Shaikh } else { 168299e85879SShahed Shaikh capab = adapter->ahw->capabilities; 168399e85879SShahed Shaikh if (QLC_83XX_GET_FW_LRO_MSS_CAPABILITY(capab)) 168499e85879SShahed Shaikh adapter->flags |= QLCNIC_FW_LRO_MSS_CAP; 168599e85879SShahed Shaikh } 168699e85879SShahed Shaikh } 168799e85879SShahed Shaikh 1688319ecf12SSony Chacko int __qlcnic_up(struct qlcnic_adapter *adapter, struct net_device *netdev) 1689aa43c215SJeff Kirsher { 1690aa43c215SJeff Kirsher int ring; 1691aa43c215SJeff Kirsher struct qlcnic_host_rds_ring *rds_ring; 1692aa43c215SJeff Kirsher 1693aa43c215SJeff Kirsher if (adapter->is_up != QLCNIC_ADAPTER_UP_MAGIC) 1694aa43c215SJeff Kirsher return -EIO; 1695aa43c215SJeff Kirsher 1696aa43c215SJeff Kirsher if (test_bit(__QLCNIC_DEV_UP, &adapter->state)) 1697aa43c215SJeff Kirsher return 0; 1698012ec812SHimanshu Madhani 1699aa43c215SJeff Kirsher if (qlcnic_set_eswitch_port_config(adapter)) 1700aa43c215SJeff Kirsher return -EIO; 1701012ec812SHimanshu Madhani 170299e85879SShahed Shaikh qlcnic_get_lro_mss_capability(adapter); 1703cae82d49SRajesh Borundia 1704aa43c215SJeff Kirsher if (qlcnic_fw_create_ctx(adapter)) 1705aa43c215SJeff Kirsher return -EIO; 1706aa43c215SJeff Kirsher 1707aa43c215SJeff Kirsher for (ring = 0; ring < adapter->max_rds_rings; ring++) { 1708aa43c215SJeff Kirsher rds_ring = &adapter->recv_ctx->rds_rings[ring]; 17094be41e92SSony Chacko qlcnic_post_rx_buffers(adapter, rds_ring, ring); 1710aa43c215SJeff Kirsher } 1711aa43c215SJeff Kirsher 1712aa43c215SJeff Kirsher qlcnic_set_multi(netdev); 1713aa43c215SJeff Kirsher qlcnic_fw_cmd_set_mtu(adapter, netdev->mtu); 1714aa43c215SJeff Kirsher 1715aa43c215SJeff Kirsher adapter->ahw->linkup = 0; 1716aa43c215SJeff Kirsher 171734e8c406SHimanshu Madhani if (adapter->drv_sds_rings > 1) 1718aa43c215SJeff Kirsher qlcnic_config_rss(adapter, 1); 1719aa43c215SJeff Kirsher 1720aa43c215SJeff Kirsher qlcnic_config_intr_coalesce(adapter); 1721aa43c215SJeff Kirsher 1722aa43c215SJeff Kirsher if (netdev->features & NETIF_F_LRO) 1723aa43c215SJeff Kirsher qlcnic_config_hw_lro(adapter, QLCNIC_LRO_ENABLED); 1724aa43c215SJeff Kirsher 1725cfacb172SPratik Pujar set_bit(__QLCNIC_DEV_UP, &adapter->state); 1726aa43c215SJeff Kirsher qlcnic_napi_enable(adapter); 1727aa43c215SJeff Kirsher 1728aa43c215SJeff Kirsher qlcnic_linkevent_request(adapter, 1); 1729aa43c215SJeff Kirsher 173079788450SSony Chacko adapter->ahw->reset_context = 0; 1731aa43c215SJeff Kirsher return 0; 1732aa43c215SJeff Kirsher } 1733aa43c215SJeff Kirsher 1734629263acSSony Chacko int qlcnic_up(struct qlcnic_adapter *adapter, struct net_device *netdev) 1735aa43c215SJeff Kirsher { 1736aa43c215SJeff Kirsher int err = 0; 1737aa43c215SJeff Kirsher 1738aa43c215SJeff Kirsher rtnl_lock(); 1739aa43c215SJeff Kirsher if (netif_running(netdev)) 1740aa43c215SJeff Kirsher err = __qlcnic_up(adapter, netdev); 1741aa43c215SJeff Kirsher rtnl_unlock(); 1742aa43c215SJeff Kirsher 1743aa43c215SJeff Kirsher return err; 1744aa43c215SJeff Kirsher } 1745aa43c215SJeff Kirsher 1746319ecf12SSony Chacko void __qlcnic_down(struct qlcnic_adapter *adapter, struct net_device *netdev) 1747aa43c215SJeff Kirsher { 1748012ec812SHimanshu Madhani int ring; 1749012ec812SHimanshu Madhani 1750aa43c215SJeff Kirsher if (adapter->is_up != QLCNIC_ADAPTER_UP_MAGIC) 1751aa43c215SJeff Kirsher return; 1752aa43c215SJeff Kirsher 1753aa43c215SJeff Kirsher if (!test_and_clear_bit(__QLCNIC_DEV_UP, &adapter->state)) 1754aa43c215SJeff Kirsher return; 1755aa43c215SJeff Kirsher 1756e8b508efSRajesh Borundia if (qlcnic_sriov_vf_check(adapter)) 1757e8b508efSRajesh Borundia qlcnic_sriov_cleanup_async_list(&adapter->ahw->sriov->bc); 1758aa43c215SJeff Kirsher smp_mb(); 175934e8c406SHimanshu Madhani spin_lock(&adapter->tx_clean_lock); 1760aa43c215SJeff Kirsher netif_carrier_off(netdev); 17610a46bac0SShahed Shaikh adapter->ahw->linkup = 0; 1762aa43c215SJeff Kirsher netif_tx_disable(netdev); 1763aa43c215SJeff Kirsher 1764aa43c215SJeff Kirsher qlcnic_free_mac_list(adapter); 1765aa43c215SJeff Kirsher 1766aa43c215SJeff Kirsher if (adapter->fhash.fnum) 1767aa43c215SJeff Kirsher qlcnic_delete_lb_filters(adapter); 1768aa43c215SJeff Kirsher 1769aa43c215SJeff Kirsher qlcnic_nic_set_promisc(adapter, QLCNIC_NIU_NON_PROMISC_MODE); 1770aa43c215SJeff Kirsher 1771aa43c215SJeff Kirsher qlcnic_napi_disable(adapter); 1772aa43c215SJeff Kirsher 1773aa43c215SJeff Kirsher qlcnic_fw_destroy_ctx(adapter); 1774cae82d49SRajesh Borundia adapter->flags &= ~QLCNIC_FW_LRO_MSS_CAP; 1775aa43c215SJeff Kirsher 1776aa43c215SJeff Kirsher qlcnic_reset_rx_buffers_list(adapter); 1777012ec812SHimanshu Madhani 177834e8c406SHimanshu Madhani for (ring = 0; ring < adapter->drv_tx_rings; ring++) 1779012ec812SHimanshu Madhani qlcnic_release_tx_buffers(adapter, &adapter->tx_ring[ring]); 178034e8c406SHimanshu Madhani spin_unlock(&adapter->tx_clean_lock); 1781aa43c215SJeff Kirsher } 1782aa43c215SJeff Kirsher 1783aa43c215SJeff Kirsher /* Usage: During suspend and firmware recovery module */ 1784aa43c215SJeff Kirsher 1785629263acSSony Chacko void qlcnic_down(struct qlcnic_adapter *adapter, struct net_device *netdev) 1786aa43c215SJeff Kirsher { 1787aa43c215SJeff Kirsher rtnl_lock(); 1788aa43c215SJeff Kirsher if (netif_running(netdev)) 1789aa43c215SJeff Kirsher __qlcnic_down(adapter, netdev); 1790aa43c215SJeff Kirsher rtnl_unlock(); 1791aa43c215SJeff Kirsher 1792aa43c215SJeff Kirsher } 1793aa43c215SJeff Kirsher 1794319ecf12SSony Chacko int 1795aa43c215SJeff Kirsher qlcnic_attach(struct qlcnic_adapter *adapter) 1796aa43c215SJeff Kirsher { 1797aa43c215SJeff Kirsher struct net_device *netdev = adapter->netdev; 1798aa43c215SJeff Kirsher struct pci_dev *pdev = adapter->pdev; 1799aa43c215SJeff Kirsher int err; 1800aa43c215SJeff Kirsher 1801aa43c215SJeff Kirsher if (adapter->is_up == QLCNIC_ADAPTER_UP_MAGIC) 1802aa43c215SJeff Kirsher return 0; 1803aa43c215SJeff Kirsher 1804aa43c215SJeff Kirsher err = qlcnic_napi_add(adapter, netdev); 1805aa43c215SJeff Kirsher if (err) 1806aa43c215SJeff Kirsher return err; 1807aa43c215SJeff Kirsher 1808aa43c215SJeff Kirsher err = qlcnic_alloc_sw_resources(adapter); 1809aa43c215SJeff Kirsher if (err) { 1810aa43c215SJeff Kirsher dev_err(&pdev->dev, "Error in setting sw resources\n"); 1811aa43c215SJeff Kirsher goto err_out_napi_del; 1812aa43c215SJeff Kirsher } 1813aa43c215SJeff Kirsher 1814aa43c215SJeff Kirsher err = qlcnic_alloc_hw_resources(adapter); 1815aa43c215SJeff Kirsher if (err) { 1816aa43c215SJeff Kirsher dev_err(&pdev->dev, "Error in setting hw resources\n"); 1817aa43c215SJeff Kirsher goto err_out_free_sw; 1818aa43c215SJeff Kirsher } 1819aa43c215SJeff Kirsher 1820aa43c215SJeff Kirsher err = qlcnic_request_irq(adapter); 1821aa43c215SJeff Kirsher if (err) { 1822aa43c215SJeff Kirsher dev_err(&pdev->dev, "failed to setup interrupt\n"); 1823aa43c215SJeff Kirsher goto err_out_free_hw; 1824aa43c215SJeff Kirsher } 1825aa43c215SJeff Kirsher 1826aa43c215SJeff Kirsher qlcnic_create_sysfs_entries(adapter); 1827aa43c215SJeff Kirsher 1828aa43c215SJeff Kirsher adapter->is_up = QLCNIC_ADAPTER_UP_MAGIC; 1829aa43c215SJeff Kirsher return 0; 1830aa43c215SJeff Kirsher 1831aa43c215SJeff Kirsher err_out_free_hw: 1832aa43c215SJeff Kirsher qlcnic_free_hw_resources(adapter); 1833aa43c215SJeff Kirsher err_out_free_sw: 1834aa43c215SJeff Kirsher qlcnic_free_sw_resources(adapter); 1835aa43c215SJeff Kirsher err_out_napi_del: 1836aa43c215SJeff Kirsher qlcnic_napi_del(adapter); 1837aa43c215SJeff Kirsher return err; 1838aa43c215SJeff Kirsher } 1839aa43c215SJeff Kirsher 1840319ecf12SSony Chacko void qlcnic_detach(struct qlcnic_adapter *adapter) 1841aa43c215SJeff Kirsher { 1842aa43c215SJeff Kirsher if (adapter->is_up != QLCNIC_ADAPTER_UP_MAGIC) 1843aa43c215SJeff Kirsher return; 1844aa43c215SJeff Kirsher 1845aa43c215SJeff Kirsher qlcnic_remove_sysfs_entries(adapter); 1846aa43c215SJeff Kirsher 1847aa43c215SJeff Kirsher qlcnic_free_hw_resources(adapter); 1848aa43c215SJeff Kirsher qlcnic_release_rx_buffers(adapter); 1849aa43c215SJeff Kirsher qlcnic_free_irq(adapter); 1850aa43c215SJeff Kirsher qlcnic_napi_del(adapter); 1851aa43c215SJeff Kirsher qlcnic_free_sw_resources(adapter); 1852aa43c215SJeff Kirsher 1853aa43c215SJeff Kirsher adapter->is_up = 0; 1854aa43c215SJeff Kirsher } 1855aa43c215SJeff Kirsher 185634e8c406SHimanshu Madhani void qlcnic_diag_free_res(struct net_device *netdev, int drv_sds_rings) 1857aa43c215SJeff Kirsher { 1858aa43c215SJeff Kirsher struct qlcnic_adapter *adapter = netdev_priv(netdev); 1859aa43c215SJeff Kirsher struct qlcnic_host_sds_ring *sds_ring; 186034e8c406SHimanshu Madhani int drv_tx_rings = adapter->drv_tx_rings; 1861aa43c215SJeff Kirsher int ring; 1862aa43c215SJeff Kirsher 1863aa43c215SJeff Kirsher clear_bit(__QLCNIC_DEV_UP, &adapter->state); 186479788450SSony Chacko if (adapter->ahw->diag_test == QLCNIC_INTERRUPT_TEST) { 186534e8c406SHimanshu Madhani for (ring = 0; ring < adapter->drv_sds_rings; ring++) { 1866aa43c215SJeff Kirsher sds_ring = &adapter->recv_ctx->sds_rings[ring]; 1867aa43c215SJeff Kirsher qlcnic_disable_int(sds_ring); 1868aa43c215SJeff Kirsher } 1869aa43c215SJeff Kirsher } 1870aa43c215SJeff Kirsher 1871aa43c215SJeff Kirsher qlcnic_fw_destroy_ctx(adapter); 1872aa43c215SJeff Kirsher 1873aa43c215SJeff Kirsher qlcnic_detach(adapter); 1874aa43c215SJeff Kirsher 187579788450SSony Chacko adapter->ahw->diag_test = 0; 187634e8c406SHimanshu Madhani adapter->drv_sds_rings = drv_sds_rings; 187734e8c406SHimanshu Madhani adapter->drv_tx_rings = drv_tx_rings; 1878aa43c215SJeff Kirsher 1879aa43c215SJeff Kirsher if (qlcnic_attach(adapter)) 1880aa43c215SJeff Kirsher goto out; 1881aa43c215SJeff Kirsher 1882aa43c215SJeff Kirsher if (netif_running(netdev)) 1883aa43c215SJeff Kirsher __qlcnic_up(adapter, netdev); 1884aa43c215SJeff Kirsher out: 1885aa43c215SJeff Kirsher netif_device_attach(netdev); 1886aa43c215SJeff Kirsher } 1887aa43c215SJeff Kirsher 1888aa43c215SJeff Kirsher static int qlcnic_alloc_adapter_resources(struct qlcnic_adapter *adapter) 1889aa43c215SJeff Kirsher { 1890be273dc1SHimanshu Madhani struct qlcnic_hardware_context *ahw = adapter->ahw; 1891aa43c215SJeff Kirsher int err = 0; 1892be273dc1SHimanshu Madhani 1893aa43c215SJeff Kirsher adapter->recv_ctx = kzalloc(sizeof(struct qlcnic_recv_context), 1894aa43c215SJeff Kirsher GFP_KERNEL); 1895aa43c215SJeff Kirsher if (!adapter->recv_ctx) { 1896aa43c215SJeff Kirsher err = -ENOMEM; 1897aa43c215SJeff Kirsher goto err_out; 1898aa43c215SJeff Kirsher } 1899aa43c215SJeff Kirsher /* Initialize interrupt coalesce parameters */ 1900be273dc1SHimanshu Madhani ahw->coal.flag = QLCNIC_INTR_DEFAULT; 1901be273dc1SHimanshu Madhani ahw->coal.type = QLCNIC_INTR_COAL_TYPE_RX; 1902be273dc1SHimanshu Madhani ahw->coal.rx_time_us = QLCNIC_DEF_INTR_COALESCE_RX_TIME_US; 1903be273dc1SHimanshu Madhani ahw->coal.rx_packets = QLCNIC_DEF_INTR_COALESCE_RX_PACKETS; 1904be273dc1SHimanshu Madhani if (qlcnic_83xx_check(adapter)) { 1905be273dc1SHimanshu Madhani ahw->coal.tx_time_us = QLCNIC_DEF_INTR_COALESCE_TX_TIME_US; 1906be273dc1SHimanshu Madhani ahw->coal.tx_packets = QLCNIC_DEF_INTR_COALESCE_TX_PACKETS; 1907be273dc1SHimanshu Madhani } 19084be41e92SSony Chacko /* clear stats */ 19094be41e92SSony Chacko memset(&adapter->stats, 0, sizeof(adapter->stats)); 1910aa43c215SJeff Kirsher err_out: 1911aa43c215SJeff Kirsher return err; 1912aa43c215SJeff Kirsher } 1913aa43c215SJeff Kirsher 1914aa43c215SJeff Kirsher static void qlcnic_free_adapter_resources(struct qlcnic_adapter *adapter) 1915aa43c215SJeff Kirsher { 1916aa43c215SJeff Kirsher kfree(adapter->recv_ctx); 1917aa43c215SJeff Kirsher adapter->recv_ctx = NULL; 1918aa43c215SJeff Kirsher 1919aa43c215SJeff Kirsher if (adapter->ahw->fw_dump.tmpl_hdr) { 1920aa43c215SJeff Kirsher vfree(adapter->ahw->fw_dump.tmpl_hdr); 1921aa43c215SJeff Kirsher adapter->ahw->fw_dump.tmpl_hdr = NULL; 1922aa43c215SJeff Kirsher } 19234be41e92SSony Chacko 192481d0aeb0SSony Chacko kfree(adapter->ahw->reset.buff); 19254be41e92SSony Chacko adapter->ahw->fw_dump.tmpl_hdr = NULL; 1926aa43c215SJeff Kirsher } 1927aa43c215SJeff Kirsher 1928aa43c215SJeff Kirsher int qlcnic_diag_alloc_res(struct net_device *netdev, int test) 1929aa43c215SJeff Kirsher { 1930aa43c215SJeff Kirsher struct qlcnic_adapter *adapter = netdev_priv(netdev); 1931aa43c215SJeff Kirsher struct qlcnic_host_sds_ring *sds_ring; 1932aa43c215SJeff Kirsher struct qlcnic_host_rds_ring *rds_ring; 1933aa43c215SJeff Kirsher int ring; 1934aa43c215SJeff Kirsher int ret; 1935aa43c215SJeff Kirsher 1936aa43c215SJeff Kirsher netif_device_detach(netdev); 1937aa43c215SJeff Kirsher 1938aa43c215SJeff Kirsher if (netif_running(netdev)) 1939aa43c215SJeff Kirsher __qlcnic_down(adapter, netdev); 1940aa43c215SJeff Kirsher 1941aa43c215SJeff Kirsher qlcnic_detach(adapter); 1942aa43c215SJeff Kirsher 194334e8c406SHimanshu Madhani adapter->drv_sds_rings = QLCNIC_SINGLE_RING; 194479788450SSony Chacko adapter->ahw->diag_test = test; 19454be41e92SSony Chacko adapter->ahw->linkup = 0; 1946aa43c215SJeff Kirsher 1947aa43c215SJeff Kirsher ret = qlcnic_attach(adapter); 1948aa43c215SJeff Kirsher if (ret) { 1949aa43c215SJeff Kirsher netif_device_attach(netdev); 1950aa43c215SJeff Kirsher return ret; 1951aa43c215SJeff Kirsher } 1952aa43c215SJeff Kirsher 1953aa43c215SJeff Kirsher ret = qlcnic_fw_create_ctx(adapter); 1954aa43c215SJeff Kirsher if (ret) { 1955aa43c215SJeff Kirsher qlcnic_detach(adapter); 1956aa43c215SJeff Kirsher netif_device_attach(netdev); 1957aa43c215SJeff Kirsher return ret; 1958aa43c215SJeff Kirsher } 1959aa43c215SJeff Kirsher 1960aa43c215SJeff Kirsher for (ring = 0; ring < adapter->max_rds_rings; ring++) { 1961aa43c215SJeff Kirsher rds_ring = &adapter->recv_ctx->rds_rings[ring]; 19624be41e92SSony Chacko qlcnic_post_rx_buffers(adapter, rds_ring, ring); 1963aa43c215SJeff Kirsher } 1964aa43c215SJeff Kirsher 196579788450SSony Chacko if (adapter->ahw->diag_test == QLCNIC_INTERRUPT_TEST) { 196634e8c406SHimanshu Madhani for (ring = 0; ring < adapter->drv_sds_rings; ring++) { 1967aa43c215SJeff Kirsher sds_ring = &adapter->recv_ctx->sds_rings[ring]; 1968aa43c215SJeff Kirsher qlcnic_enable_int(sds_ring); 1969aa43c215SJeff Kirsher } 1970aa43c215SJeff Kirsher } 1971aa43c215SJeff Kirsher 197279788450SSony Chacko if (adapter->ahw->diag_test == QLCNIC_LOOPBACK_TEST) { 1973aa43c215SJeff Kirsher adapter->ahw->loopback_state = 0; 1974aa43c215SJeff Kirsher qlcnic_linkevent_request(adapter, 1); 1975aa43c215SJeff Kirsher } 1976aa43c215SJeff Kirsher 1977aa43c215SJeff Kirsher set_bit(__QLCNIC_DEV_UP, &adapter->state); 1978aa43c215SJeff Kirsher 1979aa43c215SJeff Kirsher return 0; 1980aa43c215SJeff Kirsher } 1981aa43c215SJeff Kirsher 1982aa43c215SJeff Kirsher /* Reset context in hardware only */ 1983aa43c215SJeff Kirsher static int 1984aa43c215SJeff Kirsher qlcnic_reset_hw_context(struct qlcnic_adapter *adapter) 1985aa43c215SJeff Kirsher { 1986aa43c215SJeff Kirsher struct net_device *netdev = adapter->netdev; 1987aa43c215SJeff Kirsher 1988aa43c215SJeff Kirsher if (test_and_set_bit(__QLCNIC_RESETTING, &adapter->state)) 1989aa43c215SJeff Kirsher return -EBUSY; 1990aa43c215SJeff Kirsher 1991aa43c215SJeff Kirsher netif_device_detach(netdev); 1992aa43c215SJeff Kirsher 1993aa43c215SJeff Kirsher qlcnic_down(adapter, netdev); 1994aa43c215SJeff Kirsher 1995aa43c215SJeff Kirsher qlcnic_up(adapter, netdev); 1996aa43c215SJeff Kirsher 1997aa43c215SJeff Kirsher netif_device_attach(netdev); 1998aa43c215SJeff Kirsher 1999aa43c215SJeff Kirsher clear_bit(__QLCNIC_RESETTING, &adapter->state); 200013159183SSony Chacko dev_err(&adapter->pdev->dev, "%s:\n", __func__); 2001aa43c215SJeff Kirsher return 0; 2002aa43c215SJeff Kirsher } 2003aa43c215SJeff Kirsher 2004aa43c215SJeff Kirsher int 2005aa43c215SJeff Kirsher qlcnic_reset_context(struct qlcnic_adapter *adapter) 2006aa43c215SJeff Kirsher { 2007aa43c215SJeff Kirsher int err = 0; 2008aa43c215SJeff Kirsher struct net_device *netdev = adapter->netdev; 2009aa43c215SJeff Kirsher 2010aa43c215SJeff Kirsher if (test_and_set_bit(__QLCNIC_RESETTING, &adapter->state)) 2011aa43c215SJeff Kirsher return -EBUSY; 2012aa43c215SJeff Kirsher 2013aa43c215SJeff Kirsher if (adapter->is_up == QLCNIC_ADAPTER_UP_MAGIC) { 2014aa43c215SJeff Kirsher 2015aa43c215SJeff Kirsher netif_device_detach(netdev); 2016aa43c215SJeff Kirsher 2017aa43c215SJeff Kirsher if (netif_running(netdev)) 2018aa43c215SJeff Kirsher __qlcnic_down(adapter, netdev); 2019aa43c215SJeff Kirsher 2020aa43c215SJeff Kirsher qlcnic_detach(adapter); 2021aa43c215SJeff Kirsher 2022aa43c215SJeff Kirsher if (netif_running(netdev)) { 2023aa43c215SJeff Kirsher err = qlcnic_attach(adapter); 20241d5c88e3SAnirban Chakraborty if (!err) { 2025aa43c215SJeff Kirsher __qlcnic_up(adapter, netdev); 20261d5c88e3SAnirban Chakraborty qlcnic_restore_indev_addr(netdev, NETDEV_UP); 20271d5c88e3SAnirban Chakraborty } 2028aa43c215SJeff Kirsher } 2029aa43c215SJeff Kirsher 2030aa43c215SJeff Kirsher netif_device_attach(netdev); 2031aa43c215SJeff Kirsher } 2032aa43c215SJeff Kirsher 2033aa43c215SJeff Kirsher clear_bit(__QLCNIC_RESETTING, &adapter->state); 2034aa43c215SJeff Kirsher return err; 2035aa43c215SJeff Kirsher } 2036aa43c215SJeff Kirsher 203752e493d0SJitendra Kalsaria void qlcnic_82xx_set_mac_filter_count(struct qlcnic_adapter *adapter) 203852e493d0SJitendra Kalsaria { 203952e493d0SJitendra Kalsaria struct qlcnic_hardware_context *ahw = adapter->ahw; 204052e493d0SJitendra Kalsaria u16 act_pci_fn = ahw->act_pci_func; 204152e493d0SJitendra Kalsaria u16 count; 204252e493d0SJitendra Kalsaria 204352e493d0SJitendra Kalsaria ahw->max_mc_count = QLCNIC_MAX_MC_COUNT; 204452e493d0SJitendra Kalsaria if (act_pci_fn <= 2) 204552e493d0SJitendra Kalsaria count = (QLCNIC_MAX_UC_COUNT - QLCNIC_MAX_MC_COUNT) / 204652e493d0SJitendra Kalsaria act_pci_fn; 204752e493d0SJitendra Kalsaria else 204852e493d0SJitendra Kalsaria count = (QLCNIC_LB_MAX_FILTERS - QLCNIC_MAX_MC_COUNT) / 204952e493d0SJitendra Kalsaria act_pci_fn; 205052e493d0SJitendra Kalsaria ahw->max_uc_count = count; 205152e493d0SJitendra Kalsaria } 205252e493d0SJitendra Kalsaria 2053f8468331SRajesh Borundia int 20545ad6ff9dSSony Chacko qlcnic_setup_netdev(struct qlcnic_adapter *adapter, struct net_device *netdev, 20555ad6ff9dSSony Chacko int pci_using_dac) 2056aa43c215SJeff Kirsher { 2057aa43c215SJeff Kirsher int err; 2058aa43c215SJeff Kirsher struct pci_dev *pdev = adapter->pdev; 2059aa43c215SJeff Kirsher 206013159183SSony Chacko adapter->rx_csum = 1; 206179788450SSony Chacko adapter->ahw->mc_enabled = 0; 206252e493d0SJitendra Kalsaria qlcnic_set_mac_filter_count(adapter); 2063aa43c215SJeff Kirsher 2064aa43c215SJeff Kirsher netdev->netdev_ops = &qlcnic_netdev_ops; 206513159183SSony Chacko netdev->watchdog_timeo = QLCNIC_WATCHDOG_TIMEOUTVALUE * HZ; 2066aa43c215SJeff Kirsher 2067aa43c215SJeff Kirsher qlcnic_change_mtu(netdev, netdev->mtu); 2068aa43c215SJeff Kirsher 2069d1a1105eSRajesh Borundia if (qlcnic_sriov_vf_check(adapter)) 2070d1a1105eSRajesh Borundia SET_ETHTOOL_OPS(netdev, &qlcnic_sriov_vf_ethtool_ops); 2071d1a1105eSRajesh Borundia else 2072aa43c215SJeff Kirsher SET_ETHTOOL_OPS(netdev, &qlcnic_ethtool_ops); 2073aa43c215SJeff Kirsher 20747e38d04bSSony Chacko netdev->features |= (NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_RXCSUM | 207513159183SSony Chacko NETIF_F_IPV6_CSUM | NETIF_F_GRO | 2076f646968fSPatrick McHardy NETIF_F_HW_VLAN_CTAG_RX); 207713159183SSony Chacko netdev->vlan_features |= (NETIF_F_SG | NETIF_F_IP_CSUM | 207813159183SSony Chacko NETIF_F_IPV6_CSUM); 2079aa43c215SJeff Kirsher 208013159183SSony Chacko if (QLCNIC_IS_TSO_CAPABLE(adapter)) { 208113159183SSony Chacko netdev->features |= (NETIF_F_TSO | NETIF_F_TSO6); 208213159183SSony Chacko netdev->vlan_features |= (NETIF_F_TSO | NETIF_F_TSO6); 208313159183SSony Chacko } 2084aa43c215SJeff Kirsher 208513159183SSony Chacko if (pci_using_dac) { 208613159183SSony Chacko netdev->features |= NETIF_F_HIGHDMA; 208713159183SSony Chacko netdev->vlan_features |= NETIF_F_HIGHDMA; 208813159183SSony Chacko } 2089aa43c215SJeff Kirsher 209013159183SSony Chacko if (qlcnic_vlan_tx_check(adapter)) 2091f646968fSPatrick McHardy netdev->features |= (NETIF_F_HW_VLAN_CTAG_TX); 209213159183SSony Chacko 209391b7282bSRajesh Borundia if (qlcnic_sriov_vf_check(adapter)) 209491b7282bSRajesh Borundia netdev->features |= NETIF_F_HW_VLAN_CTAG_FILTER; 209591b7282bSRajesh Borundia 209679788450SSony Chacko if (adapter->ahw->capabilities & QLCNIC_FW_CAPABILITY_HW_LRO) 209713159183SSony Chacko netdev->features |= NETIF_F_LRO; 2098aa43c215SJeff Kirsher 20997e38d04bSSony Chacko netdev->hw_features = netdev->features; 210052e493d0SJitendra Kalsaria netdev->priv_flags |= IFF_UNICAST_FLT; 2101aa43c215SJeff Kirsher netdev->irq = adapter->msix_entries[0].vector; 2102aa43c215SJeff Kirsher 2103012ec812SHimanshu Madhani err = qlcnic_set_real_num_queues(adapter, netdev); 2104012ec812SHimanshu Madhani if (err) 2105012ec812SHimanshu Madhani return err; 2106012ec812SHimanshu Madhani 2107aa43c215SJeff Kirsher err = register_netdev(netdev); 2108aa43c215SJeff Kirsher if (err) { 2109aa43c215SJeff Kirsher dev_err(&pdev->dev, "failed to register net device\n"); 2110aa43c215SJeff Kirsher return err; 2111aa43c215SJeff Kirsher } 2112aa43c215SJeff Kirsher 21131de899d3SSucheta Chakraborty qlcnic_dcb_init_dcbnl_ops(adapter->dcb); 211448365e48SSucheta Chakraborty 2115aa43c215SJeff Kirsher return 0; 2116aa43c215SJeff Kirsher } 2117aa43c215SJeff Kirsher 21185ad6ff9dSSony Chacko static int qlcnic_set_dma_mask(struct pci_dev *pdev, int *pci_using_dac) 2119aa43c215SJeff Kirsher { 2120aa43c215SJeff Kirsher if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(64)) && 2121aa43c215SJeff Kirsher !pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64))) 2122aa43c215SJeff Kirsher *pci_using_dac = 1; 2123aa43c215SJeff Kirsher else if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(32)) && 2124aa43c215SJeff Kirsher !pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32))) 2125aa43c215SJeff Kirsher *pci_using_dac = 0; 2126aa43c215SJeff Kirsher else { 2127aa43c215SJeff Kirsher dev_err(&pdev->dev, "Unable to set DMA mask, aborting\n"); 2128aa43c215SJeff Kirsher return -EIO; 2129aa43c215SJeff Kirsher } 2130aa43c215SJeff Kirsher 2131aa43c215SJeff Kirsher return 0; 2132aa43c215SJeff Kirsher } 2133aa43c215SJeff Kirsher 21344be41e92SSony Chacko void qlcnic_free_tx_rings(struct qlcnic_adapter *adapter) 21354be41e92SSony Chacko { 21364be41e92SSony Chacko int ring; 21374be41e92SSony Chacko struct qlcnic_host_tx_ring *tx_ring; 21384be41e92SSony Chacko 213934e8c406SHimanshu Madhani for (ring = 0; ring < adapter->drv_tx_rings; ring++) { 21404be41e92SSony Chacko tx_ring = &adapter->tx_ring[ring]; 21414be41e92SSony Chacko if (tx_ring && tx_ring->cmd_buf_arr != NULL) { 21424be41e92SSony Chacko vfree(tx_ring->cmd_buf_arr); 21434be41e92SSony Chacko tx_ring->cmd_buf_arr = NULL; 21444be41e92SSony Chacko } 21454be41e92SSony Chacko } 21464be41e92SSony Chacko if (adapter->tx_ring != NULL) 21474be41e92SSony Chacko kfree(adapter->tx_ring); 21484be41e92SSony Chacko } 21494be41e92SSony Chacko 21504be41e92SSony Chacko int qlcnic_alloc_tx_rings(struct qlcnic_adapter *adapter, 21514be41e92SSony Chacko struct net_device *netdev) 21524be41e92SSony Chacko { 2153b2adaca9SJoe Perches int ring, vector, index; 21544be41e92SSony Chacko struct qlcnic_host_tx_ring *tx_ring; 21554be41e92SSony Chacko struct qlcnic_cmd_buffer *cmd_buf_arr; 21564be41e92SSony Chacko 215734e8c406SHimanshu Madhani tx_ring = kcalloc(adapter->drv_tx_rings, 2158b2adaca9SJoe Perches sizeof(struct qlcnic_host_tx_ring), GFP_KERNEL); 2159b2adaca9SJoe Perches if (tx_ring == NULL) 21604be41e92SSony Chacko return -ENOMEM; 2161b2adaca9SJoe Perches 21624be41e92SSony Chacko adapter->tx_ring = tx_ring; 21634be41e92SSony Chacko 216434e8c406SHimanshu Madhani for (ring = 0; ring < adapter->drv_tx_rings; ring++) { 21654be41e92SSony Chacko tx_ring = &adapter->tx_ring[ring]; 21664be41e92SSony Chacko tx_ring->num_desc = adapter->num_txd; 21674be41e92SSony Chacko tx_ring->txq = netdev_get_tx_queue(netdev, ring); 21684be41e92SSony Chacko cmd_buf_arr = vzalloc(TX_BUFF_RINGSIZE(tx_ring)); 21694be41e92SSony Chacko if (cmd_buf_arr == NULL) { 21704be41e92SSony Chacko qlcnic_free_tx_rings(adapter); 21714be41e92SSony Chacko return -ENOMEM; 21724be41e92SSony Chacko } 21734be41e92SSony Chacko memset(cmd_buf_arr, 0, TX_BUFF_RINGSIZE(tx_ring)); 21744be41e92SSony Chacko tx_ring->cmd_buf_arr = cmd_buf_arr; 21754be41e92SSony Chacko } 21764be41e92SSony Chacko 2177012ec812SHimanshu Madhani if (qlcnic_83xx_check(adapter) || 2178012ec812SHimanshu Madhani (qlcnic_82xx_check(adapter) && qlcnic_check_multi_tx(adapter))) { 217934e8c406SHimanshu Madhani for (ring = 0; ring < adapter->drv_tx_rings; ring++) { 21804be41e92SSony Chacko tx_ring = &adapter->tx_ring[ring]; 21814be41e92SSony Chacko tx_ring->adapter = adapter; 21824be41e92SSony Chacko if (adapter->flags & QLCNIC_MSIX_ENABLED) { 218334e8c406SHimanshu Madhani index = adapter->drv_sds_rings + ring; 21844be41e92SSony Chacko vector = adapter->msix_entries[index].vector; 21854be41e92SSony Chacko tx_ring->irq = vector; 21864be41e92SSony Chacko } 21874be41e92SSony Chacko } 21884be41e92SSony Chacko } 2189012ec812SHimanshu Madhani 21904be41e92SSony Chacko return 0; 21914be41e92SSony Chacko } 21924be41e92SSony Chacko 21938af3f33dSPratik Pujar void qlcnic_set_drv_version(struct qlcnic_adapter *adapter) 21948af3f33dSPratik Pujar { 21958af3f33dSPratik Pujar struct qlcnic_hardware_context *ahw = adapter->ahw; 21968af3f33dSPratik Pujar u32 fw_cmd = 0; 21978af3f33dSPratik Pujar 21988af3f33dSPratik Pujar if (qlcnic_82xx_check(adapter)) 21998af3f33dSPratik Pujar fw_cmd = QLCNIC_CMD_82XX_SET_DRV_VER; 22008af3f33dSPratik Pujar else if (qlcnic_83xx_check(adapter)) 22018af3f33dSPratik Pujar fw_cmd = QLCNIC_CMD_83XX_SET_DRV_VER; 22028af3f33dSPratik Pujar 2203d6994ca7SShahed Shaikh if (ahw->extra_capability[0] & QLCNIC_FW_CAPABILITY_SET_DRV_VER) 22048af3f33dSPratik Pujar qlcnic_fw_cmd_set_drv_version(adapter, fw_cmd); 22058af3f33dSPratik Pujar } 22068af3f33dSPratik Pujar 22076bb58bb0SBill Pemberton static int 2208aa43c215SJeff Kirsher qlcnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) 2209aa43c215SJeff Kirsher { 2210aa43c215SJeff Kirsher struct net_device *netdev = NULL; 2211aa43c215SJeff Kirsher struct qlcnic_adapter *adapter = NULL; 22127e2cf4feSSony Chacko struct qlcnic_hardware_context *ahw; 22135ad6ff9dSSony Chacko int err, pci_using_dac = -1; 22147bc48646SDan Carpenter char board_name[QLCNIC_MAX_BOARD_NAME_LEN + 19]; /* MAC + ": " + name */ 22151de899d3SSucheta Chakraborty struct qlcnic_dcb *dcb; 2216aa43c215SJeff Kirsher 2217f8468331SRajesh Borundia if (pdev->is_virtfn) 2218f8468331SRajesh Borundia return -ENODEV; 2219f8468331SRajesh Borundia 2220aa43c215SJeff Kirsher err = pci_enable_device(pdev); 2221aa43c215SJeff Kirsher if (err) 2222aa43c215SJeff Kirsher return err; 2223aa43c215SJeff Kirsher 2224aa43c215SJeff Kirsher if (!(pci_resource_flags(pdev, 0) & IORESOURCE_MEM)) { 2225aa43c215SJeff Kirsher err = -ENODEV; 2226aa43c215SJeff Kirsher goto err_out_disable_pdev; 2227aa43c215SJeff Kirsher } 2228aa43c215SJeff Kirsher 2229aa43c215SJeff Kirsher err = qlcnic_set_dma_mask(pdev, &pci_using_dac); 2230aa43c215SJeff Kirsher if (err) 2231aa43c215SJeff Kirsher goto err_out_disable_pdev; 2232aa43c215SJeff Kirsher 2233aa43c215SJeff Kirsher err = pci_request_regions(pdev, qlcnic_driver_name); 2234aa43c215SJeff Kirsher if (err) 2235aa43c215SJeff Kirsher goto err_out_disable_pdev; 2236aa43c215SJeff Kirsher 2237aa43c215SJeff Kirsher pci_set_master(pdev); 2238aa43c215SJeff Kirsher pci_enable_pcie_error_reporting(pdev); 2239aa43c215SJeff Kirsher 22407e2cf4feSSony Chacko ahw = kzalloc(sizeof(struct qlcnic_hardware_context), GFP_KERNEL); 224102135582SSony Chacko if (!ahw) { 224202135582SSony Chacko err = -ENOMEM; 22437e2cf4feSSony Chacko goto err_out_free_res; 224402135582SSony Chacko } 22457e2cf4feSSony Chacko 2246f8468331SRajesh Borundia switch (ent->device) { 2247f8468331SRajesh Borundia case PCI_DEVICE_ID_QLOGIC_QLE824X: 22487e2cf4feSSony Chacko ahw->hw_ops = &qlcnic_hw_ops; 22497e2cf4feSSony Chacko ahw->reg_tbl = (u32 *) qlcnic_reg_tbl; 2250f8468331SRajesh Borundia break; 2251f8468331SRajesh Borundia case PCI_DEVICE_ID_QLOGIC_QLE834X: 225215ca140fSManish Chopra case PCI_DEVICE_ID_QLOGIC_QLE844X: 225313159183SSony Chacko qlcnic_83xx_register_map(ahw); 2254f8468331SRajesh Borundia break; 2255f8468331SRajesh Borundia case PCI_DEVICE_ID_QLOGIC_VF_QLE834X: 225615ca140fSManish Chopra case PCI_DEVICE_ID_QLOGIC_VF_QLE844X: 2257f8468331SRajesh Borundia qlcnic_sriov_vf_register_map(ahw); 2258f8468331SRajesh Borundia break; 2259f8468331SRajesh Borundia default: 226013159183SSony Chacko goto err_out_free_hw_res; 22617e2cf4feSSony Chacko } 22627e2cf4feSSony Chacko 22637e2cf4feSSony Chacko err = qlcnic_setup_pci_map(pdev, ahw); 22647e2cf4feSSony Chacko if (err) 22657e2cf4feSSony Chacko goto err_out_free_hw_res; 22667e2cf4feSSony Chacko 2267012ec812SHimanshu Madhani netdev = alloc_etherdev_mq(sizeof(struct qlcnic_adapter), 2268012ec812SHimanshu Madhani QLCNIC_MAX_TX_RINGS); 2269aa43c215SJeff Kirsher if (!netdev) { 2270aa43c215SJeff Kirsher err = -ENOMEM; 22717e2cf4feSSony Chacko goto err_out_iounmap; 2272aa43c215SJeff Kirsher } 2273aa43c215SJeff Kirsher 2274aa43c215SJeff Kirsher SET_NETDEV_DEV(netdev, &pdev->dev); 2275aa43c215SJeff Kirsher 2276aa43c215SJeff Kirsher adapter = netdev_priv(netdev); 2277aa43c215SJeff Kirsher adapter->netdev = netdev; 2278aa43c215SJeff Kirsher adapter->pdev = pdev; 227913159183SSony Chacko adapter->ahw = ahw; 228013159183SSony Chacko 228113159183SSony Chacko adapter->qlcnic_wq = create_singlethread_workqueue("qlcnic"); 228213159183SSony Chacko if (adapter->qlcnic_wq == NULL) { 228302135582SSony Chacko err = -ENOMEM; 228413159183SSony Chacko dev_err(&pdev->dev, "Failed to create workqueue\n"); 228513159183SSony Chacko goto err_out_free_netdev; 228613159183SSony Chacko } 2287aa43c215SJeff Kirsher 22882dfc9671SPeter Senna Tschudin err = qlcnic_alloc_adapter_resources(adapter); 22892dfc9671SPeter Senna Tschudin if (err) 22902b1f18a4SWei Yongjun goto err_out_free_wq; 2291aa43c215SJeff Kirsher 2292aa43c215SJeff Kirsher adapter->dev_rst_time = jiffies; 22937e2cf4feSSony Chacko adapter->ahw->revision_id = pdev->revision; 2294fe1adc6bSJitendra Kalsaria if (qlcnic_mac_learn == FDB_MAC_LEARN) 2295fe1adc6bSJitendra Kalsaria adapter->fdb_mac_learn = true; 2296fe1adc6bSJitendra Kalsaria else if (qlcnic_mac_learn == DRV_MAC_LEARN) 2297fe1adc6bSJitendra Kalsaria adapter->drv_mac_learn = true; 2298aa43c215SJeff Kirsher 2299aa43c215SJeff Kirsher rwlock_init(&adapter->ahw->crb_lock); 2300aa43c215SJeff Kirsher mutex_init(&adapter->ahw->mem_lock); 2301aa43c215SJeff Kirsher 230234e8c406SHimanshu Madhani spin_lock_init(&adapter->tx_clean_lock); 2303aa43c215SJeff Kirsher INIT_LIST_HEAD(&adapter->mac_list); 2304aa43c215SJeff Kirsher 230514d385b9SSucheta Chakraborty qlcnic_register_dcb(adapter); 230614d385b9SSucheta Chakraborty 23077e2cf4feSSony Chacko if (qlcnic_82xx_check(adapter)) { 230813159183SSony Chacko qlcnic_check_vf(adapter, ent); 2309aa43c215SJeff Kirsher adapter->portnum = adapter->ahw->pci_func; 23107e2cf4feSSony Chacko err = qlcnic_start_firmware(adapter); 2311aa43c215SJeff Kirsher if (err) { 231266451615SSucheta Chakraborty dev_err(&pdev->dev, "Loading fw failed.Please Reboot\n" 231366451615SSucheta Chakraborty "\t\tIf reboot doesn't help, try flashing the card\n"); 231466451615SSucheta Chakraborty goto err_out_maintenance_mode; 2315aa43c215SJeff Kirsher } 2316aa43c215SJeff Kirsher 231734e8c406SHimanshu Madhani /* compute and set default and max tx/sds rings */ 231834e8c406SHimanshu Madhani if (adapter->ahw->msix_supported) { 231934e8c406SHimanshu Madhani if (qlcnic_check_multi_tx_capability(adapter) == 1) 232034e8c406SHimanshu Madhani qlcnic_set_tx_ring_count(adapter, 232134e8c406SHimanshu Madhani QLCNIC_SINGLE_RING); 232234e8c406SHimanshu Madhani else 232334e8c406SHimanshu Madhani qlcnic_set_tx_ring_count(adapter, 232434e8c406SHimanshu Madhani QLCNIC_DEF_TX_RINGS); 232534e8c406SHimanshu Madhani qlcnic_set_sds_ring_count(adapter, 232634e8c406SHimanshu Madhani QLCNIC_DEF_SDS_RINGS); 232734e8c406SHimanshu Madhani } else { 232834e8c406SHimanshu Madhani qlcnic_set_tx_ring_count(adapter, QLCNIC_SINGLE_RING); 232934e8c406SHimanshu Madhani qlcnic_set_sds_ring_count(adapter, QLCNIC_SINGLE_RING); 2330012ec812SHimanshu Madhani } 2331012ec812SHimanshu Madhani 2332aa43c215SJeff Kirsher err = qlcnic_setup_idc_param(adapter); 2333aa43c215SJeff Kirsher if (err) 23347e2cf4feSSony Chacko goto err_out_free_hw; 2335aa43c215SJeff Kirsher 2336aa43c215SJeff Kirsher adapter->flags |= QLCNIC_NEED_FLR; 233714d385b9SSucheta Chakraborty 23381de899d3SSucheta Chakraborty dcb = adapter->dcb; 23391de899d3SSucheta Chakraborty 23401de899d3SSucheta Chakraborty if (dcb && qlcnic_dcb_attach(dcb)) 23411de899d3SSucheta Chakraborty qlcnic_clear_dcb_ops(dcb); 234213159183SSony Chacko } else if (qlcnic_83xx_check(adapter)) { 234313159183SSony Chacko qlcnic_83xx_check_vf(adapter, ent); 234413159183SSony Chacko adapter->portnum = adapter->ahw->pci_func; 2345f8468331SRajesh Borundia err = qlcnic_83xx_init(adapter, pci_using_dac); 2346629263acSSony Chacko if (err) { 234778ea2d97SSucheta Chakraborty switch (err) { 234878ea2d97SSucheta Chakraborty case -ENOTRECOVERABLE: 234978ea2d97SSucheta Chakraborty dev_err(&pdev->dev, "Adapter initialization failed due to a faulty hardware. Please reboot\n"); 235078ea2d97SSucheta Chakraborty dev_err(&pdev->dev, "If reboot doesn't help, please replace the adapter with new one and return the faulty adapter for repair\n"); 2351629263acSSony Chacko goto err_out_free_hw; 235278ea2d97SSucheta Chakraborty case -ENOMEM: 235378ea2d97SSucheta Chakraborty dev_err(&pdev->dev, "Adapter initialization failed. Please reboot\n"); 235478ea2d97SSucheta Chakraborty goto err_out_free_hw; 235578ea2d97SSucheta Chakraborty default: 235678ea2d97SSucheta Chakraborty dev_err(&pdev->dev, "Adapter initialization failed. A reboot may be required to recover from this failure\n"); 235778ea2d97SSucheta Chakraborty dev_err(&pdev->dev, "If reboot does not help to recover from this failure, try a flash update of the adapter\n"); 235878ea2d97SSucheta Chakraborty goto err_out_maintenance_mode; 2359629263acSSony Chacko } 236078ea2d97SSucheta Chakraborty } 236178ea2d97SSucheta Chakraborty 2362f8468331SRajesh Borundia if (qlcnic_sriov_vf_check(adapter)) 2363f8468331SRajesh Borundia return 0; 236413159183SSony Chacko } else { 236513159183SSony Chacko dev_err(&pdev->dev, 236613159183SSony Chacko "%s: failed. Please Reboot\n", __func__); 236713159183SSony Chacko goto err_out_free_hw; 2368aa43c215SJeff Kirsher } 2369aa43c215SJeff Kirsher 2370aa43c215SJeff Kirsher if (qlcnic_read_mac_addr(adapter)) 2371aa43c215SJeff Kirsher dev_warn(&pdev->dev, "failed to read mac addr\n"); 2372aa43c215SJeff Kirsher 237307a251c8SShahed Shaikh qlcnic_read_phys_port_id(adapter); 237407a251c8SShahed Shaikh 2375aa43c215SJeff Kirsher if (adapter->portnum == 0) { 237622999798SSony Chacko qlcnic_get_board_name(adapter, board_name); 237713159183SSony Chacko 2378aa43c215SJeff Kirsher pr_info("%s: %s Board Chip rev 0x%x\n", 2379aa43c215SJeff Kirsher module_name(THIS_MODULE), 238022999798SSony Chacko board_name, adapter->ahw->revision_id); 2381aa43c215SJeff Kirsher } 2382460374f7SHimanshu Madhani 2383460374f7SHimanshu Madhani if (qlcnic_83xx_check(adapter) && !qlcnic_use_msi_x && 2384460374f7SHimanshu Madhani !!qlcnic_use_msi) 2385460374f7SHimanshu Madhani dev_warn(&pdev->dev, 238601b91f4cSPratik Pujar "Device does not support MSI interrupts\n"); 2387460374f7SHimanshu Madhani 2388068a8d19SManish Chopra if (qlcnic_82xx_check(adapter)) { 238934e8c406SHimanshu Madhani err = qlcnic_setup_intr(adapter); 23909a97e705SManish chopra if (err) { 23919a97e705SManish chopra dev_err(&pdev->dev, "Failed to setup interrupt\n"); 23927e2cf4feSSony Chacko goto err_out_disable_msi; 23939a97e705SManish chopra } 239413159183SSony Chacko } 2395aa43c215SJeff Kirsher 239602135582SSony Chacko err = qlcnic_get_act_pci_func(adapter); 239702135582SSony Chacko if (err) 239802135582SSony Chacko goto err_out_disable_mbx_intr; 239902135582SSony Chacko 2400aa43c215SJeff Kirsher err = qlcnic_setup_netdev(adapter, netdev, pci_using_dac); 2401aa43c215SJeff Kirsher if (err) 24027e2cf4feSSony Chacko goto err_out_disable_mbx_intr; 2403aa43c215SJeff Kirsher 240424866d15SHimanshu Madhani if (adapter->portnum == 0) 24058af3f33dSPratik Pujar qlcnic_set_drv_version(adapter); 2406c84e340aSSritej Velaga 2407aa43c215SJeff Kirsher pci_set_drvdata(pdev, adapter); 2408aa43c215SJeff Kirsher 240997ee45ebSSony Chacko if (qlcnic_82xx_check(adapter)) 241097ee45ebSSony Chacko qlcnic_schedule_work(adapter, qlcnic_fw_poll_work, 241197ee45ebSSony Chacko FW_POLL_DELAY); 2412aa43c215SJeff Kirsher 2413aa43c215SJeff Kirsher switch (adapter->ahw->port_type) { 2414aa43c215SJeff Kirsher case QLCNIC_GBE: 2415aa43c215SJeff Kirsher dev_info(&adapter->pdev->dev, "%s: GbE port initialized\n", 2416aa43c215SJeff Kirsher adapter->netdev->name); 2417aa43c215SJeff Kirsher break; 2418aa43c215SJeff Kirsher case QLCNIC_XGBE: 2419aa43c215SJeff Kirsher dev_info(&adapter->pdev->dev, "%s: XGbE port initialized\n", 2420aa43c215SJeff Kirsher adapter->netdev->name); 2421aa43c215SJeff Kirsher break; 2422aa43c215SJeff Kirsher } 2423aa43c215SJeff Kirsher 2424fe1adc6bSJitendra Kalsaria if (adapter->drv_mac_learn) 2425aa43c215SJeff Kirsher qlcnic_alloc_lb_filters_mem(adapter); 2426aa43c215SJeff Kirsher 24277e2cf4feSSony Chacko qlcnic_add_sysfs(adapter); 2428aa43c215SJeff Kirsher 2429aa43c215SJeff Kirsher return 0; 2430aa43c215SJeff Kirsher 24317e2cf4feSSony Chacko err_out_disable_mbx_intr: 24327dd90cf1SSucheta Chakraborty if (qlcnic_83xx_check(adapter)) 243313159183SSony Chacko qlcnic_83xx_free_mbx_intr(adapter); 24347e2cf4feSSony Chacko 2435aa43c215SJeff Kirsher err_out_disable_msi: 2436aa43c215SJeff Kirsher qlcnic_teardown_intr(adapter); 24377e2cf4feSSony Chacko qlcnic_cancel_idc_work(adapter); 2438aa43c215SJeff Kirsher qlcnic_clr_all_drv_state(adapter, 0); 2439aa43c215SJeff Kirsher 2440aa43c215SJeff Kirsher err_out_free_hw: 2441aa43c215SJeff Kirsher qlcnic_free_adapter_resources(adapter); 2442aa43c215SJeff Kirsher 24432b1f18a4SWei Yongjun err_out_free_wq: 24442b1f18a4SWei Yongjun destroy_workqueue(adapter->qlcnic_wq); 24452b1f18a4SWei Yongjun 2446aa43c215SJeff Kirsher err_out_free_netdev: 2447aa43c215SJeff Kirsher free_netdev(netdev); 2448aa43c215SJeff Kirsher 24497e2cf4feSSony Chacko err_out_iounmap: 2450f1a094a8SRajesh Borundia qlcnic_cleanup_pci_map(ahw); 24517e2cf4feSSony Chacko 24527e2cf4feSSony Chacko err_out_free_hw_res: 24537e2cf4feSSony Chacko kfree(ahw); 24547e2cf4feSSony Chacko 2455aa43c215SJeff Kirsher err_out_free_res: 2456aa43c215SJeff Kirsher pci_release_regions(pdev); 2457aa43c215SJeff Kirsher 2458aa43c215SJeff Kirsher err_out_disable_pdev: 2459aa43c215SJeff Kirsher pci_disable_device(pdev); 2460aa43c215SJeff Kirsher return err; 246166451615SSucheta Chakraborty 246266451615SSucheta Chakraborty err_out_maintenance_mode: 246378ea2d97SSucheta Chakraborty set_bit(__QLCNIC_MAINTENANCE_MODE, &adapter->state); 246466451615SSucheta Chakraborty netdev->netdev_ops = &qlcnic_netdev_failed_ops; 246566451615SSucheta Chakraborty SET_ETHTOOL_OPS(netdev, &qlcnic_ethtool_failed_ops); 246678ea2d97SSucheta Chakraborty ahw->port_type = QLCNIC_XGBE; 246778ea2d97SSucheta Chakraborty 246878ea2d97SSucheta Chakraborty if (qlcnic_83xx_check(adapter)) 246978ea2d97SSucheta Chakraborty adapter->tgt_status_reg = NULL; 247078ea2d97SSucheta Chakraborty else 247178ea2d97SSucheta Chakraborty ahw->board_type = QLCNIC_BRDTYPE_P3P_10G_SFP_PLUS; 247278ea2d97SSucheta Chakraborty 247366451615SSucheta Chakraborty err = register_netdev(netdev); 247466451615SSucheta Chakraborty 247566451615SSucheta Chakraborty if (err) { 247666451615SSucheta Chakraborty dev_err(&pdev->dev, "Failed to register net device\n"); 247766451615SSucheta Chakraborty qlcnic_clr_all_drv_state(adapter, 0); 247866451615SSucheta Chakraborty goto err_out_free_hw; 247966451615SSucheta Chakraborty } 248066451615SSucheta Chakraborty 248166451615SSucheta Chakraborty pci_set_drvdata(pdev, adapter); 248266451615SSucheta Chakraborty qlcnic_add_sysfs(adapter); 248366451615SSucheta Chakraborty 248466451615SSucheta Chakraborty return 0; 2485aa43c215SJeff Kirsher } 2486aa43c215SJeff Kirsher 24876bb58bb0SBill Pemberton static void qlcnic_remove(struct pci_dev *pdev) 2488aa43c215SJeff Kirsher { 2489aa43c215SJeff Kirsher struct qlcnic_adapter *adapter; 2490aa43c215SJeff Kirsher struct net_device *netdev; 249113159183SSony Chacko struct qlcnic_hardware_context *ahw; 2492aa43c215SJeff Kirsher 2493aa43c215SJeff Kirsher adapter = pci_get_drvdata(pdev); 2494aa43c215SJeff Kirsher if (adapter == NULL) 2495aa43c215SJeff Kirsher return; 2496aa43c215SJeff Kirsher 2497aa43c215SJeff Kirsher netdev = adapter->netdev; 249802feda17SRajesh Borundia qlcnic_sriov_pf_disable(adapter); 2499aa43c215SJeff Kirsher 250013159183SSony Chacko qlcnic_cancel_idc_work(adapter); 250113159183SSony Chacko ahw = adapter->ahw; 2502aa43c215SJeff Kirsher 25031de899d3SSucheta Chakraborty qlcnic_dcb_free(adapter->dcb); 250414d385b9SSucheta Chakraborty 2505aa43c215SJeff Kirsher unregister_netdev(netdev); 250602feda17SRajesh Borundia qlcnic_sriov_cleanup(adapter); 2507aa43c215SJeff Kirsher 250813159183SSony Chacko if (qlcnic_83xx_check(adapter)) { 25093d73b5fdSJitendra Kalsaria qlcnic_83xx_register_nic_idc_func(adapter, 0); 25103d73b5fdSJitendra Kalsaria cancel_delayed_work_sync(&adapter->idc_aen_work); 2511068a8d19SManish Chopra qlcnic_83xx_free_mbx_intr(adapter); 2512068a8d19SManish Chopra qlcnic_83xx_detach_mailbox_work(adapter); 2513068a8d19SManish Chopra qlcnic_83xx_free_mailbox(ahw->mailbox); 25147000078aSPratik Pujar kfree(ahw->fw_info); 251513159183SSony Chacko } 251613159183SSony Chacko 2517aa43c215SJeff Kirsher qlcnic_detach(adapter); 2518aa43c215SJeff Kirsher 2519aa43c215SJeff Kirsher if (adapter->npars != NULL) 2520aa43c215SJeff Kirsher kfree(adapter->npars); 2521aa43c215SJeff Kirsher if (adapter->eswitch != NULL) 2522aa43c215SJeff Kirsher kfree(adapter->eswitch); 2523aa43c215SJeff Kirsher 252497ee45ebSSony Chacko if (qlcnic_82xx_check(adapter)) 2525aa43c215SJeff Kirsher qlcnic_clr_all_drv_state(adapter, 0); 2526aa43c215SJeff Kirsher 2527aa43c215SJeff Kirsher clear_bit(__QLCNIC_RESETTING, &adapter->state); 2528aa43c215SJeff Kirsher 2529aa43c215SJeff Kirsher qlcnic_free_lb_filters_mem(adapter); 2530aa43c215SJeff Kirsher 2531aa43c215SJeff Kirsher qlcnic_teardown_intr(adapter); 2532aa43c215SJeff Kirsher 253313159183SSony Chacko qlcnic_remove_sysfs(adapter); 2534aa43c215SJeff Kirsher 2535f1a094a8SRajesh Borundia qlcnic_cleanup_pci_map(adapter->ahw); 2536aa43c215SJeff Kirsher 2537aa43c215SJeff Kirsher qlcnic_release_firmware(adapter); 2538aa43c215SJeff Kirsher 2539aa43c215SJeff Kirsher pci_disable_pcie_error_reporting(pdev); 2540aa43c215SJeff Kirsher pci_release_regions(pdev); 2541aa43c215SJeff Kirsher pci_disable_device(pdev); 2542aa43c215SJeff Kirsher 254313159183SSony Chacko if (adapter->qlcnic_wq) { 254413159183SSony Chacko destroy_workqueue(adapter->qlcnic_wq); 254513159183SSony Chacko adapter->qlcnic_wq = NULL; 254613159183SSony Chacko } 254714d385b9SSucheta Chakraborty 2548aa43c215SJeff Kirsher qlcnic_free_adapter_resources(adapter); 254913159183SSony Chacko kfree(ahw); 2550aa43c215SJeff Kirsher free_netdev(netdev); 2551aa43c215SJeff Kirsher } 2552aa43c215SJeff Kirsher 2553aa43c215SJeff Kirsher static void qlcnic_shutdown(struct pci_dev *pdev) 2554aa43c215SJeff Kirsher { 2555aa43c215SJeff Kirsher if (__qlcnic_shutdown(pdev)) 2556aa43c215SJeff Kirsher return; 2557aa43c215SJeff Kirsher 2558aa43c215SJeff Kirsher pci_disable_device(pdev); 2559aa43c215SJeff Kirsher } 2560aa43c215SJeff Kirsher 2561aa43c215SJeff Kirsher #ifdef CONFIG_PM 2562486a5bc7SRajesh Borundia static int qlcnic_suspend(struct pci_dev *pdev, pm_message_t state) 2563aa43c215SJeff Kirsher { 2564aa43c215SJeff Kirsher int retval; 2565aa43c215SJeff Kirsher 2566aa43c215SJeff Kirsher retval = __qlcnic_shutdown(pdev); 2567aa43c215SJeff Kirsher if (retval) 2568aa43c215SJeff Kirsher return retval; 2569aa43c215SJeff Kirsher 2570aa43c215SJeff Kirsher pci_set_power_state(pdev, pci_choose_state(pdev, state)); 2571aa43c215SJeff Kirsher return 0; 2572aa43c215SJeff Kirsher } 2573aa43c215SJeff Kirsher 2574486a5bc7SRajesh Borundia static int qlcnic_resume(struct pci_dev *pdev) 2575aa43c215SJeff Kirsher { 2576aa43c215SJeff Kirsher struct qlcnic_adapter *adapter = pci_get_drvdata(pdev); 2577aa43c215SJeff Kirsher int err; 2578aa43c215SJeff Kirsher 2579aa43c215SJeff Kirsher err = pci_enable_device(pdev); 2580aa43c215SJeff Kirsher if (err) 2581aa43c215SJeff Kirsher return err; 2582aa43c215SJeff Kirsher 2583aa43c215SJeff Kirsher pci_set_power_state(pdev, PCI_D0); 2584aa43c215SJeff Kirsher pci_set_master(pdev); 2585aa43c215SJeff Kirsher pci_restore_state(pdev); 2586aa43c215SJeff Kirsher 2587486a5bc7SRajesh Borundia return __qlcnic_resume(adapter); 2588aa43c215SJeff Kirsher } 2589aa43c215SJeff Kirsher #endif 2590aa43c215SJeff Kirsher 2591aa43c215SJeff Kirsher static int qlcnic_open(struct net_device *netdev) 2592aa43c215SJeff Kirsher { 2593aa43c215SJeff Kirsher struct qlcnic_adapter *adapter = netdev_priv(netdev); 2594aa43c215SJeff Kirsher int err; 2595aa43c215SJeff Kirsher 259678ea2d97SSucheta Chakraborty if (test_bit(__QLCNIC_MAINTENANCE_MODE, &adapter->state)) { 259778ea2d97SSucheta Chakraborty netdev_err(netdev, "%s: Device is in non-operational state\n", 259878ea2d97SSucheta Chakraborty __func__); 259966451615SSucheta Chakraborty 260066451615SSucheta Chakraborty return -EIO; 260166451615SSucheta Chakraborty } 260266451615SSucheta Chakraborty 2603aa43c215SJeff Kirsher netif_carrier_off(netdev); 2604aa43c215SJeff Kirsher 2605aa43c215SJeff Kirsher err = qlcnic_attach(adapter); 2606aa43c215SJeff Kirsher if (err) 2607aa43c215SJeff Kirsher return err; 2608aa43c215SJeff Kirsher 2609aa43c215SJeff Kirsher err = __qlcnic_up(adapter, netdev); 2610aa43c215SJeff Kirsher if (err) 2611aa43c215SJeff Kirsher goto err_out; 2612aa43c215SJeff Kirsher 2613012ec812SHimanshu Madhani netif_tx_start_all_queues(netdev); 2614aa43c215SJeff Kirsher 2615aa43c215SJeff Kirsher return 0; 2616aa43c215SJeff Kirsher 2617aa43c215SJeff Kirsher err_out: 2618aa43c215SJeff Kirsher qlcnic_detach(adapter); 2619aa43c215SJeff Kirsher return err; 2620aa43c215SJeff Kirsher } 2621aa43c215SJeff Kirsher 2622aa43c215SJeff Kirsher /* 2623aa43c215SJeff Kirsher * qlcnic_close - Disables a network interface entry point 2624aa43c215SJeff Kirsher */ 2625aa43c215SJeff Kirsher static int qlcnic_close(struct net_device *netdev) 2626aa43c215SJeff Kirsher { 2627aa43c215SJeff Kirsher struct qlcnic_adapter *adapter = netdev_priv(netdev); 2628aa43c215SJeff Kirsher 2629aa43c215SJeff Kirsher __qlcnic_down(adapter, netdev); 263013159183SSony Chacko 2631aa43c215SJeff Kirsher return 0; 2632aa43c215SJeff Kirsher } 2633aa43c215SJeff Kirsher 2634aa43c215SJeff Kirsher void qlcnic_alloc_lb_filters_mem(struct qlcnic_adapter *adapter) 2635aa43c215SJeff Kirsher { 2636aa43c215SJeff Kirsher void *head; 2637aa43c215SJeff Kirsher int i; 263813159183SSony Chacko struct net_device *netdev = adapter->netdev; 263913159183SSony Chacko u32 filter_size = 0; 264013159183SSony Chacko u16 act_pci_func = 0; 2641aa43c215SJeff Kirsher 2642aa43c215SJeff Kirsher if (adapter->fhash.fmax && adapter->fhash.fhead) 2643aa43c215SJeff Kirsher return; 2644aa43c215SJeff Kirsher 264513159183SSony Chacko act_pci_func = adapter->ahw->act_pci_func; 2646aa43c215SJeff Kirsher spin_lock_init(&adapter->mac_learn_lock); 264753643a75SShahed Shaikh spin_lock_init(&adapter->rx_mac_learn_lock); 2648aa43c215SJeff Kirsher 264913159183SSony Chacko if (qlcnic_82xx_check(adapter)) { 265013159183SSony Chacko filter_size = QLCNIC_LB_MAX_FILTERS; 265113159183SSony Chacko adapter->fhash.fbucket_size = QLCNIC_LB_BUCKET_SIZE; 265213159183SSony Chacko } else { 265313159183SSony Chacko filter_size = QLC_83XX_LB_MAX_FILTERS; 265413159183SSony Chacko adapter->fhash.fbucket_size = QLC_83XX_LB_BUCKET_SIZE; 265513159183SSony Chacko } 265613159183SSony Chacko 265713159183SSony Chacko head = kcalloc(adapter->fhash.fbucket_size, 26581d9219ddSJitendra Kalsaria sizeof(struct hlist_head), GFP_ATOMIC); 265913159183SSony Chacko 2660aa43c215SJeff Kirsher if (!head) 2661aa43c215SJeff Kirsher return; 2662aa43c215SJeff Kirsher 266313159183SSony Chacko adapter->fhash.fmax = (filter_size / act_pci_func); 2664aa43c215SJeff Kirsher adapter->fhash.fhead = head; 2665aa43c215SJeff Kirsher 266613159183SSony Chacko netdev_info(netdev, "active nic func = %d, mac filter size=%d\n", 266713159183SSony Chacko act_pci_func, adapter->fhash.fmax); 266813159183SSony Chacko 266913159183SSony Chacko for (i = 0; i < adapter->fhash.fbucket_size; i++) 2670aa43c215SJeff Kirsher INIT_HLIST_HEAD(&adapter->fhash.fhead[i]); 267153643a75SShahed Shaikh 267253643a75SShahed Shaikh adapter->rx_fhash.fbucket_size = adapter->fhash.fbucket_size; 267353643a75SShahed Shaikh 267453643a75SShahed Shaikh head = kcalloc(adapter->rx_fhash.fbucket_size, 267553643a75SShahed Shaikh sizeof(struct hlist_head), GFP_ATOMIC); 267653643a75SShahed Shaikh 267753643a75SShahed Shaikh if (!head) 267853643a75SShahed Shaikh return; 267953643a75SShahed Shaikh 268053643a75SShahed Shaikh adapter->rx_fhash.fmax = (filter_size / act_pci_func); 268153643a75SShahed Shaikh adapter->rx_fhash.fhead = head; 268253643a75SShahed Shaikh 268353643a75SShahed Shaikh for (i = 0; i < adapter->rx_fhash.fbucket_size; i++) 268453643a75SShahed Shaikh INIT_HLIST_HEAD(&adapter->rx_fhash.fhead[i]); 2685aa43c215SJeff Kirsher } 2686aa43c215SJeff Kirsher 2687aa43c215SJeff Kirsher static void qlcnic_free_lb_filters_mem(struct qlcnic_adapter *adapter) 2688aa43c215SJeff Kirsher { 2689aa43c215SJeff Kirsher if (adapter->fhash.fmax && adapter->fhash.fhead) 2690aa43c215SJeff Kirsher kfree(adapter->fhash.fhead); 2691aa43c215SJeff Kirsher 2692aa43c215SJeff Kirsher adapter->fhash.fhead = NULL; 2693aa43c215SJeff Kirsher adapter->fhash.fmax = 0; 269453643a75SShahed Shaikh 269553643a75SShahed Shaikh if (adapter->rx_fhash.fmax && adapter->rx_fhash.fhead) 269653643a75SShahed Shaikh kfree(adapter->rx_fhash.fhead); 269753643a75SShahed Shaikh 269853643a75SShahed Shaikh adapter->rx_fhash.fmax = 0; 269953643a75SShahed Shaikh adapter->rx_fhash.fhead = NULL; 2700aa43c215SJeff Kirsher } 2701aa43c215SJeff Kirsher 2702629263acSSony Chacko int qlcnic_check_temp(struct qlcnic_adapter *adapter) 2703aa43c215SJeff Kirsher { 2704aa43c215SJeff Kirsher struct net_device *netdev = adapter->netdev; 270597ee45ebSSony Chacko u32 temp_state, temp_val, temp = 0; 2706aa43c215SJeff Kirsher int rv = 0; 2707aa43c215SJeff Kirsher 270813159183SSony Chacko if (qlcnic_83xx_check(adapter)) 270913159183SSony Chacko temp = QLCRDX(adapter->ahw, QLC_83XX_ASIC_TEMP); 271013159183SSony Chacko 271197ee45ebSSony Chacko if (qlcnic_82xx_check(adapter)) 2712a15ebd37SHimanshu Madhani temp = QLC_SHARED_REG_RD32(adapter, QLCNIC_ASIC_TEMP); 2713aa43c215SJeff Kirsher 2714aa43c215SJeff Kirsher temp_state = qlcnic_get_temp_state(temp); 2715aa43c215SJeff Kirsher temp_val = qlcnic_get_temp_val(temp); 2716aa43c215SJeff Kirsher 2717aa43c215SJeff Kirsher if (temp_state == QLCNIC_TEMP_PANIC) { 2718aa43c215SJeff Kirsher dev_err(&netdev->dev, 2719aa43c215SJeff Kirsher "Device temperature %d degrees C exceeds" 2720aa43c215SJeff Kirsher " maximum allowed. Hardware has been shut down.\n", 2721aa43c215SJeff Kirsher temp_val); 2722aa43c215SJeff Kirsher rv = 1; 2723aa43c215SJeff Kirsher } else if (temp_state == QLCNIC_TEMP_WARN) { 272479788450SSony Chacko if (adapter->ahw->temp == QLCNIC_TEMP_NORMAL) { 2725aa43c215SJeff Kirsher dev_err(&netdev->dev, 2726aa43c215SJeff Kirsher "Device temperature %d degrees C " 2727aa43c215SJeff Kirsher "exceeds operating range." 2728aa43c215SJeff Kirsher " Immediate action needed.\n", 2729aa43c215SJeff Kirsher temp_val); 2730aa43c215SJeff Kirsher } 2731aa43c215SJeff Kirsher } else { 273279788450SSony Chacko if (adapter->ahw->temp == QLCNIC_TEMP_WARN) { 2733aa43c215SJeff Kirsher dev_info(&netdev->dev, 2734aa43c215SJeff Kirsher "Device temperature is now %d degrees C" 2735aa43c215SJeff Kirsher " in normal range.\n", temp_val); 2736aa43c215SJeff Kirsher } 2737aa43c215SJeff Kirsher } 273879788450SSony Chacko adapter->ahw->temp = temp_state; 2739aa43c215SJeff Kirsher return rv; 2740aa43c215SJeff Kirsher } 2741aa43c215SJeff Kirsher 2742aa43c215SJeff Kirsher static void qlcnic_tx_timeout(struct net_device *netdev) 2743aa43c215SJeff Kirsher { 2744aa43c215SJeff Kirsher struct qlcnic_adapter *adapter = netdev_priv(netdev); 2745012ec812SHimanshu Madhani struct qlcnic_host_tx_ring *tx_ring; 2746012ec812SHimanshu Madhani int ring; 2747aa43c215SJeff Kirsher 2748aa43c215SJeff Kirsher if (test_bit(__QLCNIC_RESETTING, &adapter->state)) 2749aa43c215SJeff Kirsher return; 2750aa43c215SJeff Kirsher 2751536faa61SSony Chacko if (++adapter->tx_timeo_cnt >= QLCNIC_MAX_TX_TIMEOUTS) { 2752536faa61SSony Chacko netdev_info(netdev, "Tx timeout, reset the adapter.\n"); 2753536faa61SSony Chacko if (qlcnic_82xx_check(adapter)) 2754aa43c215SJeff Kirsher adapter->need_fw_reset = 1; 2755536faa61SSony Chacko else if (qlcnic_83xx_check(adapter)) 2756536faa61SSony Chacko qlcnic_83xx_idc_request_reset(adapter, 2757536faa61SSony Chacko QLCNIC_FORCE_FW_DUMP_KEY); 2758536faa61SSony Chacko } else { 2759536faa61SSony Chacko netdev_info(netdev, "Tx timeout, reset adapter context.\n"); 276034e8c406SHimanshu Madhani for (ring = 0; ring < adapter->drv_tx_rings; ring++) { 2761012ec812SHimanshu Madhani tx_ring = &adapter->tx_ring[ring]; 2762f27c75b3SHimanshu Madhani netdev_info(netdev, "Tx ring=%d\n", ring); 2763f27c75b3SHimanshu Madhani netdev_info(netdev, 2764f27c75b3SHimanshu Madhani "crb_intr_mask=%d, producer=%d, sw_consumer=%d, hw_consumer=%d\n", 2765f27c75b3SHimanshu Madhani readl(tx_ring->crb_intr_mask), 2766f27c75b3SHimanshu Madhani readl(tx_ring->crb_cmd_producer), 2767f27c75b3SHimanshu Madhani tx_ring->sw_consumer, 2768012ec812SHimanshu Madhani le32_to_cpu(*(tx_ring->hw_consumer))); 2769f27c75b3SHimanshu Madhani netdev_info(netdev, 2770f27c75b3SHimanshu Madhani "xmit_finished=%llu, xmit_called=%llu, xmit_on=%llu, xmit_off=%llu\n", 2771f27c75b3SHimanshu Madhani tx_ring->tx_stats.xmit_finished, 2772f27c75b3SHimanshu Madhani tx_ring->tx_stats.xmit_called, 2773f27c75b3SHimanshu Madhani tx_ring->tx_stats.xmit_on, 2774f27c75b3SHimanshu Madhani tx_ring->tx_stats.xmit_off); 2775012ec812SHimanshu Madhani } 277679788450SSony Chacko adapter->ahw->reset_context = 1; 2777aa43c215SJeff Kirsher } 2778536faa61SSony Chacko } 2779aa43c215SJeff Kirsher 2780aa43c215SJeff Kirsher static struct net_device_stats *qlcnic_get_stats(struct net_device *netdev) 2781aa43c215SJeff Kirsher { 2782aa43c215SJeff Kirsher struct qlcnic_adapter *adapter = netdev_priv(netdev); 2783aa43c215SJeff Kirsher struct net_device_stats *stats = &netdev->stats; 2784aa43c215SJeff Kirsher 2785aa43c215SJeff Kirsher stats->rx_packets = adapter->stats.rx_pkts + adapter->stats.lro_pkts; 2786aa43c215SJeff Kirsher stats->tx_packets = adapter->stats.xmitfinished; 2787aa43c215SJeff Kirsher stats->rx_bytes = adapter->stats.rxbytes + adapter->stats.lrobytes; 2788aa43c215SJeff Kirsher stats->tx_bytes = adapter->stats.txbytes; 2789aa43c215SJeff Kirsher stats->rx_dropped = adapter->stats.rxdropped; 2790aa43c215SJeff Kirsher stats->tx_dropped = adapter->stats.txdropped; 2791aa43c215SJeff Kirsher 2792aa43c215SJeff Kirsher return stats; 2793aa43c215SJeff Kirsher } 2794aa43c215SJeff Kirsher 27957e2cf4feSSony Chacko irqreturn_t qlcnic_82xx_clear_legacy_intr(struct qlcnic_adapter *adapter) 2796aa43c215SJeff Kirsher { 2797aa43c215SJeff Kirsher u32 status; 2798aa43c215SJeff Kirsher 2799aa43c215SJeff Kirsher status = readl(adapter->isr_int_vec); 2800aa43c215SJeff Kirsher 280179788450SSony Chacko if (!(status & adapter->ahw->int_vec_bit)) 2802aa43c215SJeff Kirsher return IRQ_NONE; 2803aa43c215SJeff Kirsher 2804aa43c215SJeff Kirsher /* check interrupt state machine, to be sure */ 2805aa43c215SJeff Kirsher status = readl(adapter->crb_int_state_reg); 2806aa43c215SJeff Kirsher if (!ISR_LEGACY_INT_TRIGGERED(status)) 2807aa43c215SJeff Kirsher return IRQ_NONE; 2808aa43c215SJeff Kirsher 2809aa43c215SJeff Kirsher writel(0xffffffff, adapter->tgt_status_reg); 2810aa43c215SJeff Kirsher /* read twice to ensure write is flushed */ 2811aa43c215SJeff Kirsher readl(adapter->isr_int_vec); 2812aa43c215SJeff Kirsher readl(adapter->isr_int_vec); 2813aa43c215SJeff Kirsher 2814aa43c215SJeff Kirsher return IRQ_HANDLED; 2815aa43c215SJeff Kirsher } 2816aa43c215SJeff Kirsher 2817aa43c215SJeff Kirsher static irqreturn_t qlcnic_tmp_intr(int irq, void *data) 2818aa43c215SJeff Kirsher { 2819aa43c215SJeff Kirsher struct qlcnic_host_sds_ring *sds_ring = data; 2820aa43c215SJeff Kirsher struct qlcnic_adapter *adapter = sds_ring->adapter; 2821aa43c215SJeff Kirsher 2822aa43c215SJeff Kirsher if (adapter->flags & QLCNIC_MSIX_ENABLED) 2823aa43c215SJeff Kirsher goto done; 2824aa43c215SJeff Kirsher else if (adapter->flags & QLCNIC_MSI_ENABLED) { 2825aa43c215SJeff Kirsher writel(0xffffffff, adapter->tgt_status_reg); 2826aa43c215SJeff Kirsher goto done; 2827aa43c215SJeff Kirsher } 2828aa43c215SJeff Kirsher 2829aa43c215SJeff Kirsher if (qlcnic_clear_legacy_intr(adapter) == IRQ_NONE) 2830aa43c215SJeff Kirsher return IRQ_NONE; 2831aa43c215SJeff Kirsher 2832aa43c215SJeff Kirsher done: 283379788450SSony Chacko adapter->ahw->diag_cnt++; 2834aa43c215SJeff Kirsher qlcnic_enable_int(sds_ring); 2835aa43c215SJeff Kirsher return IRQ_HANDLED; 2836aa43c215SJeff Kirsher } 2837aa43c215SJeff Kirsher 2838aa43c215SJeff Kirsher static irqreturn_t qlcnic_intr(int irq, void *data) 2839aa43c215SJeff Kirsher { 2840aa43c215SJeff Kirsher struct qlcnic_host_sds_ring *sds_ring = data; 2841aa43c215SJeff Kirsher struct qlcnic_adapter *adapter = sds_ring->adapter; 2842aa43c215SJeff Kirsher 2843aa43c215SJeff Kirsher if (qlcnic_clear_legacy_intr(adapter) == IRQ_NONE) 2844aa43c215SJeff Kirsher return IRQ_NONE; 2845aa43c215SJeff Kirsher 2846aa43c215SJeff Kirsher napi_schedule(&sds_ring->napi); 2847aa43c215SJeff Kirsher 2848aa43c215SJeff Kirsher return IRQ_HANDLED; 2849aa43c215SJeff Kirsher } 2850aa43c215SJeff Kirsher 2851aa43c215SJeff Kirsher static irqreturn_t qlcnic_msi_intr(int irq, void *data) 2852aa43c215SJeff Kirsher { 2853aa43c215SJeff Kirsher struct qlcnic_host_sds_ring *sds_ring = data; 2854aa43c215SJeff Kirsher struct qlcnic_adapter *adapter = sds_ring->adapter; 2855aa43c215SJeff Kirsher 2856aa43c215SJeff Kirsher /* clear interrupt */ 2857aa43c215SJeff Kirsher writel(0xffffffff, adapter->tgt_status_reg); 2858aa43c215SJeff Kirsher 2859aa43c215SJeff Kirsher napi_schedule(&sds_ring->napi); 2860aa43c215SJeff Kirsher return IRQ_HANDLED; 2861aa43c215SJeff Kirsher } 2862aa43c215SJeff Kirsher 2863aa43c215SJeff Kirsher static irqreturn_t qlcnic_msix_intr(int irq, void *data) 2864aa43c215SJeff Kirsher { 2865aa43c215SJeff Kirsher struct qlcnic_host_sds_ring *sds_ring = data; 2866aa43c215SJeff Kirsher 2867aa43c215SJeff Kirsher napi_schedule(&sds_ring->napi); 2868aa43c215SJeff Kirsher return IRQ_HANDLED; 2869aa43c215SJeff Kirsher } 2870aa43c215SJeff Kirsher 287113159183SSony Chacko static irqreturn_t qlcnic_msix_tx_intr(int irq, void *data) 287213159183SSony Chacko { 287313159183SSony Chacko struct qlcnic_host_tx_ring *tx_ring = data; 287413159183SSony Chacko 287513159183SSony Chacko napi_schedule(&tx_ring->napi); 287613159183SSony Chacko return IRQ_HANDLED; 287713159183SSony Chacko } 287813159183SSony Chacko 2879aa43c215SJeff Kirsher #ifdef CONFIG_NET_POLL_CONTROLLER 2880aa43c215SJeff Kirsher static void qlcnic_poll_controller(struct net_device *netdev) 2881aa43c215SJeff Kirsher { 2882aa43c215SJeff Kirsher int ring; 2883aa43c215SJeff Kirsher struct qlcnic_host_sds_ring *sds_ring; 2884aa43c215SJeff Kirsher struct qlcnic_adapter *adapter = netdev_priv(netdev); 2885aa43c215SJeff Kirsher struct qlcnic_recv_context *recv_ctx = adapter->recv_ctx; 2886aa43c215SJeff Kirsher 2887aa43c215SJeff Kirsher disable_irq(adapter->irq); 288834e8c406SHimanshu Madhani for (ring = 0; ring < adapter->drv_sds_rings; ring++) { 2889aa43c215SJeff Kirsher sds_ring = &recv_ctx->sds_rings[ring]; 2890aa43c215SJeff Kirsher qlcnic_intr(adapter->irq, sds_ring); 2891aa43c215SJeff Kirsher } 2892aa43c215SJeff Kirsher enable_irq(adapter->irq); 2893aa43c215SJeff Kirsher } 2894aa43c215SJeff Kirsher #endif 2895aa43c215SJeff Kirsher 2896aa43c215SJeff Kirsher static void 2897aa43c215SJeff Kirsher qlcnic_idc_debug_info(struct qlcnic_adapter *adapter, u8 encoding) 2898aa43c215SJeff Kirsher { 2899aa43c215SJeff Kirsher u32 val; 2900aa43c215SJeff Kirsher 2901aa43c215SJeff Kirsher val = adapter->portnum & 0xf; 2902aa43c215SJeff Kirsher val |= encoding << 7; 2903aa43c215SJeff Kirsher val |= (jiffies - adapter->dev_rst_time) << 8; 2904aa43c215SJeff Kirsher 2905a15ebd37SHimanshu Madhani QLC_SHARED_REG_WR32(adapter, QLCNIC_CRB_DRV_SCRATCH, val); 2906aa43c215SJeff Kirsher adapter->dev_rst_time = jiffies; 2907aa43c215SJeff Kirsher } 2908aa43c215SJeff Kirsher 2909aa43c215SJeff Kirsher static int 2910aa43c215SJeff Kirsher qlcnic_set_drv_state(struct qlcnic_adapter *adapter, u8 state) 2911aa43c215SJeff Kirsher { 2912aa43c215SJeff Kirsher u32 val; 2913aa43c215SJeff Kirsher 2914aa43c215SJeff Kirsher WARN_ON(state != QLCNIC_DEV_NEED_RESET && 2915aa43c215SJeff Kirsher state != QLCNIC_DEV_NEED_QUISCENT); 2916aa43c215SJeff Kirsher 2917aa43c215SJeff Kirsher if (qlcnic_api_lock(adapter)) 2918aa43c215SJeff Kirsher return -EIO; 2919aa43c215SJeff Kirsher 2920a15ebd37SHimanshu Madhani val = QLC_SHARED_REG_RD32(adapter, QLCNIC_CRB_DRV_STATE); 2921aa43c215SJeff Kirsher 2922aa43c215SJeff Kirsher if (state == QLCNIC_DEV_NEED_RESET) 2923aa43c215SJeff Kirsher QLC_DEV_SET_RST_RDY(val, adapter->portnum); 2924aa43c215SJeff Kirsher else if (state == QLCNIC_DEV_NEED_QUISCENT) 2925aa43c215SJeff Kirsher QLC_DEV_SET_QSCNT_RDY(val, adapter->portnum); 2926aa43c215SJeff Kirsher 2927a15ebd37SHimanshu Madhani QLC_SHARED_REG_WR32(adapter, QLCNIC_CRB_DRV_STATE, val); 2928aa43c215SJeff Kirsher 2929aa43c215SJeff Kirsher qlcnic_api_unlock(adapter); 2930aa43c215SJeff Kirsher 2931aa43c215SJeff Kirsher return 0; 2932aa43c215SJeff Kirsher } 2933aa43c215SJeff Kirsher 2934aa43c215SJeff Kirsher static int 2935aa43c215SJeff Kirsher qlcnic_clr_drv_state(struct qlcnic_adapter *adapter) 2936aa43c215SJeff Kirsher { 2937aa43c215SJeff Kirsher u32 val; 2938aa43c215SJeff Kirsher 2939aa43c215SJeff Kirsher if (qlcnic_api_lock(adapter)) 2940aa43c215SJeff Kirsher return -EBUSY; 2941aa43c215SJeff Kirsher 2942a15ebd37SHimanshu Madhani val = QLC_SHARED_REG_RD32(adapter, QLCNIC_CRB_DRV_STATE); 2943aa43c215SJeff Kirsher QLC_DEV_CLR_RST_QSCNT(val, adapter->portnum); 2944a15ebd37SHimanshu Madhani QLC_SHARED_REG_WR32(adapter, QLCNIC_CRB_DRV_STATE, val); 2945aa43c215SJeff Kirsher 2946aa43c215SJeff Kirsher qlcnic_api_unlock(adapter); 2947aa43c215SJeff Kirsher 2948aa43c215SJeff Kirsher return 0; 2949aa43c215SJeff Kirsher } 2950aa43c215SJeff Kirsher 2951486a5bc7SRajesh Borundia void qlcnic_clr_all_drv_state(struct qlcnic_adapter *adapter, u8 failed) 2952aa43c215SJeff Kirsher { 2953aa43c215SJeff Kirsher u32 val; 2954aa43c215SJeff Kirsher 2955aa43c215SJeff Kirsher if (qlcnic_api_lock(adapter)) 2956aa43c215SJeff Kirsher goto err; 2957aa43c215SJeff Kirsher 2958a15ebd37SHimanshu Madhani val = QLC_SHARED_REG_RD32(adapter, QLCNIC_CRB_DRV_ACTIVE); 2959aa43c215SJeff Kirsher QLC_DEV_CLR_REF_CNT(val, adapter->portnum); 2960a15ebd37SHimanshu Madhani QLC_SHARED_REG_WR32(adapter, QLCNIC_CRB_DRV_ACTIVE, val); 2961aa43c215SJeff Kirsher 2962aa43c215SJeff Kirsher if (failed) { 2963a15ebd37SHimanshu Madhani QLC_SHARED_REG_WR32(adapter, QLCNIC_CRB_DEV_STATE, 2964a15ebd37SHimanshu Madhani QLCNIC_DEV_FAILED); 2965aa43c215SJeff Kirsher dev_info(&adapter->pdev->dev, 2966aa43c215SJeff Kirsher "Device state set to Failed. Please Reboot\n"); 2967aa43c215SJeff Kirsher } else if (!(val & 0x11111111)) 2968a15ebd37SHimanshu Madhani QLC_SHARED_REG_WR32(adapter, QLCNIC_CRB_DEV_STATE, 2969a15ebd37SHimanshu Madhani QLCNIC_DEV_COLD); 2970aa43c215SJeff Kirsher 2971a15ebd37SHimanshu Madhani val = QLC_SHARED_REG_RD32(adapter, QLCNIC_CRB_DRV_STATE); 2972aa43c215SJeff Kirsher QLC_DEV_CLR_RST_QSCNT(val, adapter->portnum); 2973a15ebd37SHimanshu Madhani QLC_SHARED_REG_WR32(adapter, QLCNIC_CRB_DRV_STATE, val); 2974aa43c215SJeff Kirsher 2975aa43c215SJeff Kirsher qlcnic_api_unlock(adapter); 2976aa43c215SJeff Kirsher err: 2977aa43c215SJeff Kirsher adapter->fw_fail_cnt = 0; 2978aa43c215SJeff Kirsher adapter->flags &= ~QLCNIC_FW_HANG; 2979aa43c215SJeff Kirsher clear_bit(__QLCNIC_START_FW, &adapter->state); 2980aa43c215SJeff Kirsher clear_bit(__QLCNIC_RESETTING, &adapter->state); 2981aa43c215SJeff Kirsher } 2982aa43c215SJeff Kirsher 2983aa43c215SJeff Kirsher /* Grab api lock, before checking state */ 2984aa43c215SJeff Kirsher static int 2985aa43c215SJeff Kirsher qlcnic_check_drv_state(struct qlcnic_adapter *adapter) 2986aa43c215SJeff Kirsher { 2987aa43c215SJeff Kirsher int act, state, active_mask; 2988a15ebd37SHimanshu Madhani struct qlcnic_hardware_context *ahw = adapter->ahw; 2989aa43c215SJeff Kirsher 2990a15ebd37SHimanshu Madhani state = QLC_SHARED_REG_RD32(adapter, QLCNIC_CRB_DRV_STATE); 2991a15ebd37SHimanshu Madhani act = QLC_SHARED_REG_RD32(adapter, QLCNIC_CRB_DRV_ACTIVE); 2992aa43c215SJeff Kirsher 2993aa43c215SJeff Kirsher if (adapter->flags & QLCNIC_FW_RESET_OWNER) { 2994a15ebd37SHimanshu Madhani active_mask = (~(1 << (ahw->pci_func * 4))); 2995aa43c215SJeff Kirsher act = act & active_mask; 2996aa43c215SJeff Kirsher } 2997aa43c215SJeff Kirsher 2998aa43c215SJeff Kirsher if (((state & 0x11111111) == (act & 0x11111111)) || 2999aa43c215SJeff Kirsher ((act & 0x11111111) == ((state >> 1) & 0x11111111))) 3000aa43c215SJeff Kirsher return 0; 3001aa43c215SJeff Kirsher else 3002aa43c215SJeff Kirsher return 1; 3003aa43c215SJeff Kirsher } 3004aa43c215SJeff Kirsher 3005aa43c215SJeff Kirsher static int qlcnic_check_idc_ver(struct qlcnic_adapter *adapter) 3006aa43c215SJeff Kirsher { 3007a15ebd37SHimanshu Madhani u32 val = QLC_SHARED_REG_RD32(adapter, QLCNIC_CRB_DRV_IDC_VER); 3008aa43c215SJeff Kirsher 3009aa43c215SJeff Kirsher if (val != QLCNIC_DRV_IDC_VER) { 3010aa43c215SJeff Kirsher dev_warn(&adapter->pdev->dev, "IDC Version mismatch, driver's" 3011aa43c215SJeff Kirsher " idc ver = %x; reqd = %x\n", QLCNIC_DRV_IDC_VER, val); 3012aa43c215SJeff Kirsher } 3013aa43c215SJeff Kirsher 3014aa43c215SJeff Kirsher return 0; 3015aa43c215SJeff Kirsher } 3016aa43c215SJeff Kirsher 3017aa43c215SJeff Kirsher static int 3018aa43c215SJeff Kirsher qlcnic_can_start_firmware(struct qlcnic_adapter *adapter) 3019aa43c215SJeff Kirsher { 3020aa43c215SJeff Kirsher u32 val, prev_state; 3021aa43c215SJeff Kirsher u8 dev_init_timeo = adapter->dev_init_timeo; 3022aa43c215SJeff Kirsher u8 portnum = adapter->portnum; 3023aa43c215SJeff Kirsher u8 ret; 3024aa43c215SJeff Kirsher 3025aa43c215SJeff Kirsher if (test_and_clear_bit(__QLCNIC_START_FW, &adapter->state)) 3026aa43c215SJeff Kirsher return 1; 3027aa43c215SJeff Kirsher 3028aa43c215SJeff Kirsher if (qlcnic_api_lock(adapter)) 3029aa43c215SJeff Kirsher return -1; 3030aa43c215SJeff Kirsher 3031a15ebd37SHimanshu Madhani val = QLC_SHARED_REG_RD32(adapter, QLCNIC_CRB_DRV_ACTIVE); 3032aa43c215SJeff Kirsher if (!(val & (1 << (portnum * 4)))) { 3033aa43c215SJeff Kirsher QLC_DEV_SET_REF_CNT(val, portnum); 3034a15ebd37SHimanshu Madhani QLC_SHARED_REG_WR32(adapter, QLCNIC_CRB_DRV_ACTIVE, val); 3035aa43c215SJeff Kirsher } 3036aa43c215SJeff Kirsher 3037a15ebd37SHimanshu Madhani prev_state = QLC_SHARED_REG_RD32(adapter, QLCNIC_CRB_DEV_STATE); 3038aa43c215SJeff Kirsher QLCDB(adapter, HW, "Device state = %u\n", prev_state); 3039aa43c215SJeff Kirsher 3040aa43c215SJeff Kirsher switch (prev_state) { 3041aa43c215SJeff Kirsher case QLCNIC_DEV_COLD: 3042a15ebd37SHimanshu Madhani QLC_SHARED_REG_WR32(adapter, QLCNIC_CRB_DEV_STATE, 3043a15ebd37SHimanshu Madhani QLCNIC_DEV_INITIALIZING); 3044a15ebd37SHimanshu Madhani QLC_SHARED_REG_WR32(adapter, QLCNIC_CRB_DRV_IDC_VER, 3045a15ebd37SHimanshu Madhani QLCNIC_DRV_IDC_VER); 3046aa43c215SJeff Kirsher qlcnic_idc_debug_info(adapter, 0); 3047aa43c215SJeff Kirsher qlcnic_api_unlock(adapter); 3048aa43c215SJeff Kirsher return 1; 3049aa43c215SJeff Kirsher 3050aa43c215SJeff Kirsher case QLCNIC_DEV_READY: 3051aa43c215SJeff Kirsher ret = qlcnic_check_idc_ver(adapter); 3052aa43c215SJeff Kirsher qlcnic_api_unlock(adapter); 3053aa43c215SJeff Kirsher return ret; 3054aa43c215SJeff Kirsher 3055aa43c215SJeff Kirsher case QLCNIC_DEV_NEED_RESET: 3056a15ebd37SHimanshu Madhani val = QLC_SHARED_REG_RD32(adapter, QLCNIC_CRB_DRV_STATE); 3057aa43c215SJeff Kirsher QLC_DEV_SET_RST_RDY(val, portnum); 3058a15ebd37SHimanshu Madhani QLC_SHARED_REG_WR32(adapter, QLCNIC_CRB_DRV_STATE, val); 3059aa43c215SJeff Kirsher break; 3060aa43c215SJeff Kirsher 3061aa43c215SJeff Kirsher case QLCNIC_DEV_NEED_QUISCENT: 3062a15ebd37SHimanshu Madhani val = QLC_SHARED_REG_RD32(adapter, QLCNIC_CRB_DRV_STATE); 3063aa43c215SJeff Kirsher QLC_DEV_SET_QSCNT_RDY(val, portnum); 3064a15ebd37SHimanshu Madhani QLC_SHARED_REG_WR32(adapter, QLCNIC_CRB_DRV_STATE, val); 3065aa43c215SJeff Kirsher break; 3066aa43c215SJeff Kirsher 3067aa43c215SJeff Kirsher case QLCNIC_DEV_FAILED: 3068aa43c215SJeff Kirsher dev_err(&adapter->pdev->dev, "Device in failed state.\n"); 3069aa43c215SJeff Kirsher qlcnic_api_unlock(adapter); 3070aa43c215SJeff Kirsher return -1; 3071aa43c215SJeff Kirsher 3072aa43c215SJeff Kirsher case QLCNIC_DEV_INITIALIZING: 3073aa43c215SJeff Kirsher case QLCNIC_DEV_QUISCENT: 3074aa43c215SJeff Kirsher break; 3075aa43c215SJeff Kirsher } 3076aa43c215SJeff Kirsher 3077aa43c215SJeff Kirsher qlcnic_api_unlock(adapter); 3078aa43c215SJeff Kirsher 3079aa43c215SJeff Kirsher do { 3080aa43c215SJeff Kirsher msleep(1000); 3081a15ebd37SHimanshu Madhani prev_state = QLC_SHARED_REG_RD32(adapter, QLCNIC_CRB_DEV_STATE); 3082aa43c215SJeff Kirsher 3083aa43c215SJeff Kirsher if (prev_state == QLCNIC_DEV_QUISCENT) 3084aa43c215SJeff Kirsher continue; 3085aa43c215SJeff Kirsher } while ((prev_state != QLCNIC_DEV_READY) && --dev_init_timeo); 3086aa43c215SJeff Kirsher 3087aa43c215SJeff Kirsher if (!dev_init_timeo) { 3088aa43c215SJeff Kirsher dev_err(&adapter->pdev->dev, 3089aa43c215SJeff Kirsher "Waiting for device to initialize timeout\n"); 3090aa43c215SJeff Kirsher return -1; 3091aa43c215SJeff Kirsher } 3092aa43c215SJeff Kirsher 3093aa43c215SJeff Kirsher if (qlcnic_api_lock(adapter)) 3094aa43c215SJeff Kirsher return -1; 3095aa43c215SJeff Kirsher 3096a15ebd37SHimanshu Madhani val = QLC_SHARED_REG_RD32(adapter, QLCNIC_CRB_DRV_STATE); 3097aa43c215SJeff Kirsher QLC_DEV_CLR_RST_QSCNT(val, portnum); 3098a15ebd37SHimanshu Madhani QLC_SHARED_REG_WR32(adapter, QLCNIC_CRB_DRV_STATE, val); 3099aa43c215SJeff Kirsher 3100aa43c215SJeff Kirsher ret = qlcnic_check_idc_ver(adapter); 3101aa43c215SJeff Kirsher qlcnic_api_unlock(adapter); 3102aa43c215SJeff Kirsher 3103aa43c215SJeff Kirsher return ret; 3104aa43c215SJeff Kirsher } 3105aa43c215SJeff Kirsher 3106aa43c215SJeff Kirsher static void 3107aa43c215SJeff Kirsher qlcnic_fwinit_work(struct work_struct *work) 3108aa43c215SJeff Kirsher { 3109aa43c215SJeff Kirsher struct qlcnic_adapter *adapter = container_of(work, 3110aa43c215SJeff Kirsher struct qlcnic_adapter, fw_work.work); 3111aa43c215SJeff Kirsher u32 dev_state = 0xf; 3112aa43c215SJeff Kirsher u32 val; 3113aa43c215SJeff Kirsher 3114aa43c215SJeff Kirsher if (qlcnic_api_lock(adapter)) 3115aa43c215SJeff Kirsher goto err_ret; 3116aa43c215SJeff Kirsher 3117a15ebd37SHimanshu Madhani dev_state = QLC_SHARED_REG_RD32(adapter, QLCNIC_CRB_DEV_STATE); 3118aa43c215SJeff Kirsher if (dev_state == QLCNIC_DEV_QUISCENT || 3119aa43c215SJeff Kirsher dev_state == QLCNIC_DEV_NEED_QUISCENT) { 3120aa43c215SJeff Kirsher qlcnic_api_unlock(adapter); 3121aa43c215SJeff Kirsher qlcnic_schedule_work(adapter, qlcnic_fwinit_work, 3122aa43c215SJeff Kirsher FW_POLL_DELAY * 2); 3123aa43c215SJeff Kirsher return; 3124aa43c215SJeff Kirsher } 3125aa43c215SJeff Kirsher 312679788450SSony Chacko if (adapter->ahw->op_mode == QLCNIC_NON_PRIV_FUNC) { 3127aa43c215SJeff Kirsher qlcnic_api_unlock(adapter); 3128aa43c215SJeff Kirsher goto wait_npar; 3129aa43c215SJeff Kirsher } 3130aa43c215SJeff Kirsher 313116e3cf73SSritej Velaga if (dev_state == QLCNIC_DEV_INITIALIZING || 313216e3cf73SSritej Velaga dev_state == QLCNIC_DEV_READY) { 313316e3cf73SSritej Velaga dev_info(&adapter->pdev->dev, "Detected state change from " 313416e3cf73SSritej Velaga "DEV_NEED_RESET, skipping ack check\n"); 313516e3cf73SSritej Velaga goto skip_ack_check; 313616e3cf73SSritej Velaga } 313716e3cf73SSritej Velaga 3138aa43c215SJeff Kirsher if (adapter->fw_wait_cnt++ > adapter->reset_ack_timeo) { 313916e3cf73SSritej Velaga dev_info(&adapter->pdev->dev, "Reset:Failed to get ack %d sec\n", 3140aa43c215SJeff Kirsher adapter->reset_ack_timeo); 3141aa43c215SJeff Kirsher goto skip_ack_check; 3142aa43c215SJeff Kirsher } 3143aa43c215SJeff Kirsher 3144aa43c215SJeff Kirsher if (!qlcnic_check_drv_state(adapter)) { 3145aa43c215SJeff Kirsher skip_ack_check: 3146a15ebd37SHimanshu Madhani dev_state = QLC_SHARED_REG_RD32(adapter, QLCNIC_CRB_DEV_STATE); 3147aa43c215SJeff Kirsher 3148aa43c215SJeff Kirsher if (dev_state == QLCNIC_DEV_NEED_RESET) { 3149a15ebd37SHimanshu Madhani QLC_SHARED_REG_WR32(adapter, QLCNIC_CRB_DEV_STATE, 3150aa43c215SJeff Kirsher QLCNIC_DEV_INITIALIZING); 3151aa43c215SJeff Kirsher set_bit(__QLCNIC_START_FW, &adapter->state); 3152aa43c215SJeff Kirsher QLCDB(adapter, DRV, "Restarting fw\n"); 3153aa43c215SJeff Kirsher qlcnic_idc_debug_info(adapter, 0); 3154a15ebd37SHimanshu Madhani val = QLC_SHARED_REG_RD32(adapter, 3155a15ebd37SHimanshu Madhani QLCNIC_CRB_DRV_STATE); 3156aa43c215SJeff Kirsher QLC_DEV_SET_RST_RDY(val, adapter->portnum); 3157a15ebd37SHimanshu Madhani QLC_SHARED_REG_WR32(adapter, 3158a15ebd37SHimanshu Madhani QLCNIC_CRB_DRV_STATE, val); 3159aa43c215SJeff Kirsher } 3160aa43c215SJeff Kirsher 3161aa43c215SJeff Kirsher qlcnic_api_unlock(adapter); 3162aa43c215SJeff Kirsher 3163aa43c215SJeff Kirsher rtnl_lock(); 3164890b6e02SShahed Shaikh if (qlcnic_check_fw_dump_state(adapter) && 3165aa43c215SJeff Kirsher (adapter->flags & QLCNIC_FW_RESET_OWNER)) { 3166aa43c215SJeff Kirsher QLCDB(adapter, DRV, "Take FW dump\n"); 3167aa43c215SJeff Kirsher qlcnic_dump_fw(adapter); 3168aa43c215SJeff Kirsher adapter->flags |= QLCNIC_FW_HANG; 3169aa43c215SJeff Kirsher } 3170aa43c215SJeff Kirsher rtnl_unlock(); 3171aa43c215SJeff Kirsher 3172aa43c215SJeff Kirsher adapter->flags &= ~QLCNIC_FW_RESET_OWNER; 3173aa43c215SJeff Kirsher if (!adapter->nic_ops->start_firmware(adapter)) { 3174aa43c215SJeff Kirsher qlcnic_schedule_work(adapter, qlcnic_attach_work, 0); 3175aa43c215SJeff Kirsher adapter->fw_wait_cnt = 0; 3176aa43c215SJeff Kirsher return; 3177aa43c215SJeff Kirsher } 3178aa43c215SJeff Kirsher goto err_ret; 3179aa43c215SJeff Kirsher } 3180aa43c215SJeff Kirsher 3181aa43c215SJeff Kirsher qlcnic_api_unlock(adapter); 3182aa43c215SJeff Kirsher 3183aa43c215SJeff Kirsher wait_npar: 3184a15ebd37SHimanshu Madhani dev_state = QLC_SHARED_REG_RD32(adapter, QLCNIC_CRB_DEV_STATE); 3185aa43c215SJeff Kirsher QLCDB(adapter, HW, "Func waiting: Device state=%u\n", dev_state); 3186aa43c215SJeff Kirsher 3187aa43c215SJeff Kirsher switch (dev_state) { 3188aa43c215SJeff Kirsher case QLCNIC_DEV_READY: 31897e2cf4feSSony Chacko if (!qlcnic_start_firmware(adapter)) { 3190aa43c215SJeff Kirsher qlcnic_schedule_work(adapter, qlcnic_attach_work, 0); 3191aa43c215SJeff Kirsher adapter->fw_wait_cnt = 0; 3192aa43c215SJeff Kirsher return; 3193aa43c215SJeff Kirsher } 3194aa43c215SJeff Kirsher case QLCNIC_DEV_FAILED: 3195aa43c215SJeff Kirsher break; 3196aa43c215SJeff Kirsher default: 3197aa43c215SJeff Kirsher qlcnic_schedule_work(adapter, 3198aa43c215SJeff Kirsher qlcnic_fwinit_work, FW_POLL_DELAY); 3199aa43c215SJeff Kirsher return; 3200aa43c215SJeff Kirsher } 3201aa43c215SJeff Kirsher 3202aa43c215SJeff Kirsher err_ret: 3203aa43c215SJeff Kirsher dev_err(&adapter->pdev->dev, "Fwinit work failed state=%u " 3204aa43c215SJeff Kirsher "fw_wait_cnt=%u\n", dev_state, adapter->fw_wait_cnt); 3205aa43c215SJeff Kirsher netif_device_attach(adapter->netdev); 3206aa43c215SJeff Kirsher qlcnic_clr_all_drv_state(adapter, 0); 3207aa43c215SJeff Kirsher } 3208aa43c215SJeff Kirsher 3209aa43c215SJeff Kirsher static void 3210aa43c215SJeff Kirsher qlcnic_detach_work(struct work_struct *work) 3211aa43c215SJeff Kirsher { 3212aa43c215SJeff Kirsher struct qlcnic_adapter *adapter = container_of(work, 3213aa43c215SJeff Kirsher struct qlcnic_adapter, fw_work.work); 3214aa43c215SJeff Kirsher struct net_device *netdev = adapter->netdev; 3215aa43c215SJeff Kirsher u32 status; 3216aa43c215SJeff Kirsher 3217aa43c215SJeff Kirsher netif_device_detach(netdev); 3218aa43c215SJeff Kirsher 3219aa43c215SJeff Kirsher /* Dont grab rtnl lock during Quiscent mode */ 3220aa43c215SJeff Kirsher if (adapter->dev_state == QLCNIC_DEV_NEED_QUISCENT) { 3221aa43c215SJeff Kirsher if (netif_running(netdev)) 3222aa43c215SJeff Kirsher __qlcnic_down(adapter, netdev); 3223aa43c215SJeff Kirsher } else 3224aa43c215SJeff Kirsher qlcnic_down(adapter, netdev); 3225aa43c215SJeff Kirsher 3226a15ebd37SHimanshu Madhani status = QLC_SHARED_REG_RD32(adapter, QLCNIC_PEG_HALT_STATUS1); 3227aa43c215SJeff Kirsher 322844f65b29SSony Chacko if (status & QLCNIC_RCODE_FATAL_ERROR) { 322944f65b29SSony Chacko dev_err(&adapter->pdev->dev, 323044f65b29SSony Chacko "Detaching the device: peg halt status1=0x%x\n", 323144f65b29SSony Chacko status); 3232aa43c215SJeff Kirsher 323344f65b29SSony Chacko if (QLCNIC_FWERROR_CODE(status) == QLCNIC_FWERROR_FAN_FAILURE) { 323444f65b29SSony Chacko dev_err(&adapter->pdev->dev, 323544f65b29SSony Chacko "On board active cooling fan failed. " 323644f65b29SSony Chacko "Device has been halted.\n"); 323744f65b29SSony Chacko dev_err(&adapter->pdev->dev, 323844f65b29SSony Chacko "Replace the adapter.\n"); 323944f65b29SSony Chacko } 324044f65b29SSony Chacko 3241aa43c215SJeff Kirsher goto err_ret; 324244f65b29SSony Chacko } 324344f65b29SSony Chacko 324479788450SSony Chacko if (adapter->ahw->temp == QLCNIC_TEMP_PANIC) { 324544f65b29SSony Chacko dev_err(&adapter->pdev->dev, "Detaching the device: temp=%d\n", 324679788450SSony Chacko adapter->ahw->temp); 324744f65b29SSony Chacko goto err_ret; 324844f65b29SSony Chacko } 324944f65b29SSony Chacko 3250aa43c215SJeff Kirsher /* Dont ack if this instance is the reset owner */ 3251aa43c215SJeff Kirsher if (!(adapter->flags & QLCNIC_FW_RESET_OWNER)) { 325244f65b29SSony Chacko if (qlcnic_set_drv_state(adapter, adapter->dev_state)) { 325344f65b29SSony Chacko dev_err(&adapter->pdev->dev, 325444f65b29SSony Chacko "Failed to set driver state," 325544f65b29SSony Chacko "detaching the device.\n"); 3256aa43c215SJeff Kirsher goto err_ret; 3257aa43c215SJeff Kirsher } 325844f65b29SSony Chacko } 3259aa43c215SJeff Kirsher 3260aa43c215SJeff Kirsher adapter->fw_wait_cnt = 0; 3261aa43c215SJeff Kirsher 3262aa43c215SJeff Kirsher qlcnic_schedule_work(adapter, qlcnic_fwinit_work, FW_POLL_DELAY); 3263aa43c215SJeff Kirsher 3264aa43c215SJeff Kirsher return; 3265aa43c215SJeff Kirsher 3266aa43c215SJeff Kirsher err_ret: 3267aa43c215SJeff Kirsher netif_device_attach(netdev); 3268aa43c215SJeff Kirsher qlcnic_clr_all_drv_state(adapter, 1); 3269aa43c215SJeff Kirsher } 3270aa43c215SJeff Kirsher 3271aa43c215SJeff Kirsher /*Transit NPAR state to NON Operational */ 3272aa43c215SJeff Kirsher static void 3273aa43c215SJeff Kirsher qlcnic_set_npar_non_operational(struct qlcnic_adapter *adapter) 3274aa43c215SJeff Kirsher { 3275aa43c215SJeff Kirsher u32 state; 3276aa43c215SJeff Kirsher 3277a15ebd37SHimanshu Madhani state = QLC_SHARED_REG_RD32(adapter, QLCNIC_CRB_DEV_NPAR_STATE); 3278aa43c215SJeff Kirsher if (state == QLCNIC_DEV_NPAR_NON_OPER) 3279aa43c215SJeff Kirsher return; 3280aa43c215SJeff Kirsher 3281aa43c215SJeff Kirsher if (qlcnic_api_lock(adapter)) 3282aa43c215SJeff Kirsher return; 3283a15ebd37SHimanshu Madhani QLC_SHARED_REG_WR32(adapter, QLCNIC_CRB_DEV_NPAR_STATE, 3284a15ebd37SHimanshu Madhani QLCNIC_DEV_NPAR_NON_OPER); 3285aa43c215SJeff Kirsher qlcnic_api_unlock(adapter); 3286aa43c215SJeff Kirsher } 3287aa43c215SJeff Kirsher 32887e2cf4feSSony Chacko void qlcnic_82xx_dev_request_reset(struct qlcnic_adapter *adapter, u32 key) 3289aa43c215SJeff Kirsher { 3290646779f1SSritej Velaga u32 state, xg_val = 0, gb_val = 0; 3291aa43c215SJeff Kirsher 3292646779f1SSritej Velaga qlcnic_xg_set_xg0_mask(xg_val); 3293646779f1SSritej Velaga qlcnic_xg_set_xg1_mask(xg_val); 3294646779f1SSritej Velaga QLCWR32(adapter, QLCNIC_NIU_XG_PAUSE_CTL, xg_val); 3295646779f1SSritej Velaga qlcnic_gb_set_gb0_mask(gb_val); 3296646779f1SSritej Velaga qlcnic_gb_set_gb1_mask(gb_val); 3297646779f1SSritej Velaga qlcnic_gb_set_gb2_mask(gb_val); 3298646779f1SSritej Velaga qlcnic_gb_set_gb3_mask(gb_val); 3299646779f1SSritej Velaga QLCWR32(adapter, QLCNIC_NIU_GB_PAUSE_CTL, gb_val); 3300646779f1SSritej Velaga dev_info(&adapter->pdev->dev, "Pause control frames disabled" 3301646779f1SSritej Velaga " on all ports\n"); 3302aa43c215SJeff Kirsher adapter->need_fw_reset = 1; 330313159183SSony Chacko 3304aa43c215SJeff Kirsher if (qlcnic_api_lock(adapter)) 3305aa43c215SJeff Kirsher return; 3306aa43c215SJeff Kirsher 330713159183SSony Chacko state = QLC_SHARED_REG_RD32(adapter, QLCNIC_CRB_DEV_STATE); 330878ea2d97SSucheta Chakraborty 330978ea2d97SSucheta Chakraborty if (test_bit(__QLCNIC_MAINTENANCE_MODE, &adapter->state)) { 331078ea2d97SSucheta Chakraborty netdev_err(adapter->netdev, "%s: Device is in non-operational state\n", 331166451615SSucheta Chakraborty __func__); 331266451615SSucheta Chakraborty qlcnic_api_unlock(adapter); 331366451615SSucheta Chakraborty 331466451615SSucheta Chakraborty return; 331566451615SSucheta Chakraborty } 3316aa43c215SJeff Kirsher 3317aa43c215SJeff Kirsher if (state == QLCNIC_DEV_READY) { 331813159183SSony Chacko QLC_SHARED_REG_WR32(adapter, QLCNIC_CRB_DEV_STATE, 331913159183SSony Chacko QLCNIC_DEV_NEED_RESET); 3320aa43c215SJeff Kirsher adapter->flags |= QLCNIC_FW_RESET_OWNER; 3321aa43c215SJeff Kirsher QLCDB(adapter, DRV, "NEED_RESET state set\n"); 3322aa43c215SJeff Kirsher qlcnic_idc_debug_info(adapter, 0); 3323aa43c215SJeff Kirsher } 3324aa43c215SJeff Kirsher 332513159183SSony Chacko QLC_SHARED_REG_WR32(adapter, QLCNIC_CRB_DEV_NPAR_STATE, 332613159183SSony Chacko QLCNIC_DEV_NPAR_NON_OPER); 3327aa43c215SJeff Kirsher qlcnic_api_unlock(adapter); 3328aa43c215SJeff Kirsher } 3329aa43c215SJeff Kirsher 3330aa43c215SJeff Kirsher /* Transit to NPAR READY state from NPAR NOT READY state */ 3331aa43c215SJeff Kirsher static void 3332aa43c215SJeff Kirsher qlcnic_dev_set_npar_ready(struct qlcnic_adapter *adapter) 3333aa43c215SJeff Kirsher { 3334aa43c215SJeff Kirsher if (qlcnic_api_lock(adapter)) 3335aa43c215SJeff Kirsher return; 3336aa43c215SJeff Kirsher 3337a15ebd37SHimanshu Madhani QLC_SHARED_REG_WR32(adapter, QLCNIC_CRB_DEV_NPAR_STATE, 3338a15ebd37SHimanshu Madhani QLCNIC_DEV_NPAR_OPER); 3339aa43c215SJeff Kirsher QLCDB(adapter, DRV, "NPAR operational state set\n"); 3340aa43c215SJeff Kirsher 3341aa43c215SJeff Kirsher qlcnic_api_unlock(adapter); 3342aa43c215SJeff Kirsher } 3343aa43c215SJeff Kirsher 334413159183SSony Chacko void qlcnic_schedule_work(struct qlcnic_adapter *adapter, 3345aa43c215SJeff Kirsher work_func_t func, int delay) 3346aa43c215SJeff Kirsher { 3347aa43c215SJeff Kirsher if (test_bit(__QLCNIC_AER, &adapter->state)) 3348aa43c215SJeff Kirsher return; 3349aa43c215SJeff Kirsher 3350aa43c215SJeff Kirsher INIT_DELAYED_WORK(&adapter->fw_work, func); 335113159183SSony Chacko queue_delayed_work(adapter->qlcnic_wq, &adapter->fw_work, 3352aa43c215SJeff Kirsher round_jiffies_relative(delay)); 3353aa43c215SJeff Kirsher } 3354aa43c215SJeff Kirsher 3355aa43c215SJeff Kirsher static void 3356aa43c215SJeff Kirsher qlcnic_attach_work(struct work_struct *work) 3357aa43c215SJeff Kirsher { 3358aa43c215SJeff Kirsher struct qlcnic_adapter *adapter = container_of(work, 3359aa43c215SJeff Kirsher struct qlcnic_adapter, fw_work.work); 3360aa43c215SJeff Kirsher struct net_device *netdev = adapter->netdev; 3361aa43c215SJeff Kirsher u32 npar_state; 3362aa43c215SJeff Kirsher 336379788450SSony Chacko if (adapter->ahw->op_mode != QLCNIC_MGMT_FUNC) { 3364a15ebd37SHimanshu Madhani npar_state = QLC_SHARED_REG_RD32(adapter, 3365a15ebd37SHimanshu Madhani QLCNIC_CRB_DEV_NPAR_STATE); 3366aa43c215SJeff Kirsher if (adapter->fw_wait_cnt++ > QLCNIC_DEV_NPAR_OPER_TIMEO) 3367aa43c215SJeff Kirsher qlcnic_clr_all_drv_state(adapter, 0); 3368aa43c215SJeff Kirsher else if (npar_state != QLCNIC_DEV_NPAR_OPER) 3369aa43c215SJeff Kirsher qlcnic_schedule_work(adapter, qlcnic_attach_work, 3370aa43c215SJeff Kirsher FW_POLL_DELAY); 3371aa43c215SJeff Kirsher else 3372aa43c215SJeff Kirsher goto attach; 3373aa43c215SJeff Kirsher QLCDB(adapter, DRV, "Waiting for NPAR state to operational\n"); 3374aa43c215SJeff Kirsher return; 3375aa43c215SJeff Kirsher } 3376aa43c215SJeff Kirsher attach: 33771de899d3SSucheta Chakraborty qlcnic_dcb_get_info(adapter->dcb); 337814d385b9SSucheta Chakraborty 3379aa43c215SJeff Kirsher if (netif_running(netdev)) { 3380aa43c215SJeff Kirsher if (qlcnic_up(adapter, netdev)) 3381aa43c215SJeff Kirsher goto done; 3382aa43c215SJeff Kirsher 3383aa43c215SJeff Kirsher qlcnic_restore_indev_addr(netdev, NETDEV_UP); 3384aa43c215SJeff Kirsher } 3385aa43c215SJeff Kirsher 3386aa43c215SJeff Kirsher done: 3387aa43c215SJeff Kirsher netif_device_attach(netdev); 3388aa43c215SJeff Kirsher adapter->fw_fail_cnt = 0; 3389aa43c215SJeff Kirsher adapter->flags &= ~QLCNIC_FW_HANG; 3390aa43c215SJeff Kirsher clear_bit(__QLCNIC_RESETTING, &adapter->state); 339124866d15SHimanshu Madhani if (adapter->portnum == 0) 33928af3f33dSPratik Pujar qlcnic_set_drv_version(adapter); 3393aa43c215SJeff Kirsher 3394aa43c215SJeff Kirsher if (!qlcnic_clr_drv_state(adapter)) 3395aa43c215SJeff Kirsher qlcnic_schedule_work(adapter, qlcnic_fw_poll_work, 3396aa43c215SJeff Kirsher FW_POLL_DELAY); 3397aa43c215SJeff Kirsher } 3398aa43c215SJeff Kirsher 3399aa43c215SJeff Kirsher static int 3400aa43c215SJeff Kirsher qlcnic_check_health(struct qlcnic_adapter *adapter) 3401aa43c215SJeff Kirsher { 3402891e71b1SPratik Pujar struct qlcnic_hardware_context *ahw = adapter->ahw; 3403891e71b1SPratik Pujar struct qlcnic_fw_dump *fw_dump = &ahw->fw_dump; 3404aa43c215SJeff Kirsher u32 state = 0, heartbeat; 3405853d4bcaSAmeen Rahman u32 peg_status; 34064bd8e738SHimanshu Madhani int err = 0; 3407aa43c215SJeff Kirsher 3408aa43c215SJeff Kirsher if (qlcnic_check_temp(adapter)) 3409aa43c215SJeff Kirsher goto detach; 3410aa43c215SJeff Kirsher 3411aa43c215SJeff Kirsher if (adapter->need_fw_reset) 34127e2cf4feSSony Chacko qlcnic_dev_request_reset(adapter, 0); 3413aa43c215SJeff Kirsher 3414a15ebd37SHimanshu Madhani state = QLC_SHARED_REG_RD32(adapter, QLCNIC_CRB_DEV_STATE); 3415aa43c215SJeff Kirsher if (state == QLCNIC_DEV_NEED_RESET) { 3416aa43c215SJeff Kirsher qlcnic_set_npar_non_operational(adapter); 3417aa43c215SJeff Kirsher adapter->need_fw_reset = 1; 3418aa43c215SJeff Kirsher } else if (state == QLCNIC_DEV_NEED_QUISCENT) 3419aa43c215SJeff Kirsher goto detach; 3420aa43c215SJeff Kirsher 3421a15ebd37SHimanshu Madhani heartbeat = QLC_SHARED_REG_RD32(adapter, QLCNIC_PEG_ALIVE_COUNTER); 3422aa43c215SJeff Kirsher if (heartbeat != adapter->heartbeat) { 3423aa43c215SJeff Kirsher adapter->heartbeat = heartbeat; 3424aa43c215SJeff Kirsher adapter->fw_fail_cnt = 0; 3425aa43c215SJeff Kirsher if (adapter->need_fw_reset) 3426aa43c215SJeff Kirsher goto detach; 3427aa43c215SJeff Kirsher 3428891e71b1SPratik Pujar if (ahw->reset_context && qlcnic_auto_fw_reset) 3429aa43c215SJeff Kirsher qlcnic_reset_hw_context(adapter); 3430aa43c215SJeff Kirsher 3431aa43c215SJeff Kirsher return 0; 3432aa43c215SJeff Kirsher } 3433aa43c215SJeff Kirsher 3434aa43c215SJeff Kirsher if (++adapter->fw_fail_cnt < FW_FAIL_THRESH) 3435aa43c215SJeff Kirsher return 0; 3436aa43c215SJeff Kirsher 3437aa43c215SJeff Kirsher adapter->flags |= QLCNIC_FW_HANG; 3438aa43c215SJeff Kirsher 34397e2cf4feSSony Chacko qlcnic_dev_request_reset(adapter, 0); 3440aa43c215SJeff Kirsher 3441099f7aa7SSony Chacko if (qlcnic_auto_fw_reset) 3442aa43c215SJeff Kirsher clear_bit(__QLCNIC_FW_ATTACHED, &adapter->state); 3443aa43c215SJeff Kirsher 3444853d4bcaSAmeen Rahman dev_err(&adapter->pdev->dev, "firmware hang detected\n"); 3445a15ebd37SHimanshu Madhani peg_status = QLC_SHARED_REG_RD32(adapter, QLCNIC_PEG_HALT_STATUS1); 3446853d4bcaSAmeen Rahman dev_err(&adapter->pdev->dev, "Dumping hw/fw registers\n" 3447aa43c215SJeff Kirsher "PEG_HALT_STATUS1: 0x%x, PEG_HALT_STATUS2: 0x%x,\n" 3448aa43c215SJeff Kirsher "PEG_NET_0_PC: 0x%x, PEG_NET_1_PC: 0x%x,\n" 3449aa43c215SJeff Kirsher "PEG_NET_2_PC: 0x%x, PEG_NET_3_PC: 0x%x,\n" 3450aa43c215SJeff Kirsher "PEG_NET_4_PC: 0x%x\n", 3451a15ebd37SHimanshu Madhani peg_status, 3452a15ebd37SHimanshu Madhani QLC_SHARED_REG_RD32(adapter, QLCNIC_PEG_HALT_STATUS2), 34534bd8e738SHimanshu Madhani QLCRD32(adapter, QLCNIC_CRB_PEG_NET_0 + 0x3c, &err), 34544bd8e738SHimanshu Madhani QLCRD32(adapter, QLCNIC_CRB_PEG_NET_1 + 0x3c, &err), 34554bd8e738SHimanshu Madhani QLCRD32(adapter, QLCNIC_CRB_PEG_NET_2 + 0x3c, &err), 34564bd8e738SHimanshu Madhani QLCRD32(adapter, QLCNIC_CRB_PEG_NET_3 + 0x3c, &err), 34574bd8e738SHimanshu Madhani QLCRD32(adapter, QLCNIC_CRB_PEG_NET_4 + 0x3c, &err)); 345897048a1fSSritej Velaga if (QLCNIC_FWERROR_CODE(peg_status) == 0x67) 3459853d4bcaSAmeen Rahman dev_err(&adapter->pdev->dev, 3460853d4bcaSAmeen Rahman "Firmware aborted with error code 0x00006700. " 3461853d4bcaSAmeen Rahman "Device is being reset.\n"); 3462aa43c215SJeff Kirsher detach: 3463aa43c215SJeff Kirsher adapter->dev_state = (state == QLCNIC_DEV_NEED_QUISCENT) ? state : 3464aa43c215SJeff Kirsher QLCNIC_DEV_NEED_RESET; 3465aa43c215SJeff Kirsher 3466099f7aa7SSony Chacko if (qlcnic_auto_fw_reset && !test_and_set_bit(__QLCNIC_RESETTING, 3467099f7aa7SSony Chacko &adapter->state)) { 3468aa43c215SJeff Kirsher 3469aa43c215SJeff Kirsher qlcnic_schedule_work(adapter, qlcnic_detach_work, 0); 3470aa43c215SJeff Kirsher QLCDB(adapter, DRV, "fw recovery scheduled.\n"); 3471891e71b1SPratik Pujar } else if (!qlcnic_auto_fw_reset && fw_dump->enable && 3472891e71b1SPratik Pujar adapter->flags & QLCNIC_FW_RESET_OWNER) { 3473891e71b1SPratik Pujar qlcnic_dump_fw(adapter); 3474aa43c215SJeff Kirsher } 3475aa43c215SJeff Kirsher 3476aa43c215SJeff Kirsher return 1; 3477aa43c215SJeff Kirsher } 3478aa43c215SJeff Kirsher 3479486a5bc7SRajesh Borundia void qlcnic_fw_poll_work(struct work_struct *work) 3480aa43c215SJeff Kirsher { 3481aa43c215SJeff Kirsher struct qlcnic_adapter *adapter = container_of(work, 3482aa43c215SJeff Kirsher struct qlcnic_adapter, fw_work.work); 3483aa43c215SJeff Kirsher 3484aa43c215SJeff Kirsher if (test_bit(__QLCNIC_RESETTING, &adapter->state)) 3485aa43c215SJeff Kirsher goto reschedule; 3486aa43c215SJeff Kirsher 3487aa43c215SJeff Kirsher 3488aa43c215SJeff Kirsher if (qlcnic_check_health(adapter)) 3489aa43c215SJeff Kirsher return; 3490aa43c215SJeff Kirsher 3491aa43c215SJeff Kirsher if (adapter->fhash.fnum) 3492aa43c215SJeff Kirsher qlcnic_prune_lb_filters(adapter); 3493aa43c215SJeff Kirsher 3494aa43c215SJeff Kirsher reschedule: 3495aa43c215SJeff Kirsher qlcnic_schedule_work(adapter, qlcnic_fw_poll_work, FW_POLL_DELAY); 3496aa43c215SJeff Kirsher } 3497aa43c215SJeff Kirsher 3498aa43c215SJeff Kirsher static int qlcnic_is_first_func(struct pci_dev *pdev) 3499aa43c215SJeff Kirsher { 3500aa43c215SJeff Kirsher struct pci_dev *oth_pdev; 3501aa43c215SJeff Kirsher int val = pdev->devfn; 3502aa43c215SJeff Kirsher 3503aa43c215SJeff Kirsher while (val-- > 0) { 3504aa43c215SJeff Kirsher oth_pdev = pci_get_domain_bus_and_slot(pci_domain_nr 3505aa43c215SJeff Kirsher (pdev->bus), pdev->bus->number, 3506aa43c215SJeff Kirsher PCI_DEVFN(PCI_SLOT(pdev->devfn), val)); 3507aa43c215SJeff Kirsher if (!oth_pdev) 3508aa43c215SJeff Kirsher continue; 3509aa43c215SJeff Kirsher 3510aa43c215SJeff Kirsher if (oth_pdev->current_state != PCI_D3cold) { 3511aa43c215SJeff Kirsher pci_dev_put(oth_pdev); 3512aa43c215SJeff Kirsher return 0; 3513aa43c215SJeff Kirsher } 3514aa43c215SJeff Kirsher pci_dev_put(oth_pdev); 3515aa43c215SJeff Kirsher } 3516aa43c215SJeff Kirsher return 1; 3517aa43c215SJeff Kirsher } 3518aa43c215SJeff Kirsher 3519aa43c215SJeff Kirsher static int qlcnic_attach_func(struct pci_dev *pdev) 3520aa43c215SJeff Kirsher { 3521aa43c215SJeff Kirsher int err, first_func; 3522aa43c215SJeff Kirsher struct qlcnic_adapter *adapter = pci_get_drvdata(pdev); 3523aa43c215SJeff Kirsher struct net_device *netdev = adapter->netdev; 3524aa43c215SJeff Kirsher 3525aa43c215SJeff Kirsher pdev->error_state = pci_channel_io_normal; 3526aa43c215SJeff Kirsher 3527aa43c215SJeff Kirsher err = pci_enable_device(pdev); 3528aa43c215SJeff Kirsher if (err) 3529aa43c215SJeff Kirsher return err; 3530aa43c215SJeff Kirsher 3531aa43c215SJeff Kirsher pci_set_master(pdev); 3532aa43c215SJeff Kirsher pci_restore_state(pdev); 3533aa43c215SJeff Kirsher 3534aa43c215SJeff Kirsher first_func = qlcnic_is_first_func(pdev); 3535aa43c215SJeff Kirsher 3536aa43c215SJeff Kirsher if (qlcnic_api_lock(adapter)) 3537aa43c215SJeff Kirsher return -EINVAL; 3538aa43c215SJeff Kirsher 353979788450SSony Chacko if (adapter->ahw->op_mode != QLCNIC_NON_PRIV_FUNC && first_func) { 3540aa43c215SJeff Kirsher adapter->need_fw_reset = 1; 3541aa43c215SJeff Kirsher set_bit(__QLCNIC_START_FW, &adapter->state); 3542a15ebd37SHimanshu Madhani QLC_SHARED_REG_WR32(adapter, QLCNIC_CRB_DEV_STATE, 3543a15ebd37SHimanshu Madhani QLCNIC_DEV_INITIALIZING); 3544aa43c215SJeff Kirsher QLCDB(adapter, DRV, "Restarting fw\n"); 3545aa43c215SJeff Kirsher } 3546aa43c215SJeff Kirsher qlcnic_api_unlock(adapter); 3547aa43c215SJeff Kirsher 354813159183SSony Chacko err = qlcnic_start_firmware(adapter); 3549aa43c215SJeff Kirsher if (err) 3550aa43c215SJeff Kirsher return err; 3551aa43c215SJeff Kirsher 3552aa43c215SJeff Kirsher qlcnic_clr_drv_state(adapter); 355313159183SSony Chacko kfree(adapter->msix_entries); 355413159183SSony Chacko adapter->msix_entries = NULL; 355534e8c406SHimanshu Madhani err = qlcnic_setup_intr(adapter); 355613159183SSony Chacko 35579a97e705SManish chopra if (err) { 35589a97e705SManish chopra kfree(adapter->msix_entries); 35599a97e705SManish chopra netdev_err(netdev, "failed to setup interrupt\n"); 35609a97e705SManish chopra return err; 35619a97e705SManish chopra } 35629a97e705SManish chopra 3563aa43c215SJeff Kirsher if (netif_running(netdev)) { 3564aa43c215SJeff Kirsher err = qlcnic_attach(adapter); 3565aa43c215SJeff Kirsher if (err) { 3566aa43c215SJeff Kirsher qlcnic_clr_all_drv_state(adapter, 1); 3567aa43c215SJeff Kirsher clear_bit(__QLCNIC_AER, &adapter->state); 3568aa43c215SJeff Kirsher netif_device_attach(netdev); 3569aa43c215SJeff Kirsher return err; 3570aa43c215SJeff Kirsher } 3571aa43c215SJeff Kirsher 3572aa43c215SJeff Kirsher err = qlcnic_up(adapter, netdev); 3573aa43c215SJeff Kirsher if (err) 3574aa43c215SJeff Kirsher goto done; 3575aa43c215SJeff Kirsher 3576aa43c215SJeff Kirsher qlcnic_restore_indev_addr(netdev, NETDEV_UP); 3577aa43c215SJeff Kirsher } 3578aa43c215SJeff Kirsher done: 3579aa43c215SJeff Kirsher netif_device_attach(netdev); 3580aa43c215SJeff Kirsher return err; 3581aa43c215SJeff Kirsher } 3582aa43c215SJeff Kirsher 35834460f2e8SPratik Pujar pci_ers_result_t qlcnic_82xx_io_error_detected(struct pci_dev *pdev, 3584aa43c215SJeff Kirsher pci_channel_state_t state) 3585aa43c215SJeff Kirsher { 3586aa43c215SJeff Kirsher struct qlcnic_adapter *adapter = pci_get_drvdata(pdev); 3587aa43c215SJeff Kirsher struct net_device *netdev = adapter->netdev; 3588aa43c215SJeff Kirsher 3589aa43c215SJeff Kirsher if (state == pci_channel_io_perm_failure) 3590aa43c215SJeff Kirsher return PCI_ERS_RESULT_DISCONNECT; 3591aa43c215SJeff Kirsher 3592aa43c215SJeff Kirsher if (state == pci_channel_io_normal) 3593aa43c215SJeff Kirsher return PCI_ERS_RESULT_RECOVERED; 3594aa43c215SJeff Kirsher 3595aa43c215SJeff Kirsher set_bit(__QLCNIC_AER, &adapter->state); 3596aa43c215SJeff Kirsher netif_device_detach(netdev); 3597aa43c215SJeff Kirsher 3598aa43c215SJeff Kirsher cancel_delayed_work_sync(&adapter->fw_work); 3599aa43c215SJeff Kirsher 3600aa43c215SJeff Kirsher if (netif_running(netdev)) 3601aa43c215SJeff Kirsher qlcnic_down(adapter, netdev); 3602aa43c215SJeff Kirsher 3603aa43c215SJeff Kirsher qlcnic_detach(adapter); 3604aa43c215SJeff Kirsher qlcnic_teardown_intr(adapter); 3605aa43c215SJeff Kirsher 3606aa43c215SJeff Kirsher clear_bit(__QLCNIC_RESETTING, &adapter->state); 3607aa43c215SJeff Kirsher 3608aa43c215SJeff Kirsher pci_save_state(pdev); 3609aa43c215SJeff Kirsher pci_disable_device(pdev); 3610aa43c215SJeff Kirsher 3611aa43c215SJeff Kirsher return PCI_ERS_RESULT_NEED_RESET; 3612aa43c215SJeff Kirsher } 3613aa43c215SJeff Kirsher 36144460f2e8SPratik Pujar pci_ers_result_t qlcnic_82xx_io_slot_reset(struct pci_dev *pdev) 3615aa43c215SJeff Kirsher { 3616aa43c215SJeff Kirsher return qlcnic_attach_func(pdev) ? PCI_ERS_RESULT_DISCONNECT : 3617aa43c215SJeff Kirsher PCI_ERS_RESULT_RECOVERED; 3618aa43c215SJeff Kirsher } 3619aa43c215SJeff Kirsher 36204460f2e8SPratik Pujar void qlcnic_82xx_io_resume(struct pci_dev *pdev) 3621aa43c215SJeff Kirsher { 3622a15ebd37SHimanshu Madhani u32 state; 3623aa43c215SJeff Kirsher struct qlcnic_adapter *adapter = pci_get_drvdata(pdev); 3624aa43c215SJeff Kirsher 3625aa43c215SJeff Kirsher pci_cleanup_aer_uncorrect_error_status(pdev); 3626a15ebd37SHimanshu Madhani state = QLC_SHARED_REG_RD32(adapter, QLCNIC_CRB_DEV_STATE); 3627a15ebd37SHimanshu Madhani if (state == QLCNIC_DEV_READY && test_and_clear_bit(__QLCNIC_AER, 3628a15ebd37SHimanshu Madhani &adapter->state)) 3629aa43c215SJeff Kirsher qlcnic_schedule_work(adapter, qlcnic_fw_poll_work, 3630aa43c215SJeff Kirsher FW_POLL_DELAY); 3631aa43c215SJeff Kirsher } 3632aa43c215SJeff Kirsher 36334460f2e8SPratik Pujar static pci_ers_result_t qlcnic_io_error_detected(struct pci_dev *pdev, 36344460f2e8SPratik Pujar pci_channel_state_t state) 36354460f2e8SPratik Pujar { 36364460f2e8SPratik Pujar struct qlcnic_adapter *adapter = pci_get_drvdata(pdev); 36374460f2e8SPratik Pujar struct qlcnic_hardware_ops *hw_ops = adapter->ahw->hw_ops; 36384460f2e8SPratik Pujar 36394460f2e8SPratik Pujar if (hw_ops->io_error_detected) { 36404460f2e8SPratik Pujar return hw_ops->io_error_detected(pdev, state); 36414460f2e8SPratik Pujar } else { 36424460f2e8SPratik Pujar dev_err(&pdev->dev, "AER error_detected handler not registered.\n"); 36434460f2e8SPratik Pujar return PCI_ERS_RESULT_DISCONNECT; 36444460f2e8SPratik Pujar } 36454460f2e8SPratik Pujar } 36464460f2e8SPratik Pujar 36474460f2e8SPratik Pujar static pci_ers_result_t qlcnic_io_slot_reset(struct pci_dev *pdev) 36484460f2e8SPratik Pujar { 36494460f2e8SPratik Pujar struct qlcnic_adapter *adapter = pci_get_drvdata(pdev); 36504460f2e8SPratik Pujar struct qlcnic_hardware_ops *hw_ops = adapter->ahw->hw_ops; 36514460f2e8SPratik Pujar 36524460f2e8SPratik Pujar if (hw_ops->io_slot_reset) { 36534460f2e8SPratik Pujar return hw_ops->io_slot_reset(pdev); 36544460f2e8SPratik Pujar } else { 36554460f2e8SPratik Pujar dev_err(&pdev->dev, "AER slot_reset handler not registered.\n"); 36564460f2e8SPratik Pujar return PCI_ERS_RESULT_DISCONNECT; 36574460f2e8SPratik Pujar } 36584460f2e8SPratik Pujar } 36594460f2e8SPratik Pujar 36604460f2e8SPratik Pujar static void qlcnic_io_resume(struct pci_dev *pdev) 36614460f2e8SPratik Pujar { 36624460f2e8SPratik Pujar struct qlcnic_adapter *adapter = pci_get_drvdata(pdev); 36634460f2e8SPratik Pujar struct qlcnic_hardware_ops *hw_ops = adapter->ahw->hw_ops; 36644460f2e8SPratik Pujar 36654460f2e8SPratik Pujar if (hw_ops->io_resume) 36664460f2e8SPratik Pujar hw_ops->io_resume(pdev); 36674460f2e8SPratik Pujar else 36684460f2e8SPratik Pujar dev_err(&pdev->dev, "AER resume handler not registered.\n"); 36694460f2e8SPratik Pujar } 36704460f2e8SPratik Pujar 36714460f2e8SPratik Pujar 3672aa43c215SJeff Kirsher static int 3673aa43c215SJeff Kirsher qlcnicvf_start_firmware(struct qlcnic_adapter *adapter) 3674aa43c215SJeff Kirsher { 3675aa43c215SJeff Kirsher int err; 3676aa43c215SJeff Kirsher 3677aa43c215SJeff Kirsher err = qlcnic_can_start_firmware(adapter); 3678aa43c215SJeff Kirsher if (err) 3679aa43c215SJeff Kirsher return err; 3680aa43c215SJeff Kirsher 3681aa43c215SJeff Kirsher err = qlcnic_check_npar_opertional(adapter); 3682aa43c215SJeff Kirsher if (err) 3683aa43c215SJeff Kirsher return err; 3684aa43c215SJeff Kirsher 3685aa43c215SJeff Kirsher err = qlcnic_initialize_nic(adapter); 3686aa43c215SJeff Kirsher if (err) 3687aa43c215SJeff Kirsher return err; 3688aa43c215SJeff Kirsher 3689aa43c215SJeff Kirsher qlcnic_check_options(adapter); 3690aa43c215SJeff Kirsher 3691aa43c215SJeff Kirsher err = qlcnic_set_eswitch_port_config(adapter); 3692aa43c215SJeff Kirsher if (err) 3693aa43c215SJeff Kirsher return err; 3694aa43c215SJeff Kirsher 3695aa43c215SJeff Kirsher adapter->need_fw_reset = 0; 3696aa43c215SJeff Kirsher 3697aa43c215SJeff Kirsher return err; 3698aa43c215SJeff Kirsher } 3699aa43c215SJeff Kirsher 370034e8c406SHimanshu Madhani int qlcnic_validate_rings(struct qlcnic_adapter *adapter, __u32 ring_cnt, 370134e8c406SHimanshu Madhani int queue_type) 3702aa4a1f7dSHimanshu Madhani { 3703aa4a1f7dSHimanshu Madhani struct net_device *netdev = adapter->netdev; 370434e8c406SHimanshu Madhani u8 max_hw_rings = 0; 370534e8c406SHimanshu Madhani char buf[8]; 370634e8c406SHimanshu Madhani int cur_rings; 370734e8c406SHimanshu Madhani 370834e8c406SHimanshu Madhani if (queue_type == QLCNIC_RX_QUEUE) { 370934e8c406SHimanshu Madhani max_hw_rings = adapter->max_sds_rings; 371034e8c406SHimanshu Madhani cur_rings = adapter->drv_sds_rings; 371134e8c406SHimanshu Madhani strcpy(buf, "SDS"); 371234e8c406SHimanshu Madhani } else if (queue_type == QLCNIC_TX_QUEUE) { 371334e8c406SHimanshu Madhani max_hw_rings = adapter->max_tx_rings; 371434e8c406SHimanshu Madhani cur_rings = adapter->drv_tx_rings; 371534e8c406SHimanshu Madhani strcpy(buf, "Tx"); 371634e8c406SHimanshu Madhani } 3717aa4a1f7dSHimanshu Madhani 3718aa4a1f7dSHimanshu Madhani if (!qlcnic_use_msi_x && !qlcnic_use_msi) { 371934e8c406SHimanshu Madhani netdev_err(netdev, "No RSS/TSS support in INT-x mode\n"); 3720aa4a1f7dSHimanshu Madhani return -EINVAL; 3721aa4a1f7dSHimanshu Madhani } 3722aa4a1f7dSHimanshu Madhani 372334e8c406SHimanshu Madhani if (adapter->flags & QLCNIC_MSI_ENABLED) { 372434e8c406SHimanshu Madhani netdev_err(netdev, "No RSS/TSS support in MSI mode\n"); 3725aa4a1f7dSHimanshu Madhani return -EINVAL; 3726aa4a1f7dSHimanshu Madhani } 3727aa4a1f7dSHimanshu Madhani 372834e8c406SHimanshu Madhani if (ring_cnt < 2) { 3729aa4a1f7dSHimanshu Madhani netdev_err(netdev, 373034e8c406SHimanshu Madhani "%s rings value should not be lower than 2\n", buf); 373134e8c406SHimanshu Madhani return -EINVAL; 373234e8c406SHimanshu Madhani } 373334e8c406SHimanshu Madhani 373434e8c406SHimanshu Madhani if (!is_power_of_2(ring_cnt)) { 373534e8c406SHimanshu Madhani netdev_err(netdev, "%s rings value should be a power of 2\n", 373634e8c406SHimanshu Madhani buf); 373734e8c406SHimanshu Madhani return -EINVAL; 373834e8c406SHimanshu Madhani } 373934e8c406SHimanshu Madhani 374034e8c406SHimanshu Madhani if (qlcnic_82xx_check(adapter) && (queue_type == QLCNIC_TX_QUEUE) && 374134e8c406SHimanshu Madhani !qlcnic_check_multi_tx(adapter)) { 374234e8c406SHimanshu Madhani netdev_err(netdev, "No Multi Tx queue support\n"); 374334e8c406SHimanshu Madhani return -EINVAL; 374434e8c406SHimanshu Madhani } 374534e8c406SHimanshu Madhani 374634e8c406SHimanshu Madhani if (ring_cnt > num_online_cpus()) { 3747aa4a1f7dSHimanshu Madhani netdev_err(netdev, 374834e8c406SHimanshu Madhani "%s value[%u] should not be higher than, number of online CPUs\n", 374934e8c406SHimanshu Madhani buf, num_online_cpus()); 3750aa4a1f7dSHimanshu Madhani return -EINVAL; 3751aa4a1f7dSHimanshu Madhani } 3752aa4a1f7dSHimanshu Madhani 3753aa4a1f7dSHimanshu Madhani return 0; 3754aa4a1f7dSHimanshu Madhani } 3755aa4a1f7dSHimanshu Madhani 375634e8c406SHimanshu Madhani int qlcnic_setup_rings(struct qlcnic_adapter *adapter, u8 rx_cnt, u8 tx_cnt) 3757aa43c215SJeff Kirsher { 37586389b76dSManish Chopra struct net_device *netdev = adapter->netdev; 375913159183SSony Chacko int err; 3760aa43c215SJeff Kirsher 3761319ecf12SSony Chacko if (test_bit(__QLCNIC_RESETTING, &adapter->state)) 3762319ecf12SSony Chacko return -EBUSY; 3763319ecf12SSony Chacko 3764aa43c215SJeff Kirsher netif_device_detach(netdev); 3765aa43c215SJeff Kirsher if (netif_running(netdev)) 3766aa43c215SJeff Kirsher __qlcnic_down(adapter, netdev); 376713159183SSony Chacko 3768aa43c215SJeff Kirsher qlcnic_detach(adapter); 37697dd90cf1SSucheta Chakraborty 37707ed3ce48SRajesh Borundia if (qlcnic_83xx_check(adapter)) { 37717dd90cf1SSucheta Chakraborty qlcnic_83xx_free_mbx_intr(adapter); 37727ed3ce48SRajesh Borundia qlcnic_83xx_enable_mbx_poll(adapter); 37737ed3ce48SRajesh Borundia } 37747dd90cf1SSucheta Chakraborty 3775aa43c215SJeff Kirsher qlcnic_teardown_intr(adapter); 3776aa4a1f7dSHimanshu Madhani 377734e8c406SHimanshu Madhani /* compute and set default and max tx/sds rings */ 377834e8c406SHimanshu Madhani qlcnic_set_tx_ring_count(adapter, tx_cnt); 377934e8c406SHimanshu Madhani qlcnic_set_sds_ring_count(adapter, rx_cnt); 378034e8c406SHimanshu Madhani 378134e8c406SHimanshu Madhani netif_set_real_num_tx_queues(netdev, adapter->drv_tx_rings); 378234e8c406SHimanshu Madhani 378334e8c406SHimanshu Madhani err = qlcnic_setup_intr(adapter); 37849a97e705SManish chopra if (err) { 37859a97e705SManish chopra kfree(adapter->msix_entries); 37869a97e705SManish chopra netdev_err(netdev, "failed to setup interrupt\n"); 37879a97e705SManish chopra return err; 37889a97e705SManish chopra } 3789aa43c215SJeff Kirsher 379013159183SSony Chacko if (qlcnic_83xx_check(adapter)) { 3791d5fcff04SHimanshu Madhani /* register for NIC IDC AEN Events */ 3792d5fcff04SHimanshu Madhani qlcnic_83xx_register_nic_idc_func(adapter, 1); 379313159183SSony Chacko err = qlcnic_83xx_setup_mbx_intr(adapter); 37947ed3ce48SRajesh Borundia qlcnic_83xx_disable_mbx_poll(adapter); 379513159183SSony Chacko if (err) { 379613159183SSony Chacko dev_err(&adapter->pdev->dev, 379713159183SSony Chacko "failed to setup mbx interrupt\n"); 379813159183SSony Chacko goto done; 379913159183SSony Chacko } 3800aa43c215SJeff Kirsher } 3801aa43c215SJeff Kirsher 3802aa43c215SJeff Kirsher if (netif_running(netdev)) { 3803aa43c215SJeff Kirsher err = qlcnic_attach(adapter); 3804aa43c215SJeff Kirsher if (err) 3805aa43c215SJeff Kirsher goto done; 3806aa43c215SJeff Kirsher err = __qlcnic_up(adapter, netdev); 3807aa43c215SJeff Kirsher if (err) 3808aa43c215SJeff Kirsher goto done; 3809aa43c215SJeff Kirsher qlcnic_restore_indev_addr(netdev, NETDEV_UP); 3810aa43c215SJeff Kirsher } 3811aa43c215SJeff Kirsher done: 3812aa43c215SJeff Kirsher netif_device_attach(netdev); 3813aa43c215SJeff Kirsher clear_bit(__QLCNIC_RESETTING, &adapter->state); 3814aa43c215SJeff Kirsher return err; 3815aa43c215SJeff Kirsher } 3816aa43c215SJeff Kirsher 3817aa43c215SJeff Kirsher #ifdef CONFIG_INET 3818aa43c215SJeff Kirsher 3819aa43c215SJeff Kirsher #define is_qlcnic_netdev(dev) (dev->netdev_ops == &qlcnic_netdev_ops) 3820aa43c215SJeff Kirsher 3821aa43c215SJeff Kirsher static void 3822aa43c215SJeff Kirsher qlcnic_config_indev_addr(struct qlcnic_adapter *adapter, 3823aa43c215SJeff Kirsher struct net_device *dev, unsigned long event) 3824aa43c215SJeff Kirsher { 3825aa43c215SJeff Kirsher struct in_device *indev; 3826aa43c215SJeff Kirsher 3827aa43c215SJeff Kirsher indev = in_dev_get(dev); 3828aa43c215SJeff Kirsher if (!indev) 3829aa43c215SJeff Kirsher return; 3830aa43c215SJeff Kirsher 3831aa43c215SJeff Kirsher for_ifa(indev) { 3832aa43c215SJeff Kirsher switch (event) { 3833aa43c215SJeff Kirsher case NETDEV_UP: 3834aa43c215SJeff Kirsher qlcnic_config_ipaddr(adapter, 3835aa43c215SJeff Kirsher ifa->ifa_address, QLCNIC_IP_UP); 3836aa43c215SJeff Kirsher break; 3837aa43c215SJeff Kirsher case NETDEV_DOWN: 3838aa43c215SJeff Kirsher qlcnic_config_ipaddr(adapter, 3839aa43c215SJeff Kirsher ifa->ifa_address, QLCNIC_IP_DOWN); 3840aa43c215SJeff Kirsher break; 3841aa43c215SJeff Kirsher default: 3842aa43c215SJeff Kirsher break; 3843aa43c215SJeff Kirsher } 3844aa43c215SJeff Kirsher } endfor_ifa(indev); 3845aa43c215SJeff Kirsher 3846aa43c215SJeff Kirsher in_dev_put(indev); 3847aa43c215SJeff Kirsher } 3848aa43c215SJeff Kirsher 3849319ecf12SSony Chacko void qlcnic_restore_indev_addr(struct net_device *netdev, unsigned long event) 3850aa43c215SJeff Kirsher { 3851aa43c215SJeff Kirsher struct qlcnic_adapter *adapter = netdev_priv(netdev); 3852aa43c215SJeff Kirsher struct net_device *dev; 3853aa43c215SJeff Kirsher u16 vid; 3854aa43c215SJeff Kirsher 3855aa43c215SJeff Kirsher qlcnic_config_indev_addr(adapter, netdev, event); 3856aa43c215SJeff Kirsher 385743c00a75SJiri Pirko rcu_read_lock(); 3858aa43c215SJeff Kirsher for_each_set_bit(vid, adapter->vlans, VLAN_N_VID) { 38591fd9b1fcSPatrick McHardy dev = __vlan_find_dev_deep(netdev, htons(ETH_P_8021Q), vid); 3860aa43c215SJeff Kirsher if (!dev) 3861aa43c215SJeff Kirsher continue; 3862aa43c215SJeff Kirsher qlcnic_config_indev_addr(adapter, dev, event); 3863aa43c215SJeff Kirsher } 386443c00a75SJiri Pirko rcu_read_unlock(); 3865aa43c215SJeff Kirsher } 3866aa43c215SJeff Kirsher 3867aa43c215SJeff Kirsher static int qlcnic_netdev_event(struct notifier_block *this, 3868aa43c215SJeff Kirsher unsigned long event, void *ptr) 3869aa43c215SJeff Kirsher { 3870aa43c215SJeff Kirsher struct qlcnic_adapter *adapter; 3871351638e7SJiri Pirko struct net_device *dev = netdev_notifier_info_to_dev(ptr); 3872aa43c215SJeff Kirsher 3873aa43c215SJeff Kirsher recheck: 3874aa43c215SJeff Kirsher if (dev == NULL) 3875aa43c215SJeff Kirsher goto done; 3876aa43c215SJeff Kirsher 3877aa43c215SJeff Kirsher if (dev->priv_flags & IFF_802_1Q_VLAN) { 3878aa43c215SJeff Kirsher dev = vlan_dev_real_dev(dev); 3879aa43c215SJeff Kirsher goto recheck; 3880aa43c215SJeff Kirsher } 3881aa43c215SJeff Kirsher 3882aa43c215SJeff Kirsher if (!is_qlcnic_netdev(dev)) 3883aa43c215SJeff Kirsher goto done; 3884aa43c215SJeff Kirsher 3885aa43c215SJeff Kirsher adapter = netdev_priv(dev); 3886aa43c215SJeff Kirsher 3887aa43c215SJeff Kirsher if (!adapter) 3888aa43c215SJeff Kirsher goto done; 3889aa43c215SJeff Kirsher 3890aa43c215SJeff Kirsher if (!test_bit(__QLCNIC_DEV_UP, &adapter->state)) 3891aa43c215SJeff Kirsher goto done; 3892aa43c215SJeff Kirsher 3893aa43c215SJeff Kirsher qlcnic_config_indev_addr(adapter, dev, event); 3894aa43c215SJeff Kirsher done: 3895aa43c215SJeff Kirsher return NOTIFY_DONE; 3896aa43c215SJeff Kirsher } 3897aa43c215SJeff Kirsher 3898aa43c215SJeff Kirsher static int 3899aa43c215SJeff Kirsher qlcnic_inetaddr_event(struct notifier_block *this, 3900aa43c215SJeff Kirsher unsigned long event, void *ptr) 3901aa43c215SJeff Kirsher { 3902aa43c215SJeff Kirsher struct qlcnic_adapter *adapter; 3903aa43c215SJeff Kirsher struct net_device *dev; 3904aa43c215SJeff Kirsher 3905aa43c215SJeff Kirsher struct in_ifaddr *ifa = (struct in_ifaddr *)ptr; 3906aa43c215SJeff Kirsher 3907aa43c215SJeff Kirsher dev = ifa->ifa_dev ? ifa->ifa_dev->dev : NULL; 3908aa43c215SJeff Kirsher 3909aa43c215SJeff Kirsher recheck: 3910aa43c215SJeff Kirsher if (dev == NULL) 3911aa43c215SJeff Kirsher goto done; 3912aa43c215SJeff Kirsher 3913aa43c215SJeff Kirsher if (dev->priv_flags & IFF_802_1Q_VLAN) { 3914aa43c215SJeff Kirsher dev = vlan_dev_real_dev(dev); 3915aa43c215SJeff Kirsher goto recheck; 3916aa43c215SJeff Kirsher } 3917aa43c215SJeff Kirsher 3918aa43c215SJeff Kirsher if (!is_qlcnic_netdev(dev)) 3919aa43c215SJeff Kirsher goto done; 3920aa43c215SJeff Kirsher 3921aa43c215SJeff Kirsher adapter = netdev_priv(dev); 3922aa43c215SJeff Kirsher 3923aa43c215SJeff Kirsher if (!adapter) 3924aa43c215SJeff Kirsher goto done; 3925aa43c215SJeff Kirsher 3926aa43c215SJeff Kirsher if (!test_bit(__QLCNIC_DEV_UP, &adapter->state)) 3927aa43c215SJeff Kirsher goto done; 3928aa43c215SJeff Kirsher 3929aa43c215SJeff Kirsher switch (event) { 3930aa43c215SJeff Kirsher case NETDEV_UP: 3931aa43c215SJeff Kirsher qlcnic_config_ipaddr(adapter, ifa->ifa_address, QLCNIC_IP_UP); 393213159183SSony Chacko 3933aa43c215SJeff Kirsher break; 3934aa43c215SJeff Kirsher case NETDEV_DOWN: 3935aa43c215SJeff Kirsher qlcnic_config_ipaddr(adapter, ifa->ifa_address, QLCNIC_IP_DOWN); 393613159183SSony Chacko 3937aa43c215SJeff Kirsher break; 3938aa43c215SJeff Kirsher default: 3939aa43c215SJeff Kirsher break; 3940aa43c215SJeff Kirsher } 3941aa43c215SJeff Kirsher 3942aa43c215SJeff Kirsher done: 3943aa43c215SJeff Kirsher return NOTIFY_DONE; 3944aa43c215SJeff Kirsher } 3945aa43c215SJeff Kirsher 3946aa43c215SJeff Kirsher static struct notifier_block qlcnic_netdev_cb = { 3947aa43c215SJeff Kirsher .notifier_call = qlcnic_netdev_event, 3948aa43c215SJeff Kirsher }; 3949aa43c215SJeff Kirsher 3950aa43c215SJeff Kirsher static struct notifier_block qlcnic_inetaddr_cb = { 3951aa43c215SJeff Kirsher .notifier_call = qlcnic_inetaddr_event, 3952aa43c215SJeff Kirsher }; 3953aa43c215SJeff Kirsher #else 3954f8ca2b6fSSony Chacko void qlcnic_restore_indev_addr(struct net_device *dev, unsigned long event) 3955aa43c215SJeff Kirsher { } 3956aa43c215SJeff Kirsher #endif 3957fec9dd15SStephen Hemminger static const struct pci_error_handlers qlcnic_err_handler = { 3958aa43c215SJeff Kirsher .error_detected = qlcnic_io_error_detected, 3959aa43c215SJeff Kirsher .slot_reset = qlcnic_io_slot_reset, 3960aa43c215SJeff Kirsher .resume = qlcnic_io_resume, 3961aa43c215SJeff Kirsher }; 3962aa43c215SJeff Kirsher 3963aa43c215SJeff Kirsher static struct pci_driver qlcnic_driver = { 3964aa43c215SJeff Kirsher .name = qlcnic_driver_name, 3965aa43c215SJeff Kirsher .id_table = qlcnic_pci_tbl, 3966aa43c215SJeff Kirsher .probe = qlcnic_probe, 39676bb58bb0SBill Pemberton .remove = qlcnic_remove, 3968aa43c215SJeff Kirsher #ifdef CONFIG_PM 3969aa43c215SJeff Kirsher .suspend = qlcnic_suspend, 3970aa43c215SJeff Kirsher .resume = qlcnic_resume, 3971aa43c215SJeff Kirsher #endif 3972aa43c215SJeff Kirsher .shutdown = qlcnic_shutdown, 397302feda17SRajesh Borundia .err_handler = &qlcnic_err_handler, 397402feda17SRajesh Borundia #ifdef CONFIG_QLCNIC_SRIOV 397502feda17SRajesh Borundia .sriov_configure = qlcnic_pci_sriov_configure, 397602feda17SRajesh Borundia #endif 3977aa43c215SJeff Kirsher 3978aa43c215SJeff Kirsher }; 3979aa43c215SJeff Kirsher 3980aa43c215SJeff Kirsher static int __init qlcnic_init_module(void) 3981aa43c215SJeff Kirsher { 3982aa43c215SJeff Kirsher int ret; 3983aa43c215SJeff Kirsher 3984aa43c215SJeff Kirsher printk(KERN_INFO "%s\n", qlcnic_driver_string); 3985aa43c215SJeff Kirsher 3986aa43c215SJeff Kirsher #ifdef CONFIG_INET 3987aa43c215SJeff Kirsher register_netdevice_notifier(&qlcnic_netdev_cb); 3988aa43c215SJeff Kirsher register_inetaddr_notifier(&qlcnic_inetaddr_cb); 3989aa43c215SJeff Kirsher #endif 3990aa43c215SJeff Kirsher 3991aa43c215SJeff Kirsher ret = pci_register_driver(&qlcnic_driver); 3992aa43c215SJeff Kirsher if (ret) { 3993aa43c215SJeff Kirsher #ifdef CONFIG_INET 3994aa43c215SJeff Kirsher unregister_inetaddr_notifier(&qlcnic_inetaddr_cb); 3995aa43c215SJeff Kirsher unregister_netdevice_notifier(&qlcnic_netdev_cb); 3996aa43c215SJeff Kirsher #endif 3997aa43c215SJeff Kirsher } 3998aa43c215SJeff Kirsher 3999aa43c215SJeff Kirsher return ret; 4000aa43c215SJeff Kirsher } 4001aa43c215SJeff Kirsher 4002aa43c215SJeff Kirsher module_init(qlcnic_init_module); 4003aa43c215SJeff Kirsher 4004aa43c215SJeff Kirsher static void __exit qlcnic_exit_module(void) 4005aa43c215SJeff Kirsher { 4006aa43c215SJeff Kirsher pci_unregister_driver(&qlcnic_driver); 4007aa43c215SJeff Kirsher 4008aa43c215SJeff Kirsher #ifdef CONFIG_INET 4009aa43c215SJeff Kirsher unregister_inetaddr_notifier(&qlcnic_inetaddr_cb); 4010aa43c215SJeff Kirsher unregister_netdevice_notifier(&qlcnic_netdev_cb); 4011aa43c215SJeff Kirsher #endif 4012aa43c215SJeff Kirsher } 4013aa43c215SJeff Kirsher 4014aa43c215SJeff Kirsher module_exit(qlcnic_exit_module); 4015