drivers/net/ethernet/cavium/liquidio/request_manager.c

Source file repositories/reference/linux-study-clean/drivers/net/ethernet/cavium/liquidio/request_manager.c

File Facts

System
Linux kernel
Corpus path
drivers/net/ethernet/cavium/liquidio/request_manager.c
Extension
.c
Size
24456 bytes
Lines
942
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

struct iq_post_status {
	int status;
	int index;
};

static void check_db_timeout(struct work_struct *work);
static void  __check_db_timeout(struct octeon_device *oct, u64 iq_no);

static void (*reqtype_free_fn[MAX_OCTEON_DEVICES][REQTYPE_LAST + 1]) (void *);

/* Define this to return the request status comaptible to old code */
/*#define OCTEON_USE_OLD_REQ_STATUS*/

/* Return 0 on success, 1 on failure */
int octeon_init_instr_queue(struct octeon_device *oct,
			    union oct_txpciq txpciq,
			    u32 num_descs)
{
	struct octeon_instr_queue *iq;
	struct octeon_iq_config *conf = NULL;
	u32 iq_no = (u32)txpciq.s.q_no;
	u32 q_size;
	struct cavium_wq *db_wq;
	int numa_node = dev_to_node(&oct->pci_dev->dev);

	if (OCTEON_CN6XXX(oct))
		conf = &(CFG_GET_IQ_CFG(CHIP_CONF(oct, cn6xxx)));
	else if (OCTEON_CN23XX_PF(oct))
		conf = &(CFG_GET_IQ_CFG(CHIP_CONF(oct, cn23xx_pf)));
	else if (OCTEON_CN23XX_VF(oct))
		conf = &(CFG_GET_IQ_CFG(CHIP_CONF(oct, cn23xx_vf)));

	if (!conf) {
		dev_err(&oct->pci_dev->dev, "Unsupported Chip %x\n",
			oct->chip_id);
		return 1;
	}

	q_size = (u32)conf->instr_type * num_descs;

	iq = oct->instr_queue[iq_no];

	iq->oct_dev = oct;

	iq->base_addr = lio_dma_alloc(oct, q_size, &iq->base_addr_dma);
	if (!iq->base_addr) {
		dev_err(&oct->pci_dev->dev, "Cannot allocate memory for instr queue %d\n",
			iq_no);
		return 1;
	}

	iq->max_count = num_descs;

	/* Initialize a list to holds requests that have been posted to Octeon
	 * but has yet to be fetched by octeon
	 */
	iq->request_list = vzalloc_node(array_size(num_descs, sizeof(*iq->request_list)),
					numa_node);
	if (!iq->request_list)
		iq->request_list = vzalloc(array_size(num_descs, sizeof(*iq->request_list)));
	if (!iq->request_list) {
		lio_dma_free(oct, q_size, iq->base_addr, iq->base_addr_dma);
		dev_err(&oct->pci_dev->dev, "Alloc failed for IQ[%d] nr free list\n",
			iq_no);
		return 1;
	}

	dev_dbg(&oct->pci_dev->dev, "IQ[%d]: base: %p basedma: %pad count: %d\n",
		iq_no, iq->base_addr, &iq->base_addr_dma, iq->max_count);

	iq->txpciq.u64 = txpciq.u64;
	iq->fill_threshold = (u32)conf->db_min;
	iq->fill_cnt = 0;
	iq->host_write_index = 0;
	iq->octeon_read_index = 0;
	iq->flush_index = 0;
	iq->last_db_time = 0;
	iq->do_auto_flush = 1;
	iq->db_timeout = (u32)conf->db_timeout;
	atomic_set(&iq->instr_pending, 0);
	iq->pkts_processed = 0;

	/* Initialize the spinlock for this instruction queue */
	spin_lock_init(&iq->lock);
	if (iq_no == 0) {
		iq->allow_soft_cmds = true;
		spin_lock_init(&iq->post_lock);
	} else {
		iq->allow_soft_cmds = false;
	}

Annotation

Implementation Notes