From 78fad34eb8b22ce588b9ebdab39965210588e4b5 Mon Sep 17 00:00:00 2001 From: Sathya Perla Date: Mon, 23 Feb 2015 04:20:08 -0500 Subject: be2net: move adapter fields alloc/free code to new routines The members of be_adapter struct were being allocated in two separate routines -- be_ctrl_init() and be_stats_init(). Also, some other members were allocated elsewhere. This patch moves the alloc/free code into be_drv_init/cleanup() routines. The be_pci_map_bars() routine that was called from be_ctrl_init() is now called directly from be_probe(). The new routine be_drv_init() will now be the place-holder for allocating memory for any new be_adapter{} members in the future. Some routines needed to be moved to provide forward definitions for their calls. Signed-off-by: Sathya Perla Signed-off-by: Kalesh AP Signed-off-by: David S. Miller --- drivers/net/ethernet/emulex/benet/be_main.c | 408 +++++++++++++--------------- 1 file changed, 195 insertions(+), 213 deletions(-) diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c index c1553fba7916..ae8ad5502db0 100644 --- a/drivers/net/ethernet/emulex/benet/be_main.c +++ b/drivers/net/ethernet/emulex/benet/be_main.c @@ -4878,6 +4878,130 @@ static void be_netdev_init(struct net_device *netdev) netdev->ethtool_ops = &be_ethtool_ops; } +static int lancer_recover_func(struct be_adapter *adapter) +{ + struct device *dev = &adapter->pdev->dev; + int status; + + status = lancer_test_and_set_rdy_state(adapter); + if (status) + goto err; + + if (netif_running(adapter->netdev)) + be_close(adapter->netdev); + + be_clear(adapter); + + be_clear_all_error(adapter); + + status = be_setup(adapter); + if (status) + goto err; + + if (netif_running(adapter->netdev)) { + status = be_open(adapter->netdev); + if (status) + goto err; + } + + dev_err(dev, "Adapter recovery successful\n"); + return 0; +err: + if (status == -EAGAIN) + dev_err(dev, "Waiting for resource provisioning\n"); + else + dev_err(dev, "Adapter recovery failed\n"); + + return status; +} + +static void be_func_recovery_task(struct work_struct *work) +{ + struct be_adapter *adapter = + container_of(work, struct be_adapter, func_recovery_work.work); + int status = 0; + + be_detect_error(adapter); + + if (adapter->hw_error && lancer_chip(adapter)) { + rtnl_lock(); + netif_device_detach(adapter->netdev); + rtnl_unlock(); + + status = lancer_recover_func(adapter); + if (!status) + netif_device_attach(adapter->netdev); + } + + /* In Lancer, for all errors other than provisioning error (-EAGAIN), + * no need to attempt further recovery. + */ + if (!status || status == -EAGAIN) + schedule_delayed_work(&adapter->func_recovery_work, + msecs_to_jiffies(1000)); +} + +static void be_log_sfp_info(struct be_adapter *adapter) +{ + int status; + + status = be_cmd_query_sfp_info(adapter); + if (!status) { + dev_err(&adapter->pdev->dev, + "Unqualified SFP+ detected on %c from %s part no: %s", + adapter->port_name, adapter->phy.vendor_name, + adapter->phy.vendor_pn); + } + adapter->flags &= ~BE_FLAGS_EVT_INCOMPATIBLE_SFP; +} + +static void be_worker(struct work_struct *work) +{ + struct be_adapter *adapter = + container_of(work, struct be_adapter, work.work); + struct be_rx_obj *rxo; + int i; + + /* when interrupts are not yet enabled, just reap any pending + * mcc completions + */ + if (!netif_running(adapter->netdev)) { + local_bh_disable(); + be_process_mcc(adapter); + local_bh_enable(); + goto reschedule; + } + + if (!adapter->stats_cmd_sent) { + if (lancer_chip(adapter)) + lancer_cmd_get_pport_stats(adapter, + &adapter->stats_cmd); + else + be_cmd_get_stats(adapter, &adapter->stats_cmd); + } + + if (be_physfn(adapter) && + MODULO(adapter->work_counter, adapter->be_get_temp_freq) == 0) + be_cmd_get_die_temperature(adapter); + + for_all_rx_queues(adapter, rxo, i) { + /* Replenish RX-queues starved due to memory + * allocation failures. + */ + if (rxo->rx_post_starved) + be_post_rx_frags(rxo, GFP_KERNEL, MAX_RX_POST); + } + + be_eqd_update(adapter); + + if (adapter->flags & BE_FLAGS_EVT_INCOMPATIBLE_SFP) + be_log_sfp_info(adapter); + +reschedule: + adapter->work_counter++; + schedule_delayed_work(&adapter->work, msecs_to_jiffies(1000)); +} + static void be_unmap_pci_bars(struct be_adapter *adapter) { if (adapter->csr) @@ -4909,6 +5033,12 @@ static int be_roce_map_pci_bars(struct be_adapter *adapter) static int be_map_pci_bars(struct be_adapter *adapter) { u8 __iomem *addr; + u32 sli_intf; + + pci_read_config_dword(adapter->pdev, SLI_INTF_REG_OFFSET, &sli_intf); + adapter->sli_family = (sli_intf & SLI_INTF_FAMILY_MASK) >> + SLI_INTF_FAMILY_SHIFT; + adapter->virtfn = (sli_intf & SLI_INTF_FT_MASK) ? 1 : 0; if (BEx_chip(adapter) && be_physfn(adapter)) { adapter->csr = pci_iomap(adapter->pdev, 2, 0); @@ -4930,109 +5060,93 @@ pci_map_err: return -ENOMEM; } -static void be_ctrl_cleanup(struct be_adapter *adapter) +static void be_drv_cleanup(struct be_adapter *adapter) { struct be_dma_mem *mem = &adapter->mbox_mem_alloced; - - be_unmap_pci_bars(adapter); + struct device *dev = &adapter->pdev->dev; if (mem->va) - dma_free_coherent(&adapter->pdev->dev, mem->size, mem->va, - mem->dma); + dma_free_coherent(dev, mem->size, mem->va, mem->dma); mem = &adapter->rx_filter; if (mem->va) - dma_free_coherent(&adapter->pdev->dev, mem->size, mem->va, - mem->dma); + dma_free_coherent(dev, mem->size, mem->va, mem->dma); + + mem = &adapter->stats_cmd; + if (mem->va) + dma_free_coherent(dev, mem->size, mem->va, mem->dma); } -static int be_ctrl_init(struct be_adapter *adapter) +/* Allocate and initialize various fields in be_adapter struct */ +static int be_drv_init(struct be_adapter *adapter) { struct be_dma_mem *mbox_mem_alloc = &adapter->mbox_mem_alloced; struct be_dma_mem *mbox_mem_align = &adapter->mbox_mem; struct be_dma_mem *rx_filter = &adapter->rx_filter; - u32 sli_intf; - int status; - - pci_read_config_dword(adapter->pdev, SLI_INTF_REG_OFFSET, &sli_intf); - adapter->sli_family = (sli_intf & SLI_INTF_FAMILY_MASK) >> - SLI_INTF_FAMILY_SHIFT; - adapter->virtfn = (sli_intf & SLI_INTF_FT_MASK) ? 1 : 0; - - status = be_map_pci_bars(adapter); - if (status) - goto done; + struct be_dma_mem *stats_cmd = &adapter->stats_cmd; + struct device *dev = &adapter->pdev->dev; + int status = 0; mbox_mem_alloc->size = sizeof(struct be_mcc_mailbox) + 16; - mbox_mem_alloc->va = dma_alloc_coherent(&adapter->pdev->dev, - mbox_mem_alloc->size, + mbox_mem_alloc->va = dma_alloc_coherent(dev, mbox_mem_alloc->size, &mbox_mem_alloc->dma, GFP_KERNEL); - if (!mbox_mem_alloc->va) { - status = -ENOMEM; - goto unmap_pci_bars; - } + if (!mbox_mem_alloc->va) + return -ENOMEM; + mbox_mem_align->size = sizeof(struct be_mcc_mailbox); mbox_mem_align->va = PTR_ALIGN(mbox_mem_alloc->va, 16); mbox_mem_align->dma = PTR_ALIGN(mbox_mem_alloc->dma, 16); memset(mbox_mem_align->va, 0, sizeof(struct be_mcc_mailbox)); rx_filter->size = sizeof(struct be_cmd_req_rx_filter); - rx_filter->va = dma_zalloc_coherent(&adapter->pdev->dev, - rx_filter->size, &rx_filter->dma, - GFP_KERNEL); + rx_filter->va = dma_zalloc_coherent(dev, rx_filter->size, + &rx_filter->dma, GFP_KERNEL); if (!rx_filter->va) { status = -ENOMEM; goto free_mbox; } + if (lancer_chip(adapter)) + stats_cmd->size = sizeof(struct lancer_cmd_req_pport_stats); + else if (BE2_chip(adapter)) + stats_cmd->size = sizeof(struct be_cmd_req_get_stats_v0); + else if (BE3_chip(adapter)) + stats_cmd->size = sizeof(struct be_cmd_req_get_stats_v1); + else + stats_cmd->size = sizeof(struct be_cmd_req_get_stats_v2); + stats_cmd->va = dma_zalloc_coherent(dev, stats_cmd->size, + &stats_cmd->dma, GFP_KERNEL); + if (!stats_cmd->va) { + status = -ENOMEM; + goto free_rx_filter; + } + mutex_init(&adapter->mbox_lock); spin_lock_init(&adapter->mcc_lock); spin_lock_init(&adapter->mcc_cq_lock); - init_completion(&adapter->et_cmd_compl); - pci_save_state(adapter->pdev); - return 0; - -free_mbox: - dma_free_coherent(&adapter->pdev->dev, mbox_mem_alloc->size, - mbox_mem_alloc->va, mbox_mem_alloc->dma); -unmap_pci_bars: - be_unmap_pci_bars(adapter); - -done: - return status; -} - -static void be_stats_cleanup(struct be_adapter *adapter) -{ - struct be_dma_mem *cmd = &adapter->stats_cmd; + pci_save_state(adapter->pdev); - if (cmd->va) - dma_free_coherent(&adapter->pdev->dev, cmd->size, - cmd->va, cmd->dma); -} + INIT_DELAYED_WORK(&adapter->work, be_worker); + INIT_DELAYED_WORK(&adapter->func_recovery_work, be_func_recovery_task); -static int be_stats_init(struct be_adapter *adapter) -{ - struct be_dma_mem *cmd = &adapter->stats_cmd; + adapter->rx_fc = true; + adapter->tx_fc = true; - if (lancer_chip(adapter)) - cmd->size = sizeof(struct lancer_cmd_req_pport_stats); - else if (BE2_chip(adapter)) - cmd->size = sizeof(struct be_cmd_req_get_stats_v0); - else if (BE3_chip(adapter)) - cmd->size = sizeof(struct be_cmd_req_get_stats_v1); - else - /* ALL non-BE ASICs */ - cmd->size = sizeof(struct be_cmd_req_get_stats_v2); + /* Must be a power of 2 or else MODULO will BUG_ON */ + adapter->be_get_temp_freq = 64; + adapter->cfg_num_qs = netif_get_num_default_rss_queues(); - cmd->va = dma_zalloc_coherent(&adapter->pdev->dev, cmd->size, &cmd->dma, - GFP_KERNEL); - if (!cmd->va) - return -ENOMEM; return 0; + +free_rx_filter: + dma_free_coherent(dev, rx_filter->size, rx_filter->va, rx_filter->dma); +free_mbox: + dma_free_coherent(dev, mbox_mem_alloc->size, mbox_mem_alloc->va, + mbox_mem_alloc->dma); + return status; } static void be_remove(struct pci_dev *pdev) @@ -5054,9 +5168,8 @@ static void be_remove(struct pci_dev *pdev) /* tell fw we're done with firing cmds */ be_cmd_fw_clean(adapter); - be_stats_cleanup(adapter); - - be_ctrl_cleanup(adapter); + be_unmap_pci_bars(adapter); + be_drv_cleanup(adapter); pci_disable_pcie_error_reporting(pdev); @@ -5074,141 +5187,15 @@ static int be_get_initial_config(struct be_adapter *adapter) if (status) return status; - /* Must be a power of 2 or else MODULO will BUG_ON */ - adapter->be_get_temp_freq = 64; - if (BEx_chip(adapter)) { level = be_cmd_get_fw_log_level(adapter); adapter->msg_enable = level <= FW_LOG_LEVEL_DEFAULT ? NETIF_MSG_HW : 0; } - adapter->cfg_num_qs = netif_get_num_default_rss_queues(); - return 0; -} - -static int lancer_recover_func(struct be_adapter *adapter) -{ - struct device *dev = &adapter->pdev->dev; - int status; - - status = lancer_test_and_set_rdy_state(adapter); - if (status) - goto err; - - if (netif_running(adapter->netdev)) - be_close(adapter->netdev); - - be_clear(adapter); - - be_clear_all_error(adapter); - - status = be_setup(adapter); - if (status) - goto err; - - if (netif_running(adapter->netdev)) { - status = be_open(adapter->netdev); - if (status) - goto err; - } - - dev_err(dev, "Adapter recovery successful\n"); return 0; -err: - if (status == -EAGAIN) - dev_err(dev, "Waiting for resource provisioning\n"); - else - dev_err(dev, "Adapter recovery failed\n"); - - return status; } -static void be_func_recovery_task(struct work_struct *work) -{ - struct be_adapter *adapter = - container_of(work, struct be_adapter, func_recovery_work.work); - int status = 0; - - be_detect_error(adapter); - - if (adapter->hw_error && lancer_chip(adapter)) { - rtnl_lock(); - netif_device_detach(adapter->netdev); - rtnl_unlock(); - - status = lancer_recover_func(adapter); - if (!status) - netif_device_attach(adapter->netdev); - } - - /* In Lancer, for all errors other than provisioning error (-EAGAIN), - * no need to attempt further recovery. - */ - if (!status || status == -EAGAIN) - schedule_delayed_work(&adapter->func_recovery_work, - msecs_to_jiffies(1000)); -} - -static void be_log_sfp_info(struct be_adapter *adapter) -{ - int status; - - status = be_cmd_query_sfp_info(adapter); - if (!status) { - dev_err(&adapter->pdev->dev, - "Unqualified SFP+ detected on %c from %s part no: %s", - adapter->port_name, adapter->phy.vendor_name, - adapter->phy.vendor_pn); - } - adapter->flags &= ~BE_FLAGS_EVT_INCOMPATIBLE_SFP; -} - -static void be_worker(struct work_struct *work) -{ - struct be_adapter *adapter = - container_of(work, struct be_adapter, work.work); - struct be_rx_obj *rxo; - int i; - - /* when interrupts are not yet enabled, just reap any pending - * mcc completions */ - if (!netif_running(adapter->netdev)) { - local_bh_disable(); - be_process_mcc(adapter); - local_bh_enable(); - goto reschedule; - } - - if (!adapter->stats_cmd_sent) { - if (lancer_chip(adapter)) - lancer_cmd_get_pport_stats(adapter, - &adapter->stats_cmd); - else - be_cmd_get_stats(adapter, &adapter->stats_cmd); - } - - if (be_physfn(adapter) && - MODULO(adapter->work_counter, adapter->be_get_temp_freq) == 0) - be_cmd_get_die_temperature(adapter); - - for_all_rx_queues(adapter, rxo, i) { - /* Replenish RX-queues starved due to memory - * allocation failures. - */ - if (rxo->rx_post_starved) - be_post_rx_frags(rxo, GFP_KERNEL, MAX_RX_POST); - } - - be_eqd_update(adapter); - - if (adapter->flags & BE_FLAGS_EVT_INCOMPATIBLE_SFP) - be_log_sfp_info(adapter); - -reschedule: - adapter->work_counter++; - schedule_delayed_work(&adapter->work, msecs_to_jiffies(1000)); -} /* If any VFs are already enabled don't FLR the PF */ static bool be_reset_required(struct be_adapter *adapter) @@ -5314,21 +5301,25 @@ static int be_probe(struct pci_dev *pdev, const struct pci_device_id *pdev_id) if (!status) dev_info(&pdev->dev, "PCIe error reporting enabled\n"); - status = be_ctrl_init(adapter); + status = be_map_pci_bars(adapter); if (status) goto free_netdev; + status = be_drv_init(adapter); + if (status) + goto unmap_bars; + /* sync up with fw's ready state */ if (be_physfn(adapter)) { status = be_fw_wait_ready(adapter); if (status) - goto ctrl_clean; + goto drv_cleanup; } if (be_reset_required(adapter)) { status = be_cmd_reset_function(adapter); if (status) - goto ctrl_clean; + goto drv_cleanup; /* Wait for interrupts to quiesce after an FLR */ msleep(100); @@ -5340,24 +5331,15 @@ static int be_probe(struct pci_dev *pdev, const struct pci_device_id *pdev_id) /* tell fw we're ready to fire cmds */ status = be_cmd_fw_init(adapter); if (status) - goto ctrl_clean; - - status = be_stats_init(adapter); - if (status) - goto ctrl_clean; + goto drv_cleanup; status = be_get_initial_config(adapter); if (status) - goto stats_clean; - - INIT_DELAYED_WORK(&adapter->work, be_worker); - INIT_DELAYED_WORK(&adapter->func_recovery_work, be_func_recovery_task); - adapter->rx_fc = true; - adapter->tx_fc = true; + goto drv_cleanup; status = be_setup(adapter); if (status) - goto stats_clean; + goto drv_cleanup; be_netdev_init(netdev); status = register_netdev(netdev); @@ -5376,10 +5358,10 @@ static int be_probe(struct pci_dev *pdev, const struct pci_device_id *pdev_id) unsetup: be_clear(adapter); -stats_clean: - be_stats_cleanup(adapter); -ctrl_clean: - be_ctrl_cleanup(adapter); +drv_cleanup: + be_drv_cleanup(adapter); +unmap_bars: + be_unmap_pci_bars(adapter); free_netdev: free_netdev(netdev); rel_reg: -- cgit v1.2.3 From 6b085ba9271a252b1e3f836ab5df202c51be4f2f Mon Sep 17 00:00:00 2001 From: Sathya Perla Date: Mon, 23 Feb 2015 04:20:09 -0500 Subject: be2net: get rid of be_get_initial_config() call from be_probe() Most of the code to fetch the adapter state is in be_setup()->be_get_config(). So, move the code from be_get_initial_config() to be_get_config(). Signed-off-by: Sathya Perla Signed-off-by: Kalesh AP Signed-off-by: David S. Miller --- drivers/net/ethernet/emulex/benet/be_main.c | 38 ++++++++++------------------- 1 file changed, 13 insertions(+), 25 deletions(-) diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c index ae8ad5502db0..40c8f85dbd0d 100644 --- a/drivers/net/ethernet/emulex/benet/be_main.c +++ b/drivers/net/ethernet/emulex/benet/be_main.c @@ -3771,13 +3771,25 @@ static void be_sriov_config(struct be_adapter *adapter) static int be_get_config(struct be_adapter *adapter) { + int status, level; u16 profile_id; - int status; + + status = be_cmd_get_cntl_attributes(adapter); + if (status) + return status; status = be_cmd_query_fw_cfg(adapter); if (status) return status; + if (BEx_chip(adapter)) { + level = be_cmd_get_fw_log_level(adapter); + adapter->msg_enable = + level <= FW_LOG_LEVEL_DEFAULT ? NETIF_MSG_HW : 0; + } + + be_cmd_get_acpi_wol_cap(adapter); + be_cmd_query_port_name(adapter); if (be_physfn(adapter)) { @@ -3967,8 +3979,6 @@ static int be_setup(struct be_adapter *adapter) be_set_rx_mode(adapter->netdev); - be_cmd_get_acpi_wol_cap(adapter); - status = be_cmd_set_flow_control(adapter, adapter->tx_fc, adapter->rx_fc); if (status) @@ -5179,24 +5189,6 @@ static void be_remove(struct pci_dev *pdev) free_netdev(adapter->netdev); } -static int be_get_initial_config(struct be_adapter *adapter) -{ - int status, level; - - status = be_cmd_get_cntl_attributes(adapter); - if (status) - return status; - - if (BEx_chip(adapter)) { - level = be_cmd_get_fw_log_level(adapter); - adapter->msg_enable = - level <= FW_LOG_LEVEL_DEFAULT ? NETIF_MSG_HW : 0; - } - - return 0; -} - - /* If any VFs are already enabled don't FLR the PF */ static bool be_reset_required(struct be_adapter *adapter) { @@ -5333,10 +5325,6 @@ static int be_probe(struct pci_dev *pdev, const struct pci_device_id *pdev_id) if (status) goto drv_cleanup; - status = be_get_initial_config(adapter); - if (status) - goto drv_cleanup; - status = be_setup(adapter); if (status) goto drv_cleanup; -- cgit v1.2.3 From ca3de6b29d09585bdb7b5af2e12f815468120184 Mon Sep 17 00:00:00 2001 From: Sathya Perla Date: Mon, 23 Feb 2015 04:20:10 -0500 Subject: be2net: refactor function initalization sequence into be_func_init() Function initialization sequence is executed in be_probe(), be_resume and be_eeh_resume(). Move this code to a new routine called be_func_init() to prevent code duplication. Signed-off-by: Sathya Perla Signed-off-by: Kalesh AP Signed-off-by: David S. Miller --- drivers/net/ethernet/emulex/benet/be_cmds.c | 4 ++ drivers/net/ethernet/emulex/benet/be_main.c | 76 ++++++++++++----------------- 2 files changed, 36 insertions(+), 44 deletions(-) diff --git a/drivers/net/ethernet/emulex/benet/be_cmds.c b/drivers/net/ethernet/emulex/benet/be_cmds.c index 36916cfa70f9..8a8a23030aff 100644 --- a/drivers/net/ethernet/emulex/benet/be_cmds.c +++ b/drivers/net/ethernet/emulex/benet/be_cmds.c @@ -720,6 +720,10 @@ int be_fw_wait_ready(struct be_adapter *adapter) } do { + /* There's no means to poll POST state on BE2/3 VFs */ + if (BEx_chip(adapter) && be_virtfn(adapter)) + return 0; + stage = be_POST_stage_get(adapter); if (stage == POST_STAGE_ARMFW_RDY) return 0; diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c index 40c8f85dbd0d..fda2e5dcd977 100644 --- a/drivers/net/ethernet/emulex/benet/be_main.c +++ b/drivers/net/ethernet/emulex/benet/be_main.c @@ -5250,6 +5250,35 @@ static inline char *nic_name(struct pci_dev *pdev) } } +/* Wait for the FW to be ready and perform the required initialization */ +static int be_func_init(struct be_adapter *adapter) +{ + int status; + + status = be_fw_wait_ready(adapter); + if (status) + return status; + + if (be_reset_required(adapter)) { + status = be_cmd_reset_function(adapter); + if (status) + return status; + + /* Wait for interrupts to quiesce after an FLR */ + msleep(100); + } + + /* Tell FW we're ready to fire cmds */ + status = be_cmd_fw_init(adapter); + if (status) + return status; + + /* Allow interrupts for other ULPs running on NIC function */ + be_intr_set(adapter, true); + + return 0; +} + static int be_probe(struct pci_dev *pdev, const struct pci_device_id *pdev_id) { struct be_adapter *adapter; @@ -5301,27 +5330,7 @@ static int be_probe(struct pci_dev *pdev, const struct pci_device_id *pdev_id) if (status) goto unmap_bars; - /* sync up with fw's ready state */ - if (be_physfn(adapter)) { - status = be_fw_wait_ready(adapter); - if (status) - goto drv_cleanup; - } - - if (be_reset_required(adapter)) { - status = be_cmd_reset_function(adapter); - if (status) - goto drv_cleanup; - - /* Wait for interrupts to quiesce after an FLR */ - msleep(100); - } - - /* Allow interrupts for other ULPs running on NIC function */ - be_intr_set(adapter, true); - - /* tell fw we're ready to fire cmds */ - status = be_cmd_fw_init(adapter); + status = be_func_init(adapter); if (status) goto drv_cleanup; @@ -5401,17 +5410,7 @@ static int be_resume(struct pci_dev *pdev) pci_set_power_state(pdev, PCI_D0); pci_restore_state(pdev); - status = be_fw_wait_ready(adapter); - if (status) - return status; - - status = be_cmd_reset_function(adapter); - if (status) - return status; - - be_intr_set(adapter, true); - /* tell fw we're ready to fire cmds */ - status = be_cmd_fw_init(adapter); + status = be_func_init(adapter); if (status) return status; @@ -5529,18 +5528,7 @@ static void be_eeh_resume(struct pci_dev *pdev) pci_save_state(pdev); - status = be_cmd_reset_function(adapter); - if (status) - goto err; - - /* On some BE3 FW versions, after a HW reset, - * interrupts will remain disabled for each function. - * So, explicitly enable interrupts - */ - be_intr_set(adapter, true); - - /* tell fw we're ready to fire cmds */ - status = be_cmd_fw_init(adapter); + status = be_func_init(adapter); if (status) goto err; -- cgit v1.2.3 From eb7dd46c634fa5b2f2039791bd2e79343318d6e5 Mon Sep 17 00:00:00 2001 From: Sathya Perla Date: Mon, 23 Feb 2015 04:20:11 -0500 Subject: be2net: use a wrapper to schedule and cancel error detection task Also rename func_recovery_work/task to err_detection_work/task as error detection is the primary goal of this task while recovery is not guaranteed. Signed-off-by: Sathya Perla Signed-off-by: Kalesh AP Signed-off-by: David S. Miller --- drivers/net/ethernet/emulex/benet/be.h | 3 +- drivers/net/ethernet/emulex/benet/be_main.c | 45 +++++++++++++++++++---------- 2 files changed, 32 insertions(+), 16 deletions(-) diff --git a/drivers/net/ethernet/emulex/benet/be.h b/drivers/net/ethernet/emulex/benet/be.h index ad33bf1f1df1..fac806a15a61 100644 --- a/drivers/net/ethernet/emulex/benet/be.h +++ b/drivers/net/ethernet/emulex/benet/be.h @@ -376,6 +376,7 @@ enum vf_state { #define BE_FLAGS_VXLAN_OFFLOADS BIT(8) #define BE_FLAGS_SETUP_DONE BIT(9) #define BE_FLAGS_EVT_INCOMPATIBLE_SFP BIT(10) +#define BE_FLAGS_ERR_DETECTION_SCHEDULED BIT(11) #define BE_UC_PMAC_COUNT 30 #define BE_VF_UC_PMAC_COUNT 2 @@ -501,7 +502,7 @@ struct be_adapter { struct delayed_work work; u16 work_counter; - struct delayed_work func_recovery_work; + struct delayed_work be_err_detection_work; u32 flags; u32 cmd_privileges; /* Ethtool knobs and info */ diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c index fda2e5dcd977..74ba99577bf8 100644 --- a/drivers/net/ethernet/emulex/benet/be_main.c +++ b/drivers/net/ethernet/emulex/benet/be_main.c @@ -3363,6 +3363,14 @@ static void be_cancel_worker(struct be_adapter *adapter) } } +static void be_cancel_err_detection(struct be_adapter *adapter) +{ + if (adapter->flags & BE_FLAGS_ERR_DETECTION_SCHEDULED) { + cancel_delayed_work_sync(&adapter->be_err_detection_work); + adapter->flags &= ~BE_FLAGS_ERR_DETECTION_SCHEDULED; + } +} + static void be_mac_clear(struct be_adapter *adapter) { if (adapter->pmac_id) { @@ -3847,6 +3855,13 @@ static void be_schedule_worker(struct be_adapter *adapter) adapter->flags |= BE_FLAGS_WORKER_SCHEDULED; } +static void be_schedule_err_detection(struct be_adapter *adapter) +{ + schedule_delayed_work(&adapter->be_err_detection_work, + msecs_to_jiffies(1000)); + adapter->flags |= BE_FLAGS_ERR_DETECTION_SCHEDULED; +} + static int be_setup_queues(struct be_adapter *adapter) { struct net_device *netdev = adapter->netdev; @@ -4925,10 +4940,11 @@ err: return status; } -static void be_func_recovery_task(struct work_struct *work) +static void be_err_detection_task(struct work_struct *work) { struct be_adapter *adapter = - container_of(work, struct be_adapter, func_recovery_work.work); + container_of(work, struct be_adapter, + be_err_detection_work.work); int status = 0; be_detect_error(adapter); @@ -4947,8 +4963,7 @@ static void be_func_recovery_task(struct work_struct *work) * no need to attempt further recovery. */ if (!status || status == -EAGAIN) - schedule_delayed_work(&adapter->func_recovery_work, - msecs_to_jiffies(1000)); + be_schedule_err_detection(adapter); } static void be_log_sfp_info(struct be_adapter *adapter) @@ -5140,7 +5155,8 @@ static int be_drv_init(struct be_adapter *adapter) pci_save_state(adapter->pdev); INIT_DELAYED_WORK(&adapter->work, be_worker); - INIT_DELAYED_WORK(&adapter->func_recovery_work, be_func_recovery_task); + INIT_DELAYED_WORK(&adapter->be_err_detection_work, + be_err_detection_task); adapter->rx_fc = true; adapter->tx_fc = true; @@ -5169,7 +5185,7 @@ static void be_remove(struct pci_dev *pdev) be_roce_dev_remove(adapter); be_intr_set(adapter, false); - cancel_delayed_work_sync(&adapter->func_recovery_work); + be_cancel_err_detection(adapter); unregister_netdev(adapter->netdev); @@ -5345,8 +5361,7 @@ static int be_probe(struct pci_dev *pdev, const struct pci_device_id *pdev_id) be_roce_dev_add(adapter); - schedule_delayed_work(&adapter->func_recovery_work, - msecs_to_jiffies(1000)); + be_schedule_err_detection(adapter); dev_info(&pdev->dev, "%s: %s %s port %c\n", nic_name(pdev), func_name(adapter), mc_name(adapter), adapter->port_name); @@ -5379,7 +5394,7 @@ static int be_suspend(struct pci_dev *pdev, pm_message_t state) be_setup_wol(adapter, true); be_intr_set(adapter, false); - cancel_delayed_work_sync(&adapter->func_recovery_work); + be_cancel_err_detection(adapter); netif_device_detach(netdev); if (netif_running(netdev)) { @@ -5421,10 +5436,10 @@ static int be_resume(struct pci_dev *pdev) rtnl_unlock(); } - schedule_delayed_work(&adapter->func_recovery_work, - msecs_to_jiffies(1000)); netif_device_attach(netdev); + be_schedule_err_detection(adapter); + if (adapter->wol_en) be_setup_wol(adapter, false); @@ -5443,7 +5458,7 @@ static void be_shutdown(struct pci_dev *pdev) be_roce_dev_shutdown(adapter); cancel_delayed_work_sync(&adapter->work); - cancel_delayed_work_sync(&adapter->func_recovery_work); + be_cancel_err_detection(adapter); netif_device_detach(adapter->netdev); @@ -5463,7 +5478,7 @@ static pci_ers_result_t be_eeh_err_detected(struct pci_dev *pdev, if (!adapter->eeh_error) { adapter->eeh_error = true; - cancel_delayed_work_sync(&adapter->func_recovery_work); + be_cancel_err_detection(adapter); rtnl_lock(); netif_device_detach(netdev); @@ -5542,9 +5557,9 @@ static void be_eeh_resume(struct pci_dev *pdev) goto err; } - schedule_delayed_work(&adapter->func_recovery_work, - msecs_to_jiffies(1000)); netif_device_attach(netdev); + + be_schedule_err_detection(adapter); return; err: dev_err(&adapter->pdev->dev, "EEH resume failed\n"); -- cgit v1.2.3 From d0e1b319bbf345e8b8cc8bd7702cc6c33db074d9 Mon Sep 17 00:00:00 2001 From: Kalesh AP Date: Mon, 23 Feb 2015 04:20:12 -0500 Subject: be2net: refactor error detect/recovery function Currently when an error is detected, the queue resources are being cleaned up in the recovery routine. The resources are better cleaned up in the error detection routine itself (similar to EEH code.) So, this patch re-factors error processing logic to follow the following sequence: - check if there is an error in adapter - if error, - cleanup resources - attempt recovery The patch renames lancer_recover_func() to be_err_recover() as this routine will be used in the future for error recovery on Skyhawk too. Signed-off-by: Kalesh AP Signed-off-by: Sathya Perla Signed-off-by: David S. Miller --- drivers/net/ethernet/emulex/benet/be_main.c | 31 ++++++++++++++++------------- 1 file changed, 17 insertions(+), 14 deletions(-) diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c index 74ba99577bf8..034ce7031ce2 100644 --- a/drivers/net/ethernet/emulex/benet/be_main.c +++ b/drivers/net/ethernet/emulex/benet/be_main.c @@ -2844,12 +2844,12 @@ void be_detect_error(struct be_adapter *adapter) sliport_err2 = ioread32(adapter->db + SLIPORT_ERROR2_OFFSET); adapter->hw_error = true; + error_detected = true; /* Do not log error messages if its a FW reset */ if (sliport_err1 == SLIPORT_ERROR_FW_RESET1 && sliport_err2 == SLIPORT_ERROR_FW_RESET2) { dev_info(dev, "Firmware update in progress\n"); } else { - error_detected = true; dev_err(dev, "Error detected in the card\n"); dev_err(dev, "ERR: sliport status 0x%x\n", sliport_status); @@ -4903,8 +4903,9 @@ static void be_netdev_init(struct net_device *netdev) netdev->ethtool_ops = &be_ethtool_ops; } -static int lancer_recover_func(struct be_adapter *adapter) +static int be_err_recover(struct be_adapter *adapter) { + struct net_device *netdev = adapter->netdev; struct device *dev = &adapter->pdev->dev; int status; @@ -4912,23 +4913,20 @@ static int lancer_recover_func(struct be_adapter *adapter) if (status) goto err; - if (netif_running(adapter->netdev)) - be_close(adapter->netdev); - - be_clear(adapter); - be_clear_all_error(adapter); status = be_setup(adapter); if (status) goto err; - if (netif_running(adapter->netdev)) { - status = be_open(adapter->netdev); + if (netif_running(netdev)) { + status = be_open(netdev); if (status) goto err; } + netif_device_attach(netdev); + dev_err(dev, "Adapter recovery successful\n"); return 0; err: @@ -4945,18 +4943,23 @@ static void be_err_detection_task(struct work_struct *work) struct be_adapter *adapter = container_of(work, struct be_adapter, be_err_detection_work.work); + struct net_device *netdev = adapter->netdev; int status = 0; be_detect_error(adapter); - if (adapter->hw_error && lancer_chip(adapter)) { + if (adapter->hw_error) { rtnl_lock(); - netif_device_detach(adapter->netdev); + netif_device_detach(netdev); + if (netif_running(netdev)) + be_close(netdev); rtnl_unlock(); - status = lancer_recover_func(adapter); - if (!status) - netif_device_attach(adapter->netdev); + be_clear(adapter); + + /* As of now error recovery support is in Lancer only */ + if (lancer_chip(adapter)) + status = be_err_recover(adapter); } /* In Lancer, for all errors other than provisioning error (-EAGAIN), -- cgit v1.2.3 From 9fa465c0ce0d99f098195d7b0a550aeb1b2a8c44 Mon Sep 17 00:00:00 2001 From: Sathya Perla Date: Mon, 23 Feb 2015 04:20:13 -0500 Subject: be2net: remove code duplication relating to Lancer reset sequence The steps needed for Lancer's reset/initialization sequence are: a) wait for SLIPORT_STAUS RDY bit to be set b) set the SLIPORT_CONTROL IP bit c) repeat step "a" The code needed for this sequence is already covered by the be_func_init() routine (with minor modifications.) So, get rid of the lancer_test_and_set_rdy_state() and lancer_provisioning_error() routines that unnecessarily duplicate this code. Also fixed the error recovery function to take care of these changes Signed-off-by: Sathya Perla Signed-off-by: Kalesh AP Signed-off-by: David S. Miller --- drivers/net/ethernet/emulex/benet/be_cmds.c | 81 ++++--------------------- drivers/net/ethernet/emulex/benet/be_main.c | 91 ++++++++++++++--------------- 2 files changed, 55 insertions(+), 117 deletions(-) diff --git a/drivers/net/ethernet/emulex/benet/be_cmds.c b/drivers/net/ethernet/emulex/benet/be_cmds.c index 8a8a23030aff..f6db7b3e9b70 100644 --- a/drivers/net/ethernet/emulex/benet/be_cmds.c +++ b/drivers/net/ethernet/emulex/benet/be_cmds.c @@ -635,73 +635,16 @@ static int lancer_wait_ready(struct be_adapter *adapter) for (i = 0; i < SLIPORT_READY_TIMEOUT; i++) { sliport_status = ioread32(adapter->db + SLIPORT_STATUS_OFFSET); if (sliport_status & SLIPORT_STATUS_RDY_MASK) - break; - - msleep(1000); - } - - if (i == SLIPORT_READY_TIMEOUT) - return sliport_status ? : -1; - - return 0; -} - -static bool lancer_provisioning_error(struct be_adapter *adapter) -{ - u32 sliport_status = 0, sliport_err1 = 0, sliport_err2 = 0; - - sliport_status = ioread32(adapter->db + SLIPORT_STATUS_OFFSET); - if (sliport_status & SLIPORT_STATUS_ERR_MASK) { - sliport_err1 = ioread32(adapter->db + SLIPORT_ERROR1_OFFSET); - sliport_err2 = ioread32(adapter->db + SLIPORT_ERROR2_OFFSET); - - if (sliport_err1 == SLIPORT_ERROR_NO_RESOURCE1 && - sliport_err2 == SLIPORT_ERROR_NO_RESOURCE2) - return true; - } - return false; -} - -int lancer_test_and_set_rdy_state(struct be_adapter *adapter) -{ - int status; - u32 sliport_status, err, reset_needed; - bool resource_error; + return 0; - resource_error = lancer_provisioning_error(adapter); - if (resource_error) - return -EAGAIN; + if (sliport_status & SLIPORT_STATUS_ERR_MASK && + !(sliport_status & SLIPORT_STATUS_RN_MASK)) + return -EIO; - status = lancer_wait_ready(adapter); - if (!status) { - sliport_status = ioread32(adapter->db + SLIPORT_STATUS_OFFSET); - err = sliport_status & SLIPORT_STATUS_ERR_MASK; - reset_needed = sliport_status & SLIPORT_STATUS_RN_MASK; - if (err && reset_needed) { - iowrite32(SLI_PORT_CONTROL_IP_MASK, - adapter->db + SLIPORT_CONTROL_OFFSET); - - /* check if adapter has corrected the error */ - status = lancer_wait_ready(adapter); - sliport_status = ioread32(adapter->db + - SLIPORT_STATUS_OFFSET); - sliport_status &= (SLIPORT_STATUS_ERR_MASK | - SLIPORT_STATUS_RN_MASK); - if (status || sliport_status) - status = -1; - } else if (err || reset_needed) { - status = -1; - } + msleep(1000); } - /* Stop error recovery if error is not recoverable. - * No resource error is temporary errors and will go away - * when PF provisions resources. - */ - resource_error = lancer_provisioning_error(adapter); - if (resource_error) - status = -EAGAIN; - return status; + return sliport_status ? : -1; } int be_fw_wait_ready(struct be_adapter *adapter) @@ -738,7 +681,7 @@ int be_fw_wait_ready(struct be_adapter *adapter) err: dev_err(dev, "POST timeout; stage=%#x\n", stage); - return -1; + return -ETIMEDOUT; } static inline struct be_sge *nonembedded_sgl(struct be_mcc_wrb *wrb) @@ -2130,16 +2073,12 @@ int be_cmd_reset_function(struct be_adapter *adapter) int status; if (lancer_chip(adapter)) { + iowrite32(SLI_PORT_CONTROL_IP_MASK, + adapter->db + SLIPORT_CONTROL_OFFSET); status = lancer_wait_ready(adapter); - if (!status) { - iowrite32(SLI_PORT_CONTROL_IP_MASK, - adapter->db + SLIPORT_CONTROL_OFFSET); - status = lancer_test_and_set_rdy_state(adapter); - } - if (status) { + if (status) dev_err(&adapter->pdev->dev, "Adapter in non recoverable error\n"); - } return status; } diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c index 034ce7031ce2..4a29ff15a3cc 100644 --- a/drivers/net/ethernet/emulex/benet/be_main.c +++ b/drivers/net/ethernet/emulex/benet/be_main.c @@ -4903,18 +4903,54 @@ static void be_netdev_init(struct net_device *netdev) netdev->ethtool_ops = &be_ethtool_ops; } +/* If any VFs are already enabled don't FLR the PF */ +static bool be_reset_required(struct be_adapter *adapter) +{ + return pci_num_vf(adapter->pdev) ? false : true; +} + +/* Wait for the FW to be ready and perform the required initialization */ +static int be_func_init(struct be_adapter *adapter) +{ + int status; + + status = be_fw_wait_ready(adapter); + if (status) + return status; + + if (be_reset_required(adapter)) { + status = be_cmd_reset_function(adapter); + if (status) + return status; + + /* Wait for interrupts to quiesce after an FLR */ + msleep(100); + + /* We can clear all errors when function reset succeeds */ + be_clear_all_error(adapter); + } + + /* Tell FW we're ready to fire cmds */ + status = be_cmd_fw_init(adapter); + if (status) + return status; + + /* Allow interrupts for other ULPs running on NIC function */ + be_intr_set(adapter, true); + + return 0; +} + static int be_err_recover(struct be_adapter *adapter) { struct net_device *netdev = adapter->netdev; struct device *dev = &adapter->pdev->dev; int status; - status = lancer_test_and_set_rdy_state(adapter); + status = be_func_init(adapter); if (status) goto err; - be_clear_all_error(adapter); - status = be_setup(adapter); if (status) goto err; @@ -4927,13 +4963,13 @@ static int be_err_recover(struct be_adapter *adapter) netif_device_attach(netdev); - dev_err(dev, "Adapter recovery successful\n"); + dev_info(dev, "Adapter recovery successful\n"); return 0; err: - if (status == -EAGAIN) - dev_err(dev, "Waiting for resource provisioning\n"); - else + if (be_physfn(adapter)) dev_err(dev, "Adapter recovery failed\n"); + else + dev_err(dev, "Re-trying adapter recovery\n"); return status; } @@ -4962,10 +4998,8 @@ static void be_err_detection_task(struct work_struct *work) status = be_err_recover(adapter); } - /* In Lancer, for all errors other than provisioning error (-EAGAIN), - * no need to attempt further recovery. - */ - if (!status || status == -EAGAIN) + /* Always attempt recovery on VFs */ + if (!status || be_virtfn(adapter)) be_schedule_err_detection(adapter); } @@ -5208,12 +5242,6 @@ static void be_remove(struct pci_dev *pdev) free_netdev(adapter->netdev); } -/* If any VFs are already enabled don't FLR the PF */ -static bool be_reset_required(struct be_adapter *adapter) -{ - return pci_num_vf(adapter->pdev) ? false : true; -} - static char *mc_name(struct be_adapter *adapter) { char *str = ""; /* default */ @@ -5269,35 +5297,6 @@ static inline char *nic_name(struct pci_dev *pdev) } } -/* Wait for the FW to be ready and perform the required initialization */ -static int be_func_init(struct be_adapter *adapter) -{ - int status; - - status = be_fw_wait_ready(adapter); - if (status) - return status; - - if (be_reset_required(adapter)) { - status = be_cmd_reset_function(adapter); - if (status) - return status; - - /* Wait for interrupts to quiesce after an FLR */ - msleep(100); - } - - /* Tell FW we're ready to fire cmds */ - status = be_cmd_fw_init(adapter); - if (status) - return status; - - /* Allow interrupts for other ULPs running on NIC function */ - be_intr_set(adapter, true); - - return 0; -} - static int be_probe(struct pci_dev *pdev, const struct pci_device_id *pdev_id) { struct be_adapter *adapter; -- cgit v1.2.3 From 484d76fd5154d7d7dcc8e5928a947deb9cc0b94c Mon Sep 17 00:00:00 2001 From: Kalesh AP Date: Mon, 23 Feb 2015 04:20:14 -0500 Subject: be2net: refactor adapter resource initialzation sequence into be_resume() Most of the adapter initialisation sequences performed in be_resume(), be_eeh_resume() and be_err_recover() are same. Renamed be_resume() to be_pci_resume() and moved the common code to a new routine be_resume() to avoid code duplication. Signed-off-by: Kalesh AP Signed-off-by: Sathya Perla Signed-off-by: David S. Miller --- drivers/net/ethernet/emulex/benet/be_main.c | 56 +++++++++++------------------ 1 file changed, 21 insertions(+), 35 deletions(-) diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c index 4a29ff15a3cc..80a0aabfbcf8 100644 --- a/drivers/net/ethernet/emulex/benet/be_main.c +++ b/drivers/net/ethernet/emulex/benet/be_main.c @@ -4941,28 +4941,39 @@ static int be_func_init(struct be_adapter *adapter) return 0; } -static int be_err_recover(struct be_adapter *adapter) +static int be_resume(struct be_adapter *adapter) { struct net_device *netdev = adapter->netdev; - struct device *dev = &adapter->pdev->dev; int status; status = be_func_init(adapter); if (status) - goto err; + return status; status = be_setup(adapter); if (status) - goto err; + return status; if (netif_running(netdev)) { status = be_open(netdev); if (status) - goto err; + return status; } netif_device_attach(netdev); + return 0; +} + +static int be_err_recover(struct be_adapter *adapter) +{ + struct device *dev = &adapter->pdev->dev; + int status; + + status = be_resume(adapter); + if (status) + goto err; + dev_info(dev, "Adapter recovery successful\n"); return 0; err: @@ -5412,13 +5423,10 @@ static int be_suspend(struct pci_dev *pdev, pm_message_t state) return 0; } -static int be_resume(struct pci_dev *pdev) +static int be_pci_resume(struct pci_dev *pdev) { - int status = 0; struct be_adapter *adapter = pci_get_drvdata(pdev); - struct net_device *netdev = adapter->netdev; - - netif_device_detach(netdev); + int status = 0; status = pci_enable_device(pdev); if (status) @@ -5427,19 +5435,10 @@ static int be_resume(struct pci_dev *pdev) pci_set_power_state(pdev, PCI_D0); pci_restore_state(pdev); - status = be_func_init(adapter); + status = be_resume(adapter); if (status) return status; - be_setup(adapter); - if (netif_running(netdev)) { - rtnl_lock(); - be_open(netdev); - rtnl_unlock(); - } - - netif_device_attach(netdev); - be_schedule_err_detection(adapter); if (adapter->wol_en) @@ -5539,28 +5538,15 @@ static void be_eeh_resume(struct pci_dev *pdev) { int status = 0; struct be_adapter *adapter = pci_get_drvdata(pdev); - struct net_device *netdev = adapter->netdev; dev_info(&adapter->pdev->dev, "EEH resume\n"); pci_save_state(pdev); - status = be_func_init(adapter); + status = be_resume(adapter); if (status) goto err; - status = be_setup(adapter); - if (status) - goto err; - - if (netif_running(netdev)) { - status = be_open(netdev); - if (status) - goto err; - } - - netif_device_attach(netdev); - be_schedule_err_detection(adapter); return; err: @@ -5579,7 +5565,7 @@ static struct pci_driver be_driver = { .probe = be_probe, .remove = be_remove, .suspend = be_suspend, - .resume = be_resume, + .resume = be_pci_resume, .shutdown = be_shutdown, .err_handler = &be_eeh_handlers }; -- cgit v1.2.3 From 87ac1a5296291d557080fb544f445be3bce6c51f Mon Sep 17 00:00:00 2001 From: Kalesh AP Date: Mon, 23 Feb 2015 04:20:15 -0500 Subject: be2net: refactor adapter resource cleanup sequence into be_cleanup() Most of the resource cleanup sequences performed in be_suspend(), be_eeh_err_detected() and be_err_detection_task() are same. Moved the common code to a new routine be_cleanup() to avoid code duplication. Signed-off-by: Kalesh AP Signed-off-by: Sathya Perla Signed-off-by: David S. Miller --- drivers/net/ethernet/emulex/benet/be_main.c | 40 ++++++++++++----------------- 1 file changed, 16 insertions(+), 24 deletions(-) diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c index 80a0aabfbcf8..7aa1a4dd2df9 100644 --- a/drivers/net/ethernet/emulex/benet/be_main.c +++ b/drivers/net/ethernet/emulex/benet/be_main.c @@ -4941,6 +4941,19 @@ static int be_func_init(struct be_adapter *adapter) return 0; } +static void be_cleanup(struct be_adapter *adapter) +{ + struct net_device *netdev = adapter->netdev; + + rtnl_lock(); + netif_device_detach(netdev); + if (netif_running(netdev)) + be_close(netdev); + rtnl_unlock(); + + be_clear(adapter); +} + static int be_resume(struct be_adapter *adapter) { struct net_device *netdev = adapter->netdev; @@ -4990,19 +5003,12 @@ static void be_err_detection_task(struct work_struct *work) struct be_adapter *adapter = container_of(work, struct be_adapter, be_err_detection_work.work); - struct net_device *netdev = adapter->netdev; int status = 0; be_detect_error(adapter); if (adapter->hw_error) { - rtnl_lock(); - netif_device_detach(netdev); - if (netif_running(netdev)) - be_close(netdev); - rtnl_unlock(); - - be_clear(adapter); + be_cleanup(adapter); /* As of now error recovery support is in Lancer only */ if (lancer_chip(adapter)) @@ -5401,7 +5407,6 @@ do_none: static int be_suspend(struct pci_dev *pdev, pm_message_t state) { struct be_adapter *adapter = pci_get_drvdata(pdev); - struct net_device *netdev = adapter->netdev; if (adapter->wol_en) be_setup_wol(adapter, true); @@ -5409,13 +5414,7 @@ static int be_suspend(struct pci_dev *pdev, pm_message_t state) be_intr_set(adapter, false); be_cancel_err_detection(adapter); - netif_device_detach(netdev); - if (netif_running(netdev)) { - rtnl_lock(); - be_close(netdev); - rtnl_unlock(); - } - be_clear(adapter); + be_cleanup(adapter); pci_save_state(pdev); pci_disable_device(pdev); @@ -5472,7 +5471,6 @@ static pci_ers_result_t be_eeh_err_detected(struct pci_dev *pdev, pci_channel_state_t state) { struct be_adapter *adapter = pci_get_drvdata(pdev); - struct net_device *netdev = adapter->netdev; dev_err(&adapter->pdev->dev, "EEH error detected\n"); @@ -5481,13 +5479,7 @@ static pci_ers_result_t be_eeh_err_detected(struct pci_dev *pdev, be_cancel_err_detection(adapter); - rtnl_lock(); - netif_device_detach(netdev); - if (netif_running(netdev)) - be_close(netdev); - rtnl_unlock(); - - be_clear(adapter); + be_cleanup(adapter); } if (state == pci_channel_io_perm_failure) -- cgit v1.2.3 From f962f840f81f5b9f2df136dd44872f18a82def38 Mon Sep 17 00:00:00 2001 From: Sathya Perla Date: Mon, 23 Feb 2015 04:20:16 -0500 Subject: be2net: move be_func_init() call inside be_setup() Every time be_setup() is called, the driver will have to wait for the function/FW to be properly initialized. So, it make sense to move this call inside be_setup(). Signed-off-by: Sathya Perla Signed-off-by: Kalesh AP Signed-off-by: David S. Miller --- drivers/net/ethernet/emulex/benet/be_main.c | 88 ++++++++++++++--------------- 1 file changed, 42 insertions(+), 46 deletions(-) diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c index 7aa1a4dd2df9..b2277a4c7ddf 100644 --- a/drivers/net/ethernet/emulex/benet/be_main.c +++ b/drivers/net/ethernet/emulex/benet/be_main.c @@ -3944,11 +3944,53 @@ static inline int fw_major_num(const char *fw_ver) return fw_major; } +/* If any VFs are already enabled don't FLR the PF */ +static bool be_reset_required(struct be_adapter *adapter) +{ + return pci_num_vf(adapter->pdev) ? false : true; +} + +/* Wait for the FW to be ready and perform the required initialization */ +static int be_func_init(struct be_adapter *adapter) +{ + int status; + + status = be_fw_wait_ready(adapter); + if (status) + return status; + + if (be_reset_required(adapter)) { + status = be_cmd_reset_function(adapter); + if (status) + return status; + + /* Wait for interrupts to quiesce after an FLR */ + msleep(100); + + /* We can clear all errors when function reset succeeds */ + be_clear_all_error(adapter); + } + + /* Tell FW we're ready to fire cmds */ + status = be_cmd_fw_init(adapter); + if (status) + return status; + + /* Allow interrupts for other ULPs running on NIC function */ + be_intr_set(adapter, true); + + return 0; +} + static int be_setup(struct be_adapter *adapter) { struct device *dev = &adapter->pdev->dev; int status; + status = be_func_init(adapter); + if (status) + return status; + be_setup_init(adapter); if (!lancer_chip(adapter)) @@ -4903,44 +4945,6 @@ static void be_netdev_init(struct net_device *netdev) netdev->ethtool_ops = &be_ethtool_ops; } -/* If any VFs are already enabled don't FLR the PF */ -static bool be_reset_required(struct be_adapter *adapter) -{ - return pci_num_vf(adapter->pdev) ? false : true; -} - -/* Wait for the FW to be ready and perform the required initialization */ -static int be_func_init(struct be_adapter *adapter) -{ - int status; - - status = be_fw_wait_ready(adapter); - if (status) - return status; - - if (be_reset_required(adapter)) { - status = be_cmd_reset_function(adapter); - if (status) - return status; - - /* Wait for interrupts to quiesce after an FLR */ - msleep(100); - - /* We can clear all errors when function reset succeeds */ - be_clear_all_error(adapter); - } - - /* Tell FW we're ready to fire cmds */ - status = be_cmd_fw_init(adapter); - if (status) - return status; - - /* Allow interrupts for other ULPs running on NIC function */ - be_intr_set(adapter, true); - - return 0; -} - static void be_cleanup(struct be_adapter *adapter) { struct net_device *netdev = adapter->netdev; @@ -4959,10 +4963,6 @@ static int be_resume(struct be_adapter *adapter) struct net_device *netdev = adapter->netdev; int status; - status = be_func_init(adapter); - if (status) - return status; - status = be_setup(adapter); if (status) return status; @@ -5365,10 +5365,6 @@ static int be_probe(struct pci_dev *pdev, const struct pci_device_id *pdev_id) if (status) goto unmap_bars; - status = be_func_init(adapter); - if (status) - goto drv_cleanup; - status = be_setup(adapter); if (status) goto drv_cleanup; -- cgit v1.2.3