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

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
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
@@ -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 {
+21 −18
Original line number Diff line number Diff line
@@ -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,9 +2353,16 @@ 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;

	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))
+22 −25
Original line number Diff line number Diff line
@@ -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.
+40 −26
Original line number Diff line number Diff line
@@ -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,28 +735,14 @@ 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");
		rc = ena_indirection_table_set(adapter, indir);
		if (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) {
	case ETH_RSS_HASH_NO_CHANGE:
@@ -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);
+12 −1
Original line number Diff line number Diff line
@@ -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);
}

Loading