|
|
|
@@ -49,7 +49,6 @@ MODULE_DESCRIPTION("Intel(R) Ethernet Adaptive Virtual Function Network Driver")
|
|
|
|
|
MODULE_LICENSE("GPL v2");
|
|
|
|
|
|
|
|
|
|
static const struct net_device_ops iavf_netdev_ops;
|
|
|
|
|
struct workqueue_struct *iavf_wq;
|
|
|
|
|
|
|
|
|
|
int iavf_status_to_errno(enum iavf_status status)
|
|
|
|
|
{
|
|
|
|
@@ -277,7 +276,7 @@ void iavf_schedule_reset(struct iavf_adapter *adapter)
|
|
|
|
|
if (!(adapter->flags &
|
|
|
|
|
(IAVF_FLAG_RESET_PENDING | IAVF_FLAG_RESET_NEEDED))) {
|
|
|
|
|
adapter->flags |= IAVF_FLAG_RESET_NEEDED;
|
|
|
|
|
queue_work(iavf_wq, &adapter->reset_task);
|
|
|
|
|
queue_work(adapter->wq, &adapter->reset_task);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@@ -291,7 +290,7 @@ void iavf_schedule_reset(struct iavf_adapter *adapter)
|
|
|
|
|
void iavf_schedule_request_stats(struct iavf_adapter *adapter)
|
|
|
|
|
{
|
|
|
|
|
adapter->aq_required |= IAVF_FLAG_AQ_REQUEST_STATS;
|
|
|
|
|
mod_delayed_work(iavf_wq, &adapter->watchdog_task, 0);
|
|
|
|
|
mod_delayed_work(adapter->wq, &adapter->watchdog_task, 0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
@@ -411,7 +410,7 @@ static irqreturn_t iavf_msix_aq(int irq, void *data)
|
|
|
|
|
|
|
|
|
|
if (adapter->state != __IAVF_REMOVE)
|
|
|
|
|
/* schedule work on the private workqueue */
|
|
|
|
|
queue_work(iavf_wq, &adapter->adminq_task);
|
|
|
|
|
queue_work(adapter->wq, &adapter->adminq_task);
|
|
|
|
|
|
|
|
|
|
return IRQ_HANDLED;
|
|
|
|
|
}
|
|
|
|
@@ -1034,7 +1033,7 @@ int iavf_replace_primary_mac(struct iavf_adapter *adapter,
|
|
|
|
|
|
|
|
|
|
/* schedule the watchdog task to immediately process the request */
|
|
|
|
|
if (f) {
|
|
|
|
|
queue_work(iavf_wq, &adapter->watchdog_task.work);
|
|
|
|
|
mod_delayed_work(adapter->wq, &adapter->watchdog_task, 0);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
return -ENOMEM;
|
|
|
|
@@ -1257,7 +1256,7 @@ static void iavf_up_complete(struct iavf_adapter *adapter)
|
|
|
|
|
adapter->aq_required |= IAVF_FLAG_AQ_ENABLE_QUEUES;
|
|
|
|
|
if (CLIENT_ENABLED(adapter))
|
|
|
|
|
adapter->flags |= IAVF_FLAG_CLIENT_NEEDS_OPEN;
|
|
|
|
|
mod_delayed_work(iavf_wq, &adapter->watchdog_task, 0);
|
|
|
|
|
mod_delayed_work(adapter->wq, &adapter->watchdog_task, 0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
@@ -1414,7 +1413,7 @@ void iavf_down(struct iavf_adapter *adapter)
|
|
|
|
|
adapter->aq_required |= IAVF_FLAG_AQ_DISABLE_QUEUES;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
mod_delayed_work(iavf_wq, &adapter->watchdog_task, 0);
|
|
|
|
|
mod_delayed_work(adapter->wq, &adapter->watchdog_task, 0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
@@ -2248,7 +2247,7 @@ iavf_set_vlan_offload_features(struct iavf_adapter *adapter,
|
|
|
|
|
|
|
|
|
|
if (aq_required) {
|
|
|
|
|
adapter->aq_required |= aq_required;
|
|
|
|
|
mod_delayed_work(iavf_wq, &adapter->watchdog_task, 0);
|
|
|
|
|
mod_delayed_work(adapter->wq, &adapter->watchdog_task, 0);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@@ -2693,6 +2692,15 @@ static void iavf_watchdog_task(struct work_struct *work)
|
|
|
|
|
goto restart_watchdog;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ((adapter->flags & IAVF_FLAG_SETUP_NETDEV_FEATURES) &&
|
|
|
|
|
adapter->netdev_registered &&
|
|
|
|
|
!test_bit(__IAVF_IN_REMOVE_TASK, &adapter->crit_section) &&
|
|
|
|
|
rtnl_trylock()) {
|
|
|
|
|
netdev_update_features(adapter->netdev);
|
|
|
|
|
rtnl_unlock();
|
|
|
|
|
adapter->flags &= ~IAVF_FLAG_SETUP_NETDEV_FEATURES;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (adapter->flags & IAVF_FLAG_PF_COMMS_FAILED)
|
|
|
|
|
iavf_change_state(adapter, __IAVF_COMM_FAILED);
|
|
|
|
|
|
|
|
|
@@ -2700,7 +2708,7 @@ static void iavf_watchdog_task(struct work_struct *work)
|
|
|
|
|
adapter->aq_required = 0;
|
|
|
|
|
adapter->current_op = VIRTCHNL_OP_UNKNOWN;
|
|
|
|
|
mutex_unlock(&adapter->crit_lock);
|
|
|
|
|
queue_work(iavf_wq, &adapter->reset_task);
|
|
|
|
|
queue_work(adapter->wq, &adapter->reset_task);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@@ -2708,31 +2716,31 @@ static void iavf_watchdog_task(struct work_struct *work)
|
|
|
|
|
case __IAVF_STARTUP:
|
|
|
|
|
iavf_startup(adapter);
|
|
|
|
|
mutex_unlock(&adapter->crit_lock);
|
|
|
|
|
queue_delayed_work(iavf_wq, &adapter->watchdog_task,
|
|
|
|
|
queue_delayed_work(adapter->wq, &adapter->watchdog_task,
|
|
|
|
|
msecs_to_jiffies(30));
|
|
|
|
|
return;
|
|
|
|
|
case __IAVF_INIT_VERSION_CHECK:
|
|
|
|
|
iavf_init_version_check(adapter);
|
|
|
|
|
mutex_unlock(&adapter->crit_lock);
|
|
|
|
|
queue_delayed_work(iavf_wq, &adapter->watchdog_task,
|
|
|
|
|
queue_delayed_work(adapter->wq, &adapter->watchdog_task,
|
|
|
|
|
msecs_to_jiffies(30));
|
|
|
|
|
return;
|
|
|
|
|
case __IAVF_INIT_GET_RESOURCES:
|
|
|
|
|
iavf_init_get_resources(adapter);
|
|
|
|
|
mutex_unlock(&adapter->crit_lock);
|
|
|
|
|
queue_delayed_work(iavf_wq, &adapter->watchdog_task,
|
|
|
|
|
queue_delayed_work(adapter->wq, &adapter->watchdog_task,
|
|
|
|
|
msecs_to_jiffies(1));
|
|
|
|
|
return;
|
|
|
|
|
case __IAVF_INIT_EXTENDED_CAPS:
|
|
|
|
|
iavf_init_process_extended_caps(adapter);
|
|
|
|
|
mutex_unlock(&adapter->crit_lock);
|
|
|
|
|
queue_delayed_work(iavf_wq, &adapter->watchdog_task,
|
|
|
|
|
queue_delayed_work(adapter->wq, &adapter->watchdog_task,
|
|
|
|
|
msecs_to_jiffies(1));
|
|
|
|
|
return;
|
|
|
|
|
case __IAVF_INIT_CONFIG_ADAPTER:
|
|
|
|
|
iavf_init_config_adapter(adapter);
|
|
|
|
|
mutex_unlock(&adapter->crit_lock);
|
|
|
|
|
queue_delayed_work(iavf_wq, &adapter->watchdog_task,
|
|
|
|
|
queue_delayed_work(adapter->wq, &adapter->watchdog_task,
|
|
|
|
|
msecs_to_jiffies(1));
|
|
|
|
|
return;
|
|
|
|
|
case __IAVF_INIT_FAILED:
|
|
|
|
@@ -2751,14 +2759,14 @@ static void iavf_watchdog_task(struct work_struct *work)
|
|
|
|
|
adapter->flags |= IAVF_FLAG_PF_COMMS_FAILED;
|
|
|
|
|
iavf_shutdown_adminq(hw);
|
|
|
|
|
mutex_unlock(&adapter->crit_lock);
|
|
|
|
|
queue_delayed_work(iavf_wq,
|
|
|
|
|
queue_delayed_work(adapter->wq,
|
|
|
|
|
&adapter->watchdog_task, (5 * HZ));
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
/* Try again from failed step*/
|
|
|
|
|
iavf_change_state(adapter, adapter->last_state);
|
|
|
|
|
mutex_unlock(&adapter->crit_lock);
|
|
|
|
|
queue_delayed_work(iavf_wq, &adapter->watchdog_task, HZ);
|
|
|
|
|
queue_delayed_work(adapter->wq, &adapter->watchdog_task, HZ);
|
|
|
|
|
return;
|
|
|
|
|
case __IAVF_COMM_FAILED:
|
|
|
|
|
if (test_bit(__IAVF_IN_REMOVE_TASK,
|
|
|
|
@@ -2789,13 +2797,14 @@ static void iavf_watchdog_task(struct work_struct *work)
|
|
|
|
|
adapter->aq_required = 0;
|
|
|
|
|
adapter->current_op = VIRTCHNL_OP_UNKNOWN;
|
|
|
|
|
mutex_unlock(&adapter->crit_lock);
|
|
|
|
|
queue_delayed_work(iavf_wq,
|
|
|
|
|
queue_delayed_work(adapter->wq,
|
|
|
|
|
&adapter->watchdog_task,
|
|
|
|
|
msecs_to_jiffies(10));
|
|
|
|
|
return;
|
|
|
|
|
case __IAVF_RESETTING:
|
|
|
|
|
mutex_unlock(&adapter->crit_lock);
|
|
|
|
|
queue_delayed_work(iavf_wq, &adapter->watchdog_task, HZ * 2);
|
|
|
|
|
queue_delayed_work(adapter->wq, &adapter->watchdog_task,
|
|
|
|
|
HZ * 2);
|
|
|
|
|
return;
|
|
|
|
|
case __IAVF_DOWN:
|
|
|
|
|
case __IAVF_DOWN_PENDING:
|
|
|
|
@@ -2834,9 +2843,9 @@ static void iavf_watchdog_task(struct work_struct *work)
|
|
|
|
|
adapter->aq_required = 0;
|
|
|
|
|
adapter->current_op = VIRTCHNL_OP_UNKNOWN;
|
|
|
|
|
dev_err(&adapter->pdev->dev, "Hardware reset detected\n");
|
|
|
|
|
queue_work(iavf_wq, &adapter->reset_task);
|
|
|
|
|
queue_work(adapter->wq, &adapter->reset_task);
|
|
|
|
|
mutex_unlock(&adapter->crit_lock);
|
|
|
|
|
queue_delayed_work(iavf_wq,
|
|
|
|
|
queue_delayed_work(adapter->wq,
|
|
|
|
|
&adapter->watchdog_task, HZ * 2);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
@@ -2845,12 +2854,13 @@ static void iavf_watchdog_task(struct work_struct *work)
|
|
|
|
|
mutex_unlock(&adapter->crit_lock);
|
|
|
|
|
restart_watchdog:
|
|
|
|
|
if (adapter->state >= __IAVF_DOWN)
|
|
|
|
|
queue_work(iavf_wq, &adapter->adminq_task);
|
|
|
|
|
queue_work(adapter->wq, &adapter->adminq_task);
|
|
|
|
|
if (adapter->aq_required)
|
|
|
|
|
queue_delayed_work(iavf_wq, &adapter->watchdog_task,
|
|
|
|
|
queue_delayed_work(adapter->wq, &adapter->watchdog_task,
|
|
|
|
|
msecs_to_jiffies(20));
|
|
|
|
|
else
|
|
|
|
|
queue_delayed_work(iavf_wq, &adapter->watchdog_task, HZ * 2);
|
|
|
|
|
queue_delayed_work(adapter->wq, &adapter->watchdog_task,
|
|
|
|
|
HZ * 2);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
@@ -2952,7 +2962,7 @@ static void iavf_reset_task(struct work_struct *work)
|
|
|
|
|
*/
|
|
|
|
|
if (!mutex_trylock(&adapter->crit_lock)) {
|
|
|
|
|
if (adapter->state != __IAVF_REMOVE)
|
|
|
|
|
queue_work(iavf_wq, &adapter->reset_task);
|
|
|
|
|
queue_work(adapter->wq, &adapter->reset_task);
|
|
|
|
|
|
|
|
|
|
goto reset_finish;
|
|
|
|
|
}
|
|
|
|
@@ -3116,7 +3126,7 @@ continue_reset:
|
|
|
|
|
bitmap_clear(adapter->vsi.active_cvlans, 0, VLAN_N_VID);
|
|
|
|
|
bitmap_clear(adapter->vsi.active_svlans, 0, VLAN_N_VID);
|
|
|
|
|
|
|
|
|
|
mod_delayed_work(iavf_wq, &adapter->watchdog_task, 2);
|
|
|
|
|
mod_delayed_work(adapter->wq, &adapter->watchdog_task, 2);
|
|
|
|
|
|
|
|
|
|
/* We were running when the reset started, so we need to restore some
|
|
|
|
|
* state here.
|
|
|
|
@@ -3208,7 +3218,7 @@ static void iavf_adminq_task(struct work_struct *work)
|
|
|
|
|
if (adapter->state == __IAVF_REMOVE)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
queue_work(iavf_wq, &adapter->adminq_task);
|
|
|
|
|
queue_work(adapter->wq, &adapter->adminq_task);
|
|
|
|
|
goto out;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@@ -3232,24 +3242,6 @@ static void iavf_adminq_task(struct work_struct *work)
|
|
|
|
|
} while (pending);
|
|
|
|
|
mutex_unlock(&adapter->crit_lock);
|
|
|
|
|
|
|
|
|
|
if ((adapter->flags & IAVF_FLAG_SETUP_NETDEV_FEATURES)) {
|
|
|
|
|
if (adapter->netdev_registered ||
|
|
|
|
|
!test_bit(__IAVF_IN_REMOVE_TASK, &adapter->crit_section)) {
|
|
|
|
|
struct net_device *netdev = adapter->netdev;
|
|
|
|
|
|
|
|
|
|
rtnl_lock();
|
|
|
|
|
netdev_update_features(netdev);
|
|
|
|
|
rtnl_unlock();
|
|
|
|
|
/* Request VLAN offload settings */
|
|
|
|
|
if (VLAN_V2_ALLOWED(adapter))
|
|
|
|
|
iavf_set_vlan_offload_features
|
|
|
|
|
(adapter, 0, netdev->features);
|
|
|
|
|
|
|
|
|
|
iavf_set_queue_vlan_tag_loc(adapter);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
adapter->flags &= ~IAVF_FLAG_SETUP_NETDEV_FEATURES;
|
|
|
|
|
}
|
|
|
|
|
if ((adapter->flags &
|
|
|
|
|
(IAVF_FLAG_RESET_PENDING | IAVF_FLAG_RESET_NEEDED)) ||
|
|
|
|
|
adapter->state == __IAVF_RESETTING)
|
|
|
|
@@ -4349,7 +4341,7 @@ static int iavf_change_mtu(struct net_device *netdev, int new_mtu)
|
|
|
|
|
|
|
|
|
|
if (netif_running(netdev)) {
|
|
|
|
|
adapter->flags |= IAVF_FLAG_RESET_NEEDED;
|
|
|
|
|
queue_work(iavf_wq, &adapter->reset_task);
|
|
|
|
|
queue_work(adapter->wq, &adapter->reset_task);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
@@ -4898,6 +4890,13 @@ static int iavf_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
|
|
|
|
|
hw = &adapter->hw;
|
|
|
|
|
hw->back = adapter;
|
|
|
|
|
|
|
|
|
|
adapter->wq = alloc_ordered_workqueue("%s", WQ_MEM_RECLAIM,
|
|
|
|
|
iavf_driver_name);
|
|
|
|
|
if (!adapter->wq) {
|
|
|
|
|
err = -ENOMEM;
|
|
|
|
|
goto err_alloc_wq;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
adapter->msg_enable = BIT(DEFAULT_DEBUG_LEVEL_SHIFT) - 1;
|
|
|
|
|
iavf_change_state(adapter, __IAVF_STARTUP);
|
|
|
|
|
|
|
|
|
@@ -4942,7 +4941,7 @@ static int iavf_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
|
|
|
|
|
INIT_WORK(&adapter->adminq_task, iavf_adminq_task);
|
|
|
|
|
INIT_DELAYED_WORK(&adapter->watchdog_task, iavf_watchdog_task);
|
|
|
|
|
INIT_DELAYED_WORK(&adapter->client_task, iavf_client_task);
|
|
|
|
|
queue_delayed_work(iavf_wq, &adapter->watchdog_task,
|
|
|
|
|
queue_delayed_work(adapter->wq, &adapter->watchdog_task,
|
|
|
|
|
msecs_to_jiffies(5 * (pdev->devfn & 0x07)));
|
|
|
|
|
|
|
|
|
|
/* Setup the wait queue for indicating transition to down status */
|
|
|
|
@@ -4954,6 +4953,8 @@ static int iavf_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
err_ioremap:
|
|
|
|
|
destroy_workqueue(adapter->wq);
|
|
|
|
|
err_alloc_wq:
|
|
|
|
|
free_netdev(netdev);
|
|
|
|
|
err_alloc_etherdev:
|
|
|
|
|
pci_disable_pcie_error_reporting(pdev);
|
|
|
|
@@ -5023,7 +5024,7 @@ static int __maybe_unused iavf_resume(struct device *dev_d)
|
|
|
|
|
return err;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
queue_work(iavf_wq, &adapter->reset_task);
|
|
|
|
|
queue_work(adapter->wq, &adapter->reset_task);
|
|
|
|
|
|
|
|
|
|
netif_device_attach(adapter->netdev);
|
|
|
|
|
|
|
|
|
@@ -5170,6 +5171,8 @@ static void iavf_remove(struct pci_dev *pdev)
|
|
|
|
|
}
|
|
|
|
|
spin_unlock_bh(&adapter->adv_rss_lock);
|
|
|
|
|
|
|
|
|
|
destroy_workqueue(adapter->wq);
|
|
|
|
|
|
|
|
|
|
free_netdev(netdev);
|
|
|
|
|
|
|
|
|
|
pci_disable_pcie_error_reporting(pdev);
|
|
|
|
@@ -5196,24 +5199,11 @@ static struct pci_driver iavf_driver = {
|
|
|
|
|
**/
|
|
|
|
|
static int __init iavf_init_module(void)
|
|
|
|
|
{
|
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
|
|
pr_info("iavf: %s\n", iavf_driver_string);
|
|
|
|
|
|
|
|
|
|
pr_info("%s\n", iavf_copyright);
|
|
|
|
|
|
|
|
|
|
iavf_wq = alloc_workqueue("%s", WQ_UNBOUND | WQ_MEM_RECLAIM, 1,
|
|
|
|
|
iavf_driver_name);
|
|
|
|
|
if (!iavf_wq) {
|
|
|
|
|
pr_err("%s: Failed to create workqueue\n", iavf_driver_name);
|
|
|
|
|
return -ENOMEM;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ret = pci_register_driver(&iavf_driver);
|
|
|
|
|
if (ret)
|
|
|
|
|
destroy_workqueue(iavf_wq);
|
|
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
|
return pci_register_driver(&iavf_driver);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
module_init(iavf_init_module);
|
|
|
|
@@ -5227,7 +5217,6 @@ module_init(iavf_init_module);
|
|
|
|
|
static void __exit iavf_exit_module(void)
|
|
|
|
|
{
|
|
|
|
|
pci_unregister_driver(&iavf_driver);
|
|
|
|
|
destroy_workqueue(iavf_wq);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
module_exit(iavf_exit_module);
|
|
|
|
|