drivers/net/ethernet/mellanox/mlx5/core/en/params.c

Source file repositories/reference/linux-study-clean/drivers/net/ethernet/mellanox/mlx5/core/en/params.c

File Facts

System
Linux kernel
Corpus path
drivers/net/ethernet/mellanox/mlx5/core/en/params.c
Extension
.c
Size
43414 bytes
Lines
1330
Domain
Driver Families
Bucket
drivers/net
Inferred role
Driver Families: implementation source
Status
source implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

if (byte_count > max_mtu) {
			mlx5_core_err(mdev, "MTU %u is too big for non-linear legacy RQ (max %d)\n",
				      params->sw_mtu, max_mtu);
			return -EINVAL;
		}
	}

	i = 0;
	while (buf_size < byte_count) {
		int frag_size = byte_count - buf_size;

		if (i == 0)
			frag_size = min(frag_size, first_frag_size_max);
		else if (i < MLX5E_MAX_RX_FRAGS - 1)
			frag_size = min(frag_size, frag_size_max);

		info->arr[i].frag_size = frag_size;
		buf_size += frag_size;

		if (params->xdp_prog) {
			/* XDP multi buffer expects fragments of the same size. */
			info->arr[i].frag_stride = frag_size_max;
		} else {
			if (i == 0) {
				/* Ensure that headroom and tailroom are included. */
				frag_size += headroom;
				frag_size += SKB_DATA_ALIGN(sizeof(struct skb_shared_info));
			}
			info->arr[i].frag_stride = roundup_pow_of_two(frag_size);
		}

		i++;
	}
	info->num_frags = i;

	/* The last fragment of WQE with index 2*N may share the page with the
	 * first fragment of WQE with index 2*N+1 in certain cases. If WQE 2*N+1
	 * is not completed yet, WQE 2*N must not be allocated, as it's
	 * responsible for allocating a new page.
	 */
	if (frag_size_max == PAGE_SIZE) {
		/* No WQE can start in the middle of a page. */
		info->wqe_index_mask = 0;
	} else {
		/* PAGE_SIZEs starting from 8192 don't use 2K-sized fragments,
		 * because there would be more than MLX5E_MAX_RX_FRAGS of them.
		 */
		WARN_ON(PAGE_SIZE != 2 * DEFAULT_FRAG_SIZE);

		/* Odd number of fragments allows to pack the last fragment of
		 * the previous WQE and the first fragment of the next WQE into
		 * the same page.
		 * As long as DEFAULT_FRAG_SIZE is 2048, and MLX5E_MAX_RX_FRAGS
		 * is 4, the last fragment can be bigger than the rest only if
		 * it's the fourth one, so WQEs consisting of 3 fragments will
		 * always share a page.
		 * When a page is shared, WQE bulk size is 2, otherwise just 1.
		 */
		info->wqe_index_mask = info->num_frags % 2;
	}

out:
	/* Bulking optimization to skip allocation until a large enough number
	 * of WQEs can be allocated in a row. Bulking also influences how well
	 * deferred page release works.
	 */
	mlx5e_rx_compute_wqe_bulk_params(params, info);

	mlx5_core_dbg(mdev, "%s: wqe_bulk = %u, wqe_bulk_refill_unit = %u\n",
		      __func__, info->wqe_bulk, info->refill_unit);

	info->log_num_frags = order_base_2(info->num_frags);

	*xdp_frag_size = info->num_frags > 1 && params->xdp_prog ? PAGE_SIZE : 0;

	return 0;
}

static u8 mlx5e_get_rqwq_log_stride(u8 wq_type, int ndsegs)
{
	int sz = sizeof(struct mlx5_wqe_data_seg) * ndsegs;

	switch (wq_type) {
	case MLX5_WQ_TYPE_LINKED_LIST_STRIDING_RQ:
		sz += sizeof(struct mlx5e_rx_wqe_ll);
		break;
	default: /* MLX5_WQ_TYPE_CYCLIC */
		sz += sizeof(struct mlx5e_rx_wqe_cyc);
	}

Annotation

Implementation Notes