diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c index 3116861198f0e..53f3ed2df7961 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_main.c +++ b/drivers/net/ethernet/intel/i40e/i40e_main.c @@ -38,7 +38,7 @@ static const char i40e_driver_string[] = #define DRV_VERSION_MAJOR 0 #define DRV_VERSION_MINOR 3 -#define DRV_VERSION_BUILD 31 +#define DRV_VERSION_BUILD 32 #define DRV_VERSION __stringify(DRV_VERSION_MAJOR) "." \ __stringify(DRV_VERSION_MINOR) "." \ __stringify(DRV_VERSION_BUILD) DRV_KERN @@ -3108,13 +3108,13 @@ static int i40e_vsi_control_tx(struct i40e_vsi *vsi, bool enable) pf_q = vsi->base_queue; for (i = 0; i < vsi->num_queue_pairs; i++, pf_q++) { - j = 1000; - do { - usleep_range(1000, 2000); + for (j = 0; j < 50; j++) { tx_reg = rd32(hw, I40E_QTX_ENA(pf_q)); - } while (j-- && ((tx_reg >> I40E_QTX_ENA_QENA_REQ_SHIFT) - ^ (tx_reg >> I40E_QTX_ENA_QENA_STAT_SHIFT)) & 1); - + if (((tx_reg >> I40E_QTX_ENA_QENA_REQ_SHIFT) & 1) == + ((tx_reg >> I40E_QTX_ENA_QENA_STAT_SHIFT) & 1)) + break; + usleep_range(1000, 2000); + } /* Skip if the queue is already in the requested state */ if (enable && (tx_reg & I40E_QTX_ENA_QENA_STAT_MASK)) continue; @@ -3124,8 +3124,7 @@ static int i40e_vsi_control_tx(struct i40e_vsi *vsi, bool enable) /* turn on/off the queue */ if (enable) { wr32(hw, I40E_QTX_HEAD(pf_q), 0); - tx_reg |= I40E_QTX_ENA_QENA_REQ_MASK | - I40E_QTX_ENA_QENA_STAT_MASK; + tx_reg |= I40E_QTX_ENA_QENA_REQ_MASK; } else { tx_reg &= ~I40E_QTX_ENA_QENA_REQ_MASK; } @@ -3172,12 +3171,13 @@ static int i40e_vsi_control_rx(struct i40e_vsi *vsi, bool enable) pf_q = vsi->base_queue; for (i = 0; i < vsi->num_queue_pairs; i++, pf_q++) { - j = 1000; - do { - usleep_range(1000, 2000); + for (j = 0; j < 50; j++) { rx_reg = rd32(hw, I40E_QRX_ENA(pf_q)); - } while (j-- && ((rx_reg >> I40E_QRX_ENA_QENA_REQ_SHIFT) - ^ (rx_reg >> I40E_QRX_ENA_QENA_STAT_SHIFT)) & 1); + if (((rx_reg >> I40E_QRX_ENA_QENA_REQ_SHIFT) & 1) == + ((rx_reg >> I40E_QRX_ENA_QENA_STAT_SHIFT) & 1)) + break; + usleep_range(1000, 2000); + } if (enable) { /* is STAT set ? */ @@ -3191,11 +3191,9 @@ static int i40e_vsi_control_rx(struct i40e_vsi *vsi, bool enable) /* turn on/off the queue */ if (enable) - rx_reg |= I40E_QRX_ENA_QENA_REQ_MASK | - I40E_QRX_ENA_QENA_STAT_MASK; + rx_reg |= I40E_QRX_ENA_QENA_REQ_MASK; else - rx_reg &= ~(I40E_QRX_ENA_QENA_REQ_MASK | - I40E_QRX_ENA_QENA_STAT_MASK); + rx_reg &= ~I40E_QRX_ENA_QENA_REQ_MASK; wr32(hw, I40E_QRX_ENA(pf_q), rx_reg); /* wait for the change to finish */ @@ -5927,7 +5925,7 @@ static int i40e_init_msix(struct i40e_pf *pf) } else if (vec == I40E_MIN_MSIX) { /* Adjust for minimal MSIX use */ - dev_info(&pf->pdev->dev, "Features disabled, not enough MSIX vectors\n"); + dev_info(&pf->pdev->dev, "Features disabled, not enough MSI-X vectors\n"); pf->flags &= ~I40E_FLAG_VMDQ_ENABLED; pf->num_vmdq_vsis = 0; pf->num_vmdq_qps = 0; @@ -6056,7 +6054,7 @@ static void i40e_init_interrupt_scheme(struct i40e_pf *pf) if (!(pf->flags & I40E_FLAG_MSIX_ENABLED) && (pf->flags & I40E_FLAG_MSI_ENABLED)) { - dev_info(&pf->pdev->dev, "MSIX not available, trying MSI\n"); + dev_info(&pf->pdev->dev, "MSI-X not available, trying MSI\n"); err = pci_enable_msi(pf->pdev); if (err) { dev_info(&pf->pdev->dev, "MSI init failed - %d\n", err); @@ -6065,7 +6063,7 @@ static void i40e_init_interrupt_scheme(struct i40e_pf *pf) } if (!(pf->flags & (I40E_FLAG_MSIX_ENABLED | I40E_FLAG_MSI_ENABLED))) - dev_info(&pf->pdev->dev, "MSIX and MSI not available, falling back to Legacy IRQ\n"); + dev_info(&pf->pdev->dev, "MSI-X and MSI not available, falling back to Legacy IRQ\n"); /* track first vector for misc interrupts */ err = i40e_get_lump(pf, pf->irq_pile, 1, I40E_PILE_VALID_BIT-1); @@ -6092,7 +6090,8 @@ static int i40e_setup_misc_vector(struct i40e_pf *pf) i40e_intr, 0, pf->misc_int_name, pf); if (err) { dev_info(&pf->pdev->dev, - "request_irq for msix_misc failed: %d\n", err); + "request_irq for %s failed: %d\n", + pf->misc_int_name, err); return -EFAULT; } } diff --git a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c index 7d133faad4cf8..189e250198dd6 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c +++ b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c @@ -671,7 +671,6 @@ void i40e_reset_vf(struct i40e_vf *vf, bool flr) complete_reset: /* reallocate vf resources to reset the VSI state */ i40e_free_vf_res(vf); - mdelay(10); i40e_alloc_vf_res(vf); i40e_enable_vf_mappings(vf); set_bit(I40E_VF_STAT_ACTIVE, &vf->vf_states); diff --git a/drivers/net/ethernet/intel/i40evf/i40e_adminq_cmd.h b/drivers/net/ethernet/intel/i40evf/i40e_adminq_cmd.h index f7cea1bca38d0..97662b6bd98a3 100644 --- a/drivers/net/ethernet/intel/i40evf/i40e_adminq_cmd.h +++ b/drivers/net/ethernet/intel/i40evf/i40e_adminq_cmd.h @@ -1229,7 +1229,7 @@ struct i40e_aqc_add_remove_cloud_filters_element_data { #define I40E_AQC_ADD_CLOUD_TNL_TYPE_NGE 2 #define I40E_AQC_ADD_CLOUD_TNL_TYPE_IP 3 - __le32 tenant_id ; + __le32 tenant_id; u8 reserved[4]; __le16 queue_number; #define I40E_AQC_ADD_CLOUD_QUEUE_SHIFT 0 diff --git a/drivers/net/ethernet/intel/i40evf/i40evf.h b/drivers/net/ethernet/intel/i40evf/i40evf.h index ef7ce65bc00ad..ccb43d343543f 100644 --- a/drivers/net/ethernet/intel/i40evf/i40evf.h +++ b/drivers/net/ethernet/intel/i40evf/i40evf.h @@ -196,8 +196,6 @@ struct i40evf_adapter { /* RX */ struct i40e_ring *rx_rings[I40E_MAX_VSI_QP]; - int txd_count; - int rxd_count; u64 hw_csum_rx_error; int num_msix_vectors; struct msix_entry *msix_entries; @@ -287,6 +285,7 @@ void i40evf_add_vlans(struct i40evf_adapter *adapter); void i40evf_del_vlans(struct i40evf_adapter *adapter); void i40evf_set_promiscuous(struct i40evf_adapter *adapter, int flags); void i40evf_request_stats(struct i40evf_adapter *adapter); +void i40evf_request_reset(struct i40evf_adapter *adapter); void i40evf_virtchnl_completion(struct i40evf_adapter *adapter, enum i40e_virtchnl_ops v_opcode, i40e_status v_retval, u8 *msg, u16 msglen); diff --git a/drivers/net/ethernet/intel/i40evf/i40evf_ethtool.c b/drivers/net/ethernet/intel/i40evf/i40evf_ethtool.c index b0b1f4bf5ac08..8b0db1ce179c5 100644 --- a/drivers/net/ethernet/intel/i40evf/i40evf_ethtool.c +++ b/drivers/net/ethernet/intel/i40evf/i40evf_ethtool.c @@ -1,7 +1,7 @@ /******************************************************************************* * * Intel Ethernet Controller XL710 Family Linux Virtual Function Driver - * Copyright(c) 2013 Intel Corporation. + * Copyright(c) 2013 - 2014 Intel Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms and conditions of the GNU General Public License, @@ -241,6 +241,7 @@ static int i40evf_set_ringparam(struct net_device *netdev, { struct i40evf_adapter *adapter = netdev_priv(netdev); u32 new_rx_count, new_tx_count; + int i; if ((ring->rx_mini_pending) || (ring->rx_jumbo_pending)) return -EINVAL; @@ -256,12 +257,14 @@ static int i40evf_set_ringparam(struct net_device *netdev, new_rx_count = ALIGN(new_rx_count, I40EVF_REQ_DESCRIPTOR_MULTIPLE); /* if nothing to do return success */ - if ((new_tx_count == adapter->txd_count) && - (new_rx_count == adapter->rxd_count)) + if ((new_tx_count == adapter->tx_rings[0]->count) && + (new_rx_count == adapter->rx_rings[0]->count)) return 0; - adapter->txd_count = new_tx_count; - adapter->rxd_count = new_rx_count; + for (i = 0; i < adapter->vsi_res->num_queue_pairs; i++) { + adapter->tx_rings[0]->count = new_tx_count; + adapter->rx_rings[0]->count = new_rx_count; + } if (netif_running(netdev)) i40evf_reinit_locked(adapter); diff --git a/drivers/net/ethernet/intel/i40evf/i40evf_main.c b/drivers/net/ethernet/intel/i40evf/i40evf_main.c index fe2271e19423a..b2c03bca79295 100644 --- a/drivers/net/ethernet/intel/i40evf/i40evf_main.c +++ b/drivers/net/ethernet/intel/i40evf/i40evf_main.c @@ -31,10 +31,10 @@ char i40evf_driver_name[] = "i40evf"; static const char i40evf_driver_string[] = "Intel(R) XL710 X710 Virtual Function Network Driver"; -#define DRV_VERSION "0.9.11" +#define DRV_VERSION "0.9.13" const char i40evf_driver_version[] = DRV_VERSION; static const char i40evf_copyright[] = - "Copyright (c) 2013 Intel Corporation."; + "Copyright (c) 2013 - 2014 Intel Corporation."; /* i40evf_pci_tbl - PCI Device ID Table * @@ -167,9 +167,13 @@ static void i40evf_tx_timeout(struct net_device *netdev) struct i40evf_adapter *adapter = netdev_priv(netdev); adapter->tx_timeout_count++; - - /* Do the reset outside of interrupt context */ - schedule_work(&adapter->reset_task); + dev_info(&adapter->pdev->dev, "TX timeout detected.\n"); + if (!(adapter->flags & I40EVF_FLAG_RESET_PENDING)) { + dev_info(&adapter->pdev->dev, "Requesting reset from PF\n"); + i40evf_request_reset(adapter); + adapter->flags |= I40EVF_FLAG_RESET_PENDING; + schedule_work(&adapter->reset_task); + } } /** @@ -211,6 +215,9 @@ static void i40evf_irq_disable(struct i40evf_adapter *adapter) int i; struct i40e_hw *hw = &adapter->hw; + if (!adapter->msix_entries) + return; + for (i = 1; i < adapter->num_msix_vectors; i++) { wr32(hw, I40E_VFINT_DYN_CTLN1(i - 1), 0); synchronize_irq(adapter->msix_entries[i].vector); @@ -517,7 +524,8 @@ static int i40evf_request_misc_irq(struct i40evf_adapter *adapter) adapter->misc_vector_name, netdev); if (err) { dev_err(&adapter->pdev->dev, - "request_irq for msix_aq failed: %d\n", err); + "request_irq for %s failed: %d\n", + adapter->misc_vector_name, err); free_irq(adapter->msix_entries[0].vector, netdev); } return err; @@ -968,9 +976,14 @@ void i40evf_down(struct i40evf_adapter *adapter) list_for_each_entry(f, &adapter->mac_filter_list, list) { f->remove = true; } + /* remove all VLAN filters */ + list_for_each_entry(f, &adapter->vlan_filter_list, list) { + f->remove = true; + } if (!(adapter->flags & I40EVF_FLAG_PF_COMMS_FAILED) && adapter->state != __I40EVF_RESETTING) { adapter->aq_required |= I40EVF_FLAG_AQ_DEL_MAC_FILTER; + adapter->aq_required |= I40EVF_FLAG_AQ_DEL_VLAN_FILTER; /* disable receives */ adapter->aq_required |= I40EVF_FLAG_AQ_DISABLE_QUEUES; mod_timer_pending(&adapter->watchdog_timer, jiffies + 1); @@ -1927,14 +1940,14 @@ static void i40evf_init_task(struct work_struct *work) adapter->flags &= ~I40EVF_FLAG_RESET_PENDING; err = i40e_set_mac_type(hw); if (err) { - dev_info(&pdev->dev, "%s: set_mac_type failed: %d\n", - __func__, err); + dev_err(&pdev->dev, "Failed to set MAC type (%d)\n", + err); goto err; } err = i40evf_check_reset_complete(hw); if (err) { - dev_info(&pdev->dev, "%s: device is still in reset (%d).\n", - __func__, err); + dev_err(&pdev->dev, "Device is still in reset (%d)\n", + err); goto err; } hw->aq.num_arq_entries = I40EVF_AQ_LEN; @@ -1944,14 +1957,14 @@ static void i40evf_init_task(struct work_struct *work) err = i40evf_init_adminq(hw); if (err) { - dev_info(&pdev->dev, "%s: init_adminq failed: %d\n", - __func__, err); + dev_err(&pdev->dev, "Failed to init Admin Queue (%d)\n", + err); goto err; } err = i40evf_send_api_ver(adapter); if (err) { - dev_info(&pdev->dev, "%s: unable to send to PF (%d)\n", - __func__, err); + dev_err(&pdev->dev, "Unable to send to PF (%d)\n", + err); i40evf_shutdown_adminq(hw); goto err; } @@ -1965,13 +1978,13 @@ static void i40evf_init_task(struct work_struct *work) /* aq msg sent, awaiting reply */ err = i40evf_verify_api_ver(adapter); if (err) { - dev_err(&pdev->dev, "Unable to verify API version, error %d\n", + dev_err(&pdev->dev, "Unable to verify API version (%d)\n", err); goto err; } err = i40evf_send_vf_config_msg(adapter); if (err) { - dev_err(&pdev->dev, "Unable send config request, error %d\n", + dev_err(&pdev->dev, "Unable send config request (%d)\n", err); goto err; } @@ -1985,18 +1998,15 @@ static void i40evf_init_task(struct work_struct *work) (I40E_MAX_VF_VSI * sizeof(struct i40e_virtchnl_vsi_resource)); adapter->vf_res = kzalloc(bufsz, GFP_KERNEL); - if (!adapter->vf_res) { - dev_err(&pdev->dev, "%s: unable to allocate memory\n", - __func__); + if (!adapter->vf_res) goto err; - } } err = i40evf_get_vf_config(adapter); if (err == I40E_ERR_ADMIN_QUEUE_NO_WORK) goto restart; if (err) { - dev_info(&pdev->dev, "%s: unable to get VF config (%d)\n", - __func__, err); + dev_err(&pdev->dev, "Unable to get VF config (%d)\n", + err); goto err_alloc; } adapter->state = __I40EVF_INIT_SW; @@ -2010,20 +2020,17 @@ static void i40evf_init_task(struct work_struct *work) adapter->vsi_res = &adapter->vf_res->vsi_res[i]; } if (!adapter->vsi_res) { - dev_info(&pdev->dev, "%s: no LAN VSI found\n", __func__); + dev_err(&pdev->dev, "No LAN VSI found\n"); goto err_alloc; } adapter->flags |= I40EVF_FLAG_RX_CSUM_ENABLED; - adapter->txd_count = I40EVF_DEFAULT_TXD; - adapter->rxd_count = I40EVF_DEFAULT_RXD; - netdev->netdev_ops = &i40evf_netdev_ops; i40evf_set_ethtool_ops(netdev); netdev->watchdog_timeo = 5 * HZ; - - netdev->features |= NETIF_F_SG | + netdev->features |= NETIF_F_HIGHDMA | + NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_SCTP_CSUM | NETIF_F_IPV6_CSUM | @@ -2039,11 +2046,9 @@ static void i40evf_init_task(struct work_struct *work) NETIF_F_HW_VLAN_CTAG_FILTER; } - /* The HW MAC address was set and/or determined in sw_init */ if (!is_valid_ether_addr(adapter->hw.mac.addr)) { - dev_info(&pdev->dev, - "Invalid MAC address %pMAC, using random\n", - adapter->hw.mac.addr); + dev_info(&pdev->dev, "Invalid MAC address %pMAC, using random\n", + adapter->hw.mac.addr); random_ether_addr(adapter->hw.mac.addr); } memcpy(netdev->dev_addr, adapter->hw.mac.addr, netdev->addr_len); @@ -2077,8 +2082,6 @@ static void i40evf_init_task(struct work_struct *work) netif_carrier_off(netdev); - strcpy(netdev->name, "eth%d"); - adapter->vsi.id = adapter->vsi_res->vsi_id; adapter->vsi.seid = adapter->vsi_res->vsi_id; /* dummy */ adapter->vsi.back = adapter; @@ -2168,20 +2171,18 @@ static int i40evf_probe(struct pci_dev *pdev, const struct pci_device_id *ent) struct net_device *netdev; struct i40evf_adapter *adapter = NULL; struct i40e_hw *hw = NULL; - int err, pci_using_dac; + int err; err = pci_enable_device(pdev); if (err) return err; if (!dma_set_mask(&pdev->dev, DMA_BIT_MASK(64))) { - pci_using_dac = true; /* coherent mask for the same size will always succeed if * dma_set_mask does */ dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(64)); } else if (!dma_set_mask(&pdev->dev, DMA_BIT_MASK(32))) { - pci_using_dac = false; dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32)); } else { dev_err(&pdev->dev, "%s: DMA configuration failed: %d\n", @@ -2212,8 +2213,6 @@ static int i40evf_probe(struct pci_dev *pdev, const struct pci_device_id *ent) pci_set_drvdata(pdev, netdev); adapter = netdev_priv(netdev); - if (pci_using_dac) - netdev->features |= NETIF_F_HIGHDMA; adapter->netdev = netdev; adapter->pdev = pdev; @@ -2363,17 +2362,15 @@ static void i40evf_remove(struct pci_dev *pdev) } adapter->state = __I40EVF_REMOVE; - if (adapter->num_msix_vectors) { + if (adapter->msix_entries) { i40evf_misc_irq_disable(adapter); - del_timer_sync(&adapter->watchdog_timer); - - flush_scheduled_work(); - i40evf_free_misc_irq(adapter); - i40evf_reset_interrupt_capability(adapter); } + del_timer_sync(&adapter->watchdog_timer); + flush_scheduled_work(); + if (hw->aq.asq.count) i40evf_shutdown_adminq(hw); diff --git a/drivers/net/ethernet/intel/i40evf/i40evf_virtchnl.c b/drivers/net/ethernet/intel/i40evf/i40evf_virtchnl.c index 93891a114d3f0..e294f012647d8 100644 --- a/drivers/net/ethernet/intel/i40evf/i40evf_virtchnl.c +++ b/drivers/net/ethernet/intel/i40evf/i40evf_virtchnl.c @@ -654,6 +654,18 @@ void i40evf_request_stats(struct i40evf_adapter *adapter) /* if the request failed, don't lock out others */ adapter->current_op = I40E_VIRTCHNL_OP_UNKNOWN; } +/** + * i40evf_request_reset + * @adapter: adapter structure + * + * Request that the PF reset this VF. No response is expected. + **/ +void i40evf_request_reset(struct i40evf_adapter *adapter) +{ + /* Don't check CURRENT_OP - this is always higher priority */ + i40evf_send_pf_msg(adapter, I40E_VIRTCHNL_OP_RESET_VF, NULL, 0); + adapter->current_op = I40E_VIRTCHNL_OP_UNKNOWN; +} /** * i40evf_virtchnl_completion