Commit 1036bcf7 authored by Antoine Kaufmann's avatar Antoine Kaufmann
Browse files

i40e: rss draft

parent bdffa8ba
...@@ -3,7 +3,8 @@ CPPFLAGS += -I../libnicbm/include/ ...@@ -3,7 +3,8 @@ CPPFLAGS += -I../libnicbm/include/
CXXFLAGS += -Wall -Wextra -Wno-unused-parameter -O3 -g CXXFLAGS += -Wall -Wextra -Wno-unused-parameter -O3 -g
LDFLGAS = -g LDFLGAS = -g
OBJS := i40e_bm.o i40e_queues.o i40e_adminq.o i40e_hmc.o i40e_lan.o xsums.o logger.o OBJS := i40e_bm.o i40e_queues.o i40e_adminq.o i40e_hmc.o i40e_lan.o xsums.o \
rss.o logger.o
all: i40e_bm all: i40e_bm
......
...@@ -187,6 +187,10 @@ uint32_t i40e_bm::reg_mem_read32(uint64_t addr) ...@@ -187,6 +187,10 @@ uint32_t i40e_bm::reg_mem_read32(uint64_t addr)
addr <= I40E_GLQF_HKEY(I40E_GLQF_HKEY_MAX_INDEX)) addr <= I40E_GLQF_HKEY(I40E_GLQF_HKEY_MAX_INDEX))
{ {
val = regs.glqf_hkey[(addr - I40E_GLQF_HKEY(0)) / 4]; val = regs.glqf_hkey[(addr - I40E_GLQF_HKEY(0)) / 4];
} else if (addr >= I40E_PFQF_HLUT(0) &&
addr <= I40E_PFQF_HLUT(I40E_PFQF_HLUT_MAX_INDEX))
{
val = regs.pfqf_hlut[(addr - I40E_PFQF_HLUT(0)) / 128];
} else { } else {
switch (addr) { switch (addr) {
...@@ -374,6 +378,10 @@ uint32_t i40e_bm::reg_mem_read32(uint64_t addr) ...@@ -374,6 +378,10 @@ uint32_t i40e_bm::reg_mem_read32(uint64_t addr)
val = 0; val = 0;
break; break;
case I40E_PFQF_CTL_0:
val = regs.pfqf_ctl_0;
break;
default: default:
#ifdef DEBUG_DEV #ifdef DEBUG_DEV
log << "unhandled mem read addr=" << addr log << "unhandled mem read addr=" << addr
...@@ -456,6 +464,11 @@ void i40e_bm::reg_mem_write32(uint64_t addr, uint32_t val) ...@@ -456,6 +464,11 @@ void i40e_bm::reg_mem_write32(uint64_t addr, uint32_t val)
addr <= I40E_GLQF_HKEY(I40E_GLQF_HKEY_MAX_INDEX)) addr <= I40E_GLQF_HKEY(I40E_GLQF_HKEY_MAX_INDEX))
{ {
regs.glqf_hkey[(addr - I40E_GLQF_HKEY(0)) / 4] = val; regs.glqf_hkey[(addr - I40E_GLQF_HKEY(0)) / 4] = val;
lanmgr.rss_key_updated();
} else if (addr >= I40E_PFQF_HLUT(0) &&
addr <= I40E_PFQF_HLUT(I40E_PFQF_HLUT_MAX_INDEX))
{
regs.pfqf_hlut[(addr - I40E_PFQF_HLUT(0)) / 128] = val;
} else { } else {
switch (addr) { switch (addr) {
case I40E_PFGEN_CTRL: case I40E_PFGEN_CTRL:
...@@ -564,6 +577,10 @@ void i40e_bm::reg_mem_write32(uint64_t addr, uint32_t val) ...@@ -564,6 +577,10 @@ void i40e_bm::reg_mem_write32(uint64_t addr, uint32_t val)
regs.pf_arqt = val; regs.pf_arqt = val;
break; break;
case I40E_PFQF_CTL_0:
regs.pfqf_ctl_0 = val;
break;
default: default:
#ifdef DEBUG_DEV #ifdef DEBUG_DEV
log << "unhandled mem write addr=" << addr log << "unhandled mem write addr=" << addr
...@@ -654,6 +671,21 @@ void i40e_bm::reset(bool indicate_done) ...@@ -654,6 +671,21 @@ void i40e_bm::reset(bool indicate_done)
} }
intevs[i].time = 0; intevs[i].time = 0;
} }
// add default hash key
regs.glqf_hkey[0] = 0xda565a6d;
regs.glqf_hkey[1] = 0xc20e5b25;
regs.glqf_hkey[2] = 0x3d256741;
regs.glqf_hkey[3] = 0xb08fa343;
regs.glqf_hkey[4] = 0xcb2bcad0;
regs.glqf_hkey[5] = 0xb4307bae;
regs.glqf_hkey[6] = 0xa32dcb77;
regs.glqf_hkey[7] = 0x0cf23080;
regs.glqf_hkey[8] = 0x3bb7426a;
regs.glqf_hkey[9] = 0xfa01acbe;
regs.glqf_hkey[10] = 0x0;
regs.glqf_hkey[11] = 0x0;
regs.glqf_hkey[12] = 0x0;
} }
shadow_ram::shadow_ram(i40e_bm &dev_) shadow_ram::shadow_ram(i40e_bm &dev_)
......
...@@ -405,7 +405,24 @@ class lan_queue_rx : public lan_queue_base { ...@@ -405,7 +405,24 @@ class lan_queue_rx : public lan_queue_base {
uint32_t &reg_ena, uint32_t &fpm_basereg, uint32_t &reg_ena, uint32_t &fpm_basereg,
uint32_t &reg_intqctl); uint32_t &reg_intqctl);
virtual void reset(); virtual void reset();
void packet_received(const void *data, size_t len); void packet_received(const void *data, size_t len, uint32_t hash);
};
class rss_key_cache {
protected:
static const size_t key_len = 52;
static const size_t cache_len = 288; // big enough for 2x ipv6 (2x128 + 2x16)
bool cache_dirty;
const uint32_t (&key)[key_len / 4];
uint32_t cache[cache_len];
void build();
public:
rss_key_cache(const uint32_t (&key_)[key_len / 4]);
void set_dirty();
uint32_t hash_ipv4(uint32_t sip, uint32_t dip, uint16_t sp,
uint16_t dp);
}; };
// rx tx management // rx tx management
...@@ -417,15 +434,19 @@ class lan { ...@@ -417,15 +434,19 @@ class lan {
i40e_bm &dev; i40e_bm &dev;
logger log; logger log;
rss_key_cache rss_kc;
const size_t num_qs; const size_t num_qs;
lan_queue_rx **rxqs; lan_queue_rx **rxqs;
lan_queue_tx **txqs; lan_queue_tx **txqs;
bool rss_steering(const void *data, size_t len, uint16_t &queue,
uint32_t &hash);
public: public:
lan(i40e_bm &dev, size_t num_qs); lan(i40e_bm &dev, size_t num_qs);
void reset(); void reset();
void qena_updated(uint16_t idx, bool rx); void qena_updated(uint16_t idx, bool rx);
void tail_updated(uint16_t idx, bool rx); void tail_updated(uint16_t idx, bool rx);
void rss_key_updated();
void packet_received(const void *data, size_t len); void packet_received(const void *data, size_t len);
}; };
...@@ -507,7 +528,10 @@ protected: ...@@ -507,7 +528,10 @@ protected:
uint32_t pf_arqh; uint32_t pf_arqh;
uint32_t pf_arqt; uint32_t pf_arqt;
uint32_t pfqf_ctl_0;
uint32_t glqf_hkey[13]; uint32_t glqf_hkey[13];
uint32_t pfqf_hlut[128];
}; };
public: public:
......
...@@ -2,17 +2,19 @@ ...@@ -2,17 +2,19 @@
#include <string.h> #include <string.h>
#include <cassert> #include <cassert>
#include <iostream> #include <iostream>
#include <arpa/inet.h>
#include "i40e_bm.h" #include "i40e_bm.h"
#include "i40e_base_wrapper.h" #include "i40e_base_wrapper.h"
#include "headers.h"
using namespace i40e; using namespace i40e;
extern nicbm::Runner *runner; extern nicbm::Runner *runner;
lan::lan(i40e_bm &dev_, size_t num_qs_) lan::lan(i40e_bm &dev_, size_t num_qs_)
: dev(dev_), log("lan"), num_qs(num_qs_) : dev(dev_), log("lan"), rss_kc(dev_.regs.glqf_hkey), num_qs(num_qs_)
{ {
rxqs = new lan_queue_rx *[num_qs]; rxqs = new lan_queue_rx *[num_qs];
txqs = new lan_queue_tx *[num_qs]; txqs = new lan_queue_tx *[num_qs];
...@@ -29,6 +31,7 @@ lan::lan(i40e_bm &dev_, size_t num_qs_) ...@@ -29,6 +31,7 @@ lan::lan(i40e_bm &dev_, size_t num_qs_)
void lan::reset() void lan::reset()
{ {
rss_kc.set_dirty();
for (size_t i = 0; i < num_qs; i++) { for (size_t i = 0; i < num_qs; i++) {
rxqs[i]->reset(); rxqs[i]->reset();
txqs[i]->reset(); txqs[i]->reset();
...@@ -64,14 +67,54 @@ void lan::tail_updated(uint16_t idx, bool rx) ...@@ -64,14 +67,54 @@ void lan::tail_updated(uint16_t idx, bool rx)
q.reg_updated(); q.reg_updated();
} }
void lan::rss_key_updated()
{
rss_kc.set_dirty();
}
bool lan::rss_steering(const void *data, size_t len, uint16_t &queue,
uint32_t &hash)
{
hash = 0;
const headers::pkt_tcp *tcp = reinterpret_cast<const headers::pkt_tcp *> (data);
const headers::pkt_udp *udp = reinterpret_cast<const headers::pkt_udp *> (data);
// should actually determine packet type and mask with enabled packet types
// TODO: ipv6
if (tcp->eth.type == htons(ETH_TYPE_IP) &&
tcp->ip.proto == IP_PROTO_TCP)
{
hash = rss_kc.hash_ipv4(ntohl(tcp->ip.src), ntohl(tcp->ip.dest),
ntohs(tcp->tcp.src), ntohs(tcp->tcp.dest));
} else if (udp->eth.type == htons(ETH_TYPE_IP) &&
udp->ip.proto == IP_PROTO_UDP)
{
hash = rss_kc.hash_ipv4(ntohl(udp->ip.src), ntohl(udp->ip.dest),
ntohs(udp->udp.src), ntohs(udp->udp.dest));
} else if (udp->eth.type == htons(ETH_TYPE_IP)) {
hash = rss_kc.hash_ipv4(ntohl(udp->ip.src), ntohl(udp->ip.dest), 0, 0);
} else {
return false;
}
uint16_t luts = (!(dev.regs.pfqf_ctl_0 & I40E_PFQF_CTL_0_HASHLUTSIZE_MASK) ?
128 : 512);
uint16_t idx = hash % luts;
queue = (dev.regs.pfqf_hlut[idx / 4] >> (8 * (idx % 4))) & 0x3f;
return true;
}
void lan::packet_received(const void *data, size_t len) void lan::packet_received(const void *data, size_t len)
{ {
#ifdef DEBUG_LAN #ifdef DEBUG_LAN
log << " packet received len=" << len << logger::endl; log << " packet received len=" << len << logger::endl;
#endif #endif
// TODO: steering uint32_t hash = 0;
rxqs[0]->packet_received(data, len); uint16_t queue = 0;
rss_steering(data, len, queue, hash);
rxqs[queue]->packet_received(data, len, hash);
} }
lan_queue_base::lan_queue_base(lan &lanmgr_, const std::string &qtype, lan_queue_base::lan_queue_base(lan &lanmgr_, const std::string &qtype,
...@@ -256,7 +299,7 @@ queue_base::desc_ctx &lan_queue_rx::desc_ctx_create() ...@@ -256,7 +299,7 @@ queue_base::desc_ctx &lan_queue_rx::desc_ctx_create()
return *new rx_desc_ctx(*this); return *new rx_desc_ctx(*this);
} }
void lan_queue_rx::packet_received(const void *data, size_t pktlen) void lan_queue_rx::packet_received(const void *data, size_t pktlen, uint32_t h)
{ {
size_t num_descs = (pktlen + dbuff_size - 1) / dbuff_size; size_t num_descs = (pktlen + dbuff_size - 1) / dbuff_size;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment