Commit 2e9542b1 authored by Tomasz Wlostowski's avatar Tomasz Wlostowski Committed by Alessandro Rubini

userspace/wrsw_rtud: re-done register layout for N-port generic RTU

parent 00ce398d
......@@ -7,10 +7,10 @@
* Authors: Juan Luis Manas (juan.manas@integrasys.es)
* Maciej Lipinski (maciej.lipinski@cern.ch)
*
* Description: RTU data structures definition.
* Description: RTU data structures definition.
*
* Fixes:
* Tomasz Wlostowski
* Fixes:
* Tomasz Wlostowski
*
*
* This program is free software; you can redistribute it and/or
......@@ -39,16 +39,13 @@
#include "mac.h"
#define RTU_BANKS 2
#define RTU_ENTRIES 2048
#define RTU_BUCKETS 4
#define LAST_RTU_BUCKET ((RTU_BUCKETS)-1)
#define RTU_ENTRIES (16384/(RTU_BANKS))
#define HTAB_ENTRIES ((RTU_ENTRIES)/(RTU_BUCKETS))
#define LAST_HTAB_ENTRY ((HTAB_ENTRIES)-1)
#define LAST_RTU_BUCKET (RTU_BUCKETS-1)
#define ENTRY_WORDS 8
#define CAM_ENTRIES (((RTU_HCAM_WORDS)/(ENTRY_WORDS))/(RTU_BANKS))
#define LAST_CAM_ENTRY ((CAM_ENTRIES)-1)
#define MIN_PORT 0
#define MAX_PORT 9
......@@ -80,11 +77,11 @@
*/
struct rtu_request {
int port_id; // physical port identifier
uint8_t src[ETH_ALEN]; // source MAC address
uint8_t src[ETH_ALEN]; // source MAC address
uint8_t dst[ETH_ALEN]; // destination MAC address
uint16_t vid; // VLAN ID from the packet header
int has_vid; // non-zero: VID is present,0:untagged packet (VID=0)
uint8_t prio; // packet priority (either assigned by the port
uint8_t prio; // packet priority (either assigned by the port
// or extracted from packet header)
int has_prio; // non-zero: priority present, 0:no priority defined
};
......@@ -93,36 +90,36 @@ struct rtu_request {
* \brief RTU Filtering Database Entry Object
*/
struct filtering_entry {
int valid; // bit: 1 = entry is valid, 0: entry is
int valid; // bit: 1 = entry is valid, 0: entry is
// invalid (empty)
int end_of_bucket; // bit: 1 = last entry in current bucket, stop
// search at this point
int is_bpdu; // bit: 1 = BPDU (or other non-STP-dependent
int is_bpdu; // bit: 1 = BPDU (or other non-STP-dependent
// packet)
uint8_t mac[ETH_ALEN]; // MAC address (for searching the bucketed
uint8_t mac[ETH_ALEN]; // MAC address (for searching the bucketed
// hashtable)
uint8_t fid; // Filtering database ID (for searching the
// bucketed hashtable)
uint32_t port_mask_src; // port mask for source MAC addresses. Bits
// set to 1 indicate that packet having this
// MAC address can be forwarded from these
// corresponding ports. Ports having their
uint32_t port_mask_src; // port mask for source MAC addresses. Bits
// set to 1 indicate that packet having this
// MAC address can be forwarded from these
// corresponding ports. Ports having their
// bits set to 0 shall drop the packet.
uint32_t port_mask_dst; // port mask for destination MAC address. Bits
// set to 1 indicate to which physical ports
// the packet with matching destination MAC
// the packet with matching destination MAC
// address shall be routed
int drop_when_source; // bit: 1 = drop the packet when source
int drop_when_source; // bit: 1 = drop the packet when source
// address matches
int drop_when_dest; // bit: 1 = drop the packet when destination
int drop_when_dest; // bit: 1 = drop the packet when destination
// address matches
int drop_unmatched_src_ports; // bit: 1 = drop the packet when it comes from
// source port different than specified in
// port_mask_src
// source port different than specified in
// port_mask_src
uint32_t last_access_t; // time of last access to the rule (for aging)
......@@ -134,10 +131,10 @@ struct filtering_entry {
int has_prio_dst; // priority value valid
int prio_override_dst; // priority override (force per-MAC priority)
int go_to_cam; // 1 : there are more entries outside the
int go_to_cam; // 1 : there are more entries outside the
// bucket
uint16_t cam_addr; // address of the first entry in CAM memory
uint16_t cam_addr; // address of the first entry in CAM memory
// (2 words)
int dynamic;
......@@ -148,7 +145,7 @@ struct filtering_entry {
*/
struct vlan_table_entry {
uint32_t port_mask; // VLAN port mask: 1 = ports assigned to this VLAN
uint8_t fid; // Filtering Database Identifier
uint8_t fid; // Filtering Database Identifier
uint8_t prio; // VLAN priority
int has_prio; // priority defined;
int prio_override; // priority override (force per-VLAN priority)
......@@ -159,9 +156,9 @@ struct vlan_table_entry {
* \brief Copies src filtering entry body into dst filtering entry body.
* @return pointer to dst filtering entry.
*/
static inline
struct filtering_entry *rtu_fe_copy( struct filtering_entry *dst,
struct filtering_entry *src )
static inline
struct filtering_entry *rtu_fe_copy( struct filtering_entry *dst,
struct filtering_entry *src )
{
return memcpy( dst, src, sizeof(*src) );
}
......@@ -171,8 +168,8 @@ struct filtering_entry *rtu_fe_copy( struct filtering_entry *dst,
* @param ent pointer to entry to clean (either in HCAM or HTAB)
* @return pointer to filtering entry that was cleaned
*/
static inline
struct filtering_entry *rtu_fe_clean(struct filtering_entry *ent)
static inline
struct filtering_entry *rtu_fe_clean(struct filtering_entry *ent)
{
return memset( ent, 0, sizeof(*ent) );
}
......@@ -180,13 +177,13 @@ struct filtering_entry *rtu_fe_clean(struct filtering_entry *ent)
/**
* \brief Returns number of seconds since the epoch.
*/
static inline
unsigned long now()
static inline
unsigned long now()
{
return (unsigned long) time(NULL);
return (unsigned long) time(NULL);
}
int rtud_init_exports();
void rtud_handle_wripc();
#endif /*__WHITERABBIT_RTU_H*/
This diff is collapsed.
......@@ -33,11 +33,6 @@
#include "rtu.h"
// HW RTU (should be given by wrsw_rtu_wb.h)
#define RTU_HCAM 0x4000
#define RTU_ARAM_MAIN 0x8000
#define RTU_VLAN_TAB 0xc000
#define RTU_MFIFO_R0_DATA_SEL 0x00000000
#define RTU_MFIFO_R1_ADDR_MASK 0x0007FFFF
......
This diff is collapsed.
......@@ -8,9 +8,9 @@
* Miguel Baizan (miguel.baizan@integrasys.es)
* Maciej Lipinski (maciej.lipinski@cern.ch)
*
* Description: RTU Filtering database header.
* Filtering database management related operations and filtering
* database mirror. Note there is a single Filtering Database
* Description: RTU Filtering database header.
* Filtering database management related operations and filtering
* database mirror. Note there is a single Filtering Database
* object per Bridge (See 802.1Q - 12.7.1)
*
* Fixes:
......@@ -40,13 +40,13 @@
#define STATIC 0
#define DYNAMIC 1
int rtu_fd_init(uint16_t poly, unsigned long aging)
int rtu_fd_init(uint16_t poly, unsigned long aging)
__attribute__((warn_unused_result));
int rtu_fd_create_entry(
uint8_t mac[ETH_ALEN],
uint16_t vid,
uint32_t port_map,
uint8_t mac[ETH_ALEN],
uint16_t vid,
uint32_t port_map,
int dynamic
) __attribute__((warn_unused_result));
......
......@@ -6,8 +6,8 @@
*
* Authors: Maciej Lipinski (maciej.lipinski@cern.ch)
*
* Description: Hash function presented below, produces hash which corresponds
* to hash produced by VHDL generated on this page:
* Description: Hash function presented below, produces hash which corresponds
* to hash produced by VHDL generated on this page:
* http://outputlogic.com/
*
* Fixes:
......@@ -28,6 +28,8 @@
*/
#include <hw/trace.h>
#include "rtu.h"
#include "rtu_hash.h"
......@@ -47,53 +49,53 @@ void rtu_hash_set_poly(uint16_t poly)
uint16_t rtu_hash(uint8_t mac[ETH_ALEN], uint8_t fid)
{
uint16_t hash = 0xFFFF;
hash = crc16(hash, (0xFFFF & fid));
hash = crc16(hash, ((uint16_t)mac[0] << 8) | mac[1]);
hash = crc16(hash, ((uint16_t)mac[2] << 8) | mac[3]);
hash = crc16(hash, ((uint16_t)mac[4] << 8) | mac[5]);
return hash & 0x7FF; // trim to fit in ZBT SRAM addr
return hash & (HTAB_ENTRIES - 1); /* warning: assumes that HTAB_ENTRIES is a power of 2 */
}
/*
-------------------------------------------------------------------------------
-- SOME EXPLANATION REGARDING VHDL vs C CRC IMPLEMENTATION BY ML
-------------------------------------------------------------------------------
-- C code to produce exactly the same CRC as VHDL generated
-- C code to produce exactly the same CRC as VHDL generated
-- with http://outputlogic.com/ .
-- it uses naive method, it's not optimal at all
-- but it's good enough to chech whether VHDL works OK
-- It was made (by maciej.lipinski@cern.ch) modifying source from here:
-- http://www.netrino.com/Embedded-Systems/How-To/CRC-Calculation-C-Code
-- the website provides explanation of CRC
--
-- To get the hex representation of POLY to be used with the C function, which
-- is different than hex representation of polly used to generate VHDL code
--
-- To get the hex representation of POLY to be used with the C function, which
-- is different than hex representation of polly used to generate VHDL code
-- (i.e.:0x1021 <->0x88108), here is the trick:
--
-- 1) we are using the following poly equation: 1+x^5+x^12+x^16;
-- 2) it translates to binary: (1) 0001 0000 0010 0001 = 0x1021
-- 2) it translates to binary: (1) 0001 0000 0010 0001 = 0x1021
-- | |
-- | this is default | this you can find in
-- | this is default | this you can find in
-- |-> it's the 16th bit |-> the wiki as description
-- of the polly equation
--
--
-- 3) we include the "default" bit into the polly and add zeroes at the end
-- creating 20 bit polly, like this
-- (1) 0001 0000 0010 0001 => 1000 1000 0001 0000 1000 = 0x88108
-- (1) 0001 0000 0010 0001 => 1000 1000 0001 0000 1000 = 0x88108
--
--------------------------------------------------------------------------------
--| name | polly equation | polly (hex) | our polly | tested |
--------------------------------------------------------------------------------
--| CRC-16-CCITT | 1+x^5+x^12+x^16 | 0x1021 | 0x88108 | yes |
--| CRC-16-IBM | 1+x^2+x^15+x^16 | 0x8005 | 0xC0028 | yes |
--| CRC-16-DECT | 1+x^3+x^7+x^8+x^10+x^16 | 0x0589 | 0x82C48 | yes |
--| CRC-16-DECT | 1+x^3+x^7+x^8+x^10+x^16 | 0x0589 | 0x82C48 | yes |
--------------------------------------------------------------------------------
*/
static uint16_t crc16(uint16_t const init_crc, uint16_t const message)
{
uint32_t remainder;
uint32_t remainder;
int bit;
// Initially, the dividend is the remainder.
......
......@@ -6,8 +6,8 @@
*
* Authors: Maciej Lipinski (maciej.lipinski@cern.ch)
*
* Description: Hash function presented below, produces hash which corresponds
* to hash produced by VHDL generated on this page:
* Description: Hash function presented below, produces hash which corresponds
* to hash produced by VHDL generated on this page:
* http://outputlogic.com/
*
* Fixes:
......@@ -34,16 +34,16 @@
/*
Hash polynomials implemented by RTU
---------------------------------------------------------
| name | poly equation | poly (hex) |
| name | poly equation | poly (hex) |
---------------------------------------------------------
| CRC-16-CCITT | 1+x^5+x^12+x^16 | 0x1021 |
| CRC-16-IBM | 1+x^2+x^15+x^16 | 0x8005 |
| CRC-16-DECT | 1+x^3+x^7+x^8+x^10+x^16 | 0x0589 |
---------------------------------------------------------
*/
#define HW_POLYNOMIAL_CCITT 0x1021
#define HW_POLYNOMIAL_IBM 0x8005
#define HW_POLYNOMIAL_DECT 0x0589
#define HW_POLYNOMIAL_CCITT 0x1021
#define HW_POLYNOMIAL_IBM 0x8005
#define HW_POLYNOMIAL_DECT 0x0589
void rtu_hash_set_poly(uint16_t poly);
uint16_t rtu_hash(uint8_t mac[ETH_ALEN], uint8_t fid);
......
......@@ -7,14 +7,14 @@
* Authors: Juan Luis Manas (juan.manas@integrasys.es)
* Miguel Baizan (miguel.baizan@integrasys.es)
*
* Description: RTU daemon.
* Handles the learning and aging processes.
* Description: RTU daemon.
* Handles the learning and aging processes.
* Manages the filtering and VLAN databases.
*
* Fixes:
* Fixes:
* Alessandro Rubini
* Tomasz Wlostowski
*
* Tomasz Wlostowski
*
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
......@@ -50,7 +50,7 @@ static pthread_t aging_process;
static pthread_t wripc_process;
/**
* \brief Creates the static entries in the filtering database
* \brief Creates the static entries in the filtering database
* @return error code
*/
static int rtu_create_static_entries()
......@@ -66,7 +66,7 @@ static int rtu_create_static_entries()
err = rtu_fd_create_entry(bcast_mac, 0, 0xffffffff, STATIC);
if(err)
return err;
// VLAN-aware Bridge reserved addresses (802.1Q-2005 Table 8.1)
TRACE(TRACE_INFO,"adding static routes for slow protocols...");
for(i = 0; i < NUM_RESERVED_ADDR; i++) {
......@@ -75,16 +75,16 @@ static int rtu_create_static_entries()
if(err)
return err;
}
// packets addressed to WR card interfaces are forwarded to NIC virtual port
halexp_query_ports(&plist);
halexp_query_ports(&plist);
for(i = 0; i < plist.num_ports; i++) {
halexp_get_port_state(&pstate, plist.port_names[i]);
halexp_get_port_state(&pstate, plist.port_names[i]);
TRACE(
TRACE_INFO,
"adding static route for port %s index %d [mac %s]",
plist.port_names[i],
pstate.hw_index,
"adding static route for port %s index %d [mac %s]",
plist.port_names[i],
pstate.hw_index,
mac_to_string(pstate.hw_addr)
);
err = rtu_fd_create_entry(pstate.hw_addr, 0, (1 << NIC_PORT), STATIC);
......@@ -122,18 +122,18 @@ static void *rtu_daemon_wripc_process(void *arg)
{
while(1){
rtud_handle_wripc();
sleep(1);
usleep(10000);
}
return NULL;
}
/**
* \brief Handles the learning process.
* \brief Handles the learning process.
* @return error code
*/
static int rtu_daemon_learning_process()
{
int err;
int err;
struct rtu_request req; // Request read from learning queue
uint32_t port_map; // Destination port map
uint16_t vid; // VLAN identifier
......@@ -144,8 +144,8 @@ static int rtu_daemon_learning_process()
if (!err) {
TRACE_DBG(
TRACE_INFO,
"ureq: port %d src %s VID %d priority %d",
req.port_id,
"ureq: port %d src %s VID %d priority %d",
req.port_id,
mac_to_string(req.src),
req.has_vid ? req.vid:0,
req.has_prio ? req.prio:0
......@@ -171,7 +171,7 @@ static int rtu_daemon_learning_process()
/**
* \brief RTU set up.
* \brief RTU set up.
* Initialises routing table cache and RTU at hardware.
* @param poly hash polinomial.
* @param aging_time Aging time in seconds.
......@@ -195,7 +195,6 @@ static int rtu_daemon_init(uint16_t poly, unsigned long aging_time)
TRACE(TRACE_INFO, "init port config.");
for(i = MIN_PORT; i <= MAX_PORT; i++) {
// MIN_PORT <= port <= MAX_PORT, thus no err returned
fprintf(stderr,"**4**");
err = rtu_learn_enable_on_port(i,1);
err = rtu_pass_all_on_port(i,1);
......@@ -207,7 +206,7 @@ static int rtu_daemon_init(uint16_t poly, unsigned long aging_time)
// init filtering database
TRACE(TRACE_INFO, "init fd.");
err = rtu_fd_init(poly, aging_time);
if (err)
if (err)
return err;
// create static filtering entries
......@@ -228,7 +227,7 @@ static int rtu_daemon_init(uint16_t poly, unsigned long aging_time)
* \brief RTU shutdown.
*/
static void rtu_daemon_destroy()
{
{
// Threads stuff
pthread_cancel(wripc_process);
pthread_cancel(aging_process);
......@@ -245,11 +244,11 @@ void sigint(int signum) {
/**
* \brief Starts up the learning and aging processes.
*/
*/
int main(int argc, char **argv)
{
int op, err;
char *s, *name, *optstring;
char *s, *name, *optstring;
int run_as_daemon = 0;
uint16_t poly = HW_POLYNOMIAL_CCITT; // Hash polinomial
unsigned long aging_res = DEFAULT_AGING_RES; // Aging resolution [sec.]
......@@ -272,7 +271,7 @@ int main(int argc, char **argv)
run_as_daemon = 1;
break;
case 'h':
usage(name);
usage(name);
case 'p':
if (strcmp(optarg, "CCITT") == 0) {
poly = HW_POLYNOMIAL_CCITT;
......@@ -293,7 +292,7 @@ int main(int argc, char **argv)
break;
case 't':
aging_time = atol(optarg);
if ((aging_time < MIN_AGING_TIME) ||
if ((aging_time < MIN_AGING_TIME) ||
(aging_time > MAX_AGING_TIME)) {
fprintf(stderr, "Invalid aging time\n");
usage(name);
......@@ -305,7 +304,7 @@ int main(int argc, char **argv)
}
}
// Initialise RTU.
// Initialise RTU.
if((err = rtu_daemon_init(poly, aging_time)) < 0) {
rtu_daemon_destroy();
return err;
......@@ -315,7 +314,7 @@ int main(int argc, char **argv)
signal(SIGINT, sigint);
// daemonize _before_ creating threads
if(run_as_daemon)
if(run_as_daemon)
daemonize();
// Start up aging process and auxiliary WRIPC thread
......@@ -324,7 +323,7 @@ int main(int argc, char **argv)
rtu_daemon_destroy();
return err;
}
// Start up learning process.
err = rtu_daemon_learning_process();
// On error, release RTU resources
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment