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; 1181aa43c215SJeff Kirsher adapter->flags &= ~QLCNIC_ESWITCH_ENABLED; 118234e8c406SHimanshu Madhani } 1183aa43c215SJeff Kirsher 1184aa43c215SJeff Kirsher return err; 1185aa43c215SJeff Kirsher } 1186aa43c215SJeff Kirsher 1187ec079a07SSony Chacko void qlcnic_set_vlan_config(struct qlcnic_adapter *adapter, 1188aa43c215SJeff Kirsher struct qlcnic_esw_func_cfg *esw_cfg) 1189aa43c215SJeff Kirsher { 1190aa43c215SJeff Kirsher if (esw_cfg->discard_tagged) 1191aa43c215SJeff Kirsher adapter->flags &= ~QLCNIC_TAGGING_ENABLED; 1192aa43c215SJeff Kirsher else 1193aa43c215SJeff Kirsher adapter->flags |= QLCNIC_TAGGING_ENABLED; 1194aa43c215SJeff Kirsher 119591b7282bSRajesh Borundia if (esw_cfg->vlan_id) { 119691b7282bSRajesh Borundia adapter->rx_pvid = esw_cfg->vlan_id; 119791b7282bSRajesh Borundia adapter->tx_pvid = esw_cfg->vlan_id; 119891b7282bSRajesh Borundia } else { 119991b7282bSRajesh Borundia adapter->rx_pvid = 0; 120091b7282bSRajesh Borundia adapter->tx_pvid = 0; 120191b7282bSRajesh Borundia } 1202aa43c215SJeff Kirsher } 1203aa43c215SJeff Kirsher 12048e586137SJiri Pirko static int 120580d5c368SPatrick McHardy qlcnic_vlan_rx_add(struct net_device *netdev, __be16 proto, u16 vid) 1206aa43c215SJeff Kirsher { 1207aa43c215SJeff Kirsher struct qlcnic_adapter *adapter = netdev_priv(netdev); 120891b7282bSRajesh Borundia int err; 120991b7282bSRajesh Borundia 121091b7282bSRajesh Borundia if (qlcnic_sriov_vf_check(adapter)) { 121191b7282bSRajesh Borundia err = qlcnic_sriov_cfg_vf_guest_vlan(adapter, vid, 1); 121291b7282bSRajesh Borundia if (err) { 121391b7282bSRajesh Borundia netdev_err(netdev, 121491b7282bSRajesh Borundia "Cannot add VLAN filter for VLAN id %d, err=%d", 121591b7282bSRajesh Borundia vid, err); 121691b7282bSRajesh Borundia return err; 121791b7282bSRajesh Borundia } 121891b7282bSRajesh Borundia } 121991b7282bSRajesh Borundia 1220aa43c215SJeff Kirsher set_bit(vid, adapter->vlans); 12218e586137SJiri Pirko return 0; 1222aa43c215SJeff Kirsher } 1223aa43c215SJeff Kirsher 12248e586137SJiri Pirko static int 122580d5c368SPatrick McHardy qlcnic_vlan_rx_del(struct net_device *netdev, __be16 proto, u16 vid) 1226aa43c215SJeff Kirsher { 1227aa43c215SJeff Kirsher struct qlcnic_adapter *adapter = netdev_priv(netdev); 122891b7282bSRajesh Borundia int err; 122991b7282bSRajesh Borundia 123091b7282bSRajesh Borundia if (qlcnic_sriov_vf_check(adapter)) { 123191b7282bSRajesh Borundia err = qlcnic_sriov_cfg_vf_guest_vlan(adapter, vid, 0); 123291b7282bSRajesh Borundia if (err) { 123391b7282bSRajesh Borundia netdev_err(netdev, 123491b7282bSRajesh Borundia "Cannot delete VLAN filter for VLAN id %d, err=%d", 123591b7282bSRajesh Borundia vid, err); 123691b7282bSRajesh Borundia return err; 123791b7282bSRajesh Borundia } 123891b7282bSRajesh Borundia } 1239aa43c215SJeff Kirsher 1240aa43c215SJeff Kirsher qlcnic_restore_indev_addr(netdev, NETDEV_DOWN); 1241aa43c215SJeff Kirsher clear_bit(vid, adapter->vlans); 12428e586137SJiri Pirko return 0; 1243aa43c215SJeff Kirsher } 1244aa43c215SJeff Kirsher 1245ec079a07SSony Chacko void qlcnic_set_eswitch_port_features(struct qlcnic_adapter *adapter, 1246aa43c215SJeff Kirsher struct qlcnic_esw_func_cfg *esw_cfg) 1247aa43c215SJeff Kirsher { 1248aa43c215SJeff Kirsher adapter->flags &= ~(QLCNIC_MACSPOOF | QLCNIC_MAC_OVERRIDE_DISABLED | 1249aa43c215SJeff Kirsher QLCNIC_PROMISC_DISABLED); 1250aa43c215SJeff Kirsher 1251aa43c215SJeff Kirsher if (esw_cfg->mac_anti_spoof) 1252aa43c215SJeff Kirsher adapter->flags |= QLCNIC_MACSPOOF; 1253aa43c215SJeff Kirsher 1254aa43c215SJeff Kirsher if (!esw_cfg->mac_override) 1255aa43c215SJeff Kirsher adapter->flags |= QLCNIC_MAC_OVERRIDE_DISABLED; 1256aa43c215SJeff Kirsher 1257aa43c215SJeff Kirsher if (!esw_cfg->promisc_mode) 1258aa43c215SJeff Kirsher adapter->flags |= QLCNIC_PROMISC_DISABLED; 1259aa43c215SJeff Kirsher } 1260aa43c215SJeff Kirsher 1261d71170fbSSony Chacko int qlcnic_set_eswitch_port_config(struct qlcnic_adapter *adapter) 1262aa43c215SJeff Kirsher { 1263aa43c215SJeff Kirsher struct qlcnic_esw_func_cfg esw_cfg; 1264aa43c215SJeff Kirsher 1265aa43c215SJeff Kirsher if (!(adapter->flags & QLCNIC_ESWITCH_ENABLED)) 1266aa43c215SJeff Kirsher return 0; 1267aa43c215SJeff Kirsher 1268aa43c215SJeff Kirsher esw_cfg.pci_func = adapter->ahw->pci_func; 1269aa43c215SJeff Kirsher if (qlcnic_get_eswitch_port_config(adapter, &esw_cfg)) 1270aa43c215SJeff Kirsher return -EIO; 1271aa43c215SJeff Kirsher qlcnic_set_vlan_config(adapter, &esw_cfg); 1272aa43c215SJeff Kirsher qlcnic_set_eswitch_port_features(adapter, &esw_cfg); 1273147a9088SShahed Shaikh qlcnic_set_netdev_features(adapter, &esw_cfg); 1274aa43c215SJeff Kirsher 1275aa43c215SJeff Kirsher return 0; 1276aa43c215SJeff Kirsher } 1277aa43c215SJeff Kirsher 1278147a9088SShahed Shaikh void qlcnic_set_netdev_features(struct qlcnic_adapter *adapter, 1279aa43c215SJeff Kirsher struct qlcnic_esw_func_cfg *esw_cfg) 1280aa43c215SJeff Kirsher { 1281aa43c215SJeff Kirsher struct net_device *netdev = adapter->netdev; 1282aa43c215SJeff Kirsher 128313159183SSony Chacko if (qlcnic_83xx_check(adapter)) 128413159183SSony Chacko return; 128513159183SSony Chacko 1286147a9088SShahed Shaikh adapter->offload_flags = esw_cfg->offload_flags; 1287147a9088SShahed Shaikh adapter->flags |= QLCNIC_APP_CHANGED_FLAGS; 1288147a9088SShahed Shaikh netdev_update_features(netdev); 1289147a9088SShahed Shaikh adapter->flags &= ~QLCNIC_APP_CHANGED_FLAGS; 1290aa43c215SJeff Kirsher } 1291aa43c215SJeff Kirsher 1292aa43c215SJeff Kirsher static int 1293aa43c215SJeff Kirsher qlcnic_check_eswitch_mode(struct qlcnic_adapter *adapter) 1294aa43c215SJeff Kirsher { 1295aa43c215SJeff Kirsher u32 op_mode, priv_level; 1296aa43c215SJeff Kirsher int err = 0; 1297aa43c215SJeff Kirsher 1298aa43c215SJeff Kirsher err = qlcnic_initialize_nic(adapter); 1299aa43c215SJeff Kirsher if (err) 1300aa43c215SJeff Kirsher return err; 1301aa43c215SJeff Kirsher 1302aa43c215SJeff Kirsher if (adapter->flags & QLCNIC_ADAPTER_INITIALIZED) 1303aa43c215SJeff Kirsher return 0; 1304aa43c215SJeff Kirsher 130513159183SSony Chacko op_mode = QLC_SHARED_REG_RD32(adapter, QLCNIC_DRV_OP_MODE); 1306aa43c215SJeff Kirsher priv_level = QLC_DEV_GET_DRV(op_mode, adapter->ahw->pci_func); 1307aa43c215SJeff Kirsher 1308aa43c215SJeff Kirsher if (op_mode == QLC_DEV_DRV_DEFAULT) 1309aa43c215SJeff Kirsher priv_level = QLCNIC_MGMT_FUNC; 1310aa43c215SJeff Kirsher else 1311aa43c215SJeff Kirsher priv_level = QLC_DEV_GET_DRV(op_mode, adapter->ahw->pci_func); 1312aa43c215SJeff Kirsher 1313aa43c215SJeff Kirsher if (adapter->flags & QLCNIC_ESWITCH_ENABLED) { 1314aa43c215SJeff Kirsher if (priv_level == QLCNIC_MGMT_FUNC) { 131579788450SSony Chacko adapter->ahw->op_mode = QLCNIC_MGMT_FUNC; 1316aa43c215SJeff Kirsher err = qlcnic_init_pci_info(adapter); 1317aa43c215SJeff Kirsher if (err) 1318aa43c215SJeff Kirsher return err; 1319aa43c215SJeff Kirsher /* Set privilege level for other functions */ 1320aa43c215SJeff Kirsher qlcnic_set_function_modes(adapter); 1321aa43c215SJeff Kirsher dev_info(&adapter->pdev->dev, 1322aa43c215SJeff Kirsher "HAL Version: %d, Management function\n", 132379788450SSony Chacko adapter->ahw->fw_hal_version); 1324aa43c215SJeff Kirsher } else if (priv_level == QLCNIC_PRIV_FUNC) { 132579788450SSony Chacko adapter->ahw->op_mode = QLCNIC_PRIV_FUNC; 1326aa43c215SJeff Kirsher dev_info(&adapter->pdev->dev, 1327aa43c215SJeff Kirsher "HAL Version: %d, Privileged function\n", 132879788450SSony Chacko adapter->ahw->fw_hal_version); 1329aa43c215SJeff Kirsher } 133034e8c406SHimanshu Madhani } else { 133134e8c406SHimanshu Madhani adapter->ahw->nic_mode = QLCNIC_DEFAULT_MODE; 1332aa43c215SJeff Kirsher } 1333aa43c215SJeff Kirsher 1334aa43c215SJeff Kirsher adapter->flags |= QLCNIC_ADAPTER_INITIALIZED; 1335aa43c215SJeff Kirsher 1336aa43c215SJeff Kirsher return err; 1337aa43c215SJeff Kirsher } 1338aa43c215SJeff Kirsher 1339d71170fbSSony Chacko int qlcnic_set_default_offload_settings(struct qlcnic_adapter *adapter) 1340aa43c215SJeff Kirsher { 1341aa43c215SJeff Kirsher struct qlcnic_esw_func_cfg esw_cfg; 1342aa43c215SJeff Kirsher struct qlcnic_npar_info *npar; 1343aa43c215SJeff Kirsher u8 i; 1344aa43c215SJeff Kirsher 1345aa43c215SJeff Kirsher if (adapter->need_fw_reset) 1346aa43c215SJeff Kirsher return 0; 1347aa43c215SJeff Kirsher 1348bff57d8eSSony Chacko for (i = 0; i < adapter->ahw->act_pci_func; i++) { 134935dafcb0SSony Chacko if (!adapter->npars[i].eswitch_status) 135035dafcb0SSony Chacko continue; 135135dafcb0SSony Chacko 1352aa43c215SJeff Kirsher memset(&esw_cfg, 0, sizeof(struct qlcnic_esw_func_cfg)); 1353bff57d8eSSony Chacko esw_cfg.pci_func = adapter->npars[i].pci_func; 1354aa43c215SJeff Kirsher esw_cfg.mac_override = BIT_0; 1355aa43c215SJeff Kirsher esw_cfg.promisc_mode = BIT_0; 1356bff57d8eSSony Chacko if (qlcnic_82xx_check(adapter)) { 1357bff57d8eSSony Chacko esw_cfg.offload_flags = BIT_0; 1358bff57d8eSSony Chacko if (QLCNIC_IS_TSO_CAPABLE(adapter)) 1359aa43c215SJeff Kirsher esw_cfg.offload_flags |= (BIT_1 | BIT_2); 1360bff57d8eSSony Chacko } 1361aa43c215SJeff Kirsher if (qlcnic_config_switch_port(adapter, &esw_cfg)) 1362aa43c215SJeff Kirsher return -EIO; 1363aa43c215SJeff Kirsher npar = &adapter->npars[i]; 1364aa43c215SJeff Kirsher npar->pvid = esw_cfg.vlan_id; 1365aa43c215SJeff Kirsher npar->mac_override = esw_cfg.mac_override; 1366aa43c215SJeff Kirsher npar->mac_anti_spoof = esw_cfg.mac_anti_spoof; 1367aa43c215SJeff Kirsher npar->discard_tagged = esw_cfg.discard_tagged; 1368aa43c215SJeff Kirsher npar->promisc_mode = esw_cfg.promisc_mode; 1369aa43c215SJeff Kirsher npar->offload_flags = esw_cfg.offload_flags; 1370aa43c215SJeff Kirsher } 1371aa43c215SJeff Kirsher 1372aa43c215SJeff Kirsher return 0; 1373aa43c215SJeff Kirsher } 1374aa43c215SJeff Kirsher 137513159183SSony Chacko 1376aa43c215SJeff Kirsher static int 1377aa43c215SJeff Kirsher qlcnic_reset_eswitch_config(struct qlcnic_adapter *adapter, 1378aa43c215SJeff Kirsher struct qlcnic_npar_info *npar, int pci_func) 1379aa43c215SJeff Kirsher { 1380aa43c215SJeff Kirsher struct qlcnic_esw_func_cfg esw_cfg; 1381aa43c215SJeff Kirsher esw_cfg.op_mode = QLCNIC_PORT_DEFAULTS; 1382aa43c215SJeff Kirsher esw_cfg.pci_func = pci_func; 1383aa43c215SJeff Kirsher esw_cfg.vlan_id = npar->pvid; 1384aa43c215SJeff Kirsher esw_cfg.mac_override = npar->mac_override; 1385aa43c215SJeff Kirsher esw_cfg.discard_tagged = npar->discard_tagged; 1386aa43c215SJeff Kirsher esw_cfg.mac_anti_spoof = npar->mac_anti_spoof; 1387aa43c215SJeff Kirsher esw_cfg.offload_flags = npar->offload_flags; 1388aa43c215SJeff Kirsher esw_cfg.promisc_mode = npar->promisc_mode; 1389aa43c215SJeff Kirsher if (qlcnic_config_switch_port(adapter, &esw_cfg)) 1390aa43c215SJeff Kirsher return -EIO; 1391aa43c215SJeff Kirsher 1392aa43c215SJeff Kirsher esw_cfg.op_mode = QLCNIC_ADD_VLAN; 1393aa43c215SJeff Kirsher if (qlcnic_config_switch_port(adapter, &esw_cfg)) 1394aa43c215SJeff Kirsher return -EIO; 1395aa43c215SJeff Kirsher 1396aa43c215SJeff Kirsher return 0; 1397aa43c215SJeff Kirsher } 1398aa43c215SJeff Kirsher 1399d71170fbSSony Chacko int qlcnic_reset_npar_config(struct qlcnic_adapter *adapter) 1400aa43c215SJeff Kirsher { 1401aa43c215SJeff Kirsher int i, err; 1402aa43c215SJeff Kirsher struct qlcnic_npar_info *npar; 1403aa43c215SJeff Kirsher struct qlcnic_info nic_info; 1404bff57d8eSSony Chacko u8 pci_func; 1405aa43c215SJeff Kirsher 1406bff57d8eSSony Chacko if (qlcnic_82xx_check(adapter)) 1407aa43c215SJeff Kirsher if (!adapter->need_fw_reset) 1408aa43c215SJeff Kirsher return 0; 1409aa43c215SJeff Kirsher 1410aa43c215SJeff Kirsher /* Set the NPAR config data after FW reset */ 1411bff57d8eSSony Chacko for (i = 0; i < adapter->ahw->act_pci_func; i++) { 1412aa43c215SJeff Kirsher npar = &adapter->npars[i]; 1413bff57d8eSSony Chacko pci_func = npar->pci_func; 141435dafcb0SSony Chacko if (!adapter->npars[i].eswitch_status) 141535dafcb0SSony Chacko continue; 141635dafcb0SSony Chacko 1417bff57d8eSSony Chacko memset(&nic_info, 0, sizeof(struct qlcnic_info)); 141813159183SSony Chacko err = qlcnic_get_nic_info(adapter, &nic_info, pci_func); 1419aa43c215SJeff Kirsher if (err) 1420aa43c215SJeff Kirsher return err; 1421aa43c215SJeff Kirsher nic_info.min_tx_bw = npar->min_bw; 1422aa43c215SJeff Kirsher nic_info.max_tx_bw = npar->max_bw; 1423aa43c215SJeff Kirsher err = qlcnic_set_nic_info(adapter, &nic_info); 1424aa43c215SJeff Kirsher if (err) 1425aa43c215SJeff Kirsher return err; 1426aa43c215SJeff Kirsher 1427aa43c215SJeff Kirsher if (npar->enable_pm) { 1428aa43c215SJeff Kirsher err = qlcnic_config_port_mirroring(adapter, 1429bff57d8eSSony Chacko npar->dest_npar, 1, 1430bff57d8eSSony Chacko pci_func); 1431aa43c215SJeff Kirsher if (err) 1432aa43c215SJeff Kirsher return err; 1433aa43c215SJeff Kirsher } 1434bff57d8eSSony Chacko err = qlcnic_reset_eswitch_config(adapter, npar, pci_func); 1435aa43c215SJeff Kirsher if (err) 1436aa43c215SJeff Kirsher return err; 1437aa43c215SJeff Kirsher } 1438aa43c215SJeff Kirsher return 0; 1439aa43c215SJeff Kirsher } 1440aa43c215SJeff Kirsher 1441aa43c215SJeff Kirsher static int qlcnic_check_npar_opertional(struct qlcnic_adapter *adapter) 1442aa43c215SJeff Kirsher { 1443aa43c215SJeff Kirsher u8 npar_opt_timeo = QLCNIC_DEV_NPAR_OPER_TIMEO; 1444aa43c215SJeff Kirsher u32 npar_state; 1445aa43c215SJeff Kirsher 144679788450SSony Chacko if (adapter->ahw->op_mode == QLCNIC_MGMT_FUNC) 1447aa43c215SJeff Kirsher return 0; 1448aa43c215SJeff Kirsher 1449a15ebd37SHimanshu Madhani npar_state = QLC_SHARED_REG_RD32(adapter, 1450a15ebd37SHimanshu Madhani QLCNIC_CRB_DEV_NPAR_STATE); 1451aa43c215SJeff Kirsher while (npar_state != QLCNIC_DEV_NPAR_OPER && --npar_opt_timeo) { 1452aa43c215SJeff Kirsher msleep(1000); 1453a15ebd37SHimanshu Madhani npar_state = QLC_SHARED_REG_RD32(adapter, 1454a15ebd37SHimanshu Madhani QLCNIC_CRB_DEV_NPAR_STATE); 1455aa43c215SJeff Kirsher } 1456aa43c215SJeff Kirsher if (!npar_opt_timeo) { 1457aa43c215SJeff Kirsher dev_err(&adapter->pdev->dev, 14588a168ca7SMasanari Iida "Waiting for NPAR state to operational timeout\n"); 1459aa43c215SJeff Kirsher return -EIO; 1460aa43c215SJeff Kirsher } 1461aa43c215SJeff Kirsher return 0; 1462aa43c215SJeff Kirsher } 1463aa43c215SJeff Kirsher 1464aa43c215SJeff Kirsher static int 1465aa43c215SJeff Kirsher qlcnic_set_mgmt_operations(struct qlcnic_adapter *adapter) 1466aa43c215SJeff Kirsher { 1467aa43c215SJeff Kirsher int err; 1468aa43c215SJeff Kirsher 1469aa43c215SJeff Kirsher if (!(adapter->flags & QLCNIC_ESWITCH_ENABLED) || 147079788450SSony Chacko adapter->ahw->op_mode != QLCNIC_MGMT_FUNC) 1471aa43c215SJeff Kirsher return 0; 1472aa43c215SJeff Kirsher 1473aa43c215SJeff Kirsher err = qlcnic_set_default_offload_settings(adapter); 1474aa43c215SJeff Kirsher if (err) 1475aa43c215SJeff Kirsher return err; 1476aa43c215SJeff Kirsher 1477aa43c215SJeff Kirsher err = qlcnic_reset_npar_config(adapter); 1478aa43c215SJeff Kirsher if (err) 1479aa43c215SJeff Kirsher return err; 1480aa43c215SJeff Kirsher 1481aa43c215SJeff Kirsher qlcnic_dev_set_npar_ready(adapter); 1482aa43c215SJeff Kirsher 1483aa43c215SJeff Kirsher return err; 1484aa43c215SJeff Kirsher } 1485aa43c215SJeff Kirsher 14867e2cf4feSSony Chacko int qlcnic_82xx_start_firmware(struct qlcnic_adapter *adapter) 1487aa43c215SJeff Kirsher { 1488aa43c215SJeff Kirsher int err; 1489aa43c215SJeff Kirsher 1490aa43c215SJeff Kirsher err = qlcnic_can_start_firmware(adapter); 1491aa43c215SJeff Kirsher if (err < 0) 1492aa43c215SJeff Kirsher return err; 1493aa43c215SJeff Kirsher else if (!err) 1494aa43c215SJeff Kirsher goto check_fw_status; 1495aa43c215SJeff Kirsher 1496099f7aa7SSony Chacko if (qlcnic_load_fw_file) 1497aa43c215SJeff Kirsher qlcnic_request_firmware(adapter); 1498aa43c215SJeff Kirsher else { 1499aa43c215SJeff Kirsher err = qlcnic_check_flash_fw_ver(adapter); 1500aa43c215SJeff Kirsher if (err) 1501aa43c215SJeff Kirsher goto err_out; 1502aa43c215SJeff Kirsher 150379788450SSony Chacko adapter->ahw->fw_type = QLCNIC_FLASH_ROMIMAGE; 1504aa43c215SJeff Kirsher } 1505aa43c215SJeff Kirsher 1506aa43c215SJeff Kirsher err = qlcnic_need_fw_reset(adapter); 1507aa43c215SJeff Kirsher if (err == 0) 1508aa43c215SJeff Kirsher goto check_fw_status; 1509aa43c215SJeff Kirsher 1510aa43c215SJeff Kirsher err = qlcnic_pinit_from_rom(adapter); 1511aa43c215SJeff Kirsher if (err) 1512aa43c215SJeff Kirsher goto err_out; 1513aa43c215SJeff Kirsher 1514aa43c215SJeff Kirsher err = qlcnic_load_firmware(adapter); 1515aa43c215SJeff Kirsher if (err) 1516aa43c215SJeff Kirsher goto err_out; 1517aa43c215SJeff Kirsher 1518aa43c215SJeff Kirsher qlcnic_release_firmware(adapter); 1519aa43c215SJeff Kirsher QLCWR32(adapter, CRB_DRIVER_VERSION, QLCNIC_DRIVER_VERSION); 1520aa43c215SJeff Kirsher 1521aa43c215SJeff Kirsher check_fw_status: 1522aa43c215SJeff Kirsher err = qlcnic_check_fw_status(adapter); 1523aa43c215SJeff Kirsher if (err) 1524aa43c215SJeff Kirsher goto err_out; 1525aa43c215SJeff Kirsher 1526a15ebd37SHimanshu Madhani QLC_SHARED_REG_WR32(adapter, QLCNIC_CRB_DEV_STATE, QLCNIC_DEV_READY); 1527aa43c215SJeff Kirsher qlcnic_idc_debug_info(adapter, 1); 1528aa43c215SJeff Kirsher err = qlcnic_check_eswitch_mode(adapter); 1529aa43c215SJeff Kirsher if (err) { 1530aa43c215SJeff Kirsher dev_err(&adapter->pdev->dev, 1531aa43c215SJeff Kirsher "Memory allocation failed for eswitch\n"); 1532aa43c215SJeff Kirsher goto err_out; 1533aa43c215SJeff Kirsher } 1534aa43c215SJeff Kirsher err = qlcnic_set_mgmt_operations(adapter); 1535aa43c215SJeff Kirsher if (err) 1536aa43c215SJeff Kirsher goto err_out; 1537aa43c215SJeff Kirsher 1538aa43c215SJeff Kirsher qlcnic_check_options(adapter); 1539aa43c215SJeff Kirsher adapter->need_fw_reset = 0; 1540aa43c215SJeff Kirsher 1541aa43c215SJeff Kirsher qlcnic_release_firmware(adapter); 1542aa43c215SJeff Kirsher return 0; 1543aa43c215SJeff Kirsher 1544aa43c215SJeff Kirsher err_out: 1545a15ebd37SHimanshu Madhani QLC_SHARED_REG_WR32(adapter, QLCNIC_CRB_DEV_STATE, QLCNIC_DEV_FAILED); 1546aa43c215SJeff Kirsher dev_err(&adapter->pdev->dev, "Device state set to failed\n"); 1547aa43c215SJeff Kirsher 1548aa43c215SJeff Kirsher qlcnic_release_firmware(adapter); 1549aa43c215SJeff Kirsher return err; 1550aa43c215SJeff Kirsher } 1551aa43c215SJeff Kirsher 1552aa43c215SJeff Kirsher static int 1553aa43c215SJeff Kirsher qlcnic_request_irq(struct qlcnic_adapter *adapter) 1554aa43c215SJeff Kirsher { 1555aa43c215SJeff Kirsher irq_handler_t handler; 1556aa43c215SJeff Kirsher struct qlcnic_host_sds_ring *sds_ring; 155713159183SSony Chacko struct qlcnic_host_tx_ring *tx_ring; 1558ddb2e174SHimanshu Madhani int err, ring, num_sds_rings; 1559aa43c215SJeff Kirsher 1560aa43c215SJeff Kirsher unsigned long flags = 0; 1561aa43c215SJeff Kirsher struct net_device *netdev = adapter->netdev; 1562aa43c215SJeff Kirsher struct qlcnic_recv_context *recv_ctx = adapter->recv_ctx; 1563aa43c215SJeff Kirsher 156479788450SSony Chacko if (adapter->ahw->diag_test == QLCNIC_INTERRUPT_TEST) { 156513159183SSony Chacko if (qlcnic_82xx_check(adapter)) 1566aa43c215SJeff Kirsher handler = qlcnic_tmp_intr; 1567c2534384SManish Chopra else 1568c2534384SManish Chopra handler = qlcnic_83xx_tmp_intr; 1569aa43c215SJeff Kirsher if (!QLCNIC_IS_MSI_FAMILY(adapter)) 1570aa43c215SJeff Kirsher flags |= IRQF_SHARED; 1571aa43c215SJeff Kirsher 1572aa43c215SJeff Kirsher } else { 1573aa43c215SJeff Kirsher if (adapter->flags & QLCNIC_MSIX_ENABLED) 1574aa43c215SJeff Kirsher handler = qlcnic_msix_intr; 1575aa43c215SJeff Kirsher else if (adapter->flags & QLCNIC_MSI_ENABLED) 1576aa43c215SJeff Kirsher handler = qlcnic_msi_intr; 1577aa43c215SJeff Kirsher else { 1578aa43c215SJeff Kirsher flags |= IRQF_SHARED; 1579ac166700SHimanshu Madhani if (qlcnic_82xx_check(adapter)) 1580aa43c215SJeff Kirsher handler = qlcnic_intr; 1581ac166700SHimanshu Madhani else 1582ac166700SHimanshu Madhani handler = qlcnic_83xx_intr; 1583aa43c215SJeff Kirsher } 1584aa43c215SJeff Kirsher } 1585aa43c215SJeff Kirsher adapter->irq = netdev->irq; 1586aa43c215SJeff Kirsher 158713159183SSony Chacko if (adapter->ahw->diag_test != QLCNIC_LOOPBACK_TEST) { 1588ac166700SHimanshu Madhani if (qlcnic_82xx_check(adapter) || 1589ac166700SHimanshu Madhani (qlcnic_83xx_check(adapter) && 1590ac166700SHimanshu Madhani (adapter->flags & QLCNIC_MSIX_ENABLED))) { 159134e8c406SHimanshu Madhani num_sds_rings = adapter->drv_sds_rings; 1592ddb2e174SHimanshu Madhani for (ring = 0; ring < num_sds_rings; ring++) { 1593aa43c215SJeff Kirsher sds_ring = &recv_ctx->sds_rings[ring]; 1594ddb2e174SHimanshu Madhani if (qlcnic_82xx_check(adapter) && 1595012ec812SHimanshu Madhani !qlcnic_check_multi_tx(adapter) && 1596aa2a8034SHimanshu Madhani (ring == (num_sds_rings - 1))) { 1597aa2a8034SHimanshu Madhani if (!(adapter->flags & 1598aa2a8034SHimanshu Madhani QLCNIC_MSIX_ENABLED)) 1599ddb2e174SHimanshu Madhani snprintf(sds_ring->name, 1600ddb2e174SHimanshu Madhani sizeof(sds_ring->name), 1601aa2a8034SHimanshu Madhani "qlcnic"); 1602ddb2e174SHimanshu Madhani else 1603ddb2e174SHimanshu Madhani snprintf(sds_ring->name, 1604ddb2e174SHimanshu Madhani sizeof(sds_ring->name), 1605aa2a8034SHimanshu Madhani "%s-tx-0-rx-%d", 1606ddb2e174SHimanshu Madhani netdev->name, ring); 1607aa2a8034SHimanshu Madhani } else { 1608aa2a8034SHimanshu Madhani snprintf(sds_ring->name, 1609aa2a8034SHimanshu Madhani sizeof(sds_ring->name), 1610aa2a8034SHimanshu Madhani "%s-rx-%d", 1611aa2a8034SHimanshu Madhani netdev->name, ring); 1612aa2a8034SHimanshu Madhani } 161313159183SSony Chacko err = request_irq(sds_ring->irq, handler, flags, 161413159183SSony Chacko sds_ring->name, sds_ring); 1615aa43c215SJeff Kirsher if (err) 1616aa43c215SJeff Kirsher return err; 1617aa43c215SJeff Kirsher } 1618ac166700SHimanshu Madhani } 1619012ec812SHimanshu Madhani if ((qlcnic_82xx_check(adapter) && 1620012ec812SHimanshu Madhani qlcnic_check_multi_tx(adapter)) || 1621012ec812SHimanshu Madhani (qlcnic_83xx_check(adapter) && 1622da6c8063SRajesh Borundia (adapter->flags & QLCNIC_MSIX_ENABLED) && 1623012ec812SHimanshu Madhani !(adapter->flags & QLCNIC_TX_INTR_SHARED))) { 162413159183SSony Chacko handler = qlcnic_msix_tx_intr; 162534e8c406SHimanshu Madhani for (ring = 0; ring < adapter->drv_tx_rings; 162613159183SSony Chacko ring++) { 162713159183SSony Chacko tx_ring = &adapter->tx_ring[ring]; 1628ddb2e174SHimanshu Madhani snprintf(tx_ring->name, sizeof(tx_ring->name), 1629aa2a8034SHimanshu Madhani "%s-tx-%d", netdev->name, ring); 163013159183SSony Chacko err = request_irq(tx_ring->irq, handler, flags, 163113159183SSony Chacko tx_ring->name, tx_ring); 163213159183SSony Chacko if (err) 163313159183SSony Chacko return err; 163413159183SSony Chacko } 163513159183SSony Chacko } 163613159183SSony Chacko } 1637aa43c215SJeff Kirsher return 0; 1638aa43c215SJeff Kirsher } 1639aa43c215SJeff Kirsher 1640aa43c215SJeff Kirsher static void 1641aa43c215SJeff Kirsher qlcnic_free_irq(struct qlcnic_adapter *adapter) 1642aa43c215SJeff Kirsher { 1643aa43c215SJeff Kirsher int ring; 1644aa43c215SJeff Kirsher struct qlcnic_host_sds_ring *sds_ring; 164513159183SSony Chacko struct qlcnic_host_tx_ring *tx_ring; 1646aa43c215SJeff Kirsher 1647aa43c215SJeff Kirsher struct qlcnic_recv_context *recv_ctx = adapter->recv_ctx; 1648aa43c215SJeff Kirsher 164913159183SSony Chacko if (adapter->ahw->diag_test != QLCNIC_LOOPBACK_TEST) { 1650ac166700SHimanshu Madhani if (qlcnic_82xx_check(adapter) || 1651ac166700SHimanshu Madhani (qlcnic_83xx_check(adapter) && 1652ac166700SHimanshu Madhani (adapter->flags & QLCNIC_MSIX_ENABLED))) { 165334e8c406SHimanshu Madhani for (ring = 0; ring < adapter->drv_sds_rings; ring++) { 1654aa43c215SJeff Kirsher sds_ring = &recv_ctx->sds_rings[ring]; 1655aa43c215SJeff Kirsher free_irq(sds_ring->irq, sds_ring); 1656aa43c215SJeff Kirsher } 1657ac166700SHimanshu Madhani } 1658012ec812SHimanshu Madhani if ((qlcnic_83xx_check(adapter) && 1659012ec812SHimanshu Madhani !(adapter->flags & QLCNIC_TX_INTR_SHARED)) || 1660012ec812SHimanshu Madhani (qlcnic_82xx_check(adapter) && 1661012ec812SHimanshu Madhani qlcnic_check_multi_tx(adapter))) { 166234e8c406SHimanshu Madhani for (ring = 0; ring < adapter->drv_tx_rings; 166313159183SSony Chacko ring++) { 166413159183SSony Chacko tx_ring = &adapter->tx_ring[ring]; 166513159183SSony Chacko if (tx_ring->irq) 166613159183SSony Chacko free_irq(tx_ring->irq, tx_ring); 166713159183SSony Chacko } 166813159183SSony Chacko } 166913159183SSony Chacko } 1670aa43c215SJeff Kirsher } 1671aa43c215SJeff Kirsher 167299e85879SShahed Shaikh static void qlcnic_get_lro_mss_capability(struct qlcnic_adapter *adapter) 167399e85879SShahed Shaikh { 167499e85879SShahed Shaikh u32 capab = 0; 167599e85879SShahed Shaikh 167699e85879SShahed Shaikh if (qlcnic_82xx_check(adapter)) { 1677db131786SPratik Pujar if (adapter->ahw->extra_capability[0] & 167899e85879SShahed Shaikh QLCNIC_FW_CAPABILITY_2_LRO_MAX_TCP_SEG) 167999e85879SShahed Shaikh adapter->flags |= QLCNIC_FW_LRO_MSS_CAP; 168099e85879SShahed Shaikh } else { 168199e85879SShahed Shaikh capab = adapter->ahw->capabilities; 168299e85879SShahed Shaikh if (QLC_83XX_GET_FW_LRO_MSS_CAPABILITY(capab)) 168399e85879SShahed Shaikh adapter->flags |= QLCNIC_FW_LRO_MSS_CAP; 168499e85879SShahed Shaikh } 168599e85879SShahed Shaikh } 168699e85879SShahed Shaikh 1687319ecf12SSony Chacko int __qlcnic_up(struct qlcnic_adapter *adapter, struct net_device *netdev) 1688aa43c215SJeff Kirsher { 1689aa43c215SJeff Kirsher int ring; 1690aa43c215SJeff Kirsher struct qlcnic_host_rds_ring *rds_ring; 1691aa43c215SJeff Kirsher 1692aa43c215SJeff Kirsher if (adapter->is_up != QLCNIC_ADAPTER_UP_MAGIC) 1693aa43c215SJeff Kirsher return -EIO; 1694aa43c215SJeff Kirsher 1695aa43c215SJeff Kirsher if (test_bit(__QLCNIC_DEV_UP, &adapter->state)) 1696aa43c215SJeff Kirsher return 0; 1697012ec812SHimanshu Madhani 1698aa43c215SJeff Kirsher if (qlcnic_set_eswitch_port_config(adapter)) 1699aa43c215SJeff Kirsher return -EIO; 1700012ec812SHimanshu Madhani 170199e85879SShahed Shaikh qlcnic_get_lro_mss_capability(adapter); 1702cae82d49SRajesh Borundia 1703aa43c215SJeff Kirsher if (qlcnic_fw_create_ctx(adapter)) 1704aa43c215SJeff Kirsher return -EIO; 1705aa43c215SJeff Kirsher 1706aa43c215SJeff Kirsher for (ring = 0; ring < adapter->max_rds_rings; ring++) { 1707aa43c215SJeff Kirsher rds_ring = &adapter->recv_ctx->rds_rings[ring]; 17084be41e92SSony Chacko qlcnic_post_rx_buffers(adapter, rds_ring, ring); 1709aa43c215SJeff Kirsher } 1710aa43c215SJeff Kirsher 1711aa43c215SJeff Kirsher qlcnic_set_multi(netdev); 1712aa43c215SJeff Kirsher qlcnic_fw_cmd_set_mtu(adapter, netdev->mtu); 1713aa43c215SJeff Kirsher 1714aa43c215SJeff Kirsher adapter->ahw->linkup = 0; 1715aa43c215SJeff Kirsher 171634e8c406SHimanshu Madhani if (adapter->drv_sds_rings > 1) 1717aa43c215SJeff Kirsher qlcnic_config_rss(adapter, 1); 1718aa43c215SJeff Kirsher 1719aa43c215SJeff Kirsher qlcnic_config_intr_coalesce(adapter); 1720aa43c215SJeff Kirsher 1721aa43c215SJeff Kirsher if (netdev->features & NETIF_F_LRO) 1722aa43c215SJeff Kirsher qlcnic_config_hw_lro(adapter, QLCNIC_LRO_ENABLED); 1723aa43c215SJeff Kirsher 1724cfacb172SPratik Pujar set_bit(__QLCNIC_DEV_UP, &adapter->state); 1725aa43c215SJeff Kirsher qlcnic_napi_enable(adapter); 1726aa43c215SJeff Kirsher 1727aa43c215SJeff Kirsher qlcnic_linkevent_request(adapter, 1); 1728aa43c215SJeff Kirsher 172979788450SSony Chacko adapter->ahw->reset_context = 0; 1730aa43c215SJeff Kirsher return 0; 1731aa43c215SJeff Kirsher } 1732aa43c215SJeff Kirsher 1733629263acSSony Chacko int qlcnic_up(struct qlcnic_adapter *adapter, struct net_device *netdev) 1734aa43c215SJeff Kirsher { 1735aa43c215SJeff Kirsher int err = 0; 1736aa43c215SJeff Kirsher 1737aa43c215SJeff Kirsher rtnl_lock(); 1738aa43c215SJeff Kirsher if (netif_running(netdev)) 1739aa43c215SJeff Kirsher err = __qlcnic_up(adapter, netdev); 1740aa43c215SJeff Kirsher rtnl_unlock(); 1741aa43c215SJeff Kirsher 1742aa43c215SJeff Kirsher return err; 1743aa43c215SJeff Kirsher } 1744aa43c215SJeff Kirsher 1745319ecf12SSony Chacko void __qlcnic_down(struct qlcnic_adapter *adapter, struct net_device *netdev) 1746aa43c215SJeff Kirsher { 1747012ec812SHimanshu Madhani int ring; 1748012ec812SHimanshu Madhani 1749aa43c215SJeff Kirsher if (adapter->is_up != QLCNIC_ADAPTER_UP_MAGIC) 1750aa43c215SJeff Kirsher return; 1751aa43c215SJeff Kirsher 1752aa43c215SJeff Kirsher if (!test_and_clear_bit(__QLCNIC_DEV_UP, &adapter->state)) 1753aa43c215SJeff Kirsher return; 1754aa43c215SJeff Kirsher 1755e8b508efSRajesh Borundia if (qlcnic_sriov_vf_check(adapter)) 1756e8b508efSRajesh Borundia qlcnic_sriov_cleanup_async_list(&adapter->ahw->sriov->bc); 1757aa43c215SJeff Kirsher smp_mb(); 175834e8c406SHimanshu Madhani spin_lock(&adapter->tx_clean_lock); 1759aa43c215SJeff Kirsher netif_carrier_off(netdev); 17600a46bac0SShahed Shaikh adapter->ahw->linkup = 0; 1761aa43c215SJeff Kirsher netif_tx_disable(netdev); 1762aa43c215SJeff Kirsher 1763aa43c215SJeff Kirsher qlcnic_free_mac_list(adapter); 1764aa43c215SJeff Kirsher 1765aa43c215SJeff Kirsher if (adapter->fhash.fnum) 1766aa43c215SJeff Kirsher qlcnic_delete_lb_filters(adapter); 1767aa43c215SJeff Kirsher 1768aa43c215SJeff Kirsher qlcnic_nic_set_promisc(adapter, QLCNIC_NIU_NON_PROMISC_MODE); 1769aa43c215SJeff Kirsher 1770aa43c215SJeff Kirsher qlcnic_napi_disable(adapter); 1771aa43c215SJeff Kirsher 1772aa43c215SJeff Kirsher qlcnic_fw_destroy_ctx(adapter); 1773cae82d49SRajesh Borundia adapter->flags &= ~QLCNIC_FW_LRO_MSS_CAP; 1774aa43c215SJeff Kirsher 1775aa43c215SJeff Kirsher qlcnic_reset_rx_buffers_list(adapter); 1776012ec812SHimanshu Madhani 177734e8c406SHimanshu Madhani for (ring = 0; ring < adapter->drv_tx_rings; ring++) 1778012ec812SHimanshu Madhani qlcnic_release_tx_buffers(adapter, &adapter->tx_ring[ring]); 177934e8c406SHimanshu Madhani spin_unlock(&adapter->tx_clean_lock); 1780aa43c215SJeff Kirsher } 1781aa43c215SJeff Kirsher 1782aa43c215SJeff Kirsher /* Usage: During suspend and firmware recovery module */ 1783aa43c215SJeff Kirsher 1784629263acSSony Chacko void qlcnic_down(struct qlcnic_adapter *adapter, struct net_device *netdev) 1785aa43c215SJeff Kirsher { 1786aa43c215SJeff Kirsher rtnl_lock(); 1787aa43c215SJeff Kirsher if (netif_running(netdev)) 1788aa43c215SJeff Kirsher __qlcnic_down(adapter, netdev); 1789aa43c215SJeff Kirsher rtnl_unlock(); 1790aa43c215SJeff Kirsher 1791aa43c215SJeff Kirsher } 1792aa43c215SJeff Kirsher 1793319ecf12SSony Chacko int 1794aa43c215SJeff Kirsher qlcnic_attach(struct qlcnic_adapter *adapter) 1795aa43c215SJeff Kirsher { 1796aa43c215SJeff Kirsher struct net_device *netdev = adapter->netdev; 1797aa43c215SJeff Kirsher struct pci_dev *pdev = adapter->pdev; 1798aa43c215SJeff Kirsher int err; 1799aa43c215SJeff Kirsher 1800aa43c215SJeff Kirsher if (adapter->is_up == QLCNIC_ADAPTER_UP_MAGIC) 1801aa43c215SJeff Kirsher return 0; 1802aa43c215SJeff Kirsher 1803aa43c215SJeff Kirsher err = qlcnic_napi_add(adapter, netdev); 1804aa43c215SJeff Kirsher if (err) 1805aa43c215SJeff Kirsher return err; 1806aa43c215SJeff Kirsher 1807aa43c215SJeff Kirsher err = qlcnic_alloc_sw_resources(adapter); 1808aa43c215SJeff Kirsher if (err) { 1809aa43c215SJeff Kirsher dev_err(&pdev->dev, "Error in setting sw resources\n"); 1810aa43c215SJeff Kirsher goto err_out_napi_del; 1811aa43c215SJeff Kirsher } 1812aa43c215SJeff Kirsher 1813aa43c215SJeff Kirsher err = qlcnic_alloc_hw_resources(adapter); 1814aa43c215SJeff Kirsher if (err) { 1815aa43c215SJeff Kirsher dev_err(&pdev->dev, "Error in setting hw resources\n"); 1816aa43c215SJeff Kirsher goto err_out_free_sw; 1817aa43c215SJeff Kirsher } 1818aa43c215SJeff Kirsher 1819aa43c215SJeff Kirsher err = qlcnic_request_irq(adapter); 1820aa43c215SJeff Kirsher if (err) { 1821aa43c215SJeff Kirsher dev_err(&pdev->dev, "failed to setup interrupt\n"); 1822aa43c215SJeff Kirsher goto err_out_free_hw; 1823aa43c215SJeff Kirsher } 1824aa43c215SJeff Kirsher 1825aa43c215SJeff Kirsher qlcnic_create_sysfs_entries(adapter); 1826aa43c215SJeff Kirsher 1827aa43c215SJeff Kirsher adapter->is_up = QLCNIC_ADAPTER_UP_MAGIC; 1828aa43c215SJeff Kirsher return 0; 1829aa43c215SJeff Kirsher 1830aa43c215SJeff Kirsher err_out_free_hw: 1831aa43c215SJeff Kirsher qlcnic_free_hw_resources(adapter); 1832aa43c215SJeff Kirsher err_out_free_sw: 1833aa43c215SJeff Kirsher qlcnic_free_sw_resources(adapter); 1834aa43c215SJeff Kirsher err_out_napi_del: 1835aa43c215SJeff Kirsher qlcnic_napi_del(adapter); 1836aa43c215SJeff Kirsher return err; 1837aa43c215SJeff Kirsher } 1838aa43c215SJeff Kirsher 1839319ecf12SSony Chacko void qlcnic_detach(struct qlcnic_adapter *adapter) 1840aa43c215SJeff Kirsher { 1841aa43c215SJeff Kirsher if (adapter->is_up != QLCNIC_ADAPTER_UP_MAGIC) 1842aa43c215SJeff Kirsher return; 1843aa43c215SJeff Kirsher 1844aa43c215SJeff Kirsher qlcnic_remove_sysfs_entries(adapter); 1845aa43c215SJeff Kirsher 1846aa43c215SJeff Kirsher qlcnic_free_hw_resources(adapter); 1847aa43c215SJeff Kirsher qlcnic_release_rx_buffers(adapter); 1848aa43c215SJeff Kirsher qlcnic_free_irq(adapter); 1849aa43c215SJeff Kirsher qlcnic_napi_del(adapter); 1850aa43c215SJeff Kirsher qlcnic_free_sw_resources(adapter); 1851aa43c215SJeff Kirsher 1852aa43c215SJeff Kirsher adapter->is_up = 0; 1853aa43c215SJeff Kirsher } 1854aa43c215SJeff Kirsher 185534e8c406SHimanshu Madhani void qlcnic_diag_free_res(struct net_device *netdev, int drv_sds_rings) 1856aa43c215SJeff Kirsher { 1857aa43c215SJeff Kirsher struct qlcnic_adapter *adapter = netdev_priv(netdev); 1858aa43c215SJeff Kirsher struct qlcnic_host_sds_ring *sds_ring; 185934e8c406SHimanshu Madhani int drv_tx_rings = adapter->drv_tx_rings; 1860aa43c215SJeff Kirsher int ring; 1861aa43c215SJeff Kirsher 1862aa43c215SJeff Kirsher clear_bit(__QLCNIC_DEV_UP, &adapter->state); 186379788450SSony Chacko if (adapter->ahw->diag_test == QLCNIC_INTERRUPT_TEST) { 186434e8c406SHimanshu Madhani for (ring = 0; ring < adapter->drv_sds_rings; ring++) { 1865aa43c215SJeff Kirsher sds_ring = &adapter->recv_ctx->sds_rings[ring]; 1866aa43c215SJeff Kirsher qlcnic_disable_int(sds_ring); 1867aa43c215SJeff Kirsher } 1868aa43c215SJeff Kirsher } 1869aa43c215SJeff Kirsher 1870aa43c215SJeff Kirsher qlcnic_fw_destroy_ctx(adapter); 1871aa43c215SJeff Kirsher 1872aa43c215SJeff Kirsher qlcnic_detach(adapter); 1873aa43c215SJeff Kirsher 187479788450SSony Chacko adapter->ahw->diag_test = 0; 187534e8c406SHimanshu Madhani adapter->drv_sds_rings = drv_sds_rings; 187634e8c406SHimanshu Madhani adapter->drv_tx_rings = drv_tx_rings; 1877aa43c215SJeff Kirsher 1878aa43c215SJeff Kirsher if (qlcnic_attach(adapter)) 1879aa43c215SJeff Kirsher goto out; 1880aa43c215SJeff Kirsher 1881aa43c215SJeff Kirsher if (netif_running(netdev)) 1882aa43c215SJeff Kirsher __qlcnic_up(adapter, netdev); 1883aa43c215SJeff Kirsher out: 1884aa43c215SJeff Kirsher netif_device_attach(netdev); 1885aa43c215SJeff Kirsher } 1886aa43c215SJeff Kirsher 1887aa43c215SJeff Kirsher static int qlcnic_alloc_adapter_resources(struct qlcnic_adapter *adapter) 1888aa43c215SJeff Kirsher { 1889be273dc1SHimanshu Madhani struct qlcnic_hardware_context *ahw = adapter->ahw; 1890aa43c215SJeff Kirsher int err = 0; 1891be273dc1SHimanshu Madhani 1892aa43c215SJeff Kirsher adapter->recv_ctx = kzalloc(sizeof(struct qlcnic_recv_context), 1893aa43c215SJeff Kirsher GFP_KERNEL); 1894aa43c215SJeff Kirsher if (!adapter->recv_ctx) { 1895aa43c215SJeff Kirsher err = -ENOMEM; 1896aa43c215SJeff Kirsher goto err_out; 1897aa43c215SJeff Kirsher } 1898aa43c215SJeff Kirsher /* Initialize interrupt coalesce parameters */ 1899be273dc1SHimanshu Madhani ahw->coal.flag = QLCNIC_INTR_DEFAULT; 1900be273dc1SHimanshu Madhani ahw->coal.type = QLCNIC_INTR_COAL_TYPE_RX; 1901be273dc1SHimanshu Madhani ahw->coal.rx_time_us = QLCNIC_DEF_INTR_COALESCE_RX_TIME_US; 1902be273dc1SHimanshu Madhani ahw->coal.rx_packets = QLCNIC_DEF_INTR_COALESCE_RX_PACKETS; 1903be273dc1SHimanshu Madhani if (qlcnic_83xx_check(adapter)) { 1904be273dc1SHimanshu Madhani ahw->coal.tx_time_us = QLCNIC_DEF_INTR_COALESCE_TX_TIME_US; 1905be273dc1SHimanshu Madhani ahw->coal.tx_packets = QLCNIC_DEF_INTR_COALESCE_TX_PACKETS; 1906be273dc1SHimanshu Madhani } 19074be41e92SSony Chacko /* clear stats */ 19084be41e92SSony Chacko memset(&adapter->stats, 0, sizeof(adapter->stats)); 1909aa43c215SJeff Kirsher err_out: 1910aa43c215SJeff Kirsher return err; 1911aa43c215SJeff Kirsher } 1912aa43c215SJeff Kirsher 1913aa43c215SJeff Kirsher static void qlcnic_free_adapter_resources(struct qlcnic_adapter *adapter) 1914aa43c215SJeff Kirsher { 1915aa43c215SJeff Kirsher kfree(adapter->recv_ctx); 1916aa43c215SJeff Kirsher adapter->recv_ctx = NULL; 1917aa43c215SJeff Kirsher 1918aa43c215SJeff Kirsher if (adapter->ahw->fw_dump.tmpl_hdr) { 1919aa43c215SJeff Kirsher vfree(adapter->ahw->fw_dump.tmpl_hdr); 1920aa43c215SJeff Kirsher adapter->ahw->fw_dump.tmpl_hdr = NULL; 1921aa43c215SJeff Kirsher } 19224be41e92SSony Chacko 192381d0aeb0SSony Chacko kfree(adapter->ahw->reset.buff); 19244be41e92SSony Chacko adapter->ahw->fw_dump.tmpl_hdr = NULL; 1925aa43c215SJeff Kirsher } 1926aa43c215SJeff Kirsher 1927aa43c215SJeff Kirsher int qlcnic_diag_alloc_res(struct net_device *netdev, int test) 1928aa43c215SJeff Kirsher { 1929aa43c215SJeff Kirsher struct qlcnic_adapter *adapter = netdev_priv(netdev); 1930aa43c215SJeff Kirsher struct qlcnic_host_sds_ring *sds_ring; 1931aa43c215SJeff Kirsher struct qlcnic_host_rds_ring *rds_ring; 1932aa43c215SJeff Kirsher int ring; 1933aa43c215SJeff Kirsher int ret; 1934aa43c215SJeff Kirsher 1935aa43c215SJeff Kirsher netif_device_detach(netdev); 1936aa43c215SJeff Kirsher 1937aa43c215SJeff Kirsher if (netif_running(netdev)) 1938aa43c215SJeff Kirsher __qlcnic_down(adapter, netdev); 1939aa43c215SJeff Kirsher 1940aa43c215SJeff Kirsher qlcnic_detach(adapter); 1941aa43c215SJeff Kirsher 194234e8c406SHimanshu Madhani adapter->drv_sds_rings = QLCNIC_SINGLE_RING; 194334e8c406SHimanshu Madhani adapter->drv_tx_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 */ 2215aa43c215SJeff Kirsher 2216f8468331SRajesh Borundia if (pdev->is_virtfn) 2217f8468331SRajesh Borundia return -ENODEV; 2218f8468331SRajesh Borundia 2219aa43c215SJeff Kirsher err = pci_enable_device(pdev); 2220aa43c215SJeff Kirsher if (err) 2221aa43c215SJeff Kirsher return err; 2222aa43c215SJeff Kirsher 2223aa43c215SJeff Kirsher if (!(pci_resource_flags(pdev, 0) & IORESOURCE_MEM)) { 2224aa43c215SJeff Kirsher err = -ENODEV; 2225aa43c215SJeff Kirsher goto err_out_disable_pdev; 2226aa43c215SJeff Kirsher } 2227aa43c215SJeff Kirsher 2228aa43c215SJeff Kirsher err = qlcnic_set_dma_mask(pdev, &pci_using_dac); 2229aa43c215SJeff Kirsher if (err) 2230aa43c215SJeff Kirsher goto err_out_disable_pdev; 2231aa43c215SJeff Kirsher 2232aa43c215SJeff Kirsher err = pci_request_regions(pdev, qlcnic_driver_name); 2233aa43c215SJeff Kirsher if (err) 2234aa43c215SJeff Kirsher goto err_out_disable_pdev; 2235aa43c215SJeff Kirsher 2236aa43c215SJeff Kirsher pci_set_master(pdev); 2237aa43c215SJeff Kirsher pci_enable_pcie_error_reporting(pdev); 2238aa43c215SJeff Kirsher 22397e2cf4feSSony Chacko ahw = kzalloc(sizeof(struct qlcnic_hardware_context), GFP_KERNEL); 224002135582SSony Chacko if (!ahw) { 224102135582SSony Chacko err = -ENOMEM; 22427e2cf4feSSony Chacko goto err_out_free_res; 224302135582SSony Chacko } 22447e2cf4feSSony Chacko 2245f8468331SRajesh Borundia switch (ent->device) { 2246f8468331SRajesh Borundia case PCI_DEVICE_ID_QLOGIC_QLE824X: 22477e2cf4feSSony Chacko ahw->hw_ops = &qlcnic_hw_ops; 22487e2cf4feSSony Chacko ahw->reg_tbl = (u32 *) qlcnic_reg_tbl; 2249f8468331SRajesh Borundia break; 2250f8468331SRajesh Borundia case PCI_DEVICE_ID_QLOGIC_QLE834X: 225115ca140fSManish Chopra case PCI_DEVICE_ID_QLOGIC_QLE844X: 225213159183SSony Chacko qlcnic_83xx_register_map(ahw); 2253f8468331SRajesh Borundia break; 2254f8468331SRajesh Borundia case PCI_DEVICE_ID_QLOGIC_VF_QLE834X: 225515ca140fSManish Chopra case PCI_DEVICE_ID_QLOGIC_VF_QLE844X: 2256f8468331SRajesh Borundia qlcnic_sriov_vf_register_map(ahw); 2257f8468331SRajesh Borundia break; 2258f8468331SRajesh Borundia default: 225913159183SSony Chacko goto err_out_free_hw_res; 22607e2cf4feSSony Chacko } 22617e2cf4feSSony Chacko 22627e2cf4feSSony Chacko err = qlcnic_setup_pci_map(pdev, ahw); 22637e2cf4feSSony Chacko if (err) 22647e2cf4feSSony Chacko goto err_out_free_hw_res; 22657e2cf4feSSony Chacko 2266012ec812SHimanshu Madhani netdev = alloc_etherdev_mq(sizeof(struct qlcnic_adapter), 2267012ec812SHimanshu Madhani QLCNIC_MAX_TX_RINGS); 2268aa43c215SJeff Kirsher if (!netdev) { 2269aa43c215SJeff Kirsher err = -ENOMEM; 22707e2cf4feSSony Chacko goto err_out_iounmap; 2271aa43c215SJeff Kirsher } 2272aa43c215SJeff Kirsher 2273aa43c215SJeff Kirsher SET_NETDEV_DEV(netdev, &pdev->dev); 2274aa43c215SJeff Kirsher 2275aa43c215SJeff Kirsher adapter = netdev_priv(netdev); 2276aa43c215SJeff Kirsher adapter->netdev = netdev; 2277aa43c215SJeff Kirsher adapter->pdev = pdev; 227813159183SSony Chacko adapter->ahw = ahw; 227913159183SSony Chacko 228013159183SSony Chacko adapter->qlcnic_wq = create_singlethread_workqueue("qlcnic"); 228113159183SSony Chacko if (adapter->qlcnic_wq == NULL) { 228202135582SSony Chacko err = -ENOMEM; 228313159183SSony Chacko dev_err(&pdev->dev, "Failed to create workqueue\n"); 228413159183SSony Chacko goto err_out_free_netdev; 228513159183SSony Chacko } 2286aa43c215SJeff Kirsher 22872dfc9671SPeter Senna Tschudin err = qlcnic_alloc_adapter_resources(adapter); 22882dfc9671SPeter Senna Tschudin if (err) 22892b1f18a4SWei Yongjun goto err_out_free_wq; 2290aa43c215SJeff Kirsher 2291aa43c215SJeff Kirsher adapter->dev_rst_time = jiffies; 22927e2cf4feSSony Chacko adapter->ahw->revision_id = pdev->revision; 2293fe1adc6bSJitendra Kalsaria if (qlcnic_mac_learn == FDB_MAC_LEARN) 2294fe1adc6bSJitendra Kalsaria adapter->fdb_mac_learn = true; 2295fe1adc6bSJitendra Kalsaria else if (qlcnic_mac_learn == DRV_MAC_LEARN) 2296fe1adc6bSJitendra Kalsaria adapter->drv_mac_learn = true; 2297aa43c215SJeff Kirsher 2298aa43c215SJeff Kirsher rwlock_init(&adapter->ahw->crb_lock); 2299aa43c215SJeff Kirsher mutex_init(&adapter->ahw->mem_lock); 2300aa43c215SJeff Kirsher 230134e8c406SHimanshu Madhani spin_lock_init(&adapter->tx_clean_lock); 2302aa43c215SJeff Kirsher INIT_LIST_HEAD(&adapter->mac_list); 2303aa43c215SJeff Kirsher 230414d385b9SSucheta Chakraborty qlcnic_register_dcb(adapter); 230514d385b9SSucheta Chakraborty 23067e2cf4feSSony Chacko if (qlcnic_82xx_check(adapter)) { 230713159183SSony Chacko qlcnic_check_vf(adapter, ent); 2308aa43c215SJeff Kirsher adapter->portnum = adapter->ahw->pci_func; 23097e2cf4feSSony Chacko err = qlcnic_start_firmware(adapter); 2310aa43c215SJeff Kirsher if (err) { 231166451615SSucheta Chakraborty dev_err(&pdev->dev, "Loading fw failed.Please Reboot\n" 231266451615SSucheta Chakraborty "\t\tIf reboot doesn't help, try flashing the card\n"); 231366451615SSucheta Chakraborty goto err_out_maintenance_mode; 2314aa43c215SJeff Kirsher } 2315aa43c215SJeff Kirsher 231634e8c406SHimanshu Madhani /* compute and set default and max tx/sds rings */ 231734e8c406SHimanshu Madhani if (adapter->ahw->msix_supported) { 231834e8c406SHimanshu Madhani if (qlcnic_check_multi_tx_capability(adapter) == 1) 231934e8c406SHimanshu Madhani qlcnic_set_tx_ring_count(adapter, 232034e8c406SHimanshu Madhani QLCNIC_SINGLE_RING); 232134e8c406SHimanshu Madhani else 232234e8c406SHimanshu Madhani qlcnic_set_tx_ring_count(adapter, 232334e8c406SHimanshu Madhani QLCNIC_DEF_TX_RINGS); 232434e8c406SHimanshu Madhani qlcnic_set_sds_ring_count(adapter, 232534e8c406SHimanshu Madhani QLCNIC_DEF_SDS_RINGS); 232634e8c406SHimanshu Madhani } else { 232734e8c406SHimanshu Madhani qlcnic_set_tx_ring_count(adapter, QLCNIC_SINGLE_RING); 232834e8c406SHimanshu Madhani qlcnic_set_sds_ring_count(adapter, QLCNIC_SINGLE_RING); 2329012ec812SHimanshu Madhani } 2330012ec812SHimanshu Madhani 2331aa43c215SJeff Kirsher err = qlcnic_setup_idc_param(adapter); 2332aa43c215SJeff Kirsher if (err) 23337e2cf4feSSony Chacko goto err_out_free_hw; 2334aa43c215SJeff Kirsher 2335aa43c215SJeff Kirsher adapter->flags |= QLCNIC_NEED_FLR; 233614d385b9SSucheta Chakraborty 233713159183SSony Chacko } else if (qlcnic_83xx_check(adapter)) { 233813159183SSony Chacko qlcnic_83xx_check_vf(adapter, ent); 233913159183SSony Chacko adapter->portnum = adapter->ahw->pci_func; 2340f8468331SRajesh Borundia err = qlcnic_83xx_init(adapter, pci_using_dac); 2341629263acSSony Chacko if (err) { 234278ea2d97SSucheta Chakraborty switch (err) { 234378ea2d97SSucheta Chakraborty case -ENOTRECOVERABLE: 234478ea2d97SSucheta Chakraborty dev_err(&pdev->dev, "Adapter initialization failed due to a faulty hardware. Please reboot\n"); 234578ea2d97SSucheta 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"); 2346629263acSSony Chacko goto err_out_free_hw; 234778ea2d97SSucheta Chakraborty case -ENOMEM: 234878ea2d97SSucheta Chakraborty dev_err(&pdev->dev, "Adapter initialization failed. Please reboot\n"); 234978ea2d97SSucheta Chakraborty goto err_out_free_hw; 235078ea2d97SSucheta Chakraborty default: 235178ea2d97SSucheta Chakraborty dev_err(&pdev->dev, "Adapter initialization failed. A reboot may be required to recover from this failure\n"); 235278ea2d97SSucheta Chakraborty dev_err(&pdev->dev, "If reboot does not help to recover from this failure, try a flash update of the adapter\n"); 235378ea2d97SSucheta Chakraborty goto err_out_maintenance_mode; 2354629263acSSony Chacko } 235578ea2d97SSucheta Chakraborty } 235678ea2d97SSucheta Chakraborty 2357f8468331SRajesh Borundia if (qlcnic_sriov_vf_check(adapter)) 2358f8468331SRajesh Borundia return 0; 235913159183SSony Chacko } else { 236013159183SSony Chacko dev_err(&pdev->dev, 236113159183SSony Chacko "%s: failed. Please Reboot\n", __func__); 236213159183SSony Chacko goto err_out_free_hw; 2363aa43c215SJeff Kirsher } 2364aa43c215SJeff Kirsher 23653c44bba1SSucheta Chakraborty qlcnic_dcb_enable(adapter->dcb); 23663c44bba1SSucheta Chakraborty 2367aa43c215SJeff Kirsher if (qlcnic_read_mac_addr(adapter)) 2368aa43c215SJeff Kirsher dev_warn(&pdev->dev, "failed to read mac addr\n"); 2369aa43c215SJeff Kirsher 237007a251c8SShahed Shaikh qlcnic_read_phys_port_id(adapter); 237107a251c8SShahed Shaikh 2372aa43c215SJeff Kirsher if (adapter->portnum == 0) { 237322999798SSony Chacko qlcnic_get_board_name(adapter, board_name); 237413159183SSony Chacko 2375aa43c215SJeff Kirsher pr_info("%s: %s Board Chip rev 0x%x\n", 2376aa43c215SJeff Kirsher module_name(THIS_MODULE), 237722999798SSony Chacko board_name, adapter->ahw->revision_id); 2378aa43c215SJeff Kirsher } 2379460374f7SHimanshu Madhani 2380460374f7SHimanshu Madhani if (qlcnic_83xx_check(adapter) && !qlcnic_use_msi_x && 2381460374f7SHimanshu Madhani !!qlcnic_use_msi) 2382460374f7SHimanshu Madhani dev_warn(&pdev->dev, 238301b91f4cSPratik Pujar "Device does not support MSI interrupts\n"); 2384460374f7SHimanshu Madhani 2385068a8d19SManish Chopra if (qlcnic_82xx_check(adapter)) { 238634e8c406SHimanshu Madhani err = qlcnic_setup_intr(adapter); 23879a97e705SManish chopra if (err) { 23889a97e705SManish chopra dev_err(&pdev->dev, "Failed to setup interrupt\n"); 23897e2cf4feSSony Chacko goto err_out_disable_msi; 23909a97e705SManish chopra } 239113159183SSony Chacko } 2392aa43c215SJeff Kirsher 239302135582SSony Chacko err = qlcnic_get_act_pci_func(adapter); 239402135582SSony Chacko if (err) 239502135582SSony Chacko goto err_out_disable_mbx_intr; 239602135582SSony Chacko 2397aa43c215SJeff Kirsher err = qlcnic_setup_netdev(adapter, netdev, pci_using_dac); 2398aa43c215SJeff Kirsher if (err) 23997e2cf4feSSony Chacko goto err_out_disable_mbx_intr; 2400aa43c215SJeff Kirsher 240124866d15SHimanshu Madhani if (adapter->portnum == 0) 24028af3f33dSPratik Pujar qlcnic_set_drv_version(adapter); 2403c84e340aSSritej Velaga 2404aa43c215SJeff Kirsher pci_set_drvdata(pdev, adapter); 2405aa43c215SJeff Kirsher 240697ee45ebSSony Chacko if (qlcnic_82xx_check(adapter)) 240797ee45ebSSony Chacko qlcnic_schedule_work(adapter, qlcnic_fw_poll_work, 240897ee45ebSSony Chacko FW_POLL_DELAY); 2409aa43c215SJeff Kirsher 2410aa43c215SJeff Kirsher switch (adapter->ahw->port_type) { 2411aa43c215SJeff Kirsher case QLCNIC_GBE: 2412aa43c215SJeff Kirsher dev_info(&adapter->pdev->dev, "%s: GbE port initialized\n", 2413aa43c215SJeff Kirsher adapter->netdev->name); 2414aa43c215SJeff Kirsher break; 2415aa43c215SJeff Kirsher case QLCNIC_XGBE: 2416aa43c215SJeff Kirsher dev_info(&adapter->pdev->dev, "%s: XGbE port initialized\n", 2417aa43c215SJeff Kirsher adapter->netdev->name); 2418aa43c215SJeff Kirsher break; 2419aa43c215SJeff Kirsher } 2420aa43c215SJeff Kirsher 2421fe1adc6bSJitendra Kalsaria if (adapter->drv_mac_learn) 2422aa43c215SJeff Kirsher qlcnic_alloc_lb_filters_mem(adapter); 2423aa43c215SJeff Kirsher 24247e2cf4feSSony Chacko qlcnic_add_sysfs(adapter); 2425aa43c215SJeff Kirsher 2426aa43c215SJeff Kirsher return 0; 2427aa43c215SJeff Kirsher 24287e2cf4feSSony Chacko err_out_disable_mbx_intr: 24297dd90cf1SSucheta Chakraborty if (qlcnic_83xx_check(adapter)) 243013159183SSony Chacko qlcnic_83xx_free_mbx_intr(adapter); 24317e2cf4feSSony Chacko 2432aa43c215SJeff Kirsher err_out_disable_msi: 2433aa43c215SJeff Kirsher qlcnic_teardown_intr(adapter); 24347e2cf4feSSony Chacko qlcnic_cancel_idc_work(adapter); 2435aa43c215SJeff Kirsher qlcnic_clr_all_drv_state(adapter, 0); 2436aa43c215SJeff Kirsher 2437aa43c215SJeff Kirsher err_out_free_hw: 2438aa43c215SJeff Kirsher qlcnic_free_adapter_resources(adapter); 2439aa43c215SJeff Kirsher 24402b1f18a4SWei Yongjun err_out_free_wq: 24412b1f18a4SWei Yongjun destroy_workqueue(adapter->qlcnic_wq); 24422b1f18a4SWei Yongjun 2443aa43c215SJeff Kirsher err_out_free_netdev: 2444aa43c215SJeff Kirsher free_netdev(netdev); 2445aa43c215SJeff Kirsher 24467e2cf4feSSony Chacko err_out_iounmap: 2447f1a094a8SRajesh Borundia qlcnic_cleanup_pci_map(ahw); 24487e2cf4feSSony Chacko 24497e2cf4feSSony Chacko err_out_free_hw_res: 24507e2cf4feSSony Chacko kfree(ahw); 24517e2cf4feSSony Chacko 2452aa43c215SJeff Kirsher err_out_free_res: 2453aa43c215SJeff Kirsher pci_release_regions(pdev); 2454aa43c215SJeff Kirsher 2455aa43c215SJeff Kirsher err_out_disable_pdev: 2456aa43c215SJeff Kirsher pci_disable_device(pdev); 2457aa43c215SJeff Kirsher return err; 245866451615SSucheta Chakraborty 245966451615SSucheta Chakraborty err_out_maintenance_mode: 246078ea2d97SSucheta Chakraborty set_bit(__QLCNIC_MAINTENANCE_MODE, &adapter->state); 246166451615SSucheta Chakraborty netdev->netdev_ops = &qlcnic_netdev_failed_ops; 246266451615SSucheta Chakraborty SET_ETHTOOL_OPS(netdev, &qlcnic_ethtool_failed_ops); 246378ea2d97SSucheta Chakraborty ahw->port_type = QLCNIC_XGBE; 246478ea2d97SSucheta Chakraborty 246578ea2d97SSucheta Chakraborty if (qlcnic_83xx_check(adapter)) 246678ea2d97SSucheta Chakraborty adapter->tgt_status_reg = NULL; 246778ea2d97SSucheta Chakraborty else 246878ea2d97SSucheta Chakraborty ahw->board_type = QLCNIC_BRDTYPE_P3P_10G_SFP_PLUS; 246978ea2d97SSucheta Chakraborty 247066451615SSucheta Chakraborty err = register_netdev(netdev); 247166451615SSucheta Chakraborty 247266451615SSucheta Chakraborty if (err) { 247366451615SSucheta Chakraborty dev_err(&pdev->dev, "Failed to register net device\n"); 247466451615SSucheta Chakraborty qlcnic_clr_all_drv_state(adapter, 0); 247566451615SSucheta Chakraborty goto err_out_free_hw; 247666451615SSucheta Chakraborty } 247766451615SSucheta Chakraborty 247866451615SSucheta Chakraborty pci_set_drvdata(pdev, adapter); 247966451615SSucheta Chakraborty qlcnic_add_sysfs(adapter); 248066451615SSucheta Chakraborty 248166451615SSucheta Chakraborty return 0; 2482aa43c215SJeff Kirsher } 2483aa43c215SJeff Kirsher 24846bb58bb0SBill Pemberton static void qlcnic_remove(struct pci_dev *pdev) 2485aa43c215SJeff Kirsher { 2486aa43c215SJeff Kirsher struct qlcnic_adapter *adapter; 2487aa43c215SJeff Kirsher struct net_device *netdev; 248813159183SSony Chacko struct qlcnic_hardware_context *ahw; 2489aa43c215SJeff Kirsher 2490aa43c215SJeff Kirsher adapter = pci_get_drvdata(pdev); 2491aa43c215SJeff Kirsher if (adapter == NULL) 2492aa43c215SJeff Kirsher return; 2493aa43c215SJeff Kirsher 2494aa43c215SJeff Kirsher netdev = adapter->netdev; 249502feda17SRajesh Borundia qlcnic_sriov_pf_disable(adapter); 2496aa43c215SJeff Kirsher 249713159183SSony Chacko qlcnic_cancel_idc_work(adapter); 249813159183SSony Chacko ahw = adapter->ahw; 2499aa43c215SJeff Kirsher 25001de899d3SSucheta Chakraborty qlcnic_dcb_free(adapter->dcb); 250114d385b9SSucheta Chakraborty 2502aa43c215SJeff Kirsher unregister_netdev(netdev); 250302feda17SRajesh Borundia qlcnic_sriov_cleanup(adapter); 2504aa43c215SJeff Kirsher 250513159183SSony Chacko if (qlcnic_83xx_check(adapter)) { 25063d73b5fdSJitendra Kalsaria qlcnic_83xx_register_nic_idc_func(adapter, 0); 25073d73b5fdSJitendra Kalsaria cancel_delayed_work_sync(&adapter->idc_aen_work); 2508068a8d19SManish Chopra qlcnic_83xx_free_mbx_intr(adapter); 2509068a8d19SManish Chopra qlcnic_83xx_detach_mailbox_work(adapter); 2510068a8d19SManish Chopra qlcnic_83xx_free_mailbox(ahw->mailbox); 25117000078aSPratik Pujar kfree(ahw->fw_info); 251213159183SSony Chacko } 251313159183SSony Chacko 2514aa43c215SJeff Kirsher qlcnic_detach(adapter); 2515aa43c215SJeff Kirsher 2516aa43c215SJeff Kirsher if (adapter->npars != NULL) 2517aa43c215SJeff Kirsher kfree(adapter->npars); 2518aa43c215SJeff Kirsher if (adapter->eswitch != NULL) 2519aa43c215SJeff Kirsher kfree(adapter->eswitch); 2520aa43c215SJeff Kirsher 252197ee45ebSSony Chacko if (qlcnic_82xx_check(adapter)) 2522aa43c215SJeff Kirsher qlcnic_clr_all_drv_state(adapter, 0); 2523aa43c215SJeff Kirsher 2524aa43c215SJeff Kirsher clear_bit(__QLCNIC_RESETTING, &adapter->state); 2525aa43c215SJeff Kirsher 2526aa43c215SJeff Kirsher qlcnic_free_lb_filters_mem(adapter); 2527aa43c215SJeff Kirsher 2528aa43c215SJeff Kirsher qlcnic_teardown_intr(adapter); 2529aa43c215SJeff Kirsher 253013159183SSony Chacko qlcnic_remove_sysfs(adapter); 2531aa43c215SJeff Kirsher 2532f1a094a8SRajesh Borundia qlcnic_cleanup_pci_map(adapter->ahw); 2533aa43c215SJeff Kirsher 2534aa43c215SJeff Kirsher qlcnic_release_firmware(adapter); 2535aa43c215SJeff Kirsher 2536aa43c215SJeff Kirsher pci_disable_pcie_error_reporting(pdev); 2537aa43c215SJeff Kirsher pci_release_regions(pdev); 2538aa43c215SJeff Kirsher pci_disable_device(pdev); 2539aa43c215SJeff Kirsher 254013159183SSony Chacko if (adapter->qlcnic_wq) { 254113159183SSony Chacko destroy_workqueue(adapter->qlcnic_wq); 254213159183SSony Chacko adapter->qlcnic_wq = NULL; 254313159183SSony Chacko } 254414d385b9SSucheta Chakraborty 2545aa43c215SJeff Kirsher qlcnic_free_adapter_resources(adapter); 254613159183SSony Chacko kfree(ahw); 2547aa43c215SJeff Kirsher free_netdev(netdev); 2548aa43c215SJeff Kirsher } 2549aa43c215SJeff Kirsher 2550aa43c215SJeff Kirsher static void qlcnic_shutdown(struct pci_dev *pdev) 2551aa43c215SJeff Kirsher { 2552aa43c215SJeff Kirsher if (__qlcnic_shutdown(pdev)) 2553aa43c215SJeff Kirsher return; 2554aa43c215SJeff Kirsher 2555aa43c215SJeff Kirsher pci_disable_device(pdev); 2556aa43c215SJeff Kirsher } 2557aa43c215SJeff Kirsher 2558aa43c215SJeff Kirsher #ifdef CONFIG_PM 2559486a5bc7SRajesh Borundia static int qlcnic_suspend(struct pci_dev *pdev, pm_message_t state) 2560aa43c215SJeff Kirsher { 2561aa43c215SJeff Kirsher int retval; 2562aa43c215SJeff Kirsher 2563aa43c215SJeff Kirsher retval = __qlcnic_shutdown(pdev); 2564aa43c215SJeff Kirsher if (retval) 2565aa43c215SJeff Kirsher return retval; 2566aa43c215SJeff Kirsher 2567aa43c215SJeff Kirsher pci_set_power_state(pdev, pci_choose_state(pdev, state)); 2568aa43c215SJeff Kirsher return 0; 2569aa43c215SJeff Kirsher } 2570aa43c215SJeff Kirsher 2571486a5bc7SRajesh Borundia static int qlcnic_resume(struct pci_dev *pdev) 2572aa43c215SJeff Kirsher { 2573aa43c215SJeff Kirsher struct qlcnic_adapter *adapter = pci_get_drvdata(pdev); 2574aa43c215SJeff Kirsher int err; 2575aa43c215SJeff Kirsher 2576aa43c215SJeff Kirsher err = pci_enable_device(pdev); 2577aa43c215SJeff Kirsher if (err) 2578aa43c215SJeff Kirsher return err; 2579aa43c215SJeff Kirsher 2580aa43c215SJeff Kirsher pci_set_power_state(pdev, PCI_D0); 2581aa43c215SJeff Kirsher pci_set_master(pdev); 2582aa43c215SJeff Kirsher pci_restore_state(pdev); 2583aa43c215SJeff Kirsher 2584486a5bc7SRajesh Borundia return __qlcnic_resume(adapter); 2585aa43c215SJeff Kirsher } 2586aa43c215SJeff Kirsher #endif 2587aa43c215SJeff Kirsher 2588aa43c215SJeff Kirsher static int qlcnic_open(struct net_device *netdev) 2589aa43c215SJeff Kirsher { 2590aa43c215SJeff Kirsher struct qlcnic_adapter *adapter = netdev_priv(netdev); 2591aa43c215SJeff Kirsher int err; 2592aa43c215SJeff Kirsher 259378ea2d97SSucheta Chakraborty if (test_bit(__QLCNIC_MAINTENANCE_MODE, &adapter->state)) { 259478ea2d97SSucheta Chakraborty netdev_err(netdev, "%s: Device is in non-operational state\n", 259578ea2d97SSucheta Chakraborty __func__); 259666451615SSucheta Chakraborty 259766451615SSucheta Chakraborty return -EIO; 259866451615SSucheta Chakraborty } 259966451615SSucheta Chakraborty 2600aa43c215SJeff Kirsher netif_carrier_off(netdev); 2601aa43c215SJeff Kirsher 2602aa43c215SJeff Kirsher err = qlcnic_attach(adapter); 2603aa43c215SJeff Kirsher if (err) 2604aa43c215SJeff Kirsher return err; 2605aa43c215SJeff Kirsher 2606aa43c215SJeff Kirsher err = __qlcnic_up(adapter, netdev); 2607aa43c215SJeff Kirsher if (err) 2608aa43c215SJeff Kirsher goto err_out; 2609aa43c215SJeff Kirsher 2610012ec812SHimanshu Madhani netif_tx_start_all_queues(netdev); 2611aa43c215SJeff Kirsher 2612aa43c215SJeff Kirsher return 0; 2613aa43c215SJeff Kirsher 2614aa43c215SJeff Kirsher err_out: 2615aa43c215SJeff Kirsher qlcnic_detach(adapter); 2616aa43c215SJeff Kirsher return err; 2617aa43c215SJeff Kirsher } 2618aa43c215SJeff Kirsher 2619aa43c215SJeff Kirsher /* 2620aa43c215SJeff Kirsher * qlcnic_close - Disables a network interface entry point 2621aa43c215SJeff Kirsher */ 2622aa43c215SJeff Kirsher static int qlcnic_close(struct net_device *netdev) 2623aa43c215SJeff Kirsher { 2624aa43c215SJeff Kirsher struct qlcnic_adapter *adapter = netdev_priv(netdev); 2625aa43c215SJeff Kirsher 2626aa43c215SJeff Kirsher __qlcnic_down(adapter, netdev); 262713159183SSony Chacko 2628aa43c215SJeff Kirsher return 0; 2629aa43c215SJeff Kirsher } 2630aa43c215SJeff Kirsher 2631aa43c215SJeff Kirsher void qlcnic_alloc_lb_filters_mem(struct qlcnic_adapter *adapter) 2632aa43c215SJeff Kirsher { 2633aa43c215SJeff Kirsher void *head; 2634aa43c215SJeff Kirsher int i; 263513159183SSony Chacko struct net_device *netdev = adapter->netdev; 263613159183SSony Chacko u32 filter_size = 0; 263713159183SSony Chacko u16 act_pci_func = 0; 2638aa43c215SJeff Kirsher 2639aa43c215SJeff Kirsher if (adapter->fhash.fmax && adapter->fhash.fhead) 2640aa43c215SJeff Kirsher return; 2641aa43c215SJeff Kirsher 264213159183SSony Chacko act_pci_func = adapter->ahw->act_pci_func; 2643aa43c215SJeff Kirsher spin_lock_init(&adapter->mac_learn_lock); 264453643a75SShahed Shaikh spin_lock_init(&adapter->rx_mac_learn_lock); 2645aa43c215SJeff Kirsher 264613159183SSony Chacko if (qlcnic_82xx_check(adapter)) { 264713159183SSony Chacko filter_size = QLCNIC_LB_MAX_FILTERS; 264813159183SSony Chacko adapter->fhash.fbucket_size = QLCNIC_LB_BUCKET_SIZE; 264913159183SSony Chacko } else { 265013159183SSony Chacko filter_size = QLC_83XX_LB_MAX_FILTERS; 265113159183SSony Chacko adapter->fhash.fbucket_size = QLC_83XX_LB_BUCKET_SIZE; 265213159183SSony Chacko } 265313159183SSony Chacko 265413159183SSony Chacko head = kcalloc(adapter->fhash.fbucket_size, 26551d9219ddSJitendra Kalsaria sizeof(struct hlist_head), GFP_ATOMIC); 265613159183SSony Chacko 2657aa43c215SJeff Kirsher if (!head) 2658aa43c215SJeff Kirsher return; 2659aa43c215SJeff Kirsher 266013159183SSony Chacko adapter->fhash.fmax = (filter_size / act_pci_func); 2661aa43c215SJeff Kirsher adapter->fhash.fhead = head; 2662aa43c215SJeff Kirsher 266313159183SSony Chacko netdev_info(netdev, "active nic func = %d, mac filter size=%d\n", 266413159183SSony Chacko act_pci_func, adapter->fhash.fmax); 266513159183SSony Chacko 266613159183SSony Chacko for (i = 0; i < adapter->fhash.fbucket_size; i++) 2667aa43c215SJeff Kirsher INIT_HLIST_HEAD(&adapter->fhash.fhead[i]); 266853643a75SShahed Shaikh 266953643a75SShahed Shaikh adapter->rx_fhash.fbucket_size = adapter->fhash.fbucket_size; 267053643a75SShahed Shaikh 267153643a75SShahed Shaikh head = kcalloc(adapter->rx_fhash.fbucket_size, 267253643a75SShahed Shaikh sizeof(struct hlist_head), GFP_ATOMIC); 267353643a75SShahed Shaikh 267453643a75SShahed Shaikh if (!head) 267553643a75SShahed Shaikh return; 267653643a75SShahed Shaikh 267753643a75SShahed Shaikh adapter->rx_fhash.fmax = (filter_size / act_pci_func); 267853643a75SShahed Shaikh adapter->rx_fhash.fhead = head; 267953643a75SShahed Shaikh 268053643a75SShahed Shaikh for (i = 0; i < adapter->rx_fhash.fbucket_size; i++) 268153643a75SShahed Shaikh INIT_HLIST_HEAD(&adapter->rx_fhash.fhead[i]); 2682aa43c215SJeff Kirsher } 2683aa43c215SJeff Kirsher 2684aa43c215SJeff Kirsher static void qlcnic_free_lb_filters_mem(struct qlcnic_adapter *adapter) 2685aa43c215SJeff Kirsher { 2686aa43c215SJeff Kirsher if (adapter->fhash.fmax && adapter->fhash.fhead) 2687aa43c215SJeff Kirsher kfree(adapter->fhash.fhead); 2688aa43c215SJeff Kirsher 2689aa43c215SJeff Kirsher adapter->fhash.fhead = NULL; 2690aa43c215SJeff Kirsher adapter->fhash.fmax = 0; 269153643a75SShahed Shaikh 269253643a75SShahed Shaikh if (adapter->rx_fhash.fmax && adapter->rx_fhash.fhead) 269353643a75SShahed Shaikh kfree(adapter->rx_fhash.fhead); 269453643a75SShahed Shaikh 269553643a75SShahed Shaikh adapter->rx_fhash.fmax = 0; 269653643a75SShahed Shaikh adapter->rx_fhash.fhead = NULL; 2697aa43c215SJeff Kirsher } 2698aa43c215SJeff Kirsher 2699629263acSSony Chacko int qlcnic_check_temp(struct qlcnic_adapter *adapter) 2700aa43c215SJeff Kirsher { 2701aa43c215SJeff Kirsher struct net_device *netdev = adapter->netdev; 270297ee45ebSSony Chacko u32 temp_state, temp_val, temp = 0; 2703aa43c215SJeff Kirsher int rv = 0; 2704aa43c215SJeff Kirsher 270513159183SSony Chacko if (qlcnic_83xx_check(adapter)) 270613159183SSony Chacko temp = QLCRDX(adapter->ahw, QLC_83XX_ASIC_TEMP); 270713159183SSony Chacko 270897ee45ebSSony Chacko if (qlcnic_82xx_check(adapter)) 2709a15ebd37SHimanshu Madhani temp = QLC_SHARED_REG_RD32(adapter, QLCNIC_ASIC_TEMP); 2710aa43c215SJeff Kirsher 2711aa43c215SJeff Kirsher temp_state = qlcnic_get_temp_state(temp); 2712aa43c215SJeff Kirsher temp_val = qlcnic_get_temp_val(temp); 2713aa43c215SJeff Kirsher 2714aa43c215SJeff Kirsher if (temp_state == QLCNIC_TEMP_PANIC) { 2715aa43c215SJeff Kirsher dev_err(&netdev->dev, 2716aa43c215SJeff Kirsher "Device temperature %d degrees C exceeds" 2717aa43c215SJeff Kirsher " maximum allowed. Hardware has been shut down.\n", 2718aa43c215SJeff Kirsher temp_val); 2719aa43c215SJeff Kirsher rv = 1; 2720aa43c215SJeff Kirsher } else if (temp_state == QLCNIC_TEMP_WARN) { 272179788450SSony Chacko if (adapter->ahw->temp == QLCNIC_TEMP_NORMAL) { 2722aa43c215SJeff Kirsher dev_err(&netdev->dev, 2723aa43c215SJeff Kirsher "Device temperature %d degrees C " 2724aa43c215SJeff Kirsher "exceeds operating range." 2725aa43c215SJeff Kirsher " Immediate action needed.\n", 2726aa43c215SJeff Kirsher temp_val); 2727aa43c215SJeff Kirsher } 2728aa43c215SJeff Kirsher } else { 272979788450SSony Chacko if (adapter->ahw->temp == QLCNIC_TEMP_WARN) { 2730aa43c215SJeff Kirsher dev_info(&netdev->dev, 2731aa43c215SJeff Kirsher "Device temperature is now %d degrees C" 2732aa43c215SJeff Kirsher " in normal range.\n", temp_val); 2733aa43c215SJeff Kirsher } 2734aa43c215SJeff Kirsher } 273579788450SSony Chacko adapter->ahw->temp = temp_state; 2736aa43c215SJeff Kirsher return rv; 2737aa43c215SJeff Kirsher } 2738aa43c215SJeff Kirsher 2739aa43c215SJeff Kirsher static void qlcnic_tx_timeout(struct net_device *netdev) 2740aa43c215SJeff Kirsher { 2741aa43c215SJeff Kirsher struct qlcnic_adapter *adapter = netdev_priv(netdev); 2742012ec812SHimanshu Madhani struct qlcnic_host_tx_ring *tx_ring; 2743012ec812SHimanshu Madhani int ring; 2744aa43c215SJeff Kirsher 2745aa43c215SJeff Kirsher if (test_bit(__QLCNIC_RESETTING, &adapter->state)) 2746aa43c215SJeff Kirsher return; 2747aa43c215SJeff Kirsher 2748536faa61SSony Chacko if (++adapter->tx_timeo_cnt >= QLCNIC_MAX_TX_TIMEOUTS) { 2749536faa61SSony Chacko netdev_info(netdev, "Tx timeout, reset the adapter.\n"); 2750536faa61SSony Chacko if (qlcnic_82xx_check(adapter)) 2751aa43c215SJeff Kirsher adapter->need_fw_reset = 1; 2752536faa61SSony Chacko else if (qlcnic_83xx_check(adapter)) 2753536faa61SSony Chacko qlcnic_83xx_idc_request_reset(adapter, 2754536faa61SSony Chacko QLCNIC_FORCE_FW_DUMP_KEY); 2755536faa61SSony Chacko } else { 2756536faa61SSony Chacko netdev_info(netdev, "Tx timeout, reset adapter context.\n"); 275734e8c406SHimanshu Madhani for (ring = 0; ring < adapter->drv_tx_rings; ring++) { 2758012ec812SHimanshu Madhani tx_ring = &adapter->tx_ring[ring]; 2759f27c75b3SHimanshu Madhani netdev_info(netdev, "Tx ring=%d\n", ring); 2760f27c75b3SHimanshu Madhani netdev_info(netdev, 2761f27c75b3SHimanshu Madhani "crb_intr_mask=%d, producer=%d, sw_consumer=%d, hw_consumer=%d\n", 2762f27c75b3SHimanshu Madhani readl(tx_ring->crb_intr_mask), 2763f27c75b3SHimanshu Madhani readl(tx_ring->crb_cmd_producer), 2764f27c75b3SHimanshu Madhani tx_ring->sw_consumer, 2765012ec812SHimanshu Madhani le32_to_cpu(*(tx_ring->hw_consumer))); 2766f27c75b3SHimanshu Madhani netdev_info(netdev, 2767f27c75b3SHimanshu Madhani "xmit_finished=%llu, xmit_called=%llu, xmit_on=%llu, xmit_off=%llu\n", 2768f27c75b3SHimanshu Madhani tx_ring->tx_stats.xmit_finished, 2769f27c75b3SHimanshu Madhani tx_ring->tx_stats.xmit_called, 2770f27c75b3SHimanshu Madhani tx_ring->tx_stats.xmit_on, 2771f27c75b3SHimanshu Madhani tx_ring->tx_stats.xmit_off); 2772012ec812SHimanshu Madhani } 277379788450SSony Chacko adapter->ahw->reset_context = 1; 2774aa43c215SJeff Kirsher } 2775536faa61SSony Chacko } 2776aa43c215SJeff Kirsher 2777aa43c215SJeff Kirsher static struct net_device_stats *qlcnic_get_stats(struct net_device *netdev) 2778aa43c215SJeff Kirsher { 2779aa43c215SJeff Kirsher struct qlcnic_adapter *adapter = netdev_priv(netdev); 2780aa43c215SJeff Kirsher struct net_device_stats *stats = &netdev->stats; 2781aa43c215SJeff Kirsher 2782aa43c215SJeff Kirsher stats->rx_packets = adapter->stats.rx_pkts + adapter->stats.lro_pkts; 2783aa43c215SJeff Kirsher stats->tx_packets = adapter->stats.xmitfinished; 2784aa43c215SJeff Kirsher stats->rx_bytes = adapter->stats.rxbytes + adapter->stats.lrobytes; 2785aa43c215SJeff Kirsher stats->tx_bytes = adapter->stats.txbytes; 2786aa43c215SJeff Kirsher stats->rx_dropped = adapter->stats.rxdropped; 2787aa43c215SJeff Kirsher stats->tx_dropped = adapter->stats.txdropped; 2788aa43c215SJeff Kirsher 2789aa43c215SJeff Kirsher return stats; 2790aa43c215SJeff Kirsher } 2791aa43c215SJeff Kirsher 27927e2cf4feSSony Chacko irqreturn_t qlcnic_82xx_clear_legacy_intr(struct qlcnic_adapter *adapter) 2793aa43c215SJeff Kirsher { 2794aa43c215SJeff Kirsher u32 status; 2795aa43c215SJeff Kirsher 2796aa43c215SJeff Kirsher status = readl(adapter->isr_int_vec); 2797aa43c215SJeff Kirsher 279879788450SSony Chacko if (!(status & adapter->ahw->int_vec_bit)) 2799aa43c215SJeff Kirsher return IRQ_NONE; 2800aa43c215SJeff Kirsher 2801aa43c215SJeff Kirsher /* check interrupt state machine, to be sure */ 2802aa43c215SJeff Kirsher status = readl(adapter->crb_int_state_reg); 2803aa43c215SJeff Kirsher if (!ISR_LEGACY_INT_TRIGGERED(status)) 2804aa43c215SJeff Kirsher return IRQ_NONE; 2805aa43c215SJeff Kirsher 2806aa43c215SJeff Kirsher writel(0xffffffff, adapter->tgt_status_reg); 2807aa43c215SJeff Kirsher /* read twice to ensure write is flushed */ 2808aa43c215SJeff Kirsher readl(adapter->isr_int_vec); 2809aa43c215SJeff Kirsher readl(adapter->isr_int_vec); 2810aa43c215SJeff Kirsher 2811aa43c215SJeff Kirsher return IRQ_HANDLED; 2812aa43c215SJeff Kirsher } 2813aa43c215SJeff Kirsher 2814aa43c215SJeff Kirsher static irqreturn_t qlcnic_tmp_intr(int irq, void *data) 2815aa43c215SJeff Kirsher { 2816aa43c215SJeff Kirsher struct qlcnic_host_sds_ring *sds_ring = data; 2817aa43c215SJeff Kirsher struct qlcnic_adapter *adapter = sds_ring->adapter; 2818aa43c215SJeff Kirsher 2819aa43c215SJeff Kirsher if (adapter->flags & QLCNIC_MSIX_ENABLED) 2820aa43c215SJeff Kirsher goto done; 2821aa43c215SJeff Kirsher else if (adapter->flags & QLCNIC_MSI_ENABLED) { 2822aa43c215SJeff Kirsher writel(0xffffffff, adapter->tgt_status_reg); 2823aa43c215SJeff Kirsher goto done; 2824aa43c215SJeff Kirsher } 2825aa43c215SJeff Kirsher 2826aa43c215SJeff Kirsher if (qlcnic_clear_legacy_intr(adapter) == IRQ_NONE) 2827aa43c215SJeff Kirsher return IRQ_NONE; 2828aa43c215SJeff Kirsher 2829aa43c215SJeff Kirsher done: 283079788450SSony Chacko adapter->ahw->diag_cnt++; 2831aa43c215SJeff Kirsher qlcnic_enable_int(sds_ring); 2832aa43c215SJeff Kirsher return IRQ_HANDLED; 2833aa43c215SJeff Kirsher } 2834aa43c215SJeff Kirsher 2835aa43c215SJeff Kirsher static irqreturn_t qlcnic_intr(int irq, void *data) 2836aa43c215SJeff Kirsher { 2837aa43c215SJeff Kirsher struct qlcnic_host_sds_ring *sds_ring = data; 2838aa43c215SJeff Kirsher struct qlcnic_adapter *adapter = sds_ring->adapter; 2839aa43c215SJeff Kirsher 2840aa43c215SJeff Kirsher if (qlcnic_clear_legacy_intr(adapter) == IRQ_NONE) 2841aa43c215SJeff Kirsher return IRQ_NONE; 2842aa43c215SJeff Kirsher 2843aa43c215SJeff Kirsher napi_schedule(&sds_ring->napi); 2844aa43c215SJeff Kirsher 2845aa43c215SJeff Kirsher return IRQ_HANDLED; 2846aa43c215SJeff Kirsher } 2847aa43c215SJeff Kirsher 2848aa43c215SJeff Kirsher static irqreturn_t qlcnic_msi_intr(int irq, void *data) 2849aa43c215SJeff Kirsher { 2850aa43c215SJeff Kirsher struct qlcnic_host_sds_ring *sds_ring = data; 2851aa43c215SJeff Kirsher struct qlcnic_adapter *adapter = sds_ring->adapter; 2852aa43c215SJeff Kirsher 2853aa43c215SJeff Kirsher /* clear interrupt */ 2854aa43c215SJeff Kirsher writel(0xffffffff, adapter->tgt_status_reg); 2855aa43c215SJeff Kirsher 2856aa43c215SJeff Kirsher napi_schedule(&sds_ring->napi); 2857aa43c215SJeff Kirsher return IRQ_HANDLED; 2858aa43c215SJeff Kirsher } 2859aa43c215SJeff Kirsher 2860aa43c215SJeff Kirsher static irqreturn_t qlcnic_msix_intr(int irq, void *data) 2861aa43c215SJeff Kirsher { 2862aa43c215SJeff Kirsher struct qlcnic_host_sds_ring *sds_ring = data; 2863aa43c215SJeff Kirsher 2864aa43c215SJeff Kirsher napi_schedule(&sds_ring->napi); 2865aa43c215SJeff Kirsher return IRQ_HANDLED; 2866aa43c215SJeff Kirsher } 2867aa43c215SJeff Kirsher 286813159183SSony Chacko static irqreturn_t qlcnic_msix_tx_intr(int irq, void *data) 286913159183SSony Chacko { 287013159183SSony Chacko struct qlcnic_host_tx_ring *tx_ring = data; 287113159183SSony Chacko 287213159183SSony Chacko napi_schedule(&tx_ring->napi); 287313159183SSony Chacko return IRQ_HANDLED; 287413159183SSony Chacko } 287513159183SSony Chacko 2876aa43c215SJeff Kirsher #ifdef CONFIG_NET_POLL_CONTROLLER 2877aa43c215SJeff Kirsher static void qlcnic_poll_controller(struct net_device *netdev) 2878aa43c215SJeff Kirsher { 2879aa43c215SJeff Kirsher int ring; 2880aa43c215SJeff Kirsher struct qlcnic_host_sds_ring *sds_ring; 2881aa43c215SJeff Kirsher struct qlcnic_adapter *adapter = netdev_priv(netdev); 2882aa43c215SJeff Kirsher struct qlcnic_recv_context *recv_ctx = adapter->recv_ctx; 2883aa43c215SJeff Kirsher 2884aa43c215SJeff Kirsher disable_irq(adapter->irq); 288534e8c406SHimanshu Madhani for (ring = 0; ring < adapter->drv_sds_rings; ring++) { 2886aa43c215SJeff Kirsher sds_ring = &recv_ctx->sds_rings[ring]; 2887aa43c215SJeff Kirsher qlcnic_intr(adapter->irq, sds_ring); 2888aa43c215SJeff Kirsher } 2889aa43c215SJeff Kirsher enable_irq(adapter->irq); 2890aa43c215SJeff Kirsher } 2891aa43c215SJeff Kirsher #endif 2892aa43c215SJeff Kirsher 2893aa43c215SJeff Kirsher static void 2894aa43c215SJeff Kirsher qlcnic_idc_debug_info(struct qlcnic_adapter *adapter, u8 encoding) 2895aa43c215SJeff Kirsher { 2896aa43c215SJeff Kirsher u32 val; 2897aa43c215SJeff Kirsher 2898aa43c215SJeff Kirsher val = adapter->portnum & 0xf; 2899aa43c215SJeff Kirsher val |= encoding << 7; 2900aa43c215SJeff Kirsher val |= (jiffies - adapter->dev_rst_time) << 8; 2901aa43c215SJeff Kirsher 2902a15ebd37SHimanshu Madhani QLC_SHARED_REG_WR32(adapter, QLCNIC_CRB_DRV_SCRATCH, val); 2903aa43c215SJeff Kirsher adapter->dev_rst_time = jiffies; 2904aa43c215SJeff Kirsher } 2905aa43c215SJeff Kirsher 2906aa43c215SJeff Kirsher static int 2907aa43c215SJeff Kirsher qlcnic_set_drv_state(struct qlcnic_adapter *adapter, u8 state) 2908aa43c215SJeff Kirsher { 2909aa43c215SJeff Kirsher u32 val; 2910aa43c215SJeff Kirsher 2911aa43c215SJeff Kirsher WARN_ON(state != QLCNIC_DEV_NEED_RESET && 2912aa43c215SJeff Kirsher state != QLCNIC_DEV_NEED_QUISCENT); 2913aa43c215SJeff Kirsher 2914aa43c215SJeff Kirsher if (qlcnic_api_lock(adapter)) 2915aa43c215SJeff Kirsher return -EIO; 2916aa43c215SJeff Kirsher 2917a15ebd37SHimanshu Madhani val = QLC_SHARED_REG_RD32(adapter, QLCNIC_CRB_DRV_STATE); 2918aa43c215SJeff Kirsher 2919aa43c215SJeff Kirsher if (state == QLCNIC_DEV_NEED_RESET) 2920aa43c215SJeff Kirsher QLC_DEV_SET_RST_RDY(val, adapter->portnum); 2921aa43c215SJeff Kirsher else if (state == QLCNIC_DEV_NEED_QUISCENT) 2922aa43c215SJeff Kirsher QLC_DEV_SET_QSCNT_RDY(val, adapter->portnum); 2923aa43c215SJeff Kirsher 2924a15ebd37SHimanshu Madhani QLC_SHARED_REG_WR32(adapter, QLCNIC_CRB_DRV_STATE, val); 2925aa43c215SJeff Kirsher 2926aa43c215SJeff Kirsher qlcnic_api_unlock(adapter); 2927aa43c215SJeff Kirsher 2928aa43c215SJeff Kirsher return 0; 2929aa43c215SJeff Kirsher } 2930aa43c215SJeff Kirsher 2931aa43c215SJeff Kirsher static int 2932aa43c215SJeff Kirsher qlcnic_clr_drv_state(struct qlcnic_adapter *adapter) 2933aa43c215SJeff Kirsher { 2934aa43c215SJeff Kirsher u32 val; 2935aa43c215SJeff Kirsher 2936aa43c215SJeff Kirsher if (qlcnic_api_lock(adapter)) 2937aa43c215SJeff Kirsher return -EBUSY; 2938aa43c215SJeff Kirsher 2939a15ebd37SHimanshu Madhani val = QLC_SHARED_REG_RD32(adapter, QLCNIC_CRB_DRV_STATE); 2940aa43c215SJeff Kirsher QLC_DEV_CLR_RST_QSCNT(val, adapter->portnum); 2941a15ebd37SHimanshu Madhani QLC_SHARED_REG_WR32(adapter, QLCNIC_CRB_DRV_STATE, val); 2942aa43c215SJeff Kirsher 2943aa43c215SJeff Kirsher qlcnic_api_unlock(adapter); 2944aa43c215SJeff Kirsher 2945aa43c215SJeff Kirsher return 0; 2946aa43c215SJeff Kirsher } 2947aa43c215SJeff Kirsher 2948486a5bc7SRajesh Borundia void qlcnic_clr_all_drv_state(struct qlcnic_adapter *adapter, u8 failed) 2949aa43c215SJeff Kirsher { 2950aa43c215SJeff Kirsher u32 val; 2951aa43c215SJeff Kirsher 2952aa43c215SJeff Kirsher if (qlcnic_api_lock(adapter)) 2953aa43c215SJeff Kirsher goto err; 2954aa43c215SJeff Kirsher 2955a15ebd37SHimanshu Madhani val = QLC_SHARED_REG_RD32(adapter, QLCNIC_CRB_DRV_ACTIVE); 2956aa43c215SJeff Kirsher QLC_DEV_CLR_REF_CNT(val, adapter->portnum); 2957a15ebd37SHimanshu Madhani QLC_SHARED_REG_WR32(adapter, QLCNIC_CRB_DRV_ACTIVE, val); 2958aa43c215SJeff Kirsher 2959aa43c215SJeff Kirsher if (failed) { 2960a15ebd37SHimanshu Madhani QLC_SHARED_REG_WR32(adapter, QLCNIC_CRB_DEV_STATE, 2961a15ebd37SHimanshu Madhani QLCNIC_DEV_FAILED); 2962aa43c215SJeff Kirsher dev_info(&adapter->pdev->dev, 2963aa43c215SJeff Kirsher "Device state set to Failed. Please Reboot\n"); 2964aa43c215SJeff Kirsher } else if (!(val & 0x11111111)) 2965a15ebd37SHimanshu Madhani QLC_SHARED_REG_WR32(adapter, QLCNIC_CRB_DEV_STATE, 2966a15ebd37SHimanshu Madhani QLCNIC_DEV_COLD); 2967aa43c215SJeff Kirsher 2968a15ebd37SHimanshu Madhani val = QLC_SHARED_REG_RD32(adapter, QLCNIC_CRB_DRV_STATE); 2969aa43c215SJeff Kirsher QLC_DEV_CLR_RST_QSCNT(val, adapter->portnum); 2970a15ebd37SHimanshu Madhani QLC_SHARED_REG_WR32(adapter, QLCNIC_CRB_DRV_STATE, val); 2971aa43c215SJeff Kirsher 2972aa43c215SJeff Kirsher qlcnic_api_unlock(adapter); 2973aa43c215SJeff Kirsher err: 2974aa43c215SJeff Kirsher adapter->fw_fail_cnt = 0; 2975aa43c215SJeff Kirsher adapter->flags &= ~QLCNIC_FW_HANG; 2976aa43c215SJeff Kirsher clear_bit(__QLCNIC_START_FW, &adapter->state); 2977aa43c215SJeff Kirsher clear_bit(__QLCNIC_RESETTING, &adapter->state); 2978aa43c215SJeff Kirsher } 2979aa43c215SJeff Kirsher 2980aa43c215SJeff Kirsher /* Grab api lock, before checking state */ 2981aa43c215SJeff Kirsher static int 2982aa43c215SJeff Kirsher qlcnic_check_drv_state(struct qlcnic_adapter *adapter) 2983aa43c215SJeff Kirsher { 2984aa43c215SJeff Kirsher int act, state, active_mask; 2985a15ebd37SHimanshu Madhani struct qlcnic_hardware_context *ahw = adapter->ahw; 2986aa43c215SJeff Kirsher 2987a15ebd37SHimanshu Madhani state = QLC_SHARED_REG_RD32(adapter, QLCNIC_CRB_DRV_STATE); 2988a15ebd37SHimanshu Madhani act = QLC_SHARED_REG_RD32(adapter, QLCNIC_CRB_DRV_ACTIVE); 2989aa43c215SJeff Kirsher 2990aa43c215SJeff Kirsher if (adapter->flags & QLCNIC_FW_RESET_OWNER) { 2991a15ebd37SHimanshu Madhani active_mask = (~(1 << (ahw->pci_func * 4))); 2992aa43c215SJeff Kirsher act = act & active_mask; 2993aa43c215SJeff Kirsher } 2994aa43c215SJeff Kirsher 2995aa43c215SJeff Kirsher if (((state & 0x11111111) == (act & 0x11111111)) || 2996aa43c215SJeff Kirsher ((act & 0x11111111) == ((state >> 1) & 0x11111111))) 2997aa43c215SJeff Kirsher return 0; 2998aa43c215SJeff Kirsher else 2999aa43c215SJeff Kirsher return 1; 3000aa43c215SJeff Kirsher } 3001aa43c215SJeff Kirsher 3002aa43c215SJeff Kirsher static int qlcnic_check_idc_ver(struct qlcnic_adapter *adapter) 3003aa43c215SJeff Kirsher { 3004a15ebd37SHimanshu Madhani u32 val = QLC_SHARED_REG_RD32(adapter, QLCNIC_CRB_DRV_IDC_VER); 3005aa43c215SJeff Kirsher 3006aa43c215SJeff Kirsher if (val != QLCNIC_DRV_IDC_VER) { 3007aa43c215SJeff Kirsher dev_warn(&adapter->pdev->dev, "IDC Version mismatch, driver's" 3008aa43c215SJeff Kirsher " idc ver = %x; reqd = %x\n", QLCNIC_DRV_IDC_VER, val); 3009aa43c215SJeff Kirsher } 3010aa43c215SJeff Kirsher 3011aa43c215SJeff Kirsher return 0; 3012aa43c215SJeff Kirsher } 3013aa43c215SJeff Kirsher 3014aa43c215SJeff Kirsher static int 3015aa43c215SJeff Kirsher qlcnic_can_start_firmware(struct qlcnic_adapter *adapter) 3016aa43c215SJeff Kirsher { 3017aa43c215SJeff Kirsher u32 val, prev_state; 3018aa43c215SJeff Kirsher u8 dev_init_timeo = adapter->dev_init_timeo; 3019aa43c215SJeff Kirsher u8 portnum = adapter->portnum; 3020aa43c215SJeff Kirsher u8 ret; 3021aa43c215SJeff Kirsher 3022aa43c215SJeff Kirsher if (test_and_clear_bit(__QLCNIC_START_FW, &adapter->state)) 3023aa43c215SJeff Kirsher return 1; 3024aa43c215SJeff Kirsher 3025aa43c215SJeff Kirsher if (qlcnic_api_lock(adapter)) 3026aa43c215SJeff Kirsher return -1; 3027aa43c215SJeff Kirsher 3028a15ebd37SHimanshu Madhani val = QLC_SHARED_REG_RD32(adapter, QLCNIC_CRB_DRV_ACTIVE); 3029aa43c215SJeff Kirsher if (!(val & (1 << (portnum * 4)))) { 3030aa43c215SJeff Kirsher QLC_DEV_SET_REF_CNT(val, portnum); 3031a15ebd37SHimanshu Madhani QLC_SHARED_REG_WR32(adapter, QLCNIC_CRB_DRV_ACTIVE, val); 3032aa43c215SJeff Kirsher } 3033aa43c215SJeff Kirsher 3034a15ebd37SHimanshu Madhani prev_state = QLC_SHARED_REG_RD32(adapter, QLCNIC_CRB_DEV_STATE); 3035aa43c215SJeff Kirsher QLCDB(adapter, HW, "Device state = %u\n", prev_state); 3036aa43c215SJeff Kirsher 3037aa43c215SJeff Kirsher switch (prev_state) { 3038aa43c215SJeff Kirsher case QLCNIC_DEV_COLD: 3039a15ebd37SHimanshu Madhani QLC_SHARED_REG_WR32(adapter, QLCNIC_CRB_DEV_STATE, 3040a15ebd37SHimanshu Madhani QLCNIC_DEV_INITIALIZING); 3041a15ebd37SHimanshu Madhani QLC_SHARED_REG_WR32(adapter, QLCNIC_CRB_DRV_IDC_VER, 3042a15ebd37SHimanshu Madhani QLCNIC_DRV_IDC_VER); 3043aa43c215SJeff Kirsher qlcnic_idc_debug_info(adapter, 0); 3044aa43c215SJeff Kirsher qlcnic_api_unlock(adapter); 3045aa43c215SJeff Kirsher return 1; 3046aa43c215SJeff Kirsher 3047aa43c215SJeff Kirsher case QLCNIC_DEV_READY: 3048aa43c215SJeff Kirsher ret = qlcnic_check_idc_ver(adapter); 3049aa43c215SJeff Kirsher qlcnic_api_unlock(adapter); 3050aa43c215SJeff Kirsher return ret; 3051aa43c215SJeff Kirsher 3052aa43c215SJeff Kirsher case QLCNIC_DEV_NEED_RESET: 3053a15ebd37SHimanshu Madhani val = QLC_SHARED_REG_RD32(adapter, QLCNIC_CRB_DRV_STATE); 3054aa43c215SJeff Kirsher QLC_DEV_SET_RST_RDY(val, portnum); 3055a15ebd37SHimanshu Madhani QLC_SHARED_REG_WR32(adapter, QLCNIC_CRB_DRV_STATE, val); 3056aa43c215SJeff Kirsher break; 3057aa43c215SJeff Kirsher 3058aa43c215SJeff Kirsher case QLCNIC_DEV_NEED_QUISCENT: 3059a15ebd37SHimanshu Madhani val = QLC_SHARED_REG_RD32(adapter, QLCNIC_CRB_DRV_STATE); 3060aa43c215SJeff Kirsher QLC_DEV_SET_QSCNT_RDY(val, portnum); 3061a15ebd37SHimanshu Madhani QLC_SHARED_REG_WR32(adapter, QLCNIC_CRB_DRV_STATE, val); 3062aa43c215SJeff Kirsher break; 3063aa43c215SJeff Kirsher 3064aa43c215SJeff Kirsher case QLCNIC_DEV_FAILED: 3065aa43c215SJeff Kirsher dev_err(&adapter->pdev->dev, "Device in failed state.\n"); 3066aa43c215SJeff Kirsher qlcnic_api_unlock(adapter); 3067aa43c215SJeff Kirsher return -1; 3068aa43c215SJeff Kirsher 3069aa43c215SJeff Kirsher case QLCNIC_DEV_INITIALIZING: 3070aa43c215SJeff Kirsher case QLCNIC_DEV_QUISCENT: 3071aa43c215SJeff Kirsher break; 3072aa43c215SJeff Kirsher } 3073aa43c215SJeff Kirsher 3074aa43c215SJeff Kirsher qlcnic_api_unlock(adapter); 3075aa43c215SJeff Kirsher 3076aa43c215SJeff Kirsher do { 3077aa43c215SJeff Kirsher msleep(1000); 3078a15ebd37SHimanshu Madhani prev_state = QLC_SHARED_REG_RD32(adapter, QLCNIC_CRB_DEV_STATE); 3079aa43c215SJeff Kirsher 3080aa43c215SJeff Kirsher if (prev_state == QLCNIC_DEV_QUISCENT) 3081aa43c215SJeff Kirsher continue; 3082aa43c215SJeff Kirsher } while ((prev_state != QLCNIC_DEV_READY) && --dev_init_timeo); 3083aa43c215SJeff Kirsher 3084aa43c215SJeff Kirsher if (!dev_init_timeo) { 3085aa43c215SJeff Kirsher dev_err(&adapter->pdev->dev, 3086aa43c215SJeff Kirsher "Waiting for device to initialize timeout\n"); 3087aa43c215SJeff Kirsher return -1; 3088aa43c215SJeff Kirsher } 3089aa43c215SJeff Kirsher 3090aa43c215SJeff Kirsher if (qlcnic_api_lock(adapter)) 3091aa43c215SJeff Kirsher return -1; 3092aa43c215SJeff Kirsher 3093a15ebd37SHimanshu Madhani val = QLC_SHARED_REG_RD32(adapter, QLCNIC_CRB_DRV_STATE); 3094aa43c215SJeff Kirsher QLC_DEV_CLR_RST_QSCNT(val, portnum); 3095a15ebd37SHimanshu Madhani QLC_SHARED_REG_WR32(adapter, QLCNIC_CRB_DRV_STATE, val); 3096aa43c215SJeff Kirsher 3097aa43c215SJeff Kirsher ret = qlcnic_check_idc_ver(adapter); 3098aa43c215SJeff Kirsher qlcnic_api_unlock(adapter); 3099aa43c215SJeff Kirsher 3100aa43c215SJeff Kirsher return ret; 3101aa43c215SJeff Kirsher } 3102aa43c215SJeff Kirsher 3103aa43c215SJeff Kirsher static void 3104aa43c215SJeff Kirsher qlcnic_fwinit_work(struct work_struct *work) 3105aa43c215SJeff Kirsher { 3106aa43c215SJeff Kirsher struct qlcnic_adapter *adapter = container_of(work, 3107aa43c215SJeff Kirsher struct qlcnic_adapter, fw_work.work); 3108aa43c215SJeff Kirsher u32 dev_state = 0xf; 3109aa43c215SJeff Kirsher u32 val; 3110aa43c215SJeff Kirsher 3111aa43c215SJeff Kirsher if (qlcnic_api_lock(adapter)) 3112aa43c215SJeff Kirsher goto err_ret; 3113aa43c215SJeff Kirsher 3114a15ebd37SHimanshu Madhani dev_state = QLC_SHARED_REG_RD32(adapter, QLCNIC_CRB_DEV_STATE); 3115aa43c215SJeff Kirsher if (dev_state == QLCNIC_DEV_QUISCENT || 3116aa43c215SJeff Kirsher dev_state == QLCNIC_DEV_NEED_QUISCENT) { 3117aa43c215SJeff Kirsher qlcnic_api_unlock(adapter); 3118aa43c215SJeff Kirsher qlcnic_schedule_work(adapter, qlcnic_fwinit_work, 3119aa43c215SJeff Kirsher FW_POLL_DELAY * 2); 3120aa43c215SJeff Kirsher return; 3121aa43c215SJeff Kirsher } 3122aa43c215SJeff Kirsher 312379788450SSony Chacko if (adapter->ahw->op_mode == QLCNIC_NON_PRIV_FUNC) { 3124aa43c215SJeff Kirsher qlcnic_api_unlock(adapter); 3125aa43c215SJeff Kirsher goto wait_npar; 3126aa43c215SJeff Kirsher } 3127aa43c215SJeff Kirsher 312816e3cf73SSritej Velaga if (dev_state == QLCNIC_DEV_INITIALIZING || 312916e3cf73SSritej Velaga dev_state == QLCNIC_DEV_READY) { 313016e3cf73SSritej Velaga dev_info(&adapter->pdev->dev, "Detected state change from " 313116e3cf73SSritej Velaga "DEV_NEED_RESET, skipping ack check\n"); 313216e3cf73SSritej Velaga goto skip_ack_check; 313316e3cf73SSritej Velaga } 313416e3cf73SSritej Velaga 3135aa43c215SJeff Kirsher if (adapter->fw_wait_cnt++ > adapter->reset_ack_timeo) { 313616e3cf73SSritej Velaga dev_info(&adapter->pdev->dev, "Reset:Failed to get ack %d sec\n", 3137aa43c215SJeff Kirsher adapter->reset_ack_timeo); 3138aa43c215SJeff Kirsher goto skip_ack_check; 3139aa43c215SJeff Kirsher } 3140aa43c215SJeff Kirsher 3141aa43c215SJeff Kirsher if (!qlcnic_check_drv_state(adapter)) { 3142aa43c215SJeff Kirsher skip_ack_check: 3143a15ebd37SHimanshu Madhani dev_state = QLC_SHARED_REG_RD32(adapter, QLCNIC_CRB_DEV_STATE); 3144aa43c215SJeff Kirsher 3145aa43c215SJeff Kirsher if (dev_state == QLCNIC_DEV_NEED_RESET) { 3146a15ebd37SHimanshu Madhani QLC_SHARED_REG_WR32(adapter, QLCNIC_CRB_DEV_STATE, 3147aa43c215SJeff Kirsher QLCNIC_DEV_INITIALIZING); 3148aa43c215SJeff Kirsher set_bit(__QLCNIC_START_FW, &adapter->state); 3149aa43c215SJeff Kirsher QLCDB(adapter, DRV, "Restarting fw\n"); 3150aa43c215SJeff Kirsher qlcnic_idc_debug_info(adapter, 0); 3151a15ebd37SHimanshu Madhani val = QLC_SHARED_REG_RD32(adapter, 3152a15ebd37SHimanshu Madhani QLCNIC_CRB_DRV_STATE); 3153aa43c215SJeff Kirsher QLC_DEV_SET_RST_RDY(val, adapter->portnum); 3154a15ebd37SHimanshu Madhani QLC_SHARED_REG_WR32(adapter, 3155a15ebd37SHimanshu Madhani QLCNIC_CRB_DRV_STATE, val); 3156aa43c215SJeff Kirsher } 3157aa43c215SJeff Kirsher 3158aa43c215SJeff Kirsher qlcnic_api_unlock(adapter); 3159aa43c215SJeff Kirsher 3160aa43c215SJeff Kirsher rtnl_lock(); 3161890b6e02SShahed Shaikh if (qlcnic_check_fw_dump_state(adapter) && 3162aa43c215SJeff Kirsher (adapter->flags & QLCNIC_FW_RESET_OWNER)) { 3163aa43c215SJeff Kirsher QLCDB(adapter, DRV, "Take FW dump\n"); 3164aa43c215SJeff Kirsher qlcnic_dump_fw(adapter); 3165aa43c215SJeff Kirsher adapter->flags |= QLCNIC_FW_HANG; 3166aa43c215SJeff Kirsher } 3167aa43c215SJeff Kirsher rtnl_unlock(); 3168aa43c215SJeff Kirsher 3169aa43c215SJeff Kirsher adapter->flags &= ~QLCNIC_FW_RESET_OWNER; 3170aa43c215SJeff Kirsher if (!adapter->nic_ops->start_firmware(adapter)) { 3171aa43c215SJeff Kirsher qlcnic_schedule_work(adapter, qlcnic_attach_work, 0); 3172aa43c215SJeff Kirsher adapter->fw_wait_cnt = 0; 3173aa43c215SJeff Kirsher return; 3174aa43c215SJeff Kirsher } 3175aa43c215SJeff Kirsher goto err_ret; 3176aa43c215SJeff Kirsher } 3177aa43c215SJeff Kirsher 3178aa43c215SJeff Kirsher qlcnic_api_unlock(adapter); 3179aa43c215SJeff Kirsher 3180aa43c215SJeff Kirsher wait_npar: 3181a15ebd37SHimanshu Madhani dev_state = QLC_SHARED_REG_RD32(adapter, QLCNIC_CRB_DEV_STATE); 3182aa43c215SJeff Kirsher QLCDB(adapter, HW, "Func waiting: Device state=%u\n", dev_state); 3183aa43c215SJeff Kirsher 3184aa43c215SJeff Kirsher switch (dev_state) { 3185aa43c215SJeff Kirsher case QLCNIC_DEV_READY: 31867e2cf4feSSony Chacko if (!qlcnic_start_firmware(adapter)) { 3187aa43c215SJeff Kirsher qlcnic_schedule_work(adapter, qlcnic_attach_work, 0); 3188aa43c215SJeff Kirsher adapter->fw_wait_cnt = 0; 3189aa43c215SJeff Kirsher return; 3190aa43c215SJeff Kirsher } 3191aa43c215SJeff Kirsher case QLCNIC_DEV_FAILED: 3192aa43c215SJeff Kirsher break; 3193aa43c215SJeff Kirsher default: 3194aa43c215SJeff Kirsher qlcnic_schedule_work(adapter, 3195aa43c215SJeff Kirsher qlcnic_fwinit_work, FW_POLL_DELAY); 3196aa43c215SJeff Kirsher return; 3197aa43c215SJeff Kirsher } 3198aa43c215SJeff Kirsher 3199aa43c215SJeff Kirsher err_ret: 3200aa43c215SJeff Kirsher dev_err(&adapter->pdev->dev, "Fwinit work failed state=%u " 3201aa43c215SJeff Kirsher "fw_wait_cnt=%u\n", dev_state, adapter->fw_wait_cnt); 3202aa43c215SJeff Kirsher netif_device_attach(adapter->netdev); 3203aa43c215SJeff Kirsher qlcnic_clr_all_drv_state(adapter, 0); 3204aa43c215SJeff Kirsher } 3205aa43c215SJeff Kirsher 3206aa43c215SJeff Kirsher static void 3207aa43c215SJeff Kirsher qlcnic_detach_work(struct work_struct *work) 3208aa43c215SJeff Kirsher { 3209aa43c215SJeff Kirsher struct qlcnic_adapter *adapter = container_of(work, 3210aa43c215SJeff Kirsher struct qlcnic_adapter, fw_work.work); 3211aa43c215SJeff Kirsher struct net_device *netdev = adapter->netdev; 3212aa43c215SJeff Kirsher u32 status; 3213aa43c215SJeff Kirsher 3214aa43c215SJeff Kirsher netif_device_detach(netdev); 3215aa43c215SJeff Kirsher 3216aa43c215SJeff Kirsher /* Dont grab rtnl lock during Quiscent mode */ 3217aa43c215SJeff Kirsher if (adapter->dev_state == QLCNIC_DEV_NEED_QUISCENT) { 3218aa43c215SJeff Kirsher if (netif_running(netdev)) 3219aa43c215SJeff Kirsher __qlcnic_down(adapter, netdev); 3220aa43c215SJeff Kirsher } else 3221aa43c215SJeff Kirsher qlcnic_down(adapter, netdev); 3222aa43c215SJeff Kirsher 3223a15ebd37SHimanshu Madhani status = QLC_SHARED_REG_RD32(adapter, QLCNIC_PEG_HALT_STATUS1); 3224aa43c215SJeff Kirsher 322544f65b29SSony Chacko if (status & QLCNIC_RCODE_FATAL_ERROR) { 322644f65b29SSony Chacko dev_err(&adapter->pdev->dev, 322744f65b29SSony Chacko "Detaching the device: peg halt status1=0x%x\n", 322844f65b29SSony Chacko status); 3229aa43c215SJeff Kirsher 323044f65b29SSony Chacko if (QLCNIC_FWERROR_CODE(status) == QLCNIC_FWERROR_FAN_FAILURE) { 323144f65b29SSony Chacko dev_err(&adapter->pdev->dev, 323244f65b29SSony Chacko "On board active cooling fan failed. " 323344f65b29SSony Chacko "Device has been halted.\n"); 323444f65b29SSony Chacko dev_err(&adapter->pdev->dev, 323544f65b29SSony Chacko "Replace the adapter.\n"); 323644f65b29SSony Chacko } 323744f65b29SSony Chacko 3238aa43c215SJeff Kirsher goto err_ret; 323944f65b29SSony Chacko } 324044f65b29SSony Chacko 324179788450SSony Chacko if (adapter->ahw->temp == QLCNIC_TEMP_PANIC) { 324244f65b29SSony Chacko dev_err(&adapter->pdev->dev, "Detaching the device: temp=%d\n", 324379788450SSony Chacko adapter->ahw->temp); 324444f65b29SSony Chacko goto err_ret; 324544f65b29SSony Chacko } 324644f65b29SSony Chacko 3247aa43c215SJeff Kirsher /* Dont ack if this instance is the reset owner */ 3248aa43c215SJeff Kirsher if (!(adapter->flags & QLCNIC_FW_RESET_OWNER)) { 324944f65b29SSony Chacko if (qlcnic_set_drv_state(adapter, adapter->dev_state)) { 325044f65b29SSony Chacko dev_err(&adapter->pdev->dev, 325144f65b29SSony Chacko "Failed to set driver state," 325244f65b29SSony Chacko "detaching the device.\n"); 3253aa43c215SJeff Kirsher goto err_ret; 3254aa43c215SJeff Kirsher } 325544f65b29SSony Chacko } 3256aa43c215SJeff Kirsher 3257aa43c215SJeff Kirsher adapter->fw_wait_cnt = 0; 3258aa43c215SJeff Kirsher 3259aa43c215SJeff Kirsher qlcnic_schedule_work(adapter, qlcnic_fwinit_work, FW_POLL_DELAY); 3260aa43c215SJeff Kirsher 3261aa43c215SJeff Kirsher return; 3262aa43c215SJeff Kirsher 3263aa43c215SJeff Kirsher err_ret: 3264aa43c215SJeff Kirsher netif_device_attach(netdev); 3265aa43c215SJeff Kirsher qlcnic_clr_all_drv_state(adapter, 1); 3266aa43c215SJeff Kirsher } 3267aa43c215SJeff Kirsher 3268aa43c215SJeff Kirsher /*Transit NPAR state to NON Operational */ 3269aa43c215SJeff Kirsher static void 3270aa43c215SJeff Kirsher qlcnic_set_npar_non_operational(struct qlcnic_adapter *adapter) 3271aa43c215SJeff Kirsher { 3272aa43c215SJeff Kirsher u32 state; 3273aa43c215SJeff Kirsher 3274a15ebd37SHimanshu Madhani state = QLC_SHARED_REG_RD32(adapter, QLCNIC_CRB_DEV_NPAR_STATE); 3275aa43c215SJeff Kirsher if (state == QLCNIC_DEV_NPAR_NON_OPER) 3276aa43c215SJeff Kirsher return; 3277aa43c215SJeff Kirsher 3278aa43c215SJeff Kirsher if (qlcnic_api_lock(adapter)) 3279aa43c215SJeff Kirsher return; 3280a15ebd37SHimanshu Madhani QLC_SHARED_REG_WR32(adapter, QLCNIC_CRB_DEV_NPAR_STATE, 3281a15ebd37SHimanshu Madhani QLCNIC_DEV_NPAR_NON_OPER); 3282aa43c215SJeff Kirsher qlcnic_api_unlock(adapter); 3283aa43c215SJeff Kirsher } 3284aa43c215SJeff Kirsher 32857e2cf4feSSony Chacko void qlcnic_82xx_dev_request_reset(struct qlcnic_adapter *adapter, u32 key) 3286aa43c215SJeff Kirsher { 3287646779f1SSritej Velaga u32 state, xg_val = 0, gb_val = 0; 3288aa43c215SJeff Kirsher 3289646779f1SSritej Velaga qlcnic_xg_set_xg0_mask(xg_val); 3290646779f1SSritej Velaga qlcnic_xg_set_xg1_mask(xg_val); 3291646779f1SSritej Velaga QLCWR32(adapter, QLCNIC_NIU_XG_PAUSE_CTL, xg_val); 3292646779f1SSritej Velaga qlcnic_gb_set_gb0_mask(gb_val); 3293646779f1SSritej Velaga qlcnic_gb_set_gb1_mask(gb_val); 3294646779f1SSritej Velaga qlcnic_gb_set_gb2_mask(gb_val); 3295646779f1SSritej Velaga qlcnic_gb_set_gb3_mask(gb_val); 3296646779f1SSritej Velaga QLCWR32(adapter, QLCNIC_NIU_GB_PAUSE_CTL, gb_val); 3297646779f1SSritej Velaga dev_info(&adapter->pdev->dev, "Pause control frames disabled" 3298646779f1SSritej Velaga " on all ports\n"); 3299aa43c215SJeff Kirsher adapter->need_fw_reset = 1; 330013159183SSony Chacko 3301aa43c215SJeff Kirsher if (qlcnic_api_lock(adapter)) 3302aa43c215SJeff Kirsher return; 3303aa43c215SJeff Kirsher 330413159183SSony Chacko state = QLC_SHARED_REG_RD32(adapter, QLCNIC_CRB_DEV_STATE); 330578ea2d97SSucheta Chakraborty 330678ea2d97SSucheta Chakraborty if (test_bit(__QLCNIC_MAINTENANCE_MODE, &adapter->state)) { 330778ea2d97SSucheta Chakraborty netdev_err(adapter->netdev, "%s: Device is in non-operational state\n", 330866451615SSucheta Chakraborty __func__); 330966451615SSucheta Chakraborty qlcnic_api_unlock(adapter); 331066451615SSucheta Chakraborty 331166451615SSucheta Chakraborty return; 331266451615SSucheta Chakraborty } 3313aa43c215SJeff Kirsher 3314aa43c215SJeff Kirsher if (state == QLCNIC_DEV_READY) { 331513159183SSony Chacko QLC_SHARED_REG_WR32(adapter, QLCNIC_CRB_DEV_STATE, 331613159183SSony Chacko QLCNIC_DEV_NEED_RESET); 3317aa43c215SJeff Kirsher adapter->flags |= QLCNIC_FW_RESET_OWNER; 3318aa43c215SJeff Kirsher QLCDB(adapter, DRV, "NEED_RESET state set\n"); 3319aa43c215SJeff Kirsher qlcnic_idc_debug_info(adapter, 0); 3320aa43c215SJeff Kirsher } 3321aa43c215SJeff Kirsher 332213159183SSony Chacko QLC_SHARED_REG_WR32(adapter, QLCNIC_CRB_DEV_NPAR_STATE, 332313159183SSony Chacko QLCNIC_DEV_NPAR_NON_OPER); 3324aa43c215SJeff Kirsher qlcnic_api_unlock(adapter); 3325aa43c215SJeff Kirsher } 3326aa43c215SJeff Kirsher 3327aa43c215SJeff Kirsher /* Transit to NPAR READY state from NPAR NOT READY state */ 3328aa43c215SJeff Kirsher static void 3329aa43c215SJeff Kirsher qlcnic_dev_set_npar_ready(struct qlcnic_adapter *adapter) 3330aa43c215SJeff Kirsher { 3331aa43c215SJeff Kirsher if (qlcnic_api_lock(adapter)) 3332aa43c215SJeff Kirsher return; 3333aa43c215SJeff Kirsher 3334a15ebd37SHimanshu Madhani QLC_SHARED_REG_WR32(adapter, QLCNIC_CRB_DEV_NPAR_STATE, 3335a15ebd37SHimanshu Madhani QLCNIC_DEV_NPAR_OPER); 3336aa43c215SJeff Kirsher QLCDB(adapter, DRV, "NPAR operational state set\n"); 3337aa43c215SJeff Kirsher 3338aa43c215SJeff Kirsher qlcnic_api_unlock(adapter); 3339aa43c215SJeff Kirsher } 3340aa43c215SJeff Kirsher 334113159183SSony Chacko void qlcnic_schedule_work(struct qlcnic_adapter *adapter, 3342aa43c215SJeff Kirsher work_func_t func, int delay) 3343aa43c215SJeff Kirsher { 3344aa43c215SJeff Kirsher if (test_bit(__QLCNIC_AER, &adapter->state)) 3345aa43c215SJeff Kirsher return; 3346aa43c215SJeff Kirsher 3347aa43c215SJeff Kirsher INIT_DELAYED_WORK(&adapter->fw_work, func); 334813159183SSony Chacko queue_delayed_work(adapter->qlcnic_wq, &adapter->fw_work, 3349aa43c215SJeff Kirsher round_jiffies_relative(delay)); 3350aa43c215SJeff Kirsher } 3351aa43c215SJeff Kirsher 3352aa43c215SJeff Kirsher static void 3353aa43c215SJeff Kirsher qlcnic_attach_work(struct work_struct *work) 3354aa43c215SJeff Kirsher { 3355aa43c215SJeff Kirsher struct qlcnic_adapter *adapter = container_of(work, 3356aa43c215SJeff Kirsher struct qlcnic_adapter, fw_work.work); 3357aa43c215SJeff Kirsher struct net_device *netdev = adapter->netdev; 3358aa43c215SJeff Kirsher u32 npar_state; 3359aa43c215SJeff Kirsher 336079788450SSony Chacko if (adapter->ahw->op_mode != QLCNIC_MGMT_FUNC) { 3361a15ebd37SHimanshu Madhani npar_state = QLC_SHARED_REG_RD32(adapter, 3362a15ebd37SHimanshu Madhani QLCNIC_CRB_DEV_NPAR_STATE); 3363aa43c215SJeff Kirsher if (adapter->fw_wait_cnt++ > QLCNIC_DEV_NPAR_OPER_TIMEO) 3364aa43c215SJeff Kirsher qlcnic_clr_all_drv_state(adapter, 0); 3365aa43c215SJeff Kirsher else if (npar_state != QLCNIC_DEV_NPAR_OPER) 3366aa43c215SJeff Kirsher qlcnic_schedule_work(adapter, qlcnic_attach_work, 3367aa43c215SJeff Kirsher FW_POLL_DELAY); 3368aa43c215SJeff Kirsher else 3369aa43c215SJeff Kirsher goto attach; 3370aa43c215SJeff Kirsher QLCDB(adapter, DRV, "Waiting for NPAR state to operational\n"); 3371aa43c215SJeff Kirsher return; 3372aa43c215SJeff Kirsher } 3373aa43c215SJeff Kirsher attach: 33741de899d3SSucheta Chakraborty qlcnic_dcb_get_info(adapter->dcb); 337514d385b9SSucheta Chakraborty 3376aa43c215SJeff Kirsher if (netif_running(netdev)) { 3377aa43c215SJeff Kirsher if (qlcnic_up(adapter, netdev)) 3378aa43c215SJeff Kirsher goto done; 3379aa43c215SJeff Kirsher 3380aa43c215SJeff Kirsher qlcnic_restore_indev_addr(netdev, NETDEV_UP); 3381aa43c215SJeff Kirsher } 3382aa43c215SJeff Kirsher 3383aa43c215SJeff Kirsher done: 3384aa43c215SJeff Kirsher netif_device_attach(netdev); 3385aa43c215SJeff Kirsher adapter->fw_fail_cnt = 0; 3386aa43c215SJeff Kirsher adapter->flags &= ~QLCNIC_FW_HANG; 3387aa43c215SJeff Kirsher clear_bit(__QLCNIC_RESETTING, &adapter->state); 338824866d15SHimanshu Madhani if (adapter->portnum == 0) 33898af3f33dSPratik Pujar qlcnic_set_drv_version(adapter); 3390aa43c215SJeff Kirsher 3391aa43c215SJeff Kirsher if (!qlcnic_clr_drv_state(adapter)) 3392aa43c215SJeff Kirsher qlcnic_schedule_work(adapter, qlcnic_fw_poll_work, 3393aa43c215SJeff Kirsher FW_POLL_DELAY); 3394aa43c215SJeff Kirsher } 3395aa43c215SJeff Kirsher 3396aa43c215SJeff Kirsher static int 3397aa43c215SJeff Kirsher qlcnic_check_health(struct qlcnic_adapter *adapter) 3398aa43c215SJeff Kirsher { 3399891e71b1SPratik Pujar struct qlcnic_hardware_context *ahw = adapter->ahw; 3400891e71b1SPratik Pujar struct qlcnic_fw_dump *fw_dump = &ahw->fw_dump; 3401aa43c215SJeff Kirsher u32 state = 0, heartbeat; 3402853d4bcaSAmeen Rahman u32 peg_status; 34034bd8e738SHimanshu Madhani int err = 0; 3404aa43c215SJeff Kirsher 3405aa43c215SJeff Kirsher if (qlcnic_check_temp(adapter)) 3406aa43c215SJeff Kirsher goto detach; 3407aa43c215SJeff Kirsher 3408aa43c215SJeff Kirsher if (adapter->need_fw_reset) 34097e2cf4feSSony Chacko qlcnic_dev_request_reset(adapter, 0); 3410aa43c215SJeff Kirsher 3411a15ebd37SHimanshu Madhani state = QLC_SHARED_REG_RD32(adapter, QLCNIC_CRB_DEV_STATE); 3412aa43c215SJeff Kirsher if (state == QLCNIC_DEV_NEED_RESET) { 3413aa43c215SJeff Kirsher qlcnic_set_npar_non_operational(adapter); 3414aa43c215SJeff Kirsher adapter->need_fw_reset = 1; 3415aa43c215SJeff Kirsher } else if (state == QLCNIC_DEV_NEED_QUISCENT) 3416aa43c215SJeff Kirsher goto detach; 3417aa43c215SJeff Kirsher 3418a15ebd37SHimanshu Madhani heartbeat = QLC_SHARED_REG_RD32(adapter, QLCNIC_PEG_ALIVE_COUNTER); 3419aa43c215SJeff Kirsher if (heartbeat != adapter->heartbeat) { 3420aa43c215SJeff Kirsher adapter->heartbeat = heartbeat; 3421aa43c215SJeff Kirsher adapter->fw_fail_cnt = 0; 3422aa43c215SJeff Kirsher if (adapter->need_fw_reset) 3423aa43c215SJeff Kirsher goto detach; 3424aa43c215SJeff Kirsher 3425891e71b1SPratik Pujar if (ahw->reset_context && qlcnic_auto_fw_reset) 3426aa43c215SJeff Kirsher qlcnic_reset_hw_context(adapter); 3427aa43c215SJeff Kirsher 3428aa43c215SJeff Kirsher return 0; 3429aa43c215SJeff Kirsher } 3430aa43c215SJeff Kirsher 3431aa43c215SJeff Kirsher if (++adapter->fw_fail_cnt < FW_FAIL_THRESH) 3432aa43c215SJeff Kirsher return 0; 3433aa43c215SJeff Kirsher 3434aa43c215SJeff Kirsher adapter->flags |= QLCNIC_FW_HANG; 3435aa43c215SJeff Kirsher 34367e2cf4feSSony Chacko qlcnic_dev_request_reset(adapter, 0); 3437aa43c215SJeff Kirsher 3438099f7aa7SSony Chacko if (qlcnic_auto_fw_reset) 3439aa43c215SJeff Kirsher clear_bit(__QLCNIC_FW_ATTACHED, &adapter->state); 3440aa43c215SJeff Kirsher 3441853d4bcaSAmeen Rahman dev_err(&adapter->pdev->dev, "firmware hang detected\n"); 3442a15ebd37SHimanshu Madhani peg_status = QLC_SHARED_REG_RD32(adapter, QLCNIC_PEG_HALT_STATUS1); 3443853d4bcaSAmeen Rahman dev_err(&adapter->pdev->dev, "Dumping hw/fw registers\n" 3444aa43c215SJeff Kirsher "PEG_HALT_STATUS1: 0x%x, PEG_HALT_STATUS2: 0x%x,\n" 3445aa43c215SJeff Kirsher "PEG_NET_0_PC: 0x%x, PEG_NET_1_PC: 0x%x,\n" 3446aa43c215SJeff Kirsher "PEG_NET_2_PC: 0x%x, PEG_NET_3_PC: 0x%x,\n" 3447aa43c215SJeff Kirsher "PEG_NET_4_PC: 0x%x\n", 3448a15ebd37SHimanshu Madhani peg_status, 3449a15ebd37SHimanshu Madhani QLC_SHARED_REG_RD32(adapter, QLCNIC_PEG_HALT_STATUS2), 34504bd8e738SHimanshu Madhani QLCRD32(adapter, QLCNIC_CRB_PEG_NET_0 + 0x3c, &err), 34514bd8e738SHimanshu Madhani QLCRD32(adapter, QLCNIC_CRB_PEG_NET_1 + 0x3c, &err), 34524bd8e738SHimanshu Madhani QLCRD32(adapter, QLCNIC_CRB_PEG_NET_2 + 0x3c, &err), 34534bd8e738SHimanshu Madhani QLCRD32(adapter, QLCNIC_CRB_PEG_NET_3 + 0x3c, &err), 34544bd8e738SHimanshu Madhani QLCRD32(adapter, QLCNIC_CRB_PEG_NET_4 + 0x3c, &err)); 345597048a1fSSritej Velaga if (QLCNIC_FWERROR_CODE(peg_status) == 0x67) 3456853d4bcaSAmeen Rahman dev_err(&adapter->pdev->dev, 3457853d4bcaSAmeen Rahman "Firmware aborted with error code 0x00006700. " 3458853d4bcaSAmeen Rahman "Device is being reset.\n"); 3459aa43c215SJeff Kirsher detach: 3460aa43c215SJeff Kirsher adapter->dev_state = (state == QLCNIC_DEV_NEED_QUISCENT) ? state : 3461aa43c215SJeff Kirsher QLCNIC_DEV_NEED_RESET; 3462aa43c215SJeff Kirsher 3463099f7aa7SSony Chacko if (qlcnic_auto_fw_reset && !test_and_set_bit(__QLCNIC_RESETTING, 3464099f7aa7SSony Chacko &adapter->state)) { 3465aa43c215SJeff Kirsher 3466aa43c215SJeff Kirsher qlcnic_schedule_work(adapter, qlcnic_detach_work, 0); 3467aa43c215SJeff Kirsher QLCDB(adapter, DRV, "fw recovery scheduled.\n"); 3468891e71b1SPratik Pujar } else if (!qlcnic_auto_fw_reset && fw_dump->enable && 3469891e71b1SPratik Pujar adapter->flags & QLCNIC_FW_RESET_OWNER) { 3470891e71b1SPratik Pujar qlcnic_dump_fw(adapter); 3471aa43c215SJeff Kirsher } 3472aa43c215SJeff Kirsher 3473aa43c215SJeff Kirsher return 1; 3474aa43c215SJeff Kirsher } 3475aa43c215SJeff Kirsher 3476486a5bc7SRajesh Borundia void qlcnic_fw_poll_work(struct work_struct *work) 3477aa43c215SJeff Kirsher { 3478aa43c215SJeff Kirsher struct qlcnic_adapter *adapter = container_of(work, 3479aa43c215SJeff Kirsher struct qlcnic_adapter, fw_work.work); 3480aa43c215SJeff Kirsher 3481aa43c215SJeff Kirsher if (test_bit(__QLCNIC_RESETTING, &adapter->state)) 3482aa43c215SJeff Kirsher goto reschedule; 3483aa43c215SJeff Kirsher 3484aa43c215SJeff Kirsher 3485aa43c215SJeff Kirsher if (qlcnic_check_health(adapter)) 3486aa43c215SJeff Kirsher return; 3487aa43c215SJeff Kirsher 3488aa43c215SJeff Kirsher if (adapter->fhash.fnum) 3489aa43c215SJeff Kirsher qlcnic_prune_lb_filters(adapter); 3490aa43c215SJeff Kirsher 3491aa43c215SJeff Kirsher reschedule: 3492aa43c215SJeff Kirsher qlcnic_schedule_work(adapter, qlcnic_fw_poll_work, FW_POLL_DELAY); 3493aa43c215SJeff Kirsher } 3494aa43c215SJeff Kirsher 3495aa43c215SJeff Kirsher static int qlcnic_is_first_func(struct pci_dev *pdev) 3496aa43c215SJeff Kirsher { 3497aa43c215SJeff Kirsher struct pci_dev *oth_pdev; 3498aa43c215SJeff Kirsher int val = pdev->devfn; 3499aa43c215SJeff Kirsher 3500aa43c215SJeff Kirsher while (val-- > 0) { 3501aa43c215SJeff Kirsher oth_pdev = pci_get_domain_bus_and_slot(pci_domain_nr 3502aa43c215SJeff Kirsher (pdev->bus), pdev->bus->number, 3503aa43c215SJeff Kirsher PCI_DEVFN(PCI_SLOT(pdev->devfn), val)); 3504aa43c215SJeff Kirsher if (!oth_pdev) 3505aa43c215SJeff Kirsher continue; 3506aa43c215SJeff Kirsher 3507aa43c215SJeff Kirsher if (oth_pdev->current_state != PCI_D3cold) { 3508aa43c215SJeff Kirsher pci_dev_put(oth_pdev); 3509aa43c215SJeff Kirsher return 0; 3510aa43c215SJeff Kirsher } 3511aa43c215SJeff Kirsher pci_dev_put(oth_pdev); 3512aa43c215SJeff Kirsher } 3513aa43c215SJeff Kirsher return 1; 3514aa43c215SJeff Kirsher } 3515aa43c215SJeff Kirsher 3516aa43c215SJeff Kirsher static int qlcnic_attach_func(struct pci_dev *pdev) 3517aa43c215SJeff Kirsher { 3518aa43c215SJeff Kirsher int err, first_func; 3519aa43c215SJeff Kirsher struct qlcnic_adapter *adapter = pci_get_drvdata(pdev); 3520aa43c215SJeff Kirsher struct net_device *netdev = adapter->netdev; 3521aa43c215SJeff Kirsher 3522aa43c215SJeff Kirsher pdev->error_state = pci_channel_io_normal; 3523aa43c215SJeff Kirsher 3524aa43c215SJeff Kirsher err = pci_enable_device(pdev); 3525aa43c215SJeff Kirsher if (err) 3526aa43c215SJeff Kirsher return err; 3527aa43c215SJeff Kirsher 3528aa43c215SJeff Kirsher pci_set_master(pdev); 3529aa43c215SJeff Kirsher pci_restore_state(pdev); 3530aa43c215SJeff Kirsher 3531aa43c215SJeff Kirsher first_func = qlcnic_is_first_func(pdev); 3532aa43c215SJeff Kirsher 3533aa43c215SJeff Kirsher if (qlcnic_api_lock(adapter)) 3534aa43c215SJeff Kirsher return -EINVAL; 3535aa43c215SJeff Kirsher 353679788450SSony Chacko if (adapter->ahw->op_mode != QLCNIC_NON_PRIV_FUNC && first_func) { 3537aa43c215SJeff Kirsher adapter->need_fw_reset = 1; 3538aa43c215SJeff Kirsher set_bit(__QLCNIC_START_FW, &adapter->state); 3539a15ebd37SHimanshu Madhani QLC_SHARED_REG_WR32(adapter, QLCNIC_CRB_DEV_STATE, 3540a15ebd37SHimanshu Madhani QLCNIC_DEV_INITIALIZING); 3541aa43c215SJeff Kirsher QLCDB(adapter, DRV, "Restarting fw\n"); 3542aa43c215SJeff Kirsher } 3543aa43c215SJeff Kirsher qlcnic_api_unlock(adapter); 3544aa43c215SJeff Kirsher 354513159183SSony Chacko err = qlcnic_start_firmware(adapter); 3546aa43c215SJeff Kirsher if (err) 3547aa43c215SJeff Kirsher return err; 3548aa43c215SJeff Kirsher 3549aa43c215SJeff Kirsher qlcnic_clr_drv_state(adapter); 355013159183SSony Chacko kfree(adapter->msix_entries); 355113159183SSony Chacko adapter->msix_entries = NULL; 355234e8c406SHimanshu Madhani err = qlcnic_setup_intr(adapter); 355313159183SSony Chacko 35549a97e705SManish chopra if (err) { 35559a97e705SManish chopra kfree(adapter->msix_entries); 35569a97e705SManish chopra netdev_err(netdev, "failed to setup interrupt\n"); 35579a97e705SManish chopra return err; 35589a97e705SManish chopra } 35599a97e705SManish chopra 3560aa43c215SJeff Kirsher if (netif_running(netdev)) { 3561aa43c215SJeff Kirsher err = qlcnic_attach(adapter); 3562aa43c215SJeff Kirsher if (err) { 3563aa43c215SJeff Kirsher qlcnic_clr_all_drv_state(adapter, 1); 3564aa43c215SJeff Kirsher clear_bit(__QLCNIC_AER, &adapter->state); 3565aa43c215SJeff Kirsher netif_device_attach(netdev); 3566aa43c215SJeff Kirsher return err; 3567aa43c215SJeff Kirsher } 3568aa43c215SJeff Kirsher 3569aa43c215SJeff Kirsher err = qlcnic_up(adapter, netdev); 3570aa43c215SJeff Kirsher if (err) 3571aa43c215SJeff Kirsher goto done; 3572aa43c215SJeff Kirsher 3573aa43c215SJeff Kirsher qlcnic_restore_indev_addr(netdev, NETDEV_UP); 3574aa43c215SJeff Kirsher } 3575aa43c215SJeff Kirsher done: 3576aa43c215SJeff Kirsher netif_device_attach(netdev); 3577aa43c215SJeff Kirsher return err; 3578aa43c215SJeff Kirsher } 3579aa43c215SJeff Kirsher 35804460f2e8SPratik Pujar pci_ers_result_t qlcnic_82xx_io_error_detected(struct pci_dev *pdev, 3581aa43c215SJeff Kirsher pci_channel_state_t state) 3582aa43c215SJeff Kirsher { 3583aa43c215SJeff Kirsher struct qlcnic_adapter *adapter = pci_get_drvdata(pdev); 3584aa43c215SJeff Kirsher struct net_device *netdev = adapter->netdev; 3585aa43c215SJeff Kirsher 3586aa43c215SJeff Kirsher if (state == pci_channel_io_perm_failure) 3587aa43c215SJeff Kirsher return PCI_ERS_RESULT_DISCONNECT; 3588aa43c215SJeff Kirsher 3589aa43c215SJeff Kirsher if (state == pci_channel_io_normal) 3590aa43c215SJeff Kirsher return PCI_ERS_RESULT_RECOVERED; 3591aa43c215SJeff Kirsher 3592aa43c215SJeff Kirsher set_bit(__QLCNIC_AER, &adapter->state); 3593aa43c215SJeff Kirsher netif_device_detach(netdev); 3594aa43c215SJeff Kirsher 3595aa43c215SJeff Kirsher cancel_delayed_work_sync(&adapter->fw_work); 3596aa43c215SJeff Kirsher 3597aa43c215SJeff Kirsher if (netif_running(netdev)) 3598aa43c215SJeff Kirsher qlcnic_down(adapter, netdev); 3599aa43c215SJeff Kirsher 3600aa43c215SJeff Kirsher qlcnic_detach(adapter); 3601aa43c215SJeff Kirsher qlcnic_teardown_intr(adapter); 3602aa43c215SJeff Kirsher 3603aa43c215SJeff Kirsher clear_bit(__QLCNIC_RESETTING, &adapter->state); 3604aa43c215SJeff Kirsher 3605aa43c215SJeff Kirsher pci_save_state(pdev); 3606aa43c215SJeff Kirsher pci_disable_device(pdev); 3607aa43c215SJeff Kirsher 3608aa43c215SJeff Kirsher return PCI_ERS_RESULT_NEED_RESET; 3609aa43c215SJeff Kirsher } 3610aa43c215SJeff Kirsher 36114460f2e8SPratik Pujar pci_ers_result_t qlcnic_82xx_io_slot_reset(struct pci_dev *pdev) 3612aa43c215SJeff Kirsher { 3613aa43c215SJeff Kirsher return qlcnic_attach_func(pdev) ? PCI_ERS_RESULT_DISCONNECT : 3614aa43c215SJeff Kirsher PCI_ERS_RESULT_RECOVERED; 3615aa43c215SJeff Kirsher } 3616aa43c215SJeff Kirsher 36174460f2e8SPratik Pujar void qlcnic_82xx_io_resume(struct pci_dev *pdev) 3618aa43c215SJeff Kirsher { 3619a15ebd37SHimanshu Madhani u32 state; 3620aa43c215SJeff Kirsher struct qlcnic_adapter *adapter = pci_get_drvdata(pdev); 3621aa43c215SJeff Kirsher 3622aa43c215SJeff Kirsher pci_cleanup_aer_uncorrect_error_status(pdev); 3623a15ebd37SHimanshu Madhani state = QLC_SHARED_REG_RD32(adapter, QLCNIC_CRB_DEV_STATE); 3624a15ebd37SHimanshu Madhani if (state == QLCNIC_DEV_READY && test_and_clear_bit(__QLCNIC_AER, 3625a15ebd37SHimanshu Madhani &adapter->state)) 3626aa43c215SJeff Kirsher qlcnic_schedule_work(adapter, qlcnic_fw_poll_work, 3627aa43c215SJeff Kirsher FW_POLL_DELAY); 3628aa43c215SJeff Kirsher } 3629aa43c215SJeff Kirsher 36304460f2e8SPratik Pujar static pci_ers_result_t qlcnic_io_error_detected(struct pci_dev *pdev, 36314460f2e8SPratik Pujar pci_channel_state_t state) 36324460f2e8SPratik Pujar { 36334460f2e8SPratik Pujar struct qlcnic_adapter *adapter = pci_get_drvdata(pdev); 36344460f2e8SPratik Pujar struct qlcnic_hardware_ops *hw_ops = adapter->ahw->hw_ops; 36354460f2e8SPratik Pujar 36364460f2e8SPratik Pujar if (hw_ops->io_error_detected) { 36374460f2e8SPratik Pujar return hw_ops->io_error_detected(pdev, state); 36384460f2e8SPratik Pujar } else { 36394460f2e8SPratik Pujar dev_err(&pdev->dev, "AER error_detected handler not registered.\n"); 36404460f2e8SPratik Pujar return PCI_ERS_RESULT_DISCONNECT; 36414460f2e8SPratik Pujar } 36424460f2e8SPratik Pujar } 36434460f2e8SPratik Pujar 36444460f2e8SPratik Pujar static pci_ers_result_t qlcnic_io_slot_reset(struct pci_dev *pdev) 36454460f2e8SPratik Pujar { 36464460f2e8SPratik Pujar struct qlcnic_adapter *adapter = pci_get_drvdata(pdev); 36474460f2e8SPratik Pujar struct qlcnic_hardware_ops *hw_ops = adapter->ahw->hw_ops; 36484460f2e8SPratik Pujar 36494460f2e8SPratik Pujar if (hw_ops->io_slot_reset) { 36504460f2e8SPratik Pujar return hw_ops->io_slot_reset(pdev); 36514460f2e8SPratik Pujar } else { 36524460f2e8SPratik Pujar dev_err(&pdev->dev, "AER slot_reset handler not registered.\n"); 36534460f2e8SPratik Pujar return PCI_ERS_RESULT_DISCONNECT; 36544460f2e8SPratik Pujar } 36554460f2e8SPratik Pujar } 36564460f2e8SPratik Pujar 36574460f2e8SPratik Pujar static void qlcnic_io_resume(struct pci_dev *pdev) 36584460f2e8SPratik Pujar { 36594460f2e8SPratik Pujar struct qlcnic_adapter *adapter = pci_get_drvdata(pdev); 36604460f2e8SPratik Pujar struct qlcnic_hardware_ops *hw_ops = adapter->ahw->hw_ops; 36614460f2e8SPratik Pujar 36624460f2e8SPratik Pujar if (hw_ops->io_resume) 36634460f2e8SPratik Pujar hw_ops->io_resume(pdev); 36644460f2e8SPratik Pujar else 36654460f2e8SPratik Pujar dev_err(&pdev->dev, "AER resume handler not registered.\n"); 36664460f2e8SPratik Pujar } 36674460f2e8SPratik Pujar 36684460f2e8SPratik Pujar 3669aa43c215SJeff Kirsher static int 3670aa43c215SJeff Kirsher qlcnicvf_start_firmware(struct qlcnic_adapter *adapter) 3671aa43c215SJeff Kirsher { 3672aa43c215SJeff Kirsher int err; 3673aa43c215SJeff Kirsher 3674aa43c215SJeff Kirsher err = qlcnic_can_start_firmware(adapter); 3675aa43c215SJeff Kirsher if (err) 3676aa43c215SJeff Kirsher return err; 3677aa43c215SJeff Kirsher 3678aa43c215SJeff Kirsher err = qlcnic_check_npar_opertional(adapter); 3679aa43c215SJeff Kirsher if (err) 3680aa43c215SJeff Kirsher return err; 3681aa43c215SJeff Kirsher 3682aa43c215SJeff Kirsher err = qlcnic_initialize_nic(adapter); 3683aa43c215SJeff Kirsher if (err) 3684aa43c215SJeff Kirsher return err; 3685aa43c215SJeff Kirsher 3686aa43c215SJeff Kirsher qlcnic_check_options(adapter); 3687aa43c215SJeff Kirsher 3688aa43c215SJeff Kirsher err = qlcnic_set_eswitch_port_config(adapter); 3689aa43c215SJeff Kirsher if (err) 3690aa43c215SJeff Kirsher return err; 3691aa43c215SJeff Kirsher 3692aa43c215SJeff Kirsher adapter->need_fw_reset = 0; 3693aa43c215SJeff Kirsher 3694aa43c215SJeff Kirsher return err; 3695aa43c215SJeff Kirsher } 3696aa43c215SJeff Kirsher 369734e8c406SHimanshu Madhani int qlcnic_validate_rings(struct qlcnic_adapter *adapter, __u32 ring_cnt, 369834e8c406SHimanshu Madhani int queue_type) 3699aa4a1f7dSHimanshu Madhani { 3700aa4a1f7dSHimanshu Madhani struct net_device *netdev = adapter->netdev; 370134e8c406SHimanshu Madhani u8 max_hw_rings = 0; 370234e8c406SHimanshu Madhani char buf[8]; 370334e8c406SHimanshu Madhani int cur_rings; 370434e8c406SHimanshu Madhani 370534e8c406SHimanshu Madhani if (queue_type == QLCNIC_RX_QUEUE) { 370634e8c406SHimanshu Madhani max_hw_rings = adapter->max_sds_rings; 370734e8c406SHimanshu Madhani cur_rings = adapter->drv_sds_rings; 370834e8c406SHimanshu Madhani strcpy(buf, "SDS"); 370934e8c406SHimanshu Madhani } else if (queue_type == QLCNIC_TX_QUEUE) { 371034e8c406SHimanshu Madhani max_hw_rings = adapter->max_tx_rings; 371134e8c406SHimanshu Madhani cur_rings = adapter->drv_tx_rings; 371234e8c406SHimanshu Madhani strcpy(buf, "Tx"); 371334e8c406SHimanshu Madhani } 3714aa4a1f7dSHimanshu Madhani 3715aa4a1f7dSHimanshu Madhani if (!qlcnic_use_msi_x && !qlcnic_use_msi) { 371634e8c406SHimanshu Madhani netdev_err(netdev, "No RSS/TSS support in INT-x mode\n"); 3717aa4a1f7dSHimanshu Madhani return -EINVAL; 3718aa4a1f7dSHimanshu Madhani } 3719aa4a1f7dSHimanshu Madhani 372034e8c406SHimanshu Madhani if (adapter->flags & QLCNIC_MSI_ENABLED) { 372134e8c406SHimanshu Madhani netdev_err(netdev, "No RSS/TSS support in MSI mode\n"); 3722aa4a1f7dSHimanshu Madhani return -EINVAL; 3723aa4a1f7dSHimanshu Madhani } 3724aa4a1f7dSHimanshu Madhani 372534e8c406SHimanshu Madhani if (ring_cnt < 2) { 3726aa4a1f7dSHimanshu Madhani netdev_err(netdev, 372734e8c406SHimanshu Madhani "%s rings value should not be lower than 2\n", buf); 372834e8c406SHimanshu Madhani return -EINVAL; 372934e8c406SHimanshu Madhani } 373034e8c406SHimanshu Madhani 373134e8c406SHimanshu Madhani if (!is_power_of_2(ring_cnt)) { 373234e8c406SHimanshu Madhani netdev_err(netdev, "%s rings value should be a power of 2\n", 373334e8c406SHimanshu Madhani buf); 373434e8c406SHimanshu Madhani return -EINVAL; 373534e8c406SHimanshu Madhani } 373634e8c406SHimanshu Madhani 373734e8c406SHimanshu Madhani if (qlcnic_82xx_check(adapter) && (queue_type == QLCNIC_TX_QUEUE) && 373834e8c406SHimanshu Madhani !qlcnic_check_multi_tx(adapter)) { 373934e8c406SHimanshu Madhani netdev_err(netdev, "No Multi Tx queue support\n"); 374034e8c406SHimanshu Madhani return -EINVAL; 374134e8c406SHimanshu Madhani } 374234e8c406SHimanshu Madhani 374334e8c406SHimanshu Madhani if (ring_cnt > num_online_cpus()) { 3744aa4a1f7dSHimanshu Madhani netdev_err(netdev, 374534e8c406SHimanshu Madhani "%s value[%u] should not be higher than, number of online CPUs\n", 374634e8c406SHimanshu Madhani buf, num_online_cpus()); 3747aa4a1f7dSHimanshu Madhani return -EINVAL; 3748aa4a1f7dSHimanshu Madhani } 3749aa4a1f7dSHimanshu Madhani 3750aa4a1f7dSHimanshu Madhani return 0; 3751aa4a1f7dSHimanshu Madhani } 3752aa4a1f7dSHimanshu Madhani 375334e8c406SHimanshu Madhani int qlcnic_setup_rings(struct qlcnic_adapter *adapter, u8 rx_cnt, u8 tx_cnt) 3754aa43c215SJeff Kirsher { 37556389b76dSManish Chopra struct net_device *netdev = adapter->netdev; 375613159183SSony Chacko int err; 3757aa43c215SJeff Kirsher 3758319ecf12SSony Chacko if (test_bit(__QLCNIC_RESETTING, &adapter->state)) 3759319ecf12SSony Chacko return -EBUSY; 3760319ecf12SSony Chacko 3761aa43c215SJeff Kirsher netif_device_detach(netdev); 3762aa43c215SJeff Kirsher if (netif_running(netdev)) 3763aa43c215SJeff Kirsher __qlcnic_down(adapter, netdev); 376413159183SSony Chacko 3765aa43c215SJeff Kirsher qlcnic_detach(adapter); 37667dd90cf1SSucheta Chakraborty 37677ed3ce48SRajesh Borundia if (qlcnic_83xx_check(adapter)) { 37687dd90cf1SSucheta Chakraborty qlcnic_83xx_free_mbx_intr(adapter); 37697ed3ce48SRajesh Borundia qlcnic_83xx_enable_mbx_poll(adapter); 37707ed3ce48SRajesh Borundia } 37717dd90cf1SSucheta Chakraborty 3772aa43c215SJeff Kirsher qlcnic_teardown_intr(adapter); 3773aa4a1f7dSHimanshu Madhani 377434e8c406SHimanshu Madhani /* compute and set default and max tx/sds rings */ 377534e8c406SHimanshu Madhani qlcnic_set_tx_ring_count(adapter, tx_cnt); 377634e8c406SHimanshu Madhani qlcnic_set_sds_ring_count(adapter, rx_cnt); 377734e8c406SHimanshu Madhani 377834e8c406SHimanshu Madhani netif_set_real_num_tx_queues(netdev, adapter->drv_tx_rings); 377934e8c406SHimanshu Madhani 378034e8c406SHimanshu Madhani err = qlcnic_setup_intr(adapter); 37819a97e705SManish chopra if (err) { 37829a97e705SManish chopra kfree(adapter->msix_entries); 37839a97e705SManish chopra netdev_err(netdev, "failed to setup interrupt\n"); 37849a97e705SManish chopra return err; 37859a97e705SManish chopra } 3786aa43c215SJeff Kirsher 378713159183SSony Chacko if (qlcnic_83xx_check(adapter)) { 3788d5fcff04SHimanshu Madhani /* register for NIC IDC AEN Events */ 3789d5fcff04SHimanshu Madhani qlcnic_83xx_register_nic_idc_func(adapter, 1); 379013159183SSony Chacko err = qlcnic_83xx_setup_mbx_intr(adapter); 37917ed3ce48SRajesh Borundia qlcnic_83xx_disable_mbx_poll(adapter); 379213159183SSony Chacko if (err) { 379313159183SSony Chacko dev_err(&adapter->pdev->dev, 379413159183SSony Chacko "failed to setup mbx interrupt\n"); 379513159183SSony Chacko goto done; 379613159183SSony Chacko } 3797aa43c215SJeff Kirsher } 3798aa43c215SJeff Kirsher 3799aa43c215SJeff Kirsher if (netif_running(netdev)) { 3800aa43c215SJeff Kirsher err = qlcnic_attach(adapter); 3801aa43c215SJeff Kirsher if (err) 3802aa43c215SJeff Kirsher goto done; 3803aa43c215SJeff Kirsher err = __qlcnic_up(adapter, netdev); 3804aa43c215SJeff Kirsher if (err) 3805aa43c215SJeff Kirsher goto done; 3806aa43c215SJeff Kirsher qlcnic_restore_indev_addr(netdev, NETDEV_UP); 3807aa43c215SJeff Kirsher } 3808aa43c215SJeff Kirsher done: 3809aa43c215SJeff Kirsher netif_device_attach(netdev); 3810aa43c215SJeff Kirsher clear_bit(__QLCNIC_RESETTING, &adapter->state); 3811aa43c215SJeff Kirsher return err; 3812aa43c215SJeff Kirsher } 3813aa43c215SJeff Kirsher 3814aa43c215SJeff Kirsher #ifdef CONFIG_INET 3815aa43c215SJeff Kirsher 3816aa43c215SJeff Kirsher #define is_qlcnic_netdev(dev) (dev->netdev_ops == &qlcnic_netdev_ops) 3817aa43c215SJeff Kirsher 3818aa43c215SJeff Kirsher static void 3819aa43c215SJeff Kirsher qlcnic_config_indev_addr(struct qlcnic_adapter *adapter, 3820aa43c215SJeff Kirsher struct net_device *dev, unsigned long event) 3821aa43c215SJeff Kirsher { 3822aa43c215SJeff Kirsher struct in_device *indev; 3823aa43c215SJeff Kirsher 3824aa43c215SJeff Kirsher indev = in_dev_get(dev); 3825aa43c215SJeff Kirsher if (!indev) 3826aa43c215SJeff Kirsher return; 3827aa43c215SJeff Kirsher 3828aa43c215SJeff Kirsher for_ifa(indev) { 3829aa43c215SJeff Kirsher switch (event) { 3830aa43c215SJeff Kirsher case NETDEV_UP: 3831aa43c215SJeff Kirsher qlcnic_config_ipaddr(adapter, 3832aa43c215SJeff Kirsher ifa->ifa_address, QLCNIC_IP_UP); 3833aa43c215SJeff Kirsher break; 3834aa43c215SJeff Kirsher case NETDEV_DOWN: 3835aa43c215SJeff Kirsher qlcnic_config_ipaddr(adapter, 3836aa43c215SJeff Kirsher ifa->ifa_address, QLCNIC_IP_DOWN); 3837aa43c215SJeff Kirsher break; 3838aa43c215SJeff Kirsher default: 3839aa43c215SJeff Kirsher break; 3840aa43c215SJeff Kirsher } 3841aa43c215SJeff Kirsher } endfor_ifa(indev); 3842aa43c215SJeff Kirsher 3843aa43c215SJeff Kirsher in_dev_put(indev); 3844aa43c215SJeff Kirsher } 3845aa43c215SJeff Kirsher 3846319ecf12SSony Chacko void qlcnic_restore_indev_addr(struct net_device *netdev, unsigned long event) 3847aa43c215SJeff Kirsher { 3848aa43c215SJeff Kirsher struct qlcnic_adapter *adapter = netdev_priv(netdev); 3849aa43c215SJeff Kirsher struct net_device *dev; 3850aa43c215SJeff Kirsher u16 vid; 3851aa43c215SJeff Kirsher 3852aa43c215SJeff Kirsher qlcnic_config_indev_addr(adapter, netdev, event); 3853aa43c215SJeff Kirsher 385443c00a75SJiri Pirko rcu_read_lock(); 3855aa43c215SJeff Kirsher for_each_set_bit(vid, adapter->vlans, VLAN_N_VID) { 38561fd9b1fcSPatrick McHardy dev = __vlan_find_dev_deep(netdev, htons(ETH_P_8021Q), vid); 3857aa43c215SJeff Kirsher if (!dev) 3858aa43c215SJeff Kirsher continue; 3859aa43c215SJeff Kirsher qlcnic_config_indev_addr(adapter, dev, event); 3860aa43c215SJeff Kirsher } 386143c00a75SJiri Pirko rcu_read_unlock(); 3862aa43c215SJeff Kirsher } 3863aa43c215SJeff Kirsher 3864aa43c215SJeff Kirsher static int qlcnic_netdev_event(struct notifier_block *this, 3865aa43c215SJeff Kirsher unsigned long event, void *ptr) 3866aa43c215SJeff Kirsher { 3867aa43c215SJeff Kirsher struct qlcnic_adapter *adapter; 3868351638e7SJiri Pirko struct net_device *dev = netdev_notifier_info_to_dev(ptr); 3869aa43c215SJeff Kirsher 3870aa43c215SJeff Kirsher recheck: 3871aa43c215SJeff Kirsher if (dev == NULL) 3872aa43c215SJeff Kirsher goto done; 3873aa43c215SJeff Kirsher 3874aa43c215SJeff Kirsher if (dev->priv_flags & IFF_802_1Q_VLAN) { 3875aa43c215SJeff Kirsher dev = vlan_dev_real_dev(dev); 3876aa43c215SJeff Kirsher goto recheck; 3877aa43c215SJeff Kirsher } 3878aa43c215SJeff Kirsher 3879aa43c215SJeff Kirsher if (!is_qlcnic_netdev(dev)) 3880aa43c215SJeff Kirsher goto done; 3881aa43c215SJeff Kirsher 3882aa43c215SJeff Kirsher adapter = netdev_priv(dev); 3883aa43c215SJeff Kirsher 3884aa43c215SJeff Kirsher if (!adapter) 3885aa43c215SJeff Kirsher goto done; 3886aa43c215SJeff Kirsher 3887aa43c215SJeff Kirsher if (!test_bit(__QLCNIC_DEV_UP, &adapter->state)) 3888aa43c215SJeff Kirsher goto done; 3889aa43c215SJeff Kirsher 3890aa43c215SJeff Kirsher qlcnic_config_indev_addr(adapter, dev, event); 3891aa43c215SJeff Kirsher done: 3892aa43c215SJeff Kirsher return NOTIFY_DONE; 3893aa43c215SJeff Kirsher } 3894aa43c215SJeff Kirsher 3895aa43c215SJeff Kirsher static int 3896aa43c215SJeff Kirsher qlcnic_inetaddr_event(struct notifier_block *this, 3897aa43c215SJeff Kirsher unsigned long event, void *ptr) 3898aa43c215SJeff Kirsher { 3899aa43c215SJeff Kirsher struct qlcnic_adapter *adapter; 3900aa43c215SJeff Kirsher struct net_device *dev; 3901aa43c215SJeff Kirsher 3902aa43c215SJeff Kirsher struct in_ifaddr *ifa = (struct in_ifaddr *)ptr; 3903aa43c215SJeff Kirsher 3904aa43c215SJeff Kirsher dev = ifa->ifa_dev ? ifa->ifa_dev->dev : NULL; 3905aa43c215SJeff Kirsher 3906aa43c215SJeff Kirsher recheck: 3907aa43c215SJeff Kirsher if (dev == NULL) 3908aa43c215SJeff Kirsher goto done; 3909aa43c215SJeff Kirsher 3910aa43c215SJeff Kirsher if (dev->priv_flags & IFF_802_1Q_VLAN) { 3911aa43c215SJeff Kirsher dev = vlan_dev_real_dev(dev); 3912aa43c215SJeff Kirsher goto recheck; 3913aa43c215SJeff Kirsher } 3914aa43c215SJeff Kirsher 3915aa43c215SJeff Kirsher if (!is_qlcnic_netdev(dev)) 3916aa43c215SJeff Kirsher goto done; 3917aa43c215SJeff Kirsher 3918aa43c215SJeff Kirsher adapter = netdev_priv(dev); 3919aa43c215SJeff Kirsher 3920aa43c215SJeff Kirsher if (!adapter) 3921aa43c215SJeff Kirsher goto done; 3922aa43c215SJeff Kirsher 3923aa43c215SJeff Kirsher if (!test_bit(__QLCNIC_DEV_UP, &adapter->state)) 3924aa43c215SJeff Kirsher goto done; 3925aa43c215SJeff Kirsher 3926aa43c215SJeff Kirsher switch (event) { 3927aa43c215SJeff Kirsher case NETDEV_UP: 3928aa43c215SJeff Kirsher qlcnic_config_ipaddr(adapter, ifa->ifa_address, QLCNIC_IP_UP); 392913159183SSony Chacko 3930aa43c215SJeff Kirsher break; 3931aa43c215SJeff Kirsher case NETDEV_DOWN: 3932aa43c215SJeff Kirsher qlcnic_config_ipaddr(adapter, ifa->ifa_address, QLCNIC_IP_DOWN); 393313159183SSony Chacko 3934aa43c215SJeff Kirsher break; 3935aa43c215SJeff Kirsher default: 3936aa43c215SJeff Kirsher break; 3937aa43c215SJeff Kirsher } 3938aa43c215SJeff Kirsher 3939aa43c215SJeff Kirsher done: 3940aa43c215SJeff Kirsher return NOTIFY_DONE; 3941aa43c215SJeff Kirsher } 3942aa43c215SJeff Kirsher 3943aa43c215SJeff Kirsher static struct notifier_block qlcnic_netdev_cb = { 3944aa43c215SJeff Kirsher .notifier_call = qlcnic_netdev_event, 3945aa43c215SJeff Kirsher }; 3946aa43c215SJeff Kirsher 3947aa43c215SJeff Kirsher static struct notifier_block qlcnic_inetaddr_cb = { 3948aa43c215SJeff Kirsher .notifier_call = qlcnic_inetaddr_event, 3949aa43c215SJeff Kirsher }; 3950aa43c215SJeff Kirsher #else 3951f8ca2b6fSSony Chacko void qlcnic_restore_indev_addr(struct net_device *dev, unsigned long event) 3952aa43c215SJeff Kirsher { } 3953aa43c215SJeff Kirsher #endif 3954fec9dd15SStephen Hemminger static const struct pci_error_handlers qlcnic_err_handler = { 3955aa43c215SJeff Kirsher .error_detected = qlcnic_io_error_detected, 3956aa43c215SJeff Kirsher .slot_reset = qlcnic_io_slot_reset, 3957aa43c215SJeff Kirsher .resume = qlcnic_io_resume, 3958aa43c215SJeff Kirsher }; 3959aa43c215SJeff Kirsher 3960aa43c215SJeff Kirsher static struct pci_driver qlcnic_driver = { 3961aa43c215SJeff Kirsher .name = qlcnic_driver_name, 3962aa43c215SJeff Kirsher .id_table = qlcnic_pci_tbl, 3963aa43c215SJeff Kirsher .probe = qlcnic_probe, 39646bb58bb0SBill Pemberton .remove = qlcnic_remove, 3965aa43c215SJeff Kirsher #ifdef CONFIG_PM 3966aa43c215SJeff Kirsher .suspend = qlcnic_suspend, 3967aa43c215SJeff Kirsher .resume = qlcnic_resume, 3968aa43c215SJeff Kirsher #endif 3969aa43c215SJeff Kirsher .shutdown = qlcnic_shutdown, 397002feda17SRajesh Borundia .err_handler = &qlcnic_err_handler, 397102feda17SRajesh Borundia #ifdef CONFIG_QLCNIC_SRIOV 397202feda17SRajesh Borundia .sriov_configure = qlcnic_pci_sriov_configure, 397302feda17SRajesh Borundia #endif 3974aa43c215SJeff Kirsher 3975aa43c215SJeff Kirsher }; 3976aa43c215SJeff Kirsher 3977aa43c215SJeff Kirsher static int __init qlcnic_init_module(void) 3978aa43c215SJeff Kirsher { 3979aa43c215SJeff Kirsher int ret; 3980aa43c215SJeff Kirsher 3981aa43c215SJeff Kirsher printk(KERN_INFO "%s\n", qlcnic_driver_string); 3982aa43c215SJeff Kirsher 3983aa43c215SJeff Kirsher #ifdef CONFIG_INET 3984aa43c215SJeff Kirsher register_netdevice_notifier(&qlcnic_netdev_cb); 3985aa43c215SJeff Kirsher register_inetaddr_notifier(&qlcnic_inetaddr_cb); 3986aa43c215SJeff Kirsher #endif 3987aa43c215SJeff Kirsher 3988aa43c215SJeff Kirsher ret = pci_register_driver(&qlcnic_driver); 3989aa43c215SJeff Kirsher if (ret) { 3990aa43c215SJeff Kirsher #ifdef CONFIG_INET 3991aa43c215SJeff Kirsher unregister_inetaddr_notifier(&qlcnic_inetaddr_cb); 3992aa43c215SJeff Kirsher unregister_netdevice_notifier(&qlcnic_netdev_cb); 3993aa43c215SJeff Kirsher #endif 3994aa43c215SJeff Kirsher } 3995aa43c215SJeff Kirsher 3996aa43c215SJeff Kirsher return ret; 3997aa43c215SJeff Kirsher } 3998aa43c215SJeff Kirsher 3999aa43c215SJeff Kirsher module_init(qlcnic_init_module); 4000aa43c215SJeff Kirsher 4001aa43c215SJeff Kirsher static void __exit qlcnic_exit_module(void) 4002aa43c215SJeff Kirsher { 4003aa43c215SJeff Kirsher pci_unregister_driver(&qlcnic_driver); 4004aa43c215SJeff Kirsher 4005aa43c215SJeff Kirsher #ifdef CONFIG_INET 4006aa43c215SJeff Kirsher unregister_inetaddr_notifier(&qlcnic_inetaddr_cb); 4007aa43c215SJeff Kirsher unregister_netdevice_notifier(&qlcnic_netdev_cb); 4008aa43c215SJeff Kirsher #endif 4009aa43c215SJeff Kirsher } 4010aa43c215SJeff Kirsher 4011aa43c215SJeff Kirsher module_exit(qlcnic_exit_module); 4012