Adapt NetFPGA implementation to the userspace hardware platform

This commit is contained in:
Tatsuya Yabe authored and Glen Gibb committed 2010-05-03 15:54:37 -07:00
1 parent 6778bd8cdf
commit 2e38251708
15 files changed
+4516 -88

No files matched your search

+18 -20
View File
@@ -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
+56
View File
@@ -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/
+105
View File
@@ -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 */
+510
View File
@@ -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;
}
+56
View File
@@ -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
+452
View File
@@ -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
+847
View File
@@ -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;
}
+150
View File
@@ -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
+1036
View File
File diff suppressed because it is too large. Load diff
+59
View File
@@ -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
+402
View File
@@ -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;
}
+46
View File
@@ -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.
+767
View File
@@ -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
+12 -68
View File
@@ -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 {