drivers/net/ethernet/microchip/lan966x/lan966x_vcap_impl.c

Source file repositories/reference/linux-study-clean/drivers/net/ethernet/microchip/lan966x/lan966x_vcap_impl.c

File Facts

System
Linux kernel
Corpus path
drivers/net/ethernet/microchip/lan966x/lan966x_vcap_impl.c
Extension
.c
Size
21876 bytes
Lines
785
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 lan966x_vcap_cmd_cb {
	struct lan966x *lan966x;
	u32 instance;
};

static u32 lan966x_vcap_read_update_ctrl(const struct lan966x_vcap_cmd_cb *cb)
{
	return lan_rd(cb->lan966x, VCAP_UPDATE_CTRL(cb->instance));
}

static void lan966x_vcap_wait_update(struct lan966x *lan966x, int instance)
{
	const struct lan966x_vcap_cmd_cb cb = { .lan966x = lan966x,
						.instance = instance };
	u32 val;

	readx_poll_timeout(lan966x_vcap_read_update_ctrl, &cb, val,
			   (val & VCAP_UPDATE_CTRL_UPDATE_SHOT) == 0, 10,
			   100000);
}

static void __lan966x_vcap_range_init(struct lan966x *lan966x,
				      struct vcap_admin *admin,
				      u32 addr,
				      u32 count)
{
	lan_wr(VCAP_MV_CFG_MV_NUM_POS_SET(0) |
	       VCAP_MV_CFG_MV_SIZE_SET(count - 1),
	       lan966x, VCAP_MV_CFG(admin->tgt_inst));

	lan_wr(VCAP_UPDATE_CTRL_UPDATE_CMD_SET(VCAP_CMD_INITIALIZE) |
	       VCAP_UPDATE_CTRL_UPDATE_ENTRY_DIS_SET(0) |
	       VCAP_UPDATE_CTRL_UPDATE_ACTION_DIS_SET(0) |
	       VCAP_UPDATE_CTRL_UPDATE_CNT_DIS_SET(0) |
	       VCAP_UPDATE_CTRL_UPDATE_ADDR_SET(addr) |
	       VCAP_UPDATE_CTRL_CLEAR_CACHE_SET(true) |
	       VCAP_UPDATE_CTRL_UPDATE_SHOT_SET(1),
	       lan966x, VCAP_UPDATE_CTRL(admin->tgt_inst));

	lan966x_vcap_wait_update(lan966x, admin->tgt_inst);
}

static int lan966x_vcap_is1_cid_to_lookup(int cid)
{
	int lookup = 0;

	if (cid >= LAN966X_VCAP_CID_IS1_L1 &&
	    cid < LAN966X_VCAP_CID_IS1_L2)
		lookup = 1;
	else if (cid >= LAN966X_VCAP_CID_IS1_L2 &&
		 cid < LAN966X_VCAP_CID_IS1_MAX)
		lookup = 2;

	return lookup;
}

static int lan966x_vcap_is2_cid_to_lookup(int cid)
{
	if (cid >= LAN966X_VCAP_CID_IS2_L1 &&
	    cid < LAN966X_VCAP_CID_IS2_MAX)
		return 1;

	return 0;
}

/* Return the list of keysets for the vcap port configuration */
static int
lan966x_vcap_is1_get_port_keysets(struct net_device *ndev, int lookup,
				  struct vcap_keyset_list *keysetlist,
				  u16 l3_proto)
{
	struct lan966x_port *port = netdev_priv(ndev);
	struct lan966x *lan966x = port->lan966x;
	u32 val;

	val = lan_rd(lan966x, ANA_VCAP_S1_CFG(port->chip_port, lookup));

	/* Collect all keysets for the port in a list */
	if (l3_proto == ETH_P_ALL || l3_proto == ETH_P_IP) {
		switch (ANA_VCAP_S1_CFG_KEY_IP4_CFG_GET(val)) {
		case VCAP_IS1_PS_IPV4_7TUPLE:
			vcap_keyset_list_add(keysetlist, VCAP_KFS_7TUPLE);
			break;
		case VCAP_IS1_PS_IPV4_5TUPLE_IP4:
			vcap_keyset_list_add(keysetlist, VCAP_KFS_5TUPLE_IP4);
			break;
		case VCAP_IS1_PS_IPV4_NORMAL:
			vcap_keyset_list_add(keysetlist, VCAP_KFS_NORMAL);
			break;
		}

Annotation

Implementation Notes