drivers/net/ethernet/pensando/ionic/ionic_dev.c

Source file repositories/reference/linux-study-clean/drivers/net/ethernet/pensando/ionic/ionic_dev.c

File Facts

System
Linux kernel
Corpus path
drivers/net/ethernet/pensando/ionic/ionic_dev.c
Extension
.c
Size
28369 bytes
Lines
1089
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 (!work) {
			netdev_err(lif->netdev, "rxmode change dropped\n");
			return;
		}

		work->type = IONIC_DW_TYPE_RX_MODE;
		netdev_dbg(lif->netdev, "deferred: rx_mode\n");
		ionic_lif_deferred_enqueue(lif, work);
	}
}

static void ionic_napi_schedule_do_softirq(struct napi_struct *napi)
{
	local_bh_disable();
	napi_schedule(napi);
	local_bh_enable();
}

void ionic_doorbell_napi_work(struct work_struct *work)
{
	struct ionic_qcq *qcq = container_of(work, struct ionic_qcq,
					     doorbell_napi_work);
	unsigned long now, then, dif;

	now = READ_ONCE(jiffies);
	then = qcq->q.dbell_jiffies;
	dif = now - then;

	if (dif > qcq->q.dbell_deadline)
		ionic_napi_schedule_do_softirq(&qcq->napi);
}

static int ionic_get_preferred_cpu(struct ionic *ionic,
				   struct ionic_intr_info *intr)
{
	int cpu;

	cpu = cpumask_first_and(*intr->affinity_mask, cpu_online_mask);
	if (cpu >= nr_cpu_ids)
		cpu = cpumask_local_spread(0, dev_to_node(ionic->dev));

	return cpu;
}

static void ionic_queue_dbell_napi_work(struct ionic *ionic,
					struct ionic_qcq *qcq)
{
	int cpu;

	if (!(qcq->flags & IONIC_QCQ_F_INTR))
		return;

	cpu = ionic_get_preferred_cpu(ionic, &qcq->intr);
	queue_work_on(cpu, ionic->wq, &qcq->doorbell_napi_work);
}

static void ionic_doorbell_check_dwork(struct work_struct *work)
{
	struct ionic *ionic = container_of(work, struct ionic,
					   doorbell_check_dwork.work);
	struct ionic_lif *lif = ionic->lif;

	mutex_lock(&lif->queue_lock);

	if (test_bit(IONIC_LIF_F_FW_STOPPING, lif->state) ||
	    test_bit(IONIC_LIF_F_FW_RESET, lif->state)) {
		mutex_unlock(&lif->queue_lock);
		return;
	}

	ionic_napi_schedule_do_softirq(&lif->adminqcq->napi);

	if (test_bit(IONIC_LIF_F_UP, lif->state)) {
		int i;

		for (i = 0; i < lif->nxqs; i++) {
			ionic_queue_dbell_napi_work(ionic, lif->txqcqs[i]);
			ionic_queue_dbell_napi_work(ionic, lif->rxqcqs[i]);
		}

		if (lif->hwstamp_txq &&
		    lif->hwstamp_txq->flags & IONIC_QCQ_F_INTR)
			ionic_napi_schedule_do_softirq(&lif->hwstamp_txq->napi);
		if (lif->hwstamp_rxq &&
		    lif->hwstamp_rxq->flags & IONIC_QCQ_F_INTR)
			ionic_napi_schedule_do_softirq(&lif->hwstamp_rxq->napi);
	}
	mutex_unlock(&lif->queue_lock);

	ionic_queue_doorbell_check(ionic, IONIC_NAPI_DEADLINE);

Annotation

Implementation Notes