Skip to content

Commit e6d038d

Browse files
mawilli1Jeff Kirsher
authored andcommitted
i40evf: handle big resets
The most common type of reset that the VF will encounter is a PF reset that cascades down into a VF reset for each VF. In this case, the VF will always be assigned the same VSI and recovery is fairly simple. However, in the case of 'bigger' resets, such as a Core or EMP reset, when the device is reinitialized, it's probable that the VF will NOT get the same VSI. When this happens, the VF will not be able to recover, as it will continue to request resources for its original VSI. Add an extra state to the admin queue state machine so that the driver can re-request its configuration information at runtime. During reset recovery, set this bit in the aq_required field, and fetch the (possibly new) configuration information before attempting to bring the driver back up. Since the driver doesn't know what kind of reset it has encountered, this step is done even for a PF reset, but it doesn't hurt anything - it just gets the same VSI back. Change-ID: I915d59ffb40375215117362f4ac7a37811aba748 Signed-off-by: Mitch Williams <[email protected]> Tested-by: Jim Young <[email protected]> Signed-off-by: Jeff Kirsher <[email protected]>
1 parent f4ca1a2 commit e6d038d

File tree

3 files changed

+95
-46
lines changed

3 files changed

+95
-46
lines changed

drivers/net/ethernet/intel/i40evf/i40evf.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -234,6 +234,7 @@ struct i40evf_adapter {
234234
#define I40EVF_FLAG_AQ_CONFIGURE_QUEUES (u32)(1 << 6)
235235
#define I40EVF_FLAG_AQ_MAP_VECTORS (u32)(1 << 7)
236236
#define I40EVF_FLAG_AQ_HANDLE_RESET (u32)(1 << 8)
237+
#define I40EVF_FLAG_AQ_GET_CONFIG (u32)(1 << 10)
237238

238239
/* OS defined structs */
239240
struct net_device *netdev;
@@ -273,6 +274,7 @@ extern const char i40evf_driver_version[];
273274

274275
int i40evf_up(struct i40evf_adapter *adapter);
275276
void i40evf_down(struct i40evf_adapter *adapter);
277+
int i40evf_process_config(struct i40evf_adapter *adapter);
276278
void i40evf_reset(struct i40evf_adapter *adapter);
277279
void i40evf_set_ethtool_ops(struct net_device *netdev);
278280
void i40evf_update_stats(struct i40evf_adapter *adapter);

drivers/net/ethernet/intel/i40evf/i40evf_main.c

Lines changed: 66 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1371,6 +1371,10 @@ static void i40evf_watchdog_task(struct work_struct *work)
13711371
}
13721372
goto watchdog_done;
13731373
}
1374+
if (adapter->aq_required & I40EVF_FLAG_AQ_GET_CONFIG) {
1375+
i40evf_send_vf_config_msg(adapter);
1376+
goto watchdog_done;
1377+
}
13741378

