drivers/net/ethernet/chelsio/cxgb4/smt.c

Source file repositories/reference/linux-study-clean/drivers/net/ethernet/chelsio/cxgb4/smt.c

File Facts

System
Linux kernel
Corpus path
drivers/net/ethernet/chelsio/cxgb4/smt.c
Extension
.c
Size
6499 bytes
Lines
249
Domain
Driver Families
Bucket
drivers/net
Inferred role
Driver Families: exported/initcall integration point
Status
integration 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 (e->refcnt == 0) {
			if (!first_free)
				first_free = e;
		} else {
			if (e->state == SMT_STATE_SWITCHING) {
				/* This entry is actually in use. See if we can
				 * re-use it ?
				 */
				if (memcmp(e->src_mac, smac, ETH_ALEN) == 0)
					goto found_reuse;
			}
		}
	}

	if (first_free) {
		e = first_free;
		goto found;
	}
	return NULL;

found:
	e->state = SMT_STATE_UNUSED;

found_reuse:
	return e;
}

static void t4_smte_free(struct smt_entry *e)
{
	if (e->refcnt == 0) {  /* hasn't been recycled */
		e->state = SMT_STATE_UNUSED;
	}
}

/**
 * cxgb4_smt_release - Release SMT entry
 * @e: smt entry to release
 *
 * Releases ref count and frees up an smt entry from SMT table
 */
void cxgb4_smt_release(struct smt_entry *e)
{
	spin_lock_bh(&e->lock);
	if ((--e->refcnt) == 0)
		t4_smte_free(e);
	spin_unlock_bh(&e->lock);
}
EXPORT_SYMBOL(cxgb4_smt_release);

void do_smt_write_rpl(struct adapter *adap, const struct cpl_smt_write_rpl *rpl)
{
	unsigned int smtidx = TID_TID_G(GET_TID(rpl));
	struct smt_data *s = adap->smt;

	if (unlikely(rpl->status != CPL_ERR_NONE)) {
		struct smt_entry *e = &s->smtab[smtidx];

		dev_err(adap->pdev_dev,
			"Unexpected SMT_WRITE_RPL status %u for entry %u\n",
			rpl->status, smtidx);
		spin_lock(&e->lock);
		e->state = SMT_STATE_ERROR;
		spin_unlock(&e->lock);
		return;
	}
}

static int write_smt_entry(struct adapter *adapter, struct smt_entry *e)
{
	struct cpl_t6_smt_write_req *t6req;
	struct smt_data *s = adapter->smt;
	struct cpl_smt_write_req *req;
	struct sk_buff *skb;
	int size;
	u8 row;

	if (CHELSIO_CHIP_VERSION(adapter->params.chip) <= CHELSIO_T5) {
		size = sizeof(*req);
		skb = alloc_skb(size, GFP_ATOMIC);
		if (!skb)
			return -ENOMEM;
		/* Source MAC Table (SMT) contains 256 SMAC entries
		 * organized in 128 rows of 2 entries each.
		 */
		req = (struct cpl_smt_write_req *)__skb_put(skb, size);
		INIT_TP_WR(req, 0);

		/* Each row contains an SMAC pair.
		 * LSB selects the SMAC entry within a row
		 */

Annotation

Implementation Notes