drivers/net/ethernet/broadcom/bnge/bnge_auxr.c

Source file repositories/reference/linux-study-clean/drivers/net/ethernet/broadcom/bnge/bnge_auxr.c

File Facts

System
Linux kernel
Corpus path
drivers/net/ethernet/broadcom/bnge/bnge_auxr.c
Extension
.c
Size
5978 bytes
Lines
260
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

// SPDX-License-Identifier: GPL-2.0
// Copyright (c) 2025 Broadcom.

#include <linux/module.h>

#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/interrupt.h>
#include <linux/pci.h>
#include <linux/netdevice.h>
#include <linux/rtnetlink.h>
#include <linux/bitops.h>
#include <linux/irq.h>
#include <asm/byteorder.h>
#include <linux/bitmap.h>
#include <linux/auxiliary_bus.h>
#include <linux/bnge/hsi.h>

#include "bnge.h"
#include "bnge_hwrm.h"
#include "bnge_auxr.h"

static DEFINE_IDA(bnge_aux_dev_ids);

static void bnge_fill_msix_vecs(struct bnge_dev *bd,
				struct bnge_msix_info *info)
{
	struct bnge_auxr_dev *auxr_dev = bd->auxr_dev;
	int num_msix, i;

	if (!auxr_dev->auxr_info->msix_requested) {
		dev_warn(bd->dev, "Requested MSI-X vectors not allocated\n");
		return;
	}
	num_msix = auxr_dev->auxr_info->msix_requested;
	for (i = 0; i < num_msix; i++) {
		info[i].vector = bd->irq_tbl[i].vector;
		info[i].db_offset = bd->db_offset;
		info[i].ring_idx = i;
	}
}

int bnge_register_dev(struct bnge_auxr_dev *auxr_dev,
		      void *handle)
{
	struct bnge_dev *bd = pci_get_drvdata(auxr_dev->pdev);
	struct bnge_auxr_info *auxr_info;
	int rc = 0;

	netdev_lock(bd->netdev);
	mutex_lock(&auxr_dev->auxr_dev_lock);
	if (!bd->irq_tbl) {
		rc = -ENODEV;
		goto exit;
	}

	if (!bnge_aux_has_enough_resources(bd)) {
		rc = -ENOMEM;
		goto exit;
	}

	auxr_info = auxr_dev->auxr_info;
	auxr_info->handle = handle;

	auxr_info->msix_requested = bd->aux_num_msix;

	bnge_fill_msix_vecs(bd, bd->auxr_dev->msix_info);
	auxr_dev->flags |= BNGE_ARDEV_MSIX_ALLOC;

exit:
	mutex_unlock(&auxr_dev->auxr_dev_lock);
	netdev_unlock(bd->netdev);
	return rc;
}
EXPORT_SYMBOL(bnge_register_dev);

void bnge_unregister_dev(struct bnge_auxr_dev *auxr_dev)
{
	struct bnge_dev *bd = pci_get_drvdata(auxr_dev->pdev);
	struct bnge_auxr_info *auxr_info;

	auxr_info = auxr_dev->auxr_info;
	netdev_lock(bd->netdev);
	mutex_lock(&auxr_dev->auxr_dev_lock);
	if (auxr_info->msix_requested)
		auxr_dev->flags &= ~BNGE_ARDEV_MSIX_ALLOC;
	auxr_info->msix_requested = 0;

	mutex_unlock(&auxr_dev->auxr_dev_lock);
	netdev_unlock(bd->netdev);

Annotation

Implementation Notes