[dpdk-dev,3/3] net/i40e: implement device reset on port
Checks
Commit Message
Implement the device reset function on vf port.
This restart function will detach device then
attach device, reconfigure dev, re-setup the Rx/Tx queues.
Signed-off-by: Wei Zhao <wei.zhao1@intel.com>
Signed-off-by: Wenzhuo Lu <wenzhuo.lu@intel.com>
---
drivers/net/i40e/i40e_ethdev.c | 2 +-
drivers/net/i40e/i40e_ethdev.h | 16 +++
drivers/net/i40e/i40e_ethdev_vf.c | 222 ++++++++++++++++++++++++++++++++++++--
drivers/net/i40e/i40e_rxtx.c | 10 ++
drivers/net/i40e/i40e_rxtx.h | 4 +
5 files changed, 246 insertions(+), 8 deletions(-)
Comments
On 3/3/2017 4:56 AM, Wei Zhao wrote:
> Implement the device reset function on vf port.
> This restart function will detach device then
> attach device, reconfigure dev, re-setup the Rx/Tx queues.
>
> Signed-off-by: Wei Zhao <wei.zhao1@intel.com>
> Signed-off-by: Wenzhuo Lu <wenzhuo.lu@intel.com>
<...>
> +static int i40evf_dev_uninit(struct rte_eth_dev *eth_dev);
> +static int i40evf_dev_init(struct rte_eth_dev *eth_dev);
> +static void i40evf_dev_close(struct rte_eth_dev *dev);
> +static int i40evf_dev_start(struct rte_eth_dev *dev);
> +static int i40evf_dev_configure(struct rte_eth_dev *dev);
> +static int i40evf_handle_vf_reset(struct rte_eth_dev *dev);
Some of them already seems declared, please avoid unnecessary or
duplicate declarations.
> +
>
> /* Default hash key buffer for RSS */
> static uint32_t rss_key_default[I40E_VFQF_HKEY_MAX_INDEX + 1];
> @@ -230,6 +237,7 @@ static const struct eth_dev_ops i40evf_eth_dev_ops = {
> .rss_hash_conf_get = i40evf_dev_rss_hash_conf_get,
> .mtu_set = i40evf_dev_mtu_set,
> .mac_addr_set = i40evf_set_default_mac_addr,
> + .dev_reset = i40evf_handle_vf_reset,
> };
>
> /*
> @@ -885,10 +893,13 @@ i40evf_add_mac_addr(struct rte_eth_dev *dev,
> args.out_buffer = vf->aq_resp;
> args.out_size = I40E_AQ_BUF_SZ;
> err = i40evf_execute_vf_cmd(dev, &args);
> - if (err)
> + if (err) {
> PMD_DRV_LOG(ERR, "fail to execute command "
> "OP_ADD_ETHER_ADDRESS");
> -
> + goto DONE;
Please prefer lowercase labels,
also this is error exit, I would prefer other name than "done"
> + }
> + vf->vsi.mac_num++;
> +DONE:
> return;
> }
>
<...>
> +static int
> +i40evf_handle_vf_reset(struct rte_eth_dev *dev)
> +{
> + struct i40e_adapter *adapter =
> + I40E_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);
> +
> + if (!dev->data->dev_started)
> + return 0;
> +
> + adapter->reset_number = 1;
> + i40e_vf_reset_dev(dev);
What happens if user called this function for PF ?
> + adapter->reset_number = 0;
> +
> + return 0;
> +}
> +
<...>
Hi,Ferruh
> -----Original Message-----
> From: Yigit, Ferruh
> Sent: Wednesday, March 8, 2017 7:21 PM
> To: Zhao1, Wei <wei.zhao1@intel.com>; dev@dpdk.org
> Cc: Lu, Wenzhuo <wenzhuo.lu@intel.com>
> Subject: Re: [dpdk-dev] [PATCH 3/3] net/i40e: implement device reset on
> port
>
> On 3/3/2017 4:56 AM, Wei Zhao wrote:
> > Implement the device reset function on vf port.
> > This restart function will detach device then attach device,
> > reconfigure dev, re-setup the Rx/Tx queues.
> >
> > Signed-off-by: Wei Zhao <wei.zhao1@intel.com>
> > Signed-off-by: Wenzhuo Lu <wenzhuo.lu@intel.com>
>
> <...>
>
> > +static int i40evf_dev_uninit(struct rte_eth_dev *eth_dev); static int
> > +i40evf_dev_init(struct rte_eth_dev *eth_dev); static void
> > +i40evf_dev_close(struct rte_eth_dev *dev); static int
> > +i40evf_dev_start(struct rte_eth_dev *dev); static int
> > +i40evf_dev_configure(struct rte_eth_dev *dev); static int
> > +i40evf_handle_vf_reset(struct rte_eth_dev *dev);
>
> Some of them already seems declared, please avoid unnecessary or
> duplicate declarations.
Ok, I will delete useless function declaration in V2 patch.
>
> > +
> >
> > /* Default hash key buffer for RSS */ static uint32_t
> > rss_key_default[I40E_VFQF_HKEY_MAX_INDEX + 1]; @@ -230,6 +237,7
> @@
> > static const struct eth_dev_ops i40evf_eth_dev_ops = {
> > .rss_hash_conf_get = i40evf_dev_rss_hash_conf_get,
> > .mtu_set = i40evf_dev_mtu_set,
> > .mac_addr_set = i40evf_set_default_mac_addr,
> > + .dev_reset = i40evf_handle_vf_reset,
> > };
> >
> > /*
> > @@ -885,10 +893,13 @@ i40evf_add_mac_addr(struct rte_eth_dev *dev,
> > args.out_buffer = vf->aq_resp;
> > args.out_size = I40E_AQ_BUF_SZ;
> > err = i40evf_execute_vf_cmd(dev, &args);
> > - if (err)
> > + if (err) {
> > PMD_DRV_LOG(ERR, "fail to execute command "
> > "OP_ADD_ETHER_ADDRESS");
> > -
> > + goto DONE;
>
> Please prefer lowercase labels,
> also this is error exit, I would prefer other name than "done"
Ok, I will delete useless function declaration in V2 patch.
>
> > + }
> > + vf->vsi.mac_num++;
> > +DONE:
> > return;
> > }
> >
>
> <...>
>
> > +static int
> > +i40evf_handle_vf_reset(struct rte_eth_dev *dev) {
> > + struct i40e_adapter *adapter =
> > + I40E_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);
> > +
> > + if (!dev->data->dev_started)
> > + return 0;
> > +
> > + adapter->reset_number = 1;
> > + i40e_vf_reset_dev(dev);
>
> What happens if user called this function for PF ?
This is an illegal operation, so I will may be add an check of whether it is vf port,
if not , a return command to avoid illegal operation.
>
> > + adapter->reset_number = 0;
> > +
> > + return 0;
> > +}
> > +
>
> <...>
> >
> > > +static int
> > > +i40evf_handle_vf_reset(struct rte_eth_dev *dev) {
> > > + struct i40e_adapter *adapter =
> > > + I40E_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);
> > > +
> > > + if (!dev->data->dev_started)
> > > + return 0;
> > > +
> > > + adapter->reset_number = 1;
> > > + i40e_vf_reset_dev(dev);
> >
> > What happens if user called this function for PF ?
>
> This is an illegal operation, so I will may be add an check of whether it is vf
> port, if not , a return command to avoid illegal operation.
>
VF driver is probed when it is the VF (by device id). So I don't think it
Will be called when it is PF.
Thanks
Jingjing
> /*
> * Structure to store private data specific for VF instance.
> */
> @@ -708,6 +718,10 @@ struct i40e_adapter {
> struct rte_timecounter systime_tc;
> struct rte_timecounter rx_tstamp_tc;
> struct rte_timecounter tx_tstamp_tc;
> +
> + /* For VF reset */
> + volatile uint8_t reset_number;
> + void *reset_store_data;
> };
How to move it to i40_vf? Or it can be used for PF in future?
> +
> +static int
> +i40evf_store_before_reset(struct rte_eth_dev *dev) {
> + struct i40e_adapter *adapter =
> + I40E_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);
> + struct i40e_vf_reset_store *store_data;
> + struct i40e_vf *vf = I40EVF_DEV_PRIVATE_TO_VF(dev->data-
> >dev_private);
> +
> + adapter->reset_store_data = rte_zmalloc("i40evf_store_reset",
> + sizeof(struct i40e_vf_reset_store), 0);
> + if (adapter->reset_store_data == NULL) {
> + PMD_INIT_LOG(ERR, "Failed to allocate %ld bytes needed to"
> + " to store data when reset vf",
> + sizeof(struct i40e_vf_reset_store));
> + return -ENOMEM;
> + }
i40evf_store_before_reset is allocated when reset happens.
Don't forget to free it when reset is done. Otherwise memory leak.
The same as below mac_addrs.
> + store_data =
> + (struct i40e_vf_reset_store *)adapter->reset_store_data;
> + store_data->mac_addrs = rte_zmalloc("i40evf_mac_store_reset",
> + ETHER_ADDR_LEN * I40E_NUM_MACADDR_MAX, 0);
> + if (store_data->mac_addrs == NULL) {
> + PMD_INIT_LOG(ERR, "Failed to allocate %d bytes needed to"
> + " to store MAC addresses when reset vf",
> + ETHER_ADDR_LEN *
> I40E_NUM_MACADDR_MAX);
> + }
> +
> + memcpy(store_data->mac_addrs, dev->data->mac_addrs,
> + ETHER_ADDR_LEN * I40E_NUM_MACADDR_MAX);
> +
> + store_data->promisc_unicast_enabled = vf->promisc_unicast_enabled;
> + store_data->promisc_multicast_enabled = vf-
> >promisc_multicast_enabled;
> +
> + store_data->vlan_num = vf->vsi.vlan_num;
> + memcpy(store_data->vfta, vf->vsi.vfta,
> + sizeof(uint32_t) * I40E_VFTA_SIZE);
> +
> + store_data->mac_num = vf->vsi.mac_num;
> +
> + return 0;
> +}
> +static int
> +i40evf_handle_vf_reset(struct rte_eth_dev *dev) {
> + struct i40e_adapter *adapter =
> + I40E_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);
> +
> + if (!dev->data->dev_started)
> + return 0;
> +
I think even the dev is not started, we also need to reset it. Because
the VF need to reconnect with PF.
> + adapter->reset_number = 1;
> + i40e_vf_reset_dev(dev);
> + adapter->reset_number = 0;
> +
How to name the reset_number to resetting?
> -----Original Message-----
> From: Wu, Jingjing
> Sent: Friday, March 24, 2017 5:07 PM
> To: Zhao1, Wei <wei.zhao1@intel.com>; dev@dpdk.org
> Cc: Zhao1, Wei <wei.zhao1@intel.com>; Lu, Wenzhuo
> <wenzhuo.lu@intel.com>
> Subject: RE: [dpdk-dev] [PATCH 3/3] net/i40e: implement device reset on
> port
>
>
> > /*
> > * Structure to store private data specific for VF instance.
> > */
> > @@ -708,6 +718,10 @@ struct i40e_adapter {
> > struct rte_timecounter systime_tc;
> > struct rte_timecounter rx_tstamp_tc;
> > struct rte_timecounter tx_tstamp_tc;
> > +
> > + /* For VF reset */
> > + volatile uint8_t reset_number;
> > + void *reset_store_data;
> > };
>
> How to move it to i40_vf? Or it can be used for PF in future?
This is a legacy from wenzhuo's code, his code is design in this way. If this feature is be used by pf, locus of here is may be reasonable?
>
>
> > +
> > +static int
> > +i40evf_store_before_reset(struct rte_eth_dev *dev) {
> > + struct i40e_adapter *adapter =
> > + I40E_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);
> > + struct i40e_vf_reset_store *store_data;
> > + struct i40e_vf *vf = I40EVF_DEV_PRIVATE_TO_VF(dev->data-
> > >dev_private);
> > +
> > + adapter->reset_store_data = rte_zmalloc("i40evf_store_reset",
> > + sizeof(struct i40e_vf_reset_store), 0);
> > + if (adapter->reset_store_data == NULL) {
> > + PMD_INIT_LOG(ERR, "Failed to allocate %ld bytes needed
> to"
> > + " to store data when reset vf",
> > + sizeof(struct i40e_vf_reset_store));
> > + return -ENOMEM;
> > + }
> i40evf_store_before_reset is allocated when reset happens.
> Don't forget to free it when reset is done. Otherwise memory leak.
>
> The same as below mac_addrs.
Ok, I will add rte_free for them.
> > + store_data =
> > + (struct i40e_vf_reset_store *)adapter->reset_store_data;
> > + store_data->mac_addrs = rte_zmalloc("i40evf_mac_store_reset",
> > + ETHER_ADDR_LEN * I40E_NUM_MACADDR_MAX, 0);
> > + if (store_data->mac_addrs == NULL) {
> > + PMD_INIT_LOG(ERR, "Failed to allocate %d bytes needed to"
> > + " to store MAC addresses when reset vf",
> > + ETHER_ADDR_LEN *
> > I40E_NUM_MACADDR_MAX);
> > + }
> > +
> > + memcpy(store_data->mac_addrs, dev->data->mac_addrs,
> > + ETHER_ADDR_LEN * I40E_NUM_MACADDR_MAX);
> > +
> > + store_data->promisc_unicast_enabled = vf-
> >promisc_unicast_enabled;
> > + store_data->promisc_multicast_enabled = vf-
> > >promisc_multicast_enabled;
> > +
> > + store_data->vlan_num = vf->vsi.vlan_num;
> > + memcpy(store_data->vfta, vf->vsi.vfta,
> > + sizeof(uint32_t) * I40E_VFTA_SIZE);
> > +
> > + store_data->mac_num = vf->vsi.mac_num;
> > +
> > + return 0;
> > +}
>
>
>
> > +static int
> > +i40evf_handle_vf_reset(struct rte_eth_dev *dev) {
> > + struct i40e_adapter *adapter =
> > + I40E_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);
> > +
> > + if (!dev->data->dev_started)
> > + return 0;
> > +
> I think even the dev is not started, we also need to reset it. Because the VF
> need to reconnect with PF.
Ok.
> > + adapter->reset_number = 1;
> > + i40e_vf_reset_dev(dev);
> > + adapter->reset_number = 0;
> > +
> How to name the reset_number to resetting?
>
I will change name to "adapter->reset_flag"
@@ -6006,7 +6006,7 @@ i40e_find_vlan_filter(struct i40e_vsi *vsi,
return 0;
}
-static void
+void
i40e_store_vlan_filter(struct i40e_vsi *vsi,
uint16_t vlan_id, bool on)
{
@@ -651,6 +651,16 @@ struct i40e_vf_tx_queues {
uint32_t tx_ring_len;
};
+struct i40e_vf_reset_store {
+ struct ether_addr *mac_addrs; /* Device Ethernet Link address. */
+ bool promisc_unicast_enabled;
+ bool promisc_multicast_enabled;
+ uint16_t vlan_num; /* Total VLAN number */
+ uint32_t vfta[I40E_VFTA_SIZE]; /* VLAN bitmap */
+ uint16_t mac_num; /* Total mac number */
+};
+
+
/*
* Structure to store private data specific for VF instance.
*/
@@ -708,6 +718,10 @@ struct i40e_adapter {
struct rte_timecounter systime_tc;
struct rte_timecounter rx_tstamp_tc;
struct rte_timecounter tx_tstamp_tc;
+
+ /* For VF reset */
+ volatile uint8_t reset_number;
+ void *reset_store_data;
};
extern const struct rte_flow_ops i40e_flow_ops;
@@ -748,6 +762,8 @@ int i40e_dev_link_update(struct rte_eth_dev *dev,
__rte_unused int wait_to_complete);
void i40e_vsi_queues_bind_intr(struct i40e_vsi *vsi);
void i40e_vsi_queues_unbind_intr(struct i40e_vsi *vsi);
+void i40e_store_vlan_filter(struct i40e_vsi *vsi,
+ uint16_t vlan_id, bool on);
int i40e_vsi_vlan_pvid_set(struct i40e_vsi *vsi,
struct i40e_vsi_vlan_pvid_info *info);
int i40e_vsi_config_vlan_stripping(struct i40e_vsi *vsi, bool on);
@@ -161,6 +161,13 @@ i40evf_dev_rx_queue_intr_disable(struct rte_eth_dev *dev, uint16_t queue_id);
static void i40evf_handle_pf_event(__rte_unused struct rte_eth_dev *dev,
uint8_t *msg,
uint16_t msglen);
+static int i40evf_dev_uninit(struct rte_eth_dev *eth_dev);
+static int i40evf_dev_init(struct rte_eth_dev *eth_dev);
+static void i40evf_dev_close(struct rte_eth_dev *dev);
+static int i40evf_dev_start(struct rte_eth_dev *dev);
+static int i40evf_dev_configure(struct rte_eth_dev *dev);
+static int i40evf_handle_vf_reset(struct rte_eth_dev *dev);
+
/* Default hash key buffer for RSS */
static uint32_t rss_key_default[I40E_VFQF_HKEY_MAX_INDEX + 1];
@@ -230,6 +237,7 @@ static const struct eth_dev_ops i40evf_eth_dev_ops = {
.rss_hash_conf_get = i40evf_dev_rss_hash_conf_get,
.mtu_set = i40evf_dev_mtu_set,
.mac_addr_set = i40evf_set_default_mac_addr,
+ .dev_reset = i40evf_handle_vf_reset,
};
/*
@@ -885,10 +893,13 @@ i40evf_add_mac_addr(struct rte_eth_dev *dev,
args.out_buffer = vf->aq_resp;
args.out_size = I40E_AQ_BUF_SZ;
err = i40evf_execute_vf_cmd(dev, &args);
- if (err)
+ if (err) {
PMD_DRV_LOG(ERR, "fail to execute command "
"OP_ADD_ETHER_ADDRESS");
-
+ goto DONE;
+ }
+ vf->vsi.mac_num++;
+DONE:
return;
}
@@ -923,9 +934,13 @@ i40evf_del_mac_addr_by_addr(struct rte_eth_dev *dev,
args.out_buffer = vf->aq_resp;
args.out_size = I40E_AQ_BUF_SZ;
err = i40evf_execute_vf_cmd(dev, &args);
- if (err)
+ if (err) {
PMD_DRV_LOG(ERR, "fail to execute command "
"OP_DEL_ETHER_ADDRESS");
+ goto DONE;
+ }
+ vf->vsi.mac_num--;
+DONE:
return;
}
@@ -1047,6 +1062,7 @@ static int
i40evf_add_vlan(struct rte_eth_dev *dev, uint16_t vlanid)
{
struct i40e_vf *vf = I40EVF_DEV_PRIVATE_TO_VF(dev->data->dev_private);
+ struct i40e_vsi *vsi = &vf->vsi;
struct i40e_virtchnl_vlan_filter_list *vlan_list;
uint8_t cmd_buffer[sizeof(struct i40e_virtchnl_vlan_filter_list) +
sizeof(uint16_t)];
@@ -1064,9 +1080,13 @@ i40evf_add_vlan(struct rte_eth_dev *dev, uint16_t vlanid)
args.out_buffer = vf->aq_resp;
args.out_size = I40E_AQ_BUF_SZ;
err = i40evf_execute_vf_cmd(dev, &args);
- if (err)
+ if (err) {
PMD_DRV_LOG(ERR, "fail to execute command OP_ADD_VLAN");
-
+ goto DONE;
+ }
+ i40e_store_vlan_filter(vsi, vlanid, 1);
+ vsi->vlan_num++;
+DONE:
return err;
}
@@ -1074,6 +1094,7 @@ static int
i40evf_del_vlan(struct rte_eth_dev *dev, uint16_t vlanid)
{
struct i40e_vf *vf = I40EVF_DEV_PRIVATE_TO_VF(dev->data->dev_private);
+ struct i40e_vsi *vsi = &vf->vsi;
struct i40e_virtchnl_vlan_filter_list *vlan_list;
uint8_t cmd_buffer[sizeof(struct i40e_virtchnl_vlan_filter_list) +
sizeof(uint16_t)];
@@ -1091,9 +1112,13 @@ i40evf_del_vlan(struct rte_eth_dev *dev, uint16_t vlanid)
args.out_buffer = vf->aq_resp;
args.out_size = I40E_AQ_BUF_SZ;
err = i40evf_execute_vf_cmd(dev, &args);
- if (err)
+ if (err) {
PMD_DRV_LOG(ERR, "fail to execute command OP_DEL_VLAN");
-
+ goto DONE;
+ }
+ i40e_store_vlan_filter(vsi, vlanid, 0);
+ vsi->vlan_num--;
+DONE:
return err;
}
@@ -2716,3 +2741,186 @@ i40evf_set_default_mac_addr(struct rte_eth_dev *dev,
i40evf_add_mac_addr(dev, mac_addr, 0, 0);
}
+
+static void
+i40evf_restore_vlan_filter(struct rte_eth_dev *dev,
+ uint32_t *vfta)
+{
+ uint32_t vid_idx, vid_bit;
+ uint16_t vlan_id;
+
+ for (vid_idx = 0; vid_idx < I40E_VFTA_SIZE; vid_idx++) {
+ for (vid_bit = 0; vid_bit < I40E_UINT32_BIT_SIZE; vid_bit++) {
+ if (vfta[vid_idx] & (1 << vid_bit)) {
+ vlan_id = (vid_idx << 5) + vid_bit;
+ i40evf_add_vlan(dev, vlan_id);
+ }
+ }
+ }
+}
+
+static void
+i40evf_restore_macaddr(struct rte_eth_dev *dev,
+ struct ether_addr *mac_addrs)
+{
+ struct ether_addr *addr;
+ uint16_t i;
+
+ /* replay MAC address configuration including default MAC */
+ addr = &mac_addrs[0];
+
+ memcpy(dev->data->mac_addrs, mac_addrs,
+ ETHER_ADDR_LEN * I40E_NUM_MACADDR_MAX);
+
+ i40evf_set_default_mac_addr(dev, addr);
+
+ for (i = 1; i < I40E_NUM_MACADDR_MAX; i++) {
+ addr = &mac_addrs[i];
+
+ /* skip zero address */
+ if (is_zero_ether_addr(addr))
+ continue;
+
+ i40evf_add_mac_addr(dev, addr, 0, 0);
+ }
+}
+
+
+static void
+i40e_vf_queue_reset(struct rte_eth_dev *dev)
+{
+ uint16_t i;
+
+ for (i = 0; i < dev->data->nb_rx_queues; i++) {
+ struct i40e_rx_queue *rxq = dev->data->rx_queues[i];
+
+ if (rxq->q_set) {
+ i40e_dev_rx_queue_setup(dev,
+ rxq->queue_id,
+ rxq->nb_rx_desc,
+ rxq->socket_id,
+ &rxq->rxconf,
+ rxq->mp);
+ }
+ }
+ for (i = 0; i < dev->data->nb_tx_queues; i++) {
+ struct i40e_tx_queue *txq = dev->data->tx_queues[i];
+
+ if (txq->q_set) {
+ i40e_dev_tx_queue_setup(dev,
+ txq->queue_id,
+ txq->nb_tx_desc,
+ txq->socket_id,
+ &txq->txconf);
+ }
+ }
+}
+
+static int
+i40evf_store_before_reset(struct rte_eth_dev *dev)
+{
+ struct i40e_adapter *adapter =
+ I40E_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);
+ struct i40e_vf_reset_store *store_data;
+ struct i40e_vf *vf = I40EVF_DEV_PRIVATE_TO_VF(dev->data->dev_private);
+
+ adapter->reset_store_data = rte_zmalloc("i40evf_store_reset",
+ sizeof(struct i40e_vf_reset_store), 0);
+ if (adapter->reset_store_data == NULL) {
+ PMD_INIT_LOG(ERR, "Failed to allocate %ld bytes needed to"
+ " to store data when reset vf",
+ sizeof(struct i40e_vf_reset_store));
+ return -ENOMEM;
+ }
+ store_data =
+ (struct i40e_vf_reset_store *)adapter->reset_store_data;
+ store_data->mac_addrs = rte_zmalloc("i40evf_mac_store_reset",
+ ETHER_ADDR_LEN * I40E_NUM_MACADDR_MAX, 0);
+ if (store_data->mac_addrs == NULL) {
+ PMD_INIT_LOG(ERR, "Failed to allocate %d bytes needed to"
+ " to store MAC addresses when reset vf",
+ ETHER_ADDR_LEN * I40E_NUM_MACADDR_MAX);
+ }
+
+ memcpy(store_data->mac_addrs, dev->data->mac_addrs,
+ ETHER_ADDR_LEN * I40E_NUM_MACADDR_MAX);
+
+ store_data->promisc_unicast_enabled = vf->promisc_unicast_enabled;
+ store_data->promisc_multicast_enabled = vf->promisc_multicast_enabled;
+
+ store_data->vlan_num = vf->vsi.vlan_num;
+ memcpy(store_data->vfta, vf->vsi.vfta,
+ sizeof(uint32_t) * I40E_VFTA_SIZE);
+
+ store_data->mac_num = vf->vsi.mac_num;
+
+ return 0;
+}
+
+static void
+i40evf_restore_after_reset(struct rte_eth_dev *dev)
+{
+ struct i40e_adapter *adapter =
+ I40E_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);
+ struct i40e_vf_reset_store *store_data =
+ (struct i40e_vf_reset_store *)adapter->reset_store_data;
+
+ if (store_data->promisc_unicast_enabled)
+ i40evf_dev_promiscuous_enable(dev);
+ if (store_data->promisc_multicast_enabled)
+ i40evf_dev_allmulticast_enable(dev);
+
+ if (store_data->vlan_num)
+ i40evf_restore_vlan_filter(dev, store_data->vfta);
+
+ if (store_data->mac_num)
+ i40evf_restore_macaddr(dev, store_data->mac_addrs);
+}
+
+static void
+i40e_vf_reset_dev(struct rte_eth_dev *dev)
+{
+ struct i40e_adapter *adapter =
+ I40E_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);
+
+ i40evf_store_before_reset(dev);
+
+ i40evf_dev_close(dev);
+ PMD_DRV_LOG(DEBUG, "i40evf dev close complete");
+
+ i40evf_dev_uninit(dev);
+ PMD_DRV_LOG(DEBUG, "i40evf dev detached");
+
+ memset(dev->data->dev_private, 0,
+ (uint64_t)&adapter->reset_number - (uint64_t)adapter);
+
+ i40evf_dev_init(dev);
+ PMD_DRV_LOG(DEBUG, "i40evf dev attached");
+
+ i40evf_dev_configure(dev);
+
+ i40e_vf_queue_reset(dev);
+ PMD_DRV_LOG(DEBUG, "i40evf queue reset");
+
+ i40evf_restore_after_reset(dev);
+
+ i40evf_dev_start(dev);
+ PMD_DRV_LOG(DEBUG, "i40evf dev restart");
+}
+
+static int
+i40evf_handle_vf_reset(struct rte_eth_dev *dev)
+{
+ struct i40e_adapter *adapter =
+ I40E_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);
+
+ if (!dev->data->dev_started)
+ return 0;
+
+ adapter->reset_number = 1;
+ i40e_vf_reset_dev(dev);
+ adapter->reset_number = 0;
+
+ return 0;
+}
+
@@ -1709,6 +1709,7 @@ i40e_dev_rx_queue_setup(struct rte_eth_dev *dev,
uint16_t len, i;
uint16_t base, bsf, tc_mapping;
int use_def_burst_func = 1;
+ struct rte_eth_rxconf conf = *rx_conf;
if (hw->mac.type == I40E_MAC_VF || hw->mac.type == I40E_MAC_X722_VF) {
struct i40e_vf *vf =
@@ -1748,6 +1749,8 @@ i40e_dev_rx_queue_setup(struct rte_eth_dev *dev,
}
rxq->mp = mp;
rxq->nb_rx_desc = nb_desc;
+ rxq->socket_id = socket_id;
+ rxq->rxconf = conf;
rxq->rx_free_thresh = rx_conf->rx_free_thresh;
rxq->queue_id = queue_idx;
if (hw->mac.type == I40E_MAC_VF || hw->mac.type == I40E_MAC_X722_VF)
@@ -1937,6 +1940,7 @@ i40e_dev_tx_queue_setup(struct rte_eth_dev *dev,
uint32_t ring_size;
uint16_t tx_rs_thresh, tx_free_thresh;
uint16_t i, base, bsf, tc_mapping;
+ struct rte_eth_txconf conf = *tx_conf;
if (hw->mac.type == I40E_MAC_VF || hw->mac.type == I40E_MAC_X722_VF) {
struct i40e_vf *vf =
@@ -2059,6 +2063,8 @@ i40e_dev_tx_queue_setup(struct rte_eth_dev *dev,
}
txq->nb_tx_desc = nb_desc;
+ txq->socket_id = socket_id;
+ txq->txconf = conf;
txq->tx_rs_thresh = tx_rs_thresh;
txq->tx_free_thresh = tx_free_thresh;
txq->pthresh = tx_conf->tx_thresh.pthresh;
@@ -2525,8 +2531,12 @@ void
i40e_dev_free_queues(struct rte_eth_dev *dev)
{
uint16_t i;
+ struct i40e_adapter *adapter =
+ I40E_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);
PMD_INIT_FUNC_TRACE();
+ if (adapter->reset_number)
+ return;
for (i = 0; i < dev->data->nb_rx_queues; i++) {
if (!dev->data->rx_queues[i])
@@ -136,6 +136,8 @@ struct i40e_rx_queue {
bool rx_deferred_start; /**< don't start this queue in dev start */
uint16_t rx_using_sse; /**<flag indicate the usage of vPMD for rx */
uint8_t dcb_tc; /**< Traffic class of rx queue */
+ uint8_t socket_id;
+ struct rte_eth_rxconf rxconf;
};
struct i40e_tx_entry {
@@ -177,6 +179,8 @@ struct i40e_tx_queue {
bool q_set; /**< indicate if tx queue has been configured */
bool tx_deferred_start; /**< don't start this queue in dev start */
uint8_t dcb_tc; /**< Traffic class of tx queue */
+ uint8_t socket_id;
+ struct rte_eth_txconf txconf;
};
/** Offload features */