From: Brice Goglin <brice@myri.com>
To: Jeff Garzik <jeff@garzik.org>
Cc: netdev@vger.kernel.org
Subject: [PATCH 2.6.28 3/4] myri10ge: Add Toeplitz-hashing related routines
Date: Fri, 12 Sep 2008 19:49:07 +0200 [thread overview]
Message-ID: <48CAAB93.2070703@myri.com> (raw)
In-Reply-To: <48CAAAEF.1060205@myri.com>
myri10ge uses a Toeplitz hashing. Add the corresponding select_queue()
method without using it yet.
Signed-off-by: Brice Goglin <brice@myri.com>
---
drivers/net/myri10ge/myri10ge.c | 165 ++++++++++++++++++++++++++++++++++++++++
1 file changed, 165 insertions(+)
Index: linux-2.6.git/drivers/net/myri10ge/myri10ge.c
===================================================================
--- linux-2.6.git.orig/drivers/net/myri10ge/myri10ge.c 2008-09-12 19:24:15.000000000 +0200
+++ linux-2.6.git/drivers/net/myri10ge/myri10ge.c 2008-09-12 19:24:42.000000000 +0200
@@ -250,6 +250,8 @@
u32 read_write_dma;
u32 link_changes;
u32 msg_enable;
+ u32 *toeplitz_hash_table;
+ u8 rss_key[32];
};
static char *myri10ge_fw_unaligned = "myri10ge_ethp_z8e.dat";
@@ -2194,6 +2196,169 @@
return 0;
}
+static int myri10ge_init_toeplitz(struct myri10ge_priv *mgp)
+{
+ struct myri10ge_cmd cmd;
+ int i, b, s, t, j;
+ int status;
+ u32 k[8];
+ u32 tmp;
+ u8 *key;
+
+ status = myri10ge_send_cmd(mgp, MXGEFW_CMD_GET_RSS_KEY_OFFSET, &cmd, 0);
+ if (status != 0) {
+ printk(KERN_ERR
+ "myri10ge: %s: failed to get rss key\n", mgp->dev->name);
+ return -EIO;
+ }
+ memcpy_fromio(mgp->rss_key, mgp->sram + cmd.data0,
+ sizeof(mgp->rss_key));
+
+ mgp->toeplitz_hash_table = kmalloc(sizeof(u32) * 12 * 256, GFP_KERNEL);
+ if (mgp->toeplitz_hash_table == NULL)
+ return -ENOMEM;
+ key = (u8 *) mgp->rss_key;
+ t = 0;
+ for (b = 0; b < 12; b++) {
+ for (s = 0; s < 8; s++) {
+ /* Bits: b*8+s, ..., b*8+s+31 */
+ k[s] = 0;
+ for (j = 0; j < 32; j++) {
+ int bit = b * 8 + s + j;
+ bit = 0x1 & (key[bit / 8] >> (7 - (bit & 0x7)));
+ k[s] |= bit << (31 - j);
+ }
+ }
+
+ for (i = 0; i <= 0xff; i++) {
+ tmp = 0;
+ if (i & (1 << 7)) {
+ tmp ^= k[0];
+ }
+ if (i & (1 << 6)) {
+ tmp ^= k[1];
+ }
+ if (i & (1 << 5)) {
+ tmp ^= k[2];
+ }
+ if (i & (1 << 4)) {
+ tmp ^= k[3];
+ }
+ if (i & (1 << 3)) {
+ tmp ^= k[4];
+ }
+ if (i & (1 << 2)) {
+ tmp ^= k[5];
+ }
+ if (i & (1 << 1)) {
+ tmp ^= k[6];
+ }
+ if (i & (1 << 0)) {
+ tmp ^= k[7];
+ }
+ mgp->toeplitz_hash_table[t++] = tmp;
+ }
+ }
+ return 0;
+}
+
+static inline u16
+myri10ge_toeplitz_select_queue(struct net_device *dev, struct iphdr *ip)
+{
+ struct myri10ge_priv *mgp = netdev_priv(dev);
+ struct tcphdr *hdr;
+ u32 saddr, daddr;
+ u32 hash;
+ u32 *table = mgp->toeplitz_hash_table;
+ u16 src, dst;
+
+ /*
+ * Note hashing order is reversed from how it is done
+ * in the NIC, so as to generate the same hash value
+ * for the connection to try to keep connections CPU local
+ */
+
+ /* hash on IPv4 src/dst address */
+ saddr = ntohl(ip->saddr);
+ daddr = ntohl(ip->daddr);
+ hash = table[(256 * 0) + ((daddr >> 24) & 0xff)];
+ hash ^= table[(256 * 1) + ((daddr >> 16) & 0xff)];
+ hash ^= table[(256 * 2) + ((daddr >> 8) & 0xff)];
+ hash ^= table[(256 * 3) + ((daddr) & 0xff)];
+ hash ^= table[(256 * 4) + ((saddr >> 24) & 0xff)];
+ hash ^= table[(256 * 5) + ((saddr >> 16) & 0xff)];
+ hash ^= table[(256 * 6) + ((saddr >> 8) & 0xff)];
+ hash ^= table[(256 * 7) + ((saddr) & 0xff)];
+ /* hash on TCP port, if required */
+ if ((myri10ge_rss_hash & MXGEFW_RSS_HASH_TYPE_TCP_IPV4) &&
+ ip->protocol == IPPROTO_TCP) {
+ hdr = (struct tcphdr *)(((u8 *) ip) + (ip->ihl << 2));
+ src = ntohs(hdr->source);
+ dst = ntohs(hdr->dest);
+
+ hash ^= table[(256 * 8) + ((dst >> 8) & 0xff)];
+ hash ^= table[(256 * 9) + ((dst) & 0xff)];
+ hash ^= table[(256 * 10) + ((src >> 8) & 0xff)];
+ hash ^= table[(256 * 11) + ((src) & 0xff)];
+ }
+ return (u16) (hash & (dev->real_num_tx_queues - 1));
+}
+
+static u16
+myri10ge_simple_select_queue(struct net_device *dev, struct iphdr *ip)
+{
+ struct udphdr *hdr;
+ u32 hash_val = 0;
+
+ if (ip->protocol != IPPROTO_TCP && ip->protocol != IPPROTO_UDP)
+ return (0);
+ hdr = (struct udphdr *)(((u8 *) ip) + (ip->ihl << 2));
+
+ /*
+ * Use the second byte of the *destination* address for
+ * MXGEFW_RSS_HASH_TYPE_SRC_PORT, so as to match NIC's hashing
+ */
+ hash_val = ntohs(hdr->dest) & 0xff;
+ if (myri10ge_rss_hash == MXGEFW_RSS_HASH_TYPE_SRC_DST_PORT)
+ hash_val += ntohs(hdr->source) & 0xff;
+
+ return (u16) (hash_val & (dev->real_num_tx_queues - 1));
+}
+
+static u16 myri10ge_select_queue(struct net_device *dev, struct sk_buff *skb)
+{
+ struct iphdr *ip;
+ struct vlan_hdr *vh;
+
+ if (skb->protocol == __constant_htons(ETH_P_IP)) {
+ ip = ip_hdr(skb);
+ } else if (skb->protocol == __constant_htons(ETH_P_8021Q)) {
+ vh = (struct vlan_hdr *)skb->data;
+ if ((vh->h_vlan_encapsulated_proto !=
+ __constant_htons(ETH_P_IP)))
+ return 0;
+ ip = (struct iphdr *)skb->data + sizeof(*vh);
+ } else {
+ return 0;
+ }
+
+ switch (myri10ge_rss_hash) {
+ case MXGEFW_RSS_HASH_TYPE_IPV4:
+ /* fallthru */
+ case MXGEFW_RSS_HASH_TYPE_TCP_IPV4:
+ /* fallthru */
+ case (MXGEFW_RSS_HASH_TYPE_IPV4 | MXGEFW_RSS_HASH_TYPE_TCP_IPV4):
+ return (myri10ge_toeplitz_select_queue(dev, ip));
+ break;
+ case MXGEFW_RSS_HASH_TYPE_SRC_PORT:
+ /* fallthru */
+ case MXGEFW_RSS_HASH_TYPE_SRC_DST_PORT:
+ return (myri10ge_simple_select_queue(dev, ip));
+ default:
+ return (0);
+ }
+}
+
static int myri10ge_get_txrx(struct myri10ge_priv *mgp, int slice)
{
struct myri10ge_cmd cmd;
next prev parent reply other threads:[~2008-09-12 17:50 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2008-09-12 17:46 [PATCH 2.6.28] myri10ge updates + multiqueue TX Brice Goglin
2008-09-12 17:47 ` [PATCH 2.6.28 1/4] myri10ge: Stop scaring people when DCA is built but absent Brice Goglin
2008-09-13 19:30 ` Jeff Garzik
2008-09-12 17:48 ` [PATCH 2.6.28 2/4] myri10ge: Rename DCA-related firmware counters Brice Goglin
2008-09-12 17:49 ` Brice Goglin [this message]
2008-09-12 19:54 ` [PATCH 2.6.28 3/4] myri10ge: Add Toeplitz-hashing related routines Ben Hutchings
2008-09-12 22:32 ` Duyck, Alexander H
2008-09-12 17:50 ` [PATCH 2.6.28 4/4] myri10ge: Add multiqueue TX support Brice Goglin
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=48CAAB93.2070703@myri.com \
--to=brice@myri.com \
--cc=jeff@garzik.org \
--cc=netdev@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.