13751379
if (adapter->aq_required & I40EVF_FLAG_AQ_DISABLE_QUEUES) {
13761380
i40evf_disable_queues(adapter);
@@ -1606,7 +1610,8 @@ static void i40evf_reset_task(struct work_struct *work)
16061610
dev_info(&adapter->pdev->dev, "Failed to init adminq: %d\n",
16071611
err);
16081612

1609-
i40evf_map_queues(adapter);
1613+
adapter->aq_required = I40EVF_FLAG_AQ_GET_CONFIG;
1614+
adapter->aq_required |= I40EVF_FLAG_AQ_MAP_VECTORS;
16101615

16111616
/* re-add all MAC filters */
16121617
list_for_each_entry(f, &adapter->mac_filter_list, list) {
@@ -1616,7 +1621,7 @@ static void i40evf_reset_task(struct work_struct *work)
16161621
list_for_each_entry(f, &adapter->vlan_filter_list, list) {
16171622
f->add = true;
16181623
}
1619-
adapter->aq_required = I40EVF_FLAG_AQ_ADD_MAC_FILTER;
1624+
adapter->aq_required |= I40EVF_FLAG_AQ_ADD_MAC_FILTER;
16201625
adapter->aq_required |= I40EVF_FLAG_AQ_ADD_VLAN_FILTER;
16211626
clear_bit(__I40EVF_IN_CRITICAL_TASK, &adapter->crit_section);
16221627
i40evf_misc_irq_enable(adapter);
@@ -1981,6 +1986,62 @@ static int i40evf_check_reset_complete(struct i40e_hw *hw)
19811986
return -EBUSY;
19821987
}
19831988

1989+
/**
1990+
* i40evf_process_config - Process the config information we got from the PF
1991+
* @adapter: board private structure
1992+
*
1993+
* Verify that we have a valid config struct, and set up our netdev features
1994+
* and our VSI struct.
1995+
**/
1996+
int i40evf_process_config(struct i40evf_adapter *adapter)
1997+
{
1998+
struct net_device *netdev = adapter->netdev;
1999+
int i;
2000+
2001+
/* got VF config message back from PF, now we can parse it */
2002+
for (i = 0; i < adapter->vf_res->num_vsis; i++) {
2003+
if (adapter->vf_res->vsi_res[i].vsi_type == I40E_VSI_SRIOV)
2004+
adapter->vsi_res = &adapter->vf_res->vsi_res[i];
2005+
}
2006+
if (!adapter->vsi_res) {
2007+
dev_err(&adapter->pdev->dev, "No LAN VSI found\n");
2008+
return -ENODEV;
2009+
}
2010+
2011+
if (adapter->vf_res->vf_offload_flags
2012+
& I40E_VIRTCHNL_VF_OFFLOAD_VLAN) {
2013+
netdev->vlan_features = netdev->features;
2014+
netdev->features |= NETIF_F_HW_VLAN_CTAG_TX |
2015+
NETIF_F_HW_VLAN_CTAG_RX |
2016+
NETIF_F_HW_VLAN_CTAG_FILTER;
2017+
}
2018+
netdev->features |= NETIF_F_HIGHDMA |
2019+
NETIF_F_SG |
2020+
NETIF_F_IP_CSUM |
2021+
NETIF_F_SCTP_CSUM |
2022+
NETIF_F_IPV6_CSUM |
2023+
NETIF_F_TSO |
2024+
NETIF_F_TSO6 |
2025+
NETIF_F_RXCSUM |
2026+
NETIF_F_GRO;
2027+
2028+
/* copy netdev features into list of user selectable features */
2029+
netdev->hw_features |= netdev->features;
2030+
netdev->hw_features &= ~NETIF_F_RXCSUM;
2031+
2032+
adapter->vsi.id = adapter->vsi_res->vsi_id;
2033+
2034+
adapter->vsi.back = adapter;
2035+
adapter->vsi.base_vector = 1;
2036+
adapter->vsi.work_limit = I40E_DEFAULT_IRQ_WORK;
2037+
adapter->vsi.rx_itr_setting = (I40E_ITR_DYNAMIC |
2038+
ITR_REG_TO_USEC(I40E_ITR_RX_DEF));
2039+
adapter->vsi.tx_itr_setting = (I40E_ITR_DYNAMIC |
2040+
ITR_REG_TO_USEC(I40E_ITR_TX_DEF));
2041+
adapter->vsi.netdev = adapter->netdev;
2042+
return 0;
2043+
}
2044+
19842045
/**
19852046
* i40evf_init_task - worker thread to perform delayed initialization
19862047
* @work: pointer to work_struct containing our data
@@ -2001,7 +2062,7 @@ static void i40evf_init_task(struct work_struct *work)
20012062
struct net_device *netdev = adapter->netdev;
20022063
struct i40e_hw *hw = &adapter->hw;
20032064
struct pci_dev *pdev = adapter->pdev;
2004-
int i, err, bufsz;
2065+
int err, bufsz;
20052066

20062067
switch (adapter->state) {
20072068
case __I40EVF_STARTUP:
@@ -2087,42 +2148,15 @@ static void i40evf_init_task(struct work_struct *work)
20872148
default:
20882149
goto err_alloc;
20892150
}
2090-
/* got VF config message back from PF, now we can parse it */
2091-
for (i = 0; i < adapter->vf_res->num_vsis; i++) {
2092-
if (adapter->vf_res->vsi_res[i].vsi_type == I40E_VSI_SRIOV)
2093-
adapter->vsi_res = &adapter->vf_res->vsi_res[i];
2094-
}
2095-
if (!adapter->vsi_res) {
2096-
dev_err(&pdev->dev, "No LAN VSI found\n");
2151+
if (i40evf_process_config(adapter))
20972152
goto err_alloc;
2098-
}
2153+
adapter->current_op = I40E_VIRTCHNL_OP_UNKNOWN;
20992154

21002155
adapter->flags |= I40EVF_FLAG_RX_CSUM_ENABLED;
21012156

21022157
netdev->netdev_ops = &i40evf_netdev_ops;
21032158
i40evf_set_ethtool_ops(netdev);
21042159
netdev->watchdog_timeo = 5 * HZ;
2105-
netdev->features |= NETIF_F_HIGHDMA |
2106-
NETIF_F_SG |
2107-
NETIF_F_IP_CSUM |
2108-
NETIF_F_SCTP_CSUM |
2109-
NETIF_F_IPV6_CSUM |
2110-
NETIF_F_TSO |
2111-
NETIF_F_TSO6 |
2112-
NETIF_F_RXCSUM |
2113-
NETIF_F_GRO;
2114-
2115-
if (adapter->vf_res->vf_offload_flags
2116-
& I40E_VIRTCHNL_VF_OFFLOAD_VLAN) {
2117-
netdev->vlan_features = netdev->features;
2118-
netdev->features |= NETIF_F_HW_VLAN_CTAG_TX |
2119-
NETIF_F_HW_VLAN_CTAG_RX |
2120-
NETIF_F_HW_VLAN_CTAG_FILTER;
2121-
}
2122-
2123-
/* copy netdev features into list of user selectable features */
2124-
netdev->hw_features |= netdev->features;
2125-
netdev->hw_features &= ~NETIF_F_RXCSUM;
21262160

21272161
if (!is_valid_ether_addr(adapter->hw.mac.addr)) {
21282162
dev_info(&pdev->dev, "Invalid MAC address %pM, using random\n",
@@ -2153,17 +2187,6 @@ static void i40evf_init_task(struct work_struct *work)
21532187

21542188
netif_carrier_off(netdev);
21552189

2156-
adapter->vsi.id = adapter->vsi_res->vsi_id;
2157-
adapter->vsi.seid = adapter->vsi_res->vsi_id; /* dummy */
2158-
adapter->vsi.back = adapter;
2159-
adapter->vsi.base_vector = 1;
2160-
adapter->vsi.work_limit = I40E_DEFAULT_IRQ_WORK;
2161-
adapter->vsi.rx_itr_setting = (I40E_ITR_DYNAMIC |
2162-
ITR_REG_TO_USEC(I40E_ITR_RX_DEF));
2163-
adapter->vsi.tx_itr_setting = (I40E_ITR_DYNAMIC |
2164-
ITR_REG_TO_USEC(I40E_ITR_TX_DEF));
2165-
adapter->vsi.netdev = adapter->netdev;
2166-
21672190
if (!adapter->netdev_registered) {
21682191
err = register_netdev(netdev);
21692192
if (err)

drivers/net/ethernet/intel/i40evf/i40evf_virtchnl.c

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -145,8 +145,24 @@ int i40evf_verify_api_ver(struct i40evf_adapter *adapter)
145145
**/
146146
int i40evf_send_vf_config_msg(struct i40evf_adapter *adapter)
147147
{
148-
return i40evf_send_pf_msg(adapter, I40E_VIRTCHNL_OP_GET_VF_RESOURCES,
149-
NULL, 0);
148+
u32 caps;
149+
150+
adapter->current_op = I40E_VIRTCHNL_OP_GET_VF_RESOURCES;
151+
adapter->aq_required &= ~I40EVF_FLAG_AQ_GET_CONFIG;
152+
caps = I40E_VIRTCHNL_VF_OFFLOAD_L2 |
153+
I40E_VIRTCHNL_VF_OFFLOAD_RSS_AQ |
154+
I40E_VIRTCHNL_VF_OFFLOAD_RSS_REG |
155+
I40E_VIRTCHNL_VF_OFFLOAD_VLAN;
156+
adapter->current_op = I40E_VIRTCHNL_OP_GET_VF_RESOURCES;
157+
adapter->aq_required &= ~I40EVF_FLAG_AQ_GET_CONFIG;
158+
if (PF_IS_V11(adapter))
159+
return i40evf_send_pf_msg(adapter,
160+
I40E_VIRTCHNL_OP_GET_VF_RESOURCES,
161+
(u8 *)&caps, sizeof(caps));
162+
else
163+
return i40evf_send_pf_msg(adapter,
164+
I40E_VIRTCHNL_OP_GET_VF_RESOURCES,
165+
NULL, 0);
150166
}
151167

152168
/**
@@ -729,6 +745,15 @@ void i40evf_virtchnl_completion(struct i40evf_adapter *adapter,
729745
adapter->current_stats = *stats;
730746
}
731747
break;
748+
case I40E_VIRTCHNL_OP_GET_VF_RESOURCES: {
749+
u16 len = sizeof(struct i40e_virtchnl_vf_resource) +
750+
I40E_MAX_VF_VSI *
751+
sizeof(struct i40e_virtchnl_vsi_resource);
752+
memcpy(adapter->vf_res, msg, min(msglen, len));
753+
i40e_vf_parse_hw_config(&adapter->hw, adapter->vf_res);
754+
i40evf_process_config(adapter);
755+
}
756+
break;
732757
case I40E_VIRTCHNL_OP_ENABLE_QUEUES:
733758
/* enable transmits */
734759
i40evf_irq_enable(adapter, true);
@@ -740,7 +765,6 @@ void i40evf_virtchnl_completion(struct i40evf_adapter *adapter,
740765
i40evf_free_all_rx_resources(adapter);
741766
break;
742767
case I40E_VIRTCHNL_OP_VERSION:
743-
case I40E_VIRTCHNL_OP_GET_VF_RESOURCES:
744768
case I40E_VIRTCHNL_OP_CONFIG_IRQ_MAP:
745769
/* Don't display an error if we get these out of sequence.
746770
* If the firmware needed to get kicked, we'll get these and

0 commit comments

Comments
 (0)