| 1 | /*- |
| 2 | * Copyright (c) 2010-2011 Juniper Networks, Inc. |
| 3 | * All rights reserved. |
| 4 | * |
| 5 | * This software was developed by Robert N. M. Watson under contract |
| 6 | * to Juniper Networks, Inc. |
| 7 | * |
| 8 | * Redistribution and use in source and binary forms, with or without |
| 9 | * modification, are permitted provided that the following conditions |
| 10 | * are met: |
| 11 | * 1. Redistributions of source code must retain the above copyright |
| 12 | * notice, this list of conditions and the following disclaimer. |
| 13 | * 2. Redistributions in binary form must reproduce the above copyright |
| 14 | * notice, this list of conditions and the following disclaimer in the |
| 15 | * documentation and/or other materials provided with the distribution. |
| 16 | * |
| 17 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND |
| 18 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
| 19 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
| 20 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE |
| 21 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
| 22 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
| 23 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
| 24 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
| 25 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
| 26 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
| 27 | * SUCH DAMAGE. |
| 28 | */ |
| 29 | |
| 30 | #ifndef _NET_RSS_CONFIG_H_ |
| 31 | #define	_NET_RSS_CONFIG_H_ |
| 32 | |
| 33 | #include <netinet/in.h>		/* in_addr_t */ |
| 34 | |
| 35 | /* |
| 36 | * Supported RSS hash functions. |
| 37 | */ |
| 38 | #define	RSS_HASH_NAIVE		0x00000001	/* Poor but fast hash. */ |
| 39 | #define	RSS_HASH_TOEPLITZ	0x00000002	/* Required by RSS. */ |
| 40 | #define	RSS_HASH_CRC32		0x00000004	/* Future; some NICs do it. */ |
| 41 | |
| 42 | #define	RSS_HASH_MASK		(RSS_HASH_NAIVE | RSS_HASH_TOEPLITZ) |
| 43 | |
| 44 | /* |
| 45 | * Instances of struct inpcbinfo declare an RSS hash type indicating what |
| 46 | * header fields are covered. |
| 47 | */ |
| 48 | #define	RSS_HASHFIELDS_NONE		0 |
| 49 | #define	RSS_HASHFIELDS_4TUPLE		1 |
| 50 | #define	RSS_HASHFIELDS_2TUPLE		2 |
| 51 | |
| 52 | /* |
| 53 | * Define RSS representations of the M_HASHTYPE_* values, representing |
| 54 | * which particular bits are supported. The NICs can then use this to |
| 55 | * calculate which hash types to enable and which not to enable. |
| 56 | * |
| 57 | * The fact that these line up with M_HASHTYPE_* is not to be relied |
| 58 | * upon. |
| 59 | */ |
| 60 | #define	RSS_HASHTYPE_RSS_IPV4		(1 << 1)	/* IPv4 2-tuple */ |
| 61 | #define	RSS_HASHTYPE_RSS_TCP_IPV4	(1 << 2)	/* TCPv4 4-tuple */ |
| 62 | #define	RSS_HASHTYPE_RSS_IPV6		(1 << 3)	/* IPv6 2-tuple */ |
| 63 | #define	RSS_HASHTYPE_RSS_TCP_IPV6	(1 << 4)	/* TCPv6 4-tuple */ |
| 64 | #define	RSS_HASHTYPE_RSS_IPV6_EX	(1 << 5)	/* IPv6 2-tuple + ext hdrs */ |
| 65 | #define	RSS_HASHTYPE_RSS_TCP_IPV6_EX	(1 << 6)	/* TCPv6 4-tiple + ext hdrs */ |
| 66 | #define	RSS_HASHTYPE_RSS_UDP_IPV4	(1 << 7)	/* IPv4 UDP 4-tuple */ |
| 67 | #define	RSS_HASHTYPE_RSS_UDP_IPV6	(1 << 9)	/* IPv6 UDP 4-tuple */ |
| 68 | #define	RSS_HASHTYPE_RSS_UDP_IPV6_EX	(1 << 10)	/* IPv6 UDP 4-tuple + ext hdrs */ |
| 69 | |
| 70 | /* |
| 71 | * Compile-time limits on the size of the indirection table. |
| 72 | */ |
| 73 | #define	RSS_MAXBITS	7 |
| 74 | #define	RSS_TABLE_MAXLEN	(1 << RSS_MAXBITS) |
| 75 | |
| 76 | /* |
| 77 | * Maximum key size used throughout. It's OK for hardware to use only the |
| 78 | * first 16 bytes, which is all that's required for IPv4. |
| 79 | */ |
| 80 | #define	RSS_KEYSIZE	40 |
| 81 | |
| 82 | /* |
| 83 | * For RSS hash methods that do a software hash on an mbuf, the packet |
| 84 | * direction (ingress / egress) is required. |
| 85 | * |
| 86 | * The default direction (INGRESS) is the "receive into the NIC" - ie, |
| 87 | * what the hardware is hashing on. |
| 88 | */ |
| 89 | #define	RSS_HASH_PKT_INGRESS	0 |
| 90 | #define	RSS_HASH_PKT_EGRESS	1 |
| 91 | |
| 92 | /* |
| 93 | * Rate limited debugging routines. |
| 94 | */ |
| 95 | #define	RSS_DEBUG(format, ...)	do {					\ |
| 96 | 	if (rss_debug) {						\ |
| 97 | 		static struct timeval lastfail;				\ |
| 98 | 		static int curfail;					\ |
| 99 | 		if (ppsratecheck(&lastfail, &curfail, 5))		\ |
| 100 | 			printf("RSS (%s:%u): " format, __func__, __LINE__,\ |
| 101 | 			 ##__VA_ARGS__);				\ |
| 102 | 	}								\ |
| 103 | } while (0) |
| 104 | |
| 105 | extern int	rss_debug; |
| 106 | |
| 107 | /* |
| 108 | * Device driver interfaces to query RSS properties that must be programmed |
| 109 | * into hardware. |
| 110 | */ |
| 111 | u_int	rss_getbits(void); |
| 112 | u_int	rss_getbucket(u_int hash); |
| 113 | u_int	rss_get_indirection_to_bucket(u_int index); |
| 114 | u_int	rss_getcpu(u_int bucket); |
| 115 | void	rss_getkey(uint8_t *key); |
| 116 | u_int	rss_gethashalgo(void); |
| 117 | u_int	rss_getnumbuckets(void); |
| 118 | u_int	rss_getnumcpus(void); |
| 119 | u_int	rss_gethashconfig(void); |
| 120 | |
| 121 | /* |
| 122 | * Hash calculation functions. |
| 123 | */ |
| 124 | uint32_t	rss_hash(u_int datalen, const uint8_t *data); |
| 125 | |
| 126 | /* |
| 127 | * Network stack interface to query desired CPU affinity of a packet. |
| 128 | */ |
| 129 | struct mbuf * rss_m2cpuid(struct mbuf *m, uintptr_t source, u_int *cpuid); |
| 130 | u_int	rss_hash2cpuid(uint32_t hash_val, uint32_t hash_type); |
| 131 | int	rss_hash2bucket(uint32_t hash_val, uint32_t hash_type, |
| 132 | 	 uint32_t *bucket_id); |
| 133 | int	rss_m2bucket(struct mbuf *m, uint32_t *bucket_id); |
| 134 | |
| 135 | #endif /* !_NET_RSS_CONFIG_H_ */ |