drivers/net/ethernet/intel/ice/ice_ddp.c

Source file repositories/reference/linux-study-clean/drivers/net/ethernet/intel/ice/ice_ddp.c

File Facts

System
Linux kernel
Corpus path
drivers/net/ethernet/intel/ice/ice_ddp.c
Extension
.c
Size
71400 bytes
Lines
2548
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

struct ice_ddp_send_ctx {
	struct ice_hw *hw;
/* private: only for ice_ddp_send_hunk() */
	struct ice_buf_hdr *hdr;
	int err;
};

static void ice_ddp_send_ctx_set_err(struct ice_ddp_send_ctx *ctx, int err)
{
	ctx->err = err;
}

/**
 * ice_ddp_send_hunk - send one hunk of data to FW
 * @ctx: current segment sending context
 * @hunk: next hunk to send, size is always ICE_PKG_BUF_SIZE
 *
 * Send the next hunk of data to FW, retrying if needed.
 *
 * Notice: must be called once more with a NULL @hunk to finish up; such call
 * will set up the "last" bit of an AQ request. After such call @ctx.hdr is
 * cleared, @hw is still valid.
 *
 * Return: %ICE_DDP_PKG_SUCCESS if there were no problems; a sticky @err
 *         otherwise.
 */
static enum ice_ddp_state ice_ddp_send_hunk(struct ice_ddp_send_ctx *ctx,
					    struct ice_buf_hdr *hunk)
{
	struct ice_buf_hdr *prev_hunk = ctx->hdr;
	struct ice_hw *hw = ctx->hw;
	bool prev_was_last = !hunk;
	enum libie_aq_err aq_err;
	u32 offset, info;
	int attempt, err;

	if (ctx->err)
		return ctx->err;

	ctx->hdr = hunk;
	if (!prev_hunk)
		return ICE_DDP_PKG_SUCCESS; /* no problem so far */

	for (attempt = 0; attempt < 5; attempt++) {
		if (attempt)
			msleep(20);

		err = ice_aq_download_pkg(hw, prev_hunk, ICE_PKG_BUF_SIZE,
					  prev_was_last, &offset, &info, NULL);

		aq_err = hw->adminq.sq_last_status;
		if (aq_err != LIBIE_AQ_RC_ENOSEC &&
		    aq_err != LIBIE_AQ_RC_EBADSIG)
			break;
	}

	if (err) {
		ice_debug(hw, ICE_DBG_PKG, "Pkg download failed: err %d off %d inf %d\n",
			  err, offset, info);
		ctx->err = ice_map_aq_err_to_ddp_state(aq_err);
	} else if (attempt) {
		dev_dbg(ice_hw_to_dev(hw),
			"ice_aq_download_pkg number of retries: %d\n", attempt);
	}

	return ctx->err;
}

/**
 * ice_dwnld_cfg_bufs_no_lock
 * @ctx: context of the current buffers section to send
 * @bufs: pointer to an array of buffers
 * @start: buffer index of first buffer to download
 * @count: the number of buffers to download
 *
 * Downloads package configuration buffers to the firmware. Metadata buffers
 * are skipped, and the first metadata buffer found indicates that the rest
 * of the buffers are all metadata buffers.
 */
static enum ice_ddp_state
ice_dwnld_cfg_bufs_no_lock(struct ice_ddp_send_ctx *ctx, struct ice_buf *bufs,
			   u32 start, u32 count)
{
	struct ice_buf_hdr *bh;
	enum ice_ddp_state err;

	if (!bufs || !count) {
		ice_ddp_send_ctx_set_err(ctx, ICE_DDP_PKG_ERR);
		return ICE_DDP_PKG_ERR;
	}

Annotation

Implementation Notes