drivers/net/ethernet/netronome/nfp/ccm.c

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

File Facts

System
Linux kernel
Corpus path
drivers/net/ethernet/netronome/nfp/ccm.c
Extension
.c
Size
4932 bytes
Lines
218
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 (msg_tag == tag) {
			nfp_ccm_free_tag(ccm, tag);
			__skb_unlink(skb, &ccm->replies);
			return skb;
		}
	}

	return NULL;
}

static struct sk_buff *
nfp_ccm_reply(struct nfp_ccm *ccm, struct nfp_app *app, u16 tag)
{
	struct sk_buff *skb;

	nfp_ctrl_lock(app->ctrl);
	skb = __nfp_ccm_reply(ccm, tag);
	nfp_ctrl_unlock(app->ctrl);

	return skb;
}

static struct sk_buff *
nfp_ccm_reply_drop_tag(struct nfp_ccm *ccm, struct nfp_app *app, u16 tag)
{
	struct sk_buff *skb;

	nfp_ctrl_lock(app->ctrl);
	skb = __nfp_ccm_reply(ccm, tag);
	if (!skb)
		nfp_ccm_free_tag(ccm, tag);
	nfp_ctrl_unlock(app->ctrl);

	return skb;
}

static struct sk_buff *
nfp_ccm_wait_reply(struct nfp_ccm *ccm, struct nfp_app *app,
		   enum nfp_ccm_type type, int tag)
{
	struct sk_buff *skb;
	int i, err;

	for (i = 0; i < 50; i++) {
		udelay(4);
		skb = nfp_ccm_reply(ccm, app, tag);
		if (skb)
			return skb;
	}

	err = wait_event_interruptible_timeout(ccm->wq,
					       skb = nfp_ccm_reply(ccm, app,
								   tag),
					       msecs_to_jiffies(5000));
	/* We didn't get a response - try last time and atomically drop
	 * the tag even if no response is matched.
	 */
	if (!skb)
		skb = nfp_ccm_reply_drop_tag(ccm, app, tag);
	if (err < 0) {
		ccm_warn(app, "%s waiting for response to 0x%02x: %d\n",
			 err == ERESTARTSYS ? "interrupted" : "error",
			 type, err);
		return ERR_PTR(err);
	}
	if (!skb) {
		ccm_warn(app, "timeout waiting for response to 0x%02x\n", type);
		return ERR_PTR(-ETIMEDOUT);
	}

	return skb;
}

struct sk_buff *
nfp_ccm_communicate(struct nfp_ccm *ccm, struct sk_buff *skb,
		    enum nfp_ccm_type type, unsigned int reply_size)
{
	struct nfp_app *app = ccm->app;
	struct nfp_ccm_hdr *hdr;
	int reply_type, tag;

	nfp_ctrl_lock(app->ctrl);
	tag = nfp_ccm_alloc_tag(ccm);
	if (tag < 0) {
		nfp_ctrl_unlock(app->ctrl);
		dev_kfree_skb_any(skb);
		return ERR_PTR(tag);
	}

	hdr = (void *)skb->data;

Annotation

Implementation Notes