From 1bb8b9358ee0f6b297c4f33ca0a3a45338b5205c Mon Sep 17 00:00:00 2001 From: Shannon Nelson Date: Wed, 23 Apr 2014 04:49:54 +0000 Subject: [PATCH 01/13] i40e: set lan_veb index When the VEB is created for the basic LAN device and its VSIs, we need to set the tracking lan_veb index for later use. Change-ID: I66bb74993bbda3621ca557437cb4b3517f9b315b Signed-off-by: Shannon Nelson Tested-by: Kavindya Deegala Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/i40e/i40e_main.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c index 35e5ba4a7856..a08f5a01f623 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_main.c +++ b/drivers/net/ethernet/intel/i40e/i40e_main.c @@ -7735,6 +7735,8 @@ struct i40e_veb *i40e_veb_setup(struct i40e_pf *pf, u16 flags, ret = i40e_add_veb(veb, pf->vsi[vsi_idx]); if (ret) goto err_veb; + if (vsi_idx == pf->lan_vsi) + pf->lan_veb = veb->idx; return veb; From 8eab9cfda981fc0c84b9e14badba82cc124d42be Mon Sep 17 00:00:00 2001 From: Shannon Nelson Date: Wed, 23 Apr 2014 04:49:55 +0000 Subject: [PATCH 02/13] i40e: add VEB stats to ethtool Print the VEB statistics in the ethtool stats output. Change-ID: Ic93d4c3922345c43e4cfd7f7e7a906844dd2f49f Signed-off-by: Shannon Nelson Signed-off-by: Jeff Kirsher --- .../net/ethernet/intel/i40e/i40e_ethtool.c | 127 ++++++++++++------ 1 file changed, 84 insertions(+), 43 deletions(-) diff --git a/drivers/net/ethernet/intel/i40e/i40e_ethtool.c b/drivers/net/ethernet/intel/i40e/i40e_ethtool.c index 1bb470b94094..7f03b232975f 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_ethtool.c +++ b/drivers/net/ethernet/intel/i40e/i40e_ethtool.c @@ -46,6 +46,8 @@ struct i40e_stats { I40E_STAT(struct i40e_pf, _name, _stat) #define I40E_VSI_STAT(_name, _stat) \ I40E_STAT(struct i40e_vsi, _name, _stat) +#define I40E_VEB_STAT(_name, _stat) \ + I40E_STAT(struct i40e_veb, _name, _stat) static const struct i40e_stats i40e_gstrings_net_stats[] = { I40E_NETDEV_STAT(rx_packets), @@ -62,6 +64,21 @@ static const struct i40e_stats i40e_gstrings_net_stats[] = { I40E_NETDEV_STAT(rx_crc_errors), }; +static const struct i40e_stats i40e_gstrings_veb_stats[] = { + I40E_VEB_STAT("rx_bytes", stats.rx_bytes), + I40E_VEB_STAT("tx_bytes", stats.tx_bytes), + I40E_VEB_STAT("rx_unicast", stats.rx_unicast), + I40E_VEB_STAT("tx_unicast", stats.tx_unicast), + I40E_VEB_STAT("rx_multicast", stats.rx_multicast), + I40E_VEB_STAT("tx_multicast", stats.tx_multicast), + I40E_VEB_STAT("rx_broadcast", stats.rx_broadcast), + I40E_VEB_STAT("tx_broadcast", stats.tx_broadcast), + I40E_VEB_STAT("rx_discards", stats.rx_discards), + I40E_VEB_STAT("tx_discards", stats.tx_discards), + I40E_VEB_STAT("tx_errors", stats.tx_errors), + I40E_VEB_STAT("rx_unknown_protocol", stats.rx_unknown_protocol), +}; + static const struct i40e_stats i40e_gstrings_misc_stats[] = { I40E_VSI_STAT("rx_unknown_protocol", eth_stats.rx_unknown_protocol), I40E_VSI_STAT("rx_broadcast", eth_stats.rx_broadcast), @@ -142,6 +159,7 @@ static struct i40e_stats i40e_gstrings_stats[] = { FIELD_SIZEOF(struct i40e_pf, stats.priority_xon_tx) + \ FIELD_SIZEOF(struct i40e_pf, stats.priority_xon_2_xoff)) \ / sizeof(u64)) +#define I40E_VEB_STATS_LEN ARRAY_SIZE(i40e_gstrings_veb_stats) #define I40E_PF_STATS_LEN(n) (I40E_GLOBAL_STATS_LEN + \ I40E_PFC_STATS_LEN + \ I40E_VSI_STATS_LEN((n))) @@ -627,10 +645,15 @@ static int i40e_get_sset_count(struct net_device *netdev, int sset) case ETH_SS_TEST: return I40E_TEST_LEN; case ETH_SS_STATS: - if (vsi == pf->vsi[pf->lan_vsi]) - return I40E_PF_STATS_LEN(netdev); - else + if (vsi == pf->vsi[pf->lan_vsi]) { + int len = I40E_PF_STATS_LEN(netdev); + + if (pf->lan_veb != I40E_NO_VEB) + len += I40E_VEB_STATS_LEN; + return len; + } else { return I40E_VSI_STATS_LEN(netdev); + } default: return -EOPNOTSUPP; } @@ -686,23 +709,33 @@ static void i40e_get_ethtool_stats(struct net_device *netdev, i += 2; } rcu_read_unlock(); - if (vsi == pf->vsi[pf->lan_vsi]) { - for (j = 0; j < I40E_GLOBAL_STATS_LEN; j++) { - p = (char *)pf + i40e_gstrings_stats[j].stat_offset; - data[i++] = (i40e_gstrings_stats[j].sizeof_stat == - sizeof(u64)) ? *(u64 *)p : *(u32 *)p; + if (vsi != pf->vsi[pf->lan_vsi]) + return; + + if (pf->lan_veb != I40E_NO_VEB) { + struct i40e_veb *veb = pf->veb[pf->lan_veb]; + for (j = 0; j < I40E_VEB_STATS_LEN; j++) { + p = (char *)veb; + p += i40e_gstrings_veb_stats[j].stat_offset; + data[i++] = (i40e_gstrings_veb_stats[j].sizeof_stat == + sizeof(u64)) ? *(u64 *)p : *(u32 *)p; } - for (j = 0; j < I40E_MAX_USER_PRIORITY; j++) { - data[i++] = pf->stats.priority_xon_tx[j]; - data[i++] = pf->stats.priority_xoff_tx[j]; - } - for (j = 0; j < I40E_MAX_USER_PRIORITY; j++) { - data[i++] = pf->stats.priority_xon_rx[j]; - data[i++] = pf->stats.priority_xoff_rx[j]; - } - for (j = 0; j < I40E_MAX_USER_PRIORITY; j++) - data[i++] = pf->stats.priority_xon_2_xoff[j]; } + for (j = 0; j < I40E_GLOBAL_STATS_LEN; j++) { + p = (char *)pf + i40e_gstrings_stats[j].stat_offset; + data[i++] = (i40e_gstrings_stats[j].sizeof_stat == + sizeof(u64)) ? *(u64 *)p : *(u32 *)p; + } + for (j = 0; j < I40E_MAX_USER_PRIORITY; j++) { + data[i++] = pf->stats.priority_xon_tx[j]; + data[i++] = pf->stats.priority_xoff_tx[j]; + } + for (j = 0; j < I40E_MAX_USER_PRIORITY; j++) { + data[i++] = pf->stats.priority_xon_rx[j]; + data[i++] = pf->stats.priority_xoff_rx[j]; + } + for (j = 0; j < I40E_MAX_USER_PRIORITY; j++) + data[i++] = pf->stats.priority_xon_2_xoff[j]; } static void i40e_get_strings(struct net_device *netdev, u32 stringset, @@ -742,34 +775,42 @@ static void i40e_get_strings(struct net_device *netdev, u32 stringset, snprintf(p, ETH_GSTRING_LEN, "rx-%u.rx_bytes", i); p += ETH_GSTRING_LEN; } - if (vsi == pf->vsi[pf->lan_vsi]) { - for (i = 0; i < I40E_GLOBAL_STATS_LEN; i++) { - snprintf(p, ETH_GSTRING_LEN, "port.%s", - i40e_gstrings_stats[i].stat_string); - p += ETH_GSTRING_LEN; - } - for (i = 0; i < I40E_MAX_USER_PRIORITY; i++) { - snprintf(p, ETH_GSTRING_LEN, - "port.tx_priority_%u_xon", i); - p += ETH_GSTRING_LEN; - snprintf(p, ETH_GSTRING_LEN, - "port.tx_priority_%u_xoff", i); - p += ETH_GSTRING_LEN; - } - for (i = 0; i < I40E_MAX_USER_PRIORITY; i++) { - snprintf(p, ETH_GSTRING_LEN, - "port.rx_priority_%u_xon", i); - p += ETH_GSTRING_LEN; - snprintf(p, ETH_GSTRING_LEN, - "port.rx_priority_%u_xoff", i); - p += ETH_GSTRING_LEN; - } - for (i = 0; i < I40E_MAX_USER_PRIORITY; i++) { - snprintf(p, ETH_GSTRING_LEN, - "port.rx_priority_%u_xon_2_xoff", i); + if (vsi != pf->vsi[pf->lan_vsi]) + return; + + if (pf->lan_veb != I40E_NO_VEB) { + for (i = 0; i < I40E_VEB_STATS_LEN; i++) { + snprintf(p, ETH_GSTRING_LEN, "veb.%s", + i40e_gstrings_veb_stats[i].stat_string); p += ETH_GSTRING_LEN; } } + for (i = 0; i < I40E_GLOBAL_STATS_LEN; i++) { + snprintf(p, ETH_GSTRING_LEN, "port.%s", + i40e_gstrings_stats[i].stat_string); + p += ETH_GSTRING_LEN; + } + for (i = 0; i < I40E_MAX_USER_PRIORITY; i++) { + snprintf(p, ETH_GSTRING_LEN, + "port.tx_priority_%u_xon", i); + p += ETH_GSTRING_LEN; + snprintf(p, ETH_GSTRING_LEN, + "port.tx_priority_%u_xoff", i); + p += ETH_GSTRING_LEN; + } + for (i = 0; i < I40E_MAX_USER_PRIORITY; i++) { + snprintf(p, ETH_GSTRING_LEN, + "port.rx_priority_%u_xon", i); + p += ETH_GSTRING_LEN; + snprintf(p, ETH_GSTRING_LEN, + "port.rx_priority_%u_xoff", i); + p += ETH_GSTRING_LEN; + } + for (i = 0; i < I40E_MAX_USER_PRIORITY; i++) { + snprintf(p, ETH_GSTRING_LEN, + "port.rx_priority_%u_xon_2_xoff", i); + p += ETH_GSTRING_LEN; + } /* BUG_ON(p - data != I40E_STATS_LEN * ETH_GSTRING_LEN); */ break; } From 2c5fe33bdb7e1bd43f961b2850e45b4704ee0d5b Mon Sep 17 00:00:00 2001 From: Jesse Brandeburg Date: Wed, 23 Apr 2014 04:49:57 +0000 Subject: [PATCH 03/13] i40e: print message for pre-production hardware The driver and hardware are not expected to work correctly with revision_id 0 hardware. Don't prevent the user from using it, but be sure to print a warning. Change-ID: I3712d34752bfad458078a5f35dfd0aa0ae9fd20e Signed-off-by: Jesse Brandeburg Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/i40e/i40e_main.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c index a08f5a01f623..105d7547b4f2 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_main.c +++ b/drivers/net/ethernet/intel/i40e/i40e_main.c @@ -8298,6 +8298,10 @@ static int i40e_probe(struct pci_dev *pdev, const struct pci_device_id *ent) i40e_verify_eeprom(pf); + /* Rev 0 hardware was never productized */ + if (hw->revision_id < 1) + dev_warn(&pdev->dev, "This device is a pre-production adapter/LOM. Please be aware there may be issues with your hardware. If you are experiencing problems please contact your Intel or hardware representative who provided you with this hardware.\n"); + i40e_clear_pxe_mode(hw); err = i40e_get_capabilities(pf); if (err) From 0d9c7ea84bd8d8c73660b2a6ef5fb33570525aea Mon Sep 17 00:00:00 2001 From: Mitch Williams Date: Wed, 23 Apr 2014 04:50:00 +0000 Subject: [PATCH 04/13] i40evf: make messages less dire Depending on the timing of what the PF driver is doing, it make take a few tries before the VF driver is able to communicate with the PF driver on init or reset recovery. In order to prevent confusion, make the most common messages less scary by lowering them to a less terrifying log level and indicate that the driver will retry. Change-ID: I1ec22aa59a68f4469aabe14775a1bfc1ab4b7f2f Signed-off-by: Mitch Williams Tested-by: Sibai Li Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/i40evf/i40evf_main.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/intel/i40evf/i40evf_main.c b/drivers/net/ethernet/intel/i40evf/i40evf_main.c index d24f40f1673a..f6a2bdc54660 100644 --- a/drivers/net/ethernet/intel/i40evf/i40evf_main.c +++ b/drivers/net/ethernet/intel/i40evf/i40evf_main.c @@ -1963,7 +1963,7 @@ static void i40evf_init_task(struct work_struct *work) } err = i40evf_check_reset_complete(hw); if (err) { - dev_err(&pdev->dev, "Device is still in reset (%d)\n", + dev_info(&pdev->dev, "Device is still in reset (%d), retrying\n", err); goto err; } @@ -1996,7 +1996,7 @@ 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 (%d)\n", + dev_info(&pdev->dev, "Unable to verify API version (%d), retrying\n", err); goto err; } From e03af1e1cb9297904abe96f63db4b65a88372eb1 Mon Sep 17 00:00:00 2001 From: Kamil Krawczyk Date: Wed, 23 Apr 2014 04:50:02 +0000 Subject: [PATCH 05/13] i40e/i40evf: check AQ register for valid data B0 Si blocks AQ registers when in Blank Flash mode - write is dropped, read gives 0xDEADBEEF. Introduce a simple check for a correct value in one of the AQ registers to be sure that AQ was configured correctly. Without this check we get into an endless loop while trying to send GetVersion AQ cmd. Change-ID: I00102b8c5fa6c16d14289be677aafadf87f10f0d Signed-off-by: Kamil Krawczyk Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/i40e/i40e_adminq.c | 34 ++++++++++++++++--- .../net/ethernet/intel/i40evf/i40e_adminq.c | 34 ++++++++++++++++--- 2 files changed, 60 insertions(+), 8 deletions(-) diff --git a/drivers/net/ethernet/intel/i40e/i40e_adminq.c b/drivers/net/ethernet/intel/i40e/i40e_adminq.c index ba2811be8be4..7a027499fc57 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_adminq.c +++ b/drivers/net/ethernet/intel/i40e/i40e_adminq.c @@ -291,8 +291,11 @@ static void i40e_free_asq_bufs(struct i40e_hw *hw) * * Configure base address and length registers for the transmit queue **/ -static void i40e_config_asq_regs(struct i40e_hw *hw) +static i40e_status i40e_config_asq_regs(struct i40e_hw *hw) { + i40e_status ret_code = 0; + u32 reg = 0; + if (hw->mac.type == I40E_MAC_VF) { /* configure the transmit queue */ wr32(hw, I40E_VF_ATQBAH1, @@ -301,6 +304,7 @@ static void i40e_config_asq_regs(struct i40e_hw *hw) lower_32_bits(hw->aq.asq.desc_buf.pa)); wr32(hw, I40E_VF_ATQLEN1, (hw->aq.num_asq_entries | I40E_VF_ATQLEN1_ATQENABLE_MASK)); + reg = rd32(hw, I40E_VF_ATQBAL1); } else { /* configure the transmit queue */ wr32(hw, I40E_PF_ATQBAH, @@ -309,7 +313,14 @@ static void i40e_config_asq_regs(struct i40e_hw *hw) lower_32_bits(hw->aq.asq.desc_buf.pa)); wr32(hw, I40E_PF_ATQLEN, (hw->aq.num_asq_entries | I40E_PF_ATQLEN_ATQENABLE_MASK)); + reg = rd32(hw, I40E_PF_ATQBAL); } + + /* Check one register to verify that config was applied */ + if (reg != lower_32_bits(hw->aq.asq.desc_buf.pa)) + ret_code = I40E_ERR_ADMIN_QUEUE_ERROR; + + return ret_code; } /** @@ -318,8 +329,11 @@ static void i40e_config_asq_regs(struct i40e_hw *hw) * * Configure base address and length registers for the receive (event queue) **/ -static void i40e_config_arq_regs(struct i40e_hw *hw) +static i40e_status i40e_config_arq_regs(struct i40e_hw *hw) { + i40e_status ret_code = 0; + u32 reg = 0; + if (hw->mac.type == I40E_MAC_VF) { /* configure the receive queue */ wr32(hw, I40E_VF_ARQBAH1, @@ -328,6 +342,7 @@ static void i40e_config_arq_regs(struct i40e_hw *hw) lower_32_bits(hw->aq.arq.desc_buf.pa)); wr32(hw, I40E_VF_ARQLEN1, (hw->aq.num_arq_entries | I40E_VF_ARQLEN1_ARQENABLE_MASK)); + reg = rd32(hw, I40E_VF_ARQBAL1); } else { /* configure the receive queue */ wr32(hw, I40E_PF_ARQBAH, @@ -336,10 +351,17 @@ static void i40e_config_arq_regs(struct i40e_hw *hw) lower_32_bits(hw->aq.arq.desc_buf.pa)); wr32(hw, I40E_PF_ARQLEN, (hw->aq.num_arq_entries | I40E_PF_ARQLEN_ARQENABLE_MASK)); + reg = rd32(hw, I40E_PF_ARQBAL); } /* Update tail in the HW to post pre-allocated buffers */ wr32(hw, hw->aq.arq.tail, hw->aq.num_arq_entries - 1); + + /* Check one register to verify that config was applied */ + if (reg != lower_32_bits(hw->aq.arq.desc_buf.pa)) + ret_code = I40E_ERR_ADMIN_QUEUE_ERROR; + + return ret_code; } /** @@ -387,7 +409,9 @@ static i40e_status i40e_init_asq(struct i40e_hw *hw) goto init_adminq_free_rings; /* initialize base registers */ - i40e_config_asq_regs(hw); + ret_code = i40e_config_asq_regs(hw); + if (ret_code) + goto init_adminq_free_rings; /* success! */ goto init_adminq_exit; @@ -444,7 +468,9 @@ static i40e_status i40e_init_arq(struct i40e_hw *hw) goto init_adminq_free_rings; /* initialize base registers */ - i40e_config_arq_regs(hw); + ret_code = i40e_config_arq_regs(hw); + if (ret_code) + goto init_adminq_free_rings; /* success! */ goto init_adminq_exit; diff --git a/drivers/net/ethernet/intel/i40evf/i40e_adminq.c b/drivers/net/ethernet/intel/i40evf/i40e_adminq.c index 68b4aacd43f5..eb67cce3e8f9 100644 --- a/drivers/net/ethernet/intel/i40evf/i40e_adminq.c +++ b/drivers/net/ethernet/intel/i40evf/i40e_adminq.c @@ -289,8 +289,11 @@ static void i40e_free_asq_bufs(struct i40e_hw *hw) * * Configure base address and length registers for the transmit queue **/ -static void i40e_config_asq_regs(struct i40e_hw *hw) +static i40e_status i40e_config_asq_regs(struct i40e_hw *hw) { + i40e_status ret_code = 0; + u32 reg = 0; + if (hw->mac.type == I40E_MAC_VF) { /* configure the transmit queue */ wr32(hw, I40E_VF_ATQBAH1, @@ -299,6 +302,7 @@ static void i40e_config_asq_regs(struct i40e_hw *hw) lower_32_bits(hw->aq.asq.desc_buf.pa)); wr32(hw, I40E_VF_ATQLEN1, (hw->aq.num_asq_entries | I40E_VF_ATQLEN1_ATQENABLE_MASK)); + reg = rd32(hw, I40E_VF_ATQBAL1); } else { /* configure the transmit queue */ wr32(hw, I40E_PF_ATQBAH, @@ -307,7 +311,14 @@ static void i40e_config_asq_regs(struct i40e_hw *hw) lower_32_bits(hw->aq.asq.desc_buf.pa)); wr32(hw, I40E_PF_ATQLEN, (hw->aq.num_asq_entries | I40E_PF_ATQLEN_ATQENABLE_MASK)); + reg = rd32(hw, I40E_PF_ATQBAL); } + + /* Check one register to verify that config was applied */ + if (reg != lower_32_bits(hw->aq.asq.desc_buf.pa)) + ret_code = I40E_ERR_ADMIN_QUEUE_ERROR; + + return ret_code; } /** @@ -316,8 +327,11 @@ static void i40e_config_asq_regs(struct i40e_hw *hw) * * Configure base address and length registers for the receive (event queue) **/ -static void i40e_config_arq_regs(struct i40e_hw *hw) +static i40e_status i40e_config_arq_regs(struct i40e_hw *hw) { + i40e_status ret_code = 0; + u32 reg = 0; + if (hw->mac.type == I40E_MAC_VF) { /* configure the receive queue */ wr32(hw, I40E_VF_ARQBAH1, @@ -326,6 +340,7 @@ static void i40e_config_arq_regs(struct i40e_hw *hw) lower_32_bits(hw->aq.arq.desc_buf.pa)); wr32(hw, I40E_VF_ARQLEN1, (hw->aq.num_arq_entries | I40E_VF_ARQLEN1_ARQENABLE_MASK)); + reg = rd32(hw, I40E_VF_ARQBAL1); } else { /* configure the receive queue */ wr32(hw, I40E_PF_ARQBAH, @@ -334,10 +349,17 @@ static void i40e_config_arq_regs(struct i40e_hw *hw) lower_32_bits(hw->aq.arq.desc_buf.pa)); wr32(hw, I40E_PF_ARQLEN, (hw->aq.num_arq_entries | I40E_PF_ARQLEN_ARQENABLE_MASK)); + reg = rd32(hw, I40E_PF_ARQBAL); } /* Update tail in the HW to post pre-allocated buffers */ wr32(hw, hw->aq.arq.tail, hw->aq.num_arq_entries - 1); + + /* Check one register to verify that config was applied */ + if (reg != lower_32_bits(hw->aq.arq.desc_buf.pa)) + ret_code = I40E_ERR_ADMIN_QUEUE_ERROR; + + return ret_code; } /** @@ -385,7 +407,9 @@ static i40e_status i40e_init_asq(struct i40e_hw *hw) goto init_adminq_free_rings; /* initialize base registers */ - i40e_config_asq_regs(hw); + ret_code = i40e_config_asq_regs(hw); + if (ret_code) + goto init_adminq_free_rings; /* success! */ goto init_adminq_exit; @@ -442,7 +466,9 @@ static i40e_status i40e_init_arq(struct i40e_hw *hw) goto init_adminq_free_rings; /* initialize base registers */ - i40e_config_arq_regs(hw); + ret_code = i40e_config_arq_regs(hw); + if (ret_code) + goto init_adminq_free_rings; /* success! */ goto init_adminq_exit; From 351499ab2e3f7020ee9a4fbdacaed644984ad359 Mon Sep 17 00:00:00 2001 From: Matt Jared Date: Wed, 23 Apr 2014 04:50:03 +0000 Subject: [PATCH 06/13] i40e/i40evf: add Tx pre queue disable function Add a function which indicates our intention to enable or disable a particular Tx queue. Also add a function to notify the device's Tx unit that we're about to enable or disable a Tx queue. Change-ID: I6adf3cbb5bb3e3c984d1ec969e06577c19ef296d Signed-off-by: Matt Jared Signed-off-by: Shannon Nelson Tested-by: Jim Young Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/i40e/i40e_common.c | 31 +++++++++++++++++++ drivers/net/ethernet/intel/i40e/i40e_main.c | 6 ++++ .../net/ethernet/intel/i40e/i40e_prototype.h | 1 + .../net/ethernet/intel/i40e/i40e_register.h | 8 +++++ .../net/ethernet/intel/i40evf/i40e_register.h | 8 +++++ 5 files changed, 54 insertions(+) diff --git a/drivers/net/ethernet/intel/i40e/i40e_common.c b/drivers/net/ethernet/intel/i40e/i40e_common.c index a31e3d755aea..36607b0a0774 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_common.c +++ b/drivers/net/ethernet/intel/i40e/i40e_common.c @@ -656,6 +656,37 @@ i40e_status i40e_get_mac_addr(struct i40e_hw *hw, u8 *mac_addr) return status; } +/** + * i40e_pre_tx_queue_cfg - pre tx queue configure + * @hw: pointer to the HW structure + * @queue: target pf queue index + * @enable: state change request + * + * Handles hw requirement to indicate intention to enable + * or disable target queue. + **/ +void i40e_pre_tx_queue_cfg(struct i40e_hw *hw, u32 queue, bool enable) +{ + u32 reg_val = rd32(hw, I40E_PFLAN_QALLOC); + u32 first_queue = (reg_val & I40E_PFLAN_QALLOC_FIRSTQ_MASK); + u32 abs_queue_idx = first_queue + queue; + u32 reg_block = 0; + + if (abs_queue_idx >= 128) + reg_block = abs_queue_idx / 128; + + reg_val = rd32(hw, I40E_GLLAN_TXPRE_QDIS(reg_block)); + reg_val &= ~I40E_GLLAN_TXPRE_QDIS_QINDX_MASK; + reg_val |= (abs_queue_idx << I40E_GLLAN_TXPRE_QDIS_QINDX_SHIFT); + + if (enable) + reg_val |= I40E_GLLAN_TXPRE_QDIS_CLEAR_QDIS_MASK; + else + reg_val |= I40E_GLLAN_TXPRE_QDIS_SET_QDIS_MASK; + + wr32(hw, I40E_GLLAN_TXPRE_QDIS(reg_block), reg_val); +} + /** * i40e_get_media_type - Gets media type * @hw: pointer to the hardware structure diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c index 105d7547b4f2..726ecebeb02a 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_main.c +++ b/drivers/net/ethernet/intel/i40e/i40e_main.c @@ -3183,6 +3183,12 @@ 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++) { + + /* warn the TX unit of coming changes */ + i40e_pre_tx_queue_cfg(&pf->hw, pf_q, enable); + if (!enable) + udelay(10); + for (j = 0; j < 50; j++) { tx_reg = rd32(hw, I40E_QTX_ENA(pf_q)); if (((tx_reg >> I40E_QTX_ENA_QENA_REQ_SHIFT) & 1) == diff --git a/drivers/net/ethernet/intel/i40e/i40e_prototype.h b/drivers/net/ethernet/intel/i40e/i40e_prototype.h index 57172f98f9f8..58c4e1eba5bf 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_prototype.h +++ b/drivers/net/ethernet/intel/i40e/i40e_prototype.h @@ -221,6 +221,7 @@ bool i40e_get_link_status(struct i40e_hw *hw); i40e_status i40e_get_mac_addr(struct i40e_hw *hw, u8 *mac_addr); i40e_status i40e_validate_mac_addr(u8 *mac_addr); +void i40e_pre_tx_queue_cfg(struct i40e_hw *hw, u32 queue, bool enable); /* prototype for functions used for NVM access */ i40e_status i40e_init_nvm(struct i40e_hw *hw); i40e_status i40e_acquire_nvm(struct i40e_hw *hw, diff --git a/drivers/net/ethernet/intel/i40e/i40e_register.h b/drivers/net/ethernet/intel/i40e/i40e_register.h index 25c928615f55..947de98500f3 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_register.h +++ b/drivers/net/ethernet/intel/i40e/i40e_register.h @@ -1585,6 +1585,14 @@ #define I40E_GLLAN_TSOMSK_M 0x000442DC #define I40E_GLLAN_TSOMSK_M_TCPMSKM_SHIFT 0 #define I40E_GLLAN_TSOMSK_M_TCPMSKM_MASK (0xFFF << I40E_GLLAN_TSOMSK_M_TCPMSKM_SHIFT) +#define I40E_GLLAN_TXPRE_QDIS(_i) (0x000E6500 + ((_i) * 4)) /* i=0..11 */ +#define I40E_GLLAN_TXPRE_QDIS_QINDX_SHIFT 0 +#define I40E_GLLAN_TXPRE_QDIS_QINDX_MASK (0x7FF << I40E_GLLAN_TXPRE_QDIS_QINDX_SHIFT) +#define I40E_GLLAN_TXPRE_QDIS_SET_QDIS_SHIFT 30 +#define I40E_GLLAN_TXPRE_QDIS_SET_QDIS_MASK (0x1 << I40E_GLLAN_TXPRE_QDIS_SET_QDIS_SHIFT) +#define I40E_GLLAN_TXPRE_QDIS_CLEAR_QDIS_SHIFT 31 +#define I40E_GLLAN_TXPRE_QDIS_CLEAR_QDIS_MASK (0x1 << I40E_GLLAN_TXPRE_QDIS_CLEAR_QDIS_SHIFT) + #define I40E_PFLAN_QALLOC 0x001C0400 #define I40E_PFLAN_QALLOC_FIRSTQ_SHIFT 0 #define I40E_PFLAN_QALLOC_FIRSTQ_MASK (0x7FF << I40E_PFLAN_QALLOC_FIRSTQ_SHIFT) diff --git a/drivers/net/ethernet/intel/i40evf/i40e_register.h b/drivers/net/ethernet/intel/i40evf/i40e_register.h index 7977205b1e04..369839655818 100644 --- a/drivers/net/ethernet/intel/i40evf/i40e_register.h +++ b/drivers/net/ethernet/intel/i40evf/i40e_register.h @@ -1585,6 +1585,14 @@ #define I40E_GLLAN_TSOMSK_M 0x000442DC #define I40E_GLLAN_TSOMSK_M_TCPMSKM_SHIFT 0 #define I40E_GLLAN_TSOMSK_M_TCPMSKM_MASK (0xFFF << I40E_GLLAN_TSOMSK_M_TCPMSKM_SHIFT) +#define I40E_GLLAN_TXPRE_QDIS(_i) (0x000E6500 + ((_i) * 4)) /* i=0..11 */ +#define I40E_GLLAN_TXPRE_QDIS_QINDX_SHIFT 0 +#define I40E_GLLAN_TXPRE_QDIS_QINDX_MASK (0x7FF << I40E_GLLAN_TXPRE_QDIS_QINDX_SHIFT) +#define I40E_GLLAN_TXPRE_QDIS_SET_QDIS_SHIFT 30 +#define I40E_GLLAN_TXPRE_QDIS_SET_QDIS_MASK (0x1 << I40E_GLLAN_TXPRE_QDIS_SET_QDIS_SHIFT) +#define I40E_GLLAN_TXPRE_QDIS_CLEAR_QDIS_SHIFT 31 +#define I40E_GLLAN_TXPRE_QDIS_CLEAR_QDIS_MASK (0x1 << I40E_GLLAN_TXPRE_QDIS_CLEAR_QDIS_SHIFT) + #define I40E_PFLAN_QALLOC 0x001C0400 #define I40E_PFLAN_QALLOC_FIRSTQ_SHIFT 0 #define I40E_PFLAN_QALLOC_FIRSTQ_MASK (0x7FF << I40E_PFLAN_QALLOC_FIRSTQ_SHIFT) From d0ff56879ae82ae58e12459b3d5573a70c21b8e2 Mon Sep 17 00:00:00 2001 From: Shannon Nelson Date: Wed, 23 Apr 2014 04:50:06 +0000 Subject: [PATCH 07/13] i40e: increase reset wait time The wait time was originally too optimistic and the resets were failing after EMPR. This increases the loop count to wait considerably longer. This won't delay the actual wait longer than really needed, just allows us to poll more times as needed. Change-ID: If7b96f55cc25b8d06cbbe8665259d250188c53d7 Signed-off-by: Shannon Nelson Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/i40e/i40e_common.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/ethernet/intel/i40e/i40e_common.c b/drivers/net/ethernet/intel/i40e/i40e_common.c index 36607b0a0774..fd2b573d3050 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_common.c +++ b/drivers/net/ethernet/intel/i40e/i40e_common.c @@ -734,7 +734,7 @@ static enum i40e_media_type i40e_get_media_type(struct i40e_hw *hw) } #define I40E_PF_RESET_WAIT_COUNT_A0 200 -#define I40E_PF_RESET_WAIT_COUNT 10 +#define I40E_PF_RESET_WAIT_COUNT 100 /** * i40e_pf_reset - Reset the PF * @hw: pointer to the hardware structure From 418631d4c5c2a7d39cf43cb0d07de639835777bd Mon Sep 17 00:00:00 2001 From: Shannon Nelson Date: Wed, 23 Apr 2014 04:50:07 +0000 Subject: [PATCH 08/13] i40e: add vsi x-cast stats Add VSI HW stats for unicast, multicast, and broadcast for Rx and Tx. Stop printing the netdev multicast value because it doesn't include Tx and would be confusing. Change-ID: I08278b6657e7c838fd29a4a1f305f78fe1b150be Signed-off-by: Shannon Nelson Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/i40e/i40e_ethtool.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/intel/i40e/i40e_ethtool.c b/drivers/net/ethernet/intel/i40e/i40e_ethtool.c index 7f03b232975f..d910b88510c7 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_ethtool.c +++ b/drivers/net/ethernet/intel/i40e/i40e_ethtool.c @@ -58,7 +58,6 @@ static const struct i40e_stats i40e_gstrings_net_stats[] = { I40E_NETDEV_STAT(tx_errors), I40E_NETDEV_STAT(rx_dropped), I40E_NETDEV_STAT(tx_dropped), - I40E_NETDEV_STAT(multicast), I40E_NETDEV_STAT(collisions), I40E_NETDEV_STAT(rx_length_errors), I40E_NETDEV_STAT(rx_crc_errors), @@ -80,9 +79,13 @@ static const struct i40e_stats i40e_gstrings_veb_stats[] = { }; static const struct i40e_stats i40e_gstrings_misc_stats[] = { - I40E_VSI_STAT("rx_unknown_protocol", eth_stats.rx_unknown_protocol), + I40E_VSI_STAT("rx_unicast", eth_stats.rx_unicast), + I40E_VSI_STAT("tx_unicast", eth_stats.tx_unicast), + I40E_VSI_STAT("rx_multicast", eth_stats.rx_multicast), + I40E_VSI_STAT("tx_multicast", eth_stats.tx_multicast), I40E_VSI_STAT("rx_broadcast", eth_stats.rx_broadcast), I40E_VSI_STAT("tx_broadcast", eth_stats.tx_broadcast), + I40E_VSI_STAT("rx_unknown_protocol", eth_stats.rx_unknown_protocol), }; static int i40e_add_fdir_ethtool(struct i40e_vsi *vsi, From 532d283d590d6c01457e71d59fdd5eb525a4d392 Mon Sep 17 00:00:00 2001 From: Shannon Nelson Date: Wed, 23 Apr 2014 04:50:09 +0000 Subject: [PATCH 09/13] i40e: add xcast stats for port Add the missing unicast, multicast, and broadcast stats for the port. Change-ID: Ifc366d7b7745f70eaac9d00eeb0694eb9ec076a9 Signed-off-by: Shannon Nelson Signed-off-by: Jeff Kirsher --- .../net/ethernet/intel/i40e/i40e_ethtool.c | 6 +++++ drivers/net/ethernet/intel/i40e/i40e_main.c | 26 +++++++++++++++++++ 2 files changed, 32 insertions(+) diff --git a/drivers/net/ethernet/intel/i40e/i40e_ethtool.c b/drivers/net/ethernet/intel/i40e/i40e_ethtool.c index d910b88510c7..df3917b68c99 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_ethtool.c +++ b/drivers/net/ethernet/intel/i40e/i40e_ethtool.c @@ -104,6 +104,12 @@ static int i40e_add_fdir_ethtool(struct i40e_vsi *vsi, static struct i40e_stats i40e_gstrings_stats[] = { I40E_PF_STAT("rx_bytes", stats.eth.rx_bytes), I40E_PF_STAT("tx_bytes", stats.eth.tx_bytes), + I40E_PF_STAT("rx_unicast", stats.eth.rx_unicast), + I40E_PF_STAT("tx_unicast", stats.eth.tx_unicast), + I40E_PF_STAT("rx_multicast", stats.eth.rx_multicast), + I40E_PF_STAT("tx_multicast", stats.eth.tx_multicast), + I40E_PF_STAT("rx_broadcast", stats.eth.rx_broadcast), + I40E_PF_STAT("tx_broadcast", stats.eth.tx_broadcast), I40E_PF_STAT("tx_errors", stats.eth.tx_errors), I40E_PF_STAT("rx_dropped", stats.eth.rx_discards), I40E_PF_STAT("tx_dropped", stats.eth.tx_discards), diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c index 726ecebeb02a..e9cd9bb16f39 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_main.c +++ b/drivers/net/ethernet/intel/i40e/i40e_main.c @@ -854,11 +854,37 @@ static void i40e_update_pf_stats(struct i40e_pf *pf) pf->stat_offsets_loaded, &osd->eth.tx_discards, &nsd->eth.tx_discards); + + i40e_stat_update48(hw, I40E_GLPRT_UPRCH(hw->port), + I40E_GLPRT_UPRCL(hw->port), + pf->stat_offsets_loaded, + &osd->eth.rx_unicast, + &nsd->eth.rx_unicast); i40e_stat_update48(hw, I40E_GLPRT_MPRCH(hw->port), I40E_GLPRT_MPRCL(hw->port), pf->stat_offsets_loaded, &osd->eth.rx_multicast, &nsd->eth.rx_multicast); + i40e_stat_update48(hw, I40E_GLPRT_BPRCH(hw->port), + I40E_GLPRT_BPRCL(hw->port), + pf->stat_offsets_loaded, + &osd->eth.rx_broadcast, + &nsd->eth.rx_broadcast); + i40e_stat_update48(hw, I40E_GLPRT_UPTCH(hw->port), + I40E_GLPRT_UPTCL(hw->port), + pf->stat_offsets_loaded, + &osd->eth.tx_unicast, + &nsd->eth.tx_unicast); + i40e_stat_update48(hw, I40E_GLPRT_MPTCH(hw->port), + I40E_GLPRT_MPTCL(hw->port), + pf->stat_offsets_loaded, + &osd->eth.tx_multicast, + &nsd->eth.tx_multicast); + i40e_stat_update48(hw, I40E_GLPRT_BPTCH(hw->port), + I40E_GLPRT_BPTCL(hw->port), + pf->stat_offsets_loaded, + &osd->eth.tx_broadcast, + &nsd->eth.tx_broadcast); i40e_stat_update32(hw, I40E_GLPRT_TDOLD(hw->port), pf->stat_offsets_loaded, From cf05ed083104d93f661c77f46130c8f46a896714 Mon Sep 17 00:00:00 2001 From: Jesse Brandeburg Date: Wed, 23 Apr 2014 04:50:12 +0000 Subject: [PATCH 10/13] i40e: print full link message The i40e driver should print link messages like all the other Intel Ethernet drivers. Change-ID: Ia88bdb96794e17a3962fcea94db176de01f921f7 Signed-off-by: Jesse Brandeburg Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/i40e/i40e_main.c | 56 +++++++++++++++++++-- 1 file changed, 51 insertions(+), 5 deletions(-) diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c index e9cd9bb16f39..484ada9758bb 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_main.c +++ b/drivers/net/ethernet/intel/i40e/i40e_main.c @@ -4135,6 +4135,54 @@ out: return err; } #endif /* CONFIG_I40E_DCB */ +#define SPEED_SIZE 14 +#define FC_SIZE 8 +/** + * i40e_print_link_message - print link up or down + * @vsi: the VSI for which link needs a message + */ +static void i40e_print_link_message(struct i40e_vsi *vsi, bool isup) +{ + char speed[SPEED_SIZE] = "Unknown"; + char fc[FC_SIZE] = "RX/TX"; + + if (!isup) { + netdev_info(vsi->netdev, "NIC Link is Down\n"); + return; + } + + switch (vsi->back->hw.phy.link_info.link_speed) { + case I40E_LINK_SPEED_40GB: + strncpy(speed, "40 Gbps", SPEED_SIZE); + break; + case I40E_LINK_SPEED_10GB: + strncpy(speed, "10 Gbps", SPEED_SIZE); + break; + case I40E_LINK_SPEED_1GB: + strncpy(speed, "1000 Mbps", SPEED_SIZE); + break; + default: + break; + } + + switch (vsi->back->hw.fc.current_mode) { + case I40E_FC_FULL: + strncpy(fc, "RX/TX", FC_SIZE); + break; + case I40E_FC_TX_PAUSE: + strncpy(fc, "TX", FC_SIZE); + break; + case I40E_FC_RX_PAUSE: + strncpy(fc, "RX", FC_SIZE); + break; + default: + strncpy(fc, "None", FC_SIZE); + break; + } + + netdev_info(vsi->netdev, "NIC Link is Up %s Full Duplex, Flow Control: %s\n", + speed, fc); +} /** * i40e_up_complete - Finish the last steps of bringing up a connection @@ -4161,11 +4209,11 @@ static int i40e_up_complete(struct i40e_vsi *vsi) if ((pf->hw.phy.link_info.link_info & I40E_AQ_LINK_UP) && (vsi->netdev)) { - netdev_info(vsi->netdev, "NIC Link is Up\n"); + i40e_print_link_message(vsi, true); netif_tx_start_all_queues(vsi->netdev); netif_carrier_on(vsi->netdev); } else if (vsi->netdev) { - netdev_info(vsi->netdev, "NIC Link is Down\n"); + i40e_print_link_message(vsi, false); } /* replay FDIR SB filters */ @@ -4886,10 +4934,8 @@ static void i40e_link_event(struct i40e_pf *pf) if (new_link == old_link) return; - if (!test_bit(__I40E_DOWN, &pf->vsi[pf->lan_vsi]->state)) - netdev_info(pf->vsi[pf->lan_vsi]->netdev, - "NIC Link is %s\n", (new_link ? "Up" : "Down")); + i40e_print_link_message(pf->vsi[pf->lan_vsi], new_link); /* Notify the base of the switch tree connected to * the link. Floating VEBs are not notified. From 60442dea2e9314b472c772c76ed1b2ba5b961e02 Mon Sep 17 00:00:00 2001 From: Shannon Nelson Date: Wed, 23 Apr 2014 04:50:13 +0000 Subject: [PATCH 11/13] i40e: don't remove HMC that doesn't exist If a reset recovery failed (e.g. firmware is broken), the HMC space won't get set up. We don't need to try to delete it if it didn't get set up. This stops some needless error messages when we already know we need to just tear things down. Change-ID: Iac600481765e20b136052b43a544e55d7870268b Signed-off-by: Shannon Nelson Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/i40e/i40e_main.c | 24 +++++++++++++-------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c index 484ada9758bb..52bd69d38d9c 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_main.c +++ b/drivers/net/ethernet/intel/i40e/i40e_main.c @@ -5429,7 +5429,7 @@ static void i40e_fdir_teardown(struct i40e_pf *pf) static int i40e_prep_for_reset(struct i40e_pf *pf) { struct i40e_hw *hw = &pf->hw; - i40e_status ret; + i40e_status ret = 0; u32 v; clear_bit(__I40E_RESET_INTR_RECEIVED, &pf->state); @@ -5449,10 +5449,13 @@ static int i40e_prep_for_reset(struct i40e_pf *pf) i40e_shutdown_adminq(&pf->hw); /* call shutdown HMC */ - ret = i40e_shutdown_lan_hmc(hw); - if (ret) { - dev_info(&pf->pdev->dev, "shutdown_lan_hmc failed: %d\n", ret); - clear_bit(__I40E_RESET_RECOVERY_PENDING, &pf->state); + if (hw->hmc.hmc_obj) { + ret = i40e_shutdown_lan_hmc(hw); + if (ret) { + dev_warn(&pf->pdev->dev, + "shutdown_lan_hmc failed: %d\n", ret); + clear_bit(__I40E_RESET_RECOVERY_PENDING, &pf->state); + } } return ret; } @@ -8637,10 +8640,13 @@ static void i40e_remove(struct pci_dev *pdev) } /* shutdown and destroy the HMC */ - ret_code = i40e_shutdown_lan_hmc(&pf->hw); - if (ret_code) - dev_warn(&pdev->dev, - "Failed to destroy the HMC resources: %d\n", ret_code); + if (pf->hw.hmc.hmc_obj) { + ret_code = i40e_shutdown_lan_hmc(&pf->hw); + if (ret_code) + dev_warn(&pdev->dev, + "Failed to destroy the HMC resources: %d\n", + ret_code); + } /* shutdown the adminq */ ret_code = i40e_shutdown_adminq(&pf->hw); From 6374184672c8e405640ab57ea9ad1cb7ed4fa669 Mon Sep 17 00:00:00 2001 From: Shannon Nelson Date: Wed, 23 Apr 2014 04:50:16 +0000 Subject: [PATCH 12/13] i40e: remove irqs only when they are set up Use an extra state variable to keep track of when the IRQs are fully set up. This keeps us from trying to unhook IRQs that already were left unhooked in a failed reset recovery, e.g. when firmware is broken. Change-ID: I073eb081e4ef8aedcbdf1ee0717c0ed64fa172f2 Signed-off-by: Shannon Nelson Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/i40e/i40e.h | 1 + drivers/net/ethernet/intel/i40e/i40e_main.c | 6 ++++++ 2 files changed, 7 insertions(+) diff --git a/drivers/net/ethernet/intel/i40e/i40e.h b/drivers/net/ethernet/intel/i40e/i40e.h index 581898f23223..9c27d8b657b2 100644 --- a/drivers/net/ethernet/intel/i40e/i40e.h +++ b/drivers/net/ethernet/intel/i40e/i40e.h @@ -414,6 +414,7 @@ struct i40e_vsi { struct i40e_q_vector **q_vectors; int num_q_vectors; int base_vector; + bool irqs_ready; u16 seid; /* HW index of this VSI (absolute index) */ u16 id; /* VSI number */ diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c index 52bd69d38d9c..029288e1bb98 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_main.c +++ b/drivers/net/ethernet/intel/i40e/i40e_main.c @@ -2790,6 +2790,7 @@ static int i40e_vsi_request_irq_msix(struct i40e_vsi *vsi, char *basename) &q_vector->affinity_mask); } + vsi->irqs_ready = true; return 0; free_queue_irqs: @@ -3349,6 +3350,10 @@ static void i40e_vsi_free_irq(struct i40e_vsi *vsi) if (!vsi->q_vectors) return; + if (!vsi->irqs_ready) + return; + + vsi->irqs_ready = false; for (i = 0; i < vsi->num_q_vectors; i++) { u16 vector = i + base; @@ -5953,6 +5958,7 @@ static int i40e_vsi_mem_alloc(struct i40e_pf *pf, enum i40e_vsi_type type) vsi->netdev_registered = false; vsi->work_limit = I40E_DEFAULT_IRQ_WORK; INIT_LIST_HEAD(&vsi->mac_filter_list); + vsi->irqs_ready = false; ret = i40e_set_num_rings_in_vsi(vsi); if (ret) From e454d6bfae8631b3ebd3d9735b2e8b2aa49639be Mon Sep 17 00:00:00 2001 From: Catherine Sullivan Date: Wed, 23 Apr 2014 04:50:17 +0000 Subject: [PATCH 13/13] i40e/i40evf: Bump build version Bump i40e to 0.4.3 and i40evf to 0.9.27. Change-ID: I4141e9f8615bdcfa3b1b5ecbc2ac62603a03b7ad Signed-off-by: Catherine Sullivan Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/i40e/i40e_main.c | 4 ++-- drivers/net/ethernet/intel/i40evf/i40evf_main.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c index 029288e1bb98..63147a61677b 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_main.c +++ b/drivers/net/ethernet/intel/i40e/i40e_main.c @@ -38,8 +38,8 @@ static const char i40e_driver_string[] = #define DRV_KERN "-k" #define DRV_VERSION_MAJOR 0 -#define DRV_VERSION_MINOR 3 -#define DRV_VERSION_BUILD 46 +#define DRV_VERSION_MINOR 4 +#define DRV_VERSION_BUILD 3 #define DRV_VERSION __stringify(DRV_VERSION_MAJOR) "." \ __stringify(DRV_VERSION_MINOR) "." \ __stringify(DRV_VERSION_BUILD) DRV_KERN diff --git a/drivers/net/ethernet/intel/i40evf/i40evf_main.c b/drivers/net/ethernet/intel/i40evf/i40evf_main.c index f6a2bdc54660..feff317befb6 100644 --- a/drivers/net/ethernet/intel/i40evf/i40evf_main.c +++ b/drivers/net/ethernet/intel/i40evf/i40evf_main.c @@ -36,7 +36,7 @@ char i40evf_driver_name[] = "i40evf"; static const char i40evf_driver_string[] = "Intel(R) XL710 X710 Virtual Function Network Driver"; -#define DRV_VERSION "0.9.23" +#define DRV_VERSION "0.9.27" const char i40evf_driver_version[] = DRV_VERSION; static const char i40evf_copyright[] = "Copyright (c) 2013 - 2014 Intel Corporation.";