drivers/net/ethernet/microchip/vcap/vcap_api_kunit.c

Source file repositories/reference/linux-study-clean/drivers/net/ethernet/microchip/vcap/vcap_api_kunit.c

File Facts

System
Linux kernel
Corpus path
drivers/net/ethernet/microchip/vcap/vcap_api_kunit.c
Extension
.c
Size
69026 bytes
Lines
2353
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 (admin->vtype) {
		case VCAP_TYPE_IS0:
			for (idx = 0; idx < kslist->cnt; idx++) {
				if (kslist->keysets[idx] == VCAP_KFS_ETAG)
					return kslist->keysets[idx];
				if (kslist->keysets[idx] == VCAP_KFS_PURE_5TUPLE_IP4)
					return kslist->keysets[idx];
				if (kslist->keysets[idx] == VCAP_KFS_NORMAL_5TUPLE_IP4)
					return kslist->keysets[idx];
				if (kslist->keysets[idx] == VCAP_KFS_NORMAL_7TUPLE)
					return kslist->keysets[idx];
			}
			break;
		case VCAP_TYPE_IS2:
			for (idx = 0; idx < kslist->cnt; idx++) {
				if (kslist->keysets[idx] == VCAP_KFS_MAC_ETYPE)
					return kslist->keysets[idx];
				if (kslist->keysets[idx] == VCAP_KFS_ARP)
					return kslist->keysets[idx];
				if (kslist->keysets[idx] == VCAP_KFS_IP_7TUPLE)
					return kslist->keysets[idx];
			}
			break;
		default:
			pr_info("%s:%d: no validation for VCAP %d\n",
				__func__, __LINE__, admin->vtype);
			break;
		}
	}
	return -EINVAL;
}

/* Callback used by the VCAP API */
static void test_add_def_fields(struct net_device *ndev,
				struct vcap_admin *admin,
				struct vcap_rule *rule)
{
	if (admin->vinst == 0 || admin->vinst == 2)
		vcap_rule_add_key_bit(rule, VCAP_KF_LOOKUP_FIRST_IS, VCAP_BIT_1);
	else
		vcap_rule_add_key_bit(rule, VCAP_KF_LOOKUP_FIRST_IS, VCAP_BIT_0);
}

/* Callback used by the VCAP API */
static void test_cache_erase(struct vcap_admin *admin)
{
	if (test_cache_erase_count) {
		memset(admin->cache.keystream, 0, test_cache_erase_count);
		memset(admin->cache.maskstream, 0, test_cache_erase_count);
		memset(admin->cache.actionstream, 0, test_cache_erase_count);
		test_cache_erase_count = 0;
	}
}

/* Callback used by the VCAP API */
static void test_cache_init(struct net_device *ndev, struct vcap_admin *admin,
			    u32 start, u32 count)
{
	test_init_start = start;
	test_init_count = count;
}

/* Callback used by the VCAP API */
static void test_cache_read(struct net_device *ndev, struct vcap_admin *admin,
			    enum vcap_selection sel, u32 start, u32 count)
{
	u32 *keystr, *mskstr, *actstr;
	int idx;

	pr_debug("%s:%d: %d %d\n", __func__, __LINE__, start, count);
	switch (sel) {
	case VCAP_SEL_ENTRY:
		keystr = &admin->cache.keystream[start];
		mskstr = &admin->cache.maskstream[start];
		for (idx = 0; idx < count; ++idx) {
			pr_debug("%s:%d: keydata[%02d]: 0x%08x\n", __func__,
				 __LINE__, start + idx, keystr[idx]);
		}
		for (idx = 0; idx < count; ++idx) {
			/* Invert the mask before decoding starts */
			mskstr[idx] = ~mskstr[idx];
			pr_debug("%s:%d: mskdata[%02d]: 0x%08x\n", __func__,
				 __LINE__, start + idx, mskstr[idx]);
		}
		break;
	case VCAP_SEL_ACTION:
		actstr = &admin->cache.actionstream[start];
		for (idx = 0; idx < count; ++idx) {
			pr_debug("%s:%d: actdata[%02d]: 0x%08x\n", __func__,
				 __LINE__, start + idx, actstr[idx]);

Annotation

Implementation Notes