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

Merge branch 'Enhance-current-features-in-ena-driver'

Sameeh Jubran says:

====================
Enhance current features in ena driver

Difference from v2:
* dropped patch "net: ena: move llq configuration from ena_probe to ena_device_init()"
* reworked patch ""net: ena: implement ena_com_get_admin_polling_mode() to drop the prototype

Difference from v1:
* reodered paches #01 and #02.
* dropped adding Rx/Tx drops to ethtool in patch #08

V1:
This patchset introduces the following:
* minor changes to RSS feature
* add total rx and tx drop counter
* add unmask_interrupt counter for ethtool statistics
* add missing implementation for ena_com_get_admin_polling_mode()
* some minor code clean-up and cosmetics
* use SHUTDOWN as reset reason when closing interface
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 5889a62b 77a651f5
...@@ -404,6 +404,10 @@ struct ena_admin_basic_stats { ...@@ -404,6 +404,10 @@ struct ena_admin_basic_stats {
u32 rx_drops_low; u32 rx_drops_low;
u32 rx_drops_high; u32 rx_drops_high;
u32 tx_drops_low;
u32 tx_drops_high;
}; };
struct ena_admin_acq_get_stats_resp { struct ena_admin_acq_get_stats_resp {
...@@ -1017,6 +1021,10 @@ struct ena_admin_aenq_keep_alive_desc { ...@@ -1017,6 +1021,10 @@ struct ena_admin_aenq_keep_alive_desc {
u32 rx_drops_low; u32 rx_drops_low;
u32 rx_drops_high; u32 rx_drops_high;
u32 tx_drops_low;
u32 tx_drops_high;
}; };
struct ena_admin_ena_mmio_req_read_less_resp { struct ena_admin_ena_mmio_req_read_less_resp {
......
...@@ -1067,16 +1067,10 @@ static void ena_com_hash_key_fill_default_key(struct ena_com_dev *ena_dev) ...@@ -1067,16 +1067,10 @@ static void ena_com_hash_key_fill_default_key(struct ena_com_dev *ena_dev)
static int ena_com_hash_key_allocate(struct ena_com_dev *ena_dev) static int ena_com_hash_key_allocate(struct ena_com_dev *ena_dev)
{ {
struct ena_rss *rss = &ena_dev->rss; struct ena_rss *rss = &ena_dev->rss;
struct ena_admin_get_feat_resp get_resp;
int rc;
rc = ena_com_get_feature_ex(ena_dev, &get_resp, if (!ena_com_check_supported_feature_id(ena_dev,
ENA_ADMIN_RSS_HASH_FUNCTION, ENA_ADMIN_RSS_HASH_FUNCTION))
ena_dev->rss.hash_key_dma_addr,
sizeof(ena_dev->rss.hash_key), 0);
if (unlikely(rc)) {
return -EOPNOTSUPP; return -EOPNOTSUPP;
}
rss->hash_key = rss->hash_key =
dma_alloc_coherent(ena_dev->dmadev, sizeof(*rss->hash_key), dma_alloc_coherent(ena_dev->dmadev, sizeof(*rss->hash_key),
...@@ -2286,6 +2280,7 @@ int ena_com_fill_hash_function(struct ena_com_dev *ena_dev, ...@@ -2286,6 +2280,7 @@ int ena_com_fill_hash_function(struct ena_com_dev *ena_dev,
struct ena_admin_get_feat_resp get_resp; struct ena_admin_get_feat_resp get_resp;
struct ena_admin_feature_rss_flow_hash_control *hash_key = struct ena_admin_feature_rss_flow_hash_control *hash_key =
rss->hash_key; rss->hash_key;
enum ena_admin_hash_functions old_func;
int rc; int rc;
/* Make sure size is a mult of DWs */ /* Make sure size is a mult of DWs */
...@@ -2325,26 +2320,27 @@ int ena_com_fill_hash_function(struct ena_com_dev *ena_dev, ...@@ -2325,26 +2320,27 @@ int ena_com_fill_hash_function(struct ena_com_dev *ena_dev,
return -EINVAL; return -EINVAL;
} }
old_func = rss->hash_func;
rss->hash_func = func; rss->hash_func = func;
rc = ena_com_set_hash_function(ena_dev); rc = ena_com_set_hash_function(ena_dev);
/* Restore the old function */ /* Restore the old function */
if (unlikely(rc)) if (unlikely(rc))
ena_com_get_hash_function(ena_dev, NULL, NULL); rss->hash_func = old_func;
return rc; return rc;
} }
int ena_com_get_hash_function(struct ena_com_dev *ena_dev, int ena_com_get_hash_function(struct ena_com_dev *ena_dev,
enum ena_admin_hash_functions *func, enum ena_admin_hash_functions *func)
u8 *key)
{ {
struct ena_rss *rss = &ena_dev->rss; struct ena_rss *rss = &ena_dev->rss;
struct ena_admin_get_feat_resp get_resp; struct ena_admin_get_feat_resp get_resp;
struct ena_admin_feature_rss_flow_hash_control *hash_key =
rss->hash_key;
int rc; int rc;
if (unlikely(!func))
return -EINVAL;
rc = ena_com_get_feature_ex(ena_dev, &get_resp, rc = ena_com_get_feature_ex(ena_dev, &get_resp,
ENA_ADMIN_RSS_HASH_FUNCTION, ENA_ADMIN_RSS_HASH_FUNCTION,
rss->hash_key_dma_addr, rss->hash_key_dma_addr,
...@@ -2357,9 +2353,16 @@ int ena_com_get_hash_function(struct ena_com_dev *ena_dev, ...@@ -2357,9 +2353,16 @@ int ena_com_get_hash_function(struct ena_com_dev *ena_dev,
if (rss->hash_func) if (rss->hash_func)
rss->hash_func--; rss->hash_func--;
if (func)
*func = rss->hash_func; *func = rss->hash_func;
return 0;
}
int ena_com_get_hash_key(struct ena_com_dev *ena_dev, u8 *key)
{
struct ena_admin_feature_rss_flow_hash_control *hash_key =
ena_dev->rss.hash_key;
if (key) if (key)
memcpy(key, hash_key->key, (size_t)(hash_key->keys_num) << 2); memcpy(key, hash_key->key, (size_t)(hash_key->keys_num) << 2);
...@@ -2641,10 +2644,10 @@ int ena_com_rss_init(struct ena_com_dev *ena_dev, u16 indr_tbl_log_size) ...@@ -2641,10 +2644,10 @@ int ena_com_rss_init(struct ena_com_dev *ena_dev, u16 indr_tbl_log_size)
* ignore this error and have indirection table support only. * ignore this error and have indirection table support only.
*/ */
rc = ena_com_hash_key_allocate(ena_dev); rc = ena_com_hash_key_allocate(ena_dev);
if (unlikely(rc) && rc != -EOPNOTSUPP) if (likely(!rc))
goto err_hash_key;
else if (rc != -EOPNOTSUPP)
ena_com_hash_key_fill_default_key(ena_dev); ena_com_hash_key_fill_default_key(ena_dev);
else if (rc != -EOPNOTSUPP)
goto err_hash_key;
rc = ena_com_hash_ctrl_init(ena_dev); rc = ena_com_hash_ctrl_init(ena_dev);
if (unlikely(rc)) if (unlikely(rc))
......
...@@ -501,18 +501,6 @@ bool ena_com_get_admin_running_state(struct ena_com_dev *ena_dev); ...@@ -501,18 +501,6 @@ bool ena_com_get_admin_running_state(struct ena_com_dev *ena_dev);
*/ */
void ena_com_set_admin_polling_mode(struct ena_com_dev *ena_dev, bool polling); void ena_com_set_admin_polling_mode(struct ena_com_dev *ena_dev, bool polling);
/* ena_com_set_admin_polling_mode - Get the admin completion queue polling mode
* @ena_dev: ENA communication layer struct
*
* Get the admin completion mode.
* If polling mode is on, ena_com_execute_admin_command will perform a
* polling on the admin completion queue for the commands completion,
* otherwise it will wait on wait event.
*
* @return state
*/
bool ena_com_get_ena_admin_polling_mode(struct ena_com_dev *ena_dev);
/* ena_com_set_admin_auto_polling_mode - Enable autoswitch to polling mode /* ena_com_set_admin_auto_polling_mode - Enable autoswitch to polling mode
* @ena_dev: ENA communication layer struct * @ena_dev: ENA communication layer struct
* @polling: Enable/Disable polling mode * @polling: Enable/Disable polling mode
...@@ -695,13 +683,11 @@ int ena_com_fill_hash_function(struct ena_com_dev *ena_dev, ...@@ -695,13 +683,11 @@ int ena_com_fill_hash_function(struct ena_com_dev *ena_dev,
*/ */
int ena_com_set_hash_function(struct ena_com_dev *ena_dev); int ena_com_set_hash_function(struct ena_com_dev *ena_dev);
/* ena_com_get_hash_function - Retrieve the hash function and the hash key /* ena_com_get_hash_function - Retrieve the hash function from the device.
* from the device.
* @ena_dev: ENA communication layer struct * @ena_dev: ENA communication layer struct
* @func: hash function * @func: hash function
* @key: hash key
* *
* Retrieve the hash function and the hash key from the device. * Retrieve the hash function from the device.
* *
* @note: If the caller called ena_com_fill_hash_function but didn't flash * @note: If the caller called ena_com_fill_hash_function but didn't flash
* it to the device, the new configuration will be lost. * it to the device, the new configuration will be lost.
...@@ -709,9 +695,20 @@ int ena_com_set_hash_function(struct ena_com_dev *ena_dev); ...@@ -709,9 +695,20 @@ int ena_com_set_hash_function(struct ena_com_dev *ena_dev);
* @return: 0 on Success and negative value otherwise. * @return: 0 on Success and negative value otherwise.
*/ */
int ena_com_get_hash_function(struct ena_com_dev *ena_dev, int ena_com_get_hash_function(struct ena_com_dev *ena_dev,
enum ena_admin_hash_functions *func, enum ena_admin_hash_functions *func);
u8 *key);
/* ena_com_get_hash_key - Retrieve the hash key
* @ena_dev: ENA communication layer struct
* @key: hash key
*
* Retrieve the hash key.
*
* @note: If the caller called ena_com_fill_hash_key but didn't flash
* it to the device, the new configuration will be lost.
*
* @return: 0 on Success and negative value otherwise.
*/
int ena_com_get_hash_key(struct ena_com_dev *ena_dev, u8 *key);
/* ena_com_fill_hash_ctrl - Fill RSS hash control /* ena_com_fill_hash_ctrl - Fill RSS hash control
* @ena_dev: ENA communication layer struct. * @ena_dev: ENA communication layer struct.
* @proto: The protocol to configure. * @proto: The protocol to configure.
......
...@@ -83,6 +83,7 @@ static const struct ena_stats ena_stats_tx_strings[] = { ...@@ -83,6 +83,7 @@ static const struct ena_stats ena_stats_tx_strings[] = {
ENA_STAT_TX_ENTRY(bad_req_id), ENA_STAT_TX_ENTRY(bad_req_id),
ENA_STAT_TX_ENTRY(llq_buffer_copy), ENA_STAT_TX_ENTRY(llq_buffer_copy),
ENA_STAT_TX_ENTRY(missed_tx), ENA_STAT_TX_ENTRY(missed_tx),
ENA_STAT_TX_ENTRY(unmask_interrupt),
}; };
static const struct ena_stats ena_stats_rx_strings[] = { static const struct ena_stats ena_stats_rx_strings[] = {
...@@ -635,6 +636,32 @@ static u32 ena_get_rxfh_key_size(struct net_device *netdev) ...@@ -635,6 +636,32 @@ static u32 ena_get_rxfh_key_size(struct net_device *netdev)
return ENA_HASH_KEY_SIZE; return ENA_HASH_KEY_SIZE;
} }
static int ena_indirection_table_set(struct ena_adapter *adapter,
const u32 *indir)
{
struct ena_com_dev *ena_dev = adapter->ena_dev;
int i, rc;
for (i = 0; i < ENA_RX_RSS_TABLE_SIZE; i++) {
rc = ena_com_indirect_table_fill_entry(ena_dev,
i,
ENA_IO_RXQ_IDX(indir[i]));
if (unlikely(rc)) {
netif_err(adapter, drv, adapter->netdev,
"Cannot fill indirect table (index is too large)\n");
return rc;
}
}
rc = ena_com_indirect_table_set(ena_dev);
if (rc) {
netif_err(adapter, drv, adapter->netdev,
"Cannot set indirect table\n");
return rc == -EPERM ? -EOPNOTSUPP : rc;
}
return rc;
}
static int ena_indirection_table_get(struct ena_adapter *adapter, u32 *indir) static int ena_indirection_table_get(struct ena_adapter *adapter, u32 *indir)
{ {
struct ena_com_dev *ena_dev = adapter->ena_dev; struct ena_com_dev *ena_dev = adapter->ena_dev;
...@@ -672,17 +699,18 @@ static int ena_get_rxfh(struct net_device *netdev, u32 *indir, u8 *key, ...@@ -672,17 +699,18 @@ static int ena_get_rxfh(struct net_device *netdev, u32 *indir, u8 *key,
/* We call this function in order to check if the device /* We call this function in order to check if the device
* supports getting/setting the hash function. * supports getting/setting the hash function.
*/ */
rc = ena_com_get_hash_function(adapter->ena_dev, &ena_func, key); rc = ena_com_get_hash_function(adapter->ena_dev, &ena_func);
if (rc) { if (rc) {
if (rc == -EOPNOTSUPP) { if (rc == -EOPNOTSUPP)
key = NULL;
hfunc = NULL;
rc = 0; rc = 0;
}
return rc; return rc;
} }
rc = ena_com_get_hash_key(adapter->ena_dev, key);
if (rc)
return rc;
switch (ena_func) { switch (ena_func) {
case ENA_ADMIN_TOEPLITZ: case ENA_ADMIN_TOEPLITZ:
func = ETH_RSS_HASH_TOP; func = ETH_RSS_HASH_TOP;
...@@ -699,7 +727,7 @@ static int ena_get_rxfh(struct net_device *netdev, u32 *indir, u8 *key, ...@@ -699,7 +727,7 @@ static int ena_get_rxfh(struct net_device *netdev, u32 *indir, u8 *key,
if (hfunc) if (hfunc)
*hfunc = func; *hfunc = func;
return rc; return 0;
} }
static int ena_set_rxfh(struct net_device *netdev, const u32 *indir, static int ena_set_rxfh(struct net_device *netdev, const u32 *indir,
...@@ -707,28 +735,14 @@ static int ena_set_rxfh(struct net_device *netdev, const u32 *indir, ...@@ -707,28 +735,14 @@ static int ena_set_rxfh(struct net_device *netdev, const u32 *indir,
{ {
struct ena_adapter *adapter = netdev_priv(netdev); struct ena_adapter *adapter = netdev_priv(netdev);
struct ena_com_dev *ena_dev = adapter->ena_dev; struct ena_com_dev *ena_dev = adapter->ena_dev;
enum ena_admin_hash_functions func; enum ena_admin_hash_functions func = 0;
int rc, i; int rc;
if (indir) { if (indir) {
for (i = 0; i < ENA_RX_RSS_TABLE_SIZE; i++) { rc = ena_indirection_table_set(adapter, indir);
rc = ena_com_indirect_table_fill_entry(ena_dev, if (rc)
i,
ENA_IO_RXQ_IDX(indir[i]));
if (unlikely(rc)) {
netif_err(adapter, drv, netdev,
"Cannot fill indirect table (index is too large)\n");
return rc; return rc;
} }
}
rc = ena_com_indirect_table_set(ena_dev);
if (rc) {
netif_err(adapter, drv, netdev,
"Cannot set indirect table\n");
return rc == -EPERM ? -EOPNOTSUPP : rc;
}
}
switch (hfunc) { switch (hfunc) {
case ETH_RSS_HASH_NO_CHANGE: case ETH_RSS_HASH_NO_CHANGE:
...@@ -746,7 +760,7 @@ static int ena_set_rxfh(struct net_device *netdev, const u32 *indir, ...@@ -746,7 +760,7 @@ static int ena_set_rxfh(struct net_device *netdev, const u32 *indir,
return -EOPNOTSUPP; return -EOPNOTSUPP;
} }
if (key) { if (key || func) {
rc = ena_com_fill_hash_function(ena_dev, func, key, rc = ena_com_fill_hash_function(ena_dev, func, key,
ENA_HASH_KEY_SIZE, ENA_HASH_KEY_SIZE,
0xFFFFFFFF); 0xFFFFFFFF);
......
...@@ -1762,6 +1762,9 @@ static void ena_unmask_interrupt(struct ena_ring *tx_ring, ...@@ -1762,6 +1762,9 @@ static void ena_unmask_interrupt(struct ena_ring *tx_ring,
tx_ring->smoothed_interval, tx_ring->smoothed_interval,
true); true);
u64_stats_update_begin(&tx_ring->syncp);
tx_ring->tx_stats.unmask_interrupt++;
u64_stats_update_end(&tx_ring->syncp);
/* It is a shared MSI-X. /* It is a shared MSI-X.
* Tx and Rx CQ have pointer to it. * Tx and Rx CQ have pointer to it.
* So we use one of them to reach the intr reg * So we use one of them to reach the intr reg
...@@ -3169,6 +3172,7 @@ static void ena_get_stats64(struct net_device *netdev, ...@@ -3169,6 +3172,7 @@ static void ena_get_stats64(struct net_device *netdev,
struct ena_ring *rx_ring, *tx_ring; struct ena_ring *rx_ring, *tx_ring;
unsigned int start; unsigned int start;
u64 rx_drops; u64 rx_drops;
u64 tx_drops;
int i; int i;
if (!test_bit(ENA_FLAG_DEV_UP, &adapter->flags)) if (!test_bit(ENA_FLAG_DEV_UP, &adapter->flags))
...@@ -3203,9 +3207,11 @@ static void ena_get_stats64(struct net_device *netdev, ...@@ -3203,9 +3207,11 @@ static void ena_get_stats64(struct net_device *netdev,
do { do {
start = u64_stats_fetch_begin_irq(&adapter->syncp); start = u64_stats_fetch_begin_irq(&adapter->syncp);
rx_drops = adapter->dev_stats.rx_drops; rx_drops = adapter->dev_stats.rx_drops;
tx_drops = adapter->dev_stats.tx_drops;
} while (u64_stats_fetch_retry_irq(&adapter->syncp, start)); } while (u64_stats_fetch_retry_irq(&adapter->syncp, start));
stats->rx_dropped = rx_drops; stats->rx_dropped = rx_drops;
stats->tx_dropped = tx_drops;
stats->multicast = 0; stats->multicast = 0;
stats->collisions = 0; stats->collisions = 0;
...@@ -3433,6 +3439,7 @@ static void ena_destroy_device(struct ena_adapter *adapter, bool graceful) ...@@ -3433,6 +3439,7 @@ static void ena_destroy_device(struct ena_adapter *adapter, bool graceful)
ena_com_mmio_reg_read_request_destroy(ena_dev); ena_com_mmio_reg_read_request_destroy(ena_dev);
/* return reset reason to default value */
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);
...@@ -3991,7 +3998,7 @@ static int ena_rss_init_default(struct ena_adapter *adapter) ...@@ -3991,7 +3998,7 @@ static int ena_rss_init_default(struct ena_adapter *adapter)
} }
} }
rc = ena_com_fill_hash_function(ena_dev, ENA_ADMIN_CRC32, NULL, rc = ena_com_fill_hash_function(ena_dev, ENA_ADMIN_TOEPLITZ, NULL,
ENA_HASH_KEY_SIZE, 0xFFFFFFFF); ENA_HASH_KEY_SIZE, 0xFFFFFFFF);
if (unlikely(rc && (rc != -EOPNOTSUPP))) { if (unlikely(rc && (rc != -EOPNOTSUPP))) {
dev_err(dev, "Cannot fill hash function\n"); dev_err(dev, "Cannot fill hash function\n");
...@@ -4356,6 +4363,7 @@ static void __ena_shutoff(struct pci_dev *pdev, bool shutdown) ...@@ -4356,6 +4363,7 @@ static void __ena_shutoff(struct pci_dev *pdev, bool shutdown)
cancel_work_sync(&adapter->reset_task); cancel_work_sync(&adapter->reset_task);
rtnl_lock(); /* lock released inside the below if-else block */ rtnl_lock(); /* lock released inside the below if-else block */
adapter->reset_reason = ENA_REGS_RESET_SHUTDOWN;
ena_destroy_device(adapter, true); ena_destroy_device(adapter, true);
if (shutdown) { if (shutdown) {
netif_device_detach(netdev); netif_device_detach(netdev);
...@@ -4514,14 +4522,17 @@ static void ena_keep_alive_wd(void *adapter_data, ...@@ -4514,14 +4522,17 @@ static void ena_keep_alive_wd(void *adapter_data,
struct ena_adapter *adapter = (struct ena_adapter *)adapter_data; struct ena_adapter *adapter = (struct ena_adapter *)adapter_data;
struct ena_admin_aenq_keep_alive_desc *desc; struct ena_admin_aenq_keep_alive_desc *desc;
u64 rx_drops; u64 rx_drops;
u64 tx_drops;
desc = (struct ena_admin_aenq_keep_alive_desc *)aenq_e; desc = (struct ena_admin_aenq_keep_alive_desc *)aenq_e;
adapter->last_keep_alive_jiffies = jiffies; adapter->last_keep_alive_jiffies = jiffies;
rx_drops = ((u64)desc->rx_drops_high << 32) | desc->rx_drops_low; rx_drops = ((u64)desc->rx_drops_high << 32) | desc->rx_drops_low;
tx_drops = ((u64)desc->tx_drops_high << 32) | desc->tx_drops_low;
u64_stats_update_begin(&adapter->syncp); u64_stats_update_begin(&adapter->syncp);
adapter->dev_stats.rx_drops = rx_drops; adapter->dev_stats.rx_drops = rx_drops;
adapter->dev_stats.tx_drops = tx_drops;
u64_stats_update_end(&adapter->syncp); u64_stats_update_end(&adapter->syncp);
} }
......
...@@ -248,6 +248,7 @@ struct ena_stats_tx { ...@@ -248,6 +248,7 @@ struct ena_stats_tx {
u64 bad_req_id; u64 bad_req_id;
u64 llq_buffer_copy; u64 llq_buffer_copy;
u64 missed_tx; u64 missed_tx;
u64 unmask_interrupt;
}; };
struct ena_stats_rx { struct ena_stats_rx {
...@@ -333,6 +334,7 @@ struct ena_stats_dev { ...@@ -333,6 +334,7 @@ struct ena_stats_dev {
u64 interface_down; u64 interface_down;
u64 admin_q_pause; u64 admin_q_pause;
u64 rx_drops; u64 rx_drops;
u64 tx_drops;
}; };
enum ena_flags_t { enum ena_flags_t {
......
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