Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

Merge branch 'ena-new-features-and-improvements'



Netanel Belgazal says:

====================
net: update ena ethernet driver to version 1.2.0

This patchset contains some new features/improvements that were added
to the ENA driver to increase its robustness and are based on
experience of wide ENA deployment.

Change log:

V2:
* Remove patch that add inline to C-file static function (contradict coding style).
* Remove patch that moves MTU parameter validation in ena_change_mtu() instead of
using the network stack.
* Use upper_32_bits()/lower_32_bits() instead of casting.
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 926f38e9 85238999
Loading
Loading
Loading
Loading
+31 −0
Original line number Diff line number Diff line
@@ -70,6 +70,8 @@ enum ena_admin_aq_feature_id {

	ENA_ADMIN_MAX_QUEUES_NUM		= 2,

	ENA_ADMIN_HW_HINTS			= 3,

	ENA_ADMIN_RSS_HASH_FUNCTION		= 10,

	ENA_ADMIN_STATELESS_OFFLOAD_CONFIG	= 11,
@@ -749,6 +751,31 @@ struct ena_admin_feature_rss_ind_table {
	struct ena_admin_rss_ind_table_entry inline_entry;
};

/* When hint value is 0, driver should use it's own predefined value */
struct ena_admin_ena_hw_hints {
	/* value in ms */
	u16 mmio_read_timeout;

	/* value in ms */
	u16 driver_watchdog_timeout;

	/* Per packet tx completion timeout. value in ms */
	u16 missing_tx_completion_timeout;

	u16 missed_tx_completion_count_threshold_to_reset;

	/* value in ms */
	u16 admin_completion_tx_timeout;

	u16 netdev_wd_timeout;

	u16 max_tx_sgl_size;

	u16 max_rx_sgl_size;

	u16 reserved[8];
};

struct ena_admin_get_feat_cmd {
	struct ena_admin_aq_common_desc aq_common_descriptor;

@@ -782,6 +809,8 @@ struct ena_admin_get_feat_resp {
		struct ena_admin_feature_rss_ind_table ind_table;

		struct ena_admin_feature_intr_moder_desc intr_moderation;

		struct ena_admin_ena_hw_hints hw_hints;
	} u;
};

@@ -857,6 +886,8 @@ enum ena_admin_aenq_notification_syndrom {
	ENA_ADMIN_SUSPEND	= 0,

	ENA_ADMIN_RESUME	= 1,

	ENA_ADMIN_UPDATE_HINTS	= 2,
};

struct ena_admin_aenq_entry {
+57 −28
Original line number Diff line number Diff line
@@ -99,8 +99,8 @@ static inline int ena_com_mem_addr_set(struct ena_com_dev *ena_dev,
		return -EINVAL;
	}

	ena_addr->mem_addr_low = (u32)addr;
	ena_addr->mem_addr_high = (u64)addr >> 32;
	ena_addr->mem_addr_low = lower_32_bits(addr);
	ena_addr->mem_addr_high = (u16)upper_32_bits(addr);

	return 0;
}
@@ -329,7 +329,7 @@ static int ena_com_init_io_sq(struct ena_com_dev *ena_dev,
	size_t size;
	int dev_node = 0;

	memset(&io_sq->desc_addr, 0x0, sizeof(struct ena_com_io_desc_addr));
	memset(&io_sq->desc_addr, 0x0, sizeof(io_sq->desc_addr));

	io_sq->desc_entry_size =
		(io_sq->direction == ENA_COM_IO_QUEUE_DIRECTION_TX) ?
@@ -383,7 +383,7 @@ static int ena_com_init_io_cq(struct ena_com_dev *ena_dev,
	size_t size;
	int prev_node = 0;

	memset(&io_cq->cdesc_addr, 0x0, sizeof(struct ena_com_io_desc_addr));
	memset(&io_cq->cdesc_addr, 0x0, sizeof(io_cq->cdesc_addr));

	/* Use the basic completion descriptor for Rx */
	io_cq->cdesc_entry_size_in_bytes =
@@ -494,7 +494,7 @@ static int ena_com_comp_status_to_errno(u8 comp_status)
	case ENA_ADMIN_RESOURCE_ALLOCATION_FAILURE:
		return -ENOMEM;
	case ENA_ADMIN_UNSUPPORTED_OPCODE:
		return -EPERM;
		return -EOPNOTSUPP;
	case ENA_ADMIN_BAD_OPCODE:
	case ENA_ADMIN_MALFORMED_REQUEST:
	case ENA_ADMIN_ILLEGAL_PARAMETER:
@@ -511,7 +511,7 @@ static int ena_com_wait_and_process_admin_cq_polling(struct ena_comp_ctx *comp_c
	unsigned long flags, timeout;
	int ret;

	timeout = jiffies + ADMIN_CMD_TIMEOUT_US;
	timeout = jiffies + usecs_to_jiffies(admin_queue->completion_timeout);

	while (1) {
		spin_lock_irqsave(&admin_queue->q_lock, flags);
@@ -561,7 +561,8 @@ static int ena_com_wait_and_process_admin_cq_interrupts(struct ena_comp_ctx *com
	int ret;

	wait_for_completion_timeout(&comp_ctx->wait_event,
				    usecs_to_jiffies(ADMIN_CMD_TIMEOUT_US));
				    usecs_to_jiffies(
					    admin_queue->completion_timeout));

	/* In case the command wasn't completed find out the root cause.
	 * There might be 2 kinds of errors
@@ -601,12 +602,15 @@ static u32 ena_com_reg_bar_read32(struct ena_com_dev *ena_dev, u16 offset)
	struct ena_com_mmio_read *mmio_read = &ena_dev->mmio_read;
	volatile struct ena_admin_ena_mmio_req_read_less_resp *read_resp =
		mmio_read->read_resp;
	u32 mmio_read_reg, ret;
	u32 mmio_read_reg, ret, i;
	unsigned long flags;
	int i;
	u32 timeout = mmio_read->reg_read_to;

	might_sleep();

	if (timeout == 0)
		timeout = ENA_REG_READ_TIMEOUT;

	/* If readless is disabled, perform regular read */
	if (!mmio_read->readless_supported)
		return readl(ena_dev->reg_bar + offset);
@@ -627,14 +631,14 @@ static u32 ena_com_reg_bar_read32(struct ena_com_dev *ena_dev, u16 offset)

	writel(mmio_read_reg, ena_dev->reg_bar + ENA_REGS_MMIO_REG_READ_OFF);

	for (i = 0; i < ENA_REG_READ_TIMEOUT; i++) {
	for (i = 0; i < timeout; i++) {
		if (read_resp->req_id == mmio_read->seq_num)
			break;

		udelay(1);
	}

	if (unlikely(i == ENA_REG_READ_TIMEOUT)) {
	if (unlikely(i == timeout)) {
		pr_err("reading reg failed for timeout. expected: req id[%hu] offset[%hu] actual: req id[%hu] offset[%hu]\n",
		       mmio_read->seq_num, offset, read_resp->req_id,
		       read_resp->reg_off);
@@ -681,7 +685,7 @@ static int ena_com_destroy_io_sq(struct ena_com_dev *ena_dev,
	u8 direction;
	int ret;

	memset(&destroy_cmd, 0x0, sizeof(struct ena_admin_aq_destroy_sq_cmd));
	memset(&destroy_cmd, 0x0, sizeof(destroy_cmd));

	if (io_sq->direction == ENA_COM_IO_QUEUE_DIRECTION_TX)
		direction = ENA_ADMIN_SQ_DIRECTION_TX;
@@ -786,7 +790,7 @@ static int ena_com_get_feature_ex(struct ena_com_dev *ena_dev,

	if (!ena_com_check_supported_feature_id(ena_dev, feature_id)) {
		pr_debug("Feature %d isn't supported\n", feature_id);
		return -EPERM;
		return -EOPNOTSUPP;
	}

	memset(&get_cmd, 0x0, sizeof(get_cmd));
@@ -963,7 +967,7 @@ static int ena_com_create_io_sq(struct ena_com_dev *ena_dev,
	u8 direction;
	int ret;

	memset(&create_cmd, 0x0, sizeof(struct ena_admin_aq_create_sq_cmd));
	memset(&create_cmd, 0x0, sizeof(create_cmd));

	create_cmd.aq_common_descriptor.opcode = ENA_ADMIN_CREATE_SQ;

@@ -1155,7 +1159,7 @@ int ena_com_create_io_cq(struct ena_com_dev *ena_dev,
	struct ena_admin_acq_create_cq_resp_desc cmd_completion;
	int ret;

	memset(&create_cmd, 0x0, sizeof(struct ena_admin_aq_create_cq_cmd));
	memset(&create_cmd, 0x0, sizeof(create_cmd));

	create_cmd.aq_common_descriptor.opcode = ENA_ADMIN_CREATE_CQ;

@@ -1263,7 +1267,7 @@ int ena_com_destroy_io_cq(struct ena_com_dev *ena_dev,
	struct ena_admin_acq_destroy_cq_resp_desc destroy_resp;
	int ret;

	memset(&destroy_cmd, 0x0, sizeof(struct ena_admin_aq_destroy_sq_cmd));
	memset(&destroy_cmd, 0x0, sizeof(destroy_cmd));

	destroy_cmd.cq_idx = io_cq->idx;
	destroy_cmd.aq_common_descriptor.opcode = ENA_ADMIN_DESTROY_CQ;
@@ -1324,7 +1328,7 @@ int ena_com_set_aenq_config(struct ena_com_dev *ena_dev, u32 groups_flag)
	if ((get_resp.u.aenq.supported_groups & groups_flag) != groups_flag) {
		pr_warn("Trying to set unsupported aenq events. supported flag: %x asked flag: %x\n",
			get_resp.u.aenq.supported_groups, groups_flag);
		return -EPERM;
		return -EOPNOTSUPP;
	}

	memset(&cmd, 0x0, sizeof(cmd));
@@ -1619,8 +1623,8 @@ int ena_com_create_io_queue(struct ena_com_dev *ena_dev,
	io_sq = &ena_dev->io_sq_queues[ctx->qid];
	io_cq = &ena_dev->io_cq_queues[ctx->qid];

	memset(io_sq, 0x0, sizeof(struct ena_com_io_sq));
	memset(io_cq, 0x0, sizeof(struct ena_com_io_cq));
	memset(io_sq, 0x0, sizeof(*io_sq));
	memset(io_cq, 0x0, sizeof(*io_cq));

	/* Init CQ */
	io_cq->q_depth = ctx->queue_size;
@@ -1730,6 +1734,20 @@ int ena_com_get_dev_attr_feat(struct ena_com_dev *ena_dev,
	memcpy(&get_feat_ctx->offload, &get_resp.u.offload,
	       sizeof(get_resp.u.offload));

	/* Driver hints isn't mandatory admin command. So in case the
	 * command isn't supported set driver hints to 0
	 */
	rc = ena_com_get_feature(ena_dev, &get_resp, ENA_ADMIN_HW_HINTS);

	if (!rc)
		memcpy(&get_feat_ctx->hw_hints, &get_resp.u.hw_hints,
		       sizeof(get_resp.u.hw_hints));
	else if (rc == -EOPNOTSUPP)
		memset(&get_feat_ctx->hw_hints, 0x0,
		       sizeof(get_feat_ctx->hw_hints));
	else
		return rc;

	return 0;
}

@@ -1807,7 +1825,8 @@ void ena_com_aenq_intr_handler(struct ena_com_dev *dev, void *data)
	writel((u32)aenq->head, dev->reg_bar + ENA_REGS_AENQ_HEAD_DB_OFF);
}

int ena_com_dev_reset(struct ena_com_dev *ena_dev)
int ena_com_dev_reset(struct ena_com_dev *ena_dev,
		      enum ena_regs_reset_reason_types reset_reason)
{
	u32 stat, timeout, cap, reset_val;
	int rc;
@@ -1835,6 +1854,8 @@ int ena_com_dev_reset(struct ena_com_dev *ena_dev)

	/* start reset */
	reset_val = ENA_REGS_DEV_CTL_DEV_RESET_MASK;
	reset_val |= (reset_reason << ENA_REGS_DEV_CTL_RESET_REASON_SHIFT) &
		     ENA_REGS_DEV_CTL_RESET_REASON_MASK;
	writel(reset_val, ena_dev->reg_bar + ENA_REGS_DEV_CTL_OFF);

	/* Write again the MMIO read request address */
@@ -1855,6 +1876,14 @@ int ena_com_dev_reset(struct ena_com_dev *ena_dev)
		return rc;
	}

	timeout = (cap & ENA_REGS_CAPS_ADMIN_CMD_TO_MASK) >>
		ENA_REGS_CAPS_ADMIN_CMD_TO_SHIFT;
	if (timeout)
		/* the resolution of timeout reg is 100ms */
		ena_dev->admin_queue.completion_timeout = timeout * 100000;
	else
		ena_dev->admin_queue.completion_timeout = ADMIN_CMD_TIMEOUT_US;

	return 0;
}

@@ -1909,7 +1938,7 @@ int ena_com_set_dev_mtu(struct ena_com_dev *ena_dev, int mtu)

	if (!ena_com_check_supported_feature_id(ena_dev, ENA_ADMIN_MTU)) {
		pr_debug("Feature %d isn't supported\n", ENA_ADMIN_MTU);
		return -EPERM;
		return -EOPNOTSUPP;
	}

	memset(&cmd, 0x0, sizeof(cmd));
@@ -1963,7 +1992,7 @@ int ena_com_set_hash_function(struct ena_com_dev *ena_dev)
						ENA_ADMIN_RSS_HASH_FUNCTION)) {
		pr_debug("Feature %d isn't supported\n",
			 ENA_ADMIN_RSS_HASH_FUNCTION);
		return -EPERM;
		return -EOPNOTSUPP;
	}

	/* Validate hash function is supported */
@@ -1975,7 +2004,7 @@ int ena_com_set_hash_function(struct ena_com_dev *ena_dev)
	if (get_resp.u.flow_hash_func.supported_func & (1 << rss->hash_func)) {
		pr_err("Func hash %d isn't supported by device, abort\n",
		       rss->hash_func);
		return -EPERM;
		return -EOPNOTSUPP;
	}

	memset(&cmd, 0x0, sizeof(cmd));
@@ -2034,7 +2063,7 @@ int ena_com_fill_hash_function(struct ena_com_dev *ena_dev,

	if (!((1 << func) & get_resp.u.flow_hash_func.supported_func)) {
		pr_err("Flow hash function %d isn't supported\n", func);
		return -EPERM;
		return -EOPNOTSUPP;
	}

	switch (func) {
@@ -2127,7 +2156,7 @@ int ena_com_set_hash_ctrl(struct ena_com_dev *ena_dev)
						ENA_ADMIN_RSS_HASH_INPUT)) {
		pr_debug("Feature %d isn't supported\n",
			 ENA_ADMIN_RSS_HASH_INPUT);
		return -EPERM;
		return -EOPNOTSUPP;
	}

	memset(&cmd, 0x0, sizeof(cmd));
@@ -2208,7 +2237,7 @@ int ena_com_set_default_hash_ctrl(struct ena_com_dev *ena_dev)
			pr_err("hash control doesn't support all the desire configuration. proto %x supported %x selected %x\n",
			       i, hash_ctrl->supported_fields[i].fields,
			       hash_ctrl->selected_fields[i].fields);
			return -EPERM;
			return -EOPNOTSUPP;
		}
	}

@@ -2286,7 +2315,7 @@ int ena_com_indirect_table_set(struct ena_com_dev *ena_dev)
		    ena_dev, ENA_ADMIN_RSS_REDIRECTION_TABLE_CONFIG)) {
		pr_debug("Feature %d isn't supported\n",
			 ENA_ADMIN_RSS_REDIRECTION_TABLE_CONFIG);
		return -EPERM;
		return -EOPNOTSUPP;
	}

	ret = ena_com_ind_tbl_convert_to_device(ena_dev);
@@ -2553,7 +2582,7 @@ int ena_com_init_interrupt_moderation(struct ena_com_dev *ena_dev)
				 ENA_ADMIN_INTERRUPT_MODERATION);

	if (rc) {
		if (rc == -EPERM) {
		if (rc == -EOPNOTSUPP) {
			pr_debug("Feature %d isn't supported\n",
				 ENA_ADMIN_INTERRUPT_MODERATION);
			rc = 0;
+9 −1
Original line number Diff line number Diff line
@@ -97,6 +97,8 @@
#define ENA_INTR_MODER_LEVEL_STRIDE			2
#define ENA_INTR_BYTE_COUNT_NOT_SUPPORTED		0xFFFFFF

#define ENA_HW_HINTS_NO_TIMEOUT				0xFFFF

enum ena_intr_moder_level {
	ENA_INTR_MODER_LOWEST = 0,
	ENA_INTR_MODER_LOW,
@@ -232,7 +234,9 @@ struct ena_com_stats_admin {
struct ena_com_admin_queue {
	void *q_dmadev;
	spinlock_t q_lock; /* spinlock for the admin queue */

	struct ena_comp_ctx *comp_ctx;
	u32 completion_timeout;
	u16 q_depth;
	struct ena_com_admin_cq cq;
	struct ena_com_admin_sq sq;
@@ -267,6 +271,7 @@ struct ena_com_aenq {
struct ena_com_mmio_read {
	struct ena_admin_ena_mmio_req_read_less_resp *read_resp;
	dma_addr_t read_resp_dma_addr;
	u32 reg_read_to; /* in us */
	u16 seq_num;
	bool readless_supported;
	/* spin lock to ensure a single outstanding read */
@@ -336,6 +341,7 @@ struct ena_com_dev_get_features_ctx {
	struct ena_admin_device_attr_feature_desc dev_attr;
	struct ena_admin_feature_aenq_desc aenq;
	struct ena_admin_feature_offload_desc offload;
	struct ena_admin_ena_hw_hints hw_hints;
};

struct ena_com_create_io_ctx {
@@ -414,10 +420,12 @@ void ena_com_admin_destroy(struct ena_com_dev *ena_dev);

/* ena_com_dev_reset - Perform device FLR to the device.
 * @ena_dev: ENA communication layer struct
 * @reset_reason: Specify what is the trigger for the reset in case of an error.
 *
 * @return - 0 on success, negative value on failure.
 */
int ena_com_dev_reset(struct ena_com_dev *ena_dev);
int ena_com_dev_reset(struct ena_com_dev *ena_dev,
		      enum ena_regs_reset_reason_types reset_reason);

/* ena_com_create_io_queue - Create io queue.
 * @ena_dev: ENA communication layer struct
+5 −0
Original line number Diff line number Diff line
@@ -493,6 +493,11 @@ int ena_com_tx_comp_req_id_get(struct ena_com_io_cq *io_cq, u16 *req_id)
	if (cdesc_phase != expected_phase)
		return -EAGAIN;

	if (unlikely(cdesc->req_id >= io_cq->q_depth)) {
		pr_err("Invalid req id %d\n", cdesc->req_id);
		return -EINVAL;
	}

	ena_com_cq_inc_head(io_cq);

	*req_id = READ_ONCE(cdesc->req_id);
+4 −7
Original line number Diff line number Diff line
@@ -93,6 +93,7 @@ static const struct ena_stats ena_stats_rx_strings[] = {
	ENA_STAT_RX_ENTRY(dma_mapping_err),
	ENA_STAT_RX_ENTRY(bad_desc_num),
	ENA_STAT_RX_ENTRY(rx_copybreak_pkt),
	ENA_STAT_RX_ENTRY(bad_req_id),
	ENA_STAT_RX_ENTRY(empty_rx_ring),
};

@@ -539,12 +540,8 @@ static int ena_get_rss_hash(struct ena_com_dev *ena_dev,
	}

	rc = ena_com_get_hash_ctrl(ena_dev, proto, &hash_fields);
	if (rc) {
		/* If device don't have permission, return unsupported */
		if (rc == -EPERM)
			rc = -EOPNOTSUPP;
	if (rc)
		return rc;
	}

	cmd->data = ena_flow_hash_to_flow_type(hash_fields);

@@ -612,7 +609,7 @@ static int ena_set_rxnfc(struct net_device *netdev, struct ethtool_rxnfc *info)
		rc = -EOPNOTSUPP;
	}

	return (rc == -EPERM) ? -EOPNOTSUPP : rc;
	return rc;
}

static int ena_get_rxnfc(struct net_device *netdev, struct ethtool_rxnfc *info,
@@ -638,7 +635,7 @@ static int ena_get_rxnfc(struct net_device *netdev, struct ethtool_rxnfc *info,
		rc = -EOPNOTSUPP;
	}

	return (rc == -EPERM) ? -EOPNOTSUPP : rc;
	return rc;
}

static u32 ena_get_rxfh_indir_size(struct net_device *netdev)
Loading