drivers/net/dsa/realtek/rtl8365mb_table.c

Source file repositories/reference/linux-study-clean/drivers/net/dsa/realtek/rtl8365mb_table.c

File Facts

System
Linux kernel
Corpus path
drivers/net/dsa/realtek/rtl8365mb_table.c
Extension
.c
Size
6270 bytes
Lines
215
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

switch (method) {
		case RTL8365MB_TABLE_L2_METHOD_MAC:
			/*
			 * Method MAC requires as input the same L2 table format
			 * you'll get as result. However, it might only use mac
			 * address and FID/VID fields.
			 */
			write_data = true;

			/* METHOD_MAC does not use addr as input, but may return
			 * the matched index.
			 */
			addr_as_input = false;

			break;
		case RTL8365MB_TABLE_L2_METHOD_ADDR:
		case RTL8365MB_TABLE_L2_METHOD_ADDR_NEXT:
		case RTL8365MB_TABLE_L2_METHOD_ADDR_NEXT_UC:
		case RTL8365MB_TABLE_L2_METHOD_ADDR_NEXT_MC:
			break;
		case RTL8365MB_TABLE_L2_METHOD_ADDR_NEXT_UC_PORT:
			cmd |= FIELD_PREP(RTL8365MB_TABLE_CTRL_PORT_MASK, port);
			break;
		default:
			return -EINVAL;
		}
	} else if (op == RTL8365MB_TABLE_OP_WRITE) {
		write_data = true;

		/* Writing to L2 does not use addr as input, as the table index
		 * is derived from key fields.
		 */
		if (table == RTL8365MB_TABLE_L2)
			addr_as_input = false;
	}

	/* To prevent concurrent access to the look-up tables, take the regmap
	 * lock manually and access via the map_nolock regmap.
	 */
	mutex_lock(&priv->map_lock);

	/* Protect from a busy table access (i.e. previous access timeouts) */
	ret = rtl8365mb_table_poll_busy(priv);
	if (ret)
		goto out;

	/* Write entry data if writing to the table (or L2_METHOD_MAC) */
	if (write_data) {
		/* bulk write data up to 9th word */
		ret = regmap_bulk_write(priv->map_nolock,
					RTL8365MB_TABLE_WRITE_BASE,
					data,
					min_t(size_t, size,
					      RTL8365MB_TABLE_ENTRY_MAX_SIZE -
						      1));
		if (ret)
			goto out;

		/* 10th register uses only 4 least significant bits */
		if (size == RTL8365MB_TABLE_ENTRY_MAX_SIZE) {
			val = FIELD_PREP(RTL8365MB_TABLE_10TH_DATA_MASK,
					 data[size - 1]);
			ret = regmap_update_bits(priv->map_nolock,
						 RTL8365MB_TABLE_WRITE_10TH_REG,
						 RTL8365MB_TABLE_10TH_DATA_MASK,
						 val);
		}

		if (ret)
			goto out;
	}

	/* Write address (if needed) */
	if (addr_as_input) {
		ret = regmap_write(priv->map_nolock,
				   RTL8365MB_TABLE_ACCESS_ADDR_REG,
				   FIELD_PREP(RTL8365MB_TABLE_ADDR_MASK,
					      *addr));
		if (ret)
			goto out;
	}

	/* Execute */
	ret = regmap_write(priv->map_nolock, RTL8365MB_TABLE_CTRL_REG, cmd);
	if (ret)
		goto out;

	/* Poll for completion */
	ret = rtl8365mb_table_poll_busy(priv);
	if (ret)

Annotation

Implementation Notes