drivers/net/ethernet/wangxun/libwx/wx_vf_lib.c

Source file repositories/reference/linux-study-clean/drivers/net/ethernet/wangxun/libwx/wx_vf_lib.c

File Facts

System
Linux kernel
Corpus path
drivers/net/ethernet/wangxun/libwx/wx_vf_lib.c
Extension
.c
Size
7622 bytes
Lines
293
Domain
Driver Families
Bucket
drivers/net
Inferred role
Driver Families: implementation source
Status
source 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 ((i & 3) == 3) {
			wr32(wx, WX_VXRETA(i >> 2), vfreta);
			vfreta = 0;
		}
	}

	/* Perform hash on these packet types */
	vfmrqc |= WX_VXMRQC_RSS_ALG_IPV4 |
		  WX_VXMRQC_RSS_ALG_IPV4_TCP |
		  WX_VXMRQC_RSS_ALG_IPV6 |
		  WX_VXMRQC_RSS_ALG_IPV6_TCP;

	vfmrqc |= WX_VXMRQC_RSS_EN;

	if (wx->num_rx_queues > 3)
		vfmrqc |= WX_VXMRQC_RSS_HASH(2);
	else if (wx->num_rx_queues > 1)
		vfmrqc |= WX_VXMRQC_RSS_HASH(1);
	wr32m(wx, WX_VXMRQC, WX_VXMRQC_RSS_MASK, WX_VXMRQC_RSS(vfmrqc));
}

void wx_configure_rx_ring_vf(struct wx *wx, struct wx_ring *ring)
{
	u8 reg_idx = ring->reg_idx;
	union wx_rx_desc *rx_desc;
	u64 rdba = ring->dma;
	u32 rxdctl;

	/* disable queue to avoid issues while updating state */
	rxdctl = rd32(wx, WX_VXRXDCTL(reg_idx));
	wx_disable_rx_queue(wx, ring);

	wr32(wx, WX_VXRDBAL(reg_idx), rdba & DMA_BIT_MASK(32));
	wr32(wx, WX_VXRDBAH(reg_idx), rdba >> 32);

	/* enable relaxed ordering */
	pcie_capability_clear_and_set_word(wx->pdev, PCI_EXP_DEVCTL,
					   0, PCI_EXP_DEVCTL_RELAX_EN);

	/* reset head and tail pointers */
	wr32(wx, WX_VXRDH(reg_idx), 0);
	wr32(wx, WX_VXRDT(reg_idx), 0);
	ring->tail = wx->hw_addr + WX_VXRDT(reg_idx);

	/* initialize rx_buffer_info */
	memset(ring->rx_buffer_info, 0,
	       sizeof(struct wx_rx_buffer) * ring->count);

	/* initialize Rx descriptor 0 */
	rx_desc = WX_RX_DESC(ring, 0);
	rx_desc->wb.upper.length = 0;

	/* reset ntu and ntc to place SW in sync with hardwdare */
	ring->next_to_clean = 0;
	ring->next_to_use = 0;
	ring->next_to_alloc = 0;

	wx_configure_srrctl_vf(wx, ring, reg_idx);

	/* allow any size packet since we can handle overflow */
	rxdctl &= ~WX_VXRXDCTL_BUFLEN_MASK;
	rxdctl |= WX_VXRXDCTL_BUFLEN(wx_buf_len(ring->count));
	rxdctl |= WX_VXRXDCTL_ENABLE | WX_VXRXDCTL_VLAN;

	/* enable RSC */
	rxdctl &= ~WX_VXRXDCTL_RSCMAX_MASK;
	rxdctl |= WX_VXRXDCTL_RSCMAX(0);
	rxdctl |= WX_VXRXDCTL_RSCEN;

	if (test_bit(WX_FLAG_RX_MERGE_ENABLED, wx->flags))
		rxdctl |= WX_VXRXDCTL_DESC_MERGE;

	wr32(wx, WX_VXRXDCTL(reg_idx), rxdctl);

	/* pf/vf reuse */
	wx_enable_rx_queue(wx, ring);
	wx_alloc_rx_buffers(ring, wx_desc_unused(ring));
}

Annotation

Implementation Notes