mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-12-12 21:44:06 +08:00
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: David S. Miller <davem@davemloft.net>
This commit is contained in:
commit
d1a2250954
@ -404,6 +404,10 @@ struct ena_admin_basic_stats {
|
||||
u32 rx_drops_low;
|
||||
|
||||
u32 rx_drops_high;
|
||||
|
||||
u32 tx_drops_low;
|
||||
|
||||
u32 tx_drops_high;
|
||||
};
|
||||
|
||||
struct ena_admin_acq_get_stats_resp {
|
||||
@ -1017,6 +1021,10 @@ struct ena_admin_aenq_keep_alive_desc {
|
||||
u32 rx_drops_low;
|
||||
|
||||
u32 rx_drops_high;
|
||||
|
||||
u32 tx_drops_low;
|
||||
|
||||
u32 tx_drops_high;
|
||||
};
|
||||
|
||||
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)
|
||||
static int ena_com_hash_key_allocate(struct ena_com_dev *ena_dev)
|
||||
{
|
||||
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,
|
||||
ENA_ADMIN_RSS_HASH_FUNCTION,
|
||||
ena_dev->rss.hash_key_dma_addr,
|
||||
sizeof(ena_dev->rss.hash_key), 0);
|
||||
if (unlikely(rc)) {
|
||||
if (!ena_com_check_supported_feature_id(ena_dev,
|
||||
ENA_ADMIN_RSS_HASH_FUNCTION))
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
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,
|
||||
struct ena_admin_get_feat_resp get_resp;
|
||||
struct ena_admin_feature_rss_flow_hash_control *hash_key =
|
||||
rss->hash_key;
|
||||
enum ena_admin_hash_functions old_func;
|
||||
int rc;
|
||||
|
||||
/* Make sure size is a mult of DWs */
|
||||
@ -2325,26 +2320,27 @@ int ena_com_fill_hash_function(struct ena_com_dev *ena_dev,
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
old_func = rss->hash_func;
|
||||
rss->hash_func = func;
|
||||
rc = ena_com_set_hash_function(ena_dev);
|
||||
|
||||
/* Restore the old function */
|
||||
if (unlikely(rc))
|
||||
ena_com_get_hash_function(ena_dev, NULL, NULL);
|
||||
rss->hash_func = old_func;
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
int ena_com_get_hash_function(struct ena_com_dev *ena_dev,
|
||||
enum ena_admin_hash_functions *func,
|
||||
u8 *key)
|
||||
enum ena_admin_hash_functions *func)
|
||||
{
|
||||
struct ena_rss *rss = &ena_dev->rss;
|
||||
struct ena_admin_get_feat_resp get_resp;
|
||||
struct ena_admin_feature_rss_flow_hash_control *hash_key =
|
||||
rss->hash_key;
|
||||
int rc;
|
||||
|
||||
if (unlikely(!func))
|
||||
return -EINVAL;
|
||||
|
||||
rc = ena_com_get_feature_ex(ena_dev, &get_resp,
|
||||
ENA_ADMIN_RSS_HASH_FUNCTION,
|
||||
rss->hash_key_dma_addr,
|
||||
@ -2357,8 +2353,15 @@ int ena_com_get_hash_function(struct ena_com_dev *ena_dev,
|
||||
if (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)
|
||||
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)
|
||||
* ignore this error and have indirection table support only.
|
||||
*/
|
||||
rc = ena_com_hash_key_allocate(ena_dev);
|
||||
if (unlikely(rc) && rc != -EOPNOTSUPP)
|
||||
goto err_hash_key;
|
||||
else if (rc != -EOPNOTSUPP)
|
||||
if (likely(!rc))
|
||||
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);
|
||||
if (unlikely(rc))
|
||||
|
@ -54,9 +54,9 @@
|
||||
#undef pr_fmt
|
||||
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
|
||||
|
||||
#define ENA_MAX_NUM_IO_QUEUES 128U
|
||||
#define ENA_MAX_NUM_IO_QUEUES 128U
|
||||
/* We need to queues for each IO (on for Tx and one for Rx) */
|
||||
#define ENA_TOTAL_NUM_QUEUES (2 * (ENA_MAX_NUM_IO_QUEUES))
|
||||
#define ENA_TOTAL_NUM_QUEUES (2 * (ENA_MAX_NUM_IO_QUEUES))
|
||||
|
||||
#define ENA_MAX_HANDLERS 256
|
||||
|
||||
@ -73,13 +73,13 @@
|
||||
/*****************************************************************************/
|
||||
/* ENA adaptive interrupt moderation settings */
|
||||
|
||||
#define ENA_INTR_INITIAL_TX_INTERVAL_USECS 64
|
||||
#define ENA_INTR_INITIAL_RX_INTERVAL_USECS 0
|
||||
#define ENA_DEFAULT_INTR_DELAY_RESOLUTION 1
|
||||
#define ENA_INTR_INITIAL_TX_INTERVAL_USECS 64
|
||||
#define ENA_INTR_INITIAL_RX_INTERVAL_USECS 0
|
||||
#define ENA_DEFAULT_INTR_DELAY_RESOLUTION 1
|
||||
|
||||
#define ENA_HW_HINTS_NO_TIMEOUT 0xFFFF
|
||||
#define ENA_HW_HINTS_NO_TIMEOUT 0xFFFF
|
||||
|
||||
#define ENA_FEATURE_MAX_QUEUE_EXT_VER 1
|
||||
#define ENA_FEATURE_MAX_QUEUE_EXT_VER 1
|
||||
|
||||
struct ena_llq_configurations {
|
||||
enum ena_admin_llq_header_location llq_header_location;
|
||||
@ -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);
|
||||
|
||||
/* 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_dev: ENA communication layer struct
|
||||
* @polling: Enable/Disable polling mode
|
||||
@ -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);
|
||||
|
||||
/* ena_com_get_hash_function - Retrieve the hash function and the hash key
|
||||
* from the device.
|
||||
/* ena_com_get_hash_function - Retrieve the hash function from the device.
|
||||
* @ena_dev: ENA communication layer struct
|
||||
* @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
|
||||
* 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);
|
||||
* @return: 0 on Success and negative value otherwise.
|
||||
*/
|
||||
int ena_com_get_hash_function(struct ena_com_dev *ena_dev,
|
||||
enum ena_admin_hash_functions *func,
|
||||
u8 *key);
|
||||
enum ena_admin_hash_functions *func);
|
||||
|
||||
/* 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_dev: ENA communication layer struct.
|
||||
* @proto: The protocol to configure.
|
||||
|
@ -83,6 +83,7 @@ static const struct ena_stats ena_stats_tx_strings[] = {
|
||||
ENA_STAT_TX_ENTRY(bad_req_id),
|
||||
ENA_STAT_TX_ENTRY(llq_buffer_copy),
|
||||
ENA_STAT_TX_ENTRY(missed_tx),
|
||||
ENA_STAT_TX_ENTRY(unmask_interrupt),
|
||||
};
|
||||
|
||||
static const struct ena_stats ena_stats_rx_strings[] = {
|
||||
@ -635,6 +636,32 @@ static u32 ena_get_rxfh_key_size(struct net_device *netdev)
|
||||
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)
|
||||
{
|
||||
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,
|
||||
/* We call this function in order to check if the device
|
||||
* 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 == -EOPNOTSUPP) {
|
||||
key = NULL;
|
||||
hfunc = NULL;
|
||||
if (rc == -EOPNOTSUPP)
|
||||
rc = 0;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
rc = ena_com_get_hash_key(adapter->ena_dev, key);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
switch (ena_func) {
|
||||
case ENA_ADMIN_TOEPLITZ:
|
||||
func = ETH_RSS_HASH_TOP;
|
||||
@ -699,7 +727,7 @@ static int ena_get_rxfh(struct net_device *netdev, u32 *indir, u8 *key,
|
||||
if (hfunc)
|
||||
*hfunc = func;
|
||||
|
||||
return rc;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ena_set_rxfh(struct net_device *netdev, const u32 *indir,
|
||||
@ -707,27 +735,13 @@ static int ena_set_rxfh(struct net_device *netdev, const u32 *indir,
|
||||
{
|
||||
struct ena_adapter *adapter = netdev_priv(netdev);
|
||||
struct ena_com_dev *ena_dev = adapter->ena_dev;
|
||||
enum ena_admin_hash_functions func;
|
||||
int rc, i;
|
||||
enum ena_admin_hash_functions func = 0;
|
||||
int rc;
|
||||
|
||||
if (indir) {
|
||||
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, 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, netdev,
|
||||
"Cannot set indirect table\n");
|
||||
return rc == -EPERM ? -EOPNOTSUPP : rc;
|
||||
}
|
||||
rc = ena_indirection_table_set(adapter, indir);
|
||||
if (rc)
|
||||
return rc;
|
||||
}
|
||||
|
||||
switch (hfunc) {
|
||||
@ -746,7 +760,7 @@ static int ena_set_rxfh(struct net_device *netdev, const u32 *indir,
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
if (key) {
|
||||
if (key || func) {
|
||||
rc = ena_com_fill_hash_function(ena_dev, func, key,
|
||||
ENA_HASH_KEY_SIZE,
|
||||
0xFFFFFFFF);
|
||||
|
@ -1762,6 +1762,9 @@ static void ena_unmask_interrupt(struct ena_ring *tx_ring,
|
||||
tx_ring->smoothed_interval,
|
||||
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.
|
||||
* Tx and Rx CQ have pointer to it.
|
||||
* So we use one of them to reach the intr reg
|
||||
@ -3169,6 +3172,7 @@ static void ena_get_stats64(struct net_device *netdev,
|
||||
struct ena_ring *rx_ring, *tx_ring;
|
||||
unsigned int start;
|
||||
u64 rx_drops;
|
||||
u64 tx_drops;
|
||||
int i;
|
||||
|
||||
if (!test_bit(ENA_FLAG_DEV_UP, &adapter->flags))
|
||||
@ -3203,9 +3207,11 @@ static void ena_get_stats64(struct net_device *netdev,
|
||||
do {
|
||||
start = u64_stats_fetch_begin_irq(&adapter->syncp);
|
||||
rx_drops = adapter->dev_stats.rx_drops;
|
||||
tx_drops = adapter->dev_stats.tx_drops;
|
||||
} while (u64_stats_fetch_retry_irq(&adapter->syncp, start));
|
||||
|
||||
stats->rx_dropped = rx_drops;
|
||||
stats->tx_dropped = tx_drops;
|
||||
|
||||
stats->multicast = 0;
|
||||
stats->collisions = 0;
|
||||
@ -3433,6 +3439,7 @@ static void ena_destroy_device(struct ena_adapter *adapter, bool graceful)
|
||||
|
||||
ena_com_mmio_reg_read_request_destroy(ena_dev);
|
||||
|
||||
/* return reset reason to default value */
|
||||
adapter->reset_reason = ENA_REGS_RESET_NORMAL;
|
||||
|
||||
clear_bit(ENA_FLAG_TRIGGER_RESET, &adapter->flags);
|
||||
@ -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);
|
||||
if (unlikely(rc && (rc != -EOPNOTSUPP))) {
|
||||
dev_err(dev, "Cannot fill hash function\n");
|
||||
@ -4356,6 +4363,7 @@ static void __ena_shutoff(struct pci_dev *pdev, bool shutdown)
|
||||
cancel_work_sync(&adapter->reset_task);
|
||||
|
||||
rtnl_lock(); /* lock released inside the below if-else block */
|
||||
adapter->reset_reason = ENA_REGS_RESET_SHUTDOWN;
|
||||
ena_destroy_device(adapter, true);
|
||||
if (shutdown) {
|
||||
netif_device_detach(netdev);
|
||||
@ -4514,14 +4522,17 @@ static void ena_keep_alive_wd(void *adapter_data,
|
||||
struct ena_adapter *adapter = (struct ena_adapter *)adapter_data;
|
||||
struct ena_admin_aenq_keep_alive_desc *desc;
|
||||
u64 rx_drops;
|
||||
u64 tx_drops;
|
||||
|
||||
desc = (struct ena_admin_aenq_keep_alive_desc *)aenq_e;
|
||||
adapter->last_keep_alive_jiffies = jiffies;
|
||||
|
||||
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);
|
||||
adapter->dev_stats.rx_drops = rx_drops;
|
||||
adapter->dev_stats.tx_drops = tx_drops;
|
||||
u64_stats_update_end(&adapter->syncp);
|
||||
}
|
||||
|
||||
|
@ -248,6 +248,7 @@ struct ena_stats_tx {
|
||||
u64 bad_req_id;
|
||||
u64 llq_buffer_copy;
|
||||
u64 missed_tx;
|
||||
u64 unmask_interrupt;
|
||||
};
|
||||
|
||||
struct ena_stats_rx {
|
||||
@ -333,6 +334,7 @@ struct ena_stats_dev {
|
||||
u64 interface_down;
|
||||
u64 admin_q_pause;
|
||||
u64 rx_drops;
|
||||
u64 tx_drops;
|
||||
};
|
||||
|
||||
enum ena_flags_t {
|
||||
|
Loading…
Reference in New Issue
Block a user