drivers/net/ethernet/marvell/octeontx2/nic/rep.c

Source file repositories/reference/linux-study-clean/drivers/net/ethernet/marvell/octeontx2/nic/rep.c

File Facts

System
Linux kernel
Corpus path
drivers/net/ethernet/marvell/octeontx2/nic/rep.c
Extension
.c
Size
21620 bytes
Lines
881
Domain
Driver Families
Bucket
drivers/net
Inferred role
Driver Families: operation-table or driver-model contract
Status
pattern 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

static const struct net_device_ops rvu_rep_netdev_ops = {
	.ndo_open		= rvu_rep_open,
	.ndo_stop		= rvu_rep_stop,
	.ndo_start_xmit		= rvu_rep_xmit,
	.ndo_get_stats64	= rvu_rep_get_stats64,
	.ndo_change_mtu		= rvu_rep_change_mtu,
	.ndo_has_offload_stats	= rvu_rep_has_offload_stats,
	.ndo_get_offload_stats	= rvu_rep_get_offload_stats,
	.ndo_setup_tc		= rvu_rep_setup_tc,
};

static int rvu_rep_napi_init(struct otx2_nic *priv,
			     struct netlink_ext_ack *extack)
{
	struct otx2_qset *qset = &priv->qset;
	struct otx2_cq_poll *cq_poll = NULL;
	struct otx2_hw *hw = &priv->hw;
	int err = 0, qidx, vec;
	char *irq_name;

	qset->napi = kzalloc_objs(*cq_poll, hw->cint_cnt);
	if (!qset->napi)
		return -ENOMEM;

	/* Register NAPI handler */
	for (qidx = 0; qidx < hw->cint_cnt; qidx++) {
		cq_poll = &qset->napi[qidx];
		cq_poll->cint_idx = qidx;
		cq_poll->cq_ids[CQ_RX] =
			(qidx <  hw->rx_queues) ? qidx : CINT_INVALID_CQ;
		cq_poll->cq_ids[CQ_TX] = (qidx < hw->tx_queues) ?
					  qidx + hw->rx_queues :
					  CINT_INVALID_CQ;
		cq_poll->cq_ids[CQ_XDP] = CINT_INVALID_CQ;
		cq_poll->cq_ids[CQ_QOS] = CINT_INVALID_CQ;

		cq_poll->dev = (void *)priv;
		netif_napi_add(priv->reps[qidx]->netdev, &cq_poll->napi,
			       otx2_napi_handler);
		napi_enable(&cq_poll->napi);
	}
	/* Register CQ IRQ handlers */
	vec = hw->nix_msixoff + NIX_LF_CINT_VEC_START;
	for (qidx = 0; qidx < hw->cint_cnt; qidx++) {
		irq_name = &hw->irq_name[vec * NAME_SIZE];

		snprintf(irq_name, NAME_SIZE, "rep%d-rxtx-%d", qidx, qidx);

		err = request_irq(pci_irq_vector(priv->pdev, vec),
				  otx2_cq_intr_handler, 0, irq_name,
				  &qset->napi[qidx]);
		if (err) {
			NL_SET_ERR_MSG_FMT_MOD(extack,
					       "RVU REP IRQ registration failed for CQ%d",
					       qidx);
			goto err_free_cints;
		}
		vec++;

		/* Enable CQ IRQ */
		otx2_write64(priv, NIX_LF_CINTX_INT(qidx), BIT_ULL(0));
		otx2_write64(priv, NIX_LF_CINTX_ENA_W1S(qidx), BIT_ULL(0));
	}
	priv->flags &= ~OTX2_FLAG_INTF_DOWN;
	return 0;

err_free_cints:
	otx2_free_cints(priv, qidx);
	otx2_disable_napi(priv);
	return err;
}

static void rvu_rep_free_cq_rsrc(struct otx2_nic *priv)
{
	struct otx2_qset *qset = &priv->qset;
	struct otx2_cq_poll *cq_poll = NULL;
	int qidx, vec;

	/* Cleanup CQ NAPI and IRQ */
	vec = priv->hw.nix_msixoff + NIX_LF_CINT_VEC_START;
	for (qidx = 0; qidx < priv->hw.cint_cnt; qidx++) {
		/* Disable interrupt */
		otx2_write64(priv, NIX_LF_CINTX_ENA_W1C(qidx), BIT_ULL(0));

		synchronize_irq(pci_irq_vector(priv->pdev, vec));

		cq_poll = &qset->napi[qidx];
		napi_synchronize(&cq_poll->napi);
		vec++;
	}

Annotation

Implementation Notes