Adapt NetFPGA implementation to the userspace hardware platform
This commit is contained in:
1 parent
6778bd8cdf
commit
2e38251708
15 files changed
+4516
-88
No files matched your search
+18
-20
@@ -2,29 +2,27 @@
|
||||
# Hardware library dependency file definitions.
|
||||
#
|
||||
|
||||
# Sample name
|
||||
if LB4G
|
||||
if NF2
|
||||
#
|
||||
# Sample library
|
||||
# NetFPGA hardware library
|
||||
#
|
||||
noinst_LIBRARIES += hw-lib/libskeleton.a
|
||||
noinst_LIBRARIES += hw-lib/libnf2.a
|
||||
|
||||
hw_lib_libskeleton_a_SOURCES = \
|
||||
hw-lib/skeleton/of_hw_platform.h \
|
||||
hw-lib/skeleton/txrx.c \
|
||||
hw-lib/skeleton/txrx.h \
|
||||
hw-lib/skeleton/hw_drv.c \
|
||||
hw-lib/skeleton/hw_drv.h \
|
||||
hw-lib/skeleton/hw_flow.c \
|
||||
hw-lib/skeleton/hw_flow.h \
|
||||
hw-lib/skeleton/port.c \
|
||||
hw-lib/skeleton/port.h \
|
||||
hw-lib/skeleton/debug.h
|
||||
hw_lib_libnf2_a_SOURCES = \
|
||||
hw-lib/nf2/hw_flow.c \
|
||||
hw-lib/nf2/hw_flow.h \
|
||||
hw-lib/nf2/nf2_lib.c \
|
||||
hw-lib/nf2/nf2_lib.h \
|
||||
hw-lib/nf2/nf2_hwapi.c \
|
||||
hw-lib/nf2/nf2_hwapi.h \
|
||||
hw-lib/nf2/nf2.h \
|
||||
hw-lib/nf2/debug.h \
|
||||
hw-lib/nf2/reg_defines_openflow_switch.h \
|
||||
hw-lib/nf2/nf2util.c \
|
||||
hw-lib/nf2/nf2util.h
|
||||
|
||||
hw_lib_libskeleton_a_CPPFLAGS = $(AM_CPPFLAGS) $(OF_CPP_FLAGS)
|
||||
hw_lib_libskeleton_a_CPPFLAGS += -I hw-lib/skeleton
|
||||
hw_lib_libskeleton_a_CPPFLAGS += -I $(HW_SYSTEM)/include
|
||||
hw_lib_libskeleton_a_CPPFLAGS += -DSAMPLE_PLAT
|
||||
hw_lib_libskeleton_a_CPPFLAGS += -DSKELETON
|
||||
hw_lib_nf2_a_CPPFLAGS = $(AM_CPPFLAGS) $(OF_CPP_FLAGS) -DHWTABLE_NO_DEBUG
|
||||
hw_lib_nf2_a_CPPFLAGS += -I hw-lib/nf2
|
||||
hw_lib_nf2_a_CPPFLAGS += -I $(HW_SYSTEM)/include
|
||||
|
||||
endif
|
||||
@@ -0,0 +1,56 @@
|
||||
NetFPGA Hardware Table
|
||||
Date - 03/09/10
|
||||
----------------------------------------
|
||||
|
||||
This library creates and maintains a single software table that contains all
|
||||
the flows that are currently held in the NetFPGA card. The card itself splits
|
||||
exact match flows into SRAM and wildcard match flows into TCAMs. Currently
|
||||
there are 24 usable wildcard flow entries and 32,768 available exact match
|
||||
entries. The exact match table is hashed so actual available entries will be
|
||||
varied.
|
||||
|
||||
Installation
|
||||
----------------------------------------
|
||||
|
||||
First build OpenFlow ensuring you include the directive to build the
|
||||
openflow_netfpga hardware table in your configure statement:
|
||||
|
||||
% ./configure --enable-hw-lib=nf2
|
||||
|
||||
For further help regarding building OpenFlow please see the INSTALL file in
|
||||
the OpenFlow root directory.
|
||||
|
||||
Platform support
|
||||
----------------
|
||||
|
||||
OpenFlow v1.0 with NetFPGA hardware table has been tested on CentOS5.4
|
||||
(Linux 2.6.18), which is the officially supported platform of NetFPGA.
|
||||
|
||||
Running
|
||||
----------------------------------------
|
||||
|
||||
Use nf2_download to download the openflow_switch.bit file that is located in
|
||||
the <openflow>/datapath/hwtable_nf2 folder:
|
||||
|
||||
% nf2_download -r <openflow>/hw-lib/nf2/openflow_switch.bit
|
||||
|
||||
'-r' option enables PHY interrupt for its link status changing, and OpenFlow
|
||||
switch can detect it.
|
||||
|
||||
Run ofdatapth with indicating *all* the NetFPGA interfaces:
|
||||
|
||||
% <openflow>/udatapath/ofdatapath punix:/var/run/test \
|
||||
-i nf2c0,nf2c1,nf2c2,nf2c3
|
||||
|
||||
At this point your OpenFlow switch should be ready to go.
|
||||
The way you start up ofprotocol is as same as you do for software reference
|
||||
switch.
|
||||
|
||||
Known Issues
|
||||
----------------------------------------
|
||||
* There is currently no support for priority amongst wildcard-match entries.
|
||||
|
||||
Contact
|
||||
-------
|
||||
e-mail: openflow-discuss@lists.stanford.edu
|
||||
www: http://openflowswitch.org/
|
||||
@@ -0,0 +1,105 @@
|
||||
|
||||
#ifndef OF_HW_DEBUG_H
|
||||
#define OF_HW_DEBUG_H 1
|
||||
|
||||
#include <stdio.h>
|
||||
#include <openflow/openflow.h>
|
||||
|
||||
#if !defined(HWTABLE_NO_DEBUG)
|
||||
extern int of_hw_debug;
|
||||
#define dbg_send(mod, lvl, fmt, args...) \
|
||||
if (of_hw_debug >= (lvl)) fprintf(stderr, fmt, ##args)
|
||||
|
||||
#define DBG_LVL_NONE -1 /* All output off */
|
||||
#define DBG_LVL_ERROR 0 /* Default value */
|
||||
#define DBG_LVL_ALWAYS 0 /* For requested dump output */
|
||||
#define DBG_LVL_WARN 1
|
||||
#define DBG_LVL_VERBOSE 2
|
||||
#define DBG_LVL_VVERB 3 /* Include success indications */
|
||||
|
||||
/* Sorry for the lazy syntax here. */
|
||||
#define DBG_CHECK(lvl) (((lvl) >= 0) && (of_hw_debug >= (lvl)))
|
||||
#define DBG_ERROR(fmt, args...) dbg_send(0, DBG_LVL_ERROR, fmt, ##args)
|
||||
#define DBG_ALWAYS(fmt, args...) dbg_send(0, DBG_LVL_ALWAYS, fmt, ##args)
|
||||
#define DBG_WARN(fmt, args...) dbg_send(0, DBG_LVL_WARN, fmt, ##args)
|
||||
#define DBG_VERBOSE(fmt, args...) dbg_send(0, DBG_LVL_VERBOSE, fmt, ##args)
|
||||
#define DBG_VVERB(fmt, args...) dbg_send(0, DBG_LVL_VVERB, fmt, ##args)
|
||||
#define DBG_NONE(fmt, args...)
|
||||
/* Same as DEBUG_ALWAYS */
|
||||
#define DEBUGK(fmt, args...) dbg_send(0, DBG_LVL_ALWAYS, fmt, ##args)
|
||||
|
||||
#define REPORT_ERROR(str) \
|
||||
DBG_ERROR("ERROR: %s:%d. %s\n", __FUNCTION__, __LINE__, str)
|
||||
|
||||
/* Default debugging location string */
|
||||
#define ANNOUNCE_LOCATION DBG_VVERB("%s: %d\n", __FUNCTION__, __LINE__)
|
||||
#define DBG_INCR(cnt) (++(cnt))
|
||||
|
||||
/* Should assert return? Not presently */
|
||||
#define ASSERT(cond) \
|
||||
if (!(cond)) DBG_ERROR("ASSERTION %s IN %s FAILED LINE %d\n", \
|
||||
#cond, __FUNCTION__, __LINE__)
|
||||
|
||||
/* DEBUG for HW flow lists */
|
||||
#define HW_FLOW_MAGIC 0xba5eba11
|
||||
#define HW_FLOW_MAKE_VALID(hf) (hf)->magic = HW_FLOW_MAGIC
|
||||
#define HW_FLOW_IS_VALID(hf) \
|
||||
(((hf) != NULL) && ((hf)->magic == HW_FLOW_MAGIC))
|
||||
|
||||
/*
|
||||
* Carry out an operation and check for error, optionally returning
|
||||
* from the calling routine. To avoid compiler
|
||||
* warnings in routines with void return, we give two macros.
|
||||
*
|
||||
* WARNING: This check uses rv != 0 (not just rv < 0).
|
||||
*/
|
||||
|
||||
#define TRY(op, str) do { \
|
||||
int rv; \
|
||||
if (((rv = (op)) < 0)) { \
|
||||
DBG_ERROR("ERROR %d: %s\n", rv, str); \
|
||||
return rv; \
|
||||
} else { \
|
||||
DBG_NONE("%s: success\n", str); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define TRY_NR(op, str) do { \
|
||||
int rv; \
|
||||
if (((rv = (op)) != 0)) { \
|
||||
DBG_ERROR("ERROR %d: %s\n", rv, str); \
|
||||
} else { \
|
||||
DBG_NONE("%s: success\n", str); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#else /* No debugging */
|
||||
|
||||
#define DBG_CHECK(lvl) 0
|
||||
#define ANNOUNCE_LOCATION
|
||||
#define ACT_STRING(action) ""
|
||||
#define DBG_INCR(cnt)
|
||||
#define DBG_ERROR(fmt, args...)
|
||||
#define DBG_ALWAYS(fmt, args...)
|
||||
#define DBG_WARN(fmt, args...)
|
||||
#define DBG_VERBOSE(fmt, args...)
|
||||
#define DBG_VVERB(fmt, args...)
|
||||
#define DBG_NONE(fmt, args...)
|
||||
#define DEBUGK(fmt, args...)
|
||||
#define REPORT_ERROR(str)
|
||||
|
||||
#define ASSERT(cond)
|
||||
|
||||
#define HW_FLOW_MAKE_VALID(hf)
|
||||
#define HW_FLOW_IS_VALID(hf) 1
|
||||
|
||||
#define TRY(op, str) do { \
|
||||
int rv; \
|
||||
if (((rv = (op)) != 0)) return rv; \
|
||||
} while (0)
|
||||
|
||||
#define TRY_NR(op, str) (void)op
|
||||
|
||||
#endif /* !defined(HWTABLE_NO_DEBUG) */
|
||||
|
||||
#endif /* OF_HW_DEBUG_H */
|
||||
@@ -0,0 +1,510 @@
|
||||
/*-
|
||||
* Copyright (c) 2008, 2009, 2010
|
||||
* The Board of Trustees of The Leland Stanford Junior University
|
||||
*
|
||||
* We are making the OpenFlow specification and associated documentation
|
||||
* (Software) available for public use and benefit with the expectation that
|
||||
* others will use, modify and enhance the Software and contribute those
|
||||
* enhancements back to the community. However, since we would like to make the
|
||||
* Software available for broadest use, with as few restrictions as possible
|
||||
* permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this Software to deal in the Software under the copyrights without
|
||||
* restriction, including without limitation the rights to use, copy, modify,
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of the Software,
|
||||
* and to permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
* IN THE SOFTWARE.
|
||||
*
|
||||
* The name and trademarks of copyright holder(s) may NOT be used in
|
||||
* advertising or publicity pertaining to the Software or any derivatives
|
||||
* without specific, written prior permission.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <openflow/of_hw_api.h>
|
||||
#include "list.h"
|
||||
#include "udatapath/switch-flow.h"
|
||||
#include "udatapath/datapath.h"
|
||||
#include "reg_defines_openflow_switch.h"
|
||||
#include "nf2util.h"
|
||||
#include "hw_flow.h"
|
||||
#include "nf2_hwapi.h"
|
||||
#include "nf2_lib.h"
|
||||
#include "debug.h"
|
||||
|
||||
struct nf2_flowtable {
|
||||
struct of_hw_driver hw_driver;
|
||||
unsigned int max_flows;
|
||||
unsigned int num_flows;
|
||||
struct list flows;
|
||||
struct list iter_flows;
|
||||
unsigned long int next_serial;
|
||||
};
|
||||
|
||||
static struct sw_flow *nf2_lookup_flowtable(struct sw_table *,
|
||||
const struct sw_flow_key *);
|
||||
static int nf2_install_flow(struct sw_table *, struct sw_flow *);
|
||||
static int nf2_modify_flow(struct sw_table *, const struct sw_flow_key *,
|
||||
uint16_t, int, const struct ofp_action_header *,
|
||||
size_t);
|
||||
static int do_uninstall(struct sw_flow *, struct list *);
|
||||
static int nf2_has_conflict(struct sw_table *, const struct sw_flow_key *,
|
||||
uint16_t, int);
|
||||
static int nf2_uninstall_flow_wrap(struct datapath *, struct sw_table *,
|
||||
const struct sw_flow_key *, uint16_t,
|
||||
uint16_t, int);
|
||||
static int nf2_uninstall_flow(struct datapath *, struct sw_table *,
|
||||
const struct sw_flow_key *, uint16_t,
|
||||
uint16_t, int, int);
|
||||
static void nf2_flow_timeout(struct sw_table *, struct list *);
|
||||
|
||||
static void nf2_destroy_flowtable(struct sw_table *);
|
||||
static int nf2_iterate_flowtable(struct sw_table *,
|
||||
const struct sw_flow_key *,
|
||||
uint16_t, struct sw_table_position *,
|
||||
int (*)(struct sw_flow *, void *), void *);
|
||||
static void nf2_get_flowstats(struct sw_table *, struct sw_table_stats *);
|
||||
static int nf2_get_portstats(of_hw_driver_t *, int, struct ofp_port_stats *);
|
||||
|
||||
#if !defined(HWTABLE_NO_DEBUG)
|
||||
int of_hw_debug = DBG_LVL_WARN;
|
||||
#endif
|
||||
|
||||
#define DELETE_FLOW 0
|
||||
#define KEEP_FLOW 1
|
||||
|
||||
static struct sw_flow *
|
||||
nf2_lookup_flowtable(struct sw_table *flowtab, const struct sw_flow_key *key)
|
||||
{
|
||||
struct nf2_flowtable *nf2flowtab = (struct nf2_flowtable *)flowtab;
|
||||
struct sw_flow *flow;
|
||||
|
||||
LIST_FOR_EACH(flow, struct sw_flow, node, &nf2flowtab->flows) {
|
||||
if (flow_matches_1wild(key, &flow->key)) {
|
||||
return flow;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int
|
||||
nf2_install_flow(struct sw_table *flowtab, struct sw_flow *flow)
|
||||
{
|
||||
struct nf2_flowtable *nf2flowtab = (struct nf2_flowtable *)flowtab;
|
||||
|
||||
/* Delete flows that match exactly. */
|
||||
nf2_uninstall_flow(NULL, flowtab, &flow->key, OFPP_NONE,
|
||||
flow->priority, true, KEEP_FLOW);
|
||||
|
||||
if (nf2_are_actions_supported(flow)) {
|
||||
if (nf2_build_and_write_flow(flow)) {
|
||||
/* Not successful */
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
/* Unsupported actions or no device. */
|
||||
return 0;
|
||||
}
|
||||
|
||||
nf2flowtab->num_flows++;
|
||||
list_push_front(&nf2flowtab->flows, &flow->node);
|
||||
list_push_front(&nf2flowtab->iter_flows, &flow->iter_node);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
nf2_modify_flow(struct sw_table *flowtab, const struct sw_flow_key *key,
|
||||
uint16_t priority, int strict,
|
||||
const struct ofp_action_header *actions, size_t actions_len)
|
||||
{
|
||||
struct nf2_flowtable *nf2flowtab = (struct nf2_flowtable *)flowtab;
|
||||
struct sw_flow *flow;
|
||||
unsigned int count = 0;
|
||||
|
||||
LIST_FOR_EACH(flow, struct sw_flow, node, &nf2flowtab->flows) {
|
||||
if (flow_matches_desc(&flow->key, key, strict)
|
||||
&& (!strict || flow->priority == priority)) {
|
||||
flow_replace_acts(flow, actions, actions_len);
|
||||
if (nf2_are_actions_supported(flow)) {
|
||||
count += nf2_modify_acts(flow);
|
||||
}
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
static int
|
||||
nf2_has_conflict(struct sw_table *flowtab, const struct sw_flow_key *key,
|
||||
uint16_t priority, int strict)
|
||||
{
|
||||
struct nf2_flowtable *nf2flowtab = (struct nf2_flowtable *)flowtab;
|
||||
struct sw_flow *flow;
|
||||
|
||||
LIST_FOR_EACH(flow, struct sw_flow, node, &nf2flowtab->flows) {
|
||||
|
||||
if (flow_matches_2desc(&flow->key, key, strict)
|
||||
&& (flow->priority == priority)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static int
|
||||
do_uninstall(struct sw_flow *flow, struct list *deleted)
|
||||
{
|
||||
if (flow != NULL && flow->private != NULL) {
|
||||
list_remove(&flow->node);
|
||||
list_remove(&flow->iter_node);
|
||||
list_push_back(deleted, &flow->node);
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
nf2_uninstall_flow_wrap(struct datapath *dpinst, struct sw_table *flowtab,
|
||||
const struct sw_flow_key *key, uint16_t out_port,
|
||||
uint16_t priority, int strict)
|
||||
{
|
||||
return nf2_uninstall_flow(dpinst, flowtab, key, out_port,
|
||||
priority, strict, DELETE_FLOW);
|
||||
}
|
||||
|
||||
static int
|
||||
nf2_uninstall_flow(struct datapath *dpinst, struct sw_table *flowtab,
|
||||
const struct sw_flow_key *key, uint16_t out_port,
|
||||
uint16_t priority, int strict, int keep_flow)
|
||||
{
|
||||
struct nf2device *dev;
|
||||
struct nf2_flowtable *nf2flowtab = (struct nf2_flowtable *)flowtab;
|
||||
struct sw_flow *flow, *n;
|
||||
struct nf2_flow *nf2flow;
|
||||
unsigned int count = 0;
|
||||
struct list deleted;
|
||||
list_init(&deleted);
|
||||
|
||||
LIST_FOR_EACH_SAFE (flow, n, struct sw_flow, node, &nf2flowtab->flows) {
|
||||
if (flow_matches_desc(&flow->key, key, strict)
|
||||
&& (!strict || flow->priority == priority)
|
||||
&& flow_has_out_port(flow, out_port)) {
|
||||
nf2flow = flow->private;
|
||||
|
||||
if (nf2flow != NULL) {
|
||||
dev = nf2_get_net_device();
|
||||
if (dev == NULL)
|
||||
return 0;
|
||||
flow->packet_count
|
||||
+= nf2_get_packet_count(dev,
|
||||
nf2flow);
|
||||
flow->byte_count += nf2_get_byte_count(dev,
|
||||
nf2flow);
|
||||
|
||||
nf2_free_net_device(dev);
|
||||
}
|
||||
count += do_uninstall(flow, &deleted);
|
||||
if (keep_flow == KEEP_FLOW) {
|
||||
/* Delete private in sw_flow here */
|
||||
nf2_delete_private(flow->private);
|
||||
}
|
||||
}
|
||||
}
|
||||
nf2flowtab->num_flows -= count;
|
||||
|
||||
if (keep_flow == DELETE_FLOW) {
|
||||
/* Notify DP of deleted flows and delete the flow */
|
||||
LIST_FOR_EACH_SAFE (flow, n, struct sw_flow, node, &deleted) {
|
||||
dp_send_flow_end(dpinst, flow, flow->reason);
|
||||
list_remove(&flow->node);
|
||||
nf2_delete_private(flow->private);
|
||||
flow_free(flow);
|
||||
}
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
static void
|
||||
nf2_flow_timeout(struct sw_table *flowtab, struct list *deleted)
|
||||
{
|
||||
struct nf2device *dev;
|
||||
struct nf2_flowtable *nf2flowtab = (struct nf2_flowtable *)flowtab;
|
||||
struct sw_flow *flow, *n;
|
||||
struct nf2_flow *nf2flow;
|
||||
int num_uninst_flows = 0;
|
||||
uint64_t num_forw_packets = 0;
|
||||
uint64_t now = time_msec();
|
||||
|
||||
dev = nf2_get_net_device();
|
||||
if (dev == NULL) {
|
||||
DBG_ERROR("Could not open NetFPGA device\n");
|
||||
return;
|
||||
}
|
||||
|
||||
/* LOCK; */
|
||||
/* FIXME */
|
||||
LIST_FOR_EACH_SAFE (flow, n, struct sw_flow, node, &nf2flowtab->flows) {
|
||||
nf2flow = flow->private;
|
||||
if (nf2flow != NULL) {
|
||||
num_forw_packets = flow->packet_count
|
||||
+ nf2_get_packet_count(dev, nf2flow);
|
||||
flow->byte_count += nf2_get_byte_count(dev, nf2flow);
|
||||
}
|
||||
if (num_forw_packets > flow->packet_count
|
||||
&& flow->idle_timeout != OFP_FLOW_PERMANENT) {
|
||||
flow->packet_count = num_forw_packets;
|
||||
flow->used = now;
|
||||
}
|
||||
|
||||
if (flow_timeout(flow)) {
|
||||
num_uninst_flows += do_uninstall(flow, deleted);
|
||||
nf2_delete_private(flow->private);
|
||||
}
|
||||
}
|
||||
|
||||
/* UNLOCK; */
|
||||
|
||||
nf2_clear_watchdog(dev);
|
||||
nf2_free_net_device(dev);
|
||||
|
||||
nf2flowtab->num_flows -= num_uninst_flows;
|
||||
}
|
||||
|
||||
static void
|
||||
nf2_destroy_flowtable(struct sw_table *flowtab)
|
||||
{
|
||||
struct nf2_flowtable *nf2flowtab = (struct nf2_flowtable *)flowtab;
|
||||
struct nf2_flow *nf2flow = NULL;
|
||||
|
||||
if (nf2flowtab == NULL)
|
||||
return;
|
||||
|
||||
while (!list_is_empty(&nf2flowtab->flows)) {
|
||||
struct sw_flow *flow
|
||||
= CONTAINER_OF(list_front(&nf2flowtab->flows),
|
||||
struct sw_flow, node);
|
||||
list_remove(&flow->node);
|
||||
if (flow->private) {
|
||||
nf2flow = (struct nf2_flow *)flow->private;
|
||||
|
||||
if (nf2flow->type == NF2_TABLE_EXACT) {
|
||||
nf2_add_free_exact(nf2flow);
|
||||
} else if (nf2flow->type == NF2_TABLE_WILDCARD) {
|
||||
nf2_add_free_wildcard(nf2flow);
|
||||
}
|
||||
flow->private = NULL;
|
||||
}
|
||||
flow_free(flow);
|
||||
}
|
||||
free(nf2flowtab);
|
||||
|
||||
nf2_destroy_exact_freelist();
|
||||
nf2_destroy_wildcard_freelist();
|
||||
}
|
||||
|
||||
static int
|
||||
nf2_iterate_flowtable(struct sw_table *flowtab, const struct sw_flow_key *key,
|
||||
uint16_t out_port, struct sw_table_position *position,
|
||||
int (*callback) (struct sw_flow *, void *),
|
||||
void *private)
|
||||
{
|
||||
unsigned long start;
|
||||
struct nf2_flowtable *nf2flowtab = (struct nf2_flowtable *)flowtab;
|
||||
struct sw_flow *flow;
|
||||
int error = 0;
|
||||
|
||||
start = ~position->private[0];
|
||||
LIST_FOR_EACH(flow, struct sw_flow, iter_node, &nf2flowtab->iter_flows) {
|
||||
if (flow->serial <= start
|
||||
&& flow_matches_2wild(key, &flow->key)
|
||||
&& flow_has_out_port(flow, out_port)) {
|
||||
error = callback(flow, private);
|
||||
if (error != 0) {
|
||||
position->private[0] = ~flow->serial;
|
||||
return error;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
static void
|
||||
nf2_get_flowstats(struct sw_table *flowtab, struct sw_table_stats *stats)
|
||||
{
|
||||
struct nf2_flowtable *nf2flowtab = (struct nf2_flowtable *)flowtab;
|
||||
struct nf2device *dev;
|
||||
unsigned long int num_matched = 0;
|
||||
unsigned long int num_missed = 0;
|
||||
|
||||
dev = nf2_get_net_device();
|
||||
if (dev == NULL) {
|
||||
DBG_VERBOSE("Could not open NetFPGA device\n");
|
||||
} else {
|
||||
num_matched = nf2_get_matched_count(dev);
|
||||
num_missed = nf2_get_missed_count(dev);
|
||||
nf2_free_net_device(dev);
|
||||
}
|
||||
|
||||
stats->name = "nf2";
|
||||
stats->wildcards = OPENFLOW_WILDCARD_TABLE_SIZE
|
||||
- RESERVED_FOR_CPU2NETFPGA;
|
||||
stats->n_flows = nf2flowtab->num_flows;
|
||||
stats->max_flows = nf2flowtab->max_flows;
|
||||
stats->n_lookup = num_matched + num_missed;
|
||||
stats->n_matched = num_matched;
|
||||
}
|
||||
|
||||
static int
|
||||
nf2_get_portstats(of_hw_driver_t *hw_drv, int of_port,
|
||||
struct ofp_port_stats *stats)
|
||||
{
|
||||
int nf2_port;
|
||||
struct nf2_port_info *nf2portinfo;
|
||||
struct nf2device *dev;
|
||||
|
||||
if ((of_port > NF2_PORT_NUM) || (of_port <= 0)) {
|
||||
return 1;
|
||||
}
|
||||
nf2_port = of_port - 1;
|
||||
|
||||
nf2portinfo = calloc(1, sizeof(struct nf2_port_info));
|
||||
if (nf2portinfo == NULL) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
dev = nf2_get_net_device();
|
||||
if (dev == NULL) {
|
||||
free(nf2portinfo);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (nf2_get_port_info(dev, nf2_port, nf2portinfo)) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
stats->rx_packets = (uint64_t)(nf2portinfo->rx_q_num_pkts_stored);
|
||||
stats->rx_dropped = (uint64_t)(nf2portinfo->rx_q_num_pkts_dropped_full
|
||||
+ nf2portinfo->rx_q_num_pkts_dropped_bad);
|
||||
stats->rx_bytes = (uint64_t)(nf2portinfo->rx_q_num_bytes_pushed);
|
||||
stats->tx_packets = (uint64_t)(nf2portinfo->tx_q_num_pkts_sent);
|
||||
stats->tx_bytes = (uint64_t)(nf2portinfo->tx_q_num_bytes_pushed);
|
||||
|
||||
/* Not supported */
|
||||
stats->tx_dropped = -1;
|
||||
stats->rx_errors = -1;
|
||||
stats->tx_errors = -1;
|
||||
stats->rx_frame_err = -1;
|
||||
stats->rx_over_err = -1;
|
||||
stats->rx_crc_err = -1;
|
||||
stats->collisions = -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Create and initialize a new hardware datapath object
|
||||
*/
|
||||
|
||||
of_hw_driver_t *
|
||||
new_of_hw_driver(struct datapath *dp)
|
||||
{
|
||||
struct sw_table *sw_tab;
|
||||
of_hw_driver_t *hw_drv;
|
||||
struct nf2device *dev;
|
||||
struct nf2_flowtable *nf2flowtab;
|
||||
|
||||
dev = nf2_get_net_device();
|
||||
if (dev == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
nf2_reset_card(dev);
|
||||
nf2_free_net_device(dev);
|
||||
|
||||
nf2flowtab = calloc(1, sizeof(*nf2flowtab));
|
||||
if (nf2flowtab == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* These all point to the same place */
|
||||
hw_drv = &nf2flowtab->hw_driver;
|
||||
sw_tab = &hw_drv->sw_table;
|
||||
|
||||
sw_tab->n_lookup = 0;
|
||||
sw_tab->n_matched = 0;
|
||||
|
||||
/* Fill out the function pointers */
|
||||
sw_tab->lookup = nf2_lookup_flowtable;
|
||||
sw_tab->insert = nf2_install_flow;
|
||||
sw_tab->modify = nf2_modify_flow;
|
||||
sw_tab->has_conflict = nf2_has_conflict;
|
||||
|
||||
sw_tab->delete = nf2_uninstall_flow_wrap;
|
||||
sw_tab->timeout = nf2_flow_timeout;
|
||||
|
||||
sw_tab->destroy = nf2_destroy_flowtable;
|
||||
sw_tab->iterate = nf2_iterate_flowtable;
|
||||
sw_tab->stats = nf2_get_flowstats;
|
||||
|
||||
nf2flowtab->max_flows = OPENFLOW_NF2_EXACT_TABLE_SIZE
|
||||
+ OPENFLOW_WILDCARD_TABLE_SIZE - RESERVED_FOR_CPU2NETFPGA;
|
||||
nf2flowtab->num_flows = 0;
|
||||
list_init(&nf2flowtab->flows);
|
||||
list_init(&nf2flowtab->iter_flows);
|
||||
nf2flowtab->next_serial = 0;
|
||||
|
||||
if (nf2_init_wildcard_freelist()) {
|
||||
DBG_ERROR("Could not create wildcard freelist\n");
|
||||
free(nf2flowtab);
|
||||
return NULL;
|
||||
}
|
||||
if (nf2_write_static_wildcard()) {
|
||||
DBG_ERROR("Could not create wildcard freelist\n");
|
||||
free(nf2flowtab);
|
||||
return NULL;
|
||||
}
|
||||
if (nf2_init_exact_freelist()) {
|
||||
DBG_ERROR("Could not create exact freelist\n");
|
||||
free(nf2flowtab);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
hw_drv->table_stats_get = NULL;
|
||||
hw_drv->port_stats_get = nf2_get_portstats;
|
||||
hw_drv->flow_stats_get = NULL;
|
||||
hw_drv->aggregate_stats_get = NULL;
|
||||
|
||||
hw_drv->port_add = NULL;
|
||||
hw_drv->port_remove = NULL;
|
||||
hw_drv->port_link_get = NULL;
|
||||
hw_drv->port_enable_set = NULL;
|
||||
hw_drv->port_enable_get = NULL;
|
||||
hw_drv->port_queue_config = NULL;
|
||||
hw_drv->port_queue_remove = NULL;
|
||||
hw_drv->port_change_register = NULL;
|
||||
|
||||
hw_drv->packet_send = NULL;
|
||||
hw_drv->packet_receive_register = NULL;
|
||||
|
||||
hw_drv->ioctl = NULL;
|
||||
|
||||
return hw_drv;
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
/*-
|
||||
* Copyright (c) 2008, 2009, 2010
|
||||
* The Board of Trustees of The Leland Stanford Junior University
|
||||
*
|
||||
* We are making the OpenFlow specification and associated documentation
|
||||
* (Software) available for public use and benefit with the expectation that
|
||||
* others will use, modify and enhance the Software and contribute those
|
||||
* enhancements back to the community. However, since we would like to make the
|
||||
* Software available for broadest use, with as few restrictions as possible
|
||||
* permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this Software to deal in the Software under the copyrights without
|
||||
* restriction, including without limitation the rights to use, copy, modify,
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of the Software,
|
||||
* and to permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
* IN THE SOFTWARE.
|
||||
*
|
||||
* The name and trademarks of copyright holder(s) may NOT be used in
|
||||
* advertising or publicity pertaining to the Software or any derivatives
|
||||
* without specific, written prior permission.
|
||||
*/
|
||||
|
||||
#ifndef HWTABLE_NF2_NF2_FLOWTABLE_
|
||||
#define HWTABLE_NF2_NF2_FLOWTABLE_
|
||||
|
||||
#define RESERVED_FOR_CPU2NETFPGA 8
|
||||
|
||||
struct nf2_flow {
|
||||
struct list node;
|
||||
uint32_t pos;
|
||||
uint32_t type;
|
||||
uint32_t hw_packet_count;
|
||||
uint32_t hw_byte_count;
|
||||
};
|
||||
|
||||
enum nf2_of_table_type {
|
||||
NF2_TABLE_EXACT,
|
||||
NF2_TABLE_WILDCARD
|
||||
};
|
||||
|
||||
/* Remove the commentout of the following 'define' line
|
||||
* if you want to enable NetFPGA watchdog timer capability.
|
||||
*/
|
||||
/* #define NF2_WATCHDOG 1 */
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,452 @@
|
||||
/* ****************************************************************************
|
||||
* $Id: nf2.h 5575 2009-05-13 18:44:26Z grg $
|
||||
*
|
||||
* Module: nf2.h
|
||||
* Project: NetFPGA 2 Linux Kernel Driver
|
||||
* Description: Header file for kernel driver
|
||||
*
|
||||
* Change history:
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _NF2_H
|
||||
#define _NF2_H 1
|
||||
|
||||
#define NF2_DEV_NAME "nf2"
|
||||
|
||||
/* Include for socket IOCTLs */
|
||||
#include <linux/sockios.h>
|
||||
|
||||
/* Maximum number of interfaces */
|
||||
#ifndef MAX_IFACE
|
||||
#define MAX_IFACE 4
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Register names and locations.
|
||||
*
|
||||
* Note that these names are not necessarily identical to
|
||||
* those in NF2/hw/common/src/defines
|
||||
*/
|
||||
|
||||
/* CPCI registers */
|
||||
#define CPCI_REG_ID 0x000
|
||||
#define CPCI_REG_BOARD_ID 0x004
|
||||
#define CPCI_REG_CTRL 0x008
|
||||
#define CPCI_REG_RESET 0x00c
|
||||
#define CPCI_REG_ERROR 0x010
|
||||
#define CPCI_REG_DUMMY 0x020
|
||||
#define CPCI_REG_INTERRUPT_MASK 0x040
|
||||
#define CPCI_REG_INTERRUPT_STATUS 0x044
|
||||
#define CPCI_REG_PROG_DATA 0x100
|
||||
#define CPCI_REG_PROG_STATUS 0x104
|
||||
#define CPCI_REG_PROG_CTRL 0x108
|
||||
#define CPCI_REG_DMA_I_ADDR 0x140
|
||||
#define CPCI_REG_DMA_E_ADDR 0x144
|
||||
#define CPCI_REG_DMA_I_SIZE 0x148
|
||||
#define CPCI_REG_DMA_E_SIZE 0x14c
|
||||
#define CPCI_REG_DMA_I_CTRL 0x150
|
||||
#define CPCI_REG_DMA_E_CTRL 0x154
|
||||
#define CPCI_REG_DMA_MAX_XFER_TIME 0x180
|
||||
#define CPCI_REG_DMA_MAX_RETRIES 0x184
|
||||
#define CPCI_REG_CNET_MAX_XFER_TIME 0x188
|
||||
#define CPCI_REG_DMA_I_PKT_CNT 0x400
|
||||
#define CPCI_REG_DMA_E_PKT_CNT 0x404
|
||||
#define CPCI_REG_CPCI_REG_RD_CNT 0x408
|
||||
#define CPCI_REG_CPCI_REG_WR_CNT 0x40c
|
||||
#define CPCI_REG_CNET_REG_RD_CNT 0x410
|
||||
#define CPCI_REG_CNET_REG_WR_CNT 0x414
|
||||
|
||||
#define CPCI_REG_N_CLK_COUNT 0x500
|
||||
#define CPCI_REG_P_MAX 0x504
|
||||
#define CPCI_REG_N_EXP 0x508
|
||||
#define CPCI_REG_P_CLK_CTR 0x510
|
||||
#define CPCI_REG_RESET_CTR 0x520
|
||||
|
||||
|
||||
|
||||
/* Base address for CNET registers */
|
||||
#define CNET_REG_BASE 0x400000
|
||||
|
||||
|
||||
/* Added by nweaver for building memory manipulation
|
||||
utilities */
|
||||
/* 2 MB SRAM size on current board, MAX and SIZE will
|
||||
need to be changed if upgraded to 4 MB SRAMs */
|
||||
#define SRAM_SIZE 0x200000
|
||||
|
||||
#define SRAM_1_BASE 0x800000
|
||||
#define SRAM_1_MAX 0x9FFFFF
|
||||
|
||||
#define SRAM_2_BASE 0xC00000
|
||||
#define SRAM_2_MAX 0xDFFFFF
|
||||
/* end nweaver addition */
|
||||
|
||||
|
||||
/* Device ID registers */
|
||||
#define NF2_DEVICE_ID 0x0400000
|
||||
#define NF2_REVISION 0x0400004
|
||||
#define NF2_DEVICE_STR 0x0400008
|
||||
|
||||
|
||||
/* CNET registers */
|
||||
#define CNET_REG_ID (CNET_REG_BASE + 0x000)
|
||||
#define CNET_REG_CTRL (CNET_REG_BASE + 0x004)
|
||||
#define CNET_REG_RESET (CNET_REG_BASE + 0x008)
|
||||
#define CNET_REG_ERROR (CNET_REG_BASE + 0x00C)
|
||||
#define CNET_REG_ENABLE (CNET_REG_BASE + 0x010)
|
||||
#define CNET_REG_WR_SRAM1_EOP (CNET_REG_BASE + 0x0F0)
|
||||
#define CNET_REG_RD_SRAM1_EOP (CNET_REG_BASE + 0x0F4)
|
||||
#define CNET_REG_WR_SRAM2_EOP (CNET_REG_BASE + 0x0F8)
|
||||
#define CNET_REG_RD_SRAM2_EOP (CNET_REG_BASE + 0x0FC)
|
||||
#define CNET_REG_MF_STATUS_0 (CNET_REG_BASE + 0x100)
|
||||
#define CNET_REG_MF_TX_PKTS_SENT_0 (CNET_REG_BASE + 0x104)
|
||||
#define CNET_REG_MF_RX_PKTS_RCVD_0 (CNET_REG_BASE + 0x108)
|
||||
#define CNET_REG_MF_RX_PKTS_LOST_0 (CNET_REG_BASE + 0x10C)
|
||||
#define CNET_REG_MAC_CONFIG_0 (CNET_REG_BASE + 0x110)
|
||||
#define CNET_REG_MF_STATUS_1 (CNET_REG_BASE + 0x140)
|
||||
#define CNET_REG_MF_TX_PKTS_SENT_1 (CNET_REG_BASE + 0x144)
|
||||
#define CNET_REG_MF_RX_PKTS_RCVD_1 (CNET_REG_BASE + 0x148)
|
||||
#define CNET_REG_MF_RX_PKTS_LOST_1 (CNET_REG_BASE + 0x14C)
|
||||
#define CNET_REG_MAC_CONFIG_1 (CNET_REG_BASE + 0x150)
|
||||
#define CNET_REG_MF_STATUS_2 (CNET_REG_BASE + 0x180)
|
||||
#define CNET_REG_MF_TX_PKTS_SENT_2 (CNET_REG_BASE + 0x184)
|
||||
#define CNET_REG_MF_RX_PKTS_RCVD_2 (CNET_REG_BASE + 0x188)
|
||||
#define CNET_REG_MF_RX_PKTS_LOST_2 (CNET_REG_BASE + 0x18C)
|
||||
#define CNET_REG_MAC_CONFIG_2 (CNET_REG_BASE + 0x190)
|
||||
#define CNET_REG_MF_STATUS_3 (CNET_REG_BASE + 0x1C0)
|
||||
#define CNET_REG_MF_TX_PKTS_SENT_3 (CNET_REG_BASE + 0x1C4)
|
||||
#define CNET_REG_MF_RX_PKTS_RCVD_3 (CNET_REG_BASE + 0x1C8)
|
||||
#define CNET_REG_MF_RX_PKTS_LOST_3 (CNET_REG_BASE + 0x1CC)
|
||||
#define CNET_REG_MAC_CONFIG_3 (CNET_REG_BASE + 0x1D0)
|
||||
#define CNET_REG_RXQ_NUM_PKTS_0 (CNET_REG_BASE + 0x200)
|
||||
#define CNET_REG_RXQ_POINTERS_0 (CNET_REG_BASE + 0x204)
|
||||
#define CNET_REG_RXQ_NUM_PKTS_1 (CNET_REG_BASE + 0x240)
|
||||
#define CNET_REG_RXQ_POINTERS_1 (CNET_REG_BASE + 0x244)
|
||||
#define CNET_REG_RXQ_NUM_PKTS_2 (CNET_REG_BASE + 0x280)
|
||||
#define CNET_REG_RXQ_POINTERS_2 (CNET_REG_BASE + 0x284)
|
||||
#define CNET_REG_RXQ_NUM_PKTS_3 (CNET_REG_BASE + 0x2C0)
|
||||
#define CNET_REG_RXQ_POINTERS_3 (CNET_REG_BASE + 0x2C4)
|
||||
|
||||
#define CNET_REG_MF_RX_PKTS_LOST_BAD_FCS_0 (CNET_REG_BASE + 0x114)
|
||||
#define CNET_REG_MF_RX_PKTS_LOST_FULL_FIFO_0 (CNET_REG_BASE+0x118)
|
||||
#define CNET_REG_MF_RX_GOOD_PKTS_RCVD_0 (CNET_REG_BASE+0x11C)
|
||||
#define CNET_REG_MF_RX_GOOD_BYTES_RCVD_0 (CNET_REG_BASE+0x120)
|
||||
#define CNET_REG_MF_TX_BYTES_SENT_0 (CNET_REG_BASE+0x124)
|
||||
#define CNET_REG_MF_RX_PKTS_LOST_BAD_FCS_1 (CNET_REG_BASE+0x154)
|
||||
#define CNET_REG_MF_RX_PKTS_LOST_FULL_FIFO_1 (CNET_REG_BASE+0x158)
|
||||
#define CNET_REG_MF_RX_GOOD_PKTS_RCVD_1 (CNET_REG_BASE+0x15C)
|
||||
#define CNET_REG_MF_RX_GOOD_BYTES_RCVD_1 (CNET_REG_BASE+0x160)
|
||||
#define CNET_REG_MF_TX_BYTES_SENT_1 (CNET_REG_BASE+0x164)
|
||||
#define CNET_REG_MF_RX_PKTS_LOST_BAD_FCS_2 (CNET_REG_BASE+0x194)
|
||||
#define CNET_REG_MF_RX_PKTS_LOST_FULL_FIFO_2 (CNET_REG_BASE+0x198)
|
||||
#define CNET_REG_MF_RX_GOOD_PKTS_RCVD_2 (CNET_REG_BASE+0x19C)
|
||||
#define CNET_REG_MF_RX_GOOD_BYTES_RCVD_2 (CNET_REG_BASE+0x1A0)
|
||||
#define CNET_REG_MF_TX_BYTES_SENT_2 (CNET_REG_BASE+0x1A4)
|
||||
#define CNET_REG_MF_RX_PKTS_LOST_BAD_FCS_3 (CNET_REG_BASE+0x1D4)
|
||||
#define CNET_REG_MF_RX_PKTS_LOST_FULL_FIFO_3 (CNET_REG_BASE+0x1D8)
|
||||
#define CNET_REG_MF_RX_GOOD_PKTS_RCVD_3 (CNET_REG_BASE+0x1DC)
|
||||
#define CNET_REG_MF_RX_GOOD_BYTES_RCVD_3 (CNET_REG_BASE+0x1E0)
|
||||
#define CNET_REG_MF_TX_BYTES_SENT_3 (CNET_REG_BASE+0x1E4)
|
||||
|
||||
#define CNET_MAC_CLK_CHK_CTRL (CNET_REG_BASE + 0xF00)
|
||||
#define CNET_MAC_CLK_CHK_CNT_VALUE (CNET_REG_BASE + 0xF04)
|
||||
|
||||
|
||||
/* Base address for CNET PHY registers */
|
||||
#define PHY_REG_BASE 0x600000
|
||||
|
||||
#define PHY_REG_CMD (PHY_REG_BASE)
|
||||
#define PHY_REG_STATUS (PHY_REG_BASE)
|
||||
|
||||
/*
|
||||
* CPCI register masks
|
||||
*/
|
||||
|
||||
/* ID Masks */
|
||||
#define ID_VERSION 0x00FFFFFF
|
||||
#define ID_REVISION 0xFF000000
|
||||
|
||||
/* Board ID Masks */
|
||||
#define BOARD_ID 0x00000F00
|
||||
#define BOARD_ID_CONTROL 0x00000001
|
||||
|
||||
/* Control masks */
|
||||
#define CTRL_CNET_RESET 0x00000100
|
||||
#define CTRL_LED 0x00000001
|
||||
|
||||
/* RESET masks */
|
||||
#define RESET_CPCI 0x00000001
|
||||
|
||||
/* Error masks */
|
||||
#define ERR_CNET_READ_TIMEOUT 0x02000000
|
||||
#define ERR_CNET_ERROR 0x01000000
|
||||
#define ERR_PROG_BUF_OVERFLOW 0x00020000
|
||||
#define ERR_PROG_ERROR 0x00010000
|
||||
#define ERR_DMA_TIMEOUT 0x00000400
|
||||
#define ERR_DMA_RETRY_CNT_EXPIRED 0x00000200
|
||||
#define ERR_DMA_BUF_OVERFLOW 0x00000100
|
||||
#define ERR_DMA_RD_SIZE_ERROR 0x00000040
|
||||
#define ERR_DMA_WR_SIZE_ERROR 0x00000020
|
||||
#define ERR_DMA_RD_ADDR_ERROR 0x00000010
|
||||
#define ERR_DMA_WR_ADDR_ERROR 0x00000008
|
||||
#define ERR_DMA_RD_MAC_ERROR 0x00000004
|
||||
#define ERR_DMA_WR_MAC_ERROR 0x00000002
|
||||
#define ERR_DMA_FATAL_ERROR 0x00000001
|
||||
|
||||
#define ERR_DMA_SETUP_ERROR ( ERR_DMA_WR_MAC_ERROR | \
|
||||
ERR_DMA_RD_MAC_ERROR | \
|
||||
ERR_DMA_WR_ADDR_ERROR | \
|
||||
ERR_DMA_RD_ADDR_ERROR | \
|
||||
ERR_DMA_WR_SIZE_ERROR | \
|
||||
ERR_DMA_RD_SIZE_ERROR )
|
||||
|
||||
|
||||
/* Interrupt masks */
|
||||
#define INT_DMA_RX_COMPLETE 0x80000000
|
||||
#define INT_DMA_TX_COMPLETE 0x40000000
|
||||
#define INT_PHY_INTERRUPT 0x20000000
|
||||
#define INT_PKT_AVAIL 0x00000100
|
||||
#define INT_CNET_ERROR 0x00000020
|
||||
#define INT_CNET_READ_TIMEOUT 0x00000010
|
||||
#define INT_PROG_ERROR 0x00000008
|
||||
#define INT_DMA_TRANSFER_ERROR 0x00000004
|
||||
#define INT_DMA_SETUP_ERROR 0x00000002
|
||||
#define INT_DMA_FATAL_ERROR 0x00000001
|
||||
|
||||
#define INT_UNKNOWN ~(INT_DMA_RX_COMPLETE | \
|
||||
INT_DMA_TX_COMPLETE | \
|
||||
INT_PHY_INTERRUPT | \
|
||||
INT_PKT_AVAIL | \
|
||||
INT_CNET_ERROR | \
|
||||
INT_CNET_READ_TIMEOUT | \
|
||||
INT_PROG_ERROR | \
|
||||
INT_DMA_TRANSFER_ERROR | \
|
||||
INT_DMA_SETUP_ERROR | \
|
||||
INT_DMA_FATAL_ERROR)
|
||||
|
||||
/* Programming status */
|
||||
#define PROG_INIT 0x00010000
|
||||
#define PROG_DONE 0x00000100
|
||||
#define PROG_FIFO_EMPTY 0x00000002
|
||||
#define PROG_IN_PROGRESS 0x00000001
|
||||
|
||||
/* Programming control */
|
||||
#define PROG_CTRL_RESET 0x00000001
|
||||
|
||||
/* DMA control */
|
||||
#define DMA_CTRL_MAC 0x00000300
|
||||
#define DMA_CTRL_OWNER 0x00000001
|
||||
|
||||
/*
|
||||
* CNET register masks
|
||||
*/
|
||||
|
||||
/* Reset masks */
|
||||
#define CNET_RESET_MAC 0x0000000F
|
||||
#define CNET_RESET_MAC_3 0x00000008
|
||||
#define CNET_RESET_MAC_2 0x00000004
|
||||
#define CNET_RESET_MAC_1 0x00000002
|
||||
#define CNET_RESET_MAC_0 0x00000001
|
||||
|
||||
/* Error masks */
|
||||
#define CNET_ERROR_TX_UNDERRUN_MAC 0x000000F0
|
||||
#define CNET_ERROR_TX_UNDERRUN_MAC_3 0x00000080
|
||||
#define CNET_ERROR_TX_UNDERRUN_MAC_2 0x00000040
|
||||
#define CNET_ERROR_TX_UNDERRUN_MAC_1 0x00000020
|
||||
#define CNET_ERROR_TX_UNDERRUN_MAC_0 0x00000010
|
||||
#define CNET_ERROR_TX_OVERRUN_MAC 0x0000000F
|
||||
#define CNET_ERROR_TX_OVERRUN_MAC_3 0x00000008
|
||||
#define CNET_ERROR_TX_OVERRUN_MAC_2 0x00000004
|
||||
#define CNET_ERROR_TX_OVERRUN_MAC_1 0x00000002
|
||||
#define CNET_ERROR_TX_OVERRUN_MAC_0 0x00000001
|
||||
|
||||
/* Enable masks */
|
||||
#define CNET_ENABLE_RX_FIFO 0x0000F000
|
||||
#define CNET_ENABLE_RX_FIFO_3 0x00008000
|
||||
#define CNET_ENABLE_RX_FIFO_2 0x00004000
|
||||
#define CNET_ENABLE_RX_FIFO_1 0x00002000
|
||||
#define CNET_ENABLE_RX_FIFO_0 0x00001000
|
||||
#define CNET_ENABLE_TX_MAC 0x00000F00
|
||||
#define CNET_ENABLE_TX_MAC_3 0x00000800
|
||||
#define CNET_ENABLE_TX_MAC_2 0x00000400
|
||||
#define CNET_ENABLE_TX_MAC_1 0x00000200
|
||||
#define CNET_ENABLE_TX_MAC_0 0x00000100
|
||||
#define CNET_ENABLE_DEBUG_TRISTATE 0x00000004
|
||||
#define CNET_ENABLE_INGRESS_ARBITER 0x00000002
|
||||
#define CNET_ENABLE_RX_DMA 0x00000001
|
||||
|
||||
/* MF Status masks */
|
||||
#define CNET_MF_STATUS_RX_FIFO_EMPTY 0x02000000
|
||||
#define CNET_MF_STATUS_RX_PKT_AVAIL 0x01000000
|
||||
#define CNET_MF_STATUS_RX_NUM_PKTS 0x00FF0000
|
||||
#define CNET_MF_STATUS_TX_FIFO_FULL 0x00000200
|
||||
#define CNET_MF_STATUS_TX_FIFO_NO_MAX_PKT 0x00000100
|
||||
#define CNET_MF_STATUS_TX_NUM_PKTS 0x000000FF
|
||||
|
||||
/* MAC Config masks */
|
||||
#define CNET_MAC_CFG_FULL_DUPLEX 0x00000020
|
||||
#define CNET_MAC_CFG_TX_FCS_SUPPLIED 0x00000010
|
||||
#define CNET_MAC_CFG_RX_WANT_FCS 0x00000008
|
||||
#define CNET_MAC_CFG_JUMBO_ENABLE 0x00000004
|
||||
|
||||
#define CNET_MAC_CFG_SPEED 0x00000002
|
||||
#define CNET_MAC_CFG_1000_MBPS 0x00000002
|
||||
#define CNET_MAC_CFG_100_MBPS 0x00000001
|
||||
#define CNET_MAC_CFG_10_MBPS 0x00000000
|
||||
|
||||
#define CNET_RXQ_WR_PTR 0x00FF0000
|
||||
#define CNET_RXQ_RD_PTR 0x000000FF
|
||||
|
||||
|
||||
/* Phy register masks */
|
||||
#define PHY_RD_WR 0x80000000
|
||||
#define PHY_PHY 0x03000000
|
||||
#define PHY_ADDR 0x001F0000
|
||||
#define PHY_DATA 0x0000FFFF
|
||||
|
||||
#define PHY_DONE 0x80000000
|
||||
#define PHY_DONE_CNT 0x001F0000
|
||||
|
||||
/* Defines to calculate register values */
|
||||
/* CPCI Funcs */
|
||||
#define NF2_GET_VERSION(x) (x & 0xFFFFFF)
|
||||
#define NF2_GET_REVISION(x) ((x & 0xFF000000) >> 24)
|
||||
|
||||
#define NF2_GET_BOARD_ID(x) ((x & BOARD_ID) >> 8)
|
||||
#define NF2_GET_CONTROL(x) (x & BOARD_ID_CONTROL)
|
||||
|
||||
#define NF2_GET_CNET_RESET(x) ((x & CTRL_CNET_RESET) >> 8)
|
||||
#define NF2_GET_LED(x) (x & CTRL_LED)
|
||||
|
||||
#define NF2_GET_RESET(x) (x & RESET_CPCI)
|
||||
|
||||
#define NF2_GET_CNET_READ_TIMEOUT(x) ((x & ERR_CNET_READ_TIMEOUT) >> 25)
|
||||
#define NF2_GET_CNET_ERROR(x) ((x & ERR_CNET_ERROR) >> 24)
|
||||
#define NF2_GET_PROG_BUF_OVERFLOW(x) ((x & ERR_PROG_BUF_OVERFLOW) >> 12)
|
||||
#define NF2_GET_PROG_ERROR(x) ((x & ERR_PROG_ERROR) >> 11)
|
||||
#define NF2_GET_DMA_TIMEOUT(x) ((x & ERR_DMA_TIMEOUT) >> 10)
|
||||
#define NF2_GET_DMA_RETRY_CNT_EXPIRED(x) \
|
||||
((x & ERR_DMA_RETRY_CNT_EXPIRED) >> 9)
|
||||
#define NF2_GET_DMA_BUF_OVERFLOW(x) ((x & ERR_DMA_BUF_OVERFLOW) >> 8)
|
||||
#define NF2_GET_DMA_RD_SIZE_ERROR(x) ((x & ERR_DMA_RD_SIZE_ERROR) >> 6)
|
||||
#define NF2_GET_DMA_WR_SIZE_ERROR(x) ((x & ERR_DMA_WR_SIZE_ERROR) >> 5)
|
||||
#define NF2_GET_DMA_RD_ADDR_ERROR(x) ((x & ERR_DMA_RD_ADDR_ERROR) >> 4)
|
||||
#define NF2_GET_DMA_WR_ADDR_ERROR(x) ((x & ERR_DMA_WR_ADDR_ERROR) >> 3)
|
||||
#define NF2_GET_DMA_RD_MAC_ERROR(x) ((x & ERR_DMA_RD_MAC_ERROR) >> 2)
|
||||
#define NF2_GET_DMA_WR_MAC_ERROR(x) ((x & ERR_DMA_WR_MAC_ERROR) >> 1)
|
||||
#define NF2_GET_DMA_FATAL_ERROR(x) (x & ERR_DMA_FATAL_ERROR)
|
||||
|
||||
#define NF2_GET_INT_DMA_TX_COMPLETE(x) ((x & INT_DMA_TX_COMPLETE) >> 31)
|
||||
#define NF2_GET_INT_DMA_RX_COMPLETE(x) ((x & INT_DMA_RX_COMPLETE) >> 30)
|
||||
#define NF2_GET_INT_PHY_INTERRUPT(x) ((x & INT_PHY_INTERRUPT) >> 29)
|
||||
#define NF2_GET_INT_PKT_AVAIL(x) ((x & INT_PKT_AVAIL) >> 8)
|
||||
#define NF2_GET_INT_CNET_ERROR(x) ((x & INT_CNET_ERROR) >> 5)
|
||||
#define NF2_GET_INT_CNET_READ_TIMEOUT(x) \
|
||||
((x & INT_CNET_READ_TIMEOUT) >> 4)
|
||||
#define NF2_GET_INT_PROG_ERROR(x) ((x & INT_PROG_ERROR) >> 3)
|
||||
#define NF2_GET_INT_DMA_TRANSFER_ERROR(x) \
|
||||
((x & INT_DMA_TRANSFER_ERROR) >> 2)
|
||||
#define NF2_GET_INT_DMA_SETUP_ERROR(x) ((x & INT_DMA_SETUP_ERROR) >> 1)
|
||||
#define NF2_GET_INT_DMA_FATAL_ERROR(x) (x & INT_DMA_FATAL_ERROR)
|
||||
|
||||
#define NF2_GET_PROG_INIT(x) ((x & PROG_INIT) >> 16)
|
||||
#define NF2_GET_PROG_DONE(x) ((x & PROG_DONE) >> 8)
|
||||
#define NF2_GET_PROG_FIFO_EMPTY(x) ((x & PROG_FIFO_EMPTY) >> 1)
|
||||
#define NF2_GET_PROG_IN_PROGRESS(x) (x & PROG_IN_PROGRESS)
|
||||
|
||||
#define NF2_GET_DMA_CTRL_MAC(x) ((x & DMA_CTRL_MAC) >> 8)
|
||||
#define NF2_GET_DMA_CTRL_OWNER(x) (x & DMA_CTRL_OWNER)
|
||||
|
||||
#define NF2_SET_DMA_CTRL_MAC(x) (x << 8)
|
||||
|
||||
|
||||
/* CNET Funcs */
|
||||
#define NF2_GET_CNET_VERSION(x) ((x & 0xFFFF0000) >> 16)
|
||||
#define NF2_GET_CNET_DEVICE_ID(x) (x & 0xFFFF)
|
||||
|
||||
#define NF2_GET_CNET_RESET_MAC(x) (x & CNET_RESET_MAC)
|
||||
|
||||
#define NF2_GET_CNET_ERROR_TX_UNDERRUN_MAC(x) \
|
||||
((x & CNET_ERROR_TX_UNDERRUN_MAC) >> 4)
|
||||
#define NF2_GET_CNET_ERROR_TX_OVERRUN_MAC(x) \
|
||||
(x & CNET_ERROR_TX_OVERRUN_MAC)
|
||||
|
||||
#define NF2_GET_CNET_ENABLE_RX_FIFO(x) ((x & CNET_ENABLE_RX_FIFO) >> 12)
|
||||
#define NF2_GET_CNET_ENABLE_TX_MAC(x) ((x & CNET_ENABLE_TX_MAC) >> 8)
|
||||
#define NF2_GET_CNET_ENABLE_DEBUG_TRISTATE(x) \
|
||||
((x & CNET_ENABLE_DEBUG_TRISTATE) >> 2)
|
||||
#define NF2_GET_CNET_ENABLE_INGRESS_ARBITER(x) \
|
||||
((x & CNET_ENABLE_INGRESS_ARBITER) >> 1)
|
||||
#define NF2_GET_CNET_ENABLE_RX_DMA(x) (x & CNET_ENABLE_RX_DMA)
|
||||
|
||||
#define NF2_GET_CNET_MF_STATUS_RX_FIFO_EMPTY(x) \
|
||||
((x & CNET_MF_STATUS_RX_FIFO_EMPTY) >> 25)
|
||||
#define NF2_GET_CNET_MF_STATUS_RX_PKT_AVAIL(x) \
|
||||
((x & CNET_MF_STATUS_RX_PKT_AVAIL) >> 24)
|
||||
#define NF2_GET_CNET_MF_STATUS_RX_NUM_PKTS(x) \
|
||||
((x & CNET_MF_STATUS_RX_NUM_PKTS) >> 16)
|
||||
#define NF2_GET_CNET_MF_STATUS_TX_FIFO_FULL(x) \
|
||||
((x & CNET_MF_STATUS_TX_FIFO_FULL) >> 9)
|
||||
#define NF2_GET_CNET_MF_STATUS_TX_FIFO_NO_MAX_PKT(x) \
|
||||
((x & CNET_MF_STATUS_TX_FIFO_NO_MAX_PKT) >> 8)
|
||||
#define NF2_GET_CNET_MF_STATUS_TX_NUM_PKTS(x) \
|
||||
(x & CNET_MF_STATUS_TX_NUM_PKTS)
|
||||
|
||||
#define NF2_GET_CNET_MAC_CFG_FULL_DUPLEX(x) \
|
||||
((x & CNET_MAC_CFG_FULL_DUPLEX) >> 5)
|
||||
#define NF2_GET_CNET_MAC_CFG_TX_FCS_SUPPLIED(x) \
|
||||
((x & CNET_MAC_CFG_TX_FCS_SUPPLIED) >> 4)
|
||||
#define NF2_GET_CNET_MAC_CFG_RX_WANT_FCS(x) \
|
||||
((x & CNET_MAC_CFG_RX_WANT_FCS) >> 3)
|
||||
#define NF2_GET_CNET_MAC_CFG_JUMBO_ENABLE(x) \
|
||||
((x & CNET_MAC_CFG_JUMBO_ENABLE) >> 2)
|
||||
#define NF2_GET_CNET_MAC_CFG_SPEED(x) \
|
||||
(x & CNET_MAC_CFG_SPEED)
|
||||
|
||||
#define NF2_GET_CNET_RXQ_WR_PTR(x) ((x & CNET_RXQ_WR_PTR) >> 16)
|
||||
#define NF2_GET_CNET_RXQ_RD_PTR(x) (x & CNET_RXQ_RD_PTR)
|
||||
|
||||
|
||||
/* PHY functions */
|
||||
#define NF2_SET_PHY_IS_READ(x) (x << 31)
|
||||
#define NF2_SET_PHY_SELECT(x) (x << 24)
|
||||
#define NF2_SET_PHY_ADDR(x) (x << 16)
|
||||
#define NF2_SET_PHY_DATA(x) (x)
|
||||
|
||||
#define NF2_GET_PHY_DATA(x) (x & PHY_DATA)
|
||||
#define NF2_GET_PHY_DONE(x) ((x & PHY_DONE) >> 31)
|
||||
#define NF2_GET_PHY_DONE_CNT(x) ((x & PHY_DONE_CNT) >> 16)
|
||||
|
||||
|
||||
/*
|
||||
* IOCTLs
|
||||
*/
|
||||
#define SIOCREGREAD SIOCDEVPRIVATE
|
||||
#define SIOCREGWRITE (SIOCDEVPRIVATE + 1)
|
||||
|
||||
|
||||
/* MDIO registers */
|
||||
#define MDIO_0_AUX_STATUS 0x04c0064
|
||||
#define MDIO_0_INTR_STATUS 0x04c0068
|
||||
#define MDIO_0_INTR_MASK 0x04c006c
|
||||
|
||||
|
||||
/* MDIO address delta between each phy base address */
|
||||
#define ADDRESS_DELTA 0x80
|
||||
|
||||
|
||||
/* MDIO bit positions */
|
||||
#define INTR_LINK_STATUS_POS 0x2
|
||||
#define AUX_LINK_STATUS_POS 0x4
|
||||
|
||||
|
||||
/*
|
||||
* Structure for transferring register data via an IOCTL
|
||||
*/
|
||||
struct nf2reg {
|
||||
unsigned int reg;
|
||||
unsigned int val;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,847 @@
|
||||
/*-
|
||||
* Copyright (c) 2008, 2009, 2010
|
||||
* The Board of Trustees of The Leland Stanford Junior University
|
||||
*
|
||||
* We are making the OpenFlow specification and associated documentation
|
||||
* (Software) available for public use and benefit with the expectation that
|
||||
* others will use, modify and enhance the Software and contribute those
|
||||
* enhancements back to the community. However, since we would like to make the
|
||||
* Software available for broadest use, with as few restrictions as possible
|
||||
* permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this Software to deal in the Software under the copyrights without
|
||||
* restriction, including without limitation the rights to use, copy, modify,
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of the Software,
|
||||
* and to permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
* IN THE SOFTWARE.
|
||||
*
|
||||
* The name and trademarks of copyright holder(s) may NOT be used in
|
||||
* advertising or publicity pertaining to the Software or any derivatives
|
||||
* without specific, written prior permission.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "udatapath/switch-flow.h"
|
||||
#include "udatapath/table.h"
|
||||
#include "timeval.h"
|
||||
#include "reg_defines_openflow_switch.h"
|
||||
#include "nf2.h"
|
||||
#include "nf2util.h"
|
||||
#include "hw_flow.h"
|
||||
#include "nf2_hwapi.h"
|
||||
#include "nf2_lib.h"
|
||||
#include "debug.h"
|
||||
|
||||
static void log_entry(nf2_of_entry_wrap *);
|
||||
static void log_entry_raw(nf2_of_entry_wrap *);
|
||||
static void log_mask(nf2_of_mask_wrap *);
|
||||
static void log_mask_raw(nf2_of_mask_wrap *);
|
||||
static void log_action(nf2_of_action_wrap *);
|
||||
static void log_action_raw(nf2_of_action_wrap *);
|
||||
static void log_watchdog_info(struct nf2device *);
|
||||
static void nf2_get_all_ports_info_addr(struct nf2_all_ports_info_addr *);
|
||||
|
||||
static void
|
||||
log_entry(nf2_of_entry_wrap *entry)
|
||||
{
|
||||
int i;
|
||||
|
||||
DBG_VERBOSE("log entry\n");
|
||||
#ifdef HWTABLE_NO_DEBUG
|
||||
return;
|
||||
#else
|
||||
|
||||
// Log the physical source port
|
||||
DBG_VERBOSE("E psrc[%i] ", entry->entry.src_port / 2);
|
||||
|
||||
// Log the link layer source
|
||||
DBG_VERBOSE("dlsrc[");
|
||||
for (i = 5; i > 0; --i) {
|
||||
DBG_VERBOSE("%0X:", entry->entry.eth_src[i]);
|
||||
}
|
||||
DBG_VERBOSE("%0X] ", entry->entry.eth_src[0]);
|
||||
|
||||
// Log the link layer dest
|
||||
DBG_VERBOSE("dldst[");
|
||||
for (i = 5; i > 0; --i) {
|
||||
DBG_VERBOSE("%0X:", entry->entry.eth_dst[i]);
|
||||
}
|
||||
DBG_VERBOSE("%0X] ", entry->entry.eth_dst[0]);
|
||||
|
||||
// Log the link layer type
|
||||
DBG_VERBOSE("dltype[%0X] ", entry->entry.eth_type);
|
||||
|
||||
// Log the link layer vlan
|
||||
DBG_VERBOSE("dlvlan[%0X] ", entry->entry.vlan_id);
|
||||
|
||||
// Log the network source
|
||||
DBG_VERBOSE("nwsrc[");
|
||||
DBG_VERBOSE("%0i.", (entry->entry.ip_src >> 24) & 0xFF);
|
||||
DBG_VERBOSE("%0i.", (entry->entry.ip_src >> 16) & 0xFF);
|
||||
DBG_VERBOSE("%0i.", (entry->entry.ip_src >> 8) & 0xFF);
|
||||
DBG_VERBOSE("%0i", entry->entry.ip_src & 0xFF);
|
||||
DBG_VERBOSE("] ");
|
||||
|
||||
// Log the network dest
|
||||
DBG_VERBOSE("nwdst[");
|
||||
DBG_VERBOSE("%0i.", (entry->entry.ip_dst >> 24) & 0xFF);
|
||||
DBG_VERBOSE("%0i.", (entry->entry.ip_dst >> 16) & 0xFF);
|
||||
DBG_VERBOSE("%0i.", (entry->entry.ip_dst >> 8) & 0xFF);
|
||||
DBG_VERBOSE("%0i", entry->entry.ip_dst & 0xFF);
|
||||
DBG_VERBOSE("] ");
|
||||
|
||||
// Log the network TOS
|
||||
DBG_VERBOSE("nwtos[0x%0X] ", entry->entry.ip_tos);
|
||||
|
||||
// Log the transport source port
|
||||
DBG_VERBOSE("tsrc[%i] ", entry->entry.transp_src);
|
||||
|
||||
// Log the transport dest port
|
||||
DBG_VERBOSE("tdst[%i]\n", entry->entry.transp_dst);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
log_entry_raw(nf2_of_entry_wrap *entry)
|
||||
{
|
||||
#ifdef HWTABLE_NO_DEBUG
|
||||
return;
|
||||
#else
|
||||
int i;
|
||||
unsigned char *c;
|
||||
|
||||
DBG_VERBOSE("E ");
|
||||
c = (unsigned char *)entry;
|
||||
for (i = 0; i < sizeof(nf2_of_entry_wrap); ++i) {
|
||||
if (!(i % 4)) {
|
||||
DBG_VERBOSE(" ");
|
||||
}
|
||||
DBG_VERBOSE("%02x", c[i]);
|
||||
}
|
||||
DBG_VERBOSE("\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
log_mask(nf2_of_mask_wrap *mask)
|
||||
{
|
||||
#ifdef HWTABLE_NO_DEBUG
|
||||
return;
|
||||
#else
|
||||
int i;
|
||||
|
||||
// Log the physical source port
|
||||
DBG_VERBOSE("M psrc[%0X] ", mask->entry.src_port / 2);
|
||||
|
||||
// Log the link layer source
|
||||
DBG_VERBOSE("dlsrc[");
|
||||
for (i = 5; i > 0; --i) {
|
||||
DBG_VERBOSE("%0X:", mask->entry.eth_src[i]);
|
||||
}
|
||||
DBG_VERBOSE("%0X] ", mask->entry.eth_dst[0]);
|
||||
|
||||
// Log the link layer dest
|
||||
DBG_VERBOSE("dldst[");
|
||||
for (i = 5; i > 0; --i) {
|
||||
DBG_VERBOSE("%0X:", mask->entry.eth_dst[i]);
|
||||
}
|
||||
DBG_VERBOSE("%0X] ", mask->entry.eth_dst[0]);
|
||||
|
||||
// Log the link layer type
|
||||
DBG_VERBOSE("dltype[%0X] ", mask->entry.eth_type);
|
||||
|
||||
// Log the link layer vlan
|
||||
DBG_VERBOSE("dlvlan[%0X] ", mask->entry.vlan_id);
|
||||
|
||||
// Log the network source
|
||||
DBG_VERBOSE("nwsrc[");
|
||||
DBG_VERBOSE("%0X.", (mask->entry.ip_src >> 24) & 0xFF);
|
||||
DBG_VERBOSE("%0X.", (mask->entry.ip_src >> 16) & 0xFF);
|
||||
DBG_VERBOSE("%0X.", (mask->entry.ip_src >> 8) & 0xFF);
|
||||
DBG_VERBOSE("%0X", mask->entry.ip_src & 0xFF);
|
||||
DBG_VERBOSE("] ");
|
||||
|
||||
// Log the network dest
|
||||
DBG_VERBOSE("nwdst[");
|
||||
DBG_VERBOSE("%0X.", (mask->entry.ip_dst >> 24) & 0xFF);
|
||||
DBG_VERBOSE("%0X.", (mask->entry.ip_dst >> 16) & 0xFF);
|
||||
DBG_VERBOSE("%0X.", (mask->entry.ip_dst >> 8) & 0xFF);
|
||||
DBG_VERBOSE("%0X", mask->entry.ip_dst & 0xFF);
|
||||
DBG_VERBOSE("] ");
|
||||
|
||||
// Log the network TOS
|
||||
DBG_VERBOSE("nwtos[0x%0X] ", mask->entry.ip_tos);
|
||||
|
||||
// Log the transport source port
|
||||
DBG_VERBOSE("tsrc[%0X] ", mask->entry.transp_src);
|
||||
|
||||
// Log the transport dest port
|
||||
DBG_VERBOSE("tdst[%0X]\n", mask->entry.transp_dst);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
log_mask_raw(nf2_of_mask_wrap *mask)
|
||||
{
|
||||
#ifdef HWTABLE_NO_DEBUG
|
||||
return;
|
||||
#else
|
||||
int i;
|
||||
unsigned char *c;
|
||||
|
||||
DBG_VERBOSE("M ");
|
||||
c = (unsigned char *)mask;
|
||||
for (i = 0; i < sizeof(nf2_of_mask_wrap); ++i) {
|
||||
if (!(i % 4)) {
|
||||
DBG_VERBOSE(" ");
|
||||
}
|
||||
DBG_VERBOSE("%02x", c[i]);
|
||||
}
|
||||
DBG_VERBOSE("\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
log_action(nf2_of_action_wrap *action)
|
||||
{
|
||||
#ifdef HWTABLE_NO_DEBUG
|
||||
return;
|
||||
#else
|
||||
int i;
|
||||
|
||||
DBG_VERBOSE("A Output P[");
|
||||
for (i = 0; i < 4; ++i) {
|
||||
if (action->action.forward_bitmask & (1 << (i * 2))) {
|
||||
DBG_VERBOSE("%i", i);
|
||||
}
|
||||
}
|
||||
DBG_VERBOSE("] CPU[");
|
||||
for (i = 0; i < 4; ++i) {
|
||||
if (action->action.forward_bitmask & (1 << (1 + (i * 2)))) {
|
||||
DBG_VERBOSE("%i", i);
|
||||
}
|
||||
}
|
||||
DBG_VERBOSE("]\n");
|
||||
|
||||
// Log the link layer source
|
||||
if (action->action.nf2_action_flag & (1 << OFPAT_SET_DL_SRC)) {
|
||||
DBG_VERBOSE("A Modify: dlsrc: new value [");
|
||||
for (i = 5; i > 0; --i) {
|
||||
DBG_VERBOSE("%0X:", action->action.eth_src[i]);
|
||||
}
|
||||
DBG_VERBOSE("%0X]\n", action->action.eth_src[0]);
|
||||
}
|
||||
|
||||
// Log the link layer dest
|
||||
if (action->action.nf2_action_flag & (1 << OFPAT_SET_DL_DST)) {
|
||||
DBG_VERBOSE("A Modify: dldst: new value [");
|
||||
for (i = 5; i > 0; --i) {
|
||||
DBG_VERBOSE("%0X:", action->action.eth_dst[i]);
|
||||
}
|
||||
DBG_VERBOSE("%0X]\n", action->action.eth_dst[0]);
|
||||
}
|
||||
|
||||
// Log the link layer vlan id
|
||||
if (action->action.nf2_action_flag & (1 << OFPAT_SET_VLAN_VID)) {
|
||||
DBG_VERBOSE("A Modify: dlvlanid: new value [%0X]\n",
|
||||
action->action.vlan_id);
|
||||
}
|
||||
|
||||
// Log the link layer vlan pcp
|
||||
if (action->action.nf2_action_flag & (1 << OFPAT_SET_VLAN_PCP)) {
|
||||
DBG_VERBOSE("A Modify: dlvlanpcp: new value [%0X]\n",
|
||||
action->action.vlan_pcp);
|
||||
}
|
||||
|
||||
// Log the link layer vlan strip
|
||||
if (action->action.nf2_action_flag & (1 << OFPAT_STRIP_VLAN)) {
|
||||
DBG_VERBOSE("A Modify: dlvlan strip\n");
|
||||
}
|
||||
|
||||
// Log the network source
|
||||
if (action->action.nf2_action_flag & (1 << OFPAT_SET_NW_SRC)) {
|
||||
DBG_VERBOSE("A Modify: nwsrc: new value [");
|
||||
DBG_VERBOSE("%0i.", (action->action.ip_src >> 24) & 0xFF);
|
||||
DBG_VERBOSE("%0i.", (action->action.ip_src >> 16) & 0xFF);
|
||||
DBG_VERBOSE("%0i.", (action->action.ip_src >> 8) & 0xFF);
|
||||
DBG_VERBOSE("%0i", action->action.ip_src & 0xFF);
|
||||
DBG_VERBOSE("]\n");
|
||||
}
|
||||
|
||||
// Log the network dest
|
||||
if (action->action.nf2_action_flag & (1 << OFPAT_SET_NW_DST)) {
|
||||
DBG_VERBOSE("A Modify: nwdst: new value [");
|
||||
DBG_VERBOSE("%0i.", (action->action.ip_dst >> 24) & 0xFF);
|
||||
DBG_VERBOSE("%0i.", (action->action.ip_dst >> 16) & 0xFF);
|
||||
DBG_VERBOSE("%0i.", (action->action.ip_dst >> 8) & 0xFF);
|
||||
DBG_VERBOSE("%0i", action->action.ip_dst & 0xFF);
|
||||
DBG_VERBOSE("]\n");
|
||||
}
|
||||
|
||||
// Log the network TOS
|
||||
if (action->action.nf2_action_flag & (1 << OFPAT_SET_NW_TOS)) {
|
||||
DBG_VERBOSE("A Modify: nwtos: new value [%0X]\n",
|
||||
action->action.ip_tos & 0xFF);
|
||||
}
|
||||
|
||||
// Log the transport source port
|
||||
if (action->action.nf2_action_flag & (1 << OFPAT_SET_TP_SRC)) {
|
||||
DBG_VERBOSE("A Modify: tsrc: new value [%0X]\n",
|
||||
action->action.transp_src);
|
||||
}
|
||||
|
||||
// Log the transport dest port
|
||||
if (action->action.nf2_action_flag & (1 << OFPAT_SET_TP_DST)) {
|
||||
DBG_VERBOSE("A Modify: tdst: new value [%0X]\n",
|
||||
action->action.transp_dst);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
log_action_raw(nf2_of_action_wrap *action)
|
||||
{
|
||||
#ifdef HWTABLE_NO_DEBUG
|
||||
return;
|
||||
#else
|
||||
int i;
|
||||
unsigned char *c;
|
||||
|
||||
DBG_VERBOSE("A ");
|
||||
c = (unsigned char *)action;
|
||||
for (i = 0; i < sizeof(nf2_of_action_wrap); ++i) {
|
||||
if (!(i % 4)) {
|
||||
DBG_VERBOSE(" ");
|
||||
}
|
||||
DBG_VERBOSE("%02x", c[i]);
|
||||
}
|
||||
DBG_VERBOSE("\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
nf2_reset_card(struct nf2device *dev)
|
||||
{
|
||||
volatile unsigned int val;
|
||||
|
||||
/* If we are operating on a NetFPGA enabled box, reset the card */
|
||||
readReg(dev, CPCI_REG_CTRL, (void *)&val);
|
||||
val |= 0x100;
|
||||
writeReg(dev, CPCI_REG_CTRL, val);
|
||||
DBG_VERBOSE("Reset the NetFPGA.\n");
|
||||
sleep(2);
|
||||
}
|
||||
|
||||
void
|
||||
nf2_clear_watchdog(struct nf2device *dev)
|
||||
{
|
||||
volatile unsigned int enable_status;
|
||||
|
||||
#ifndef NF2_WATCHDOG
|
||||
return;
|
||||
#endif
|
||||
log_watchdog_info(dev);
|
||||
|
||||
readReg(dev, WDT_ENABLE_FLG_REG, (void *)&enable_status);
|
||||
enable_status &= 0x1;
|
||||
|
||||
if (enable_status == WATCHDOG_DISABLE) {
|
||||
enable_status = WATCHDOG_ENABLE;
|
||||
writeReg(dev, WDT_ENABLE_FLG_REG, enable_status);
|
||||
}
|
||||
}
|
||||
|
||||
/* Write a wildcard entry to the specified device and row. The row consists of
|
||||
* the actual entry, its mask that specifies wildcards, as well as the action(s)
|
||||
* to be taken if the row is matched
|
||||
*/
|
||||
int
|
||||
nf2_write_of_wildcard(struct nf2device *dev, int row,
|
||||
nf2_of_entry_wrap *entry, nf2_of_mask_wrap *mask,
|
||||
nf2_of_action_wrap *action)
|
||||
{
|
||||
int i;
|
||||
unsigned int val;
|
||||
|
||||
DBG_VERBOSE("** Begin wildcard entry write to row: %i\n", row);
|
||||
log_entry(entry);
|
||||
log_mask(mask);
|
||||
log_action(action);
|
||||
log_entry_raw(entry);
|
||||
log_mask_raw(mask);
|
||||
log_action_raw(action);
|
||||
|
||||
for (i = 0; i < NF2_OF_ENTRY_WORD_LEN; ++i) {
|
||||
writeReg(dev,
|
||||
OPENFLOW_WILDCARD_LOOKUP_CMP_0_REG
|
||||
+ (4 * i), entry->raw[i]);
|
||||
}
|
||||
|
||||
for (i = 0; i < NF2_OF_MASK_WORD_LEN; ++i) {
|
||||
writeReg(dev,
|
||||
OPENFLOW_WILDCARD_LOOKUP_CMP_MASK_0_REG
|
||||
+ (4 * i), mask->raw[i]);
|
||||
}
|
||||
|
||||
for (i = 0; i < NF2_OF_ACTION_WORD_LEN; ++i) {
|
||||
writeReg(dev,
|
||||
OPENFLOW_WILDCARD_LOOKUP_ACTION_0_REG
|
||||
+ (4 * i), action->raw[i]);
|
||||
}
|
||||
|
||||
// Reset the stats for the row
|
||||
val = 0;
|
||||
writeReg(dev,
|
||||
OPENFLOW_WILDCARD_LOOKUP_BYTES_HIT_0_REG + (4 * row),
|
||||
val);
|
||||
writeReg(dev, OPENFLOW_WILDCARD_LOOKUP_PKTS_HIT_0_REG + (4 * row),
|
||||
val);
|
||||
writeReg(dev,
|
||||
OPENFLOW_WILDCARD_LOOKUP_LAST_SEEN_TS_0_REG + (4 * row),
|
||||
val);
|
||||
writeReg(dev, OPENFLOW_WILDCARD_LOOKUP_WRITE_ADDR_REG, row);
|
||||
|
||||
DBG_VERBOSE("** End wildcard entry write to row: %i time(msec): %llu\n",
|
||||
row, time_msec());
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
nf2_write_of_exact(struct nf2device *dev, int row,
|
||||
nf2_of_entry_wrap *entry, nf2_of_action_wrap *action)
|
||||
{
|
||||
int i;
|
||||
unsigned int val;
|
||||
unsigned int index = row << 7;
|
||||
|
||||
DBG_VERBOSE("** Begin exact match entry write to row: %i\n", row);
|
||||
log_entry(entry);
|
||||
log_action(action);
|
||||
log_entry_raw(entry);
|
||||
log_action_raw(action);
|
||||
|
||||
for (i = 0; i < NF2_OF_ENTRY_WORD_LEN; ++i) {
|
||||
writeReg(dev, SRAM_BASE_ADDR + index
|
||||
+ (4 * i), entry->raw[i]);
|
||||
}
|
||||
|
||||
// blank out the counters
|
||||
val = 0;
|
||||
for (i = 0; i < NF2_OF_EXACT_COUNTERS_WORD_LEN; ++i) {
|
||||
writeReg(dev, SRAM_BASE_ADDR + index
|
||||
+ sizeof(nf2_of_entry_wrap)
|
||||
+ (4 * i), val);
|
||||
}
|
||||
|
||||
// write the actions
|
||||
for (i = 0; i < NF2_OF_ACTION_WORD_LEN; ++i) {
|
||||
writeReg(dev, SRAM_BASE_ADDR + index
|
||||
+ sizeof(nf2_of_entry_wrap)
|
||||
+ sizeof(nf2_of_exact_counters_wrap)
|
||||
+ (4 * i), action->raw[i]);
|
||||
}
|
||||
|
||||
DBG_VERBOSE
|
||||
("** End exact match entry write to row: %i time(msec): %llu\n",
|
||||
row, time_msec());
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Write wildcard action(s) to the specified device and row. */
|
||||
int
|
||||
nf2_modify_write_of_wildcard(struct nf2device *dev, int row,
|
||||
nf2_of_entry_wrap *entry, nf2_of_mask_wrap *mask,
|
||||
nf2_of_action_wrap *action)
|
||||
{
|
||||
int i;
|
||||
unsigned int bytes_reg_val;
|
||||
unsigned int pkts_reg_val;
|
||||
unsigned int last_reg_val;
|
||||
|
||||
DBG_VERBOSE("** Begin wildcard modified action write to row: %i\n",
|
||||
row);
|
||||
log_entry(entry);
|
||||
log_mask(mask);
|
||||
log_action(action);
|
||||
log_entry_raw(entry);
|
||||
log_mask_raw(mask);
|
||||
log_action_raw(action);
|
||||
|
||||
writeReg(dev, OPENFLOW_WILDCARD_LOOKUP_READ_ADDR_REG, row);
|
||||
readReg(dev,
|
||||
OPENFLOW_WILDCARD_LOOKUP_BYTES_HIT_0_REG + (4 * row),
|
||||
&bytes_reg_val);
|
||||
readReg(dev,
|
||||
OPENFLOW_WILDCARD_LOOKUP_PKTS_HIT_0_REG + (4 * row),
|
||||
&pkts_reg_val);
|
||||
readReg(dev,
|
||||
OPENFLOW_WILDCARD_LOOKUP_LAST_SEEN_TS_0_REG + (4 * row),
|
||||
&last_reg_val);
|
||||
|
||||
for (i = 0; i < NF2_OF_ENTRY_WORD_LEN; ++i) {
|
||||
writeReg(dev, OPENFLOW_WILDCARD_LOOKUP_CMP_0_REG
|
||||
+ (4 * i), entry->raw[i]);
|
||||
}
|
||||
|
||||
for (i = 0; i < NF2_OF_MASK_WORD_LEN; ++i) {
|
||||
writeReg(dev, OPENFLOW_WILDCARD_LOOKUP_CMP_MASK_0_REG
|
||||
+ (4 * i), mask->raw[i]);
|
||||
}
|
||||
|
||||
for (i = 0; i < NF2_OF_ACTION_WORD_LEN; ++i) {
|
||||
writeReg(dev, OPENFLOW_WILDCARD_LOOKUP_ACTION_0_REG
|
||||
+ (4 * i), action->raw[i]);
|
||||
}
|
||||
|
||||
writeReg(dev,
|
||||
OPENFLOW_WILDCARD_LOOKUP_BYTES_HIT_0_REG + (4 * row),
|
||||
bytes_reg_val);
|
||||
writeReg(dev, OPENFLOW_WILDCARD_LOOKUP_PKTS_HIT_0_REG + (4 * row),
|
||||
pkts_reg_val);
|
||||
writeReg(dev,
|
||||
OPENFLOW_WILDCARD_LOOKUP_LAST_SEEN_TS_0_REG + (4 * row),
|
||||
last_reg_val);
|
||||
writeReg(dev, OPENFLOW_WILDCARD_LOOKUP_WRITE_ADDR_REG, row);
|
||||
|
||||
DBG_VERBOSE
|
||||
("** End wildcard modified action write to row: %i time(msec): %llu\n",
|
||||
row, time_msec());
|
||||
DBG_VERBOSE(" Bytes hit count: %d\n", bytes_reg_val);
|
||||
DBG_VERBOSE(" Pkts hit count: %d\n", pkts_reg_val);
|
||||
DBG_VERBOSE(" Last seen : %d\n", last_reg_val);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
nf2_modify_write_of_exact(struct nf2device *dev, int row,
|
||||
nf2_of_action_wrap *action)
|
||||
{
|
||||
int i;
|
||||
unsigned int index = row << 7;
|
||||
|
||||
DBG_VERBOSE("** Begin exact match modified action write to row: %i\n",
|
||||
row);
|
||||
log_action(action);
|
||||
log_action_raw(action);
|
||||
|
||||
// write the actions
|
||||
for (i = 0; i < NF2_OF_ACTION_WORD_LEN; ++i) {
|
||||
writeReg(dev, SRAM_BASE_ADDR + index
|
||||
+ sizeof(nf2_of_entry_wrap)
|
||||
+ sizeof(nf2_of_exact_counters_wrap)
|
||||
+ (4 * i), action->raw[i]);
|
||||
}
|
||||
|
||||
DBG_VERBOSE
|
||||
("** End exact match modified action write to row: %i time(msec): %llu\n",
|
||||
row, time_msec());
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned int
|
||||
nf2_get_exact_packet_count(struct nf2device *dev, int row)
|
||||
{
|
||||
unsigned int val = 0;
|
||||
unsigned int index = 0;
|
||||
|
||||
/* TODO: Need to scrape data from all 4 registers
|
||||
* in the case of a wildcarded source port and
|
||||
* forward all action type
|
||||
*/
|
||||
nf2_of_exact_counters_wrap counters;
|
||||
memset(&counters, 0, sizeof(nf2_of_exact_counters_wrap));
|
||||
|
||||
// build the index to our counters
|
||||
index = row << 7;
|
||||
|
||||
// Read the first word into our struct, to not disturb the byte count
|
||||
readReg(dev,
|
||||
SRAM_BASE_ADDR + index + sizeof(nf2_of_entry_wrap),
|
||||
&counters.raw[0]);
|
||||
val = counters.counters.pkt_count;
|
||||
|
||||
DBG_VERBOSE
|
||||
("** Exact match packet count(delta) row: %i count: %i time(msec): %llu\n",
|
||||
row, val, time_msec());
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
unsigned int
|
||||
nf2_get_exact_byte_count(struct nf2device *dev, int row)
|
||||
{
|
||||
unsigned int val = 0;
|
||||
unsigned int index = 0;
|
||||
|
||||
/* TODO: Need to scrape data from all 4 registers
|
||||
* in the case of a wildcarded source port and
|
||||
* forward all action type
|
||||
*/
|
||||
nf2_of_exact_counters_wrap counters;
|
||||
memset(&counters, 0, sizeof(nf2_of_exact_counters_wrap));
|
||||
|
||||
// build the index to our counters
|
||||
index = row << 7;
|
||||
|
||||
// Read the second word into our struct, to not disturb the packet count
|
||||
readReg(dev, SRAM_BASE_ADDR + index +
|
||||
sizeof(nf2_of_entry_wrap) + 4, &counters.raw[1]);
|
||||
val = counters.counters.byte_count;
|
||||
|
||||
DBG_VERBOSE
|
||||
("** Exact match byte count(delta) row: %i count: %i time(msec): %llu\n",
|
||||
row, val, time_msec());
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
unsigned int
|
||||
nf2_get_wildcard_packet_count(struct nf2device *dev, int row)
|
||||
{
|
||||
unsigned int val = 0;
|
||||
|
||||
writeReg(dev, OPENFLOW_WILDCARD_LOOKUP_READ_ADDR_REG, row);
|
||||
readReg(dev, OPENFLOW_WILDCARD_LOOKUP_PKTS_HIT_0_REG
|
||||
+ (4 * row), &val);
|
||||
|
||||
DBG_VERBOSE
|
||||
("** Wildcard packet count(sum) row: %i count: %i time(msec): %llu\n",
|
||||
row, val, time_msec());
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
unsigned int
|
||||
nf2_get_wildcard_byte_count(struct nf2device *dev, int row)
|
||||
{
|
||||
unsigned int val = 0;
|
||||
|
||||
writeReg(dev, OPENFLOW_WILDCARD_LOOKUP_READ_ADDR_REG, row);
|
||||
readReg(dev, OPENFLOW_WILDCARD_LOOKUP_BYTES_HIT_0_REG
|
||||
+ (4 * row), &val);
|
||||
|
||||
DBG_VERBOSE
|
||||
("** Wildcard byte count(sum) row: %i count: %i time(msec): %llu\n",
|
||||
row, val, time_msec());
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
unsigned long int
|
||||
nf2_get_matched_count(struct nf2device *dev)
|
||||
{
|
||||
unsigned int val_wild = 0;
|
||||
unsigned int val_exact = 0;
|
||||
|
||||
readReg(dev, OPENFLOW_LOOKUP_WILDCARD_HITS_REG, &val_wild);
|
||||
readReg(dev, OPENFLOW_LOOKUP_EXACT_HITS_REG, &val_exact);
|
||||
|
||||
DBG_VERBOSE("** Wildcard Matched count: %i time(msec): %llu\n",
|
||||
val_wild, time_msec());
|
||||
DBG_VERBOSE("** Exact Matched count: %i time(msec): %llu\n",
|
||||
val_exact, time_msec());
|
||||
|
||||
return ((unsigned long int)(val_wild + val_exact));
|
||||
}
|
||||
|
||||
unsigned long int
|
||||
nf2_get_missed_count(struct nf2device *dev)
|
||||
{
|
||||
unsigned int val_wild = 0;
|
||||
unsigned int val_exact = 0;
|
||||
|
||||
readReg(dev, OPENFLOW_LOOKUP_WILDCARD_MISSES_REG, &val_wild);
|
||||
readReg(dev, OPENFLOW_LOOKUP_EXACT_MISSES_REG, &val_exact);
|
||||
|
||||
DBG_VERBOSE("** Wildcard Missed count: %i time(msec): %llu\n",
|
||||
val_wild, time_msec());
|
||||
DBG_VERBOSE("** Exact Missed count: %i time(msec): %llu\n",
|
||||
val_exact, time_msec());
|
||||
|
||||
return ((unsigned long int)(val_wild + val_exact));
|
||||
}
|
||||
|
||||
static void
|
||||
log_watchdog_info(struct nf2device *dev)
|
||||
{
|
||||
#ifdef HWTABLE_NO_DEBUG
|
||||
return;
|
||||
#else
|
||||
#define CLK_CYCLE 8
|
||||
unsigned int nf2wdtinfo;
|
||||
unsigned int elapsed_time;
|
||||
readReg(dev, WDT_COUNTER_REG, &nf2wdtinfo);
|
||||
elapsed_time = nf2wdtinfo * CLK_CYCLE / 1000000;
|
||||
DBG_VVERB
|
||||
("%u (msec) passed since the watchdog counter has been cleared last time\n",
|
||||
elapsed_time);
|
||||
DBG_VVERB("NetFPGA WDT now clearing\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
nf2_get_all_ports_info_addr(struct nf2_all_ports_info_addr *nf2addr)
|
||||
{
|
||||
nf2addr->rx_q_num_pkts_stored_reg[0]
|
||||
= MAC_GRP_0_RX_QUEUE_NUM_PKTS_STORED_REG;
|
||||
nf2addr->rx_q_num_pkts_dropped_full_reg[0]
|
||||
= MAC_GRP_0_RX_QUEUE_NUM_PKTS_DROPPED_FULL_REG;
|
||||
nf2addr->rx_q_num_pkts_dropped_bad_reg[0]
|
||||
= MAC_GRP_0_RX_QUEUE_NUM_PKTS_DROPPED_BAD_REG;
|
||||
nf2addr->rx_q_num_words_pushed_reg[0]
|
||||
= MAC_GRP_0_RX_QUEUE_NUM_WORDS_PUSHED_REG;
|
||||
nf2addr->rx_q_num_bytes_pushed_reg[0]
|
||||
= MAC_GRP_0_RX_QUEUE_NUM_BYTES_PUSHED_REG;
|
||||
nf2addr->rx_q_num_pkts_dequeued_reg[0]
|
||||
= MAC_GRP_0_RX_QUEUE_NUM_PKTS_DEQUEUED_REG;
|
||||
nf2addr->rx_q_num_pkts_in_queue_reg[0]
|
||||
= MAC_GRP_0_RX_QUEUE_NUM_PKTS_IN_QUEUE_REG;
|
||||
nf2addr->tx_q_num_pkts_in_queue_reg[0]
|
||||
= MAC_GRP_0_TX_QUEUE_NUM_PKTS_IN_QUEUE_REG;
|
||||
nf2addr->tx_q_num_pkts_sent_reg[0]
|
||||
= MAC_GRP_0_TX_QUEUE_NUM_PKTS_SENT_REG;
|
||||
nf2addr->tx_q_num_words_pushed_reg[0]
|
||||
= MAC_GRP_0_TX_QUEUE_NUM_WORDS_PUSHED_REG;
|
||||
nf2addr->tx_q_num_bytes_pushed_reg[0]
|
||||
= MAC_GRP_0_TX_QUEUE_NUM_BYTES_PUSHED_REG;
|
||||
nf2addr->tx_q_num_pkts_enqueued_reg[0]
|
||||
= MAC_GRP_0_TX_QUEUE_NUM_PKTS_ENQUEUED_REG;
|
||||
|
||||
nf2addr->rx_q_num_pkts_stored_reg[1]
|
||||
= MAC_GRP_1_RX_QUEUE_NUM_PKTS_STORED_REG;
|
||||
nf2addr->rx_q_num_pkts_dropped_full_reg[1]
|
||||
= MAC_GRP_1_RX_QUEUE_NUM_PKTS_DROPPED_FULL_REG;
|
||||
nf2addr->rx_q_num_pkts_dropped_bad_reg[1]
|
||||
= MAC_GRP_1_RX_QUEUE_NUM_PKTS_DROPPED_BAD_REG;
|
||||
nf2addr->rx_q_num_words_pushed_reg[1]
|
||||
= MAC_GRP_1_RX_QUEUE_NUM_WORDS_PUSHED_REG;
|
||||
nf2addr->rx_q_num_bytes_pushed_reg[1]
|
||||
= MAC_GRP_1_RX_QUEUE_NUM_BYTES_PUSHED_REG;
|
||||
nf2addr->rx_q_num_pkts_dequeued_reg[1]
|
||||
= MAC_GRP_1_RX_QUEUE_NUM_PKTS_DEQUEUED_REG;
|
||||
nf2addr->rx_q_num_pkts_in_queue_reg[1]
|
||||
= MAC_GRP_1_RX_QUEUE_NUM_PKTS_IN_QUEUE_REG;
|
||||
nf2addr->tx_q_num_pkts_in_queue_reg[1]
|
||||
= MAC_GRP_1_TX_QUEUE_NUM_PKTS_IN_QUEUE_REG;
|
||||
nf2addr->tx_q_num_pkts_sent_reg[1]
|
||||
= MAC_GRP_1_TX_QUEUE_NUM_PKTS_SENT_REG;
|
||||
nf2addr->tx_q_num_words_pushed_reg[1]
|
||||
= MAC_GRP_1_TX_QUEUE_NUM_WORDS_PUSHED_REG;
|
||||
nf2addr->tx_q_num_bytes_pushed_reg[1]
|
||||
= MAC_GRP_1_TX_QUEUE_NUM_BYTES_PUSHED_REG;
|
||||
nf2addr->tx_q_num_pkts_enqueued_reg[1]
|
||||
= MAC_GRP_1_TX_QUEUE_NUM_PKTS_ENQUEUED_REG;
|
||||
|
||||
nf2addr->rx_q_num_pkts_stored_reg[2]
|
||||
= MAC_GRP_2_RX_QUEUE_NUM_PKTS_STORED_REG;
|
||||
nf2addr->rx_q_num_pkts_dropped_full_reg[2]
|
||||
= MAC_GRP_2_RX_QUEUE_NUM_PKTS_DROPPED_FULL_REG;
|
||||
nf2addr->rx_q_num_pkts_dropped_bad_reg[2]
|
||||
= MAC_GRP_2_RX_QUEUE_NUM_PKTS_DROPPED_BAD_REG;
|
||||
nf2addr->rx_q_num_words_pushed_reg[2]
|
||||
= MAC_GRP_2_RX_QUEUE_NUM_WORDS_PUSHED_REG;
|
||||
nf2addr->rx_q_num_bytes_pushed_reg[2]
|
||||
= MAC_GRP_2_RX_QUEUE_NUM_BYTES_PUSHED_REG;
|
||||
nf2addr->rx_q_num_pkts_dequeued_reg[2]
|
||||
= MAC_GRP_2_RX_QUEUE_NUM_PKTS_DEQUEUED_REG;
|
||||
nf2addr->rx_q_num_pkts_in_queue_reg[2]
|
||||
= MAC_GRP_2_RX_QUEUE_NUM_PKTS_IN_QUEUE_REG;
|
||||
nf2addr->tx_q_num_pkts_in_queue_reg[2]
|
||||
= MAC_GRP_2_TX_QUEUE_NUM_PKTS_IN_QUEUE_REG;
|
||||
nf2addr->tx_q_num_pkts_sent_reg[2]
|
||||
= MAC_GRP_2_TX_QUEUE_NUM_PKTS_SENT_REG;
|
||||
nf2addr->tx_q_num_words_pushed_reg[2]
|
||||
= MAC_GRP_2_TX_QUEUE_NUM_WORDS_PUSHED_REG;
|
||||
nf2addr->tx_q_num_bytes_pushed_reg[2]
|
||||
= MAC_GRP_2_TX_QUEUE_NUM_BYTES_PUSHED_REG;
|
||||
nf2addr->tx_q_num_pkts_enqueued_reg[2]
|
||||
= MAC_GRP_2_TX_QUEUE_NUM_PKTS_ENQUEUED_REG;
|
||||
|
||||
nf2addr->rx_q_num_pkts_stored_reg[3]
|
||||
= MAC_GRP_3_RX_QUEUE_NUM_PKTS_STORED_REG;
|
||||
nf2addr->rx_q_num_pkts_dropped_full_reg[3]
|
||||
= MAC_GRP_3_RX_QUEUE_NUM_PKTS_DROPPED_FULL_REG;
|
||||
nf2addr->rx_q_num_pkts_dropped_bad_reg[3]
|
||||
= MAC_GRP_3_RX_QUEUE_NUM_PKTS_DROPPED_BAD_REG;
|
||||
nf2addr->rx_q_num_words_pushed_reg[3]
|
||||
= MAC_GRP_3_RX_QUEUE_NUM_WORDS_PUSHED_REG;
|
||||
nf2addr->rx_q_num_bytes_pushed_reg[3]
|
||||
= MAC_GRP_3_RX_QUEUE_NUM_BYTES_PUSHED_REG;
|
||||
nf2addr->rx_q_num_pkts_dequeued_reg[3]
|
||||
= MAC_GRP_3_RX_QUEUE_NUM_PKTS_DEQUEUED_REG;
|
||||
nf2addr->rx_q_num_pkts_in_queue_reg[3]
|
||||
= MAC_GRP_3_RX_QUEUE_NUM_PKTS_IN_QUEUE_REG;
|
||||
nf2addr->tx_q_num_pkts_in_queue_reg[3]
|
||||
= MAC_GRP_3_TX_QUEUE_NUM_PKTS_IN_QUEUE_REG;
|
||||
nf2addr->tx_q_num_pkts_sent_reg[3]
|
||||
= MAC_GRP_3_TX_QUEUE_NUM_PKTS_SENT_REG;
|
||||
nf2addr->tx_q_num_words_pushed_reg[3]
|
||||
= MAC_GRP_3_TX_QUEUE_NUM_WORDS_PUSHED_REG;
|
||||
nf2addr->tx_q_num_bytes_pushed_reg[3]
|
||||
= MAC_GRP_3_TX_QUEUE_NUM_BYTES_PUSHED_REG;
|
||||
nf2addr->tx_q_num_pkts_enqueued_reg[3]
|
||||
= MAC_GRP_3_TX_QUEUE_NUM_PKTS_ENQUEUED_REG;
|
||||
}
|
||||
|
||||
int
|
||||
nf2_get_port_info(struct nf2device *dev, int nf_port,
|
||||
struct nf2_port_info *nf2portinfo)
|
||||
{
|
||||
struct nf2_all_ports_info_addr *nf2addr;
|
||||
|
||||
if ((nf_port >= NF2_PORT_NUM) || (nf_port < 0)) {
|
||||
DBG_ERROR("Illegal port number\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
nf2addr = calloc(1, sizeof(struct nf2_all_ports_info_addr));
|
||||
if (nf2addr == NULL) {
|
||||
DBG_ERROR("Could not allocate memory for port information gathering\n");
|
||||
return 1;
|
||||
}
|
||||
nf2_get_all_ports_info_addr(nf2addr);
|
||||
|
||||
readReg(dev, nf2addr->rx_q_num_pkts_stored_reg[nf_port],
|
||||
&(nf2portinfo->rx_q_num_pkts_stored));
|
||||
readReg(dev, nf2addr->rx_q_num_pkts_dropped_full_reg[nf_port],
|
||||
&(nf2portinfo->rx_q_num_pkts_dropped_full));
|
||||
readReg(dev, nf2addr->rx_q_num_pkts_dropped_bad_reg[nf_port],
|
||||
&(nf2portinfo->rx_q_num_pkts_dropped_bad));
|
||||
readReg(dev, nf2addr->rx_q_num_words_pushed_reg[nf_port],
|
||||
&(nf2portinfo->rx_q_num_words_pushed));
|
||||
readReg(dev, nf2addr->rx_q_num_bytes_pushed_reg[nf_port],
|
||||
&(nf2portinfo->rx_q_num_bytes_pushed));
|
||||
readReg(dev, nf2addr->rx_q_num_pkts_dequeued_reg[nf_port],
|
||||
&(nf2portinfo->rx_q_num_pkts_dequeued));
|
||||
readReg(dev, nf2addr->rx_q_num_pkts_in_queue_reg[nf_port],
|
||||
&(nf2portinfo->rx_q_num_pkts_in_queue));
|
||||
readReg(dev, nf2addr->tx_q_num_pkts_in_queue_reg[nf_port],
|
||||
&(nf2portinfo->tx_q_num_pkts_in_queue));
|
||||
readReg(dev, nf2addr->tx_q_num_pkts_sent_reg[nf_port],
|
||||
&(nf2portinfo->tx_q_num_pkts_sent));
|
||||
readReg(dev, nf2addr->tx_q_num_words_pushed_reg[nf_port],
|
||||
&(nf2portinfo->tx_q_num_words_pushed));
|
||||
readReg(dev, nf2addr->tx_q_num_bytes_pushed_reg[nf_port],
|
||||
&(nf2portinfo->tx_q_num_bytes_pushed));
|
||||
readReg(dev, nf2addr->tx_q_num_pkts_enqueued_reg[nf_port],
|
||||
&(nf2portinfo->tx_q_num_pkts_enqueued));
|
||||
free(nf2addr);
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,150 @@
|
||||
/*-
|
||||
* Copyright (c) 2008, 2009, 2010
|
||||
* The Board of Trustees of The Leland Stanford Junior University
|
||||
*
|
||||
* We are making the OpenFlow specification and associated documentation
|
||||
* (Software) available for public use and benefit with the expectation that
|
||||
* others will use, modify and enhance the Software and contribute those
|
||||
* enhancements back to the community. However, since we would like to make the
|
||||
* Software available for broadest use, with as few restrictions as possible
|
||||
* permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this Software to deal in the Software under the copyrights without
|
||||
* restriction, including without limitation the rights to use, copy, modify,
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of the Software,
|
||||
* and to permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
* IN THE SOFTWARE.
|
||||
*
|
||||
* The name and trademarks of copyright holder(s) may NOT be used in
|
||||
* advertising or publicity pertaining to the Software or any derivatives
|
||||
* without specific, written prior permission.
|
||||
*/
|
||||
|
||||
#ifndef HATABLE_NF2_NF2_OPENFLOW_H_
|
||||
#define HATABLE_NF2_NF2_OPENFLOW_H_
|
||||
|
||||
#define OPENFLOW_NF2_EXACT_TABLE_SIZE 32768
|
||||
#define WATCHDOG_ENABLE 1
|
||||
#define WATCHDOG_DISABLE 0
|
||||
|
||||
#pragma pack(push) /* push current alignment to stack */
|
||||
#pragma pack(1) /* set alignment to 1 byte boundary */
|
||||
|
||||
#define NF2_OF_ENTRY_WORD_LEN 8
|
||||
struct nf2_of_entry {
|
||||
uint16_t transp_dst;
|
||||
uint16_t transp_src;
|
||||
uint8_t ip_proto;
|
||||
uint32_t ip_dst;
|
||||
uint32_t ip_src;
|
||||
uint16_t eth_type;
|
||||
uint8_t eth_dst[6];
|
||||
uint8_t eth_src[6];
|
||||
uint8_t src_port;
|
||||
uint8_t ip_tos;
|
||||
uint16_t vlan_id;
|
||||
uint8_t pad;
|
||||
};
|
||||
|
||||
typedef union nf2_of_entry_wrap {
|
||||
struct nf2_of_entry entry;
|
||||
uint32_t raw[NF2_OF_ENTRY_WORD_LEN];
|
||||
} nf2_of_entry_wrap;
|
||||
|
||||
typedef nf2_of_entry_wrap nf2_of_mask_wrap;
|
||||
#define NF2_OF_MASK_WORD_LEN 8
|
||||
|
||||
struct nf2_of_action {
|
||||
uint16_t forward_bitmask;
|
||||
uint16_t nf2_action_flag;
|
||||
uint16_t vlan_id;
|
||||
uint8_t vlan_pcp;
|
||||
uint8_t eth_src[6];
|
||||
uint8_t eth_dst[6];
|
||||
uint32_t ip_src;
|
||||
uint32_t ip_dst;
|
||||
uint8_t ip_tos;
|
||||
uint16_t transp_src;
|
||||
uint16_t transp_dst;
|
||||
uint8_t reserved[18];
|
||||
};
|
||||
|
||||
#define NF2_OF_ACTION_WORD_LEN 10
|
||||
typedef union nf2_of_action_wrap {
|
||||
struct nf2_of_action action;
|
||||
uint32_t raw[10];
|
||||
} nf2_of_action_wrap;
|
||||
|
||||
struct nf2_of_exact_counters {
|
||||
uint32_t pkt_count:25;
|
||||
uint8_t last_seen:7;
|
||||
uint32_t byte_count;
|
||||
};
|
||||
|
||||
#define NF2_OF_EXACT_COUNTERS_WORD_LEN 2
|
||||
typedef union nf2_of_exact_counters_wrap {
|
||||
struct nf2_of_exact_counters counters;
|
||||
uint32_t raw[NF2_OF_EXACT_COUNTERS_WORD_LEN];
|
||||
} nf2_of_exact_counters_wrap;
|
||||
|
||||
#define NF2_PORT_NUM 4
|
||||
struct nf2_all_ports_info_addr {
|
||||
unsigned int rx_q_num_pkts_stored_reg[NF2_PORT_NUM];
|
||||
unsigned int rx_q_num_pkts_dropped_full_reg[NF2_PORT_NUM];
|
||||
unsigned int rx_q_num_pkts_dropped_bad_reg[NF2_PORT_NUM];
|
||||
unsigned int rx_q_num_words_pushed_reg[NF2_PORT_NUM];
|
||||
unsigned int rx_q_num_bytes_pushed_reg[NF2_PORT_NUM];
|
||||
unsigned int rx_q_num_pkts_dequeued_reg[NF2_PORT_NUM];
|
||||
unsigned int rx_q_num_pkts_in_queue_reg[NF2_PORT_NUM];
|
||||
unsigned int tx_q_num_pkts_in_queue_reg[NF2_PORT_NUM];
|
||||
unsigned int tx_q_num_pkts_sent_reg[NF2_PORT_NUM];
|
||||
unsigned int tx_q_num_words_pushed_reg[NF2_PORT_NUM];
|
||||
unsigned int tx_q_num_bytes_pushed_reg[NF2_PORT_NUM];
|
||||
unsigned int tx_q_num_pkts_enqueued_reg[NF2_PORT_NUM];
|
||||
};
|
||||
|
||||
struct nf2_port_info {
|
||||
uint32_t rx_q_num_pkts_stored;
|
||||
uint32_t rx_q_num_pkts_dropped_full;
|
||||
uint32_t rx_q_num_pkts_dropped_bad;
|
||||
uint32_t rx_q_num_words_pushed;
|
||||
uint32_t rx_q_num_bytes_pushed;
|
||||
uint32_t rx_q_num_pkts_dequeued;
|
||||
uint32_t rx_q_num_pkts_in_queue;
|
||||
uint32_t tx_q_num_pkts_in_queue;
|
||||
uint32_t tx_q_num_pkts_sent;
|
||||
uint32_t tx_q_num_words_pushed;
|
||||
uint32_t tx_q_num_bytes_pushed;
|
||||
uint32_t tx_q_num_pkts_enqueued;
|
||||
};
|
||||
|
||||
#pragma pack(pop) /* XXX: Restore original alignment from stack */
|
||||
|
||||
void nf2_reset_card(struct nf2device *);
|
||||
void nf2_clear_watchdog(struct nf2device *);
|
||||
int nf2_write_of_wildcard(struct nf2device *, int, nf2_of_entry_wrap *,
|
||||
nf2_of_mask_wrap *, nf2_of_action_wrap *);
|
||||
int nf2_write_of_exact(struct nf2device *, int, nf2_of_entry_wrap *,
|
||||
nf2_of_action_wrap *);
|
||||
int nf2_modify_write_of_wildcard(struct nf2device *, int, nf2_of_entry_wrap *,
|
||||
nf2_of_mask_wrap *, nf2_of_action_wrap *);
|
||||
int nf2_modify_write_of_exact(struct nf2device *, int, nf2_of_action_wrap *);
|
||||
unsigned int nf2_get_exact_packet_count(struct nf2device *, int);
|
||||
unsigned int nf2_get_exact_byte_count(struct nf2device *, int);
|
||||
unsigned int nf2_get_wildcard_packet_count(struct nf2device *, int);
|
||||
unsigned int nf2_get_wildcard_byte_count(struct nf2device *, int);
|
||||
unsigned long int nf2_get_matched_count(struct nf2device *);
|
||||
unsigned long int nf2_get_missed_count(struct nf2device *);
|
||||
int nf2_get_port_info(struct nf2device *, int, struct nf2_port_info *);
|
||||
|
||||
#endif
|
||||
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,59 @@
|
||||
/*-
|
||||
* Copyright (c) 2008, 2009, 2010
|
||||
* The Board of Trustees of The Leland Stanford Junior University
|
||||
*
|
||||
* We are making the OpenFlow specification and associated documentation
|
||||
* (Software) available for public use and benefit with the expectation that
|
||||
* others will use, modify and enhance the Software and contribute those
|
||||
* enhancements back to the community. However, since we would like to make the
|
||||
* Software available for broadest use, with as few restrictions as possible
|
||||
* permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this Software to deal in the Software under the copyrights without
|
||||
* restriction, including without limitation the rights to use, copy, modify,
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of the Software,
|
||||
* and to permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
* IN THE SOFTWARE.
|
||||
*
|
||||
* The name and trademarks of copyright holder(s) may NOT be used in
|
||||
* advertising or publicity pertaining to the Software or any derivatives
|
||||
* without specific, written prior permission.
|
||||
*/
|
||||
|
||||
#ifndef HWTABLE_NF2_NF2_LIB_H_
|
||||
#define HWTABLE_NF2_NF2_LIB_H_
|
||||
|
||||
struct nf2device *nf2_get_net_device(void);
|
||||
void nf2_free_net_device(struct nf2device *);
|
||||
int nf2_are_actions_supported(struct sw_flow *);
|
||||
void nf2_clear_of_exact(uint32_t);
|
||||
void nf2_clear_of_wildcard(uint32_t);
|
||||
int nf2_init_exact_freelist(void);
|
||||
int nf2_init_wildcard_freelist(void);
|
||||
void nf2_destroy_exact_freelist(void);
|
||||
void nf2_destroy_wildcard_freelist(void);
|
||||
int nf2_write_static_wildcard(void);
|
||||
void nf2_populate_of_entry(nf2_of_entry_wrap *, struct sw_flow *);
|
||||
void nf2_populate_of_mask(nf2_of_mask_wrap *, struct sw_flow *);
|
||||
void nf2_populate_of_action(nf2_of_action_wrap *, nf2_of_entry_wrap *,
|
||||
struct sw_flow *);
|
||||
void nf2_add_free_exact(struct nf2_flow *);
|
||||
void nf2_add_free_wildcard(struct nf2_flow *);
|
||||
int nf2_get_table_type(struct sw_flow *);
|
||||
int nf2_build_and_write_flow(struct sw_flow *);
|
||||
void nf2_delete_private(void *);
|
||||
int nf2_modify_acts(struct sw_flow *);
|
||||
uint64_t nf2_get_packet_count(struct nf2device *, struct nf2_flow *);
|
||||
uint64_t nf2_get_byte_count(struct nf2device *, struct nf2_flow *);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,402 @@
|
||||
/* ****************************************************************************
|
||||
* $Id: nf2util.c 3764 2008-05-22 06:48:34Z grg $
|
||||
*
|
||||
* Module: nf2util.c
|
||||
* Project: NetFPGA 2 Linux Kernel Driver
|
||||
* Description: Utility functions for user mode programs
|
||||
*
|
||||
* Change history:
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/ioctl.h>
|
||||
|
||||
#include <net/if.h>
|
||||
|
||||
#include <arpa/inet.h>
|
||||
|
||||
#include "nf2.h"
|
||||
#include "nf2util.h"
|
||||
|
||||
#include "reg_defines_openflow_switch.h"
|
||||
|
||||
#define MD5_LEN 4
|
||||
|
||||
/* Function declarations */
|
||||
static int readRegNet(struct nf2device *nf2, unsigned reg, unsigned *val);
|
||||
static int readRegFile(struct nf2device *nf2, unsigned reg, unsigned *val);
|
||||
static int writeRegNet(struct nf2device *nf2, unsigned reg, unsigned val);
|
||||
static int writeRegFile(struct nf2device *nf2, unsigned reg, unsigned val);
|
||||
|
||||
/* Local variables */
|
||||
unsigned cpci_version = -1;
|
||||
unsigned cpci_revision = -1;
|
||||
unsigned nf2_device_id = -1;
|
||||
unsigned nf2_revision = -1;
|
||||
unsigned nf2_cpci_version = -1;
|
||||
unsigned nf2_cpci_revision = -1;
|
||||
char nf2_device_str[DEVICE_STR_LEN] = "";
|
||||
|
||||
/*
|
||||
* readReg - read a register
|
||||
*/
|
||||
int readReg(struct nf2device *nf2, unsigned reg, unsigned *val)
|
||||
{
|
||||
if (nf2->net_iface)
|
||||
{
|
||||
return readRegNet(nf2, reg, val);
|
||||
}
|
||||
else
|
||||
{
|
||||
return readRegFile(nf2, reg, val);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* readRegNet - read a register, using a network socket
|
||||
*/
|
||||
static int readRegNet(struct nf2device *nf2, unsigned reg, unsigned *val)
|
||||
{
|
||||
struct ifreq ifreq;
|
||||
struct nf2reg nf2reg;
|
||||
int ret;
|
||||
|
||||
nf2reg.reg = reg;
|
||||
|
||||
/* Set up the ifreq structure */
|
||||
ifreq.ifr_data = (char *)&nf2reg;
|
||||
strncpy(ifreq.ifr_ifrn.ifrn_name, nf2->device_name, IFNAMSIZ);
|
||||
/*if (setsockopt(nf2->fd, SOL_SOCKET, SO_BINDTODEVICE,
|
||||
(char *)&ifreq, sizeof(ifreq)) < 0) {
|
||||
perror("sendpacket: setting SO_BINDTODEVICE");
|
||||
return -1;
|
||||
} */
|
||||
|
||||
/* Call the ioctl */
|
||||
if ((ret = ioctl(nf2->fd, SIOCREGREAD, &ifreq)) == 0)
|
||||
{
|
||||
*val = nf2reg.val;
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
perror("sendpacket: ioctl failed");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* readRegFile - read a register, using a file descriptor
|
||||
*/
|
||||
static int readRegFile(struct nf2device *nf2, unsigned reg, unsigned *val)
|
||||
{
|
||||
struct nf2reg nf2reg;
|
||||
int ret;
|
||||
|
||||
nf2reg.reg = reg;
|
||||
|
||||
/* Call the ioctl */
|
||||
if ((ret = ioctl(nf2->fd, SIOCREGREAD, &nf2reg)) == 0)
|
||||
{
|
||||
*val = nf2reg.val;
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
perror("sendpacket: ioctl failed");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* writeReg - write a register
|
||||
*/
|
||||
int writeReg(struct nf2device *nf2, unsigned reg, unsigned val)
|
||||
{
|
||||
if (nf2->net_iface)
|
||||
{
|
||||
return writeRegNet(nf2, reg, val);
|
||||
}
|
||||
else
|
||||
{
|
||||
return writeRegFile(nf2, reg, val);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* writeRegNet - write a register, using a network socket
|
||||
*/
|
||||
static int writeRegNet(struct nf2device *nf2, unsigned reg, unsigned val)
|
||||
{
|
||||
struct ifreq ifreq;
|
||||
struct nf2reg nf2reg;
|
||||
int ret;
|
||||
|
||||
nf2reg.reg = reg;
|
||||
nf2reg.val = val;
|
||||
|
||||
/* Set up the ifreq structure */
|
||||
ifreq.ifr_data = (char *)&nf2reg;
|
||||
strncpy(ifreq.ifr_ifrn.ifrn_name, nf2->device_name, IFNAMSIZ);
|
||||
/*if (setsockopt(nf2->fd, SOL_SOCKET, SO_BINDTODEVICE,
|
||||
(char *)&ifreq, sizeof(ifreq)) < 0) {
|
||||
perror("sendpacket: setting SO_BINDTODEVICE");
|
||||
return -1;
|
||||
} */
|
||||
|
||||
/* Call the ioctl */
|
||||
if ((ret = ioctl(nf2->fd, SIOCREGWRITE, &ifreq)) == 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
perror("sendpacket: ioctl failed");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* writeRegFile - write a register, using a file descriptor
|
||||
*/
|
||||
static int writeRegFile(struct nf2device *nf2, unsigned reg, unsigned val)
|
||||
{
|
||||
struct nf2reg nf2reg;
|
||||
int ret;
|
||||
|
||||
nf2reg.reg = reg;
|
||||
nf2reg.val = val;
|
||||
|
||||
/* Call the ioctl */
|
||||
if ((ret = ioctl(nf2->fd, SIOCREGWRITE, &nf2reg)) == 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
perror("sendpacket: ioctl failed");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Check the iface name to make sure we can find the interface
|
||||
*/
|
||||
int check_iface(struct nf2device *nf2)
|
||||
{
|
||||
struct stat buf;
|
||||
char filename[PATHLEN];
|
||||
|
||||
/* See if we can find the interface name as a network device */
|
||||
|
||||
/* Test the length first of all */
|
||||
if (strlen(nf2->device_name) > IFNAMSIZ)
|
||||
{
|
||||
fprintf(stderr, "Interface name is too long: %s\n", nf2->device_name);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Check for /sys/class/net/iface_name */
|
||||
strcpy(filename, "/sys/class/net/");
|
||||
strcat(filename, nf2->device_name);
|
||||
if (stat(filename, &buf) == 0)
|
||||
{
|
||||
fprintf(stderr, "Found net device: %s\n", nf2->device_name);
|
||||
nf2->net_iface = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Check for /dev/iface_name */
|
||||
strcpy(filename, "/dev/");
|
||||
strcat(filename, nf2->device_name);
|
||||
if (stat(filename, &buf) == 0)
|
||||
{
|
||||
fprintf(stderr, "Found dev device: %s\n", nf2->device_name);
|
||||
nf2->net_iface = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
fprintf(stderr, "Can't find device: %s\n", nf2->device_name);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Open the descriptor associated with the device name
|
||||
*/
|
||||
int openDescriptor(struct nf2device *nf2)
|
||||
{
|
||||
struct ifreq ifreq;
|
||||
char filename[PATHLEN];
|
||||
struct sockaddr_in address;
|
||||
int i;
|
||||
struct sockaddr_in *sin = (struct sockaddr_in *) &ifreq.ifr_addr;
|
||||
int found = 0;
|
||||
|
||||
if (nf2->net_iface)
|
||||
{
|
||||
/* Open a network socket */
|
||||
nf2->fd = socket(AF_INET, SOCK_DGRAM, 0);
|
||||
if (nf2->fd == -1)
|
||||
{
|
||||
perror("socket: creating socket");
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Root can bind to a network interface.
|
||||
Non-root has to bind to a network address. */
|
||||
if (geteuid() == 0)
|
||||
{
|
||||
strncpy(ifreq.ifr_ifrn.ifrn_name, nf2->device_name, IFNAMSIZ);
|
||||
if (setsockopt(nf2->fd, SOL_SOCKET, SO_BINDTODEVICE,
|
||||
(char *)&ifreq, sizeof(ifreq)) < 0) {
|
||||
perror("setsockopt: setting SO_BINDTODEVICE");
|
||||
return -1;
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Attempt to find the IP address for the interface */
|
||||
for (i = 1; ; i++)
|
||||
{
|
||||
/* Find interface number i*/
|
||||
ifreq.ifr_ifindex = i;
|
||||
if (ioctl (nf2->fd, SIOCGIFNAME, &ifreq) < 0)
|
||||
break;
|
||||
|
||||
/* Check if we've found the correct interface */
|
||||
if (strcmp(ifreq.ifr_name, nf2->device_name) != 0)
|
||||
continue;
|
||||
|
||||
/* If we get to here we've found the IP */
|
||||
found = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Verify that we found the interface */
|
||||
if (!found)
|
||||
{
|
||||
fprintf(stderr, "Can't find device: %s\n", nf2->device_name);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Attempt to get the IP address associated with the interface */
|
||||
if (ioctl (nf2->fd, SIOCGIFADDR, &ifreq) < 0)
|
||||
{
|
||||
perror("ioctl: calling SIOCGIFADDR");
|
||||
|
||||
fprintf(stderr, "Unable to find IP address for device: %s\n", nf2->device_name);
|
||||
fprintf(stderr, "Either run this program as root or ask an administrator\n");
|
||||
fprintf(stderr, "to assign an IP address to the device\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Set the addres and attempt to bind to the socket */
|
||||
address.sin_family = AF_INET;
|
||||
address.sin_addr.s_addr = sin->sin_addr.s_addr;
|
||||
address.sin_port = htons(0);
|
||||
if (bind(nf2->fd,(struct sockaddr *)&address,sizeof(address)) == -1) {
|
||||
perror("bind: binding");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
strcpy(filename, "/dev/");
|
||||
strcat(filename, nf2->device_name);
|
||||
nf2->fd = fileno(fopen(filename, "w+"));
|
||||
if (nf2->fd == -1)
|
||||
{
|
||||
perror("fileno: creating descriptor");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Close the descriptor associated with the device name
|
||||
*/
|
||||
int closeDescriptor(struct nf2device *nf2)
|
||||
{
|
||||
if (nf2->net_iface)
|
||||
{
|
||||
close(nf2->fd);
|
||||
}
|
||||
else
|
||||
{
|
||||
close(nf2->fd);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Read the version info from the Virtex and CPCI
|
||||
*/
|
||||
void nf2_read_info(struct nf2device *nf2)
|
||||
{
|
||||
int i;
|
||||
int md5_good = 1;
|
||||
unsigned md5[MD5_LEN];
|
||||
unsigned cpci_id;
|
||||
unsigned nf2_cpci_id;
|
||||
|
||||
// Read the CPCI version/revision
|
||||
readReg(nf2, CPCI_REG_ID, &cpci_id);
|
||||
cpci_version = cpci_id & 0xffffff;
|
||||
cpci_revision = cpci_id >> 24;
|
||||
|
||||
// Verify the MD5 checksum of the device ID block
|
||||
for (i = 0; i < MD5_LEN; i++) {
|
||||
readReg(nf2, DEV_ID_MD5_0_REG + i * 4, &md5[i]);
|
||||
}
|
||||
md5_good &= md5[0] == DEV_ID_MD5_VALUE_0;
|
||||
md5_good &= md5[1] == DEV_ID_MD5_VALUE_1;
|
||||
md5_good &= md5[2] == DEV_ID_MD5_VALUE_2;
|
||||
md5_good &= md5[3] == DEV_ID_MD5_VALUE_3;
|
||||
|
||||
// Process only if the MD5 sum is good
|
||||
if (md5_good) {
|
||||
// Read the version and revision
|
||||
readReg(nf2, DEV_ID_DEVICE_ID_REG, &nf2_device_id);
|
||||
readReg(nf2, DEV_ID_REVISION_REG, &nf2_revision);
|
||||
readReg(nf2, DEV_ID_CPCI_ID_REG, &nf2_cpci_id);
|
||||
nf2_cpci_version = nf2_cpci_id & 0xffffff;
|
||||
nf2_cpci_revision = nf2_cpci_id >> 24;
|
||||
|
||||
// Read the version string
|
||||
for (i = 0; i < (DEVICE_STR_LEN / 4) - 2; i++)
|
||||
{
|
||||
readReg(nf2, DEV_ID_DEV_STR_0_REG + i * 4, (unsigned *)(nf2_device_str + i * 4));
|
||||
|
||||
// Perform byte swapping if necessary
|
||||
*(unsigned *)(nf2_device_str + i * 4) = ntohl(*(unsigned *)(nf2_device_str + i * 4));
|
||||
}
|
||||
nf2_device_str[DEVICE_STR_LEN - 1] = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Print out a test string
|
||||
*/
|
||||
void printHello (struct nf2device *nf2, int *val)
|
||||
{
|
||||
printf ("Hello world. Name=%s val=%d\n", nf2->device_name, *val);
|
||||
*val = 10;
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
/* ****************************************************************************
|
||||
* $Id: nf2util.h 3764 2008-05-22 06:48:34Z grg $
|
||||
*
|
||||
* Module: nf2util.h
|
||||
* Project: NetFPGA 2 Linux Kernel Driver
|
||||
* Description: Header file for kernel driver
|
||||
*
|
||||
* Change history:
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _NF2UTIL_H
|
||||
#define _NF2UTIL_H 1
|
||||
|
||||
#define PATHLEN 80
|
||||
#define DEVICE_STR_LEN 100
|
||||
|
||||
|
||||
/*
|
||||
* Structure to represent an nf2 device to a user mode programs
|
||||
*/
|
||||
struct nf2device {
|
||||
char *device_name;
|
||||
int fd;
|
||||
int net_iface;
|
||||
};
|
||||
|
||||
/* Function declarations */
|
||||
|
||||
int readReg(struct nf2device *nf2, unsigned reg, unsigned *val);
|
||||
int writeReg(struct nf2device *nf2, unsigned reg, unsigned val);
|
||||
int check_iface(struct nf2device *nf2);
|
||||
int openDescriptor(struct nf2device *nf2);
|
||||
int closeDescriptor(struct nf2device *nf2);
|
||||
void nf2_read_info(struct nf2device *nf2);
|
||||
void printHello (struct nf2device *nf2, int *val);
|
||||
|
||||
extern unsigned cpci_version;
|
||||
extern unsigned cpci_revision;
|
||||
extern unsigned nf2_device_id;
|
||||
extern unsigned nf2_revision;
|
||||
extern unsigned nf2_cpci_version;
|
||||
extern unsigned nf2_cpci_revision;
|
||||
extern char nf2_device_str[DEVICE_STR_LEN];
|
||||
|
||||
#endif
|
||||
Binary file not shown.
@@ -0,0 +1,767 @@
|
||||
/********************************************************
|
||||
*
|
||||
* C register defines file for openflow_switch
|
||||
*
|
||||
********************************************************/
|
||||
|
||||
#ifndef _REG_DEFINES_
|
||||
#define _REG_DEFINES_
|
||||
|
||||
/* ========= Constants ========= */
|
||||
|
||||
// ===== File: lib/verilog/core/common/xml/global.xml =====
|
||||
|
||||
// Maximum number of phy ports
|
||||
#define MAX_PHY_PORTS 4
|
||||
|
||||
// PCI address bus width
|
||||
#define PCI_ADDR_WIDTH 32
|
||||
|
||||
// PCI data bus width
|
||||
#define PCI_DATA_WIDTH 32
|
||||
|
||||
// PCI byte enable bus width
|
||||
#define PCI_BE_WIDTH 4
|
||||
|
||||
// CPCI--CNET address bus width. This is byte addresses even though bottom bits are zero.
|
||||
#define CPCI_CNET_ADDR_WIDTH 27
|
||||
|
||||
// CPCI--CNET data bus width
|
||||
#define CPCI_CNET_DATA_WIDTH 32
|
||||
|
||||
// CPCI--NF2 address bus width. This is byte addresses even though bottom bits are zero.
|
||||
#define CPCI_NF2_ADDR_WIDTH 27
|
||||
|
||||
// CPCI--NF2 data bus width
|
||||
#define CPCI_NF2_DATA_WIDTH 32
|
||||
|
||||
// DMA data bus width
|
||||
#define DMA_DATA_WIDTH 32
|
||||
|
||||
// DMA control bus width
|
||||
#define DMA_CTRL_WIDTH 4
|
||||
|
||||
// CPCI debug bus width
|
||||
#define CPCI_DEBUG_DATA_WIDTH 29
|
||||
|
||||
// SRAM address width
|
||||
#define SRAM_ADDR_WIDTH 19
|
||||
|
||||
// SRAM data width
|
||||
#define SRAM_DATA_WIDTH 36
|
||||
|
||||
// DRAM address width
|
||||
#define DRAM_ADDR_WIDTH 24
|
||||
|
||||
// ===== File: lib/verilog/core/common/xml/nf_defines.xml =====
|
||||
|
||||
// Clock period of 125 MHz clock in ns
|
||||
#define FAST_CLK_PERIOD 8
|
||||
|
||||
// Clock period of 62.5 MHz clock in ns
|
||||
#define SLOW_CLK_PERIOD 16
|
||||
|
||||
// Header value used by the IO queues
|
||||
#define IO_QUEUE_STAGE_NUM 0xff
|
||||
|
||||
// Data path data width
|
||||
#define DATA_WIDTH 64
|
||||
|
||||
// Data path control width
|
||||
#define CTRL_WIDTH 8
|
||||
|
||||
// ===== File: projects/openflow_switch/include/output_port_lookup.xml =====
|
||||
|
||||
#define FAST_CLOCK_PERIOD 8
|
||||
|
||||
// ===== File: projects/openflow_switch/include/vlan_remover.xml =====
|
||||
|
||||
#define VLAN_CTRL_WORD 0x42
|
||||
|
||||
#define VLAN_ETHERTYPE 0x8100
|
||||
|
||||
// ===== File: lib/verilog/core/output_queues/bram_output_queues/xml/bram_output_queues.xml =====
|
||||
|
||||
#define NUM_OUTPUT_QUEUES 8
|
||||
|
||||
// ===== File: projects/openflow_switch/include/opl_processor.xml =====
|
||||
|
||||
#define NF2_OFPAT_OUTPUT 0x0001
|
||||
|
||||
#define NF2_OFPAT_SET_VLAN_VID 0x0002
|
||||
|
||||
#define NF2_OFPAT_SET_VLAN_PCP 0x0004
|
||||
|
||||
#define NF2_OFPAT_STRIP_VLAN 0x0008
|
||||
|
||||
#define NF2_OFPAT_SET_DL_SRC 0x0010
|
||||
|
||||
#define NF2_OFPAT_SET_DL_DST 0x0020
|
||||
|
||||
#define NF2_OFPAT_SET_NW_SRC 0x0040
|
||||
|
||||
#define NF2_OFPAT_SET_NW_DST 0x0080
|
||||
|
||||
#define NF2_OFPAT_SET_TP_SRC 0x0100
|
||||
|
||||
#define NF2_OFPAT_SET_TP_DST 0x0200
|
||||
|
||||
// ===== File: projects/openflow_switch/include/wildcard_match.xml =====
|
||||
|
||||
#define OPENFLOW_WILDCARD_TABLE_SIZE 32
|
||||
|
||||
#define OPENFLOW_WILDCARD_NUM_DATA_WORDS_USED 10
|
||||
|
||||
#define OPENFLOW_WILDCARD_NUM_CMP_WORDS_USED 8
|
||||
|
||||
// ===== File: lib/verilog/core/utils/xml/device_id_reg.xml =====
|
||||
|
||||
// Total number of registers
|
||||
#define DEV_ID_NUM_REGS 32
|
||||
|
||||
// Number of non string registers
|
||||
#define DEV_ID_NON_DEV_STR_REGS 7
|
||||
|
||||
// Device description length (in words, not chars)
|
||||
#define DEV_ID_DEV_STR_WORD_LEN 25
|
||||
|
||||
// Device description length (in bytes/chars)
|
||||
#define DEV_ID_DEV_STR_BYTE_LEN 100
|
||||
|
||||
// Device description length (in bits)
|
||||
#define DEV_ID_DEV_STR_BIT_LEN 800
|
||||
|
||||
// Length of MD5 sum (bits)
|
||||
#define DEV_ID_MD5SUM_LENGTH 128
|
||||
|
||||
// MD5 sum of the string "device_id.v"
|
||||
#define DEV_ID_MD5_VALUE 0x4071736d8a603d2b4d55f62989a73c95
|
||||
#define DEV_ID_MD5_VALUE_0 0x4071736d
|
||||
#define DEV_ID_MD5_VALUE_1 0x8a603d2b
|
||||
#define DEV_ID_MD5_VALUE_2 0x4d55f629
|
||||
#define DEV_ID_MD5_VALUE_3 0x89a73c95
|
||||
|
||||
// ===== File: projects/openflow_switch/include/header_parser.xml =====
|
||||
|
||||
#define ETH_TYPE_IP 0x0800
|
||||
|
||||
#define IP_PROTO_TCP 0x06
|
||||
|
||||
#define IP_PROTO_UDP 0x11
|
||||
|
||||
#define IP_PROTO_ICMP 0x01
|
||||
|
||||
// ===== File: projects/openflow_switch/include/watchdog.xml =====
|
||||
|
||||
#define WDT_CPCI_REG_CTRL 0x00000008
|
||||
|
||||
// ===== File: lib/verilog/core/io_queues/ethernet_mac/xml/ethernet_mac.xml =====
|
||||
|
||||
// TX queue disable bit
|
||||
#define MAC_GRP_TX_QUEUE_DISABLE_BIT_NUM 0
|
||||
|
||||
// RX queue disable bit
|
||||
#define MAC_GRP_RX_QUEUE_DISABLE_BIT_NUM 1
|
||||
|
||||
// Reset MAC bit
|
||||
#define MAC_GRP_RESET_MAC_BIT_NUM 2
|
||||
|
||||
// MAC TX queue disable bit
|
||||
#define MAC_GRP_MAC_DISABLE_TX_BIT_NUM 3
|
||||
|
||||
// MAC RX queue disable bit
|
||||
#define MAC_GRP_MAC_DISABLE_RX_BIT_NUM 4
|
||||
|
||||
// MAC disable jumbo TX bit
|
||||
#define MAC_GRP_MAC_DIS_JUMBO_TX_BIT_NUM 5
|
||||
|
||||
// MAC disable jumbo RX bit
|
||||
#define MAC_GRP_MAC_DIS_JUMBO_RX_BIT_NUM 6
|
||||
|
||||
// MAC disable crc check disable bit
|
||||
#define MAC_GRP_MAC_DIS_CRC_CHECK_BIT_NUM 7
|
||||
|
||||
// MAC disable crc generate bit
|
||||
#define MAC_GRP_MAC_DIS_CRC_GEN_BIT_NUM 8
|
||||
|
||||
// ===== File: projects/openflow_switch/include/match_arbiter.xml =====
|
||||
|
||||
#define OPENFLOW_ENTRY_TRANSP_DST_WIDTH 16
|
||||
|
||||
#define OPENFLOW_ENTRY_TRANSP_DST_POS 0
|
||||
|
||||
#define OPENFLOW_ENTRY_TRANSP_SRC_WIDTH 16
|
||||
|
||||
#define OPENFLOW_ENTRY_TRANSP_SRC_POS 16
|
||||
|
||||
#define OPENFLOW_ENTRY_IP_PROTO_WIDTH 8
|
||||
|
||||
#define OPENFLOW_ENTRY_IP_PROTO_POS 32
|
||||
|
||||
#define OPENFLOW_ENTRY_IP_DST_WIDTH 32
|
||||
|
||||
#define OPENFLOW_ENTRY_IP_DST_POS 40
|
||||
|
||||
#define OPENFLOW_ENTRY_IP_SRC_WIDTH 32
|
||||
|
||||
#define OPENFLOW_ENTRY_IP_SRC_POS 72
|
||||
|
||||
#define OPENFLOW_ENTRY_ETH_TYPE_WIDTH 16
|
||||
|
||||
#define OPENFLOW_ENTRY_ETH_TYPE_POS 104
|
||||
|
||||
#define OPENFLOW_ENTRY_ETH_DST_WIDTH 48
|
||||
|
||||
#define OPENFLOW_ENTRY_ETH_DST_POS 120
|
||||
|
||||
#define OPENFLOW_ENTRY_ETH_SRC_WIDTH 48
|
||||
|
||||
#define OPENFLOW_ENTRY_ETH_SRC_POS 168
|
||||
|
||||
#define OPENFLOW_ENTRY_SRC_PORT_WIDTH 8
|
||||
|
||||
#define OPENFLOW_ENTRY_SRC_PORT_POS 216
|
||||
|
||||
#define OPENFLOW_ENTRY_VLAN_ID_WIDTH 16
|
||||
|
||||
#define OPENFLOW_ENTRY_VLAN_ID_POS 224
|
||||
|
||||
#define OPENFLOW_ENTRY_WIDTH 240
|
||||
|
||||
// The actionfield is composed of a bitmask specifying actions to take and arguments.
|
||||
#define OPENFLOW_ACTION_WIDTH 320
|
||||
|
||||
// Ports to forward on
|
||||
#define OPENFLOW_FORWARD_BITMASK_WIDTH 16
|
||||
|
||||
#define OPENFLOW_FORWARD_BITMASK_POS 0
|
||||
|
||||
#define OPENFLOW_NF2_ACTION_FLAG_WIDTH 16
|
||||
|
||||
#define OPENFLOW_NF2_ACTION_FLAG_POS 16
|
||||
|
||||
// Vlan ID to be replaced
|
||||
#define OPENFLOW_SET_VLAN_VID_WIDTH 16
|
||||
|
||||
#define OPENFLOW_SET_VLAN_VID_POS 32
|
||||
|
||||
// Vlan priority to be replaced
|
||||
#define OPENFLOW_SET_VLAN_PCP_WIDTH 8
|
||||
|
||||
#define OPENFLOW_SET_VLAN_PCP_POS 48
|
||||
|
||||
// Source MAC address to be replaced
|
||||
#define OPENFLOW_SET_DL_SRC_WIDTH 48
|
||||
|
||||
#define OPENFLOW_SET_DL_SRC_POS 56
|
||||
|
||||
// Destination MAC address to be replaced
|
||||
#define OPENFLOW_SET_DL_DST_WIDTH 48
|
||||
|
||||
#define OPENFLOW_SET_DL_DST_POS 104
|
||||
|
||||
// Source network address to be replaced
|
||||
#define OPENFLOW_SET_NW_SRC_WIDTH 32
|
||||
|
||||
#define OPENFLOW_SET_NW_SRC_POS 152
|
||||
|
||||
// Destination network address to be replaced
|
||||
#define OPENFLOW_SET_NW_DST_WIDTH 32
|
||||
|
||||
#define OPENFLOW_SET_NW_DST_POS 184
|
||||
|
||||
// Source transport port to be replaced
|
||||
#define OPENFLOW_SET_TP_SRC_WIDTH 16
|
||||
|
||||
#define OPENFLOW_SET_TP_SRC_POS 216
|
||||
|
||||
// Destination transport port to be replaced
|
||||
#define OPENFLOW_SET_TP_DST_WIDTH 16
|
||||
|
||||
#define OPENFLOW_SET_TP_DST_POS 232
|
||||
|
||||
// ===== File: projects/openflow_switch/include/exact_match.xml =====
|
||||
|
||||
#define OPENFLOW_EXACT_ENTRY_PKT_COUNTER_WIDTH 25
|
||||
|
||||
#define OPENFLOW_EXACT_ENTRY_PKT_COUNTER_POS 0
|
||||
|
||||
#define OPENFLOW_EXACT_ENTRY_LAST_SEEN_WIDTH 7
|
||||
|
||||
#define OPENFLOW_EXACT_ENTRY_LAST_SEEN_POS 25
|
||||
|
||||
#define OPENFLOW_EXACT_ENTRY_BYTE_COUNTER_WIDTH 32
|
||||
|
||||
#define OPENFLOW_EXACT_ENTRY_BYTE_COUNTER_POS 32
|
||||
|
||||
#define OPENFLOW_EXACT_ENTRY_HDR_BASE_POS 0x00000000
|
||||
|
||||
#define OPENFLOW_EXACT_ENTRY_COUNTERS_POS 0x00000008
|
||||
|
||||
#define OPENFLOW_EXACT_ENTRY_ACTION_BASE_POS 0x0000000a
|
||||
|
||||
// -------------------------------------
|
||||
// Modules
|
||||
// -------------------------------------
|
||||
|
||||
// Module tags
|
||||
#define CORE_BASE_ADDR 0x0000000
|
||||
#define DEV_ID_BASE_ADDR 0x0400000
|
||||
#define MDIO_BASE_ADDR 0x0440000
|
||||
#define DMA_BASE_ADDR 0x0500000
|
||||
#define MAC_GRP_0_BASE_ADDR 0x0600000
|
||||
#define MAC_GRP_1_BASE_ADDR 0x0640000
|
||||
#define MAC_GRP_2_BASE_ADDR 0x0680000
|
||||
#define MAC_GRP_3_BASE_ADDR 0x06c0000
|
||||
#define CPU_QUEUE_0_BASE_ADDR 0x0700000
|
||||
#define CPU_QUEUE_1_BASE_ADDR 0x0740000
|
||||
#define CPU_QUEUE_2_BASE_ADDR 0x0780000
|
||||
#define CPU_QUEUE_3_BASE_ADDR 0x07c0000
|
||||
#define SRAM_BASE_ADDR 0x1000000
|
||||
#define UDP_BASE_ADDR 0x2000000
|
||||
#define OPENFLOW_LOOKUP_BASE_ADDR 0x2000000
|
||||
#define IN_ARB_BASE_ADDR 0x2000100
|
||||
#define VLAN_REMOVER_BASE_ADDR 0x2000200
|
||||
#define OPL_PROCESSOR_BASE_ADDR 0x2000240
|
||||
#define HEADER_PARSER_BASE_ADDR 0x2000280
|
||||
#define MATCH_ARBITER_BASE_ADDR 0x20002c0
|
||||
#define BRAM_OQ_BASE_ADDR 0x2000300
|
||||
#define WDT_BASE_ADDR 0x2000400
|
||||
#define EXACT_MATCH_BASE_ADDR 0x2000500
|
||||
#define OPENFLOW_WILDCARD_LOOKUP_BASE_ADDR 0x2001000
|
||||
#define DRAM_BASE_ADDR 0x4000000
|
||||
|
||||
#define CPU_QUEUE_OFFSET 0x0040000
|
||||
#define MAC_GRP_OFFSET 0x0040000
|
||||
|
||||
/* ========== Registers ========== */
|
||||
|
||||
// Name: device_id (DEV_ID)
|
||||
// Description: Device identification
|
||||
// File: lib/verilog/core/utils/xml/device_id_reg.xml
|
||||
#define DEV_ID_MD5_0_REG 0x0400000
|
||||
#define DEV_ID_MD5_1_REG 0x0400004
|
||||
#define DEV_ID_MD5_2_REG 0x0400008
|
||||
#define DEV_ID_MD5_3_REG 0x040000c
|
||||
#define DEV_ID_DEVICE_ID_REG 0x0400010
|
||||
#define DEV_ID_REVISION_REG 0x0400014
|
||||
#define DEV_ID_CPCI_ID_REG 0x0400018
|
||||
#define DEV_ID_DEV_STR_0_REG 0x040001c
|
||||
#define DEV_ID_DEV_STR_1_REG 0x0400020
|
||||
#define DEV_ID_DEV_STR_2_REG 0x0400024
|
||||
#define DEV_ID_DEV_STR_3_REG 0x0400028
|
||||
#define DEV_ID_DEV_STR_4_REG 0x040002c
|
||||
#define DEV_ID_DEV_STR_5_REG 0x0400030
|
||||
#define DEV_ID_DEV_STR_6_REG 0x0400034
|
||||
#define DEV_ID_DEV_STR_7_REG 0x0400038
|
||||
#define DEV_ID_DEV_STR_8_REG 0x040003c
|
||||
#define DEV_ID_DEV_STR_9_REG 0x0400040
|
||||
#define DEV_ID_DEV_STR_10_REG 0x0400044
|
||||
#define DEV_ID_DEV_STR_11_REG 0x0400048
|
||||
#define DEV_ID_DEV_STR_12_REG 0x040004c
|
||||
#define DEV_ID_DEV_STR_13_REG 0x0400050
|
||||
#define DEV_ID_DEV_STR_14_REG 0x0400054
|
||||
#define DEV_ID_DEV_STR_15_REG 0x0400058
|
||||
#define DEV_ID_DEV_STR_16_REG 0x040005c
|
||||
#define DEV_ID_DEV_STR_17_REG 0x0400060
|
||||
#define DEV_ID_DEV_STR_18_REG 0x0400064
|
||||
#define DEV_ID_DEV_STR_19_REG 0x0400068
|
||||
#define DEV_ID_DEV_STR_20_REG 0x040006c
|
||||
#define DEV_ID_DEV_STR_21_REG 0x0400070
|
||||
#define DEV_ID_DEV_STR_22_REG 0x0400074
|
||||
#define DEV_ID_DEV_STR_23_REG 0x0400078
|
||||
#define DEV_ID_DEV_STR_24_REG 0x040007c
|
||||
|
||||
// Name: mdio (MDIO)
|
||||
// Description: MDIO interface
|
||||
// File: lib/verilog/core/io/mdio/xml/mdio.xml
|
||||
#define MDIO_PHY_0_CONTROL_REG 0x0440000
|
||||
#define MDIO_PHY_0_STATUS_REG 0x0440004
|
||||
#define MDIO_PHY_0_PHY_ID_0_REG 0x0440008
|
||||
#define MDIO_PHY_0_PHY_ID_1_REG 0x044000c
|
||||
#define MDIO_PHY_0_AUTONEGOTIATION_ADVERT_REG 0x0440010
|
||||
#define MDIO_PHY_0_AUTONEG_LINK_PARTNER_BASE_PAGE_ABILITY_REG 0x0440014
|
||||
#define MDIO_PHY_0_AUTONEG_EXPANSION_REG 0x0440018
|
||||
#define MDIO_PHY_0_AUTONEG_NEXT_PAGE_TX_REG 0x044001c
|
||||
#define MDIO_PHY_0_AUTONEG_LINK_PARTNER_RCVD_NEXT_PAGE_REG 0x0440020
|
||||
#define MDIO_PHY_0_MASTER_SLAVE_CTRL_REG 0x0440024
|
||||
#define MDIO_PHY_0_MASTER_SLAVE_STATUS_REG 0x0440028
|
||||
#define MDIO_PHY_0_PSE_CTRL_REG 0x044002c
|
||||
#define MDIO_PHY_0_PSE_STATUS_REG 0x0440030
|
||||
#define MDIO_PHY_0_MMD_ACCESS_CTRL_REG 0x0440034
|
||||
#define MDIO_PHY_0_MMD_ACCESS_STATUS_REG 0x0440038
|
||||
#define MDIO_PHY_0_EXTENDED_STATUS_REG 0x044003c
|
||||
#define MDIO_PHY_1_CONTROL_REG 0x0440080
|
||||
#define MDIO_PHY_1_STATUS_REG 0x0440084
|
||||
#define MDIO_PHY_1_PHY_ID_0_REG 0x0440088
|
||||
#define MDIO_PHY_1_PHY_ID_1_REG 0x044008c
|
||||
#define MDIO_PHY_1_AUTONEGOTIATION_ADVERT_REG 0x0440090
|
||||
#define MDIO_PHY_1_AUTONEG_LINK_PARTNER_BASE_PAGE_ABILITY_REG 0x0440094
|
||||
#define MDIO_PHY_1_AUTONEG_EXPANSION_REG 0x0440098
|
||||
#define MDIO_PHY_1_AUTONEG_NEXT_PAGE_TX_REG 0x044009c
|
||||
#define MDIO_PHY_1_AUTONEG_LINK_PARTNER_RCVD_NEXT_PAGE_REG 0x04400a0
|
||||
#define MDIO_PHY_1_MASTER_SLAVE_CTRL_REG 0x04400a4
|
||||
#define MDIO_PHY_1_MASTER_SLAVE_STATUS_REG 0x04400a8
|
||||
#define MDIO_PHY_1_PSE_CTRL_REG 0x04400ac
|
||||
#define MDIO_PHY_1_PSE_STATUS_REG 0x04400b0
|
||||
#define MDIO_PHY_1_MMD_ACCESS_CTRL_REG 0x04400b4
|
||||
#define MDIO_PHY_1_MMD_ACCESS_STATUS_REG 0x04400b8
|
||||
#define MDIO_PHY_1_EXTENDED_STATUS_REG 0x04400bc
|
||||
#define MDIO_PHY_2_CONTROL_REG 0x0440100
|
||||
#define MDIO_PHY_2_STATUS_REG 0x0440104
|
||||
#define MDIO_PHY_2_PHY_ID_0_REG 0x0440108
|
||||
#define MDIO_PHY_2_PHY_ID_1_REG 0x044010c
|
||||
#define MDIO_PHY_2_AUTONEGOTIATION_ADVERT_REG 0x0440110
|
||||
#define MDIO_PHY_2_AUTONEG_LINK_PARTNER_BASE_PAGE_ABILITY_REG 0x0440114
|
||||
#define MDIO_PHY_2_AUTONEG_EXPANSION_REG 0x0440118
|
||||
#define MDIO_PHY_2_AUTONEG_NEXT_PAGE_TX_REG 0x044011c
|
||||
#define MDIO_PHY_2_AUTONEG_LINK_PARTNER_RCVD_NEXT_PAGE_REG 0x0440120
|
||||
#define MDIO_PHY_2_MASTER_SLAVE_CTRL_REG 0x0440124
|
||||
#define MDIO_PHY_2_MASTER_SLAVE_STATUS_REG 0x0440128
|
||||
#define MDIO_PHY_2_PSE_CTRL_REG 0x044012c
|
||||
#define MDIO_PHY_2_PSE_STATUS_REG 0x0440130
|
||||
#define MDIO_PHY_2_MMD_ACCESS_CTRL_REG 0x0440134
|
||||
#define MDIO_PHY_2_MMD_ACCESS_STATUS_REG 0x0440138
|
||||
#define MDIO_PHY_2_EXTENDED_STATUS_REG 0x044013c
|
||||
#define MDIO_PHY_3_CONTROL_REG 0x0440180
|
||||
#define MDIO_PHY_3_STATUS_REG 0x0440184
|
||||
#define MDIO_PHY_3_PHY_ID_0_REG 0x0440188
|
||||
#define MDIO_PHY_3_PHY_ID_1_REG 0x044018c
|
||||
#define MDIO_PHY_3_AUTONEGOTIATION_ADVERT_REG 0x0440190
|
||||
#define MDIO_PHY_3_AUTONEG_LINK_PARTNER_BASE_PAGE_ABILITY_REG 0x0440194
|
||||
#define MDIO_PHY_3_AUTONEG_EXPANSION_REG 0x0440198
|
||||
#define MDIO_PHY_3_AUTONEG_NEXT_PAGE_TX_REG 0x044019c
|
||||
#define MDIO_PHY_3_AUTONEG_LINK_PARTNER_RCVD_NEXT_PAGE_REG 0x04401a0
|
||||
#define MDIO_PHY_3_MASTER_SLAVE_CTRL_REG 0x04401a4
|
||||
#define MDIO_PHY_3_MASTER_SLAVE_STATUS_REG 0x04401a8
|
||||
#define MDIO_PHY_3_PSE_CTRL_REG 0x04401ac
|
||||
#define MDIO_PHY_3_PSE_STATUS_REG 0x04401b0
|
||||
#define MDIO_PHY_3_MMD_ACCESS_CTRL_REG 0x04401b4
|
||||
#define MDIO_PHY_3_MMD_ACCESS_STATUS_REG 0x04401b8
|
||||
#define MDIO_PHY_3_EXTENDED_STATUS_REG 0x04401bc
|
||||
|
||||
#define MDIO_PHY_GROUP_BASE_ADDR 0x0440000
|
||||
#define MDIO_PHY_GROUP_INST_OFFSET 0x0000080
|
||||
|
||||
// Name: dma (DMA)
|
||||
// Description: DMA transfer module
|
||||
// File: lib/verilog/core/dma/xml/dma.xml
|
||||
|
||||
// Name: nf2_mac_grp (MAC_GRP_0)
|
||||
// Description: Ethernet MAC group
|
||||
// File: lib/verilog/core/io_queues/ethernet_mac/xml/ethernet_mac.xml
|
||||
#define MAC_GRP_0_CONTROL_REG 0x0600000
|
||||
#define MAC_GRP_0_RX_QUEUE_NUM_PKTS_IN_QUEUE_REG 0x0600004
|
||||
#define MAC_GRP_0_RX_QUEUE_NUM_PKTS_STORED_REG 0x0600008
|
||||
#define MAC_GRP_0_RX_QUEUE_NUM_PKTS_DROPPED_FULL_REG 0x060000c
|
||||
#define MAC_GRP_0_RX_QUEUE_NUM_PKTS_DROPPED_BAD_REG 0x0600010
|
||||
#define MAC_GRP_0_RX_QUEUE_NUM_PKTS_DEQUEUED_REG 0x0600014
|
||||
#define MAC_GRP_0_RX_QUEUE_NUM_WORDS_PUSHED_REG 0x0600018
|
||||
#define MAC_GRP_0_RX_QUEUE_NUM_BYTES_PUSHED_REG 0x060001c
|
||||
#define MAC_GRP_0_TX_QUEUE_NUM_PKTS_IN_QUEUE_REG 0x0600020
|
||||
#define MAC_GRP_0_TX_QUEUE_NUM_PKTS_ENQUEUED_REG 0x0600024
|
||||
#define MAC_GRP_0_TX_QUEUE_NUM_PKTS_SENT_REG 0x0600028
|
||||
#define MAC_GRP_0_TX_QUEUE_NUM_WORDS_PUSHED_REG 0x060002c
|
||||
#define MAC_GRP_0_TX_QUEUE_NUM_BYTES_PUSHED_REG 0x0600030
|
||||
|
||||
// Name: nf2_mac_grp (MAC_GRP_1)
|
||||
// Description: Ethernet MAC group
|
||||
// File: lib/verilog/core/io_queues/ethernet_mac/xml/ethernet_mac.xml
|
||||
#define MAC_GRP_1_CONTROL_REG 0x0640000
|
||||
#define MAC_GRP_1_RX_QUEUE_NUM_PKTS_IN_QUEUE_REG 0x0640004
|
||||
#define MAC_GRP_1_RX_QUEUE_NUM_PKTS_STORED_REG 0x0640008
|
||||
#define MAC_GRP_1_RX_QUEUE_NUM_PKTS_DROPPED_FULL_REG 0x064000c
|
||||
#define MAC_GRP_1_RX_QUEUE_NUM_PKTS_DROPPED_BAD_REG 0x0640010
|
||||
#define MAC_GRP_1_RX_QUEUE_NUM_PKTS_DEQUEUED_REG 0x0640014
|
||||
#define MAC_GRP_1_RX_QUEUE_NUM_WORDS_PUSHED_REG 0x0640018
|
||||
#define MAC_GRP_1_RX_QUEUE_NUM_BYTES_PUSHED_REG 0x064001c
|
||||
#define MAC_GRP_1_TX_QUEUE_NUM_PKTS_IN_QUEUE_REG 0x0640020
|
||||
#define MAC_GRP_1_TX_QUEUE_NUM_PKTS_ENQUEUED_REG 0x0640024
|
||||
#define MAC_GRP_1_TX_QUEUE_NUM_PKTS_SENT_REG 0x0640028
|
||||
#define MAC_GRP_1_TX_QUEUE_NUM_WORDS_PUSHED_REG 0x064002c
|
||||
#define MAC_GRP_1_TX_QUEUE_NUM_BYTES_PUSHED_REG 0x0640030
|
||||
|
||||
// Name: nf2_mac_grp (MAC_GRP_2)
|
||||
// Description: Ethernet MAC group
|
||||
// File: lib/verilog/core/io_queues/ethernet_mac/xml/ethernet_mac.xml
|
||||
#define MAC_GRP_2_CONTROL_REG 0x0680000
|
||||
#define MAC_GRP_2_RX_QUEUE_NUM_PKTS_IN_QUEUE_REG 0x0680004
|
||||
#define MAC_GRP_2_RX_QUEUE_NUM_PKTS_STORED_REG 0x0680008
|
||||
#define MAC_GRP_2_RX_QUEUE_NUM_PKTS_DROPPED_FULL_REG 0x068000c
|
||||
#define MAC_GRP_2_RX_QUEUE_NUM_PKTS_DROPPED_BAD_REG 0x0680010
|
||||
#define MAC_GRP_2_RX_QUEUE_NUM_PKTS_DEQUEUED_REG 0x0680014
|
||||
#define MAC_GRP_2_RX_QUEUE_NUM_WORDS_PUSHED_REG 0x0680018
|
||||
#define MAC_GRP_2_RX_QUEUE_NUM_BYTES_PUSHED_REG 0x068001c
|
||||
#define MAC_GRP_2_TX_QUEUE_NUM_PKTS_IN_QUEUE_REG 0x0680020
|
||||
#define MAC_GRP_2_TX_QUEUE_NUM_PKTS_ENQUEUED_REG 0x0680024
|
||||
#define MAC_GRP_2_TX_QUEUE_NUM_PKTS_SENT_REG 0x0680028
|
||||
#define MAC_GRP_2_TX_QUEUE_NUM_WORDS_PUSHED_REG 0x068002c
|
||||
#define MAC_GRP_2_TX_QUEUE_NUM_BYTES_PUSHED_REG 0x0680030
|
||||
|
||||
// Name: nf2_mac_grp (MAC_GRP_3)
|
||||
// Description: Ethernet MAC group
|
||||
// File: lib/verilog/core/io_queues/ethernet_mac/xml/ethernet_mac.xml
|
||||
#define MAC_GRP_3_CONTROL_REG 0x06c0000
|
||||
#define MAC_GRP_3_RX_QUEUE_NUM_PKTS_IN_QUEUE_REG 0x06c0004
|
||||
#define MAC_GRP_3_RX_QUEUE_NUM_PKTS_STORED_REG 0x06c0008
|
||||
#define MAC_GRP_3_RX_QUEUE_NUM_PKTS_DROPPED_FULL_REG 0x06c000c
|
||||
#define MAC_GRP_3_RX_QUEUE_NUM_PKTS_DROPPED_BAD_REG 0x06c0010
|
||||
#define MAC_GRP_3_RX_QUEUE_NUM_PKTS_DEQUEUED_REG 0x06c0014
|
||||
#define MAC_GRP_3_RX_QUEUE_NUM_WORDS_PUSHED_REG 0x06c0018
|
||||
#define MAC_GRP_3_RX_QUEUE_NUM_BYTES_PUSHED_REG 0x06c001c
|
||||
#define MAC_GRP_3_TX_QUEUE_NUM_PKTS_IN_QUEUE_REG 0x06c0020
|
||||
#define MAC_GRP_3_TX_QUEUE_NUM_PKTS_ENQUEUED_REG 0x06c0024
|
||||
#define MAC_GRP_3_TX_QUEUE_NUM_PKTS_SENT_REG 0x06c0028
|
||||
#define MAC_GRP_3_TX_QUEUE_NUM_WORDS_PUSHED_REG 0x06c002c
|
||||
#define MAC_GRP_3_TX_QUEUE_NUM_BYTES_PUSHED_REG 0x06c0030
|
||||
|
||||
// Name: cpu_dma_queue (CPU_QUEUE_0)
|
||||
// Description: CPU DMA queue
|
||||
// File: lib/verilog/core/io_queues/cpu_dma_queue/xml/cpu_dma_queue.xml
|
||||
|
||||
// Name: cpu_dma_queue (CPU_QUEUE_1)
|
||||
// Description: CPU DMA queue
|
||||
// File: lib/verilog/core/io_queues/cpu_dma_queue/xml/cpu_dma_queue.xml
|
||||
|
||||
// Name: cpu_dma_queue (CPU_QUEUE_2)
|
||||
// Description: CPU DMA queue
|
||||
// File: lib/verilog/core/io_queues/cpu_dma_queue/xml/cpu_dma_queue.xml
|
||||
|
||||
// Name: cpu_dma_queue (CPU_QUEUE_3)
|
||||
// Description: CPU DMA queue
|
||||
// File: lib/verilog/core/io_queues/cpu_dma_queue/xml/cpu_dma_queue.xml
|
||||
|
||||
// Name: SRAM (SRAM)
|
||||
// Description: SRAM
|
||||
|
||||
// Name: openflow_output_port_lookup (OPENFLOW_LOOKUP)
|
||||
// Description: Output Port Lookup for OpenFlow hardware datapath
|
||||
// File: projects/openflow_switch/include/output_port_lookup.xml
|
||||
#define OPENFLOW_LOOKUP_WILDCARD_MISSES_REG 0x2000000
|
||||
#define OPENFLOW_LOOKUP_WILDCARD_HITS_REG 0x2000004
|
||||
#define OPENFLOW_LOOKUP_EXACT_MISSES_REG 0x2000008
|
||||
#define OPENFLOW_LOOKUP_EXACT_HITS_REG 0x200000c
|
||||
#define OPENFLOW_LOOKUP_NUM_PKTS_DROPPED_0_REG 0x2000010
|
||||
#define OPENFLOW_LOOKUP_NUM_PKTS_DROPPED_1_REG 0x2000014
|
||||
#define OPENFLOW_LOOKUP_NUM_PKTS_DROPPED_2_REG 0x2000018
|
||||
#define OPENFLOW_LOOKUP_NUM_PKTS_DROPPED_3_REG 0x200001c
|
||||
#define OPENFLOW_LOOKUP_NUM_PKTS_DROPPED_4_REG 0x2000020
|
||||
#define OPENFLOW_LOOKUP_NUM_PKTS_DROPPED_5_REG 0x2000024
|
||||
#define OPENFLOW_LOOKUP_NUM_PKTS_DROPPED_6_REG 0x2000028
|
||||
#define OPENFLOW_LOOKUP_NUM_PKTS_DROPPED_7_REG 0x200002c
|
||||
#define OPENFLOW_LOOKUP_DUMY_SOFTWARE_0_REG 0x2000030
|
||||
#define OPENFLOW_LOOKUP_DUMY_SOFTWARE_1_REG 0x2000034
|
||||
#define OPENFLOW_LOOKUP_TIMER_REG 0x2000038
|
||||
|
||||
// Name: in_arb (IN_ARB)
|
||||
// Description: Round-robin input arbiter
|
||||
// File: lib/verilog/core/input_arbiter/rr_input_arbiter/xml/rr_input_arbiter.xml
|
||||
#define IN_ARB_NUM_PKTS_SENT_REG 0x2000100
|
||||
#define IN_ARB_LAST_PKT_WORD_0_HI_REG 0x2000104
|
||||
#define IN_ARB_LAST_PKT_WORD_0_LO_REG 0x2000108
|
||||
#define IN_ARB_LAST_PKT_CTRL_0_REG 0x200010c
|
||||
#define IN_ARB_LAST_PKT_WORD_1_HI_REG 0x2000110
|
||||
#define IN_ARB_LAST_PKT_WORD_1_LO_REG 0x2000114
|
||||
#define IN_ARB_LAST_PKT_CTRL_1_REG 0x2000118
|
||||
#define IN_ARB_STATE_REG 0x200011c
|
||||
|
||||
// Name: vlan_remover (VLAN_REMOVER)
|
||||
// Description: Remove vlan tag and ethtype if ethtype is vlan, and store them into module header
|
||||
// File: projects/openflow_switch/include/vlan_remover.xml
|
||||
|
||||
// Name: opl_processor (OPL_PROCESSOR)
|
||||
// Description: opl_processor
|
||||
// File: projects/openflow_switch/include/opl_processor.xml
|
||||
|
||||
// Name: header_parser (HEADER_PARSER)
|
||||
// Description: Chop ether/IP/UDP-TCP header into 11 tuples
|
||||
// File: projects/openflow_switch/include/header_parser.xml
|
||||
|
||||
// Name: match_arbiter (MATCH_ARBITER)
|
||||
// Description: Arbitration between exact and wildcard lookups results
|
||||
// File: projects/openflow_switch/include/match_arbiter.xml
|
||||
|
||||
// Name: bram_output_queues (BRAM_OQ)
|
||||
// Description: BRAM-based output queues
|
||||
// File: lib/verilog/core/output_queues/bram_output_queues/xml/bram_output_queues.xml
|
||||
#define BRAM_OQ_DISABLE_QUEUES_REG 0x2000300
|
||||
#define BRAM_OQ_QUEUE_0_NUM_PKT_BYTES_RECEIVED_REG 0x2000380
|
||||
#define BRAM_OQ_QUEUE_0_NUM_PKTS_RECEIVED_REG 0x2000384
|
||||
#define BRAM_OQ_QUEUE_0_NUM_PKTS_DROPPED_REG 0x2000388
|
||||
#define BRAM_OQ_QUEUE_0_NUM_WORDS_IN_QUEUE_REG 0x200038c
|
||||
#define BRAM_OQ_QUEUE_1_NUM_PKT_BYTES_RECEIVED_REG 0x2000390
|
||||
#define BRAM_OQ_QUEUE_1_NUM_PKTS_RECEIVED_REG 0x2000394
|
||||
#define BRAM_OQ_QUEUE_1_NUM_PKTS_DROPPED_REG 0x2000398
|
||||
#define BRAM_OQ_QUEUE_1_NUM_WORDS_IN_QUEUE_REG 0x200039c
|
||||
#define BRAM_OQ_QUEUE_2_NUM_PKT_BYTES_RECEIVED_REG 0x20003a0
|
||||
#define BRAM_OQ_QUEUE_2_NUM_PKTS_RECEIVED_REG 0x20003a4
|
||||
#define BRAM_OQ_QUEUE_2_NUM_PKTS_DROPPED_REG 0x20003a8
|
||||
#define BRAM_OQ_QUEUE_2_NUM_WORDS_IN_QUEUE_REG 0x20003ac
|
||||
#define BRAM_OQ_QUEUE_3_NUM_PKT_BYTES_RECEIVED_REG 0x20003b0
|
||||
#define BRAM_OQ_QUEUE_3_NUM_PKTS_RECEIVED_REG 0x20003b4
|
||||
#define BRAM_OQ_QUEUE_3_NUM_PKTS_DROPPED_REG 0x20003b8
|
||||
#define BRAM_OQ_QUEUE_3_NUM_WORDS_IN_QUEUE_REG 0x20003bc
|
||||
#define BRAM_OQ_QUEUE_4_NUM_PKT_BYTES_RECEIVED_REG 0x20003c0
|
||||
#define BRAM_OQ_QUEUE_4_NUM_PKTS_RECEIVED_REG 0x20003c4
|
||||
#define BRAM_OQ_QUEUE_4_NUM_PKTS_DROPPED_REG 0x20003c8
|
||||
#define BRAM_OQ_QUEUE_4_NUM_WORDS_IN_QUEUE_REG 0x20003cc
|
||||
#define BRAM_OQ_QUEUE_5_NUM_PKT_BYTES_RECEIVED_REG 0x20003d0
|
||||
#define BRAM_OQ_QUEUE_5_NUM_PKTS_RECEIVED_REG 0x20003d4
|
||||
#define BRAM_OQ_QUEUE_5_NUM_PKTS_DROPPED_REG 0x20003d8
|
||||
#define BRAM_OQ_QUEUE_5_NUM_WORDS_IN_QUEUE_REG 0x20003dc
|
||||
#define BRAM_OQ_QUEUE_6_NUM_PKT_BYTES_RECEIVED_REG 0x20003e0
|
||||
#define BRAM_OQ_QUEUE_6_NUM_PKTS_RECEIVED_REG 0x20003e4
|
||||
#define BRAM_OQ_QUEUE_6_NUM_PKTS_DROPPED_REG 0x20003e8
|
||||
#define BRAM_OQ_QUEUE_6_NUM_WORDS_IN_QUEUE_REG 0x20003ec
|
||||
#define BRAM_OQ_QUEUE_7_NUM_PKT_BYTES_RECEIVED_REG 0x20003f0
|
||||
#define BRAM_OQ_QUEUE_7_NUM_PKTS_RECEIVED_REG 0x20003f4
|
||||
#define BRAM_OQ_QUEUE_7_NUM_PKTS_DROPPED_REG 0x20003f8
|
||||
#define BRAM_OQ_QUEUE_7_NUM_WORDS_IN_QUEUE_REG 0x20003fc
|
||||
|
||||
#define BRAM_OQ_QUEUE_GROUP_BASE_ADDR 0x2000380
|
||||
#define BRAM_OQ_QUEUE_GROUP_INST_OFFSET 0x0000010
|
||||
|
||||
// Name: watchdog (WDT)
|
||||
// Description: Watchdog timer
|
||||
// File: projects/openflow_switch/include/watchdog.xml
|
||||
#define WDT_ENABLE_FLG_REG 0x2000400
|
||||
#define WDT_COUNTER_REG 0x2000404
|
||||
|
||||
// Name: exact_match (EXACT_MATCH)
|
||||
// Description: exact match lookup
|
||||
// File: projects/openflow_switch/include/exact_match.xml
|
||||
|
||||
// Name: wildcard_match (OPENFLOW_WILDCARD_LOOKUP)
|
||||
// Description: wildcard match lookup
|
||||
// File: projects/openflow_switch/include/wildcard_match.xml
|
||||
#define OPENFLOW_WILDCARD_LOOKUP_ACTION_0_REG 0x2001000
|
||||
#define OPENFLOW_WILDCARD_LOOKUP_ACTION_1_REG 0x2001004
|
||||
#define OPENFLOW_WILDCARD_LOOKUP_ACTION_2_REG 0x2001008
|
||||
#define OPENFLOW_WILDCARD_LOOKUP_ACTION_3_REG 0x200100c
|
||||
#define OPENFLOW_WILDCARD_LOOKUP_ACTION_4_REG 0x2001010
|
||||
#define OPENFLOW_WILDCARD_LOOKUP_ACTION_5_REG 0x2001014
|
||||
#define OPENFLOW_WILDCARD_LOOKUP_ACTION_6_REG 0x2001018
|
||||
#define OPENFLOW_WILDCARD_LOOKUP_ACTION_7_REG 0x200101c
|
||||
#define OPENFLOW_WILDCARD_LOOKUP_ACTION_8_REG 0x2001020
|
||||
#define OPENFLOW_WILDCARD_LOOKUP_ACTION_9_REG 0x2001024
|
||||
#define OPENFLOW_WILDCARD_LOOKUP_CMP_MASK_0_REG 0x2001028
|
||||
#define OPENFLOW_WILDCARD_LOOKUP_CMP_MASK_1_REG 0x200102c
|
||||
#define OPENFLOW_WILDCARD_LOOKUP_CMP_MASK_2_REG 0x2001030
|
||||
#define OPENFLOW_WILDCARD_LOOKUP_CMP_MASK_3_REG 0x2001034
|
||||
#define OPENFLOW_WILDCARD_LOOKUP_CMP_MASK_4_REG 0x2001038
|
||||
#define OPENFLOW_WILDCARD_LOOKUP_CMP_MASK_5_REG 0x200103c
|
||||
#define OPENFLOW_WILDCARD_LOOKUP_CMP_MASK_6_REG 0x2001040
|
||||
#define OPENFLOW_WILDCARD_LOOKUP_CMP_MASK_7_REG 0x2001044
|
||||
#define OPENFLOW_WILDCARD_LOOKUP_CMP_0_REG 0x2001048
|
||||
#define OPENFLOW_WILDCARD_LOOKUP_CMP_1_REG 0x200104c
|
||||
#define OPENFLOW_WILDCARD_LOOKUP_CMP_2_REG 0x2001050
|
||||
#define OPENFLOW_WILDCARD_LOOKUP_CMP_3_REG 0x2001054
|
||||
#define OPENFLOW_WILDCARD_LOOKUP_CMP_4_REG 0x2001058
|
||||
#define OPENFLOW_WILDCARD_LOOKUP_CMP_5_REG 0x200105c
|
||||
#define OPENFLOW_WILDCARD_LOOKUP_CMP_6_REG 0x2001060
|
||||
#define OPENFLOW_WILDCARD_LOOKUP_CMP_7_REG 0x2001064
|
||||
#define OPENFLOW_WILDCARD_LOOKUP_READ_ADDR_REG 0x2001068
|
||||
#define OPENFLOW_WILDCARD_LOOKUP_WRITE_ADDR_REG 0x200106c
|
||||
#define OPENFLOW_WILDCARD_LOOKUP_BYTES_HIT_0_REG 0x2001070
|
||||
#define OPENFLOW_WILDCARD_LOOKUP_BYTES_HIT_1_REG 0x2001074
|
||||
#define OPENFLOW_WILDCARD_LOOKUP_BYTES_HIT_2_REG 0x2001078
|
||||
#define OPENFLOW_WILDCARD_LOOKUP_BYTES_HIT_3_REG 0x200107c
|
||||
#define OPENFLOW_WILDCARD_LOOKUP_BYTES_HIT_4_REG 0x2001080
|
||||
#define OPENFLOW_WILDCARD_LOOKUP_BYTES_HIT_5_REG 0x2001084
|
||||
#define OPENFLOW_WILDCARD_LOOKUP_BYTES_HIT_6_REG 0x2001088
|
||||
#define OPENFLOW_WILDCARD_LOOKUP_BYTES_HIT_7_REG 0x200108c
|
||||
#define OPENFLOW_WILDCARD_LOOKUP_BYTES_HIT_8_REG 0x2001090
|
||||
#define OPENFLOW_WILDCARD_LOOKUP_BYTES_HIT_9_REG 0x2001094
|
||||
#define OPENFLOW_WILDCARD_LOOKUP_BYTES_HIT_10_REG 0x2001098
|
||||
#define OPENFLOW_WILDCARD_LOOKUP_BYTES_HIT_11_REG 0x200109c
|
||||
#define OPENFLOW_WILDCARD_LOOKUP_BYTES_HIT_12_REG 0x20010a0
|
||||
#define OPENFLOW_WILDCARD_LOOKUP_BYTES_HIT_13_REG 0x20010a4
|
||||
#define OPENFLOW_WILDCARD_LOOKUP_BYTES_HIT_14_REG 0x20010a8
|
||||
#define OPENFLOW_WILDCARD_LOOKUP_BYTES_HIT_15_REG 0x20010ac
|
||||
#define OPENFLOW_WILDCARD_LOOKUP_BYTES_HIT_16_REG 0x20010b0
|
||||
#define OPENFLOW_WILDCARD_LOOKUP_BYTES_HIT_17_REG 0x20010b4
|
||||
#define OPENFLOW_WILDCARD_LOOKUP_BYTES_HIT_18_REG 0x20010b8
|
||||
#define OPENFLOW_WILDCARD_LOOKUP_BYTES_HIT_19_REG 0x20010bc
|
||||
#define OPENFLOW_WILDCARD_LOOKUP_BYTES_HIT_20_REG 0x20010c0
|
||||
#define OPENFLOW_WILDCARD_LOOKUP_BYTES_HIT_21_REG 0x20010c4
|
||||
#define OPENFLOW_WILDCARD_LOOKUP_BYTES_HIT_22_REG 0x20010c8
|
||||
#define OPENFLOW_WILDCARD_LOOKUP_BYTES_HIT_23_REG 0x20010cc
|
||||
#define OPENFLOW_WILDCARD_LOOKUP_BYTES_HIT_24_REG 0x20010d0
|
||||
#define OPENFLOW_WILDCARD_LOOKUP_BYTES_HIT_25_REG 0x20010d4
|
||||
#define OPENFLOW_WILDCARD_LOOKUP_BYTES_HIT_26_REG 0x20010d8
|
||||
#define OPENFLOW_WILDCARD_LOOKUP_BYTES_HIT_27_REG 0x20010dc
|
||||
#define OPENFLOW_WILDCARD_LOOKUP_BYTES_HIT_28_REG 0x20010e0
|
||||
#define OPENFLOW_WILDCARD_LOOKUP_BYTES_HIT_29_REG 0x20010e4
|
||||
#define OPENFLOW_WILDCARD_LOOKUP_BYTES_HIT_30_REG 0x20010e8
|
||||
#define OPENFLOW_WILDCARD_LOOKUP_BYTES_HIT_31_REG 0x20010ec
|
||||
#define OPENFLOW_WILDCARD_LOOKUP_PKTS_HIT_0_REG 0x20010f0
|
||||
#define OPENFLOW_WILDCARD_LOOKUP_PKTS_HIT_1_REG 0x20010f4
|
||||
#define OPENFLOW_WILDCARD_LOOKUP_PKTS_HIT_2_REG 0x20010f8
|
||||
#define OPENFLOW_WILDCARD_LOOKUP_PKTS_HIT_3_REG 0x20010fc
|
||||
#define OPENFLOW_WILDCARD_LOOKUP_PKTS_HIT_4_REG 0x2001100
|
||||
#define OPENFLOW_WILDCARD_LOOKUP_PKTS_HIT_5_REG 0x2001104
|
||||
#define OPENFLOW_WILDCARD_LOOKUP_PKTS_HIT_6_REG 0x2001108
|
||||
#define OPENFLOW_WILDCARD_LOOKUP_PKTS_HIT_7_REG 0x200110c
|
||||
#define OPENFLOW_WILDCARD_LOOKUP_PKTS_HIT_8_REG 0x2001110
|
||||
#define OPENFLOW_WILDCARD_LOOKUP_PKTS_HIT_9_REG 0x2001114
|
||||
#define OPENFLOW_WILDCARD_LOOKUP_PKTS_HIT_10_REG 0x2001118
|
||||
#define OPENFLOW_WILDCARD_LOOKUP_PKTS_HIT_11_REG 0x200111c
|
||||
#define OPENFLOW_WILDCARD_LOOKUP_PKTS_HIT_12_REG 0x2001120
|
||||
#define OPENFLOW_WILDCARD_LOOKUP_PKTS_HIT_13_REG 0x2001124
|
||||
#define OPENFLOW_WILDCARD_LOOKUP_PKTS_HIT_14_REG 0x2001128
|
||||
#define OPENFLOW_WILDCARD_LOOKUP_PKTS_HIT_15_REG 0x200112c
|
||||
#define OPENFLOW_WILDCARD_LOOKUP_PKTS_HIT_16_REG 0x2001130
|
||||
#define OPENFLOW_WILDCARD_LOOKUP_PKTS_HIT_17_REG 0x2001134
|
||||
#define OPENFLOW_WILDCARD_LOOKUP_PKTS_HIT_18_REG 0x2001138
|
||||
#define OPENFLOW_WILDCARD_LOOKUP_PKTS_HIT_19_REG 0x200113c
|
||||
#define OPENFLOW_WILDCARD_LOOKUP_PKTS_HIT_20_REG 0x2001140
|
||||
#define OPENFLOW_WILDCARD_LOOKUP_PKTS_HIT_21_REG 0x2001144
|
||||
#define OPENFLOW_WILDCARD_LOOKUP_PKTS_HIT_22_REG 0x2001148
|
||||
#define OPENFLOW_WILDCARD_LOOKUP_PKTS_HIT_23_REG 0x200114c
|
||||
#define OPENFLOW_WILDCARD_LOOKUP_PKTS_HIT_24_REG 0x2001150
|
||||
#define OPENFLOW_WILDCARD_LOOKUP_PKTS_HIT_25_REG 0x2001154
|
||||
#define OPENFLOW_WILDCARD_LOOKUP_PKTS_HIT_26_REG 0x2001158
|
||||
#define OPENFLOW_WILDCARD_LOOKUP_PKTS_HIT_27_REG 0x200115c
|
||||
#define OPENFLOW_WILDCARD_LOOKUP_PKTS_HIT_28_REG 0x2001160
|
||||
#define OPENFLOW_WILDCARD_LOOKUP_PKTS_HIT_29_REG 0x2001164
|
||||
#define OPENFLOW_WILDCARD_LOOKUP_PKTS_HIT_30_REG 0x2001168
|
||||
#define OPENFLOW_WILDCARD_LOOKUP_PKTS_HIT_31_REG 0x200116c
|
||||
#define OPENFLOW_WILDCARD_LOOKUP_DUMMY_1_REG 0x2001170
|
||||
#define OPENFLOW_WILDCARD_LOOKUP_DUMMY_2_REG 0x2001174
|
||||
#define OPENFLOW_WILDCARD_LOOKUP_LAST_SEEN_TS_0_REG 0x2001178
|
||||
#define OPENFLOW_WILDCARD_LOOKUP_LAST_SEEN_TS_1_REG 0x200117c
|
||||
#define OPENFLOW_WILDCARD_LOOKUP_LAST_SEEN_TS_2_REG 0x2001180
|
||||
#define OPENFLOW_WILDCARD_LOOKUP_LAST_SEEN_TS_3_REG 0x2001184
|
||||
#define OPENFLOW_WILDCARD_LOOKUP_LAST_SEEN_TS_4_REG 0x2001188
|
||||
#define OPENFLOW_WILDCARD_LOOKUP_LAST_SEEN_TS_5_REG 0x200118c
|
||||
#define OPENFLOW_WILDCARD_LOOKUP_LAST_SEEN_TS_6_REG 0x2001190
|
||||
#define OPENFLOW_WILDCARD_LOOKUP_LAST_SEEN_TS_7_REG 0x2001194
|
||||
#define OPENFLOW_WILDCARD_LOOKUP_LAST_SEEN_TS_8_REG 0x2001198
|
||||
#define OPENFLOW_WILDCARD_LOOKUP_LAST_SEEN_TS_9_REG 0x200119c
|
||||
#define OPENFLOW_WILDCARD_LOOKUP_LAST_SEEN_TS_10_REG 0x20011a0
|
||||
#define OPENFLOW_WILDCARD_LOOKUP_LAST_SEEN_TS_11_REG 0x20011a4
|
||||
#define OPENFLOW_WILDCARD_LOOKUP_LAST_SEEN_TS_12_REG 0x20011a8
|
||||
#define OPENFLOW_WILDCARD_LOOKUP_LAST_SEEN_TS_13_REG 0x20011ac
|
||||
#define OPENFLOW_WILDCARD_LOOKUP_LAST_SEEN_TS_14_REG 0x20011b0
|
||||
#define OPENFLOW_WILDCARD_LOOKUP_LAST_SEEN_TS_15_REG 0x20011b4
|
||||
#define OPENFLOW_WILDCARD_LOOKUP_LAST_SEEN_TS_16_REG 0x20011b8
|
||||
#define OPENFLOW_WILDCARD_LOOKUP_LAST_SEEN_TS_17_REG 0x20011bc
|
||||
#define OPENFLOW_WILDCARD_LOOKUP_LAST_SEEN_TS_18_REG 0x20011c0
|
||||
#define OPENFLOW_WILDCARD_LOOKUP_LAST_SEEN_TS_19_REG 0x20011c4
|
||||
#define OPENFLOW_WILDCARD_LOOKUP_LAST_SEEN_TS_20_REG 0x20011c8
|
||||
#define OPENFLOW_WILDCARD_LOOKUP_LAST_SEEN_TS_21_REG 0x20011cc
|
||||
#define OPENFLOW_WILDCARD_LOOKUP_LAST_SEEN_TS_22_REG 0x20011d0
|
||||
#define OPENFLOW_WILDCARD_LOOKUP_LAST_SEEN_TS_23_REG 0x20011d4
|
||||
#define OPENFLOW_WILDCARD_LOOKUP_LAST_SEEN_TS_24_REG 0x20011d8
|
||||
#define OPENFLOW_WILDCARD_LOOKUP_LAST_SEEN_TS_25_REG 0x20011dc
|
||||
#define OPENFLOW_WILDCARD_LOOKUP_LAST_SEEN_TS_26_REG 0x20011e0
|
||||
#define OPENFLOW_WILDCARD_LOOKUP_LAST_SEEN_TS_27_REG 0x20011e4
|
||||
#define OPENFLOW_WILDCARD_LOOKUP_LAST_SEEN_TS_28_REG 0x20011e8
|
||||
#define OPENFLOW_WILDCARD_LOOKUP_LAST_SEEN_TS_29_REG 0x20011ec
|
||||
#define OPENFLOW_WILDCARD_LOOKUP_LAST_SEEN_TS_30_REG 0x20011f0
|
||||
#define OPENFLOW_WILDCARD_LOOKUP_LAST_SEEN_TS_31_REG 0x20011f4
|
||||
|
||||
// Name: DRAM (DRAM)
|
||||
// Description: DRAM
|
||||
|
||||
#endif
|
||||
@@ -230,23 +230,8 @@ sub setup_NF2 {
|
||||
|
||||
setup_pcap_interfaces();
|
||||
|
||||
# verify kernel module not loaded
|
||||
my $of_kmod_loaded = `lsmod | grep ofdatapath`;
|
||||
if ( $of_kmod_loaded ne "" ) {
|
||||
print "$of_kmod_loaded\n";
|
||||
print "openflow kernel module already loaded... please fix!\n";
|
||||
exit 1;
|
||||
}
|
||||
|
||||
# verify controller not already running
|
||||
my $controller_loaded = `ps -A | grep controller`;
|
||||
if ( $controller_loaded ne "" ) {
|
||||
print "controller already loaded... please remove and try again!\n";
|
||||
exit 1;
|
||||
}
|
||||
|
||||
# load the openflow bitfile on the NetFPGA
|
||||
system("nf2_download ${openflow_dir}/datapath/hwtable_nf2/openflow_switch.bit");
|
||||
system("nf2_download ${openflow_dir}/hw-lib/nf2/openflow_switch.bit");
|
||||
sleep(2);
|
||||
|
||||
# turn on phy(0-3) interrupt mask
|
||||
@@ -257,22 +242,18 @@ sub setup_NF2 {
|
||||
`regwrite 0x04c01ec 0xffff`;
|
||||
|
||||
# create openflow switch on four ports
|
||||
`insmod ${openflow_dir}/datapath/linux-2.6/ofdatapath.ko`;
|
||||
|
||||
# add the hardware kernel module
|
||||
`insmod ${openflow_dir}/${nf2_kernel_module_path}/${nf2_kernel_module_name}`;
|
||||
|
||||
`${openflow_dir}/utilities/dpctl adddp nl:0`;
|
||||
print "added datapath\n";
|
||||
|
||||
for ( my $i = 5 ; $i <= 8 ; $i++ ) {
|
||||
my $iface = nftest_get_iface("eth$i");
|
||||
print "${openflow_dir}/utilities/dpctl addif nl:0 $iface";
|
||||
`${openflow_dir}/utilities/dpctl addif nl:0 $iface`;
|
||||
print "added interface\n";
|
||||
my $if_string = '';
|
||||
for (my $i = 5 ; $i <= 7 ; $i++) {
|
||||
$if_string .= nftest_get_iface("eth$i") . ',';
|
||||
}
|
||||
$if_string .= nftest_get_iface("eth8");
|
||||
|
||||
start_ofprotocol("nl:0", @_);
|
||||
print "about to create ofdatapath` punix:/var/run/test -i $if_string \& \n";
|
||||
system("${openflow_dir}/udatapath/ofdatapath punix:/var/run/test -i $if_string \&");
|
||||
|
||||
sleep(1);
|
||||
|
||||
start_ofprotocol("unix:/var/run/test", @_);
|
||||
}
|
||||
|
||||
|
||||
@@ -335,44 +316,7 @@ sub teardown_kmod {
|
||||
}
|
||||
|
||||
sub teardown_NF2 {
|
||||
|
||||
# check that we're root?
|
||||
my $who = `whoami`;
|
||||
if ( trim($who) ne 'root' ) { die "must be root\n"; }
|
||||
|
||||
`killall ofprotocol`;
|
||||
|
||||
# check if openflow kernel module loaded
|
||||
my $of_kmod_loaded = `lsmod | grep ofdatapath`;
|
||||
if ( $of_kmod_loaded eq "" ) { exit 0; }
|
||||
|
||||
print "tearing down interfaces and datapaths\n";
|
||||
|
||||
# remove interfaces from openflow
|
||||
for ( my $i = 5 ; $i <= 8 ; $i++ ) {
|
||||
my $iface = nftest_get_iface("eth$i");
|
||||
`${openflow_dir}/utilities/dpctl delif nl:0 $iface`;
|
||||
}
|
||||
|
||||
`${openflow_dir}/utilities/dpctl deldp nl:0`;
|
||||
|
||||
# tear down the NF2 module
|
||||
my $of_hw_kmod_removed = `rmmod ${nf2_kernel_module_name_no_ext}`;
|
||||
if ( $of_hw_kmod_removed ne "" ) {
|
||||
die "failed to remove hardware kernel module... please fix!\n";
|
||||
}
|
||||
|
||||
my $of_kmod_removed = `rmmod ofdatapath`;
|
||||
if ( $of_kmod_removed ne "" ) {
|
||||
die "failed to remove kernel module... please fix!\n";
|
||||
}
|
||||
|
||||
$of_kmod_loaded = `lsmod | grep ofdatapath`;
|
||||
if ( $of_kmod_loaded ne "" ) {
|
||||
die "failed to remove kernel module... please fix!\n";
|
||||
}
|
||||
|
||||
exit 0;
|
||||
teardown_user();
|
||||
}
|
||||
|
||||
sub teardown_user {
|
||||
|
||||
Reference in new issue
Block a user