drivers/net/ethernet/netronome/nfp/nfpcore/nfp_nffw.c

Source file repositories/reference/linux-study-clean/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_nffw.c

File Facts

System
Linux kernel
Corpus path
drivers/net/ethernet/netronome/nfp/nfpcore/nfp_nffw.c
Extension
.c
Size
6681 bytes
Lines
262
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 nffw_meinfo {
	__le32 ctxmask__fwid__meid;
};

struct nffw_fwinfo {
	__le32 loaded__mu_da__mip_off_hi;
	__le32 mip_cppid; /* 0 means no MIP */
	__le32 mip_offset_lo;
};

struct nfp_nffw_info_v1 {
	struct nffw_meinfo meinfo[NFFW_MEINFO_CNT_V1];
	struct nffw_fwinfo fwinfo[NFFW_FWINFO_CNT_V1];
};

struct nfp_nffw_info_v2 {
	struct nffw_meinfo meinfo[NFFW_MEINFO_CNT_V2];
	struct nffw_fwinfo fwinfo[NFFW_FWINFO_CNT_V2];
};

/** Resource: nfp.nffw main **/
struct nfp_nffw_info_data {
	__le32 flags[2];
	union {
		struct nfp_nffw_info_v1 v1;
		struct nfp_nffw_info_v2 v2;
	} info;
};

struct nfp_nffw_info {
	struct nfp_cpp *cpp;
	struct nfp_resource *res;

	struct nfp_nffw_info_data fwinf;
};

/* flg_info_version = flags[0]<27:16>
 * This is a small version counter intended only to detect if the current
 * implementation can read the current struct. Struct changes should be very
 * rare and as such a 12-bit counter should cover large spans of time. By the
 * time it wraps around, we don't expect to have 4096 versions of this struct
 * to be in use at the same time.
 */
static u32 nffw_res_info_version_get(const struct nfp_nffw_info_data *res)
{
	return (le32_to_cpu(res->flags[0]) >> 16) & 0xfff;
}

/* flg_init = flags[0]<0> */
static u32 nffw_res_flg_init_get(const struct nfp_nffw_info_data *res)
{
	return (le32_to_cpu(res->flags[0]) >> 0) & 1;
}

/* loaded = loaded__mu_da__mip_off_hi<31:31> */
static u32 nffw_fwinfo_loaded_get(const struct nffw_fwinfo *fi)
{
	return (le32_to_cpu(fi->loaded__mu_da__mip_off_hi) >> 31) & 1;
}

/* mip_cppid = mip_cppid */
static u32 nffw_fwinfo_mip_cppid_get(const struct nffw_fwinfo *fi)
{
	return le32_to_cpu(fi->mip_cppid);
}

/* loaded = loaded__mu_da__mip_off_hi<8:8> */
static u32 nffw_fwinfo_mip_mu_da_get(const struct nffw_fwinfo *fi)
{
	return (le32_to_cpu(fi->loaded__mu_da__mip_off_hi) >> 8) & 1;
}

/* mip_offset = (loaded__mu_da__mip_off_hi<7:0> << 8) | mip_offset_lo */
static u64 nffw_fwinfo_mip_offset_get(const struct nffw_fwinfo *fi)
{
	u64 mip_off_hi = le32_to_cpu(fi->loaded__mu_da__mip_off_hi);

	return (mip_off_hi & 0xFF) << 32 | le32_to_cpu(fi->mip_offset_lo);
}

static unsigned int
nffw_res_fwinfos(struct nfp_nffw_info_data *fwinf, struct nffw_fwinfo **arr)
{
	/* For the this code, version 0 is most likely to be
	 * version 1 in this case. Since the kernel driver
	 * does not take responsibility for initialising the
	 * nfp.nffw resource, any previous code (CA firmware or
	 * userspace) that left the version 0 and did set
	 * the init flag is going to be version 1.
	 */

Annotation

Implementation Notes