Commit a90cca7c authored by David S. Miller's avatar David S. Miller

Merge branch 'ena-next'

Netanel Belgazal says:
====================
update ENA driver to releawse 1.3.0
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents c057c683 046b3071
...@@ -627,6 +627,12 @@ enum ena_admin_flow_hash_proto { ...@@ -627,6 +627,12 @@ enum ena_admin_flow_hash_proto {
ENA_ADMIN_RSS_NOT_IP = 7, ENA_ADMIN_RSS_NOT_IP = 7,
/* TCPv6 with extension header */
ENA_ADMIN_RSS_TCP6_EX = 8,
/* IPv6 with extension header */
ENA_ADMIN_RSS_IP6_EX = 9,
ENA_ADMIN_RSS_PROTO_NUM = 16, ENA_ADMIN_RSS_PROTO_NUM = 16,
}; };
......
...@@ -63,6 +63,8 @@ ...@@ -63,6 +63,8 @@
#define ENA_REGS_ADMIN_INTR_MASK 1 #define ENA_REGS_ADMIN_INTR_MASK 1
#define ENA_POLL_MS 5
/*****************************************************************************/ /*****************************************************************************/
/*****************************************************************************/ /*****************************************************************************/
/*****************************************************************************/ /*****************************************************************************/
...@@ -533,7 +535,7 @@ static int ena_com_wait_and_process_admin_cq_polling(struct ena_comp_ctx *comp_c ...@@ -533,7 +535,7 @@ static int ena_com_wait_and_process_admin_cq_polling(struct ena_comp_ctx *comp_c
goto err; goto err;
} }
msleep(100); msleep(ENA_POLL_MS);
} }
if (unlikely(comp_ctx->status == ENA_CMD_ABORTED)) { if (unlikely(comp_ctx->status == ENA_CMD_ABORTED)) {
...@@ -746,6 +748,9 @@ static int wait_for_reset_state(struct ena_com_dev *ena_dev, u32 timeout, ...@@ -746,6 +748,9 @@ static int wait_for_reset_state(struct ena_com_dev *ena_dev, u32 timeout,
{ {
u32 val, i; u32 val, i;
/* Convert timeout from resolution of 100ms to ENA_POLL_MS */
timeout = (timeout * 100) / ENA_POLL_MS;
for (i = 0; i < timeout; i++) { for (i = 0; i < timeout; i++) {
val = ena_com_reg_bar_read32(ena_dev, ENA_REGS_DEV_STS_OFF); val = ena_com_reg_bar_read32(ena_dev, ENA_REGS_DEV_STS_OFF);
...@@ -758,8 +763,7 @@ static int wait_for_reset_state(struct ena_com_dev *ena_dev, u32 timeout, ...@@ -758,8 +763,7 @@ static int wait_for_reset_state(struct ena_com_dev *ena_dev, u32 timeout,
exp_state) exp_state)
return 0; return 0;
/* The resolution of the timeout is 100ms */ msleep(ENA_POLL_MS);
msleep(100);
} }
return -ETIME; return -ETIME;
...@@ -1253,7 +1257,7 @@ void ena_com_wait_for_abort_completion(struct ena_com_dev *ena_dev) ...@@ -1253,7 +1257,7 @@ void ena_com_wait_for_abort_completion(struct ena_com_dev *ena_dev)
spin_lock_irqsave(&admin_queue->q_lock, flags); spin_lock_irqsave(&admin_queue->q_lock, flags);
while (atomic_read(&admin_queue->outstanding_cmds) != 0) { while (atomic_read(&admin_queue->outstanding_cmds) != 0) {
spin_unlock_irqrestore(&admin_queue->q_lock, flags); spin_unlock_irqrestore(&admin_queue->q_lock, flags);
msleep(20); msleep(ENA_POLL_MS);
spin_lock_irqsave(&admin_queue->q_lock, flags); spin_lock_irqsave(&admin_queue->q_lock, flags);
} }
spin_unlock_irqrestore(&admin_queue->q_lock, flags); spin_unlock_irqrestore(&admin_queue->q_lock, flags);
......
...@@ -60,8 +60,8 @@ struct ena_stats { ...@@ -60,8 +60,8 @@ struct ena_stats {
static const struct ena_stats ena_stats_global_strings[] = { static const struct ena_stats ena_stats_global_strings[] = {
ENA_STAT_GLOBAL_ENTRY(tx_timeout), ENA_STAT_GLOBAL_ENTRY(tx_timeout),
ENA_STAT_GLOBAL_ENTRY(io_suspend), ENA_STAT_GLOBAL_ENTRY(suspend),
ENA_STAT_GLOBAL_ENTRY(io_resume), ENA_STAT_GLOBAL_ENTRY(resume),
ENA_STAT_GLOBAL_ENTRY(wd_expired), ENA_STAT_GLOBAL_ENTRY(wd_expired),
ENA_STAT_GLOBAL_ENTRY(interface_up), ENA_STAT_GLOBAL_ENTRY(interface_up),
ENA_STAT_GLOBAL_ENTRY(interface_down), ENA_STAT_GLOBAL_ENTRY(interface_down),
...@@ -81,6 +81,7 @@ static const struct ena_stats ena_stats_tx_strings[] = { ...@@ -81,6 +81,7 @@ static const struct ena_stats ena_stats_tx_strings[] = {
ENA_STAT_TX_ENTRY(doorbells), ENA_STAT_TX_ENTRY(doorbells),
ENA_STAT_TX_ENTRY(prepare_ctx_err), ENA_STAT_TX_ENTRY(prepare_ctx_err),
ENA_STAT_TX_ENTRY(bad_req_id), ENA_STAT_TX_ENTRY(bad_req_id),
ENA_STAT_TX_ENTRY(missed_tx),
}; };
static const struct ena_stats ena_stats_rx_strings[] = { static const struct ena_stats ena_stats_rx_strings[] = {
......
...@@ -2361,38 +2361,6 @@ static const struct net_device_ops ena_netdev_ops = { ...@@ -2361,38 +2361,6 @@ static const struct net_device_ops ena_netdev_ops = {
#endif /* CONFIG_NET_POLL_CONTROLLER */ #endif /* CONFIG_NET_POLL_CONTROLLER */
}; };
static void ena_device_io_suspend(struct work_struct *work)
{
struct ena_adapter *adapter =
container_of(work, struct ena_adapter, suspend_io_task);
struct net_device *netdev = adapter->netdev;
/* ena_napi_disable_all disables only the IO handling.
* We are still subject to AENQ keep alive watchdog.
*/
u64_stats_update_begin(&adapter->syncp);
adapter->dev_stats.io_suspend++;
u64_stats_update_begin(&adapter->syncp);
ena_napi_disable_all(adapter);
netif_tx_lock(netdev);
netif_device_detach(netdev);
netif_tx_unlock(netdev);
}
static void ena_device_io_resume(struct work_struct *work)
{
struct ena_adapter *adapter =
container_of(work, struct ena_adapter, resume_io_task);
struct net_device *netdev = adapter->netdev;
u64_stats_update_begin(&adapter->syncp);
adapter->dev_stats.io_resume++;
u64_stats_update_end(&adapter->syncp);
netif_device_attach(netdev);
ena_napi_enable_all(adapter);
}
static int ena_device_validate_params(struct ena_adapter *adapter, static int ena_device_validate_params(struct ena_adapter *adapter,
struct ena_com_dev_get_features_ctx *get_feat_ctx) struct ena_com_dev_get_features_ctx *get_feat_ctx)
{ {
...@@ -2561,38 +2529,31 @@ static int ena_enable_msix_and_set_admin_interrupts(struct ena_adapter *adapter, ...@@ -2561,38 +2529,31 @@ static int ena_enable_msix_and_set_admin_interrupts(struct ena_adapter *adapter,
return rc; return rc;
} }
static void ena_fw_reset_device(struct work_struct *work) static void ena_destroy_device(struct ena_adapter *adapter)
{ {
struct ena_com_dev_get_features_ctx get_feat_ctx;
struct ena_adapter *adapter =
container_of(work, struct ena_adapter, reset_task);
struct net_device *netdev = adapter->netdev; struct net_device *netdev = adapter->netdev;
struct ena_com_dev *ena_dev = adapter->ena_dev; struct ena_com_dev *ena_dev = adapter->ena_dev;
struct pci_dev *pdev = adapter->pdev; bool dev_up;
bool dev_up, wd_state;
int rc;
if (unlikely(!test_bit(ENA_FLAG_TRIGGER_RESET, &adapter->flags))) {
dev_err(&pdev->dev,
"device reset schedule while reset bit is off\n");
return;
}
netif_carrier_off(netdev); netif_carrier_off(netdev);
del_timer_sync(&adapter->timer_service); del_timer_sync(&adapter->timer_service);
rtnl_lock();
dev_up = test_bit(ENA_FLAG_DEV_UP, &adapter->flags); dev_up = test_bit(ENA_FLAG_DEV_UP, &adapter->flags);
adapter->dev_up_before_reset = dev_up;
ena_com_set_admin_running_state(ena_dev, false); ena_com_set_admin_running_state(ena_dev, false);
/* After calling ena_close the tx queues and the napi
* are disabled so no one can interfere or touch the
* data structures
*/
ena_close(netdev); ena_close(netdev);
/* Before releasing the ENA resources, a device reset is required.
* (to prevent the device from accessing them).
* In case the reset flag is set and the device is up, ena_close
* already perform the reset, so it can be skipped.
*/
if (!(test_bit(ENA_FLAG_TRIGGER_RESET, &adapter->flags) && dev_up))
ena_com_dev_reset(adapter->ena_dev, adapter->reset_reason);
ena_free_mgmnt_irq(adapter); ena_free_mgmnt_irq(adapter);
ena_disable_msix(adapter); ena_disable_msix(adapter);
...@@ -2606,9 +2567,17 @@ static void ena_fw_reset_device(struct work_struct *work) ...@@ -2606,9 +2567,17 @@ static void ena_fw_reset_device(struct work_struct *work)
ena_com_mmio_reg_read_request_destroy(ena_dev); ena_com_mmio_reg_read_request_destroy(ena_dev);
adapter->reset_reason = ENA_REGS_RESET_NORMAL; adapter->reset_reason = ENA_REGS_RESET_NORMAL;
clear_bit(ENA_FLAG_TRIGGER_RESET, &adapter->flags); clear_bit(ENA_FLAG_TRIGGER_RESET, &adapter->flags);
}
/* Finish with the destroy part. Start the init part */ static int ena_restore_device(struct ena_adapter *adapter)
{
struct ena_com_dev_get_features_ctx get_feat_ctx;
struct ena_com_dev *ena_dev = adapter->ena_dev;
struct pci_dev *pdev = adapter->pdev;
bool wd_state;
int rc;
rc = ena_device_init(ena_dev, adapter->pdev, &get_feat_ctx, &wd_state); rc = ena_device_init(ena_dev, adapter->pdev, &get_feat_ctx, &wd_state);
if (rc) { if (rc) {
...@@ -2630,7 +2599,7 @@ static void ena_fw_reset_device(struct work_struct *work) ...@@ -2630,7 +2599,7 @@ static void ena_fw_reset_device(struct work_struct *work)
goto err_device_destroy; goto err_device_destroy;
} }
/* If the interface was up before the reset bring it up */ /* If the interface was up before the reset bring it up */
if (dev_up) { if (adapter->dev_up_before_reset) {
rc = ena_up(adapter); rc = ena_up(adapter);
if (rc) { if (rc) {
dev_err(&pdev->dev, "Failed to create I/O queues\n"); dev_err(&pdev->dev, "Failed to create I/O queues\n");
...@@ -2639,24 +2608,38 @@ static void ena_fw_reset_device(struct work_struct *work) ...@@ -2639,24 +2608,38 @@ static void ena_fw_reset_device(struct work_struct *work)
} }
mod_timer(&adapter->timer_service, round_jiffies(jiffies + HZ)); mod_timer(&adapter->timer_service, round_jiffies(jiffies + HZ));
rtnl_unlock();
dev_err(&pdev->dev, "Device reset completed successfully\n"); dev_err(&pdev->dev, "Device reset completed successfully\n");
return; return rc;
err_disable_msix: err_disable_msix:
ena_free_mgmnt_irq(adapter); ena_free_mgmnt_irq(adapter);
ena_disable_msix(adapter); ena_disable_msix(adapter);
err_device_destroy: err_device_destroy:
ena_com_admin_destroy(ena_dev); ena_com_admin_destroy(ena_dev);
err: err:
rtnl_unlock();
clear_bit(ENA_FLAG_DEVICE_RUNNING, &adapter->flags); clear_bit(ENA_FLAG_DEVICE_RUNNING, &adapter->flags);
dev_err(&pdev->dev, dev_err(&pdev->dev,
"Reset attempt failed. Can not reset the device\n"); "Reset attempt failed. Can not reset the device\n");
return rc;
}
static void ena_fw_reset_device(struct work_struct *work)
{
struct ena_adapter *adapter =
container_of(work, struct ena_adapter, reset_task);
struct pci_dev *pdev = adapter->pdev;
if (unlikely(!test_bit(ENA_FLAG_TRIGGER_RESET, &adapter->flags))) {
dev_err(&pdev->dev,
"device reset schedule while reset bit is off\n");
return;
}
rtnl_lock();
ena_destroy_device(adapter);
ena_restore_device(adapter);
rtnl_unlock();
} }
static int check_missing_comp_in_queue(struct ena_adapter *adapter, static int check_missing_comp_in_queue(struct ena_adapter *adapter,
...@@ -2665,7 +2648,7 @@ static int check_missing_comp_in_queue(struct ena_adapter *adapter, ...@@ -2665,7 +2648,7 @@ static int check_missing_comp_in_queue(struct ena_adapter *adapter,
struct ena_tx_buffer *tx_buf; struct ena_tx_buffer *tx_buf;
unsigned long last_jiffies; unsigned long last_jiffies;
u32 missed_tx = 0; u32 missed_tx = 0;
int i; int i, rc = 0;
for (i = 0; i < tx_ring->ring_size; i++) { for (i = 0; i < tx_ring->ring_size; i++) {
tx_buf = &tx_ring->tx_buffer_info[i]; tx_buf = &tx_ring->tx_buffer_info[i];
...@@ -2679,21 +2662,25 @@ static int check_missing_comp_in_queue(struct ena_adapter *adapter, ...@@ -2679,21 +2662,25 @@ static int check_missing_comp_in_queue(struct ena_adapter *adapter,
tx_buf->print_once = 1; tx_buf->print_once = 1;
missed_tx++; missed_tx++;
if (unlikely(missed_tx > adapter->missing_tx_completion_threshold)) {
netif_err(adapter, tx_err, adapter->netdev,
"The number of lost tx completions is above the threshold (%d > %d). Reset the device\n",
missed_tx,
adapter->missing_tx_completion_threshold);
adapter->reset_reason =
ENA_REGS_RESET_MISS_TX_CMPL;
set_bit(ENA_FLAG_TRIGGER_RESET, &adapter->flags);
return -EIO;
}
} }
} }
return 0; if (unlikely(missed_tx > adapter->missing_tx_completion_threshold)) {
netif_err(adapter, tx_err, adapter->netdev,
"The number of lost tx completions is above the threshold (%d > %d). Reset the device\n",
missed_tx,
adapter->missing_tx_completion_threshold);
adapter->reset_reason =
ENA_REGS_RESET_MISS_TX_CMPL;
set_bit(ENA_FLAG_TRIGGER_RESET, &adapter->flags);
rc = -EIO;
}
u64_stats_update_begin(&tx_ring->syncp);
tx_ring->tx_stats.missed_tx = missed_tx;
u64_stats_update_end(&tx_ring->syncp);
return rc;
} }
static void check_for_missing_tx_completions(struct ena_adapter *adapter) static void check_for_missing_tx_completions(struct ena_adapter *adapter)
...@@ -3275,8 +3262,6 @@ static int ena_probe(struct pci_dev *pdev, const struct pci_device_id *ent) ...@@ -3275,8 +3262,6 @@ static int ena_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
goto err_rss; goto err_rss;
} }
INIT_WORK(&adapter->suspend_io_task, ena_device_io_suspend);
INIT_WORK(&adapter->resume_io_task, ena_device_io_resume);
INIT_WORK(&adapter->reset_task, ena_fw_reset_device); INIT_WORK(&adapter->reset_task, ena_fw_reset_device);
adapter->last_keep_alive_jiffies = jiffies; adapter->last_keep_alive_jiffies = jiffies;
...@@ -3310,8 +3295,6 @@ static int ena_probe(struct pci_dev *pdev, const struct pci_device_id *ent) ...@@ -3310,8 +3295,6 @@ static int ena_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
err_worker_destroy: err_worker_destroy:
ena_com_destroy_interrupt_moderation(ena_dev); ena_com_destroy_interrupt_moderation(ena_dev);
del_timer(&adapter->timer_service); del_timer(&adapter->timer_service);
cancel_work_sync(&adapter->suspend_io_task);
cancel_work_sync(&adapter->resume_io_task);
err_netdev_destroy: err_netdev_destroy:
free_netdev(netdev); free_netdev(netdev);
err_device_destroy: err_device_destroy:
...@@ -3381,10 +3364,6 @@ static void ena_remove(struct pci_dev *pdev) ...@@ -3381,10 +3364,6 @@ static void ena_remove(struct pci_dev *pdev)
cancel_work_sync(&adapter->reset_task); cancel_work_sync(&adapter->reset_task);
cancel_work_sync(&adapter->suspend_io_task);
cancel_work_sync(&adapter->resume_io_task);
/* Reset the device only if the device is running. */ /* Reset the device only if the device is running. */
if (test_bit(ENA_FLAG_DEVICE_RUNNING, &adapter->flags)) if (test_bit(ENA_FLAG_DEVICE_RUNNING, &adapter->flags))
ena_com_dev_reset(ena_dev, adapter->reset_reason); ena_com_dev_reset(ena_dev, adapter->reset_reason);
...@@ -3418,11 +3397,59 @@ static void ena_remove(struct pci_dev *pdev) ...@@ -3418,11 +3397,59 @@ static void ena_remove(struct pci_dev *pdev)
vfree(ena_dev); vfree(ena_dev);
} }
#ifdef CONFIG_PM
/* ena_suspend - PM suspend callback
* @pdev: PCI device information struct
* @state:power state
*/
static int ena_suspend(struct pci_dev *pdev, pm_message_t state)
{
struct ena_adapter *adapter = pci_get_drvdata(pdev);
u64_stats_update_begin(&adapter->syncp);
adapter->dev_stats.suspend++;
u64_stats_update_end(&adapter->syncp);
rtnl_lock();
if (unlikely(test_bit(ENA_FLAG_TRIGGER_RESET, &adapter->flags))) {
dev_err(&pdev->dev,
"ignoring device reset request as the device is being suspended\n");
clear_bit(ENA_FLAG_TRIGGER_RESET, &adapter->flags);
}
ena_destroy_device(adapter);
rtnl_unlock();
return 0;
}
/* ena_resume - PM resume callback
* @pdev: PCI device information struct
*
*/
static int ena_resume(struct pci_dev *pdev)
{
struct ena_adapter *adapter = pci_get_drvdata(pdev);
int rc;
u64_stats_update_begin(&adapter->syncp);
adapter->dev_stats.resume++;
u64_stats_update_end(&adapter->syncp);
rtnl_lock();
rc = ena_restore_device(adapter);
rtnl_unlock();
return rc;
}
#endif
static struct pci_driver ena_pci_driver = { static struct pci_driver ena_pci_driver = {
.name = DRV_MODULE_NAME, .name = DRV_MODULE_NAME,
.id_table = ena_pci_tbl, .id_table = ena_pci_tbl,
.probe = ena_probe, .probe = ena_probe,
.remove = ena_remove, .remove = ena_remove,
#ifdef CONFIG_PM
.suspend = ena_suspend,
.resume = ena_resume,
#endif
.sriov_configure = ena_sriov_configure, .sriov_configure = ena_sriov_configure,
}; };
...@@ -3503,16 +3530,6 @@ static void ena_notification(void *adapter_data, ...@@ -3503,16 +3530,6 @@ static void ena_notification(void *adapter_data,
ENA_ADMIN_NOTIFICATION); ENA_ADMIN_NOTIFICATION);
switch (aenq_e->aenq_common_desc.syndrom) { switch (aenq_e->aenq_common_desc.syndrom) {
case ENA_ADMIN_SUSPEND:
/* Suspend just the IO queues.
* We deliberately don't suspend admin so the timer and
* the keep_alive events should remain.
*/
queue_work(ena_wq, &adapter->suspend_io_task);
break;
case ENA_ADMIN_RESUME:
queue_work(ena_wq, &adapter->resume_io_task);
break;
case ENA_ADMIN_UPDATE_HINTS: case ENA_ADMIN_UPDATE_HINTS:
hints = (struct ena_admin_ena_hw_hints *) hints = (struct ena_admin_ena_hw_hints *)
(&aenq_e->inline_data_w4); (&aenq_e->inline_data_w4);
......
...@@ -44,7 +44,7 @@ ...@@ -44,7 +44,7 @@
#include "ena_eth_com.h" #include "ena_eth_com.h"
#define DRV_MODULE_VER_MAJOR 1 #define DRV_MODULE_VER_MAJOR 1
#define DRV_MODULE_VER_MINOR 2 #define DRV_MODULE_VER_MINOR 3
#define DRV_MODULE_VER_SUBMINOR 0 #define DRV_MODULE_VER_SUBMINOR 0
#define DRV_MODULE_NAME "ena" #define DRV_MODULE_NAME "ena"
...@@ -52,7 +52,7 @@ ...@@ -52,7 +52,7 @@
#define DRV_MODULE_VERSION \ #define DRV_MODULE_VERSION \
__stringify(DRV_MODULE_VER_MAJOR) "." \ __stringify(DRV_MODULE_VER_MAJOR) "." \
__stringify(DRV_MODULE_VER_MINOR) "." \ __stringify(DRV_MODULE_VER_MINOR) "." \
__stringify(DRV_MODULE_VER_SUBMINOR) "k" __stringify(DRV_MODULE_VER_SUBMINOR) "K"
#endif #endif
#define DEVICE_NAME "Elastic Network Adapter (ENA)" #define DEVICE_NAME "Elastic Network Adapter (ENA)"
...@@ -185,6 +185,7 @@ struct ena_stats_tx { ...@@ -185,6 +185,7 @@ struct ena_stats_tx {
u64 tx_poll; u64 tx_poll;
u64 doorbells; u64 doorbells;
u64 bad_req_id; u64 bad_req_id;
u64 missed_tx;
}; };
struct ena_stats_rx { struct ena_stats_rx {
...@@ -257,8 +258,8 @@ struct ena_ring { ...@@ -257,8 +258,8 @@ struct ena_ring {
struct ena_stats_dev { struct ena_stats_dev {
u64 tx_timeout; u64 tx_timeout;
u64 io_suspend; u64 suspend;
u64 io_resume; u64 resume;
u64 wd_expired; u64 wd_expired;
u64 interface_up; u64 interface_up;
u64 interface_down; u64 interface_down;
...@@ -326,11 +327,10 @@ struct ena_adapter { ...@@ -326,11 +327,10 @@ struct ena_adapter {
/* timer service */ /* timer service */
struct work_struct reset_task; struct work_struct reset_task;
struct work_struct suspend_io_task;
struct work_struct resume_io_task;
struct timer_list timer_service; struct timer_list timer_service;
bool wd_state; bool wd_state;
bool dev_up_before_reset;
unsigned long last_keep_alive_jiffies; unsigned long last_keep_alive_jiffies;
struct u64_stats_sync syncp; struct u64_stats_sync syncp;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment