drivers/net/ethernet/meta/fbnic/fbnic_mac.c

Source file repositories/reference/linux-study-clean/drivers/net/ethernet/meta/fbnic/fbnic_mac.c

File Facts

System
Linux kernel
Corpus path
drivers/net/ethernet/meta/fbnic/fbnic_mac.c
Extension
.c
Size
31856 bytes
Lines
1032
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

struct fbnic_fifo_config {
	unsigned int addr;
	unsigned int size;
};

/* Rx FIFO Configuration
 * The table consists of 8 entries, of which only 4 are currently used
 * The starting addr is in units of 64B and the size is in 2KB units
 * Below is the human readable version of the table defined below:
 * Function		Addr	Size
 * ----------------------------------
 * Network to Host/BMC	384K	64K
 * Unused
 * Unused
 * Network to BMC	448K	32K
 * Network to Host	0	384K
 * Unused
 * BMC to Host		480K	32K
 * Unused
 */
static const struct fbnic_fifo_config fifo_config[] = {
	{ .addr = 0x1800, .size = 0x20 },	/* Network to Host/BMC */
	{ },					/* Unused */
	{ },					/* Unused */
	{ .addr = 0x1c00, .size = 0x10 },	/* Network to BMC */
	{ .addr = 0x0000, .size = 0xc0 },	/* Network to Host */
	{ },					/* Unused */
	{ .addr = 0x1e00, .size = 0x10 },	/* BMC to Host */
	{ }					/* Unused */
};

static void fbnic_mac_init_rxb(struct fbnic_dev *fbd)
{
	bool rx_enable;
	int i;

	rx_enable = !!(rd32(fbd, FBNIC_RPC_RMI_CONFIG) &
		       FBNIC_RPC_RMI_CONFIG_ENABLE);

	for (i = 0; i < 8; i++) {
		unsigned int size = fifo_config[i].size;

		/* If we are coming up on a system that already has the
		 * Rx data path enabled we don't need to reconfigure the
		 * FIFOs. Instead we can check to verify the values are
		 * large enough to meet our needs, and use the values to
		 * populate the flow control, ECN, and drop thresholds.
		 */
		if (rx_enable) {
			size = FIELD_GET(FBNIC_RXB_PBUF_SIZE,
					 rd32(fbd, FBNIC_RXB_PBUF_CFG(i)));
			if (size < fifo_config[i].size)
				dev_warn(fbd->dev,
					 "fifo%d size of %d smaller than expected value of %d\n",
					 i, size << 11,
					 fifo_config[i].size << 11);
		} else {
			/* Program RXB Cuthrough */
			wr32(fbd, FBNIC_RXB_CT_SIZE(i),
			     FIELD_PREP(FBNIC_RXB_CT_SIZE_HEADER, 4) |
			     FIELD_PREP(FBNIC_RXB_CT_SIZE_PAYLOAD, 2));

			/* The granularity for the packet buffer size is 2KB
			 * granularity while the packet buffer base address is
			 * only 64B granularity
			 */
			wr32(fbd, FBNIC_RXB_PBUF_CFG(i),
			     FIELD_PREP(FBNIC_RXB_PBUF_BASE_ADDR,
					fifo_config[i].addr) |
			     FIELD_PREP(FBNIC_RXB_PBUF_SIZE, size));

			/* The granularity for the credits is 64B. This is
			 * based on RXB_PBUF_SIZE * 32 + 4.
			 */
			wr32(fbd, FBNIC_RXB_PBUF_CREDIT(i),
			     FIELD_PREP(FBNIC_RXB_PBUF_CREDIT_MASK,
					size ? size * 32 + 4 : 0));
		}

		if (!size)
			continue;

		/* Pause is size of FIFO with 56KB skid to start/stop */
		wr32(fbd, FBNIC_RXB_PAUSE_THLD(i),
		     !(FBNIC_PAUSE_EN_MASK & (1u << i)) ? 0x1fff :
		     FIELD_PREP(FBNIC_RXB_PAUSE_THLD_ON,
				size * 32 - 0x380) |
		     FIELD_PREP(FBNIC_RXB_PAUSE_THLD_OFF, 0x380));

		/* Enable Drop when only one packet is left in the FIFO */

Annotation

Implementation Notes