tools/testing/selftests/drivers/net/hw/toeplitz.c

Source file repositories/reference/linux-study-clean/tools/testing/selftests/drivers/net/hw/toeplitz.c

File Facts

System
Linux kernel
Corpus path
tools/testing/selftests/drivers/net/hw/toeplitz.c
Extension
.c
Size
16937 bytes
Lines
674
Domain
Support Tooling And Documentation
Bucket
tools
Inferred role
Support Tooling And Documentation: implementation source
Status
source implementation candidate

Why This File Exists

Repository support layer: documentation, build tooling, samples, user-space helper tools, generated initramfs support, licenses, and validation utilities.

Dependency Surface

Detected Declarations

Annotated Snippet

struct ring_state {
	int fd;
	char *mmap;
	int idx;
	int cpu;
};

static unsigned int rx_irq_cpus[RSS_MAX_CPUS];	/* map from rxq to cpu */
static int rps_silo_to_cpu[RPS_MAX_CPUS];
static unsigned char toeplitz_key[TOEPLITZ_KEY_MAX_LEN];
static unsigned int rss_indir_tbl[RSS_MAX_INDIR];
static unsigned int rss_indir_tbl_size;
static struct ring_state rings[RSS_MAX_CPUS];

static inline uint32_t toeplitz(const unsigned char *four_tuple,
				const unsigned char *key)
{
	int i, bit, ret = 0;
	uint32_t key32;

	key32 = ntohl(*((uint32_t *)key));
	key += 4;

	for (i = 0; i < FOUR_TUPLE_MAX_LEN; i++) {
		for (bit = 7; bit >= 0; bit--) {
			if (four_tuple[i] & (1 << bit))
				ret ^= key32;

			key32 <<= 1;
			key32 |= !!(key[0] & (1 << bit));
		}
		key++;
	}

	return ret;
}

/* Compare computed cpu with arrival cpu from packet_fanout_cpu */
static void verify_rss(uint32_t rx_hash, int cpu)
{
	int queue;

	if (rss_indir_tbl_size)
		queue = rss_indir_tbl[rx_hash % rss_indir_tbl_size];
	else
		queue = rx_hash % cfg_num_queues;

	log_verbose(" rxq %d (cpu %d)", queue, rx_irq_cpus[queue]);
	if (rx_irq_cpus[queue] != cpu) {
		log_verbose(". error: rss cpu mismatch (%d)", cpu);
		frames_error++;
	}
}

static void verify_rps(uint64_t rx_hash, int cpu)
{
	int silo = (rx_hash * cfg_num_rps_cpus) >> 32;

	log_verbose(" silo %d (cpu %d)", silo, rps_silo_to_cpu[silo]);
	if (rps_silo_to_cpu[silo] != cpu) {
		log_verbose(". error: rps cpu mismatch (%d)", cpu);
		frames_error++;
	}
}

static void log_rxhash(int cpu, uint32_t rx_hash,
		       const char *addrs, int addr_len)
{
	char saddr[INET6_ADDRSTRLEN], daddr[INET6_ADDRSTRLEN];
	uint16_t *ports;

	if (!inet_ntop(cfg_family, addrs, saddr, sizeof(saddr)) ||
	    !inet_ntop(cfg_family, addrs + addr_len, daddr, sizeof(daddr)))
		error(1, 0, "address parse error");

	ports = (void *)addrs + (addr_len * 2);
	log_verbose("cpu %d: rx_hash 0x%08x [saddr %s daddr %s sport %02hu dport %02hu]",
		    cpu, rx_hash, saddr, daddr,
		    ntohs(ports[0]), ntohs(ports[1]));
}

/* Compare computed rxhash with rxhash received from tpacket_v3 */
static void verify_rxhash(const char *pkt, uint32_t rx_hash, int cpu)
{
	unsigned char four_tuple[FOUR_TUPLE_MAX_LEN] = {0};
	uint32_t rx_hash_sw;
	const char *addrs;
	int addr_len;

	if (cfg_family == AF_INET) {

Annotation

Implementation Notes