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) && 64980c0e4f3SHimanshu Madhani !adapter->ahw->diag_test) 65034e8c406SHimanshu Madhani drv_sds_rings = num_msix - drv_tx_rings; 651012ec812SHimanshu Madhani else 65234e8c406SHimanshu Madhani drv_sds_rings = num_msix; 653012ec812SHimanshu Madhani 65434e8c406SHimanshu Madhani adapter->drv_sds_rings = drv_sds_rings; 65513159183SSony Chacko } 656aa43c215SJeff Kirsher dev_info(&pdev->dev, "using msi-x interrupts\n"); 657aa43c215SJeff Kirsher return err; 65813159183SSony Chacko } else if (err > 0) { 65913159183SSony Chacko dev_info(&pdev->dev, 66013159183SSony Chacko "Unable to allocate %d MSI-X interrupt vectors\n", 66113159183SSony Chacko num_msix); 66213159183SSony Chacko if (qlcnic_83xx_check(adapter)) { 663da6c8063SRajesh Borundia if (err < (QLC_83XX_MINIMUM_VECTOR - tx_vector)) 66413159183SSony Chacko return err; 66534e8c406SHimanshu Madhani err -= drv_tx_rings + 1; 666aa43c215SJeff Kirsher num_msix = rounddown_pow_of_two(err); 66734e8c406SHimanshu Madhani num_msix += drv_tx_rings + 1; 66813159183SSony Chacko } else { 66913159183SSony Chacko num_msix = rounddown_pow_of_two(err); 670012ec812SHimanshu Madhani if (qlcnic_check_multi_tx(adapter)) 67134e8c406SHimanshu Madhani num_msix += drv_tx_rings; 67213159183SSony Chacko } 67313159183SSony Chacko 67413159183SSony Chacko if (num_msix) { 67513159183SSony Chacko dev_info(&pdev->dev, 676dce056cbSManish Chopra "Trying to allocate %d MSI-X interrupt vectors\n", 67713159183SSony Chacko num_msix); 678aa43c215SJeff Kirsher goto enable_msix; 679aa43c215SJeff Kirsher } 68013159183SSony Chacko } else { 681dce056cbSManish Chopra dev_info(&pdev->dev, 682dce056cbSManish Chopra "Unable to allocate %d MSI-X interrupt vectors\n", 68313159183SSony Chacko num_msix); 684aa43c215SJeff Kirsher } 68513159183SSony Chacko } 68613159183SSony Chacko 687aa43c215SJeff Kirsher return err; 688aa43c215SJeff Kirsher } 689aa43c215SJeff Kirsher 6909a97e705SManish chopra static int qlcnic_enable_msi_legacy(struct qlcnic_adapter *adapter) 691aa43c215SJeff Kirsher { 6929a97e705SManish chopra int err = 0; 69315087c2bSSony Chacko u32 offset, mask_reg; 694aa43c215SJeff Kirsher const struct qlcnic_legacy_intr_set *legacy_intrp; 69515087c2bSSony Chacko struct qlcnic_hardware_context *ahw = adapter->ahw; 696aa43c215SJeff Kirsher struct pci_dev *pdev = adapter->pdev; 697aa43c215SJeff Kirsher 698099f7aa7SSony Chacko if (qlcnic_use_msi && !pci_enable_msi(pdev)) { 699aa43c215SJeff Kirsher adapter->flags |= QLCNIC_MSI_ENABLED; 70015087c2bSSony Chacko offset = msi_tgt_status[adapter->ahw->pci_func]; 70115087c2bSSony Chacko adapter->tgt_status_reg = qlcnic_get_ioaddr(adapter->ahw, 70215087c2bSSony Chacko offset); 703aa43c215SJeff Kirsher dev_info(&pdev->dev, "using msi interrupts\n"); 704aa43c215SJeff Kirsher adapter->msix_entries[0].vector = pdev->irq; 7059a97e705SManish chopra return err; 706aa43c215SJeff Kirsher } 707012ec812SHimanshu Madhani 7089a97e705SManish chopra if (qlcnic_use_msi || qlcnic_use_msi_x) 7099a97e705SManish chopra return -EOPNOTSUPP; 710aa43c215SJeff Kirsher 711aa43c215SJeff Kirsher legacy_intrp = &legacy_intr[adapter->ahw->pci_func]; 71279788450SSony Chacko adapter->ahw->int_vec_bit = legacy_intrp->int_vec_bit; 71315087c2bSSony Chacko offset = legacy_intrp->tgt_status_reg; 71415087c2bSSony Chacko adapter->tgt_status_reg = qlcnic_get_ioaddr(ahw, offset); 71515087c2bSSony Chacko mask_reg = legacy_intrp->tgt_mask_reg; 71615087c2bSSony Chacko adapter->tgt_mask_reg = qlcnic_get_ioaddr(ahw, mask_reg); 71715087c2bSSony Chacko adapter->isr_int_vec = qlcnic_get_ioaddr(ahw, ISR_INT_VECTOR); 71815087c2bSSony Chacko adapter->crb_int_state_reg = qlcnic_get_ioaddr(ahw, ISR_INT_STATE_REG); 719aa43c215SJeff Kirsher dev_info(&pdev->dev, "using legacy interrupts\n"); 720aa43c215SJeff Kirsher adapter->msix_entries[0].vector = pdev->irq; 7219a97e705SManish chopra return err; 722aa43c215SJeff Kirsher } 723aa43c215SJeff Kirsher 72434e8c406SHimanshu Madhani int qlcnic_82xx_setup_intr(struct qlcnic_adapter *adapter) 725aa43c215SJeff Kirsher { 7269a97e705SManish chopra int num_msix, err = 0; 727aa43c215SJeff Kirsher 72834e8c406SHimanshu Madhani num_msix = adapter->drv_sds_rings; 7297e2cf4feSSony Chacko 73034e8c406SHimanshu Madhani if (qlcnic_check_multi_tx(adapter)) 73134e8c406SHimanshu Madhani num_msix += adapter->drv_tx_rings; 732aa43c215SJeff Kirsher 7337e2cf4feSSony Chacko err = qlcnic_enable_msix(adapter, num_msix); 734012ec812SHimanshu Madhani if (err == -ENOMEM) 7357e2cf4feSSony Chacko return err; 736aa43c215SJeff Kirsher 737012ec812SHimanshu Madhani if (!(adapter->flags & QLCNIC_MSIX_ENABLED)) { 738012ec812SHimanshu Madhani qlcnic_disable_multi_tx(adapter); 739012ec812SHimanshu Madhani 7409a97e705SManish chopra err = qlcnic_enable_msi_legacy(adapter); 7419a97e705SManish chopra if (!err) 7429a97e705SManish chopra return err; 743012ec812SHimanshu Madhani } 7449a97e705SManish chopra 745012ec812SHimanshu Madhani return 0; 746012ec812SHimanshu Madhani } 747012ec812SHimanshu Madhani 748012ec812SHimanshu Madhani int qlcnic_82xx_mq_intrpt(struct qlcnic_adapter *adapter, int op_type) 749012ec812SHimanshu Madhani { 750012ec812SHimanshu Madhani struct qlcnic_hardware_context *ahw = adapter->ahw; 751012ec812SHimanshu Madhani int err, i; 752012ec812SHimanshu Madhani 753012ec812SHimanshu Madhani if (qlcnic_check_multi_tx(adapter) && 754c2c5e3a0SHimanshu Madhani !ahw->diag_test && 755012ec812SHimanshu Madhani (adapter->flags & QLCNIC_MSIX_ENABLED)) { 756012ec812SHimanshu Madhani ahw->intr_tbl = vzalloc(ahw->num_msix * 757012ec812SHimanshu Madhani sizeof(struct qlcnic_intrpt_config)); 758012ec812SHimanshu Madhani if (!ahw->intr_tbl) 759012ec812SHimanshu Madhani return -ENOMEM; 760012ec812SHimanshu Madhani 761012ec812SHimanshu Madhani for (i = 0; i < ahw->num_msix; i++) { 762012ec812SHimanshu Madhani ahw->intr_tbl[i].type = QLCNIC_INTRPT_MSIX; 763012ec812SHimanshu Madhani ahw->intr_tbl[i].id = i; 764012ec812SHimanshu Madhani ahw->intr_tbl[i].src = 0; 765012ec812SHimanshu Madhani } 766012ec812SHimanshu Madhani 767012ec812SHimanshu Madhani err = qlcnic_82xx_config_intrpt(adapter, 1); 768012ec812SHimanshu Madhani if (err) 769012ec812SHimanshu Madhani dev_err(&adapter->pdev->dev, 770012ec812SHimanshu Madhani "Failed to configure Interrupt for %d vector\n", 771012ec812SHimanshu Madhani ahw->num_msix); 772012ec812SHimanshu Madhani return err; 773012ec812SHimanshu Madhani } 774012ec812SHimanshu Madhani 775012ec812SHimanshu Madhani return 0; 776aa43c215SJeff Kirsher } 77713159183SSony Chacko 778319ecf12SSony Chacko void qlcnic_teardown_intr(struct qlcnic_adapter *adapter) 779aa43c215SJeff Kirsher { 780aa43c215SJeff Kirsher if (adapter->flags & QLCNIC_MSIX_ENABLED) 781aa43c215SJeff Kirsher pci_disable_msix(adapter->pdev); 782aa43c215SJeff Kirsher if (adapter->flags & QLCNIC_MSI_ENABLED) 783aa43c215SJeff Kirsher pci_disable_msi(adapter->pdev); 78413159183SSony Chacko 78513159183SSony Chacko kfree(adapter->msix_entries); 78613159183SSony Chacko adapter->msix_entries = NULL; 78713159183SSony Chacko 78813159183SSony Chacko if (adapter->ahw->intr_tbl) { 78913159183SSony Chacko vfree(adapter->ahw->intr_tbl); 79013159183SSony Chacko adapter->ahw->intr_tbl = NULL; 79113159183SSony Chacko } 792aa43c215SJeff Kirsher } 793aa43c215SJeff Kirsher 794f1a094a8SRajesh Borundia static void qlcnic_cleanup_pci_map(struct qlcnic_hardware_context *ahw) 795aa43c215SJeff Kirsher { 796f1a094a8SRajesh Borundia if (ahw->pci_base0 != NULL) 797f1a094a8SRajesh Borundia iounmap(ahw->pci_base0); 798aa43c215SJeff Kirsher } 799aa43c215SJeff Kirsher 8007e2cf4feSSony Chacko static int qlcnic_get_act_pci_func(struct qlcnic_adapter *adapter) 8017e2cf4feSSony Chacko { 8027e2cf4feSSony Chacko struct qlcnic_pci_info *pci_info; 8037e2cf4feSSony Chacko int ret; 8047e2cf4feSSony Chacko 8057e2cf4feSSony Chacko if (!(adapter->flags & QLCNIC_ESWITCH_ENABLED)) { 8067e2cf4feSSony Chacko switch (adapter->ahw->port_type) { 8077e2cf4feSSony Chacko case QLCNIC_GBE: 8087e2cf4feSSony Chacko adapter->ahw->act_pci_func = QLCNIC_NIU_MAX_GBE_PORTS; 8097e2cf4feSSony Chacko break; 8107e2cf4feSSony Chacko case QLCNIC_XGBE: 8117e2cf4feSSony Chacko adapter->ahw->act_pci_func = QLCNIC_NIU_MAX_XG_PORTS; 8127e2cf4feSSony Chacko break; 8137e2cf4feSSony Chacko } 8147e2cf4feSSony Chacko return 0; 8157e2cf4feSSony Chacko } 8167e2cf4feSSony Chacko 8177e2cf4feSSony Chacko if (adapter->ahw->op_mode == QLCNIC_MGMT_FUNC) 8187e2cf4feSSony Chacko return 0; 8197e2cf4feSSony Chacko 8207e2cf4feSSony Chacko pci_info = kcalloc(QLCNIC_MAX_PCI_FUNC, sizeof(*pci_info), GFP_KERNEL); 8217e2cf4feSSony Chacko if (!pci_info) 8227e2cf4feSSony Chacko return -ENOMEM; 8237e2cf4feSSony Chacko 8247e2cf4feSSony Chacko ret = qlcnic_get_pci_info(adapter, pci_info); 8257e2cf4feSSony Chacko kfree(pci_info); 8267e2cf4feSSony Chacko return ret; 8277e2cf4feSSony Chacko } 828d71170fbSSony Chacko 82935dafcb0SSony Chacko static bool qlcnic_port_eswitch_cfg_capability(struct qlcnic_adapter *adapter) 83035dafcb0SSony Chacko { 83135dafcb0SSony Chacko bool ret = false; 83235dafcb0SSony Chacko 83335dafcb0SSony Chacko if (qlcnic_84xx_check(adapter)) { 83435dafcb0SSony Chacko ret = true; 83535dafcb0SSony Chacko } else if (qlcnic_83xx_check(adapter)) { 83635dafcb0SSony Chacko if (adapter->ahw->extra_capability[0] & 83735dafcb0SSony Chacko QLCNIC_FW_CAPABILITY_2_PER_PORT_ESWITCH_CFG) 83835dafcb0SSony Chacko ret = true; 83935dafcb0SSony Chacko else 84035dafcb0SSony Chacko ret = false; 84135dafcb0SSony Chacko } 84235dafcb0SSony Chacko 84335dafcb0SSony Chacko return ret; 84435dafcb0SSony Chacko } 84535dafcb0SSony Chacko 846d71170fbSSony Chacko int qlcnic_init_pci_info(struct qlcnic_adapter *adapter) 847aa43c215SJeff Kirsher { 848aa43c215SJeff Kirsher struct qlcnic_pci_info *pci_info; 8494c776aadSSony Chacko int i, id = 0, ret = 0, j = 0; 850bff57d8eSSony Chacko u16 act_pci_func; 851aa43c215SJeff Kirsher u8 pfn; 852aa43c215SJeff Kirsher 853aa43c215SJeff Kirsher pci_info = kcalloc(QLCNIC_MAX_PCI_FUNC, sizeof(*pci_info), GFP_KERNEL); 854aa43c215SJeff Kirsher if (!pci_info) 855aa43c215SJeff Kirsher return -ENOMEM; 856aa43c215SJeff Kirsher 857bff57d8eSSony Chacko ret = qlcnic_get_pci_info(adapter, pci_info); 858bff57d8eSSony Chacko if (ret) 859bff57d8eSSony Chacko goto err_pci_info; 860bff57d8eSSony Chacko 861bff57d8eSSony Chacko act_pci_func = adapter->ahw->act_pci_func; 862bff57d8eSSony Chacko 863aa43c215SJeff Kirsher adapter->npars = kzalloc(sizeof(struct qlcnic_npar_info) * 864bff57d8eSSony Chacko act_pci_func, GFP_KERNEL); 865aa43c215SJeff Kirsher if (!adapter->npars) { 866aa43c215SJeff Kirsher ret = -ENOMEM; 867aa43c215SJeff Kirsher goto err_pci_info; 868aa43c215SJeff Kirsher } 869aa43c215SJeff Kirsher 870aa43c215SJeff Kirsher adapter->eswitch = kzalloc(sizeof(struct qlcnic_eswitch) * 871aa43c215SJeff Kirsher QLCNIC_NIU_MAX_XG_PORTS, GFP_KERNEL); 872aa43c215SJeff Kirsher if (!adapter->eswitch) { 873aa43c215SJeff Kirsher ret = -ENOMEM; 874aa43c215SJeff Kirsher goto err_npars; 875aa43c215SJeff Kirsher } 876aa43c215SJeff Kirsher 877aa43c215SJeff Kirsher for (i = 0; i < QLCNIC_MAX_PCI_FUNC; i++) { 878aa43c215SJeff Kirsher pfn = pci_info[i].id; 879bff57d8eSSony Chacko 8800f6efff9SDan Carpenter if (pfn >= QLCNIC_MAX_PCI_FUNC) { 881aa43c215SJeff Kirsher ret = QL_STATUS_INVALID_PARAM; 882aa43c215SJeff Kirsher goto err_eswitch; 883aa43c215SJeff Kirsher } 884bff57d8eSSony Chacko 885bff57d8eSSony Chacko if (!pci_info[i].active || 886bff57d8eSSony Chacko (pci_info[i].type != QLCNIC_TYPE_NIC)) 887bff57d8eSSony Chacko continue; 888bff57d8eSSony Chacko 88935dafcb0SSony Chacko if (qlcnic_port_eswitch_cfg_capability(adapter)) { 8904c776aadSSony Chacko if (!qlcnic_83xx_set_port_eswitch_status(adapter, pfn, 8914c776aadSSony Chacko &id)) 89235dafcb0SSony Chacko adapter->npars[j].eswitch_status = true; 89335dafcb0SSony Chacko else 89435dafcb0SSony Chacko continue; 89535dafcb0SSony Chacko } else { 89635dafcb0SSony Chacko adapter->npars[j].eswitch_status = true; 89735dafcb0SSony Chacko } 89835dafcb0SSony Chacko 899bff57d8eSSony Chacko adapter->npars[j].pci_func = pfn; 900bff57d8eSSony Chacko adapter->npars[j].active = (u8)pci_info[i].active; 901bff57d8eSSony Chacko adapter->npars[j].type = (u8)pci_info[i].type; 902bff57d8eSSony Chacko adapter->npars[j].phy_port = (u8)pci_info[i].default_port; 903bff57d8eSSony Chacko adapter->npars[j].min_bw = pci_info[i].tx_min_bw; 904bff57d8eSSony Chacko adapter->npars[j].max_bw = pci_info[i].tx_max_bw; 90535dafcb0SSony Chacko 9069e630955SSucheta Chakraborty memcpy(&adapter->npars[j].mac, &pci_info[i].mac, ETH_ALEN); 907bff57d8eSSony Chacko j++; 908aa43c215SJeff Kirsher } 909aa43c215SJeff Kirsher 9104c776aadSSony Chacko /* Update eSwitch status for adapters without per port eSwitch 9114c776aadSSony Chacko * configuration capability 9124c776aadSSony Chacko */ 9134c776aadSSony Chacko if (!qlcnic_port_eswitch_cfg_capability(adapter)) { 91435dafcb0SSony Chacko for (i = 0; i < QLCNIC_NIU_MAX_XG_PORTS; i++) 915aa43c215SJeff Kirsher adapter->eswitch[i].flags |= QLCNIC_SWITCH_ENABLE; 91613159183SSony Chacko } 917aa43c215SJeff Kirsher 918aa43c215SJeff Kirsher kfree(pci_info); 919aa43c215SJeff Kirsher return 0; 920aa43c215SJeff Kirsher 921aa43c215SJeff Kirsher err_eswitch: 922aa43c215SJeff Kirsher kfree(adapter->eswitch); 923aa43c215SJeff Kirsher adapter->eswitch = NULL; 924aa43c215SJeff Kirsher err_npars: 925aa43c215SJeff Kirsher kfree(adapter->npars); 926aa43c215SJeff Kirsher adapter->npars = NULL; 927aa43c215SJeff Kirsher err_pci_info: 928aa43c215SJeff Kirsher kfree(pci_info); 929aa43c215SJeff Kirsher 930aa43c215SJeff Kirsher return ret; 931aa43c215SJeff Kirsher } 932aa43c215SJeff Kirsher 933aa43c215SJeff Kirsher static int 934aa43c215SJeff Kirsher qlcnic_set_function_modes(struct qlcnic_adapter *adapter) 935aa43c215SJeff Kirsher { 936aa43c215SJeff Kirsher u8 id; 9377e8fd003SShahed Shaikh int ret; 938aa43c215SJeff Kirsher u32 data = QLCNIC_MGMT_FUNC; 939bff57d8eSSony Chacko struct qlcnic_hardware_context *ahw = adapter->ahw; 940aa43c215SJeff Kirsher 941aa43c215SJeff Kirsher ret = qlcnic_api_lock(adapter); 942aa43c215SJeff Kirsher if (ret) 943aa43c215SJeff Kirsher goto err_lock; 944aa43c215SJeff Kirsher 9457e8fd003SShahed Shaikh id = ahw->pci_func; 946a15ebd37SHimanshu Madhani data = QLC_SHARED_REG_RD32(adapter, QLCNIC_DRV_OP_MODE); 9477e8fd003SShahed Shaikh data = (data & ~QLC_DEV_SET_DRV(0xf, id)) | 9487e8fd003SShahed Shaikh QLC_DEV_SET_DRV(QLCNIC_MGMT_FUNC, id); 949a15ebd37SHimanshu Madhani QLC_SHARED_REG_WR32(adapter, QLCNIC_DRV_OP_MODE, data); 950aa43c215SJeff Kirsher qlcnic_api_unlock(adapter); 951aa43c215SJeff Kirsher err_lock: 952aa43c215SJeff Kirsher return ret; 953aa43c215SJeff Kirsher } 954aa43c215SJeff Kirsher 95513159183SSony Chacko static void qlcnic_check_vf(struct qlcnic_adapter *adapter, 95613159183SSony Chacko const struct pci_device_id *ent) 957aa43c215SJeff Kirsher { 958aa43c215SJeff Kirsher u32 op_mode, priv_level; 959aa43c215SJeff Kirsher 960aa43c215SJeff Kirsher /* Determine FW API version */ 96113159183SSony Chacko adapter->ahw->fw_hal_version = QLC_SHARED_REG_RD32(adapter, 962aa43c215SJeff Kirsher QLCNIC_FW_API); 963aa43c215SJeff Kirsher 964aa43c215SJeff Kirsher /* Find PCI function number */ 96513159183SSony Chacko qlcnic_get_func_no(adapter); 966aa43c215SJeff Kirsher 967aa43c215SJeff Kirsher /* Determine function privilege level */ 96813159183SSony Chacko op_mode = QLC_SHARED_REG_RD32(adapter, QLCNIC_DRV_OP_MODE); 969aa43c215SJeff Kirsher if (op_mode == QLC_DEV_DRV_DEFAULT) 970aa43c215SJeff Kirsher priv_level = QLCNIC_MGMT_FUNC; 971aa43c215SJeff Kirsher else 972aa43c215SJeff Kirsher priv_level = QLC_DEV_GET_DRV(op_mode, adapter->ahw->pci_func); 973aa43c215SJeff Kirsher 974aa43c215SJeff Kirsher if (priv_level == QLCNIC_NON_PRIV_FUNC) { 97579788450SSony Chacko adapter->ahw->op_mode = QLCNIC_NON_PRIV_FUNC; 976aa43c215SJeff Kirsher dev_info(&adapter->pdev->dev, 977aa43c215SJeff Kirsher "HAL Version: %d Non Privileged function\n", 97879788450SSony Chacko adapter->ahw->fw_hal_version); 979aa43c215SJeff Kirsher adapter->nic_ops = &qlcnic_vf_ops; 980aa43c215SJeff Kirsher } else 981aa43c215SJeff Kirsher adapter->nic_ops = &qlcnic_ops; 982aa43c215SJeff Kirsher } 983aa43c215SJeff Kirsher 98415087c2bSSony Chacko #define QLCNIC_82XX_BAR0_LENGTH 0x00200000UL 98513159183SSony Chacko #define QLCNIC_83XX_BAR0_LENGTH 0x4000 98615087c2bSSony Chacko static void qlcnic_get_bar_length(u32 dev_id, ulong *bar) 987aa43c215SJeff Kirsher { 98815087c2bSSony Chacko switch (dev_id) { 98915087c2bSSony Chacko case PCI_DEVICE_ID_QLOGIC_QLE824X: 99015087c2bSSony Chacko *bar = QLCNIC_82XX_BAR0_LENGTH; 99115087c2bSSony Chacko break; 99213159183SSony Chacko case PCI_DEVICE_ID_QLOGIC_QLE834X: 99315ca140fSManish Chopra case PCI_DEVICE_ID_QLOGIC_QLE844X: 994f8468331SRajesh Borundia case PCI_DEVICE_ID_QLOGIC_VF_QLE834X: 99515ca140fSManish Chopra case PCI_DEVICE_ID_QLOGIC_VF_QLE844X: 99613159183SSony Chacko *bar = QLCNIC_83XX_BAR0_LENGTH; 99713159183SSony Chacko break; 99815087c2bSSony Chacko default: 99915087c2bSSony Chacko *bar = 0; 100015087c2bSSony Chacko } 100115087c2bSSony Chacko } 100215087c2bSSony Chacko 100315087c2bSSony Chacko static int qlcnic_setup_pci_map(struct pci_dev *pdev, 100415087c2bSSony Chacko struct qlcnic_hardware_context *ahw) 100515087c2bSSony Chacko { 100615087c2bSSony Chacko u32 offset; 1007aa43c215SJeff Kirsher void __iomem *mem_ptr0 = NULL; 100815087c2bSSony Chacko unsigned long mem_len, pci_len0 = 0, bar0_len; 1009aa43c215SJeff Kirsher 1010aa43c215SJeff Kirsher /* remap phys address */ 1011aa43c215SJeff Kirsher mem_len = pci_resource_len(pdev, 0); 1012aa43c215SJeff Kirsher 101315087c2bSSony Chacko qlcnic_get_bar_length(pdev->device, &bar0_len); 101415087c2bSSony Chacko if (mem_len >= bar0_len) { 1015aa43c215SJeff Kirsher 1016aa43c215SJeff Kirsher mem_ptr0 = pci_ioremap_bar(pdev, 0); 1017aa43c215SJeff Kirsher if (mem_ptr0 == NULL) { 1018aa43c215SJeff Kirsher dev_err(&pdev->dev, "failed to map PCI bar 0\n"); 1019aa43c215SJeff Kirsher return -EIO; 1020aa43c215SJeff Kirsher } 1021aa43c215SJeff Kirsher pci_len0 = mem_len; 1022aa43c215SJeff Kirsher } else { 1023aa43c215SJeff Kirsher return -EIO; 1024aa43c215SJeff Kirsher } 1025aa43c215SJeff Kirsher 1026f8468331SRajesh Borundia dev_info(&pdev->dev, "%dKB memory map\n", (int)(mem_len >> 10)); 10277e2cf4feSSony Chacko 102815087c2bSSony Chacko ahw->pci_base0 = mem_ptr0; 102915087c2bSSony Chacko ahw->pci_len0 = pci_len0; 103015087c2bSSony Chacko offset = QLCNIC_PCIX_PS_REG(PCIX_OCM_WINDOW_REG(ahw->pci_func)); 103115087c2bSSony Chacko qlcnic_get_ioaddr(ahw, offset); 1032aa43c215SJeff Kirsher 1033aa43c215SJeff Kirsher return 0; 1034aa43c215SJeff Kirsher } 1035aa43c215SJeff Kirsher 103660dcbcb0SManish Chopra static bool qlcnic_validate_subsystem_id(struct qlcnic_adapter *adapter, 10372343f06aSManish Chopra int index) 10382343f06aSManish Chopra { 10392343f06aSManish Chopra struct pci_dev *pdev = adapter->pdev; 10402343f06aSManish Chopra unsigned short subsystem_vendor; 10412343f06aSManish Chopra bool ret = true; 10422343f06aSManish Chopra 10432343f06aSManish Chopra subsystem_vendor = pdev->subsystem_vendor; 10442343f06aSManish Chopra 10452343f06aSManish Chopra if (pdev->device == PCI_DEVICE_ID_QLOGIC_QLE824X || 10462343f06aSManish Chopra pdev->device == PCI_DEVICE_ID_QLOGIC_QLE834X) { 10472343f06aSManish Chopra if (qlcnic_boards[index].sub_vendor == subsystem_vendor && 10482343f06aSManish Chopra qlcnic_boards[index].sub_device == pdev->subsystem_device) 10492343f06aSManish Chopra ret = true; 10502343f06aSManish Chopra else 10512343f06aSManish Chopra ret = false; 10522343f06aSManish Chopra } 10532343f06aSManish Chopra 10542343f06aSManish Chopra return ret; 10552343f06aSManish Chopra } 10562343f06aSManish Chopra 105722999798SSony Chacko static void qlcnic_get_board_name(struct qlcnic_adapter *adapter, char *name) 1058aa43c215SJeff Kirsher { 1059aa43c215SJeff Kirsher struct pci_dev *pdev = adapter->pdev; 1060aa43c215SJeff Kirsher int i, found = 0; 1061aa43c215SJeff Kirsher 1062aa43c215SJeff Kirsher for (i = 0; i < NUM_SUPPORTED_BOARDS; ++i) { 1063aa43c215SJeff Kirsher if (qlcnic_boards[i].vendor == pdev->vendor && 1064aa43c215SJeff Kirsher qlcnic_boards[i].device == pdev->device && 10652343f06aSManish Chopra qlcnic_validate_subsystem_id(adapter, i)) { 1066aa43c215SJeff Kirsher found = 1; 1067aa43c215SJeff Kirsher break; 1068aa43c215SJeff Kirsher } 1069aa43c215SJeff Kirsher } 1070aa43c215SJeff Kirsher 1071aa43c215SJeff Kirsher if (!found) 1072aa43c215SJeff Kirsher sprintf(name, "%pM Gigabit Ethernet", adapter->mac_addr); 10732343f06aSManish Chopra else 10742343f06aSManish Chopra sprintf(name, "%pM: %s" , adapter->mac_addr, 10752343f06aSManish Chopra qlcnic_boards[i].short_name); 1076aa43c215SJeff Kirsher } 1077aa43c215SJeff Kirsher 1078aa43c215SJeff Kirsher static void 1079aa43c215SJeff Kirsher qlcnic_check_options(struct qlcnic_adapter *adapter) 1080aa43c215SJeff Kirsher { 1081a15ebd37SHimanshu Madhani int err; 1082aa43c215SJeff Kirsher u32 fw_major, fw_minor, fw_build, prev_fw_version; 1083aa43c215SJeff Kirsher struct pci_dev *pdev = adapter->pdev; 1084a15ebd37SHimanshu Madhani struct qlcnic_hardware_context *ahw = adapter->ahw; 1085a15ebd37SHimanshu Madhani struct qlcnic_fw_dump *fw_dump = &ahw->fw_dump; 1086aa43c215SJeff Kirsher 1087aa43c215SJeff Kirsher prev_fw_version = adapter->fw_version; 1088aa43c215SJeff Kirsher 1089a15ebd37SHimanshu Madhani fw_major = QLC_SHARED_REG_RD32(adapter, QLCNIC_FW_VERSION_MAJOR); 1090a15ebd37SHimanshu Madhani fw_minor = QLC_SHARED_REG_RD32(adapter, QLCNIC_FW_VERSION_MINOR); 1091a15ebd37SHimanshu Madhani fw_build = QLC_SHARED_REG_RD32(adapter, QLCNIC_FW_VERSION_SUB); 1092aa43c215SJeff Kirsher 1093aa43c215SJeff Kirsher adapter->fw_version = QLCNIC_VERSION_CODE(fw_major, fw_minor, fw_build); 1094aa43c215SJeff Kirsher 1095a15ebd37SHimanshu Madhani err = qlcnic_get_board_info(adapter); 1096a15ebd37SHimanshu Madhani if (err) { 1097a15ebd37SHimanshu Madhani dev_err(&pdev->dev, "Error getting board config info.\n"); 1098a15ebd37SHimanshu Madhani return; 1099a15ebd37SHimanshu Madhani } 1100a15ebd37SHimanshu Madhani if (ahw->op_mode != QLCNIC_NON_PRIV_FUNC) { 1101aa43c215SJeff Kirsher if (fw_dump->tmpl_hdr == NULL || 1102aa43c215SJeff Kirsher adapter->fw_version > prev_fw_version) { 1103aa43c215SJeff Kirsher if (fw_dump->tmpl_hdr) 1104aa43c215SJeff Kirsher vfree(fw_dump->tmpl_hdr); 1105aa43c215SJeff Kirsher if (!qlcnic_fw_cmd_get_minidump_temp(adapter)) 1106aa43c215SJeff Kirsher dev_info(&pdev->dev, 1107aa43c215SJeff Kirsher "Supports FW dump capability\n"); 1108aa43c215SJeff Kirsher } 1109aa43c215SJeff Kirsher } 1110aa43c215SJeff Kirsher 111113159183SSony Chacko dev_info(&pdev->dev, "Driver v%s, firmware v%d.%d.%d\n", 111213159183SSony Chacko QLCNIC_LINUX_VERSIONID, fw_major, fw_minor, fw_build); 111313159183SSony Chacko 1114aa43c215SJeff Kirsher if (adapter->ahw->port_type == QLCNIC_XGBE) { 1115aa43c215SJeff Kirsher if (adapter->flags & QLCNIC_ESWITCH_ENABLED) { 1116aa43c215SJeff Kirsher adapter->num_rxd = DEFAULT_RCV_DESCRIPTORS_VF; 1117aa43c215SJeff Kirsher adapter->max_rxd = MAX_RCV_DESCRIPTORS_VF; 1118aa43c215SJeff Kirsher } else { 1119aa43c215SJeff Kirsher adapter->num_rxd = DEFAULT_RCV_DESCRIPTORS_10G; 1120aa43c215SJeff Kirsher adapter->max_rxd = MAX_RCV_DESCRIPTORS_10G; 1121aa43c215SJeff Kirsher } 1122aa43c215SJeff Kirsher 1123aa43c215SJeff Kirsher adapter->num_jumbo_rxd = MAX_JUMBO_RCV_DESCRIPTORS_10G; 1124aa43c215SJeff Kirsher adapter->max_jumbo_rxd = MAX_JUMBO_RCV_DESCRIPTORS_10G; 1125aa43c215SJeff Kirsher 1126aa43c215SJeff Kirsher } else if (adapter->ahw->port_type == QLCNIC_GBE) { 1127aa43c215SJeff Kirsher adapter->num_rxd = DEFAULT_RCV_DESCRIPTORS_1G; 1128aa43c215SJeff Kirsher adapter->num_jumbo_rxd = MAX_JUMBO_RCV_DESCRIPTORS_1G; 1129aa43c215SJeff Kirsher adapter->max_jumbo_rxd = MAX_JUMBO_RCV_DESCRIPTORS_1G; 1130aa43c215SJeff Kirsher adapter->max_rxd = MAX_RCV_DESCRIPTORS_1G; 1131aa43c215SJeff Kirsher } 1132aa43c215SJeff Kirsher 1133099f7aa7SSony Chacko adapter->ahw->msix_supported = !!qlcnic_use_msi_x; 1134aa43c215SJeff Kirsher 1135aa43c215SJeff Kirsher adapter->num_txd = MAX_CMD_DESCRIPTORS; 1136aa43c215SJeff Kirsher 1137aa43c215SJeff Kirsher adapter->max_rds_rings = MAX_RDS_RINGS; 1138aa43c215SJeff Kirsher } 1139aa43c215SJeff Kirsher 1140aa43c215SJeff Kirsher static int 1141aa43c215SJeff Kirsher qlcnic_initialize_nic(struct qlcnic_adapter *adapter) 1142aa43c215SJeff Kirsher { 1143aa43c215SJeff Kirsher struct qlcnic_info nic_info; 11444bd8e738SHimanshu Madhani int err = 0; 1145aa43c215SJeff Kirsher 1146bff57d8eSSony Chacko memset(&nic_info, 0, sizeof(struct qlcnic_info)); 1147aa43c215SJeff Kirsher err = qlcnic_get_nic_info(adapter, &nic_info, adapter->ahw->pci_func); 1148aa43c215SJeff Kirsher if (err) 1149aa43c215SJeff Kirsher return err; 1150aa43c215SJeff Kirsher 115179788450SSony Chacko adapter->ahw->physical_port = (u8)nic_info.phys_port; 115279788450SSony Chacko adapter->ahw->switch_mode = nic_info.switch_mode; 115379788450SSony Chacko adapter->ahw->max_tx_ques = nic_info.max_tx_ques; 115479788450SSony Chacko adapter->ahw->max_rx_ques = nic_info.max_rx_ques; 115579788450SSony Chacko adapter->ahw->capabilities = nic_info.capabilities; 1156776e7bdeSShahed Shaikh 1157776e7bdeSShahed Shaikh if (adapter->ahw->capabilities & QLCNIC_FW_CAPABILITY_MORE_CAPS) { 1158776e7bdeSShahed Shaikh u32 temp; 11594bd8e738SHimanshu Madhani temp = QLCRD32(adapter, CRB_FW_CAPABILITIES_2, &err); 11604bd8e738SHimanshu Madhani if (err == -EIO) 11614bd8e738SHimanshu Madhani return err; 1162db131786SPratik Pujar adapter->ahw->extra_capability[0] = temp; 1163d6994ca7SShahed Shaikh } else { 1164d6994ca7SShahed Shaikh adapter->ahw->extra_capability[0] = 0; 1165776e7bdeSShahed Shaikh } 1166d6994ca7SShahed Shaikh 116779788450SSony Chacko adapter->ahw->max_mac_filters = nic_info.max_mac_filters; 116879788450SSony Chacko adapter->ahw->max_mtu = nic_info.max_mtu; 1169aa43c215SJeff Kirsher 117034e8c406SHimanshu Madhani if (adapter->ahw->capabilities & BIT_6) { 1171aa43c215SJeff Kirsher adapter->flags |= QLCNIC_ESWITCH_ENABLED; 117234e8c406SHimanshu Madhani adapter->ahw->nic_mode = QLCNIC_VNIC_MODE; 117334e8c406SHimanshu Madhani adapter->max_tx_rings = QLCNIC_MAX_HW_VNIC_TX_RINGS; 117434e8c406SHimanshu Madhani adapter->max_sds_rings = QLCNIC_MAX_VNIC_SDS_RINGS; 117534e8c406SHimanshu Madhani 117634e8c406SHimanshu Madhani dev_info(&adapter->pdev->dev, "vNIC mode enabled.\n"); 117734e8c406SHimanshu Madhani } else { 117834e8c406SHimanshu Madhani adapter->ahw->nic_mode = QLCNIC_DEFAULT_MODE; 117934e8c406SHimanshu Madhani adapter->max_tx_rings = QLCNIC_MAX_HW_TX_RINGS; 1180aa43c215SJeff Kirsher adapter->flags &= ~QLCNIC_ESWITCH_ENABLED; 118134e8c406SHimanshu Madhani } 1182aa43c215SJeff Kirsher 1183aa43c215SJeff Kirsher return err; 1184aa43c215SJeff Kirsher } 1185aa43c215SJeff Kirsher 1186ec079a07SSony Chacko void qlcnic_set_vlan_config(struct qlcnic_adapter *adapter, 1187aa43c215SJeff Kirsher struct qlcnic_esw_func_cfg *esw_cfg) 1188aa43c215SJeff Kirsher { 1189aa43c215SJeff Kirsher if (esw_cfg->discard_tagged) 1190aa43c215SJeff Kirsher adapter->flags &= ~QLCNIC_TAGGING_ENABLED; 1191aa43c215SJeff Kirsher else 1192aa43c215SJeff Kirsher adapter->flags |= QLCNIC_TAGGING_ENABLED; 1193aa43c215SJeff Kirsher 119491b7282bSRajesh Borundia if (esw_cfg->vlan_id) { 119591b7282bSRajesh Borundia adapter->rx_pvid = esw_cfg->vlan_id; 119691b7282bSRajesh Borundia adapter->tx_pvid = esw_cfg->vlan_id; 119791b7282bSRajesh Borundia } else { 119891b7282bSRajesh Borundia adapter->rx_pvid = 0; 119991b7282bSRajesh Borundia adapter->tx_pvid = 0; 120091b7282bSRajesh Borundia } 1201aa43c215SJeff Kirsher } 1202aa43c215SJeff Kirsher 12038e586137SJiri Pirko static int 120480d5c368SPatrick McHardy qlcnic_vlan_rx_add(struct net_device *netdev, __be16 proto, u16 vid) 1205aa43c215SJeff Kirsher { 1206aa43c215SJeff Kirsher struct qlcnic_adapter *adapter = netdev_priv(netdev); 120791b7282bSRajesh Borundia int err; 120891b7282bSRajesh Borundia 120991b7282bSRajesh Borundia if (qlcnic_sriov_vf_check(adapter)) { 121091b7282bSRajesh Borundia err = qlcnic_sriov_cfg_vf_guest_vlan(adapter, vid, 1); 121191b7282bSRajesh Borundia if (err) { 121291b7282bSRajesh Borundia netdev_err(netdev, 121391b7282bSRajesh Borundia "Cannot add VLAN filter for VLAN id %d, err=%d", 121491b7282bSRajesh Borundia vid, err); 121591b7282bSRajesh Borundia return err; 121691b7282bSRajesh Borundia } 121791b7282bSRajesh Borundia } 121891b7282bSRajesh Borundia 1219aa43c215SJeff Kirsher set_bit(vid, adapter->vlans); 12208e586137SJiri Pirko return 0; 1221aa43c215SJeff Kirsher } 1222aa43c215SJeff Kirsher 12238e586137SJiri Pirko static int 122480d5c368SPatrick McHardy qlcnic_vlan_rx_del(struct net_device *netdev, __be16 proto, u16 vid) 1225aa43c215SJeff Kirsher { 1226aa43c215SJeff Kirsher struct qlcnic_adapter *adapter = netdev_priv(netdev); 122791b7282bSRajesh Borundia int err; 122891b7282bSRajesh Borundia 122991b7282bSRajesh Borundia if (qlcnic_sriov_vf_check(adapter)) { 123091b7282bSRajesh Borundia err = qlcnic_sriov_cfg_vf_guest_vlan(adapter, vid, 0); 123191b7282bSRajesh Borundia if (err) { 123291b7282bSRajesh Borundia netdev_err(netdev, 123391b7282bSRajesh Borundia "Cannot delete VLAN filter for VLAN id %d, err=%d", 123491b7282bSRajesh Borundia vid, err); 123591b7282bSRajesh Borundia return err; 123691b7282bSRajesh Borundia } 123791b7282bSRajesh Borundia } 1238aa43c215SJeff Kirsher 1239aa43c215SJeff Kirsher qlcnic_restore_indev_addr(netdev, NETDEV_DOWN); 1240aa43c215SJeff Kirsher clear_bit(vid, adapter->vlans); 12418e586137SJiri Pirko return 0; 1242aa43c215SJeff Kirsher } 1243aa43c215SJeff Kirsher 1244ec079a07SSony Chacko void qlcnic_set_eswitch_port_features(struct qlcnic_adapter *adapter, 1245aa43c215SJeff Kirsher struct qlcnic_esw_func_cfg *esw_cfg) 1246aa43c215SJeff Kirsher { 1247aa43c215SJeff Kirsher adapter->flags &= ~(QLCNIC_MACSPOOF | QLCNIC_MAC_OVERRIDE_DISABLED | 1248aa43c215SJeff Kirsher QLCNIC_PROMISC_DISABLED); 1249aa43c215SJeff Kirsher 1250aa43c215SJeff Kirsher if (esw_cfg->mac_anti_spoof) 1251aa43c215SJeff Kirsher adapter->flags |= QLCNIC_MACSPOOF; 1252aa43c215SJeff Kirsher 1253aa43c215SJeff Kirsher if (!esw_cfg->mac_override) 1254aa43c215SJeff Kirsher adapter->flags |= QLCNIC_MAC_OVERRIDE_DISABLED; 1255aa43c215SJeff Kirsher 1256aa43c215SJeff Kirsher if (!esw_cfg->promisc_mode) 1257aa43c215SJeff Kirsher adapter->flags |= QLCNIC_PROMISC_DISABLED; 1258aa43c215SJeff Kirsher } 1259aa43c215SJeff Kirsher 1260d71170fbSSony Chacko int qlcnic_set_eswitch_port_config(struct qlcnic_adapter *adapter) 1261aa43c215SJeff Kirsher { 1262aa43c215SJeff Kirsher struct qlcnic_esw_func_cfg esw_cfg; 1263aa43c215SJeff Kirsher 1264aa43c215SJeff Kirsher if (!(adapter->flags & QLCNIC_ESWITCH_ENABLED)) 1265aa43c215SJeff Kirsher return 0; 1266aa43c215SJeff Kirsher 1267aa43c215SJeff Kirsher esw_cfg.pci_func = adapter->ahw->pci_func; 1268aa43c215SJeff Kirsher if (qlcnic_get_eswitch_port_config(adapter, &esw_cfg)) 1269aa43c215SJeff Kirsher return -EIO; 1270aa43c215SJeff Kirsher qlcnic_set_vlan_config(adapter, &esw_cfg); 1271aa43c215SJeff Kirsher qlcnic_set_eswitch_port_features(adapter, &esw_cfg); 1272147a9088SShahed Shaikh qlcnic_set_netdev_features(adapter, &esw_cfg); 1273aa43c215SJeff Kirsher 1274aa43c215SJeff Kirsher return 0; 1275aa43c215SJeff Kirsher } 1276aa43c215SJeff Kirsher 1277147a9088SShahed Shaikh void qlcnic_set_netdev_features(struct qlcnic_adapter *adapter, 1278aa43c215SJeff Kirsher struct qlcnic_esw_func_cfg *esw_cfg) 1279aa43c215SJeff Kirsher { 1280aa43c215SJeff Kirsher struct net_device *netdev = adapter->netdev; 1281aa43c215SJeff Kirsher 128213159183SSony Chacko if (qlcnic_83xx_check(adapter)) 128313159183SSony Chacko return; 128413159183SSony Chacko 1285147a9088SShahed Shaikh adapter->offload_flags = esw_cfg->offload_flags; 1286147a9088SShahed Shaikh adapter->flags |= QLCNIC_APP_CHANGED_FLAGS; 1287147a9088SShahed Shaikh netdev_update_features(netdev); 1288147a9088SShahed Shaikh adapter->flags &= ~QLCNIC_APP_CHANGED_FLAGS; 1289aa43c215SJeff Kirsher } 1290aa43c215SJeff Kirsher 1291aa43c215SJeff Kirsher static int 1292aa43c215SJeff Kirsher qlcnic_check_eswitch_mode(struct qlcnic_adapter *adapter) 1293aa43c215SJeff Kirsher { 1294aa43c215SJeff Kirsher u32 op_mode, priv_level; 1295aa43c215SJeff Kirsher int err = 0; 1296aa43c215SJeff Kirsher 1297aa43c215SJeff Kirsher err = qlcnic_initialize_nic(adapter); 1298aa43c215SJeff Kirsher if (err) 1299aa43c215SJeff Kirsher return err; 1300aa43c215SJeff Kirsher 1301aa43c215SJeff Kirsher if (adapter->flags & QLCNIC_ADAPTER_INITIALIZED) 1302aa43c215SJeff Kirsher return 0; 1303aa43c215SJeff Kirsher 130413159183SSony Chacko op_mode = QLC_SHARED_REG_RD32(adapter, QLCNIC_DRV_OP_MODE); 1305aa43c215SJeff Kirsher priv_level = QLC_DEV_GET_DRV(op_mode, adapter->ahw->pci_func); 1306aa43c215SJeff Kirsher 1307aa43c215SJeff Kirsher if (op_mode == QLC_DEV_DRV_DEFAULT) 1308aa43c215SJeff Kirsher priv_level = QLCNIC_MGMT_FUNC; 1309aa43c215SJeff Kirsher else 1310aa43c215SJeff Kirsher priv_level = QLC_DEV_GET_DRV(op_mode, adapter->ahw->pci_func); 1311aa43c215SJeff Kirsher 1312aa43c215SJeff Kirsher if (adapter->flags & QLCNIC_ESWITCH_ENABLED) { 1313aa43c215SJeff Kirsher if (priv_level == QLCNIC_MGMT_FUNC) { 131479788450SSony Chacko adapter->ahw->op_mode = QLCNIC_MGMT_FUNC; 1315aa43c215SJeff Kirsher err = qlcnic_init_pci_info(adapter); 1316aa43c215SJeff Kirsher if (err) 1317aa43c215SJeff Kirsher return err; 1318aa43c215SJeff Kirsher /* Set privilege level for other functions */ 1319aa43c215SJeff Kirsher qlcnic_set_function_modes(adapter); 1320aa43c215SJeff Kirsher dev_info(&adapter->pdev->dev, 1321aa43c215SJeff Kirsher "HAL Version: %d, Management function\n", 132279788450SSony Chacko adapter->ahw->fw_hal_version); 1323aa43c215SJeff Kirsher } else if (priv_level == QLCNIC_PRIV_FUNC) { 132479788450SSony Chacko adapter->ahw->op_mode = QLCNIC_PRIV_FUNC; 1325aa43c215SJeff Kirsher dev_info(&adapter->pdev->dev, 1326aa43c215SJeff Kirsher "HAL Version: %d, Privileged function\n", 132779788450SSony Chacko adapter->ahw->fw_hal_version); 1328aa43c215SJeff Kirsher } 132934e8c406SHimanshu Madhani } else { 133034e8c406SHimanshu Madhani adapter->ahw->nic_mode = QLCNIC_DEFAULT_MODE; 1331aa43c215SJeff Kirsher } 1332aa43c215SJeff Kirsher 1333aa43c215SJeff Kirsher adapter->flags |= QLCNIC_ADAPTER_INITIALIZED; 1334aa43c215SJeff Kirsher 1335aa43c215SJeff Kirsher return err; 1336aa43c215SJeff Kirsher } 1337aa43c215SJeff Kirsher 1338d71170fbSSony Chacko int qlcnic_set_default_offload_settings(struct qlcnic_adapter *adapter) 1339aa43c215SJeff Kirsher { 1340aa43c215SJeff Kirsher struct qlcnic_esw_func_cfg esw_cfg; 1341aa43c215SJeff Kirsher struct qlcnic_npar_info *npar; 1342aa43c215SJeff Kirsher u8 i; 1343aa43c215SJeff Kirsher 1344aa43c215SJeff Kirsher if (adapter->need_fw_reset) 1345aa43c215SJeff Kirsher return 0; 1346aa43c215SJeff Kirsher 1347bff57d8eSSony Chacko for (i = 0; i < adapter->ahw->act_pci_func; i++) { 134835dafcb0SSony Chacko if (!adapter->npars[i].eswitch_status) 134935dafcb0SSony Chacko continue; 135035dafcb0SSony Chacko 1351aa43c215SJeff Kirsher memset(&esw_cfg, 0, sizeof(struct qlcnic_esw_func_cfg)); 1352bff57d8eSSony Chacko esw_cfg.pci_func = adapter->npars[i].pci_func; 1353aa43c215SJeff Kirsher esw_cfg.mac_override = BIT_0; 1354aa43c215SJeff Kirsher esw_cfg.promisc_mode = BIT_0; 1355bff57d8eSSony Chacko if (qlcnic_82xx_check(adapter)) { 1356bff57d8eSSony Chacko esw_cfg.offload_flags = BIT_0; 1357bff57d8eSSony Chacko if (QLCNIC_IS_TSO_CAPABLE(adapter)) 1358aa43c215SJeff Kirsher esw_cfg.offload_flags |= (BIT_1 | BIT_2); 1359bff57d8eSSony Chacko } 1360aa43c215SJeff Kirsher if (qlcnic_config_switch_port(adapter, &esw_cfg)) 1361aa43c215SJeff Kirsher return -EIO; 1362aa43c215SJeff Kirsher npar = &adapter->npars[i]; 1363aa43c215SJeff Kirsher npar->pvid = esw_cfg.vlan_id; 1364aa43c215SJeff Kirsher npar->mac_override = esw_cfg.mac_override; 1365aa43c215SJeff Kirsher npar->mac_anti_spoof = esw_cfg.mac_anti_spoof; 1366aa43c215SJeff Kirsher npar->discard_tagged = esw_cfg.discard_tagged; 1367aa43c215SJeff Kirsher npar->promisc_mode = esw_cfg.promisc_mode; 1368aa43c215SJeff Kirsher npar->offload_flags = esw_cfg.offload_flags; 1369aa43c215SJeff Kirsher } 1370aa43c215SJeff Kirsher 1371aa43c215SJeff Kirsher return 0; 1372aa43c215SJeff Kirsher } 1373aa43c215SJeff Kirsher 137413159183SSony Chacko 1375aa43c215SJeff Kirsher static int 1376aa43c215SJeff Kirsher qlcnic_reset_eswitch_config(struct qlcnic_adapter *adapter, 1377aa43c215SJeff Kirsher struct qlcnic_npar_info *npar, int pci_func) 1378aa43c215SJeff Kirsher { 1379aa43c215SJeff Kirsher struct qlcnic_esw_func_cfg esw_cfg; 1380aa43c215SJeff Kirsher esw_cfg.op_mode = QLCNIC_PORT_DEFAULTS; 1381aa43c215SJeff Kirsher esw_cfg.pci_func = pci_func; 1382aa43c215SJeff Kirsher esw_cfg.vlan_id = npar->pvid; 1383aa43c215SJeff Kirsher esw_cfg.mac_override = npar->mac_override; 1384aa43c215SJeff Kirsher esw_cfg.discard_tagged = npar->discard_tagged; 1385aa43c215SJeff Kirsher esw_cfg.mac_anti_spoof = npar->mac_anti_spoof; 1386aa43c215SJeff Kirsher esw_cfg.offload_flags = npar->offload_flags; 1387aa43c215SJeff Kirsher esw_cfg.promisc_mode = npar->promisc_mode; 1388aa43c215SJeff Kirsher if (qlcnic_config_switch_port(adapter, &esw_cfg)) 1389aa43c215SJeff Kirsher return -EIO; 1390aa43c215SJeff Kirsher 1391aa43c215SJeff Kirsher esw_cfg.op_mode = QLCNIC_ADD_VLAN; 1392aa43c215SJeff Kirsher if (qlcnic_config_switch_port(adapter, &esw_cfg)) 1393aa43c215SJeff Kirsher return -EIO; 1394aa43c215SJeff Kirsher 1395aa43c215SJeff Kirsher return 0; 1396aa43c215SJeff Kirsher } 1397aa43c215SJeff Kirsher 1398d71170fbSSony Chacko int qlcnic_reset_npar_config(struct qlcnic_adapter *adapter) 1399aa43c215SJeff Kirsher { 1400aa43c215SJeff Kirsher int i, err; 1401aa43c215SJeff Kirsher struct qlcnic_npar_info *npar; 1402aa43c215SJeff Kirsher struct qlcnic_info nic_info; 1403bff57d8eSSony Chacko u8 pci_func; 1404aa43c215SJeff Kirsher 1405bff57d8eSSony Chacko if (qlcnic_82xx_check(adapter)) 1406aa43c215SJeff Kirsher if (!adapter->need_fw_reset) 1407aa43c215SJeff Kirsher return 0; 1408aa43c215SJeff Kirsher 1409aa43c215SJeff Kirsher /* Set the NPAR config data after FW reset */ 1410bff57d8eSSony Chacko for (i = 0; i < adapter->ahw->act_pci_func; i++) { 1411aa43c215SJeff Kirsher npar = &adapter->npars[i]; 1412bff57d8eSSony Chacko pci_func = npar->pci_func; 141335dafcb0SSony Chacko if (!adapter->npars[i].eswitch_status) 141435dafcb0SSony Chacko continue; 141535dafcb0SSony Chacko 1416bff57d8eSSony Chacko memset(&nic_info, 0, sizeof(struct qlcnic_info)); 141713159183SSony Chacko err = qlcnic_get_nic_info(adapter, &nic_info, pci_func); 1418aa43c215SJeff Kirsher if (err) 1419aa43c215SJeff Kirsher return err; 1420aa43c215SJeff Kirsher nic_info.min_tx_bw = npar->min_bw; 1421aa43c215SJeff Kirsher nic_info.max_tx_bw = npar->max_bw; 1422aa43c215SJeff Kirsher err = qlcnic_set_nic_info(adapter, &nic_info); 1423aa43c215SJeff Kirsher if (err) 1424aa43c215SJeff Kirsher return err; 1425aa43c215SJeff Kirsher 1426aa43c215SJeff Kirsher if (npar->enable_pm) { 1427aa43c215SJeff Kirsher err = qlcnic_config_port_mirroring(adapter, 1428bff57d8eSSony Chacko npar->dest_npar, 1, 1429bff57d8eSSony Chacko pci_func); 1430aa43c215SJeff Kirsher if (err) 1431aa43c215SJeff Kirsher return err; 1432aa43c215SJeff Kirsher } 1433bff57d8eSSony Chacko err = qlcnic_reset_eswitch_config(adapter, npar, pci_func); 1434aa43c215SJeff Kirsher if (err) 1435aa43c215SJeff Kirsher return err; 1436aa43c215SJeff Kirsher } 1437aa43c215SJeff Kirsher return 0; 1438aa43c215SJeff Kirsher } 1439aa43c215SJeff Kirsher 1440aa43c215SJeff Kirsher static int qlcnic_check_npar_opertional(struct qlcnic_adapter *adapter) 1441aa43c215SJeff Kirsher { 1442aa43c215SJeff Kirsher u8 npar_opt_timeo = QLCNIC_DEV_NPAR_OPER_TIMEO; 1443aa43c215SJeff Kirsher u32 npar_state; 1444aa43c215SJeff Kirsher 144579788450SSony Chacko if (adapter->ahw->op_mode == QLCNIC_MGMT_FUNC) 1446aa43c215SJeff Kirsher return 0; 1447aa43c215SJeff Kirsher 1448a15ebd37SHimanshu Madhani npar_state = QLC_SHARED_REG_RD32(adapter, 1449a15ebd37SHimanshu Madhani QLCNIC_CRB_DEV_NPAR_STATE); 1450aa43c215SJeff Kirsher while (npar_state != QLCNIC_DEV_NPAR_OPER && --npar_opt_timeo) { 1451aa43c215SJeff Kirsher msleep(1000); 1452a15ebd37SHimanshu Madhani npar_state = QLC_SHARED_REG_RD32(adapter, 1453a15ebd37SHimanshu Madhani QLCNIC_CRB_DEV_NPAR_STATE); 1454aa43c215SJeff Kirsher } 1455aa43c215SJeff Kirsher if (!npar_opt_timeo) { 1456aa43c215SJeff Kirsher dev_err(&adapter->pdev->dev, 14578a168ca7SMasanari Iida "Waiting for NPAR state to operational timeout\n"); 1458aa43c215SJeff Kirsher return -EIO; 1459aa43c215SJeff Kirsher } 1460aa43c215SJeff Kirsher return 0; 1461aa43c215SJeff Kirsher } 1462aa43c215SJeff Kirsher 1463aa43c215SJeff Kirsher static int 1464aa43c215SJeff Kirsher qlcnic_set_mgmt_operations(struct qlcnic_adapter *adapter) 1465aa43c215SJeff Kirsher { 1466aa43c215SJeff Kirsher int err; 1467aa43c215SJeff Kirsher 1468aa43c215SJeff Kirsher if (!(adapter->flags & QLCNIC_ESWITCH_ENABLED) || 146979788450SSony Chacko adapter->ahw->op_mode != QLCNIC_MGMT_FUNC) 1470aa43c215SJeff Kirsher return 0; 1471aa43c215SJeff Kirsher 1472aa43c215SJeff Kirsher err = qlcnic_set_default_offload_settings(adapter); 1473aa43c215SJeff Kirsher if (err) 1474aa43c215SJeff Kirsher return err; 1475aa43c215SJeff Kirsher 1476aa43c215SJeff Kirsher err = qlcnic_reset_npar_config(adapter); 1477aa43c215SJeff Kirsher if (err) 1478aa43c215SJeff Kirsher return err; 1479aa43c215SJeff Kirsher 1480aa43c215SJeff Kirsher qlcnic_dev_set_npar_ready(adapter); 1481aa43c215SJeff Kirsher 1482aa43c215SJeff Kirsher return err; 1483aa43c215SJeff Kirsher } 1484aa43c215SJeff Kirsher 14857e2cf4feSSony Chacko int qlcnic_82xx_start_firmware(struct qlcnic_adapter *adapter) 1486aa43c215SJeff Kirsher { 1487aa43c215SJeff Kirsher int err; 1488aa43c215SJeff Kirsher 1489aa43c215SJeff Kirsher err = qlcnic_can_start_firmware(adapter); 1490aa43c215SJeff Kirsher if (err < 0) 1491aa43c215SJeff Kirsher return err; 1492aa43c215SJeff Kirsher else if (!err) 1493aa43c215SJeff Kirsher goto check_fw_status; 1494aa43c215SJeff Kirsher 1495099f7aa7SSony Chacko if (qlcnic_load_fw_file) 1496aa43c215SJeff Kirsher qlcnic_request_firmware(adapter); 1497aa43c215SJeff Kirsher else { 1498aa43c215SJeff Kirsher err = qlcnic_check_flash_fw_ver(adapter); 1499aa43c215SJeff Kirsher if (err) 1500aa43c215SJeff Kirsher goto err_out; 1501aa43c215SJeff Kirsher 150279788450SSony Chacko adapter->ahw->fw_type = QLCNIC_FLASH_ROMIMAGE; 1503aa43c215SJeff Kirsher } 1504aa43c215SJeff Kirsher 1505aa43c215SJeff Kirsher err = qlcnic_need_fw_reset(adapter); 1506aa43c215SJeff Kirsher if (err == 0) 1507aa43c215SJeff Kirsher goto check_fw_status; 1508aa43c215SJeff Kirsher 1509aa43c215SJeff Kirsher err = qlcnic_pinit_from_rom(adapter); 1510aa43c215SJeff Kirsher if (err) 1511aa43c215SJeff Kirsher goto err_out; 1512aa43c215SJeff Kirsher 1513aa43c215SJeff Kirsher err = qlcnic_load_firmware(adapter); 1514aa43c215SJeff Kirsher if (err) 1515aa43c215SJeff Kirsher goto err_out; 1516aa43c215SJeff Kirsher 1517aa43c215SJeff Kirsher qlcnic_release_firmware(adapter); 1518aa43c215SJeff Kirsher QLCWR32(adapter, CRB_DRIVER_VERSION, QLCNIC_DRIVER_VERSION); 1519aa43c215SJeff Kirsher 1520aa43c215SJeff Kirsher check_fw_status: 1521aa43c215SJeff Kirsher err = qlcnic_check_fw_status(adapter); 1522aa43c215SJeff Kirsher if (err) 1523aa43c215SJeff Kirsher goto err_out; 1524aa43c215SJeff Kirsher 1525a15ebd37SHimanshu Madhani QLC_SHARED_REG_WR32(adapter, QLCNIC_CRB_DEV_STATE, QLCNIC_DEV_READY); 1526aa43c215SJeff Kirsher qlcnic_idc_debug_info(adapter, 1); 1527aa43c215SJeff Kirsher err = qlcnic_check_eswitch_mode(adapter); 1528aa43c215SJeff Kirsher if (err) { 1529aa43c215SJeff Kirsher dev_err(&adapter->pdev->dev, 1530aa43c215SJeff Kirsher "Memory allocation failed for eswitch\n"); 1531aa43c215SJeff Kirsher goto err_out; 1532aa43c215SJeff Kirsher } 1533aa43c215SJeff Kirsher err = qlcnic_set_mgmt_operations(adapter); 1534aa43c215SJeff Kirsher if (err) 1535aa43c215SJeff Kirsher goto err_out; 1536aa43c215SJeff Kirsher 1537aa43c215SJeff Kirsher qlcnic_check_options(adapter); 1538aa43c215SJeff Kirsher adapter->need_fw_reset = 0; 1539aa43c215SJeff Kirsher 1540aa43c215SJeff Kirsher qlcnic_release_firmware(adapter); 1541aa43c215SJeff Kirsher return 0; 1542aa43c215SJeff Kirsher 1543aa43c215SJeff Kirsher err_out: 1544a15ebd37SHimanshu Madhani QLC_SHARED_REG_WR32(adapter, QLCNIC_CRB_DEV_STATE, QLCNIC_DEV_FAILED); 1545aa43c215SJeff Kirsher dev_err(&adapter->pdev->dev, "Device state set to failed\n"); 1546aa43c215SJeff Kirsher 1547aa43c215SJeff Kirsher qlcnic_release_firmware(adapter); 1548aa43c215SJeff Kirsher return err; 1549aa43c215SJeff Kirsher } 1550aa43c215SJeff Kirsher 1551aa43c215SJeff Kirsher static int 1552aa43c215SJeff Kirsher qlcnic_request_irq(struct qlcnic_adapter *adapter) 1553aa43c215SJeff Kirsher { 1554aa43c215SJeff Kirsher irq_handler_t handler; 1555aa43c215SJeff Kirsher struct qlcnic_host_sds_ring *sds_ring; 155613159183SSony Chacko struct qlcnic_host_tx_ring *tx_ring; 1557ddb2e174SHimanshu Madhani int err, ring, num_sds_rings; 1558aa43c215SJeff Kirsher 1559aa43c215SJeff Kirsher unsigned long flags = 0; 1560aa43c215SJeff Kirsher struct net_device *netdev = adapter->netdev; 1561aa43c215SJeff Kirsher struct qlcnic_recv_context *recv_ctx = adapter->recv_ctx; 1562aa43c215SJeff Kirsher 156379788450SSony Chacko if (adapter->ahw->diag_test == QLCNIC_INTERRUPT_TEST) { 156413159183SSony Chacko if (qlcnic_82xx_check(adapter)) 1565aa43c215SJeff Kirsher handler = qlcnic_tmp_intr; 1566c2534384SManish Chopra else 1567c2534384SManish Chopra handler = qlcnic_83xx_tmp_intr; 1568aa43c215SJeff Kirsher if (!QLCNIC_IS_MSI_FAMILY(adapter)) 1569aa43c215SJeff Kirsher flags |= IRQF_SHARED; 1570aa43c215SJeff Kirsher 1571aa43c215SJeff Kirsher } else { 1572aa43c215SJeff Kirsher if (adapter->flags & QLCNIC_MSIX_ENABLED) 1573aa43c215SJeff Kirsher handler = qlcnic_msix_intr; 1574aa43c215SJeff Kirsher else if (adapter->flags & QLCNIC_MSI_ENABLED) 1575aa43c215SJeff Kirsher handler = qlcnic_msi_intr; 1576aa43c215SJeff Kirsher else { 1577aa43c215SJeff Kirsher flags |= IRQF_SHARED; 1578ac166700SHimanshu Madhani if (qlcnic_82xx_check(adapter)) 1579aa43c215SJeff Kirsher handler = qlcnic_intr; 1580ac166700SHimanshu Madhani else 1581ac166700SHimanshu Madhani handler = qlcnic_83xx_intr; 1582aa43c215SJeff Kirsher } 1583aa43c215SJeff Kirsher } 1584aa43c215SJeff Kirsher adapter->irq = netdev->irq; 1585aa43c215SJeff Kirsher 158613159183SSony Chacko if (adapter->ahw->diag_test != QLCNIC_LOOPBACK_TEST) { 1587ac166700SHimanshu Madhani if (qlcnic_82xx_check(adapter) || 1588ac166700SHimanshu Madhani (qlcnic_83xx_check(adapter) && 1589ac166700SHimanshu Madhani (adapter->flags & QLCNIC_MSIX_ENABLED))) { 159034e8c406SHimanshu Madhani num_sds_rings = adapter->drv_sds_rings; 1591ddb2e174SHimanshu Madhani for (ring = 0; ring < num_sds_rings; ring++) { 1592aa43c215SJeff Kirsher sds_ring = &recv_ctx->sds_rings[ring]; 1593ddb2e174SHimanshu Madhani if (qlcnic_82xx_check(adapter) && 1594012ec812SHimanshu Madhani !qlcnic_check_multi_tx(adapter) && 1595aa2a8034SHimanshu Madhani (ring == (num_sds_rings - 1))) { 1596aa2a8034SHimanshu Madhani if (!(adapter->flags & 1597aa2a8034SHimanshu Madhani QLCNIC_MSIX_ENABLED)) 1598ddb2e174SHimanshu Madhani snprintf(sds_ring->name, 1599ddb2e174SHimanshu Madhani sizeof(sds_ring->name), 1600aa2a8034SHimanshu Madhani "qlcnic"); 1601ddb2e174SHimanshu Madhani else 1602ddb2e174SHimanshu Madhani snprintf(sds_ring->name, 1603ddb2e174SHimanshu Madhani sizeof(sds_ring->name), 1604aa2a8034SHimanshu Madhani "%s-tx-0-rx-%d", 1605ddb2e174SHimanshu Madhani netdev->name, ring); 1606aa2a8034SHimanshu Madhani } else { 1607aa2a8034SHimanshu Madhani snprintf(sds_ring->name, 1608aa2a8034SHimanshu Madhani sizeof(sds_ring->name), 1609aa2a8034SHimanshu Madhani "%s-rx-%d", 1610aa2a8034SHimanshu Madhani netdev->name, ring); 1611aa2a8034SHimanshu Madhani } 161213159183SSony Chacko err = request_irq(sds_ring->irq, handler, flags, 161313159183SSony Chacko sds_ring->name, sds_ring); 1614aa43c215SJeff Kirsher if (err) 1615aa43c215SJeff Kirsher return err; 1616aa43c215SJeff Kirsher } 1617ac166700SHimanshu Madhani } 1618012ec812SHimanshu Madhani if ((qlcnic_82xx_check(adapter) && 1619012ec812SHimanshu Madhani qlcnic_check_multi_tx(adapter)) || 1620012ec812SHimanshu Madhani (qlcnic_83xx_check(adapter) && 1621da6c8063SRajesh Borundia (adapter->flags & QLCNIC_MSIX_ENABLED) && 1622012ec812SHimanshu Madhani !(adapter->flags & QLCNIC_TX_INTR_SHARED))) { 162313159183SSony Chacko handler = qlcnic_msix_tx_intr; 162434e8c406SHimanshu Madhani for (ring = 0; ring < adapter->drv_tx_rings; 162513159183SSony Chacko ring++) { 162613159183SSony Chacko tx_ring = &adapter->tx_ring[ring]; 1627ddb2e174SHimanshu Madhani snprintf(tx_ring->name, sizeof(tx_ring->name), 1628aa2a8034SHimanshu Madhani "%s-tx-%d", netdev->name, ring); 162913159183SSony Chacko err = request_irq(tx_ring->irq, handler, flags, 163013159183SSony Chacko tx_ring->name, tx_ring); 163113159183SSony Chacko if (err) 163213159183SSony Chacko return err; 163313159183SSony Chacko } 163413159183SSony Chacko } 163513159183SSony Chacko } 1636aa43c215SJeff Kirsher return 0; 1637aa43c215SJeff Kirsher } 1638aa43c215SJeff Kirsher 1639aa43c215SJeff Kirsher static void 1640aa43c215SJeff Kirsher qlcnic_free_irq(struct qlcnic_adapter *adapter) 1641aa43c215SJeff Kirsher { 1642aa43c215SJeff Kirsher int ring; 1643aa43c215SJeff Kirsher struct qlcnic_host_sds_ring *sds_ring; 164413159183SSony Chacko struct qlcnic_host_tx_ring *tx_ring; 1645aa43c215SJeff Kirsher 1646aa43c215SJeff Kirsher struct qlcnic_recv_context *recv_ctx = adapter->recv_ctx; 1647aa43c215SJeff Kirsher 164813159183SSony Chacko if (adapter->ahw->diag_test != QLCNIC_LOOPBACK_TEST) { 1649ac166700SHimanshu Madhani if (qlcnic_82xx_check(adapter) || 1650ac166700SHimanshu Madhani (qlcnic_83xx_check(adapter) && 1651ac166700SHimanshu Madhani (adapter->flags & QLCNIC_MSIX_ENABLED))) { 165234e8c406SHimanshu Madhani for (ring = 0; ring < adapter->drv_sds_rings; ring++) { 1653aa43c215SJeff Kirsher sds_ring = &recv_ctx->sds_rings[ring]; 1654aa43c215SJeff Kirsher free_irq(sds_ring->irq, sds_ring); 1655aa43c215SJeff Kirsher } 1656ac166700SHimanshu Madhani } 1657012ec812SHimanshu Madhani if ((qlcnic_83xx_check(adapter) && 1658012ec812SHimanshu Madhani !(adapter->flags & QLCNIC_TX_INTR_SHARED)) || 1659012ec812SHimanshu Madhani (qlcnic_82xx_check(adapter) && 1660012ec812SHimanshu Madhani qlcnic_check_multi_tx(adapter))) { 166134e8c406SHimanshu Madhani for (ring = 0; ring < adapter->drv_tx_rings; 166213159183SSony Chacko ring++) { 166313159183SSony Chacko tx_ring = &adapter->tx_ring[ring]; 166413159183SSony Chacko if (tx_ring->irq) 166513159183SSony Chacko free_irq(tx_ring->irq, tx_ring); 166613159183SSony Chacko } 166713159183SSony Chacko } 166813159183SSony Chacko } 1669aa43c215SJeff Kirsher } 1670aa43c215SJeff Kirsher 167199e85879SShahed Shaikh static void qlcnic_get_lro_mss_capability(struct qlcnic_adapter *adapter) 167299e85879SShahed Shaikh { 167399e85879SShahed Shaikh u32 capab = 0; 167499e85879SShahed Shaikh 167599e85879SShahed Shaikh if (qlcnic_82xx_check(adapter)) { 1676db131786SPratik Pujar if (adapter->ahw->extra_capability[0] & 167799e85879SShahed Shaikh QLCNIC_FW_CAPABILITY_2_LRO_MAX_TCP_SEG) 167899e85879SShahed Shaikh adapter->flags |= QLCNIC_FW_LRO_MSS_CAP; 167999e85879SShahed Shaikh } else { 168099e85879SShahed Shaikh capab = adapter->ahw->capabilities; 168199e85879SShahed Shaikh if (QLC_83XX_GET_FW_LRO_MSS_CAPABILITY(capab)) 168299e85879SShahed Shaikh adapter->flags |= QLCNIC_FW_LRO_MSS_CAP; 168399e85879SShahed Shaikh } 168499e85879SShahed Shaikh } 168599e85879SShahed Shaikh 1686319ecf12SSony Chacko int __qlcnic_up(struct qlcnic_adapter *adapter, struct net_device *netdev) 1687aa43c215SJeff Kirsher { 1688aa43c215SJeff Kirsher int ring; 1689aa43c215SJeff Kirsher struct qlcnic_host_rds_ring *rds_ring; 1690aa43c215SJeff Kirsher 1691aa43c215SJeff Kirsher if (adapter->is_up != QLCNIC_ADAPTER_UP_MAGIC) 1692aa43c215SJeff Kirsher return -EIO; 1693aa43c215SJeff Kirsher 1694aa43c215SJeff Kirsher if (test_bit(__QLCNIC_DEV_UP, &adapter->state)) 1695aa43c215SJeff Kirsher return 0; 1696012ec812SHimanshu Madhani 1697aa43c215SJeff Kirsher if (qlcnic_set_eswitch_port_config(adapter)) 1698aa43c215SJeff Kirsher return -EIO; 1699012ec812SHimanshu Madhani 170099e85879SShahed Shaikh qlcnic_get_lro_mss_capability(adapter); 1701cae82d49SRajesh Borundia 1702aa43c215SJeff Kirsher if (qlcnic_fw_create_ctx(adapter)) 1703aa43c215SJeff Kirsher return -EIO; 1704aa43c215SJeff Kirsher 1705aa43c215SJeff Kirsher for (ring = 0; ring < adapter->max_rds_rings; ring++) { 1706aa43c215SJeff Kirsher rds_ring = &adapter->recv_ctx->rds_rings[ring]; 17074be41e92SSony Chacko qlcnic_post_rx_buffers(adapter, rds_ring, ring); 1708aa43c215SJeff Kirsher } 1709aa43c215SJeff Kirsher 1710aa43c215SJeff Kirsher qlcnic_set_multi(netdev); 1711aa43c215SJeff Kirsher qlcnic_fw_cmd_set_mtu(adapter, netdev->mtu); 1712aa43c215SJeff Kirsher 1713aa43c215SJeff Kirsher adapter->ahw->linkup = 0; 1714aa43c215SJeff Kirsher 171534e8c406SHimanshu Madhani if (adapter->drv_sds_rings > 1) 1716aa43c215SJeff Kirsher qlcnic_config_rss(adapter, 1); 1717aa43c215SJeff Kirsher 1718aa43c215SJeff Kirsher qlcnic_config_intr_coalesce(adapter); 1719aa43c215SJeff Kirsher 1720aa43c215SJeff Kirsher if (netdev->features & NETIF_F_LRO) 1721aa43c215SJeff Kirsher qlcnic_config_hw_lro(adapter, QLCNIC_LRO_ENABLED); 1722aa43c215SJeff Kirsher 1723cfacb172SPratik Pujar set_bit(__QLCNIC_DEV_UP, &adapter->state); 1724aa43c215SJeff Kirsher qlcnic_napi_enable(adapter); 1725aa43c215SJeff Kirsher 1726aa43c215SJeff Kirsher qlcnic_linkevent_request(adapter, 1); 1727aa43c215SJeff Kirsher 172879788450SSony Chacko adapter->ahw->reset_context = 0; 1729aa43c215SJeff Kirsher return 0; 1730aa43c215SJeff Kirsher } 1731aa43c215SJeff Kirsher 1732629263acSSony Chacko int qlcnic_up(struct qlcnic_adapter *adapter, struct net_device *netdev) 1733aa43c215SJeff Kirsher { 1734aa43c215SJeff Kirsher int err = 0; 1735aa43c215SJeff Kirsher 1736aa43c215SJeff Kirsher rtnl_lock(); 1737aa43c215SJeff Kirsher if (netif_running(netdev)) 1738aa43c215SJeff Kirsher err = __qlcnic_up(adapter, netdev); 1739aa43c215SJeff Kirsher rtnl_unlock(); 1740aa43c215SJeff Kirsher 1741aa43c215SJeff Kirsher return err; 1742aa43c215SJeff Kirsher } 1743aa43c215SJeff Kirsher 1744319ecf12SSony Chacko void __qlcnic_down(struct qlcnic_adapter *adapter, struct net_device *netdev) 1745aa43c215SJeff Kirsher { 1746012ec812SHimanshu Madhani int ring; 1747012ec812SHimanshu Madhani 1748aa43c215SJeff Kirsher if (adapter->is_up != QLCNIC_ADAPTER_UP_MAGIC) 1749aa43c215SJeff Kirsher return; 1750aa43c215SJeff Kirsher 1751aa43c215SJeff Kirsher if (!test_and_clear_bit(__QLCNIC_DEV_UP, &adapter->state)) 1752aa43c215SJeff Kirsher return; 1753aa43c215SJeff Kirsher 1754e8b508efSRajesh Borundia if (qlcnic_sriov_vf_check(adapter)) 1755e8b508efSRajesh Borundia qlcnic_sriov_cleanup_async_list(&adapter->ahw->sriov->bc); 1756aa43c215SJeff Kirsher smp_mb(); 175734e8c406SHimanshu Madhani spin_lock(&adapter->tx_clean_lock); 1758aa43c215SJeff Kirsher netif_carrier_off(netdev); 17590a46bac0SShahed Shaikh adapter->ahw->linkup = 0; 1760aa43c215SJeff Kirsher netif_tx_disable(netdev); 1761aa43c215SJeff Kirsher 1762aa43c215SJeff Kirsher qlcnic_free_mac_list(adapter); 1763aa43c215SJeff Kirsher 1764aa43c215SJeff Kirsher if (adapter->fhash.fnum) 1765aa43c215SJeff Kirsher qlcnic_delete_lb_filters(adapter); 1766aa43c215SJeff Kirsher 1767aa43c215SJeff Kirsher qlcnic_nic_set_promisc(adapter, QLCNIC_NIU_NON_PROMISC_MODE); 1768aa43c215SJeff Kirsher 1769aa43c215SJeff Kirsher qlcnic_napi_disable(adapter); 1770aa43c215SJeff Kirsher 1771aa43c215SJeff Kirsher qlcnic_fw_destroy_ctx(adapter); 1772cae82d49SRajesh Borundia adapter->flags &= ~QLCNIC_FW_LRO_MSS_CAP; 1773aa43c215SJeff Kirsher 1774aa43c215SJeff Kirsher qlcnic_reset_rx_buffers_list(adapter); 1775012ec812SHimanshu Madhani 177634e8c406SHimanshu Madhani for (ring = 0; ring < adapter->drv_tx_rings; ring++) 1777012ec812SHimanshu Madhani qlcnic_release_tx_buffers(adapter, &adapter->tx_ring[ring]); 177834e8c406SHimanshu Madhani spin_unlock(&adapter->tx_clean_lock); 1779aa43c215SJeff Kirsher } 1780aa43c215SJeff Kirsher 1781aa43c215SJeff Kirsher /* Usage: During suspend and firmware recovery module */ 1782aa43c215SJeff Kirsher 1783629263acSSony Chacko void qlcnic_down(struct qlcnic_adapter *adapter, struct net_device *netdev) 1784aa43c215SJeff Kirsher { 1785aa43c215SJeff Kirsher rtnl_lock(); 1786aa43c215SJeff Kirsher if (netif_running(netdev)) 1787aa43c215SJeff Kirsher __qlcnic_down(adapter, netdev); 1788aa43c215SJeff Kirsher rtnl_unlock(); 1789aa43c215SJeff Kirsher 1790aa43c215SJeff Kirsher } 1791aa43c215SJeff Kirsher 1792319ecf12SSony Chacko int 1793aa43c215SJeff Kirsher qlcnic_attach(struct qlcnic_adapter *adapter) 1794aa43c215SJeff Kirsher { 1795aa43c215SJeff Kirsher struct net_device *netdev = adapter->netdev; 1796aa43c215SJeff Kirsher struct pci_dev *pdev = adapter->pdev; 1797aa43c215SJeff Kirsher int err; 1798aa43c215SJeff Kirsher 1799aa43c215SJeff Kirsher if (adapter->is_up == QLCNIC_ADAPTER_UP_MAGIC) 1800aa43c215SJeff Kirsher return 0; 1801aa43c215SJeff Kirsher 1802aa43c215SJeff Kirsher err = qlcnic_napi_add(adapter, netdev); 1803aa43c215SJeff Kirsher if (err) 1804aa43c215SJeff Kirsher return err; 1805aa43c215SJeff Kirsher 1806aa43c215SJeff Kirsher err = qlcnic_alloc_sw_resources(adapter); 1807aa43c215SJeff Kirsher if (err) { 1808aa43c215SJeff Kirsher dev_err(&pdev->dev, "Error in setting sw resources\n"); 1809aa43c215SJeff Kirsher goto err_out_napi_del; 1810aa43c215SJeff Kirsher } 1811aa43c215SJeff Kirsher 1812aa43c215SJeff Kirsher err = qlcnic_alloc_hw_resources(adapter); 1813aa43c215SJeff Kirsher if (err) { 1814aa43c215SJeff Kirsher dev_err(&pdev->dev, "Error in setting hw resources\n"); 1815aa43c215SJeff Kirsher goto err_out_free_sw; 1816aa43c215SJeff Kirsher } 1817aa43c215SJeff Kirsher 1818aa43c215SJeff Kirsher err = qlcnic_request_irq(adapter); 1819aa43c215SJeff Kirsher if (err) { 1820aa43c215SJeff Kirsher dev_err(&pdev->dev, "failed to setup interrupt\n"); 1821aa43c215SJeff Kirsher goto err_out_free_hw; 1822aa43c215SJeff Kirsher } 1823aa43c215SJeff Kirsher 1824aa43c215SJeff Kirsher qlcnic_create_sysfs_entries(adapter); 1825aa43c215SJeff Kirsher 1826aa43c215SJeff Kirsher adapter->is_up = QLCNIC_ADAPTER_UP_MAGIC; 1827aa43c215SJeff Kirsher return 0; 1828aa43c215SJeff Kirsher 1829aa43c215SJeff Kirsher err_out_free_hw: 1830aa43c215SJeff Kirsher qlcnic_free_hw_resources(adapter); 1831aa43c215SJeff Kirsher err_out_free_sw: 1832aa43c215SJeff Kirsher qlcnic_free_sw_resources(adapter); 1833aa43c215SJeff Kirsher err_out_napi_del: 1834aa43c215SJeff Kirsher qlcnic_napi_del(adapter); 1835aa43c215SJeff Kirsher return err; 1836aa43c215SJeff Kirsher } 1837aa43c215SJeff Kirsher 1838319ecf12SSony Chacko void qlcnic_detach(struct qlcnic_adapter *adapter) 1839aa43c215SJeff Kirsher { 1840aa43c215SJeff Kirsher if (adapter->is_up != QLCNIC_ADAPTER_UP_MAGIC) 1841aa43c215SJeff Kirsher return; 1842aa43c215SJeff Kirsher 1843aa43c215SJeff Kirsher qlcnic_remove_sysfs_entries(adapter); 1844aa43c215SJeff Kirsher 1845aa43c215SJeff Kirsher qlcnic_free_hw_resources(adapter); 1846aa43c215SJeff Kirsher qlcnic_release_rx_buffers(adapter); 1847aa43c215SJeff Kirsher qlcnic_free_irq(adapter); 1848aa43c215SJeff Kirsher qlcnic_napi_del(adapter); 1849aa43c215SJeff Kirsher qlcnic_free_sw_resources(adapter); 1850aa43c215SJeff Kirsher 1851aa43c215SJeff Kirsher adapter->is_up = 0; 1852aa43c215SJeff Kirsher } 1853aa43c215SJeff Kirsher 185434e8c406SHimanshu Madhani void qlcnic_diag_free_res(struct net_device *netdev, int drv_sds_rings) 1855aa43c215SJeff Kirsher { 1856aa43c215SJeff Kirsher struct qlcnic_adapter *adapter = netdev_priv(netdev); 1857aa43c215SJeff Kirsher struct qlcnic_host_sds_ring *sds_ring; 185834e8c406SHimanshu Madhani int drv_tx_rings = adapter->drv_tx_rings; 1859aa43c215SJeff Kirsher int ring; 1860aa43c215SJeff Kirsher 1861aa43c215SJeff Kirsher clear_bit(__QLCNIC_DEV_UP, &adapter->state); 186279788450SSony Chacko if (adapter->ahw->diag_test == QLCNIC_INTERRUPT_TEST) { 186334e8c406SHimanshu Madhani for (ring = 0; ring < adapter->drv_sds_rings; ring++) { 1864aa43c215SJeff Kirsher sds_ring = &adapter->recv_ctx->sds_rings[ring]; 1865aa43c215SJeff Kirsher qlcnic_disable_int(sds_ring); 1866aa43c215SJeff Kirsher } 1867aa43c215SJeff Kirsher } 1868aa43c215SJeff Kirsher 1869aa43c215SJeff Kirsher qlcnic_fw_destroy_ctx(adapter); 1870aa43c215SJeff Kirsher 1871aa43c215SJeff Kirsher qlcnic_detach(adapter); 1872aa43c215SJeff Kirsher 187379788450SSony Chacko adapter->ahw->diag_test = 0; 187434e8c406SHimanshu Madhani adapter->drv_sds_rings = drv_sds_rings; 187534e8c406SHimanshu Madhani adapter->drv_tx_rings = drv_tx_rings; 1876aa43c215SJeff Kirsher 1877aa43c215SJeff Kirsher if (qlcnic_attach(adapter)) 1878aa43c215SJeff Kirsher goto out; 1879aa43c215SJeff Kirsher 1880aa43c215SJeff Kirsher if (netif_running(netdev)) 1881aa43c215SJeff Kirsher __qlcnic_up(adapter, netdev); 1882aa43c215SJeff Kirsher out: 1883aa43c215SJeff Kirsher netif_device_attach(netdev); 1884aa43c215SJeff Kirsher } 1885aa43c215SJeff Kirsher 1886aa43c215SJeff Kirsher static int qlcnic_alloc_adapter_resources(struct qlcnic_adapter *adapter) 1887aa43c215SJeff Kirsher { 1888be273dc1SHimanshu Madhani struct qlcnic_hardware_context *ahw = adapter->ahw; 1889aa43c215SJeff Kirsher int err = 0; 1890be273dc1SHimanshu Madhani 1891aa43c215SJeff Kirsher adapter->recv_ctx = kzalloc(sizeof(struct qlcnic_recv_context), 1892aa43c215SJeff Kirsher GFP_KERNEL); 1893aa43c215SJeff Kirsher if (!adapter->recv_ctx) { 1894aa43c215SJeff Kirsher err = -ENOMEM; 1895aa43c215SJeff Kirsher goto err_out; 1896aa43c215SJeff Kirsher } 1897aa43c215SJeff Kirsher /* Initialize interrupt coalesce parameters */ 1898be273dc1SHimanshu Madhani ahw->coal.flag = QLCNIC_INTR_DEFAULT; 1899be273dc1SHimanshu Madhani ahw->coal.type = QLCNIC_INTR_COAL_TYPE_RX; 1900be273dc1SHimanshu Madhani ahw->coal.rx_time_us = QLCNIC_DEF_INTR_COALESCE_RX_TIME_US; 1901be273dc1SHimanshu Madhani ahw->coal.rx_packets = QLCNIC_DEF_INTR_COALESCE_RX_PACKETS; 1902be273dc1SHimanshu Madhani if (qlcnic_83xx_check(adapter)) { 1903be273dc1SHimanshu Madhani ahw->coal.tx_time_us = QLCNIC_DEF_INTR_COALESCE_TX_TIME_US; 1904be273dc1SHimanshu Madhani ahw->coal.tx_packets = QLCNIC_DEF_INTR_COALESCE_TX_PACKETS; 1905be273dc1SHimanshu Madhani } 19064be41e92SSony Chacko /* clear stats */ 19074be41e92SSony Chacko memset(&adapter->stats, 0, sizeof(adapter->stats)); 1908aa43c215SJeff Kirsher err_out: 1909aa43c215SJeff Kirsher return err; 1910aa43c215SJeff Kirsher } 1911aa43c215SJeff Kirsher 1912aa43c215SJeff Kirsher static void qlcnic_free_adapter_resources(struct qlcnic_adapter *adapter) 1913aa43c215SJeff Kirsher { 1914aa43c215SJeff Kirsher kfree(adapter->recv_ctx); 1915aa43c215SJeff Kirsher adapter->recv_ctx = NULL; 1916aa43c215SJeff Kirsher 1917aa43c215SJeff Kirsher if (adapter->ahw->fw_dump.tmpl_hdr) { 1918aa43c215SJeff Kirsher vfree(adapter->ahw->fw_dump.tmpl_hdr); 1919aa43c215SJeff Kirsher adapter->ahw->fw_dump.tmpl_hdr = NULL; 1920aa43c215SJeff Kirsher } 19214be41e92SSony Chacko 192281d0aeb0SSony Chacko kfree(adapter->ahw->reset.buff); 19234be41e92SSony Chacko adapter->ahw->fw_dump.tmpl_hdr = NULL; 1924aa43c215SJeff Kirsher } 1925aa43c215SJeff Kirsher 1926aa43c215SJeff Kirsher int qlcnic_diag_alloc_res(struct net_device *netdev, int test) 1927aa43c215SJeff Kirsher { 1928aa43c215SJeff Kirsher struct qlcnic_adapter *adapter = netdev_priv(netdev); 1929aa43c215SJeff Kirsher struct qlcnic_host_sds_ring *sds_ring; 1930aa43c215SJeff Kirsher struct qlcnic_host_rds_ring *rds_ring; 1931aa43c215SJeff Kirsher int ring; 1932aa43c215SJeff Kirsher int ret; 1933aa43c215SJeff Kirsher 1934aa43c215SJeff Kirsher netif_device_detach(netdev); 1935aa43c215SJeff Kirsher 1936aa43c215SJeff Kirsher if (netif_running(netdev)) 1937aa43c215SJeff Kirsher __qlcnic_down(adapter, netdev); 1938aa43c215SJeff Kirsher 1939aa43c215SJeff Kirsher qlcnic_detach(adapter); 1940aa43c215SJeff Kirsher 194134e8c406SHimanshu Madhani adapter->drv_sds_rings = QLCNIC_SINGLE_RING; 194234e8c406SHimanshu Madhani adapter->drv_tx_rings = QLCNIC_SINGLE_RING; 194379788450SSony Chacko adapter->ahw->diag_test = test; 19444be41e92SSony Chacko adapter->ahw->linkup = 0; 1945aa43c215SJeff Kirsher 1946aa43c215SJeff Kirsher ret = qlcnic_attach(adapter); 1947aa43c215SJeff Kirsher if (ret) { 1948aa43c215SJeff Kirsher netif_device_attach(netdev); 1949aa43c215SJeff Kirsher return ret; 1950aa43c215SJeff Kirsher } 1951aa43c215SJeff Kirsher 1952aa43c215SJeff Kirsher ret = qlcnic_fw_create_ctx(adapter); 1953aa43c215SJeff Kirsher if (ret) { 1954aa43c215SJeff Kirsher qlcnic_detach(adapter); 1955aa43c215SJeff Kirsher netif_device_attach(netdev); 1956aa43c215SJeff Kirsher return ret; 1957aa43c215SJeff Kirsher } 1958aa43c215SJeff Kirsher 1959aa43c215SJeff Kirsher for (ring = 0; ring < adapter->max_rds_rings; ring++) { 1960aa43c215SJeff Kirsher rds_ring = &adapter->recv_ctx->rds_rings[ring]; 19614be41e92SSony Chacko qlcnic_post_rx_buffers(adapter, rds_ring, ring); 1962aa43c215SJeff Kirsher } 1963aa43c215SJeff Kirsher 196479788450SSony Chacko if (adapter->ahw->diag_test == QLCNIC_INTERRUPT_TEST) { 196534e8c406SHimanshu Madhani for (ring = 0; ring < adapter->drv_sds_rings; ring++) { 1966aa43c215SJeff Kirsher sds_ring = &adapter->recv_ctx->sds_rings[ring]; 1967aa43c215SJeff Kirsher qlcnic_enable_int(sds_ring); 1968aa43c215SJeff Kirsher } 1969aa43c215SJeff Kirsher } 1970aa43c215SJeff Kirsher 197179788450SSony Chacko if (adapter->ahw->diag_test == QLCNIC_LOOPBACK_TEST) { 1972aa43c215SJeff Kirsher adapter->ahw->loopback_state = 0; 1973aa43c215SJeff Kirsher qlcnic_linkevent_request(adapter, 1); 1974aa43c215SJeff Kirsher } 1975aa43c215SJeff Kirsher 1976aa43c215SJeff Kirsher set_bit(__QLCNIC_DEV_UP, &adapter->state); 1977aa43c215SJeff Kirsher 1978aa43c215SJeff Kirsher return 0; 1979aa43c215SJeff Kirsher } 1980aa43c215SJeff Kirsher 1981aa43c215SJeff Kirsher /* Reset context in hardware only */ 1982aa43c215SJeff Kirsher static int 1983aa43c215SJeff Kirsher qlcnic_reset_hw_context(struct qlcnic_adapter *adapter) 1984aa43c215SJeff Kirsher { 1985aa43c215SJeff Kirsher struct net_device *netdev = adapter->netdev; 1986aa43c215SJeff Kirsher 1987aa43c215SJeff Kirsher if (test_and_set_bit(__QLCNIC_RESETTING, &adapter->state)) 1988aa43c215SJeff Kirsher return -EBUSY; 1989aa43c215SJeff Kirsher 1990aa43c215SJeff Kirsher netif_device_detach(netdev); 1991aa43c215SJeff Kirsher 1992aa43c215SJeff Kirsher qlcnic_down(adapter, netdev); 1993aa43c215SJeff Kirsher 1994aa43c215SJeff Kirsher qlcnic_up(adapter, netdev); 1995aa43c215SJeff Kirsher 1996aa43c215SJeff Kirsher netif_device_attach(netdev); 1997aa43c215SJeff Kirsher 1998aa43c215SJeff Kirsher clear_bit(__QLCNIC_RESETTING, &adapter->state); 199913159183SSony Chacko dev_err(&adapter->pdev->dev, "%s:\n", __func__); 2000aa43c215SJeff Kirsher return 0; 2001aa43c215SJeff Kirsher } 2002aa43c215SJeff Kirsher 2003aa43c215SJeff Kirsher int 2004aa43c215SJeff Kirsher qlcnic_reset_context(struct qlcnic_adapter *adapter) 2005aa43c215SJeff Kirsher { 2006aa43c215SJeff Kirsher int err = 0; 2007aa43c215SJeff Kirsher struct net_device *netdev = adapter->netdev; 2008aa43c215SJeff Kirsher 2009aa43c215SJeff Kirsher if (test_and_set_bit(__QLCNIC_RESETTING, &adapter->state)) 2010aa43c215SJeff Kirsher return -EBUSY; 2011aa43c215SJeff Kirsher 2012aa43c215SJeff Kirsher if (adapter->is_up == QLCNIC_ADAPTER_UP_MAGIC) { 2013aa43c215SJeff Kirsher 2014aa43c215SJeff Kirsher netif_device_detach(netdev); 2015aa43c215SJeff Kirsher 2016aa43c215SJeff Kirsher if (netif_running(netdev)) 2017aa43c215SJeff Kirsher __qlcnic_down(adapter, netdev); 2018aa43c215SJeff Kirsher 2019aa43c215SJeff Kirsher qlcnic_detach(adapter); 2020aa43c215SJeff Kirsher 2021aa43c215SJeff Kirsher if (netif_running(netdev)) { 2022aa43c215SJeff Kirsher err = qlcnic_attach(adapter); 20231d5c88e3SAnirban Chakraborty if (!err) { 2024aa43c215SJeff Kirsher __qlcnic_up(adapter, netdev); 20251d5c88e3SAnirban Chakraborty qlcnic_restore_indev_addr(netdev, NETDEV_UP); 20261d5c88e3SAnirban Chakraborty } 2027aa43c215SJeff Kirsher } 2028aa43c215SJeff Kirsher 2029aa43c215SJeff Kirsher netif_device_attach(netdev); 2030aa43c215SJeff Kirsher } 2031aa43c215SJeff Kirsher 2032aa43c215SJeff Kirsher clear_bit(__QLCNIC_RESETTING, &adapter->state); 2033aa43c215SJeff Kirsher return err; 2034aa43c215SJeff Kirsher } 2035aa43c215SJeff Kirsher 203652e493d0SJitendra Kalsaria void qlcnic_82xx_set_mac_filter_count(struct qlcnic_adapter *adapter) 203752e493d0SJitendra Kalsaria { 203852e493d0SJitendra Kalsaria struct qlcnic_hardware_context *ahw = adapter->ahw; 203952e493d0SJitendra Kalsaria u16 act_pci_fn = ahw->act_pci_func; 204052e493d0SJitendra Kalsaria u16 count; 204152e493d0SJitendra Kalsaria 204252e493d0SJitendra Kalsaria ahw->max_mc_count = QLCNIC_MAX_MC_COUNT; 204352e493d0SJitendra Kalsaria if (act_pci_fn <= 2) 204452e493d0SJitendra Kalsaria count = (QLCNIC_MAX_UC_COUNT - QLCNIC_MAX_MC_COUNT) / 204552e493d0SJitendra Kalsaria act_pci_fn; 204652e493d0SJitendra Kalsaria else 204752e493d0SJitendra Kalsaria count = (QLCNIC_LB_MAX_FILTERS - QLCNIC_MAX_MC_COUNT) / 204852e493d0SJitendra Kalsaria act_pci_fn; 204952e493d0SJitendra Kalsaria ahw->max_uc_count = count; 205052e493d0SJitendra Kalsaria } 205152e493d0SJitendra Kalsaria 2052f8468331SRajesh Borundia int 20535ad6ff9dSSony Chacko qlcnic_setup_netdev(struct qlcnic_adapter *adapter, struct net_device *netdev, 20545ad6ff9dSSony Chacko int pci_using_dac) 2055aa43c215SJeff Kirsher { 2056aa43c215SJeff Kirsher int err; 2057aa43c215SJeff Kirsher struct pci_dev *pdev = adapter->pdev; 2058aa43c215SJeff Kirsher 205913159183SSony Chacko adapter->rx_csum = 1; 206079788450SSony Chacko adapter->ahw->mc_enabled = 0; 206152e493d0SJitendra Kalsaria qlcnic_set_mac_filter_count(adapter); 2062aa43c215SJeff Kirsher 2063aa43c215SJeff Kirsher netdev->netdev_ops = &qlcnic_netdev_ops; 206413159183SSony Chacko netdev->watchdog_timeo = QLCNIC_WATCHDOG_TIMEOUTVALUE * HZ; 2065aa43c215SJeff Kirsher 2066aa43c215SJeff Kirsher qlcnic_change_mtu(netdev, netdev->mtu); 2067aa43c215SJeff Kirsher 2068d1a1105eSRajesh Borundia if (qlcnic_sriov_vf_check(adapter)) 2069d1a1105eSRajesh Borundia SET_ETHTOOL_OPS(netdev, &qlcnic_sriov_vf_ethtool_ops); 2070d1a1105eSRajesh Borundia else 2071aa43c215SJeff Kirsher SET_ETHTOOL_OPS(netdev, &qlcnic_ethtool_ops); 2072aa43c215SJeff Kirsher 20737e38d04bSSony Chacko netdev->features |= (NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_RXCSUM | 207413159183SSony Chacko NETIF_F_IPV6_CSUM | NETIF_F_GRO | 2075f646968fSPatrick McHardy NETIF_F_HW_VLAN_CTAG_RX); 207613159183SSony Chacko netdev->vlan_features |= (NETIF_F_SG | NETIF_F_IP_CSUM | 207713159183SSony Chacko NETIF_F_IPV6_CSUM); 2078aa43c215SJeff Kirsher 207913159183SSony Chacko if (QLCNIC_IS_TSO_CAPABLE(adapter)) { 208013159183SSony Chacko netdev->features |= (NETIF_F_TSO | NETIF_F_TSO6); 208113159183SSony Chacko netdev->vlan_features |= (NETIF_F_TSO | NETIF_F_TSO6); 208213159183SSony Chacko } 2083aa43c215SJeff Kirsher 208413159183SSony Chacko if (pci_using_dac) { 208513159183SSony Chacko netdev->features |= NETIF_F_HIGHDMA; 208613159183SSony Chacko netdev->vlan_features |= NETIF_F_HIGHDMA; 208713159183SSony Chacko } 2088aa43c215SJeff Kirsher 208913159183SSony Chacko if (qlcnic_vlan_tx_check(adapter)) 2090f646968fSPatrick McHardy netdev->features |= (NETIF_F_HW_VLAN_CTAG_TX); 209113159183SSony Chacko 209291b7282bSRajesh Borundia if (qlcnic_sriov_vf_check(adapter)) 209391b7282bSRajesh Borundia netdev->features |= NETIF_F_HW_VLAN_CTAG_FILTER; 209491b7282bSRajesh Borundia 209579788450SSony Chacko if (adapter->ahw->capabilities & QLCNIC_FW_CAPABILITY_HW_LRO) 209613159183SSony Chacko netdev->features |= NETIF_F_LRO; 2097aa43c215SJeff Kirsher 20987e38d04bSSony Chacko netdev->hw_features = netdev->features; 209952e493d0SJitendra Kalsaria netdev->priv_flags |= IFF_UNICAST_FLT; 2100aa43c215SJeff Kirsher netdev->irq = adapter->msix_entries[0].vector; 2101aa43c215SJeff Kirsher 2102012ec812SHimanshu Madhani err = qlcnic_set_real_num_queues(adapter, netdev); 2103012ec812SHimanshu Madhani if (err) 2104012ec812SHimanshu Madhani return err; 2105012ec812SHimanshu Madhani 2106aa43c215SJeff Kirsher err = register_netdev(netdev); 2107aa43c215SJeff Kirsher if (err) { 2108aa43c215SJeff Kirsher dev_err(&pdev->dev, "failed to register net device\n"); 2109aa43c215SJeff Kirsher return err; 2110aa43c215SJeff Kirsher } 2111aa43c215SJeff Kirsher 21121de899d3SSucheta Chakraborty qlcnic_dcb_init_dcbnl_ops(adapter->dcb); 211348365e48SSucheta Chakraborty 2114aa43c215SJeff Kirsher return 0; 2115aa43c215SJeff Kirsher } 2116aa43c215SJeff Kirsher 21175ad6ff9dSSony Chacko static int qlcnic_set_dma_mask(struct pci_dev *pdev, int *pci_using_dac) 2118aa43c215SJeff Kirsher { 2119aa43c215SJeff Kirsher if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(64)) && 2120aa43c215SJeff Kirsher !pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64))) 2121aa43c215SJeff Kirsher *pci_using_dac = 1; 2122aa43c215SJeff Kirsher else if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(32)) && 2123aa43c215SJeff Kirsher !pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32))) 2124aa43c215SJeff Kirsher *pci_using_dac = 0; 2125aa43c215SJeff Kirsher else { 2126aa43c215SJeff Kirsher dev_err(&pdev->dev, "Unable to set DMA mask, aborting\n"); 2127aa43c215SJeff Kirsher return -EIO; 2128aa43c215SJeff Kirsher } 2129aa43c215SJeff Kirsher 2130aa43c215SJeff Kirsher return 0; 2131aa43c215SJeff Kirsher } 2132aa43c215SJeff Kirsher 21334be41e92SSony Chacko void qlcnic_free_tx_rings(struct qlcnic_adapter *adapter) 21344be41e92SSony Chacko { 21354be41e92SSony Chacko int ring; 21364be41e92SSony Chacko struct qlcnic_host_tx_ring *tx_ring; 21374be41e92SSony Chacko 213834e8c406SHimanshu Madhani for (ring = 0; ring < adapter->drv_tx_rings; ring++) { 21394be41e92SSony Chacko tx_ring = &adapter->tx_ring[ring]; 21404be41e92SSony Chacko if (tx_ring && tx_ring->cmd_buf_arr != NULL) { 21414be41e92SSony Chacko vfree(tx_ring->cmd_buf_arr); 21424be41e92SSony Chacko tx_ring->cmd_buf_arr = NULL; 21434be41e92SSony Chacko } 21444be41e92SSony Chacko } 21454be41e92SSony Chacko if (adapter->tx_ring != NULL) 21464be41e92SSony Chacko kfree(adapter->tx_ring); 21474be41e92SSony Chacko } 21484be41e92SSony Chacko 21494be41e92SSony Chacko int qlcnic_alloc_tx_rings(struct qlcnic_adapter *adapter, 21504be41e92SSony Chacko struct net_device *netdev) 21514be41e92SSony Chacko { 2152b2adaca9SJoe Perches int ring, vector, index; 21534be41e92SSony Chacko struct qlcnic_host_tx_ring *tx_ring; 21544be41e92SSony Chacko struct qlcnic_cmd_buffer *cmd_buf_arr; 21554be41e92SSony Chacko 215634e8c406SHimanshu Madhani tx_ring = kcalloc(adapter->drv_tx_rings, 2157b2adaca9SJoe Perches sizeof(struct qlcnic_host_tx_ring), GFP_KERNEL); 2158b2adaca9SJoe Perches if (tx_ring == NULL) 21594be41e92SSony Chacko return -ENOMEM; 2160b2adaca9SJoe Perches 21614be41e92SSony Chacko adapter->tx_ring = tx_ring; 21624be41e92SSony Chacko 216334e8c406SHimanshu Madhani for (ring = 0; ring < adapter->drv_tx_rings; ring++) { 21644be41e92SSony Chacko tx_ring = &adapter->tx_ring[ring]; 21654be41e92SSony Chacko tx_ring->num_desc = adapter->num_txd; 21664be41e92SSony Chacko tx_ring->txq = netdev_get_tx_queue(netdev, ring); 21674be41e92SSony Chacko cmd_buf_arr = vzalloc(TX_BUFF_RINGSIZE(tx_ring)); 21684be41e92SSony Chacko if (cmd_buf_arr == NULL) { 21694be41e92SSony Chacko qlcnic_free_tx_rings(adapter); 21704be41e92SSony Chacko return -ENOMEM; 21714be41e92SSony Chacko } 21724be41e92SSony Chacko memset(cmd_buf_arr, 0, TX_BUFF_RINGSIZE(tx_ring)); 21734be41e92SSony Chacko tx_ring->cmd_buf_arr = cmd_buf_arr; 21744be41e92SSony Chacko } 21754be41e92SSony Chacko 2176012ec812SHimanshu Madhani if (qlcnic_83xx_check(adapter) || 2177012ec812SHimanshu Madhani (qlcnic_82xx_check(adapter) && qlcnic_check_multi_tx(adapter))) { 217834e8c406SHimanshu Madhani for (ring = 0; ring < adapter->drv_tx_rings; ring++) { 21794be41e92SSony Chacko tx_ring = &adapter->tx_ring[ring]; 21804be41e92SSony Chacko tx_ring->adapter = adapter; 21814be41e92SSony Chacko if (adapter->flags & QLCNIC_MSIX_ENABLED) { 218234e8c406SHimanshu Madhani index = adapter->drv_sds_rings + ring; 21834be41e92SSony Chacko vector = adapter->msix_entries[index].vector; 21844be41e92SSony Chacko tx_ring->irq = vector; 21854be41e92SSony Chacko } 21864be41e92SSony Chacko } 21874be41e92SSony Chacko } 2188012ec812SHimanshu Madhani 21894be41e92SSony Chacko return 0; 21904be41e92SSony Chacko } 21914be41e92SSony Chacko 21928af3f33dSPratik Pujar void qlcnic_set_drv_version(struct qlcnic_adapter *adapter) 21938af3f33dSPratik Pujar { 21948af3f33dSPratik Pujar struct qlcnic_hardware_context *ahw = adapter->ahw; 21958af3f33dSPratik Pujar u32 fw_cmd = 0; 21968af3f33dSPratik Pujar 21978af3f33dSPratik Pujar if (qlcnic_82xx_check(adapter)) 21988af3f33dSPratik Pujar fw_cmd = QLCNIC_CMD_82XX_SET_DRV_VER; 21998af3f33dSPratik Pujar else if (qlcnic_83xx_check(adapter)) 22008af3f33dSPratik Pujar fw_cmd = QLCNIC_CMD_83XX_SET_DRV_VER; 22018af3f33dSPratik Pujar 2202d6994ca7SShahed Shaikh if (ahw->extra_capability[0] & QLCNIC_FW_CAPABILITY_SET_DRV_VER) 22038af3f33dSPratik Pujar qlcnic_fw_cmd_set_drv_version(adapter, fw_cmd); 22048af3f33dSPratik Pujar } 22058af3f33dSPratik Pujar 22066bb58bb0SBill Pemberton static int 2207aa43c215SJeff Kirsher qlcnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) 2208aa43c215SJeff Kirsher { 2209aa43c215SJeff Kirsher struct net_device *netdev = NULL; 2210aa43c215SJeff Kirsher struct qlcnic_adapter *adapter = NULL; 22117e2cf4feSSony Chacko struct qlcnic_hardware_context *ahw; 22125ad6ff9dSSony Chacko int err, pci_using_dac = -1; 22137bc48646SDan Carpenter char board_name[QLCNIC_MAX_BOARD_NAME_LEN + 19]; /* MAC + ": " + name */ 2214aa43c215SJeff Kirsher 2215f8468331SRajesh Borundia if (pdev->is_virtfn) 2216f8468331SRajesh Borundia return -ENODEV; 2217f8468331SRajesh Borundia 2218aa43c215SJeff Kirsher err = pci_enable_device(pdev); 2219aa43c215SJeff Kirsher if (err) 2220aa43c215SJeff Kirsher return err; 2221aa43c215SJeff Kirsher 2222aa43c215SJeff Kirsher if (!(pci_resource_flags(pdev, 0) & IORESOURCE_MEM)) { 2223aa43c215SJeff Kirsher err = -ENODEV; 2224aa43c215SJeff Kirsher goto err_out_disable_pdev; 2225aa43c215SJeff Kirsher } 2226aa43c215SJeff Kirsher 2227aa43c215SJeff Kirsher err = qlcnic_set_dma_mask(pdev, &pci_using_dac); 2228aa43c215SJeff Kirsher if (err) 2229aa43c215SJeff Kirsher goto err_out_disable_pdev; 2230aa43c215SJeff Kirsher 2231aa43c215SJeff Kirsher err = pci_request_regions(pdev, qlcnic_driver_name); 2232aa43c215SJeff Kirsher if (err) 2233aa43c215SJeff Kirsher goto err_out_disable_pdev; 2234aa43c215SJeff Kirsher 2235aa43c215SJeff Kirsher pci_set_master(pdev); 2236aa43c215SJeff Kirsher pci_enable_pcie_error_reporting(pdev); 2237aa43c215SJeff Kirsher 22387e2cf4feSSony Chacko ahw = kzalloc(sizeof(struct qlcnic_hardware_context), GFP_KERNEL); 223902135582SSony Chacko if (!ahw) { 224002135582SSony Chacko err = -ENOMEM; 22417e2cf4feSSony Chacko goto err_out_free_res; 224202135582SSony Chacko } 22437e2cf4feSSony Chacko 2244f8468331SRajesh Borundia switch (ent->device) { 2245f8468331SRajesh Borundia case PCI_DEVICE_ID_QLOGIC_QLE824X: 22467e2cf4feSSony Chacko ahw->hw_ops = &qlcnic_hw_ops; 22477e2cf4feSSony Chacko ahw->reg_tbl = (u32 *) qlcnic_reg_tbl; 2248f8468331SRajesh Borundia break; 2249f8468331SRajesh Borundia case PCI_DEVICE_ID_QLOGIC_QLE834X: 225015ca140fSManish Chopra case PCI_DEVICE_ID_QLOGIC_QLE844X: 225113159183SSony Chacko qlcnic_83xx_register_map(ahw); 2252f8468331SRajesh Borundia break; 2253f8468331SRajesh Borundia case PCI_DEVICE_ID_QLOGIC_VF_QLE834X: 225415ca140fSManish Chopra case PCI_DEVICE_ID_QLOGIC_VF_QLE844X: 2255f8468331SRajesh Borundia qlcnic_sriov_vf_register_map(ahw); 2256f8468331SRajesh Borundia break; 2257f8468331SRajesh Borundia default: 225813159183SSony Chacko goto err_out_free_hw_res; 22597e2cf4feSSony Chacko } 22607e2cf4feSSony Chacko 22617e2cf4feSSony Chacko err = qlcnic_setup_pci_map(pdev, ahw); 22627e2cf4feSSony Chacko if (err) 22637e2cf4feSSony Chacko goto err_out_free_hw_res; 22647e2cf4feSSony Chacko 2265012ec812SHimanshu Madhani netdev = alloc_etherdev_mq(sizeof(struct qlcnic_adapter), 2266012ec812SHimanshu Madhani QLCNIC_MAX_TX_RINGS); 2267aa43c215SJeff Kirsher if (!netdev) { 2268aa43c215SJeff Kirsher err = -ENOMEM; 22697e2cf4feSSony Chacko goto err_out_iounmap; 2270aa43c215SJeff Kirsher } 2271aa43c215SJeff Kirsher 2272aa43c215SJeff Kirsher SET_NETDEV_DEV(netdev, &pdev->dev); 2273aa43c215SJeff Kirsher 2274aa43c215SJeff Kirsher adapter = netdev_priv(netdev); 2275aa43c215SJeff Kirsher adapter->netdev = netdev; 2276aa43c215SJeff Kirsher adapter->pdev = pdev; 227713159183SSony Chacko adapter->ahw = ahw; 227813159183SSony Chacko 227913159183SSony Chacko adapter->qlcnic_wq = create_singlethread_workqueue("qlcnic"); 228013159183SSony Chacko if (adapter->qlcnic_wq == NULL) { 228102135582SSony Chacko err = -ENOMEM; 228213159183SSony Chacko dev_err(&pdev->dev, "Failed to create workqueue\n"); 228313159183SSony Chacko goto err_out_free_netdev; 228413159183SSony Chacko } 2285aa43c215SJeff Kirsher 22862dfc9671SPeter Senna Tschudin err = qlcnic_alloc_adapter_resources(adapter); 22872dfc9671SPeter Senna Tschudin if (err) 22882b1f18a4SWei Yongjun goto err_out_free_wq; 2289aa43c215SJeff Kirsher 2290aa43c215SJeff Kirsher adapter->dev_rst_time = jiffies; 22917e2cf4feSSony Chacko adapter->ahw->revision_id = pdev->revision; 2292fe1adc6bSJitendra Kalsaria if (qlcnic_mac_learn == FDB_MAC_LEARN) 2293fe1adc6bSJitendra Kalsaria adapter->fdb_mac_learn = true; 2294fe1adc6bSJitendra Kalsaria else if (qlcnic_mac_learn == DRV_MAC_LEARN) 2295fe1adc6bSJitendra Kalsaria adapter->drv_mac_learn = true; 2296aa43c215SJeff Kirsher 2297aa43c215SJeff Kirsher rwlock_init(&adapter->ahw->crb_lock); 2298aa43c215SJeff Kirsher mutex_init(&adapter->ahw->mem_lock); 2299aa43c215SJeff Kirsher 230034e8c406SHimanshu Madhani spin_lock_init(&adapter->tx_clean_lock); 2301aa43c215SJeff Kirsher INIT_LIST_HEAD(&adapter->mac_list); 2302aa43c215SJeff Kirsher 230314d385b9SSucheta Chakraborty qlcnic_register_dcb(adapter); 230414d385b9SSucheta Chakraborty 23057e2cf4feSSony Chacko if (qlcnic_82xx_check(adapter)) { 230613159183SSony Chacko qlcnic_check_vf(adapter, ent); 2307aa43c215SJeff Kirsher adapter->portnum = adapter->ahw->pci_func; 23087e2cf4feSSony Chacko err = qlcnic_start_firmware(adapter); 2309aa43c215SJeff Kirsher if (err) { 231066451615SSucheta Chakraborty dev_err(&pdev->dev, "Loading fw failed.Please Reboot\n" 231166451615SSucheta Chakraborty "\t\tIf reboot doesn't help, try flashing the card\n"); 231266451615SSucheta Chakraborty goto err_out_maintenance_mode; 2313aa43c215SJeff Kirsher } 2314aa43c215SJeff Kirsher 231534e8c406SHimanshu Madhani /* compute and set default and max tx/sds rings */ 231634e8c406SHimanshu Madhani if (adapter->ahw->msix_supported) { 231734e8c406SHimanshu Madhani if (qlcnic_check_multi_tx_capability(adapter) == 1) 231834e8c406SHimanshu Madhani qlcnic_set_tx_ring_count(adapter, 231934e8c406SHimanshu Madhani QLCNIC_SINGLE_RING); 232034e8c406SHimanshu Madhani else 232134e8c406SHimanshu Madhani qlcnic_set_tx_ring_count(adapter, 232234e8c406SHimanshu Madhani QLCNIC_DEF_TX_RINGS); 232334e8c406SHimanshu Madhani qlcnic_set_sds_ring_count(adapter, 232434e8c406SHimanshu Madhani QLCNIC_DEF_SDS_RINGS); 232534e8c406SHimanshu Madhani } else { 232634e8c406SHimanshu Madhani qlcnic_set_tx_ring_count(adapter, QLCNIC_SINGLE_RING); 232734e8c406SHimanshu Madhani qlcnic_set_sds_ring_count(adapter, QLCNIC_SINGLE_RING); 2328012ec812SHimanshu Madhani } 2329012ec812SHimanshu Madhani 2330aa43c215SJeff Kirsher err = qlcnic_setup_idc_param(adapter); 2331aa43c215SJeff Kirsher if (err) 23327e2cf4feSSony Chacko goto err_out_free_hw; 2333aa43c215SJeff Kirsher 2334aa43c215SJeff Kirsher adapter->flags |= QLCNIC_NEED_FLR; 233514d385b9SSucheta Chakraborty 233613159183SSony Chacko } else if (qlcnic_83xx_check(adapter)) { 233713159183SSony Chacko qlcnic_83xx_check_vf(adapter, ent); 233813159183SSony Chacko adapter->portnum = adapter->ahw->pci_func; 2339f8468331SRajesh Borundia err = qlcnic_83xx_init(adapter, pci_using_dac); 2340629263acSSony Chacko if (err) { 234178ea2d97SSucheta Chakraborty switch (err) { 234278ea2d97SSucheta Chakraborty case -ENOTRECOVERABLE: 234378ea2d97SSucheta Chakraborty dev_err(&pdev->dev, "Adapter initialization failed due to a faulty hardware. Please reboot\n"); 234478ea2d97SSucheta 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"); 2345629263acSSony Chacko goto err_out_free_hw; 234678ea2d97SSucheta Chakraborty case -ENOMEM: 234778ea2d97SSucheta Chakraborty dev_err(&pdev->dev, "Adapter initialization failed. Please reboot\n"); 234878ea2d97SSucheta Chakraborty goto err_out_free_hw; 234978ea2d97SSucheta Chakraborty default: 235078ea2d97SSucheta Chakraborty dev_err(&pdev->dev, "Adapter initialization failed. A reboot may be required to recover from this failure\n"); 235178ea2d97SSucheta Chakraborty dev_err(&pdev->dev, "If reboot does not help to recover from this failure, try a flash update of the adapter\n"); 235278ea2d97SSucheta Chakraborty goto err_out_maintenance_mode; 2353629263acSSony Chacko } 235478ea2d97SSucheta Chakraborty } 235578ea2d97SSucheta Chakraborty 2356f8468331SRajesh Borundia if (qlcnic_sriov_vf_check(adapter)) 2357f8468331SRajesh Borundia return 0; 235813159183SSony Chacko } else { 235913159183SSony Chacko dev_err(&pdev->dev, 236013159183SSony Chacko "%s: failed. Please Reboot\n", __func__); 236113159183SSony Chacko goto err_out_free_hw; 2362aa43c215SJeff Kirsher } 2363aa43c215SJeff Kirsher 23643c44bba1SSucheta Chakraborty qlcnic_dcb_enable(adapter->dcb); 23653c44bba1SSucheta Chakraborty 2366aa43c215SJeff Kirsher if (qlcnic_read_mac_addr(adapter)) 2367aa43c215SJeff Kirsher dev_warn(&pdev->dev, "failed to read mac addr\n"); 2368aa43c215SJeff Kirsher 236907a251c8SShahed Shaikh qlcnic_read_phys_port_id(adapter); 237007a251c8SShahed Shaikh 2371aa43c215SJeff Kirsher if (adapter->portnum == 0) { 237222999798SSony Chacko qlcnic_get_board_name(adapter, board_name); 237313159183SSony Chacko 2374aa43c215SJeff Kirsher pr_info("%s: %s Board Chip rev 0x%x\n", 2375aa43c215SJeff Kirsher module_name(THIS_MODULE), 237622999798SSony Chacko board_name, adapter->ahw->revision_id); 2377aa43c215SJeff Kirsher } 2378460374f7SHimanshu Madhani 2379460374f7SHimanshu Madhani if (qlcnic_83xx_check(adapter) && !qlcnic_use_msi_x && 2380460374f7SHimanshu Madhani !!qlcnic_use_msi) 2381460374f7SHimanshu Madhani dev_warn(&pdev->dev, 238201b91f4cSPratik Pujar "Device does not support MSI interrupts\n"); 2383460374f7SHimanshu Madhani 2384068a8d19SManish Chopra if (qlcnic_82xx_check(adapter)) { 238534e8c406SHimanshu Madhani err = qlcnic_setup_intr(adapter); 23869a97e705SManish chopra if (err) { 23879a97e705SManish chopra dev_err(&pdev->dev, "Failed to setup interrupt\n"); 23887e2cf4feSSony Chacko goto err_out_disable_msi; 23899a97e705SManish chopra } 239013159183SSony Chacko } 2391aa43c215SJeff Kirsher 239202135582SSony Chacko err = qlcnic_get_act_pci_func(adapter); 239302135582SSony Chacko if (err) 239402135582SSony Chacko goto err_out_disable_mbx_intr; 239502135582SSony Chacko 2396aa43c215SJeff Kirsher err = qlcnic_setup_netdev(adapter, netdev, pci_using_dac); 2397aa43c215SJeff Kirsher if (err) 23987e2cf4feSSony Chacko goto err_out_disable_mbx_intr; 2399aa43c215SJeff Kirsher 240024866d15SHimanshu Madhani if (adapter->portnum == 0) 24018af3f33dSPratik Pujar qlcnic_set_drv_version(adapter); 2402c84e340aSSritej Velaga 2403aa43c215SJeff Kirsher pci_set_drvdata(pdev, adapter); 2404aa43c215SJeff Kirsher 240597ee45ebSSony Chacko if (qlcnic_82xx_check(adapter)) 240697ee45ebSSony Chacko qlcnic_schedule_work(adapter, qlcnic_fw_poll_work, 240797ee45ebSSony Chacko FW_POLL_DELAY); 2408aa43c215SJeff Kirsher 2409aa43c215SJeff Kirsher switch (adapter->ahw->port_type) { 2410aa43c215SJeff Kirsher case QLCNIC_GBE: 2411aa43c215SJeff Kirsher dev_info(&adapter->pdev->dev, "%s: GbE port initialized\n", 2412aa43c215SJeff Kirsher adapter->netdev->name); 2413aa43c215SJeff Kirsher break; 2414aa43c215SJeff Kirsher case QLCNIC_XGBE: 2415aa43c215SJeff Kirsher dev_info(&adapter->pdev->dev, "%s: XGbE port initialized\n", 2416aa43c215SJeff Kirsher adapter->netdev->name); 2417aa43c215SJeff Kirsher break; 2418aa43c215SJeff Kirsher } 2419aa43c215SJeff Kirsher 2420fe1adc6bSJitendra Kalsaria if (adapter->drv_mac_learn) 2421aa43c215SJeff Kirsher qlcnic_alloc_lb_filters_mem(adapter); 2422aa43c215SJeff Kirsher 24237e2cf4feSSony Chacko qlcnic_add_sysfs(adapter); 2424aa43c215SJeff Kirsher 2425aa43c215SJeff Kirsher return 0; 2426aa43c215SJeff Kirsher 24277e2cf4feSSony Chacko err_out_disable_mbx_intr: 24287dd90cf1SSucheta Chakraborty if (qlcnic_83xx_check(adapter)) 242913159183SSony Chacko qlcnic_83xx_free_mbx_intr(adapter); 24307e2cf4feSSony Chacko 2431aa43c215SJeff Kirsher err_out_disable_msi: 2432aa43c215SJeff Kirsher qlcnic_teardown_intr(adapter); 24337e2cf4feSSony Chacko qlcnic_cancel_idc_work(adapter); 2434aa43c215SJeff Kirsher qlcnic_clr_all_drv_state(adapter, 0); 2435aa43c215SJeff Kirsher 2436aa43c215SJeff Kirsher err_out_free_hw: 2437aa43c215SJeff Kirsher qlcnic_free_adapter_resources(adapter); 2438aa43c215SJeff Kirsher 24392b1f18a4SWei Yongjun err_out_free_wq: 24402b1f18a4SWei Yongjun destroy_workqueue(adapter->qlcnic_wq); 24412b1f18a4SWei Yongjun 2442aa43c215SJeff Kirsher err_out_free_netdev: 2443aa43c215SJeff Kirsher free_netdev(netdev); 2444aa43c215SJeff Kirsher 24457e2cf4feSSony Chacko err_out_iounmap: 2446f1a094a8SRajesh Borundia qlcnic_cleanup_pci_map(ahw); 24477e2cf4feSSony Chacko 24487e2cf4feSSony Chacko err_out_free_hw_res: 24497e2cf4feSSony Chacko kfree(ahw); 24507e2cf4feSSony Chacko 2451aa43c215SJeff Kirsher err_out_free_res: 2452aa43c215SJeff Kirsher pci_release_regions(pdev); 2453aa43c215SJeff Kirsher 2454aa43c215SJeff Kirsher err_out_disable_pdev: 2455aa43c215SJeff Kirsher pci_disable_device(pdev); 2456aa43c215SJeff Kirsher return err; 245766451615SSucheta Chakraborty 245866451615SSucheta Chakraborty err_out_maintenance_mode: 245978ea2d97SSucheta Chakraborty set_bit(__QLCNIC_MAINTENANCE_MODE, &adapter->state); 246066451615SSucheta Chakraborty netdev->netdev_ops = &qlcnic_netdev_failed_ops; 246166451615SSucheta Chakraborty SET_ETHTOOL_OPS(netdev, &qlcnic_ethtool_failed_ops); 246278ea2d97SSucheta Chakraborty ahw->port_type = QLCNIC_XGBE; 246378ea2d97SSucheta Chakraborty 246478ea2d97SSucheta Chakraborty if (qlcnic_83xx_check(adapter)) 246578ea2d97SSucheta Chakraborty adapter->tgt_status_reg = NULL; 246678ea2d97SSucheta Chakraborty else 246778ea2d97SSucheta Chakraborty ahw->board_type = QLCNIC_BRDTYPE_P3P_10G_SFP_PLUS; 246878ea2d97SSucheta Chakraborty 246966451615SSucheta Chakraborty err = register_netdev(netdev); 247066451615SSucheta Chakraborty 247166451615SSucheta Chakraborty if (err) { 247266451615SSucheta Chakraborty dev_err(&pdev->dev, "Failed to register net device\n"); 247366451615SSucheta Chakraborty qlcnic_clr_all_drv_state(adapter, 0); 247466451615SSucheta Chakraborty goto err_out_free_hw; 247566451615SSucheta Chakraborty } 247666451615SSucheta Chakraborty 247766451615SSucheta Chakraborty pci_set_drvdata(pdev, adapter); 247866451615SSucheta Chakraborty qlcnic_add_sysfs(adapter); 247966451615SSucheta Chakraborty 248066451615SSucheta Chakraborty return 0; 2481aa43c215SJeff Kirsher } 2482aa43c215SJeff Kirsher 24836bb58bb0SBill Pemberton static void qlcnic_remove(struct pci_dev *pdev) 2484aa43c215SJeff Kirsher { 2485aa43c215SJeff Kirsher struct qlcnic_adapter *adapter; 2486aa43c215SJeff Kirsher struct net_device *netdev; 248713159183SSony Chacko struct qlcnic_hardware_context *ahw; 2488aa43c215SJeff Kirsher 2489aa43c215SJeff Kirsher adapter = pci_get_drvdata(pdev); 2490aa43c215SJeff Kirsher if (adapter == NULL) 2491aa43c215SJeff Kirsher return; 2492aa43c215SJeff Kirsher 2493aa43c215SJeff Kirsher netdev = adapter->netdev; 249402feda17SRajesh Borundia qlcnic_sriov_pf_disable(adapter); 2495aa43c215SJeff Kirsher 249613159183SSony Chacko qlcnic_cancel_idc_work(adapter); 249713159183SSony Chacko ahw = adapter->ahw; 2498aa43c215SJeff Kirsher 2499aa43c215SJeff Kirsher unregister_netdev(netdev); 250002feda17SRajesh Borundia qlcnic_sriov_cleanup(adapter); 2501aa43c215SJeff Kirsher 250213159183SSony Chacko if (qlcnic_83xx_check(adapter)) { 25039b0fff2aSSucheta Chakraborty qlcnic_83xx_initialize_nic(adapter, 0); 25043d73b5fdSJitendra Kalsaria cancel_delayed_work_sync(&adapter->idc_aen_work); 2505068a8d19SManish Chopra qlcnic_83xx_free_mbx_intr(adapter); 2506068a8d19SManish Chopra qlcnic_83xx_detach_mailbox_work(adapter); 2507068a8d19SManish Chopra qlcnic_83xx_free_mailbox(ahw->mailbox); 25087000078aSPratik Pujar kfree(ahw->fw_info); 250913159183SSony Chacko } 251013159183SSony Chacko 25113720bf79SSucheta Chakraborty qlcnic_dcb_free(adapter->dcb); 25123720bf79SSucheta Chakraborty 2513aa43c215SJeff Kirsher qlcnic_detach(adapter); 2514aa43c215SJeff Kirsher 2515aa43c215SJeff Kirsher if (adapter->npars != NULL) 2516aa43c215SJeff Kirsher kfree(adapter->npars); 2517aa43c215SJeff Kirsher if (adapter->eswitch != NULL) 2518aa43c215SJeff Kirsher kfree(adapter->eswitch); 2519aa43c215SJeff Kirsher 252097ee45ebSSony Chacko if (qlcnic_82xx_check(adapter)) 2521aa43c215SJeff Kirsher qlcnic_clr_all_drv_state(adapter, 0); 2522aa43c215SJeff Kirsher 2523aa43c215SJeff Kirsher clear_bit(__QLCNIC_RESETTING, &adapter->state); 2524aa43c215SJeff Kirsher 2525aa43c215SJeff Kirsher qlcnic_free_lb_filters_mem(adapter); 2526aa43c215SJeff Kirsher 2527aa43c215SJeff Kirsher qlcnic_teardown_intr(adapter); 2528aa43c215SJeff Kirsher 252913159183SSony Chacko qlcnic_remove_sysfs(adapter); 2530aa43c215SJeff Kirsher 2531f1a094a8SRajesh Borundia qlcnic_cleanup_pci_map(adapter->ahw); 2532aa43c215SJeff Kirsher 2533aa43c215SJeff Kirsher qlcnic_release_firmware(adapter); 2534aa43c215SJeff Kirsher 2535aa43c215SJeff Kirsher pci_disable_pcie_error_reporting(pdev); 2536aa43c215SJeff Kirsher pci_release_regions(pdev); 2537aa43c215SJeff Kirsher pci_disable_device(pdev); 2538aa43c215SJeff Kirsher 253913159183SSony Chacko if (adapter->qlcnic_wq) { 254013159183SSony Chacko destroy_workqueue(adapter->qlcnic_wq); 254113159183SSony Chacko adapter->qlcnic_wq = NULL; 254213159183SSony Chacko } 254314d385b9SSucheta Chakraborty 2544aa43c215SJeff Kirsher qlcnic_free_adapter_resources(adapter); 254513159183SSony Chacko kfree(ahw); 2546aa43c215SJeff Kirsher free_netdev(netdev); 2547aa43c215SJeff Kirsher } 2548aa43c215SJeff Kirsher 2549aa43c215SJeff Kirsher static void qlcnic_shutdown(struct pci_dev *pdev) 2550aa43c215SJeff Kirsher { 2551aa43c215SJeff Kirsher if (__qlcnic_shutdown(pdev)) 2552aa43c215SJeff Kirsher return; 2553aa43c215SJeff Kirsher 2554aa43c215SJeff Kirsher pci_disable_device(pdev); 2555aa43c215SJeff Kirsher } 2556aa43c215SJeff Kirsher 2557aa43c215SJeff Kirsher #ifdef CONFIG_PM 2558486a5bc7SRajesh Borundia static int qlcnic_suspend(struct pci_dev *pdev, pm_message_t state) 2559aa43c215SJeff Kirsher { 2560aa43c215SJeff Kirsher int retval; 2561aa43c215SJeff Kirsher 2562aa43c215SJeff Kirsher retval = __qlcnic_shutdown(pdev); 2563aa43c215SJeff Kirsher if (retval) 2564aa43c215SJeff Kirsher return retval; 2565aa43c215SJeff Kirsher 2566aa43c215SJeff Kirsher pci_set_power_state(pdev, pci_choose_state(pdev, state)); 2567aa43c215SJeff Kirsher return 0; 2568aa43c215SJeff Kirsher } 2569aa43c215SJeff Kirsher 2570486a5bc7SRajesh Borundia static int qlcnic_resume(struct pci_dev *pdev) 2571aa43c215SJeff Kirsher { 2572aa43c215SJeff Kirsher struct qlcnic_adapter *adapter = pci_get_drvdata(pdev); 2573aa43c215SJeff Kirsher int err; 2574aa43c215SJeff Kirsher 2575aa43c215SJeff Kirsher err = pci_enable_device(pdev); 2576aa43c215SJeff Kirsher if (err) 2577aa43c215SJeff Kirsher return err; 2578aa43c215SJeff Kirsher 2579aa43c215SJeff Kirsher pci_set_power_state(pdev, PCI_D0); 2580aa43c215SJeff Kirsher pci_set_master(pdev); 2581aa43c215SJeff Kirsher pci_restore_state(pdev); 2582aa43c215SJeff Kirsher 2583486a5bc7SRajesh Borundia return __qlcnic_resume(adapter); 2584aa43c215SJeff Kirsher } 2585aa43c215SJeff Kirsher #endif 2586aa43c215SJeff Kirsher 2587aa43c215SJeff Kirsher static int qlcnic_open(struct net_device *netdev) 2588aa43c215SJeff Kirsher { 2589aa43c215SJeff Kirsher struct qlcnic_adapter *adapter = netdev_priv(netdev); 2590aa43c215SJeff Kirsher int err; 2591aa43c215SJeff Kirsher 259278ea2d97SSucheta Chakraborty if (test_bit(__QLCNIC_MAINTENANCE_MODE, &adapter->state)) { 259378ea2d97SSucheta Chakraborty netdev_err(netdev, "%s: Device is in non-operational state\n", 259478ea2d97SSucheta Chakraborty __func__); 259566451615SSucheta Chakraborty 259666451615SSucheta Chakraborty return -EIO; 259766451615SSucheta Chakraborty } 259866451615SSucheta Chakraborty 2599aa43c215SJeff Kirsher netif_carrier_off(netdev); 2600aa43c215SJeff Kirsher 2601aa43c215SJeff Kirsher err = qlcnic_attach(adapter); 2602aa43c215SJeff Kirsher if (err) 2603aa43c215SJeff Kirsher return err; 2604aa43c215SJeff Kirsher 2605aa43c215SJeff Kirsher err = __qlcnic_up(adapter, netdev); 2606aa43c215SJeff Kirsher if (err) 2607aa43c215SJeff Kirsher goto err_out; 2608aa43c215SJeff Kirsher 2609012ec812SHimanshu Madhani netif_tx_start_all_queues(netdev); 2610aa43c215SJeff Kirsher 2611aa43c215SJeff Kirsher return 0; 2612aa43c215SJeff Kirsher 2613aa43c215SJeff Kirsher err_out: 2614aa43c215SJeff Kirsher qlcnic_detach(adapter); 2615aa43c215SJeff Kirsher return err; 2616aa43c215SJeff Kirsher } 2617aa43c215SJeff Kirsher 2618aa43c215SJeff Kirsher /* 2619aa43c215SJeff Kirsher * qlcnic_close - Disables a network interface entry point 2620aa43c215SJeff Kirsher */ 2621aa43c215SJeff Kirsher static int qlcnic_close(struct net_device *netdev) 2622aa43c215SJeff Kirsher { 2623aa43c215SJeff Kirsher struct qlcnic_adapter *adapter = netdev_priv(netdev); 2624aa43c215SJeff Kirsher 2625aa43c215SJeff Kirsher __qlcnic_down(adapter, netdev); 262613159183SSony Chacko 2627aa43c215SJeff Kirsher return 0; 2628aa43c215SJeff Kirsher } 2629aa43c215SJeff Kirsher 2630aa43c215SJeff Kirsher void qlcnic_alloc_lb_filters_mem(struct qlcnic_adapter *adapter) 2631aa43c215SJeff Kirsher { 2632aa43c215SJeff Kirsher void *head; 2633aa43c215SJeff Kirsher int i; 263413159183SSony Chacko struct net_device *netdev = adapter->netdev; 263513159183SSony Chacko u32 filter_size = 0; 263613159183SSony Chacko u16 act_pci_func = 0; 2637aa43c215SJeff Kirsher 2638aa43c215SJeff Kirsher if (adapter->fhash.fmax && adapter->fhash.fhead) 2639aa43c215SJeff Kirsher return; 2640aa43c215SJeff Kirsher 264113159183SSony Chacko act_pci_func = adapter->ahw->act_pci_func; 2642aa43c215SJeff Kirsher spin_lock_init(&adapter->mac_learn_lock); 264353643a75SShahed Shaikh spin_lock_init(&adapter->rx_mac_learn_lock); 2644aa43c215SJeff Kirsher 264513159183SSony Chacko if (qlcnic_82xx_check(adapter)) { 264613159183SSony Chacko filter_size = QLCNIC_LB_MAX_FILTERS; 264713159183SSony Chacko adapter->fhash.fbucket_size = QLCNIC_LB_BUCKET_SIZE; 264813159183SSony Chacko } else { 264913159183SSony Chacko filter_size = QLC_83XX_LB_MAX_FILTERS; 265013159183SSony Chacko adapter->fhash.fbucket_size = QLC_83XX_LB_BUCKET_SIZE; 265113159183SSony Chacko } 265213159183SSony Chacko 265313159183SSony Chacko head = kcalloc(adapter->fhash.fbucket_size, 26541d9219ddSJitendra Kalsaria sizeof(struct hlist_head), GFP_ATOMIC); 265513159183SSony Chacko 2656aa43c215SJeff Kirsher if (!head) 2657aa43c215SJeff Kirsher return; 2658aa43c215SJeff Kirsher 265913159183SSony Chacko adapter->fhash.fmax = (filter_size / act_pci_func); 2660aa43c215SJeff Kirsher adapter->fhash.fhead = head; 2661aa43c215SJeff Kirsher 266213159183SSony Chacko netdev_info(netdev, "active nic func = %d, mac filter size=%d\n", 266313159183SSony Chacko act_pci_func, adapter->fhash.fmax); 266413159183SSony Chacko 266513159183SSony Chacko for (i = 0; i < adapter->fhash.fbucket_size; i++) 2666aa43c215SJeff Kirsher INIT_HLIST_HEAD(&adapter->fhash.fhead[i]); 266753643a75SShahed Shaikh 266853643a75SShahed Shaikh adapter->rx_fhash.fbucket_size = adapter->fhash.fbucket_size; 266953643a75SShahed Shaikh 267053643a75SShahed Shaikh head = kcalloc(adapter->rx_fhash.fbucket_size, 267153643a75SShahed Shaikh sizeof(struct hlist_head), GFP_ATOMIC); 267253643a75SShahed Shaikh 267353643a75SShahed Shaikh if (!head) 267453643a75SShahed Shaikh return; 267553643a75SShahed Shaikh 267653643a75SShahed Shaikh adapter->rx_fhash.fmax = (filter_size / act_pci_func); 267753643a75SShahed Shaikh adapter->rx_fhash.fhead = head; 267853643a75SShahed Shaikh 267953643a75SShahed Shaikh for (i = 0; i < adapter->rx_fhash.fbucket_size; i++) 268053643a75SShahed Shaikh INIT_HLIST_HEAD(&adapter->rx_fhash.fhead[i]); 2681aa43c215SJeff Kirsher } 2682aa43c215SJeff Kirsher 2683aa43c215SJeff Kirsher static void qlcnic_free_lb_filters_mem(struct qlcnic_adapter *adapter) 2684aa43c215SJeff Kirsher { 2685aa43c215SJeff Kirsher if (adapter->fhash.fmax && adapter->fhash.fhead) 2686aa43c215SJeff Kirsher kfree(adapter->fhash.fhead); 2687aa43c215SJeff Kirsher 2688aa43c215SJeff Kirsher adapter->fhash.fhead = NULL; 2689aa43c215SJeff Kirsher adapter->fhash.fmax = 0; 269053643a75SShahed Shaikh 269153643a75SShahed Shaikh if (adapter->rx_fhash.fmax && adapter->rx_fhash.fhead) 269253643a75SShahed Shaikh kfree(adapter->rx_fhash.fhead); 269353643a75SShahed Shaikh 269453643a75SShahed Shaikh adapter->rx_fhash.fmax = 0; 269553643a75SShahed Shaikh adapter->rx_fhash.fhead = NULL; 2696aa43c215SJeff Kirsher } 2697aa43c215SJeff Kirsher 2698629263acSSony Chacko int qlcnic_check_temp(struct qlcnic_adapter *adapter) 2699aa43c215SJeff Kirsher { 2700aa43c215SJeff Kirsher struct net_device *netdev = adapter->netdev; 270197ee45ebSSony Chacko u32 temp_state, temp_val, temp = 0; 2702aa43c215SJeff Kirsher int rv = 0; 2703aa43c215SJeff Kirsher 270413159183SSony Chacko if (qlcnic_83xx_check(adapter)) 270513159183SSony Chacko temp = QLCRDX(adapter->ahw, QLC_83XX_ASIC_TEMP); 270613159183SSony Chacko 270797ee45ebSSony Chacko if (qlcnic_82xx_check(adapter)) 2708a15ebd37SHimanshu Madhani temp = QLC_SHARED_REG_RD32(adapter, QLCNIC_ASIC_TEMP); 2709aa43c215SJeff Kirsher 2710aa43c215SJeff Kirsher temp_state = qlcnic_get_temp_state(temp); 2711aa43c215SJeff Kirsher temp_val = qlcnic_get_temp_val(temp); 2712aa43c215SJeff Kirsher 2713aa43c215SJeff Kirsher if (temp_state == QLCNIC_TEMP_PANIC) { 2714aa43c215SJeff Kirsher dev_err(&netdev->dev, 2715aa43c215SJeff Kirsher "Device temperature %d degrees C exceeds" 2716aa43c215SJeff Kirsher " maximum allowed. Hardware has been shut down.\n", 2717aa43c215SJeff Kirsher temp_val); 2718aa43c215SJeff Kirsher rv = 1; 2719aa43c215SJeff Kirsher } else if (temp_state == QLCNIC_TEMP_WARN) { 272079788450SSony Chacko if (adapter->ahw->temp == QLCNIC_TEMP_NORMAL) { 2721aa43c215SJeff Kirsher dev_err(&netdev->dev, 2722aa43c215SJeff Kirsher "Device temperature %d degrees C " 2723aa43c215SJeff Kirsher "exceeds operating range." 2724aa43c215SJeff Kirsher " Immediate action needed.\n", 2725aa43c215SJeff Kirsher temp_val); 2726aa43c215SJeff Kirsher } 2727aa43c215SJeff Kirsher } else { 272879788450SSony Chacko if (adapter->ahw->temp == QLCNIC_TEMP_WARN) { 2729aa43c215SJeff Kirsher dev_info(&netdev->dev, 2730aa43c215SJeff Kirsher "Device temperature is now %d degrees C" 2731aa43c215SJeff Kirsher " in normal range.\n", temp_val); 2732aa43c215SJeff Kirsher } 2733aa43c215SJeff Kirsher } 273479788450SSony Chacko adapter->ahw->temp = temp_state; 2735aa43c215SJeff Kirsher return rv; 2736aa43c215SJeff Kirsher } 2737aa43c215SJeff Kirsher 2738aa43c215SJeff Kirsher static void qlcnic_tx_timeout(struct net_device *netdev) 2739aa43c215SJeff Kirsher { 2740aa43c215SJeff Kirsher struct qlcnic_adapter *adapter = netdev_priv(netdev); 2741012ec812SHimanshu Madhani struct qlcnic_host_tx_ring *tx_ring; 2742012ec812SHimanshu Madhani int ring; 2743aa43c215SJeff Kirsher 2744aa43c215SJeff Kirsher if (test_bit(__QLCNIC_RESETTING, &adapter->state)) 2745aa43c215SJeff Kirsher return; 2746aa43c215SJeff Kirsher 2747536faa61SSony Chacko if (++adapter->tx_timeo_cnt >= QLCNIC_MAX_TX_TIMEOUTS) { 2748536faa61SSony Chacko netdev_info(netdev, "Tx timeout, reset the adapter.\n"); 2749536faa61SSony Chacko if (qlcnic_82xx_check(adapter)) 2750aa43c215SJeff Kirsher adapter->need_fw_reset = 1; 2751536faa61SSony Chacko else if (qlcnic_83xx_check(adapter)) 2752536faa61SSony Chacko qlcnic_83xx_idc_request_reset(adapter, 2753536faa61SSony Chacko QLCNIC_FORCE_FW_DUMP_KEY); 2754536faa61SSony Chacko } else { 2755536faa61SSony Chacko netdev_info(netdev, "Tx timeout, reset adapter context.\n"); 275634e8c406SHimanshu Madhani for (ring = 0; ring < adapter->drv_tx_rings; ring++) { 2757012ec812SHimanshu Madhani tx_ring = &adapter->tx_ring[ring]; 2758f27c75b3SHimanshu Madhani netdev_info(netdev, "Tx ring=%d\n", ring); 2759f27c75b3SHimanshu Madhani netdev_info(netdev, 2760f27c75b3SHimanshu Madhani "crb_intr_mask=%d, producer=%d, sw_consumer=%d, hw_consumer=%d\n", 2761f27c75b3SHimanshu Madhani readl(tx_ring->crb_intr_mask), 2762f27c75b3SHimanshu Madhani readl(tx_ring->crb_cmd_producer), 2763f27c75b3SHimanshu Madhani tx_ring->sw_consumer, 2764012ec812SHimanshu Madhani le32_to_cpu(*(tx_ring->hw_consumer))); 2765f27c75b3SHimanshu Madhani netdev_info(netdev, 2766f27c75b3SHimanshu Madhani "xmit_finished=%llu, xmit_called=%llu, xmit_on=%llu, xmit_off=%llu\n", 2767f27c75b3SHimanshu Madhani tx_ring->tx_stats.xmit_finished, 2768f27c75b3SHimanshu Madhani tx_ring->tx_stats.xmit_called, 2769f27c75b3SHimanshu Madhani tx_ring->tx_stats.xmit_on, 2770f27c75b3SHimanshu Madhani tx_ring->tx_stats.xmit_off); 2771012ec812SHimanshu Madhani } 277279788450SSony Chacko adapter->ahw->reset_context = 1; 2773aa43c215SJeff Kirsher } 2774536faa61SSony Chacko } 2775aa43c215SJeff Kirsher 2776aa43c215SJeff Kirsher static struct net_device_stats *qlcnic_get_stats(struct net_device *netdev) 2777aa43c215SJeff Kirsher { 2778aa43c215SJeff Kirsher struct qlcnic_adapter *adapter = netdev_priv(netdev); 2779aa43c215SJeff Kirsher struct net_device_stats *stats = &netdev->stats; 2780aa43c215SJeff Kirsher 2781aa43c215SJeff Kirsher stats->rx_packets = adapter->stats.rx_pkts + adapter->stats.lro_pkts; 2782aa43c215SJeff Kirsher stats->tx_packets = adapter->stats.xmitfinished; 2783aa43c215SJeff Kirsher stats->rx_bytes = adapter->stats.rxbytes + adapter->stats.lrobytes; 2784aa43c215SJeff Kirsher stats->tx_bytes = adapter->stats.txbytes; 2785aa43c215SJeff Kirsher stats->rx_dropped = adapter->stats.rxdropped; 2786aa43c215SJeff Kirsher stats->tx_dropped = adapter->stats.txdropped; 2787aa43c215SJeff Kirsher 2788aa43c215SJeff Kirsher return stats; 2789aa43c215SJeff Kirsher } 2790aa43c215SJeff Kirsher 27917e2cf4feSSony Chacko irqreturn_t qlcnic_82xx_clear_legacy_intr(struct qlcnic_adapter *adapter) 2792aa43c215SJeff Kirsher { 2793aa43c215SJeff Kirsher u32 status; 2794aa43c215SJeff Kirsher 2795aa43c215SJeff Kirsher status = readl(adapter->isr_int_vec); 2796aa43c215SJeff Kirsher 279779788450SSony Chacko if (!(status & adapter->ahw->int_vec_bit)) 2798aa43c215SJeff Kirsher return IRQ_NONE; 2799aa43c215SJeff Kirsher 2800aa43c215SJeff Kirsher /* check interrupt state machine, to be sure */ 2801aa43c215SJeff Kirsher status = readl(adapter->crb_int_state_reg); 2802aa43c215SJeff Kirsher if (!ISR_LEGACY_INT_TRIGGERED(status)) 2803aa43c215SJeff Kirsher return IRQ_NONE; 2804aa43c215SJeff Kirsher 2805aa43c215SJeff Kirsher writel(0xffffffff, adapter->tgt_status_reg); 2806aa43c215SJeff Kirsher /* read twice to ensure write is flushed */ 2807aa43c215SJeff Kirsher readl(adapter->isr_int_vec); 2808aa43c215SJeff Kirsher readl(adapter->isr_int_vec); 2809aa43c215SJeff Kirsher 2810aa43c215SJeff Kirsher return IRQ_HANDLED; 2811aa43c215SJeff Kirsher } 2812aa43c215SJeff Kirsher 2813aa43c215SJeff Kirsher static irqreturn_t qlcnic_tmp_intr(int irq, void *data) 2814aa43c215SJeff Kirsher { 2815aa43c215SJeff Kirsher struct qlcnic_host_sds_ring *sds_ring = data; 2816aa43c215SJeff Kirsher struct qlcnic_adapter *adapter = sds_ring->adapter; 2817aa43c215SJeff Kirsher 2818aa43c215SJeff Kirsher if (adapter->flags & QLCNIC_MSIX_ENABLED) 2819aa43c215SJeff Kirsher goto done; 2820aa43c215SJeff Kirsher else if (adapter->flags & QLCNIC_MSI_ENABLED) { 2821aa43c215SJeff Kirsher writel(0xffffffff, adapter->tgt_status_reg); 2822aa43c215SJeff Kirsher goto done; 2823aa43c215SJeff Kirsher } 2824aa43c215SJeff Kirsher 2825aa43c215SJeff Kirsher if (qlcnic_clear_legacy_intr(adapter) == IRQ_NONE) 2826aa43c215SJeff Kirsher return IRQ_NONE; 2827aa43c215SJeff Kirsher 2828aa43c215SJeff Kirsher done: 282979788450SSony Chacko adapter->ahw->diag_cnt++; 2830aa43c215SJeff Kirsher qlcnic_enable_int(sds_ring); 2831aa43c215SJeff Kirsher return IRQ_HANDLED; 2832aa43c215SJeff Kirsher } 2833aa43c215SJeff Kirsher 2834aa43c215SJeff Kirsher static irqreturn_t qlcnic_intr(int irq, void *data) 2835aa43c215SJeff Kirsher { 2836aa43c215SJeff Kirsher struct qlcnic_host_sds_ring *sds_ring = data; 2837aa43c215SJeff Kirsher struct qlcnic_adapter *adapter = sds_ring->adapter; 2838aa43c215SJeff Kirsher 2839aa43c215SJeff Kirsher if (qlcnic_clear_legacy_intr(adapter) == IRQ_NONE) 2840aa43c215SJeff Kirsher return IRQ_NONE; 2841aa43c215SJeff Kirsher 2842aa43c215SJeff Kirsher napi_schedule(&sds_ring->napi); 2843aa43c215SJeff Kirsher 2844aa43c215SJeff Kirsher return IRQ_HANDLED; 2845aa43c215SJeff Kirsher } 2846aa43c215SJeff Kirsher 2847aa43c215SJeff Kirsher static irqreturn_t qlcnic_msi_intr(int irq, void *data) 2848aa43c215SJeff Kirsher { 2849aa43c215SJeff Kirsher struct qlcnic_host_sds_ring *sds_ring = data; 2850aa43c215SJeff Kirsher struct qlcnic_adapter *adapter = sds_ring->adapter; 2851aa43c215SJeff Kirsher 2852aa43c215SJeff Kirsher /* clear interrupt */ 2853aa43c215SJeff Kirsher writel(0xffffffff, adapter->tgt_status_reg); 2854aa43c215SJeff Kirsher 2855aa43c215SJeff Kirsher napi_schedule(&sds_ring->napi); 2856aa43c215SJeff Kirsher return IRQ_HANDLED; 2857aa43c215SJeff Kirsher } 2858aa43c215SJeff Kirsher 2859aa43c215SJeff Kirsher static irqreturn_t qlcnic_msix_intr(int irq, void *data) 2860aa43c215SJeff Kirsher { 2861aa43c215SJeff Kirsher struct qlcnic_host_sds_ring *sds_ring = data; 2862aa43c215SJeff Kirsher 2863aa43c215SJeff Kirsher napi_schedule(&sds_ring->napi); 2864aa43c215SJeff Kirsher return IRQ_HANDLED; 2865aa43c215SJeff Kirsher } 2866aa43c215SJeff Kirsher 286713159183SSony Chacko static irqreturn_t qlcnic_msix_tx_intr(int irq, void *data) 286813159183SSony Chacko { 286913159183SSony Chacko struct qlcnic_host_tx_ring *tx_ring = data; 287013159183SSony Chacko 287113159183SSony Chacko napi_schedule(&tx_ring->napi); 287213159183SSony Chacko return IRQ_HANDLED; 287313159183SSony Chacko } 287413159183SSony Chacko 2875aa43c215SJeff Kirsher #ifdef CONFIG_NET_POLL_CONTROLLER 2876aa43c215SJeff Kirsher static void qlcnic_poll_controller(struct net_device *netdev) 2877aa43c215SJeff Kirsher { 2878aa43c215SJeff Kirsher int ring; 2879aa43c215SJeff Kirsher struct qlcnic_host_sds_ring *sds_ring; 2880aa43c215SJeff Kirsher struct qlcnic_adapter *adapter = netdev_priv(netdev); 2881aa43c215SJeff Kirsher struct qlcnic_recv_context *recv_ctx = adapter->recv_ctx; 2882aa43c215SJeff Kirsher 2883aa43c215SJeff Kirsher disable_irq(adapter->irq); 288434e8c406SHimanshu Madhani for (ring = 0; ring < adapter->drv_sds_rings; ring++) { 2885aa43c215SJeff Kirsher sds_ring = &recv_ctx->sds_rings[ring]; 2886aa43c215SJeff Kirsher qlcnic_intr(adapter->irq, sds_ring); 2887aa43c215SJeff Kirsher } 2888aa43c215SJeff Kirsher enable_irq(adapter->irq); 2889aa43c215SJeff Kirsher } 2890aa43c215SJeff Kirsher #endif 2891aa43c215SJeff Kirsher 2892aa43c215SJeff Kirsher static void 2893aa43c215SJeff Kirsher qlcnic_idc_debug_info(struct qlcnic_adapter *adapter, u8 encoding) 2894aa43c215SJeff Kirsher { 2895aa43c215SJeff Kirsher u32 val; 2896aa43c215SJeff Kirsher 2897aa43c215SJeff Kirsher val = adapter->portnum & 0xf; 2898aa43c215SJeff Kirsher val |= encoding << 7; 2899aa43c215SJeff Kirsher val |= (jiffies - adapter->dev_rst_time) << 8; 2900aa43c215SJeff Kirsher 2901a15ebd37SHimanshu Madhani QLC_SHARED_REG_WR32(adapter, QLCNIC_CRB_DRV_SCRATCH, val); 2902aa43c215SJeff Kirsher adapter->dev_rst_time = jiffies; 2903aa43c215SJeff Kirsher } 2904aa43c215SJeff Kirsher 2905aa43c215SJeff Kirsher static int 2906aa43c215SJeff Kirsher qlcnic_set_drv_state(struct qlcnic_adapter *adapter, u8 state) 2907aa43c215SJeff Kirsher { 2908aa43c215SJeff Kirsher u32 val; 2909aa43c215SJeff Kirsher 2910aa43c215SJeff Kirsher WARN_ON(state != QLCNIC_DEV_NEED_RESET && 2911aa43c215SJeff Kirsher state != QLCNIC_DEV_NEED_QUISCENT); 2912aa43c215SJeff Kirsher 2913aa43c215SJeff Kirsher if (qlcnic_api_lock(adapter)) 2914aa43c215SJeff Kirsher return -EIO; 2915aa43c215SJeff Kirsher 2916a15ebd37SHimanshu Madhani val = QLC_SHARED_REG_RD32(adapter, QLCNIC_CRB_DRV_STATE); 2917aa43c215SJeff Kirsher 2918aa43c215SJeff Kirsher if (state == QLCNIC_DEV_NEED_RESET) 2919aa43c215SJeff Kirsher QLC_DEV_SET_RST_RDY(val, adapter->portnum); 2920aa43c215SJeff Kirsher else if (state == QLCNIC_DEV_NEED_QUISCENT) 2921aa43c215SJeff Kirsher QLC_DEV_SET_QSCNT_RDY(val, adapter->portnum); 2922aa43c215SJeff Kirsher 2923a15ebd37SHimanshu Madhani QLC_SHARED_REG_WR32(adapter, QLCNIC_CRB_DRV_STATE, val); 2924aa43c215SJeff Kirsher 2925aa43c215SJeff Kirsher qlcnic_api_unlock(adapter); 2926aa43c215SJeff Kirsher 2927aa43c215SJeff Kirsher return 0; 2928aa43c215SJeff Kirsher } 2929aa43c215SJeff Kirsher 2930aa43c215SJeff Kirsher static int 2931aa43c215SJeff Kirsher qlcnic_clr_drv_state(struct qlcnic_adapter *adapter) 2932aa43c215SJeff Kirsher { 2933aa43c215SJeff Kirsher u32 val; 2934aa43c215SJeff Kirsher 2935aa43c215SJeff Kirsher if (qlcnic_api_lock(adapter)) 2936aa43c215SJeff Kirsher return -EBUSY; 2937aa43c215SJeff Kirsher 2938a15ebd37SHimanshu Madhani val = QLC_SHARED_REG_RD32(adapter, QLCNIC_CRB_DRV_STATE); 2939aa43c215SJeff Kirsher QLC_DEV_CLR_RST_QSCNT(val, adapter->portnum); 2940a15ebd37SHimanshu Madhani QLC_SHARED_REG_WR32(adapter, QLCNIC_CRB_DRV_STATE, val); 2941aa43c215SJeff Kirsher 2942aa43c215SJeff Kirsher qlcnic_api_unlock(adapter); 2943aa43c215SJeff Kirsher 2944aa43c215SJeff Kirsher return 0; 2945aa43c215SJeff Kirsher } 2946aa43c215SJeff Kirsher 2947486a5bc7SRajesh Borundia void qlcnic_clr_all_drv_state(struct qlcnic_adapter *adapter, u8 failed) 2948aa43c215SJeff Kirsher { 2949aa43c215SJeff Kirsher u32 val; 2950aa43c215SJeff Kirsher 2951aa43c215SJeff Kirsher if (qlcnic_api_lock(adapter)) 2952aa43c215SJeff Kirsher goto err; 2953aa43c215SJeff Kirsher 2954a15ebd37SHimanshu Madhani val = QLC_SHARED_REG_RD32(adapter, QLCNIC_CRB_DRV_ACTIVE); 2955aa43c215SJeff Kirsher QLC_DEV_CLR_REF_CNT(val, adapter->portnum); 2956a15ebd37SHimanshu Madhani QLC_SHARED_REG_WR32(adapter, QLCNIC_CRB_DRV_ACTIVE, val); 2957aa43c215SJeff Kirsher 2958aa43c215SJeff Kirsher if (failed) { 2959a15ebd37SHimanshu Madhani QLC_SHARED_REG_WR32(adapter, QLCNIC_CRB_DEV_STATE, 2960a15ebd37SHimanshu Madhani QLCNIC_DEV_FAILED); 2961aa43c215SJeff Kirsher dev_info(&adapter->pdev->dev, 2962aa43c215SJeff Kirsher "Device state set to Failed. Please Reboot\n"); 2963aa43c215SJeff Kirsher } else if (!(val & 0x11111111)) 2964a15ebd37SHimanshu Madhani QLC_SHARED_REG_WR32(adapter, QLCNIC_CRB_DEV_STATE, 2965a15ebd37SHimanshu Madhani QLCNIC_DEV_COLD); 2966aa43c215SJeff Kirsher 2967a15ebd37SHimanshu Madhani val = QLC_SHARED_REG_RD32(adapter, QLCNIC_CRB_DRV_STATE); 2968aa43c215SJeff Kirsher QLC_DEV_CLR_RST_QSCNT(val, adapter->portnum); 2969a15ebd37SHimanshu Madhani QLC_SHARED_REG_WR32(adapter, QLCNIC_CRB_DRV_STATE, val); 2970aa43c215SJeff Kirsher 2971aa43c215SJeff Kirsher qlcnic_api_unlock(adapter); 2972aa43c215SJeff Kirsher err: 2973aa43c215SJeff Kirsher adapter->fw_fail_cnt = 0; 2974aa43c215SJeff Kirsher adapter->flags &= ~QLCNIC_FW_HANG; 2975aa43c215SJeff Kirsher clear_bit(__QLCNIC_START_FW, &adapter->state); 2976aa43c215SJeff Kirsher clear_bit(__QLCNIC_RESETTING, &adapter->state); 2977aa43c215SJeff Kirsher } 2978aa43c215SJeff Kirsher 2979aa43c215SJeff Kirsher /* Grab api lock, before checking state */ 2980aa43c215SJeff Kirsher static int 2981aa43c215SJeff Kirsher qlcnic_check_drv_state(struct qlcnic_adapter *adapter) 2982aa43c215SJeff Kirsher { 2983aa43c215SJeff Kirsher int act, state, active_mask; 2984a15ebd37SHimanshu Madhani struct qlcnic_hardware_context *ahw = adapter->ahw; 2985aa43c215SJeff Kirsher 2986a15ebd37SHimanshu Madhani state = QLC_SHARED_REG_RD32(adapter, QLCNIC_CRB_DRV_STATE); 2987a15ebd37SHimanshu Madhani act = QLC_SHARED_REG_RD32(adapter, QLCNIC_CRB_DRV_ACTIVE); 2988aa43c215SJeff Kirsher 2989aa43c215SJeff Kirsher if (adapter->flags & QLCNIC_FW_RESET_OWNER) { 2990a15ebd37SHimanshu Madhani active_mask = (~(1 << (ahw->pci_func * 4))); 2991aa43c215SJeff Kirsher act = act & active_mask; 2992aa43c215SJeff Kirsher } 2993aa43c215SJeff Kirsher 2994aa43c215SJeff Kirsher if (((state & 0x11111111) == (act & 0x11111111)) || 2995aa43c215SJeff Kirsher ((act & 0x11111111) == ((state >> 1) & 0x11111111))) 2996aa43c215SJeff Kirsher return 0; 2997aa43c215SJeff Kirsher else 2998aa43c215SJeff Kirsher return 1; 2999aa43c215SJeff Kirsher } 3000aa43c215SJeff Kirsher 3001aa43c215SJeff Kirsher static int qlcnic_check_idc_ver(struct qlcnic_adapter *adapter) 3002aa43c215SJeff Kirsher { 3003a15ebd37SHimanshu Madhani u32 val = QLC_SHARED_REG_RD32(adapter, QLCNIC_CRB_DRV_IDC_VER); 3004aa43c215SJeff Kirsher 3005aa43c215SJeff Kirsher if (val != QLCNIC_DRV_IDC_VER) { 3006aa43c215SJeff Kirsher dev_warn(&adapter->pdev->dev, "IDC Version mismatch, driver's" 3007aa43c215SJeff Kirsher " idc ver = %x; reqd = %x\n", QLCNIC_DRV_IDC_VER, val); 3008aa43c215SJeff Kirsher } 3009aa43c215SJeff Kirsher 3010aa43c215SJeff Kirsher return 0; 3011aa43c215SJeff Kirsher } 3012aa43c215SJeff Kirsher 3013aa43c215SJeff Kirsher static int 3014aa43c215SJeff Kirsher qlcnic_can_start_firmware(struct qlcnic_adapter *adapter) 3015aa43c215SJeff Kirsher { 3016aa43c215SJeff Kirsher u32 val, prev_state; 3017aa43c215SJeff Kirsher u8 dev_init_timeo = adapter->dev_init_timeo; 3018aa43c215SJeff Kirsher u8 portnum = adapter->portnum; 3019aa43c215SJeff Kirsher u8 ret; 3020aa43c215SJeff Kirsher 3021aa43c215SJeff Kirsher if (test_and_clear_bit(__QLCNIC_START_FW, &adapter->state)) 3022aa43c215SJeff Kirsher return 1; 3023aa43c215SJeff Kirsher 3024aa43c215SJeff Kirsher if (qlcnic_api_lock(adapter)) 3025aa43c215SJeff Kirsher return -1; 3026aa43c215SJeff Kirsher 3027a15ebd37SHimanshu Madhani val = QLC_SHARED_REG_RD32(adapter, QLCNIC_CRB_DRV_ACTIVE); 3028aa43c215SJeff Kirsher if (!(val & (1 << (portnum * 4)))) { 3029aa43c215SJeff Kirsher QLC_DEV_SET_REF_CNT(val, portnum); 3030a15ebd37SHimanshu Madhani QLC_SHARED_REG_WR32(adapter, QLCNIC_CRB_DRV_ACTIVE, val); 3031aa43c215SJeff Kirsher } 3032aa43c215SJeff Kirsher 3033a15ebd37SHimanshu Madhani prev_state = QLC_SHARED_REG_RD32(adapter, QLCNIC_CRB_DEV_STATE); 3034aa43c215SJeff Kirsher QLCDB(adapter, HW, "Device state = %u\n", prev_state); 3035aa43c215SJeff Kirsher 3036aa43c215SJeff Kirsher switch (prev_state) { 3037aa43c215SJeff Kirsher case QLCNIC_DEV_COLD: 3038a15ebd37SHimanshu Madhani QLC_SHARED_REG_WR32(adapter, QLCNIC_CRB_DEV_STATE, 3039a15ebd37SHimanshu Madhani QLCNIC_DEV_INITIALIZING); 3040a15ebd37SHimanshu Madhani QLC_SHARED_REG_WR32(adapter, QLCNIC_CRB_DRV_IDC_VER, 3041a15ebd37SHimanshu Madhani QLCNIC_DRV_IDC_VER); 3042aa43c215SJeff Kirsher qlcnic_idc_debug_info(adapter, 0); 3043aa43c215SJeff Kirsher qlcnic_api_unlock(adapter); 3044aa43c215SJeff Kirsher return 1; 3045aa43c215SJeff Kirsher 3046aa43c215SJeff Kirsher case QLCNIC_DEV_READY: 3047aa43c215SJeff Kirsher ret = qlcnic_check_idc_ver(adapter); 3048aa43c215SJeff Kirsher qlcnic_api_unlock(adapter); 3049aa43c215SJeff Kirsher return ret; 3050aa43c215SJeff Kirsher 3051aa43c215SJeff Kirsher case QLCNIC_DEV_NEED_RESET: 3052a15ebd37SHimanshu Madhani val = QLC_SHARED_REG_RD32(adapter, QLCNIC_CRB_DRV_STATE); 3053aa43c215SJeff Kirsher QLC_DEV_SET_RST_RDY(val, portnum); 3054a15ebd37SHimanshu Madhani QLC_SHARED_REG_WR32(adapter, QLCNIC_CRB_DRV_STATE, val); 3055aa43c215SJeff Kirsher break; 3056aa43c215SJeff Kirsher 3057aa43c215SJeff Kirsher case QLCNIC_DEV_NEED_QUISCENT: 3058a15ebd37SHimanshu Madhani val = QLC_SHARED_REG_RD32(adapter, QLCNIC_CRB_DRV_STATE); 3059aa43c215SJeff Kirsher QLC_DEV_SET_QSCNT_RDY(val, portnum); 3060a15ebd37SHimanshu Madhani QLC_SHARED_REG_WR32(adapter, QLCNIC_CRB_DRV_STATE, val); 3061aa43c215SJeff Kirsher break; 3062aa43c215SJeff Kirsher 3063aa43c215SJeff Kirsher case QLCNIC_DEV_FAILED: 3064aa43c215SJeff Kirsher dev_err(&adapter->pdev->dev, "Device in failed state.\n"); 3065aa43c215SJeff Kirsher qlcnic_api_unlock(adapter); 3066aa43c215SJeff Kirsher return -1; 3067aa43c215SJeff Kirsher 3068aa43c215SJeff Kirsher case QLCNIC_DEV_INITIALIZING: 3069aa43c215SJeff Kirsher case QLCNIC_DEV_QUISCENT: 3070aa43c215SJeff Kirsher break; 3071aa43c215SJeff Kirsher } 3072aa43c215SJeff Kirsher 3073aa43c215SJeff Kirsher qlcnic_api_unlock(adapter); 3074aa43c215SJeff Kirsher 3075aa43c215SJeff Kirsher do { 3076aa43c215SJeff Kirsher msleep(1000); 3077a15ebd37SHimanshu Madhani prev_state = QLC_SHARED_REG_RD32(adapter, QLCNIC_CRB_DEV_STATE); 3078aa43c215SJeff Kirsher 3079aa43c215SJeff Kirsher if (prev_state == QLCNIC_DEV_QUISCENT) 3080aa43c215SJeff Kirsher continue; 3081aa43c215SJeff Kirsher } while ((prev_state != QLCNIC_DEV_READY) && --dev_init_timeo); 3082aa43c215SJeff Kirsher 3083aa43c215SJeff Kirsher if (!dev_init_timeo) { 3084aa43c215SJeff Kirsher dev_err(&adapter->pdev->dev, 3085aa43c215SJeff Kirsher "Waiting for device to initialize timeout\n"); 3086aa43c215SJeff Kirsher return -1; 3087aa43c215SJeff Kirsher } 3088aa43c215SJeff Kirsher 3089aa43c215SJeff Kirsher if (qlcnic_api_lock(adapter)) 3090aa43c215SJeff Kirsher return -1; 3091aa43c215SJeff Kirsher 3092a15ebd37SHimanshu Madhani val = QLC_SHARED_REG_RD32(adapter, QLCNIC_CRB_DRV_STATE); 3093aa43c215SJeff Kirsher QLC_DEV_CLR_RST_QSCNT(val, portnum); 3094a15ebd37SHimanshu Madhani QLC_SHARED_REG_WR32(adapter, QLCNIC_CRB_DRV_STATE, val); 3095aa43c215SJeff Kirsher 3096aa43c215SJeff Kirsher ret = qlcnic_check_idc_ver(adapter); 3097aa43c215SJeff Kirsher qlcnic_api_unlock(adapter); 3098aa43c215SJeff Kirsher 3099aa43c215SJeff Kirsher return ret; 3100aa43c215SJeff Kirsher } 3101aa43c215SJeff Kirsher 3102aa43c215SJeff Kirsher static void 3103aa43c215SJeff Kirsher qlcnic_fwinit_work(struct work_struct *work) 3104aa43c215SJeff Kirsher { 3105aa43c215SJeff Kirsher struct qlcnic_adapter *adapter = container_of(work, 3106aa43c215SJeff Kirsher struct qlcnic_adapter, fw_work.work); 3107aa43c215SJeff Kirsher u32 dev_state = 0xf; 3108aa43c215SJeff Kirsher u32 val; 3109aa43c215SJeff Kirsher 3110aa43c215SJeff Kirsher if (qlcnic_api_lock(adapter)) 3111aa43c215SJeff Kirsher goto err_ret; 3112aa43c215SJeff Kirsher 3113a15ebd37SHimanshu Madhani dev_state = QLC_SHARED_REG_RD32(adapter, QLCNIC_CRB_DEV_STATE); 3114aa43c215SJeff Kirsher if (dev_state == QLCNIC_DEV_QUISCENT || 3115aa43c215SJeff Kirsher dev_state == QLCNIC_DEV_NEED_QUISCENT) { 3116aa43c215SJeff Kirsher qlcnic_api_unlock(adapter); 3117aa43c215SJeff Kirsher qlcnic_schedule_work(adapter, qlcnic_fwinit_work, 3118aa43c215SJeff Kirsher FW_POLL_DELAY * 2); 3119aa43c215SJeff Kirsher return; 3120aa43c215SJeff Kirsher } 3121aa43c215SJeff Kirsher 312279788450SSony Chacko if (adapter->ahw->op_mode == QLCNIC_NON_PRIV_FUNC) { 3123aa43c215SJeff Kirsher qlcnic_api_unlock(adapter); 3124aa43c215SJeff Kirsher goto wait_npar; 3125aa43c215SJeff Kirsher } 3126aa43c215SJeff Kirsher 312716e3cf73SSritej Velaga if (dev_state == QLCNIC_DEV_INITIALIZING || 312816e3cf73SSritej Velaga dev_state == QLCNIC_DEV_READY) { 312916e3cf73SSritej Velaga dev_info(&adapter->pdev->dev, "Detected state change from " 313016e3cf73SSritej Velaga "DEV_NEED_RESET, skipping ack check\n"); 313116e3cf73SSritej Velaga goto skip_ack_check; 313216e3cf73SSritej Velaga } 313316e3cf73SSritej Velaga 3134aa43c215SJeff Kirsher if (adapter->fw_wait_cnt++ > adapter->reset_ack_timeo) { 313516e3cf73SSritej Velaga dev_info(&adapter->pdev->dev, "Reset:Failed to get ack %d sec\n", 3136aa43c215SJeff Kirsher adapter->reset_ack_timeo); 3137aa43c215SJeff Kirsher goto skip_ack_check; 3138aa43c215SJeff Kirsher } 3139aa43c215SJeff Kirsher 3140aa43c215SJeff Kirsher if (!qlcnic_check_drv_state(adapter)) { 3141aa43c215SJeff Kirsher skip_ack_check: 3142a15ebd37SHimanshu Madhani dev_state = QLC_SHARED_REG_RD32(adapter, QLCNIC_CRB_DEV_STATE); 3143aa43c215SJeff Kirsher 3144aa43c215SJeff Kirsher if (dev_state == QLCNIC_DEV_NEED_RESET) { 3145a15ebd37SHimanshu Madhani QLC_SHARED_REG_WR32(adapter, QLCNIC_CRB_DEV_STATE, 3146aa43c215SJeff Kirsher QLCNIC_DEV_INITIALIZING); 3147aa43c215SJeff Kirsher set_bit(__QLCNIC_START_FW, &adapter->state); 3148aa43c215SJeff Kirsher QLCDB(adapter, DRV, "Restarting fw\n"); 3149aa43c215SJeff Kirsher qlcnic_idc_debug_info(adapter, 0); 3150a15ebd37SHimanshu Madhani val = QLC_SHARED_REG_RD32(adapter, 3151a15ebd37SHimanshu Madhani QLCNIC_CRB_DRV_STATE); 3152aa43c215SJeff Kirsher QLC_DEV_SET_RST_RDY(val, adapter->portnum); 3153a15ebd37SHimanshu Madhani QLC_SHARED_REG_WR32(adapter, 3154a15ebd37SHimanshu Madhani QLCNIC_CRB_DRV_STATE, val); 3155aa43c215SJeff Kirsher } 3156aa43c215SJeff Kirsher 3157aa43c215SJeff Kirsher qlcnic_api_unlock(adapter); 3158aa43c215SJeff Kirsher 3159aa43c215SJeff Kirsher rtnl_lock(); 3160890b6e02SShahed Shaikh if (qlcnic_check_fw_dump_state(adapter) && 3161aa43c215SJeff Kirsher (adapter->flags & QLCNIC_FW_RESET_OWNER)) { 3162aa43c215SJeff Kirsher QLCDB(adapter, DRV, "Take FW dump\n"); 3163aa43c215SJeff Kirsher qlcnic_dump_fw(adapter); 3164aa43c215SJeff Kirsher adapter->flags |= QLCNIC_FW_HANG; 3165aa43c215SJeff Kirsher } 3166aa43c215SJeff Kirsher rtnl_unlock(); 3167aa43c215SJeff Kirsher 3168aa43c215SJeff Kirsher adapter->flags &= ~QLCNIC_FW_RESET_OWNER; 3169aa43c215SJeff Kirsher if (!adapter->nic_ops->start_firmware(adapter)) { 3170aa43c215SJeff Kirsher qlcnic_schedule_work(adapter, qlcnic_attach_work, 0); 3171aa43c215SJeff Kirsher adapter->fw_wait_cnt = 0; 3172aa43c215SJeff Kirsher return; 3173aa43c215SJeff Kirsher } 3174aa43c215SJeff Kirsher goto err_ret; 3175aa43c215SJeff Kirsher } 3176aa43c215SJeff Kirsher 3177aa43c215SJeff Kirsher qlcnic_api_unlock(adapter); 3178aa43c215SJeff Kirsher 3179aa43c215SJeff Kirsher wait_npar: 3180a15ebd37SHimanshu Madhani dev_state = QLC_SHARED_REG_RD32(adapter, QLCNIC_CRB_DEV_STATE); 3181aa43c215SJeff Kirsher QLCDB(adapter, HW, "Func waiting: Device state=%u\n", dev_state); 3182aa43c215SJeff Kirsher 3183aa43c215SJeff Kirsher switch (dev_state) { 3184aa43c215SJeff Kirsher case QLCNIC_DEV_READY: 31857e2cf4feSSony Chacko if (!qlcnic_start_firmware(adapter)) { 3186aa43c215SJeff Kirsher qlcnic_schedule_work(adapter, qlcnic_attach_work, 0); 3187aa43c215SJeff Kirsher adapter->fw_wait_cnt = 0; 3188aa43c215SJeff Kirsher return; 3189aa43c215SJeff Kirsher } 3190aa43c215SJeff Kirsher case QLCNIC_DEV_FAILED: 3191aa43c215SJeff Kirsher break; 3192aa43c215SJeff Kirsher default: 3193aa43c215SJeff Kirsher qlcnic_schedule_work(adapter, 3194aa43c215SJeff Kirsher qlcnic_fwinit_work, FW_POLL_DELAY); 3195aa43c215SJeff Kirsher return; 3196aa43c215SJeff Kirsher } 3197aa43c215SJeff Kirsher 3198aa43c215SJeff Kirsher err_ret: 3199aa43c215SJeff Kirsher dev_err(&adapter->pdev->dev, "Fwinit work failed state=%u " 3200aa43c215SJeff Kirsher "fw_wait_cnt=%u\n", dev_state, adapter->fw_wait_cnt); 3201aa43c215SJeff Kirsher netif_device_attach(adapter->netdev); 3202aa43c215SJeff Kirsher qlcnic_clr_all_drv_state(adapter, 0); 3203aa43c215SJeff Kirsher } 3204aa43c215SJeff Kirsher 3205aa43c215SJeff Kirsher static void 3206aa43c215SJeff Kirsher qlcnic_detach_work(struct work_struct *work) 3207aa43c215SJeff Kirsher { 3208aa43c215SJeff Kirsher struct qlcnic_adapter *adapter = container_of(work, 3209aa43c215SJeff Kirsher struct qlcnic_adapter, fw_work.work); 3210aa43c215SJeff Kirsher struct net_device *netdev = adapter->netdev; 3211aa43c215SJeff Kirsher u32 status; 3212aa43c215SJeff Kirsher 3213aa43c215SJeff Kirsher netif_device_detach(netdev); 3214aa43c215SJeff Kirsher 3215aa43c215SJeff Kirsher /* Dont grab rtnl lock during Quiscent mode */ 3216aa43c215SJeff Kirsher if (adapter->dev_state == QLCNIC_DEV_NEED_QUISCENT) { 3217aa43c215SJeff Kirsher if (netif_running(netdev)) 3218aa43c215SJeff Kirsher __qlcnic_down(adapter, netdev); 3219aa43c215SJeff Kirsher } else 3220aa43c215SJeff Kirsher qlcnic_down(adapter, netdev); 3221aa43c215SJeff Kirsher 3222a15ebd37SHimanshu Madhani status = QLC_SHARED_REG_RD32(adapter, QLCNIC_PEG_HALT_STATUS1); 3223aa43c215SJeff Kirsher 322444f65b29SSony Chacko if (status & QLCNIC_RCODE_FATAL_ERROR) { 322544f65b29SSony Chacko dev_err(&adapter->pdev->dev, 322644f65b29SSony Chacko "Detaching the device: peg halt status1=0x%x\n", 322744f65b29SSony Chacko status); 3228aa43c215SJeff Kirsher 322944f65b29SSony Chacko if (QLCNIC_FWERROR_CODE(status) == QLCNIC_FWERROR_FAN_FAILURE) { 323044f65b29SSony Chacko dev_err(&adapter->pdev->dev, 323144f65b29SSony Chacko "On board active cooling fan failed. " 323244f65b29SSony Chacko "Device has been halted.\n"); 323344f65b29SSony Chacko dev_err(&adapter->pdev->dev, 323444f65b29SSony Chacko "Replace the adapter.\n"); 323544f65b29SSony Chacko } 323644f65b29SSony Chacko 3237aa43c215SJeff Kirsher goto err_ret; 323844f65b29SSony Chacko } 323944f65b29SSony Chacko 324079788450SSony Chacko if (adapter->ahw->temp == QLCNIC_TEMP_PANIC) { 324144f65b29SSony Chacko dev_err(&adapter->pdev->dev, "Detaching the device: temp=%d\n", 324279788450SSony Chacko adapter->ahw->temp); 324344f65b29SSony Chacko goto err_ret; 324444f65b29SSony Chacko } 324544f65b29SSony Chacko 3246aa43c215SJeff Kirsher /* Dont ack if this instance is the reset owner */ 3247aa43c215SJeff Kirsher if (!(adapter->flags & QLCNIC_FW_RESET_OWNER)) { 324844f65b29SSony Chacko if (qlcnic_set_drv_state(adapter, adapter->dev_state)) { 324944f65b29SSony Chacko dev_err(&adapter->pdev->dev, 325044f65b29SSony Chacko "Failed to set driver state," 325144f65b29SSony Chacko "detaching the device.\n"); 3252aa43c215SJeff Kirsher goto err_ret; 3253aa43c215SJeff Kirsher } 325444f65b29SSony Chacko } 3255aa43c215SJeff Kirsher 3256aa43c215SJeff Kirsher adapter->fw_wait_cnt = 0; 3257aa43c215SJeff Kirsher 3258aa43c215SJeff Kirsher qlcnic_schedule_work(adapter, qlcnic_fwinit_work, FW_POLL_DELAY); 3259aa43c215SJeff Kirsher 3260aa43c215SJeff Kirsher return; 3261aa43c215SJeff Kirsher 3262aa43c215SJeff Kirsher err_ret: 3263aa43c215SJeff Kirsher netif_device_attach(netdev); 3264aa43c215SJeff Kirsher qlcnic_clr_all_drv_state(adapter, 1); 3265aa43c215SJeff Kirsher } 3266aa43c215SJeff Kirsher 3267aa43c215SJeff Kirsher /*Transit NPAR state to NON Operational */ 3268aa43c215SJeff Kirsher static void 3269aa43c215SJeff Kirsher qlcnic_set_npar_non_operational(struct qlcnic_adapter *adapter) 3270aa43c215SJeff Kirsher { 3271aa43c215SJeff Kirsher u32 state; 3272aa43c215SJeff Kirsher 3273a15ebd37SHimanshu Madhani state = QLC_SHARED_REG_RD32(adapter, QLCNIC_CRB_DEV_NPAR_STATE); 3274aa43c215SJeff Kirsher if (state == QLCNIC_DEV_NPAR_NON_OPER) 3275aa43c215SJeff Kirsher return; 3276aa43c215SJeff Kirsher 3277aa43c215SJeff Kirsher if (qlcnic_api_lock(adapter)) 3278aa43c215SJeff Kirsher return; 3279a15ebd37SHimanshu Madhani QLC_SHARED_REG_WR32(adapter, QLCNIC_CRB_DEV_NPAR_STATE, 3280a15ebd37SHimanshu Madhani QLCNIC_DEV_NPAR_NON_OPER); 3281aa43c215SJeff Kirsher qlcnic_api_unlock(adapter); 3282aa43c215SJeff Kirsher } 3283aa43c215SJeff Kirsher 32847e2cf4feSSony Chacko void qlcnic_82xx_dev_request_reset(struct qlcnic_adapter *adapter, u32 key) 3285aa43c215SJeff Kirsher { 3286646779f1SSritej Velaga u32 state, xg_val = 0, gb_val = 0; 3287aa43c215SJeff Kirsher 3288646779f1SSritej Velaga qlcnic_xg_set_xg0_mask(xg_val); 3289646779f1SSritej Velaga qlcnic_xg_set_xg1_mask(xg_val); 3290646779f1SSritej Velaga QLCWR32(adapter, QLCNIC_NIU_XG_PAUSE_CTL, xg_val); 3291646779f1SSritej Velaga qlcnic_gb_set_gb0_mask(gb_val); 3292646779f1SSritej Velaga qlcnic_gb_set_gb1_mask(gb_val); 3293646779f1SSritej Velaga qlcnic_gb_set_gb2_mask(gb_val); 3294646779f1SSritej Velaga qlcnic_gb_set_gb3_mask(gb_val); 3295646779f1SSritej Velaga QLCWR32(adapter, QLCNIC_NIU_GB_PAUSE_CTL, gb_val); 3296646779f1SSritej Velaga dev_info(&adapter->pdev->dev, "Pause control frames disabled" 3297646779f1SSritej Velaga " on all ports\n"); 3298aa43c215SJeff Kirsher adapter->need_fw_reset = 1; 329913159183SSony Chacko 3300aa43c215SJeff Kirsher if (qlcnic_api_lock(adapter)) 3301aa43c215SJeff Kirsher return; 3302aa43c215SJeff Kirsher 330313159183SSony Chacko state = QLC_SHARED_REG_RD32(adapter, QLCNIC_CRB_DEV_STATE); 330478ea2d97SSucheta Chakraborty 330578ea2d97SSucheta Chakraborty if (test_bit(__QLCNIC_MAINTENANCE_MODE, &adapter->state)) { 330678ea2d97SSucheta Chakraborty netdev_err(adapter->netdev, "%s: Device is in non-operational state\n", 330766451615SSucheta Chakraborty __func__); 330866451615SSucheta Chakraborty qlcnic_api_unlock(adapter); 330966451615SSucheta Chakraborty 331066451615SSucheta Chakraborty return; 331166451615SSucheta Chakraborty } 3312aa43c215SJeff Kirsher 3313aa43c215SJeff Kirsher if (state == QLCNIC_DEV_READY) { 331413159183SSony Chacko QLC_SHARED_REG_WR32(adapter, QLCNIC_CRB_DEV_STATE, 331513159183SSony Chacko QLCNIC_DEV_NEED_RESET); 3316aa43c215SJeff Kirsher adapter->flags |= QLCNIC_FW_RESET_OWNER; 3317aa43c215SJeff Kirsher QLCDB(adapter, DRV, "NEED_RESET state set\n"); 3318aa43c215SJeff Kirsher qlcnic_idc_debug_info(adapter, 0); 3319aa43c215SJeff Kirsher } 3320aa43c215SJeff Kirsher 332113159183SSony Chacko QLC_SHARED_REG_WR32(adapter, QLCNIC_CRB_DEV_NPAR_STATE, 332213159183SSony Chacko QLCNIC_DEV_NPAR_NON_OPER); 3323aa43c215SJeff Kirsher qlcnic_api_unlock(adapter); 3324aa43c215SJeff Kirsher } 3325aa43c215SJeff Kirsher 3326aa43c215SJeff Kirsher /* Transit to NPAR READY state from NPAR NOT READY state */ 3327aa43c215SJeff Kirsher static void 3328aa43c215SJeff Kirsher qlcnic_dev_set_npar_ready(struct qlcnic_adapter *adapter) 3329aa43c215SJeff Kirsher { 3330aa43c215SJeff Kirsher if (qlcnic_api_lock(adapter)) 3331aa43c215SJeff Kirsher return; 3332aa43c215SJeff Kirsher 3333a15ebd37SHimanshu Madhani QLC_SHARED_REG_WR32(adapter, QLCNIC_CRB_DEV_NPAR_STATE, 3334a15ebd37SHimanshu Madhani QLCNIC_DEV_NPAR_OPER); 3335aa43c215SJeff Kirsher QLCDB(adapter, DRV, "NPAR operational state set\n"); 3336aa43c215SJeff Kirsher 3337aa43c215SJeff Kirsher qlcnic_api_unlock(adapter); 3338aa43c215SJeff Kirsher } 3339aa43c215SJeff Kirsher 334013159183SSony Chacko void qlcnic_schedule_work(struct qlcnic_adapter *adapter, 3341aa43c215SJeff Kirsher work_func_t func, int delay) 3342aa43c215SJeff Kirsher { 3343aa43c215SJeff Kirsher if (test_bit(__QLCNIC_AER, &adapter->state)) 3344aa43c215SJeff Kirsher return; 3345aa43c215SJeff Kirsher 3346aa43c215SJeff Kirsher INIT_DELAYED_WORK(&adapter->fw_work, func); 334713159183SSony Chacko queue_delayed_work(adapter->qlcnic_wq, &adapter->fw_work, 3348aa43c215SJeff Kirsher round_jiffies_relative(delay)); 3349aa43c215SJeff Kirsher } 3350aa43c215SJeff Kirsher 3351aa43c215SJeff Kirsher static void 3352aa43c215SJeff Kirsher qlcnic_attach_work(struct work_struct *work) 3353aa43c215SJeff Kirsher { 3354aa43c215SJeff Kirsher struct qlcnic_adapter *adapter = container_of(work, 3355aa43c215SJeff Kirsher struct qlcnic_adapter, fw_work.work); 3356aa43c215SJeff Kirsher struct net_device *netdev = adapter->netdev; 3357aa43c215SJeff Kirsher u32 npar_state; 3358aa43c215SJeff Kirsher 335979788450SSony Chacko if (adapter->ahw->op_mode != QLCNIC_MGMT_FUNC) { 3360a15ebd37SHimanshu Madhani npar_state = QLC_SHARED_REG_RD32(adapter, 3361a15ebd37SHimanshu Madhani QLCNIC_CRB_DEV_NPAR_STATE); 3362aa43c215SJeff Kirsher if (adapter->fw_wait_cnt++ > QLCNIC_DEV_NPAR_OPER_TIMEO) 3363aa43c215SJeff Kirsher qlcnic_clr_all_drv_state(adapter, 0); 3364aa43c215SJeff Kirsher else if (npar_state != QLCNIC_DEV_NPAR_OPER) 3365aa43c215SJeff Kirsher qlcnic_schedule_work(adapter, qlcnic_attach_work, 3366aa43c215SJeff Kirsher FW_POLL_DELAY); 3367aa43c215SJeff Kirsher else 3368aa43c215SJeff Kirsher goto attach; 3369aa43c215SJeff Kirsher QLCDB(adapter, DRV, "Waiting for NPAR state to operational\n"); 3370aa43c215SJeff Kirsher return; 3371aa43c215SJeff Kirsher } 3372aa43c215SJeff Kirsher attach: 33731de899d3SSucheta Chakraborty qlcnic_dcb_get_info(adapter->dcb); 337414d385b9SSucheta Chakraborty 3375aa43c215SJeff Kirsher if (netif_running(netdev)) { 3376aa43c215SJeff Kirsher if (qlcnic_up(adapter, netdev)) 3377aa43c215SJeff Kirsher goto done; 3378aa43c215SJeff Kirsher 3379aa43c215SJeff Kirsher qlcnic_restore_indev_addr(netdev, NETDEV_UP); 3380aa43c215SJeff Kirsher } 3381aa43c215SJeff Kirsher 3382aa43c215SJeff Kirsher done: 3383aa43c215SJeff Kirsher netif_device_attach(netdev); 3384aa43c215SJeff Kirsher adapter->fw_fail_cnt = 0; 3385aa43c215SJeff Kirsher adapter->flags &= ~QLCNIC_FW_HANG; 3386aa43c215SJeff Kirsher clear_bit(__QLCNIC_RESETTING, &adapter->state); 338724866d15SHimanshu Madhani if (adapter->portnum == 0) 33888af3f33dSPratik Pujar qlcnic_set_drv_version(adapter); 3389aa43c215SJeff Kirsher 3390aa43c215SJeff Kirsher if (!qlcnic_clr_drv_state(adapter)) 3391aa43c215SJeff Kirsher qlcnic_schedule_work(adapter, qlcnic_fw_poll_work, 3392aa43c215SJeff Kirsher FW_POLL_DELAY); 3393aa43c215SJeff Kirsher } 3394aa43c215SJeff Kirsher 3395aa43c215SJeff Kirsher static int 3396aa43c215SJeff Kirsher qlcnic_check_health(struct qlcnic_adapter *adapter) 3397aa43c215SJeff Kirsher { 3398891e71b1SPratik Pujar struct qlcnic_hardware_context *ahw = adapter->ahw; 3399891e71b1SPratik Pujar struct qlcnic_fw_dump *fw_dump = &ahw->fw_dump; 3400aa43c215SJeff Kirsher u32 state = 0, heartbeat; 3401853d4bcaSAmeen Rahman u32 peg_status; 34024bd8e738SHimanshu Madhani int err = 0; 3403aa43c215SJeff Kirsher 3404aa43c215SJeff Kirsher if (qlcnic_check_temp(adapter)) 3405aa43c215SJeff Kirsher goto detach; 3406aa43c215SJeff Kirsher 3407aa43c215SJeff Kirsher if (adapter->need_fw_reset) 34087e2cf4feSSony Chacko qlcnic_dev_request_reset(adapter, 0); 3409aa43c215SJeff Kirsher 3410a15ebd37SHimanshu Madhani state = QLC_SHARED_REG_RD32(adapter, QLCNIC_CRB_DEV_STATE); 3411aa43c215SJeff Kirsher if (state == QLCNIC_DEV_NEED_RESET) { 3412aa43c215SJeff Kirsher qlcnic_set_npar_non_operational(adapter); 3413aa43c215SJeff Kirsher adapter->need_fw_reset = 1; 3414aa43c215SJeff Kirsher } else if (state == QLCNIC_DEV_NEED_QUISCENT) 3415aa43c215SJeff Kirsher goto detach; 3416aa43c215SJeff Kirsher 3417a15ebd37SHimanshu Madhani heartbeat = QLC_SHARED_REG_RD32(adapter, QLCNIC_PEG_ALIVE_COUNTER); 3418aa43c215SJeff Kirsher if (heartbeat != adapter->heartbeat) { 3419aa43c215SJeff Kirsher adapter->heartbeat = heartbeat; 3420aa43c215SJeff Kirsher adapter->fw_fail_cnt = 0; 3421aa43c215SJeff Kirsher if (adapter->need_fw_reset) 3422aa43c215SJeff Kirsher goto detach; 3423aa43c215SJeff Kirsher 3424891e71b1SPratik Pujar if (ahw->reset_context && qlcnic_auto_fw_reset) 3425aa43c215SJeff Kirsher qlcnic_reset_hw_context(adapter); 3426aa43c215SJeff Kirsher 3427aa43c215SJeff Kirsher return 0; 3428aa43c215SJeff Kirsher } 3429aa43c215SJeff Kirsher 3430aa43c215SJeff Kirsher if (++adapter->fw_fail_cnt < FW_FAIL_THRESH) 3431aa43c215SJeff Kirsher return 0; 3432aa43c215SJeff Kirsher 3433aa43c215SJeff Kirsher adapter->flags |= QLCNIC_FW_HANG; 3434aa43c215SJeff Kirsher 34357e2cf4feSSony Chacko qlcnic_dev_request_reset(adapter, 0); 3436aa43c215SJeff Kirsher 3437099f7aa7SSony Chacko if (qlcnic_auto_fw_reset) 3438aa43c215SJeff Kirsher clear_bit(__QLCNIC_FW_ATTACHED, &adapter->state); 3439aa43c215SJeff Kirsher 3440853d4bcaSAmeen Rahman dev_err(&adapter->pdev->dev, "firmware hang detected\n"); 3441a15ebd37SHimanshu Madhani peg_status = QLC_SHARED_REG_RD32(adapter, QLCNIC_PEG_HALT_STATUS1); 3442853d4bcaSAmeen Rahman dev_err(&adapter->pdev->dev, "Dumping hw/fw registers\n" 3443aa43c215SJeff Kirsher "PEG_HALT_STATUS1: 0x%x, PEG_HALT_STATUS2: 0x%x,\n" 3444aa43c215SJeff Kirsher "PEG_NET_0_PC: 0x%x, PEG_NET_1_PC: 0x%x,\n" 3445aa43c215SJeff Kirsher "PEG_NET_2_PC: 0x%x, PEG_NET_3_PC: 0x%x,\n" 3446aa43c215SJeff Kirsher "PEG_NET_4_PC: 0x%x\n", 3447a15ebd37SHimanshu Madhani peg_status, 3448a15ebd37SHimanshu Madhani QLC_SHARED_REG_RD32(adapter, QLCNIC_PEG_HALT_STATUS2), 34494bd8e738SHimanshu Madhani QLCRD32(adapter, QLCNIC_CRB_PEG_NET_0 + 0x3c, &err), 34504bd8e738SHimanshu Madhani QLCRD32(adapter, QLCNIC_CRB_PEG_NET_1 + 0x3c, &err), 34514bd8e738SHimanshu Madhani QLCRD32(adapter, QLCNIC_CRB_PEG_NET_2 + 0x3c, &err), 34524bd8e738SHimanshu Madhani QLCRD32(adapter, QLCNIC_CRB_PEG_NET_3 + 0x3c, &err), 34534bd8e738SHimanshu Madhani QLCRD32(adapter, QLCNIC_CRB_PEG_NET_4 + 0x3c, &err)); 345497048a1fSSritej Velaga if (QLCNIC_FWERROR_CODE(peg_status) == 0x67) 3455853d4bcaSAmeen Rahman dev_err(&adapter->pdev->dev, 3456853d4bcaSAmeen Rahman "Firmware aborted with error code 0x00006700. " 3457853d4bcaSAmeen Rahman "Device is being reset.\n"); 3458aa43c215SJeff Kirsher detach: 3459aa43c215SJeff Kirsher adapter->dev_state = (state == QLCNIC_DEV_NEED_QUISCENT) ? state : 3460aa43c215SJeff Kirsher QLCNIC_DEV_NEED_RESET; 3461aa43c215SJeff Kirsher 3462099f7aa7SSony Chacko if (qlcnic_auto_fw_reset && !test_and_set_bit(__QLCNIC_RESETTING, 3463099f7aa7SSony Chacko &adapter->state)) { 3464aa43c215SJeff Kirsher 3465aa43c215SJeff Kirsher qlcnic_schedule_work(adapter, qlcnic_detach_work, 0); 3466aa43c215SJeff Kirsher QLCDB(adapter, DRV, "fw recovery scheduled.\n"); 3467891e71b1SPratik Pujar } else if (!qlcnic_auto_fw_reset && fw_dump->enable && 3468891e71b1SPratik Pujar adapter->flags & QLCNIC_FW_RESET_OWNER) { 3469891e71b1SPratik Pujar qlcnic_dump_fw(adapter); 3470aa43c215SJeff Kirsher } 3471aa43c215SJeff Kirsher 3472aa43c215SJeff Kirsher return 1; 3473aa43c215SJeff Kirsher } 3474aa43c215SJeff Kirsher 3475486a5bc7SRajesh Borundia void qlcnic_fw_poll_work(struct work_struct *work) 3476aa43c215SJeff Kirsher { 3477aa43c215SJeff Kirsher struct qlcnic_adapter *adapter = container_of(work, 3478aa43c215SJeff Kirsher struct qlcnic_adapter, fw_work.work); 3479aa43c215SJeff Kirsher 3480aa43c215SJeff Kirsher if (test_bit(__QLCNIC_RESETTING, &adapter->state)) 3481aa43c215SJeff Kirsher goto reschedule; 3482aa43c215SJeff Kirsher 3483aa43c215SJeff Kirsher 3484aa43c215SJeff Kirsher if (qlcnic_check_health(adapter)) 3485aa43c215SJeff Kirsher return; 3486aa43c215SJeff Kirsher 3487aa43c215SJeff Kirsher if (adapter->fhash.fnum) 3488aa43c215SJeff Kirsher qlcnic_prune_lb_filters(adapter); 3489aa43c215SJeff Kirsher 3490aa43c215SJeff Kirsher reschedule: 3491aa43c215SJeff Kirsher qlcnic_schedule_work(adapter, qlcnic_fw_poll_work, FW_POLL_DELAY); 3492aa43c215SJeff Kirsher } 3493aa43c215SJeff Kirsher 3494aa43c215SJeff Kirsher static int qlcnic_is_first_func(struct pci_dev *pdev) 3495aa43c215SJeff Kirsher { 3496aa43c215SJeff Kirsher struct pci_dev *oth_pdev; 3497aa43c215SJeff Kirsher int val = pdev->devfn; 3498aa43c215SJeff Kirsher 3499aa43c215SJeff Kirsher while (val-- > 0) { 3500aa43c215SJeff Kirsher oth_pdev = pci_get_domain_bus_and_slot(pci_domain_nr 3501aa43c215SJeff Kirsher (pdev->bus), pdev->bus->number, 3502aa43c215SJeff Kirsher PCI_DEVFN(PCI_SLOT(pdev->devfn), val)); 3503aa43c215SJeff Kirsher if (!oth_pdev) 3504aa43c215SJeff Kirsher continue; 3505aa43c215SJeff Kirsher 3506aa43c215SJeff Kirsher if (oth_pdev->current_state != PCI_D3cold) { 3507aa43c215SJeff Kirsher pci_dev_put(oth_pdev); 3508aa43c215SJeff Kirsher return 0; 3509aa43c215SJeff Kirsher } 3510aa43c215SJeff Kirsher pci_dev_put(oth_pdev); 3511aa43c215SJeff Kirsher } 3512aa43c215SJeff Kirsher return 1; 3513aa43c215SJeff Kirsher } 3514aa43c215SJeff Kirsher 3515aa43c215SJeff Kirsher static int qlcnic_attach_func(struct pci_dev *pdev) 3516aa43c215SJeff Kirsher { 3517aa43c215SJeff Kirsher int err, first_func; 3518aa43c215SJeff Kirsher struct qlcnic_adapter *adapter = pci_get_drvdata(pdev); 3519aa43c215SJeff Kirsher struct net_device *netdev = adapter->netdev; 3520aa43c215SJeff Kirsher 3521aa43c215SJeff Kirsher pdev->error_state = pci_channel_io_normal; 3522aa43c215SJeff Kirsher 3523aa43c215SJeff Kirsher err = pci_enable_device(pdev); 3524aa43c215SJeff Kirsher if (err) 3525aa43c215SJeff Kirsher return err; 3526aa43c215SJeff Kirsher 3527aa43c215SJeff Kirsher pci_set_master(pdev); 3528aa43c215SJeff Kirsher pci_restore_state(pdev); 3529aa43c215SJeff Kirsher 3530aa43c215SJeff Kirsher first_func = qlcnic_is_first_func(pdev); 3531aa43c215SJeff Kirsher 3532aa43c215SJeff Kirsher if (qlcnic_api_lock(adapter)) 3533aa43c215SJeff Kirsher return -EINVAL; 3534aa43c215SJeff Kirsher 353579788450SSony Chacko if (adapter->ahw->op_mode != QLCNIC_NON_PRIV_FUNC && first_func) { 3536aa43c215SJeff Kirsher adapter->need_fw_reset = 1; 3537aa43c215SJeff Kirsher set_bit(__QLCNIC_START_FW, &adapter->state); 3538a15ebd37SHimanshu Madhani QLC_SHARED_REG_WR32(adapter, QLCNIC_CRB_DEV_STATE, 3539a15ebd37SHimanshu Madhani QLCNIC_DEV_INITIALIZING); 3540aa43c215SJeff Kirsher QLCDB(adapter, DRV, "Restarting fw\n"); 3541aa43c215SJeff Kirsher } 3542aa43c215SJeff Kirsher qlcnic_api_unlock(adapter); 3543aa43c215SJeff Kirsher 354413159183SSony Chacko err = qlcnic_start_firmware(adapter); 3545aa43c215SJeff Kirsher if (err) 3546aa43c215SJeff Kirsher return err; 3547aa43c215SJeff Kirsher 3548aa43c215SJeff Kirsher qlcnic_clr_drv_state(adapter); 354913159183SSony Chacko kfree(adapter->msix_entries); 355013159183SSony Chacko adapter->msix_entries = NULL; 355134e8c406SHimanshu Madhani err = qlcnic_setup_intr(adapter); 355213159183SSony Chacko 35539a97e705SManish chopra if (err) { 35549a97e705SManish chopra kfree(adapter->msix_entries); 35559a97e705SManish chopra netdev_err(netdev, "failed to setup interrupt\n"); 35569a97e705SManish chopra return err; 35579a97e705SManish chopra } 35589a97e705SManish chopra 3559aa43c215SJeff Kirsher if (netif_running(netdev)) { 3560aa43c215SJeff Kirsher err = qlcnic_attach(adapter); 3561aa43c215SJeff Kirsher if (err) { 3562aa43c215SJeff Kirsher qlcnic_clr_all_drv_state(adapter, 1); 3563aa43c215SJeff Kirsher clear_bit(__QLCNIC_AER, &adapter->state); 3564aa43c215SJeff Kirsher netif_device_attach(netdev); 3565aa43c215SJeff Kirsher return err; 3566aa43c215SJeff Kirsher } 3567aa43c215SJeff Kirsher 3568aa43c215SJeff Kirsher err = qlcnic_up(adapter, netdev); 3569aa43c215SJeff Kirsher if (err) 3570aa43c215SJeff Kirsher goto done; 3571aa43c215SJeff Kirsher 3572aa43c215SJeff Kirsher qlcnic_restore_indev_addr(netdev, NETDEV_UP); 3573aa43c215SJeff Kirsher } 3574aa43c215SJeff Kirsher done: 3575aa43c215SJeff Kirsher netif_device_attach(netdev); 3576aa43c215SJeff Kirsher return err; 3577aa43c215SJeff Kirsher } 3578aa43c215SJeff Kirsher 35794460f2e8SPratik Pujar pci_ers_result_t qlcnic_82xx_io_error_detected(struct pci_dev *pdev, 3580aa43c215SJeff Kirsher pci_channel_state_t state) 3581aa43c215SJeff Kirsher { 3582aa43c215SJeff Kirsher struct qlcnic_adapter *adapter = pci_get_drvdata(pdev); 3583aa43c215SJeff Kirsher struct net_device *netdev = adapter->netdev; 3584aa43c215SJeff Kirsher 3585aa43c215SJeff Kirsher if (state == pci_channel_io_perm_failure) 3586aa43c215SJeff Kirsher return PCI_ERS_RESULT_DISCONNECT; 3587aa43c215SJeff Kirsher 3588aa43c215SJeff Kirsher if (state == pci_channel_io_normal) 3589aa43c215SJeff Kirsher return PCI_ERS_RESULT_RECOVERED; 3590aa43c215SJeff Kirsher 3591aa43c215SJeff Kirsher set_bit(__QLCNIC_AER, &adapter->state); 3592aa43c215SJeff Kirsher netif_device_detach(netdev); 3593aa43c215SJeff Kirsher 3594aa43c215SJeff Kirsher cancel_delayed_work_sync(&adapter->fw_work); 3595aa43c215SJeff Kirsher 3596aa43c215SJeff Kirsher if (netif_running(netdev)) 3597aa43c215SJeff Kirsher qlcnic_down(adapter, netdev); 3598aa43c215SJeff Kirsher 3599aa43c215SJeff Kirsher qlcnic_detach(adapter); 3600aa43c215SJeff Kirsher qlcnic_teardown_intr(adapter); 3601aa43c215SJeff Kirsher 3602aa43c215SJeff Kirsher clear_bit(__QLCNIC_RESETTING, &adapter->state); 3603aa43c215SJeff Kirsher 3604aa43c215SJeff Kirsher pci_save_state(pdev); 3605aa43c215SJeff Kirsher pci_disable_device(pdev); 3606aa43c215SJeff Kirsher 3607aa43c215SJeff Kirsher return PCI_ERS_RESULT_NEED_RESET; 3608aa43c215SJeff Kirsher } 3609aa43c215SJeff Kirsher 36104460f2e8SPratik Pujar pci_ers_result_t qlcnic_82xx_io_slot_reset(struct pci_dev *pdev) 3611aa43c215SJeff Kirsher { 3612aa43c215SJeff Kirsher return qlcnic_attach_func(pdev) ? PCI_ERS_RESULT_DISCONNECT : 3613aa43c215SJeff Kirsher PCI_ERS_RESULT_RECOVERED; 3614aa43c215SJeff Kirsher } 3615aa43c215SJeff Kirsher 36164460f2e8SPratik Pujar void qlcnic_82xx_io_resume(struct pci_dev *pdev) 3617aa43c215SJeff Kirsher { 3618a15ebd37SHimanshu Madhani u32 state; 3619aa43c215SJeff Kirsher struct qlcnic_adapter *adapter = pci_get_drvdata(pdev); 3620aa43c215SJeff Kirsher 3621aa43c215SJeff Kirsher pci_cleanup_aer_uncorrect_error_status(pdev); 3622a15ebd37SHimanshu Madhani state = QLC_SHARED_REG_RD32(adapter, QLCNIC_CRB_DEV_STATE); 3623a15ebd37SHimanshu Madhani if (state == QLCNIC_DEV_READY && test_and_clear_bit(__QLCNIC_AER, 3624a15ebd37SHimanshu Madhani &adapter->state)) 3625aa43c215SJeff Kirsher qlcnic_schedule_work(adapter, qlcnic_fw_poll_work, 3626aa43c215SJeff Kirsher FW_POLL_DELAY); 3627aa43c215SJeff Kirsher } 3628aa43c215SJeff Kirsher 36294460f2e8SPratik Pujar static pci_ers_result_t qlcnic_io_error_detected(struct pci_dev *pdev, 36304460f2e8SPratik Pujar pci_channel_state_t state) 36314460f2e8SPratik Pujar { 36324460f2e8SPratik Pujar struct qlcnic_adapter *adapter = pci_get_drvdata(pdev); 36334460f2e8SPratik Pujar struct qlcnic_hardware_ops *hw_ops = adapter->ahw->hw_ops; 36344460f2e8SPratik Pujar 36354460f2e8SPratik Pujar if (hw_ops->io_error_detected) { 36364460f2e8SPratik Pujar return hw_ops->io_error_detected(pdev, state); 36374460f2e8SPratik Pujar } else { 36384460f2e8SPratik Pujar dev_err(&pdev->dev, "AER error_detected handler not registered.\n"); 36394460f2e8SPratik Pujar return PCI_ERS_RESULT_DISCONNECT; 36404460f2e8SPratik Pujar } 36414460f2e8SPratik Pujar } 36424460f2e8SPratik Pujar 36434460f2e8SPratik Pujar static pci_ers_result_t qlcnic_io_slot_reset(struct pci_dev *pdev) 36444460f2e8SPratik Pujar { 36454460f2e8SPratik Pujar struct qlcnic_adapter *adapter = pci_get_drvdata(pdev); 36464460f2e8SPratik Pujar struct qlcnic_hardware_ops *hw_ops = adapter->ahw->hw_ops; 36474460f2e8SPratik Pujar 36484460f2e8SPratik Pujar if (hw_ops->io_slot_reset) { 36494460f2e8SPratik Pujar return hw_ops->io_slot_reset(pdev); 36504460f2e8SPratik Pujar } else { 36514460f2e8SPratik Pujar dev_err(&pdev->dev, "AER slot_reset handler not registered.\n"); 36524460f2e8SPratik Pujar return PCI_ERS_RESULT_DISCONNECT; 36534460f2e8SPratik Pujar } 36544460f2e8SPratik Pujar } 36554460f2e8SPratik Pujar 36564460f2e8SPratik Pujar static void qlcnic_io_resume(struct pci_dev *pdev) 36574460f2e8SPratik Pujar { 36584460f2e8SPratik Pujar struct qlcnic_adapter *adapter = pci_get_drvdata(pdev); 36594460f2e8SPratik Pujar struct qlcnic_hardware_ops *hw_ops = adapter->ahw->hw_ops; 36604460f2e8SPratik Pujar 36614460f2e8SPratik Pujar if (hw_ops->io_resume) 36624460f2e8SPratik Pujar hw_ops->io_resume(pdev); 36634460f2e8SPratik Pujar else 36644460f2e8SPratik Pujar dev_err(&pdev->dev, "AER resume handler not registered.\n"); 36654460f2e8SPratik Pujar } 36664460f2e8SPratik Pujar 36674460f2e8SPratik Pujar 3668aa43c215SJeff Kirsher static int 3669aa43c215SJeff Kirsher qlcnicvf_start_firmware(struct qlcnic_adapter *adapter) 3670aa43c215SJeff Kirsher { 3671aa43c215SJeff Kirsher int err; 3672aa43c215SJeff Kirsher 3673aa43c215SJeff Kirsher err = qlcnic_can_start_firmware(adapter); 3674aa43c215SJeff Kirsher if (err) 3675aa43c215SJeff Kirsher return err; 3676aa43c215SJeff Kirsher 3677aa43c215SJeff Kirsher err = qlcnic_check_npar_opertional(adapter); 3678aa43c215SJeff Kirsher if (err) 3679aa43c215SJeff Kirsher return err; 3680aa43c215SJeff Kirsher 3681aa43c215SJeff Kirsher err = qlcnic_initialize_nic(adapter); 3682aa43c215SJeff Kirsher if (err) 3683aa43c215SJeff Kirsher return err; 3684aa43c215SJeff Kirsher 3685aa43c215SJeff Kirsher qlcnic_check_options(adapter); 3686aa43c215SJeff Kirsher 3687aa43c215SJeff Kirsher err = qlcnic_set_eswitch_port_config(adapter); 3688aa43c215SJeff Kirsher if (err) 3689aa43c215SJeff Kirsher return err; 3690aa43c215SJeff Kirsher 3691aa43c215SJeff Kirsher adapter->need_fw_reset = 0; 3692aa43c215SJeff Kirsher 3693aa43c215SJeff Kirsher return err; 3694aa43c215SJeff Kirsher } 3695aa43c215SJeff Kirsher 369634e8c406SHimanshu Madhani int qlcnic_validate_rings(struct qlcnic_adapter *adapter, __u32 ring_cnt, 369734e8c406SHimanshu Madhani int queue_type) 3698aa4a1f7dSHimanshu Madhani { 3699aa4a1f7dSHimanshu Madhani struct net_device *netdev = adapter->netdev; 370034e8c406SHimanshu Madhani u8 max_hw_rings = 0; 370134e8c406SHimanshu Madhani char buf[8]; 370234e8c406SHimanshu Madhani int cur_rings; 370334e8c406SHimanshu Madhani 370434e8c406SHimanshu Madhani if (queue_type == QLCNIC_RX_QUEUE) { 370534e8c406SHimanshu Madhani max_hw_rings = adapter->max_sds_rings; 370634e8c406SHimanshu Madhani cur_rings = adapter->drv_sds_rings; 370734e8c406SHimanshu Madhani strcpy(buf, "SDS"); 370834e8c406SHimanshu Madhani } else if (queue_type == QLCNIC_TX_QUEUE) { 370934e8c406SHimanshu Madhani max_hw_rings = adapter->max_tx_rings; 371034e8c406SHimanshu Madhani cur_rings = adapter->drv_tx_rings; 371134e8c406SHimanshu Madhani strcpy(buf, "Tx"); 371234e8c406SHimanshu Madhani } 3713aa4a1f7dSHimanshu Madhani 3714aa4a1f7dSHimanshu Madhani if (!qlcnic_use_msi_x && !qlcnic_use_msi) { 371534e8c406SHimanshu Madhani netdev_err(netdev, "No RSS/TSS support in INT-x mode\n"); 3716aa4a1f7dSHimanshu Madhani return -EINVAL; 3717aa4a1f7dSHimanshu Madhani } 3718aa4a1f7dSHimanshu Madhani 371934e8c406SHimanshu Madhani if (adapter->flags & QLCNIC_MSI_ENABLED) { 372034e8c406SHimanshu Madhani netdev_err(netdev, "No RSS/TSS support in MSI mode\n"); 3721aa4a1f7dSHimanshu Madhani return -EINVAL; 3722aa4a1f7dSHimanshu Madhani } 3723aa4a1f7dSHimanshu Madhani 372434e8c406SHimanshu Madhani if (!is_power_of_2(ring_cnt)) { 372534e8c406SHimanshu Madhani netdev_err(netdev, "%s rings value should be a power of 2\n", 372634e8c406SHimanshu Madhani buf); 372734e8c406SHimanshu Madhani return -EINVAL; 372834e8c406SHimanshu Madhani } 372934e8c406SHimanshu Madhani 373034e8c406SHimanshu Madhani if (qlcnic_82xx_check(adapter) && (queue_type == QLCNIC_TX_QUEUE) && 373134e8c406SHimanshu Madhani !qlcnic_check_multi_tx(adapter)) { 373234e8c406SHimanshu Madhani netdev_err(netdev, "No Multi Tx queue support\n"); 373334e8c406SHimanshu Madhani return -EINVAL; 373434e8c406SHimanshu Madhani } 373534e8c406SHimanshu Madhani 373634e8c406SHimanshu Madhani if (ring_cnt > num_online_cpus()) { 3737aa4a1f7dSHimanshu Madhani netdev_err(netdev, 373834e8c406SHimanshu Madhani "%s value[%u] should not be higher than, number of online CPUs\n", 373934e8c406SHimanshu Madhani buf, num_online_cpus()); 3740aa4a1f7dSHimanshu Madhani return -EINVAL; 3741aa4a1f7dSHimanshu Madhani } 3742aa4a1f7dSHimanshu Madhani 3743aa4a1f7dSHimanshu Madhani return 0; 3744aa4a1f7dSHimanshu Madhani } 3745aa4a1f7dSHimanshu Madhani 374634e8c406SHimanshu Madhani int qlcnic_setup_rings(struct qlcnic_adapter *adapter, u8 rx_cnt, u8 tx_cnt) 3747aa43c215SJeff Kirsher { 37486389b76dSManish Chopra struct net_device *netdev = adapter->netdev; 374913159183SSony Chacko int err; 3750aa43c215SJeff Kirsher 3751319ecf12SSony Chacko if (test_bit(__QLCNIC_RESETTING, &adapter->state)) 3752319ecf12SSony Chacko return -EBUSY; 3753319ecf12SSony Chacko 3754aa43c215SJeff Kirsher netif_device_detach(netdev); 3755aa43c215SJeff Kirsher if (netif_running(netdev)) 3756aa43c215SJeff Kirsher __qlcnic_down(adapter, netdev); 375713159183SSony Chacko 3758aa43c215SJeff Kirsher qlcnic_detach(adapter); 37597dd90cf1SSucheta Chakraborty 37607ed3ce48SRajesh Borundia if (qlcnic_83xx_check(adapter)) { 37617dd90cf1SSucheta Chakraborty qlcnic_83xx_free_mbx_intr(adapter); 37627ed3ce48SRajesh Borundia qlcnic_83xx_enable_mbx_poll(adapter); 37637ed3ce48SRajesh Borundia } 37647dd90cf1SSucheta Chakraborty 3765aa43c215SJeff Kirsher qlcnic_teardown_intr(adapter); 3766aa4a1f7dSHimanshu Madhani 376734e8c406SHimanshu Madhani /* compute and set default and max tx/sds rings */ 376834e8c406SHimanshu Madhani qlcnic_set_tx_ring_count(adapter, tx_cnt); 376934e8c406SHimanshu Madhani qlcnic_set_sds_ring_count(adapter, rx_cnt); 377034e8c406SHimanshu Madhani 377134e8c406SHimanshu Madhani netif_set_real_num_tx_queues(netdev, adapter->drv_tx_rings); 377234e8c406SHimanshu Madhani 377334e8c406SHimanshu Madhani err = qlcnic_setup_intr(adapter); 37749a97e705SManish chopra if (err) { 37759a97e705SManish chopra kfree(adapter->msix_entries); 37769a97e705SManish chopra netdev_err(netdev, "failed to setup interrupt\n"); 37779a97e705SManish chopra return err; 37789a97e705SManish chopra } 3779aa43c215SJeff Kirsher 378013159183SSony Chacko if (qlcnic_83xx_check(adapter)) { 37819b0fff2aSSucheta Chakraborty qlcnic_83xx_initialize_nic(adapter, 1); 378213159183SSony Chacko err = qlcnic_83xx_setup_mbx_intr(adapter); 37837ed3ce48SRajesh Borundia qlcnic_83xx_disable_mbx_poll(adapter); 378413159183SSony Chacko if (err) { 378513159183SSony Chacko dev_err(&adapter->pdev->dev, 378613159183SSony Chacko "failed to setup mbx interrupt\n"); 378713159183SSony Chacko goto done; 378813159183SSony Chacko } 3789aa43c215SJeff Kirsher } 3790aa43c215SJeff Kirsher 3791aa43c215SJeff Kirsher if (netif_running(netdev)) { 3792aa43c215SJeff Kirsher err = qlcnic_attach(adapter); 3793aa43c215SJeff Kirsher if (err) 3794aa43c215SJeff Kirsher goto done; 3795aa43c215SJeff Kirsher err = __qlcnic_up(adapter, netdev); 3796aa43c215SJeff Kirsher if (err) 3797aa43c215SJeff Kirsher goto done; 3798aa43c215SJeff Kirsher qlcnic_restore_indev_addr(netdev, NETDEV_UP); 3799aa43c215SJeff Kirsher } 3800aa43c215SJeff Kirsher done: 3801aa43c215SJeff Kirsher netif_device_attach(netdev); 3802aa43c215SJeff Kirsher clear_bit(__QLCNIC_RESETTING, &adapter->state); 3803aa43c215SJeff Kirsher return err; 3804aa43c215SJeff Kirsher } 3805aa43c215SJeff Kirsher 3806aa43c215SJeff Kirsher #ifdef CONFIG_INET 3807aa43c215SJeff Kirsher 3808aa43c215SJeff Kirsher #define is_qlcnic_netdev(dev) (dev->netdev_ops == &qlcnic_netdev_ops) 3809aa43c215SJeff Kirsher 3810aa43c215SJeff Kirsher static void 3811aa43c215SJeff Kirsher qlcnic_config_indev_addr(struct qlcnic_adapter *adapter, 3812aa43c215SJeff Kirsher struct net_device *dev, unsigned long event) 3813aa43c215SJeff Kirsher { 3814aa43c215SJeff Kirsher struct in_device *indev; 3815aa43c215SJeff Kirsher 3816aa43c215SJeff Kirsher indev = in_dev_get(dev); 3817aa43c215SJeff Kirsher if (!indev) 3818aa43c215SJeff Kirsher return; 3819aa43c215SJeff Kirsher 3820aa43c215SJeff Kirsher for_ifa(indev) { 3821aa43c215SJeff Kirsher switch (event) { 3822aa43c215SJeff Kirsher case NETDEV_UP: 3823aa43c215SJeff Kirsher qlcnic_config_ipaddr(adapter, 3824aa43c215SJeff Kirsher ifa->ifa_address, QLCNIC_IP_UP); 3825aa43c215SJeff Kirsher break; 3826aa43c215SJeff Kirsher case NETDEV_DOWN: 3827aa43c215SJeff Kirsher qlcnic_config_ipaddr(adapter, 3828aa43c215SJeff Kirsher ifa->ifa_address, QLCNIC_IP_DOWN); 3829aa43c215SJeff Kirsher break; 3830aa43c215SJeff Kirsher default: 3831aa43c215SJeff Kirsher break; 3832aa43c215SJeff Kirsher } 3833aa43c215SJeff Kirsher } endfor_ifa(indev); 3834aa43c215SJeff Kirsher 3835aa43c215SJeff Kirsher in_dev_put(indev); 3836aa43c215SJeff Kirsher } 3837aa43c215SJeff Kirsher 3838319ecf12SSony Chacko void qlcnic_restore_indev_addr(struct net_device *netdev, unsigned long event) 3839aa43c215SJeff Kirsher { 3840aa43c215SJeff Kirsher struct qlcnic_adapter *adapter = netdev_priv(netdev); 3841aa43c215SJeff Kirsher struct net_device *dev; 3842aa43c215SJeff Kirsher u16 vid; 3843aa43c215SJeff Kirsher 3844aa43c215SJeff Kirsher qlcnic_config_indev_addr(adapter, netdev, event); 3845aa43c215SJeff Kirsher 384643c00a75SJiri Pirko rcu_read_lock(); 3847aa43c215SJeff Kirsher for_each_set_bit(vid, adapter->vlans, VLAN_N_VID) { 38481fd9b1fcSPatrick McHardy dev = __vlan_find_dev_deep(netdev, htons(ETH_P_8021Q), vid); 3849aa43c215SJeff Kirsher if (!dev) 3850aa43c215SJeff Kirsher continue; 3851aa43c215SJeff Kirsher qlcnic_config_indev_addr(adapter, dev, event); 3852aa43c215SJeff Kirsher } 385343c00a75SJiri Pirko rcu_read_unlock(); 3854aa43c215SJeff Kirsher } 3855aa43c215SJeff Kirsher 3856aa43c215SJeff Kirsher static int qlcnic_netdev_event(struct notifier_block *this, 3857aa43c215SJeff Kirsher unsigned long event, void *ptr) 3858aa43c215SJeff Kirsher { 3859aa43c215SJeff Kirsher struct qlcnic_adapter *adapter; 3860351638e7SJiri Pirko struct net_device *dev = netdev_notifier_info_to_dev(ptr); 3861aa43c215SJeff Kirsher 3862aa43c215SJeff Kirsher recheck: 3863aa43c215SJeff Kirsher if (dev == NULL) 3864aa43c215SJeff Kirsher goto done; 3865aa43c215SJeff Kirsher 3866aa43c215SJeff Kirsher if (dev->priv_flags & IFF_802_1Q_VLAN) { 3867aa43c215SJeff Kirsher dev = vlan_dev_real_dev(dev); 3868aa43c215SJeff Kirsher goto recheck; 3869aa43c215SJeff Kirsher } 3870aa43c215SJeff Kirsher 3871aa43c215SJeff Kirsher if (!is_qlcnic_netdev(dev)) 3872aa43c215SJeff Kirsher goto done; 3873aa43c215SJeff Kirsher 3874aa43c215SJeff Kirsher adapter = netdev_priv(dev); 3875aa43c215SJeff Kirsher 3876aa43c215SJeff Kirsher if (!adapter) 3877aa43c215SJeff Kirsher goto done; 3878aa43c215SJeff Kirsher 3879aa43c215SJeff Kirsher if (!test_bit(__QLCNIC_DEV_UP, &adapter->state)) 3880aa43c215SJeff Kirsher goto done; 3881aa43c215SJeff Kirsher 3882aa43c215SJeff Kirsher qlcnic_config_indev_addr(adapter, dev, event); 3883aa43c215SJeff Kirsher done: 3884aa43c215SJeff Kirsher return NOTIFY_DONE; 3885aa43c215SJeff Kirsher } 3886aa43c215SJeff Kirsher 3887aa43c215SJeff Kirsher static int 3888aa43c215SJeff Kirsher qlcnic_inetaddr_event(struct notifier_block *this, 3889aa43c215SJeff Kirsher unsigned long event, void *ptr) 3890aa43c215SJeff Kirsher { 3891aa43c215SJeff Kirsher struct qlcnic_adapter *adapter; 3892aa43c215SJeff Kirsher struct net_device *dev; 3893aa43c215SJeff Kirsher 3894aa43c215SJeff Kirsher struct in_ifaddr *ifa = (struct in_ifaddr *)ptr; 3895aa43c215SJeff Kirsher 3896aa43c215SJeff Kirsher dev = ifa->ifa_dev ? ifa->ifa_dev->dev : NULL; 3897aa43c215SJeff Kirsher 3898aa43c215SJeff Kirsher recheck: 3899aa43c215SJeff Kirsher if (dev == NULL) 3900aa43c215SJeff Kirsher goto done; 3901aa43c215SJeff Kirsher 3902aa43c215SJeff Kirsher if (dev->priv_flags & IFF_802_1Q_VLAN) { 3903aa43c215SJeff Kirsher dev = vlan_dev_real_dev(dev); 3904aa43c215SJeff Kirsher goto recheck; 3905aa43c215SJeff Kirsher } 3906aa43c215SJeff Kirsher 3907aa43c215SJeff Kirsher if (!is_qlcnic_netdev(dev)) 3908aa43c215SJeff Kirsher goto done; 3909aa43c215SJeff Kirsher 3910aa43c215SJeff Kirsher adapter = netdev_priv(dev); 3911aa43c215SJeff Kirsher 3912aa43c215SJeff Kirsher if (!adapter) 3913aa43c215SJeff Kirsher goto done; 3914aa43c215SJeff Kirsher 3915aa43c215SJeff Kirsher if (!test_bit(__QLCNIC_DEV_UP, &adapter->state)) 3916aa43c215SJeff Kirsher goto done; 3917aa43c215SJeff Kirsher 3918aa43c215SJeff Kirsher switch (event) { 3919aa43c215SJeff Kirsher case NETDEV_UP: 3920aa43c215SJeff Kirsher qlcnic_config_ipaddr(adapter, ifa->ifa_address, QLCNIC_IP_UP); 392113159183SSony Chacko 3922aa43c215SJeff Kirsher break; 3923aa43c215SJeff Kirsher case NETDEV_DOWN: 3924aa43c215SJeff Kirsher qlcnic_config_ipaddr(adapter, ifa->ifa_address, QLCNIC_IP_DOWN); 392513159183SSony Chacko 3926aa43c215SJeff Kirsher break; 3927aa43c215SJeff Kirsher default: 3928aa43c215SJeff Kirsher break; 3929aa43c215SJeff Kirsher } 3930aa43c215SJeff Kirsher 3931aa43c215SJeff Kirsher done: 3932aa43c215SJeff Kirsher return NOTIFY_DONE; 3933aa43c215SJeff Kirsher } 3934aa43c215SJeff Kirsher 3935aa43c215SJeff Kirsher static struct notifier_block qlcnic_netdev_cb = { 3936aa43c215SJeff Kirsher .notifier_call = qlcnic_netdev_event, 3937aa43c215SJeff Kirsher }; 3938aa43c215SJeff Kirsher 3939aa43c215SJeff Kirsher static struct notifier_block qlcnic_inetaddr_cb = { 3940aa43c215SJeff Kirsher .notifier_call = qlcnic_inetaddr_event, 3941aa43c215SJeff Kirsher }; 3942aa43c215SJeff Kirsher #else 3943f8ca2b6fSSony Chacko void qlcnic_restore_indev_addr(struct net_device *dev, unsigned long event) 3944aa43c215SJeff Kirsher { } 3945aa43c215SJeff Kirsher #endif 3946fec9dd15SStephen Hemminger static const struct pci_error_handlers qlcnic_err_handler = { 3947aa43c215SJeff Kirsher .error_detected = qlcnic_io_error_detected, 3948aa43c215SJeff Kirsher .slot_reset = qlcnic_io_slot_reset, 3949aa43c215SJeff Kirsher .resume = qlcnic_io_resume, 3950aa43c215SJeff Kirsher }; 3951aa43c215SJeff Kirsher 3952aa43c215SJeff Kirsher static struct pci_driver qlcnic_driver = { 3953aa43c215SJeff Kirsher .name = qlcnic_driver_name, 3954aa43c215SJeff Kirsher .id_table = qlcnic_pci_tbl, 3955aa43c215SJeff Kirsher .probe = qlcnic_probe, 39566bb58bb0SBill Pemberton .remove = qlcnic_remove, 3957aa43c215SJeff Kirsher #ifdef CONFIG_PM 3958aa43c215SJeff Kirsher .suspend = qlcnic_suspend, 3959aa43c215SJeff Kirsher .resume = qlcnic_resume, 3960aa43c215SJeff Kirsher #endif 3961aa43c215SJeff Kirsher .shutdown = qlcnic_shutdown, 396202feda17SRajesh Borundia .err_handler = &qlcnic_err_handler, 396302feda17SRajesh Borundia #ifdef CONFIG_QLCNIC_SRIOV 396402feda17SRajesh Borundia .sriov_configure = qlcnic_pci_sriov_configure, 396502feda17SRajesh Borundia #endif 3966aa43c215SJeff Kirsher 3967aa43c215SJeff Kirsher }; 3968aa43c215SJeff Kirsher 3969aa43c215SJeff Kirsher static int __init qlcnic_init_module(void) 3970aa43c215SJeff Kirsher { 3971aa43c215SJeff Kirsher int ret; 3972aa43c215SJeff Kirsher 3973aa43c215SJeff Kirsher printk(KERN_INFO "%s\n", qlcnic_driver_string); 3974aa43c215SJeff Kirsher 3975aa43c215SJeff Kirsher #ifdef CONFIG_INET 3976aa43c215SJeff Kirsher register_netdevice_notifier(&qlcnic_netdev_cb); 3977aa43c215SJeff Kirsher register_inetaddr_notifier(&qlcnic_inetaddr_cb); 3978aa43c215SJeff Kirsher #endif 3979aa43c215SJeff Kirsher 3980aa43c215SJeff Kirsher ret = pci_register_driver(&qlcnic_driver); 3981aa43c215SJeff Kirsher if (ret) { 3982aa43c215SJeff Kirsher #ifdef CONFIG_INET 3983aa43c215SJeff Kirsher unregister_inetaddr_notifier(&qlcnic_inetaddr_cb); 3984aa43c215SJeff Kirsher unregister_netdevice_notifier(&qlcnic_netdev_cb); 3985aa43c215SJeff Kirsher #endif 3986aa43c215SJeff Kirsher } 3987aa43c215SJeff Kirsher 3988aa43c215SJeff Kirsher return ret; 3989aa43c215SJeff Kirsher } 3990aa43c215SJeff Kirsher 3991aa43c215SJeff Kirsher module_init(qlcnic_init_module); 3992aa43c215SJeff Kirsher 3993aa43c215SJeff Kirsher static void __exit qlcnic_exit_module(void) 3994aa43c215SJeff Kirsher { 3995aa43c215SJeff Kirsher pci_unregister_driver(&qlcnic_driver); 3996aa43c215SJeff Kirsher 3997aa43c215SJeff Kirsher #ifdef CONFIG_INET 3998aa43c215SJeff Kirsher unregister_inetaddr_notifier(&qlcnic_inetaddr_cb); 3999aa43c215SJeff Kirsher unregister_netdevice_notifier(&qlcnic_netdev_cb); 4000aa43c215SJeff Kirsher #endif 4001aa43c215SJeff Kirsher } 4002aa43c215SJeff Kirsher 4003aa43c215SJeff Kirsher module_exit(qlcnic_exit_module); 4004