drivers/net/ethernet/sfc/mae.c

Source file repositories/reference/linux-study-clean/drivers/net/ethernet/sfc/mae.c

File Facts

System
Linux kernel
Corpus path
drivers/net/ethernet/sfc/mae.c
Extension
.c
Size
79042 bytes
Lines
2337
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 (outlen < MC_CMD_TABLE_DESCRIPTOR_OUT_LEN(i + 1)) {
			offset += i;
			goto more;
		}
		if (i + offset < desc->n_keys)
			field = desc->keys + i + offset;
		else
			field = desc->resps + (i + offset - desc->n_keys);
		fdesc = MCDI_ARRAY_STRUCT_PTR(outbuf,
					      TABLE_DESCRIPTOR_OUT_FIELDS, i);
		field->field_id = MCDI_STRUCT_WORD(fdesc,
						   TABLE_FIELD_DESCR_FIELD_ID);
		field->lbn = MCDI_STRUCT_WORD(fdesc, TABLE_FIELD_DESCR_LBN);
		field->width = MCDI_STRUCT_WORD(fdesc, TABLE_FIELD_DESCR_WIDTH);
		field->masking = MCDI_STRUCT_BYTE(fdesc, TABLE_FIELD_DESCR_MASK_TYPE);
		field->scheme = MCDI_STRUCT_BYTE(fdesc, TABLE_FIELD_DESCR_SCHEME);
	}
	return 0;

fail:
	kfree(desc->keys);
	kfree(desc->resps);
	return rc;
}

static int efx_mae_table_hook_find(u16 n_fields,
				   struct efx_tc_table_field_fmt *fields,
				   u16 field_id)
{
	unsigned int i;

	for (i = 0; i < n_fields; i++) {
		if (fields[i].field_id == field_id)
			return i;
	}
	return -EPROTO;
}

#define TABLE_FIND_KEY(_desc, _id)	\
	efx_mae_table_hook_find((_desc)->n_keys, (_desc)->keys, _id)
#define TABLE_FIND_RESP(_desc, _id)	\
	efx_mae_table_hook_find((_desc)->n_resps, (_desc)->resps, _id)

#define TABLE_HOOK_KEY(_meta, _name, _mcdi_name)	({			\
	int _rc = TABLE_FIND_KEY(&_meta->desc, TABLE_FIELD_ID_##_mcdi_name);	\
										\
	if (_rc > U8_MAX)							\
		_rc = -EOPNOTSUPP;						\
	if (_rc >= 0) {								\
		_meta->keys._name##_idx = _rc;					\
		_rc = 0;							\
	}									\
	_rc;									\
})
#define TABLE_HOOK_RESP(_meta, _name, _mcdi_name)	({			\
	int _rc = TABLE_FIND_RESP(&_meta->desc, TABLE_FIELD_ID_##_mcdi_name);	\
										\
	if (_rc > U8_MAX)							\
		_rc = -EOPNOTSUPP;						\
	if (_rc >= 0) {								\
		_meta->resps._name##_idx = _rc;					\
		_rc = 0;							\
	}									\
	_rc;									\
})

static int efx_mae_table_hook_ct(struct efx_nic *efx,
				 struct efx_tc_table_ct *meta_ct)
{
	int rc;

	rc = TABLE_HOOK_KEY(meta_ct, eth_proto, ETHER_TYPE);
	if (rc)
		return rc;
	rc = TABLE_HOOK_KEY(meta_ct, ip_proto, IP_PROTO);
	if (rc)
		return rc;
	rc = TABLE_HOOK_KEY(meta_ct, src_ip, SRC_IP);
	if (rc)
		return rc;
	rc = TABLE_HOOK_KEY(meta_ct, dst_ip, DST_IP);
	if (rc)
		return rc;
	rc = TABLE_HOOK_KEY(meta_ct, l4_sport, SRC_PORT);
	if (rc)
		return rc;
	rc = TABLE_HOOK_KEY(meta_ct, l4_dport, DST_PORT);
	if (rc)
		return rc;
	rc = TABLE_HOOK_KEY(meta_ct, zone, DOMAIN);

Annotation

Implementation Notes