提交 5a9b7bfb 编写于 作者: D Dawid Wesierski 提交者: Tony Nguyen

igbvf: add PCI reset handler functions

There was a problem with resuming ping after conducting a PCI reset.
This commit adds two functions, igbvf_io_prepare and igbvf_io_done,
which, after being added to the pci_error_handlers struct,
will prepare the drivers for a PCI reset and then bring the interface up
and reset it after. This will prevent the driver from ending up in
incorrect state. Test_and_set_bit is highly reliable in this context,
so we are not including a timeout in this commit

This introduces 900ms - 1100ms of overhead to this operation but it's in
non-time-critical flow. And also allows the driver to continue
functioning after the reset.

Functionality documented in ethernet-controller-i350-datasheet 4.2.1.3
https://www.intel.com/content/www/us/en/products/details/ethernet/gigabit-controllers/i350-controllers/docs.htmlSigned-off-by: NDawid Wesierski <dawidx.wesierski@intel.com>
Signed-off-by: NKamil Maziarz <kamil.maziarz@intel.com>
Reviewed-by: NMichal Kubiak <michal.kubiak@intel.com>
Tested-by: NMarek Szlosek <marek.szlosek@intel.com>
Signed-off-by: NTony Nguyen <anthony.l.nguyen@intel.com>
上级 d71980d4
...@@ -2589,6 +2589,33 @@ static void igbvf_io_resume(struct pci_dev *pdev) ...@@ -2589,6 +2589,33 @@ static void igbvf_io_resume(struct pci_dev *pdev)
netif_device_attach(netdev); netif_device_attach(netdev);
} }
/**
* igbvf_io_prepare - prepare device driver for PCI reset
* @pdev: PCI device information struct
*/
static void igbvf_io_prepare(struct pci_dev *pdev)
{
struct net_device *netdev = pci_get_drvdata(pdev);
struct igbvf_adapter *adapter = netdev_priv(netdev);
while (test_and_set_bit(__IGBVF_RESETTING, &adapter->state))
usleep_range(1000, 2000);
igbvf_down(adapter);
}
/**
* igbvf_io_reset_done - PCI reset done, device driver reset can begin
* @pdev: PCI device information struct
*/
static void igbvf_io_reset_done(struct pci_dev *pdev)
{
struct net_device *netdev = pci_get_drvdata(pdev);
struct igbvf_adapter *adapter = netdev_priv(netdev);
igbvf_up(adapter);
clear_bit(__IGBVF_RESETTING, &adapter->state);
}
static void igbvf_print_device_info(struct igbvf_adapter *adapter) static void igbvf_print_device_info(struct igbvf_adapter *adapter)
{ {
struct e1000_hw *hw = &adapter->hw; struct e1000_hw *hw = &adapter->hw;
...@@ -2916,6 +2943,8 @@ static const struct pci_error_handlers igbvf_err_handler = { ...@@ -2916,6 +2943,8 @@ static const struct pci_error_handlers igbvf_err_handler = {
.error_detected = igbvf_io_error_detected, .error_detected = igbvf_io_error_detected,
.slot_reset = igbvf_io_slot_reset, .slot_reset = igbvf_io_slot_reset,
.resume = igbvf_io_resume, .resume = igbvf_io_resume,
.reset_prepare = igbvf_io_prepare,
.reset_done = igbvf_io_reset_done,
}; };
static const struct pci_device_id igbvf_pci_tbl[] = { static const struct pci_device_id igbvf_pci_tbl[] = {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册