Commit a6513e44 authored by Alessandro Rubini's avatar Alessandro Rubini

userspace/wrsw_rtud: removed trailing blanks

parent 523affb1
...@@ -6,10 +6,10 @@ ...@@ -6,10 +6,10 @@
* *
* Authors: Tomasz Wlostowski (tomasz.wlostowski@cern.ch) * Authors: Tomasz Wlostowski (tomasz.wlostowski@cern.ch)
* *
* Description: MAC address type related operations. * Description: MAC address type related operations.
* *
* Fixes: * Fixes:
* *
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
......
...@@ -6,11 +6,11 @@ ...@@ -6,11 +6,11 @@
* *
* Authors: Juan Luis Manas (juan.manas@integrasys.es) * Authors: Juan Luis Manas (juan.manas@integrasys.es)
* *
* Description: MAC address type related operations. * Description: MAC address type related operations.
* *
* Fixes: * Fixes:
* Alessandro Rubini * Alessandro Rubini
* *
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
...@@ -34,8 +34,8 @@ ...@@ -34,8 +34,8 @@
#include <string.h> #include <string.h>
#include <linux/if_ether.h> #include <linux/if_ether.h>
/** /**
* \brief Check whether two mac addresses are equal. * \brief Check whether two mac addresses are equal.
* @return 1 if both addresses are equal. 0 otherwise. * @return 1 if both addresses are equal. 0 otherwise.
*/ */
static inline int mac_equal(uint8_t a[ETH_ALEN], uint8_t b[ETH_ALEN]) static inline int mac_equal(uint8_t a[ETH_ALEN], uint8_t b[ETH_ALEN])
...@@ -56,7 +56,7 @@ static inline uint8_t* mac_copy(uint8_t dst[ETH_ALEN], uint8_t src[ETH_ALEN]) ...@@ -56,7 +56,7 @@ static inline uint8_t* mac_copy(uint8_t dst[ETH_ALEN], uint8_t src[ETH_ALEN])
* \brief Set MAC address to 00:00:00:00:00:00. * \brief Set MAC address to 00:00:00:00:00:00.
* @return pointer to mac address * @return pointer to mac address
*/ */
static inline uint8_t* mac_clean(uint8_t mac[ETH_ALEN]) static inline uint8_t* mac_clean(uint8_t mac[ETH_ALEN])
{ {
return memset(mac, 0x00, ETH_ALEN); return memset(mac, 0x00, ETH_ALEN);
} }
......
...@@ -7,10 +7,10 @@ ...@@ -7,10 +7,10 @@
* Authors: Juan Luis Manas (juan.manas@integrasys.es) * Authors: Juan Luis Manas (juan.manas@integrasys.es)
* Maciej Lipinski (maciej.lipinski@cern.ch) * Maciej Lipinski (maciej.lipinski@cern.ch)
* *
* Description: RTU data structures definition. * Description: RTU data structures definition.
* *
* Fixes: * Fixes:
* Tomasz Wlostowski * Tomasz Wlostowski
* *
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
...@@ -80,11 +80,11 @@ ...@@ -80,11 +80,11 @@
*/ */
struct rtu_request { struct rtu_request {
int port_id; // physical port identifier 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 uint8_t dst[ETH_ALEN]; // destination MAC address
uint16_t vid; // VLAN ID from the packet header uint16_t vid; // VLAN ID from the packet header
int has_vid; // non-zero: VID is present,0:untagged packet (VID=0) 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) // or extracted from packet header)
int has_prio; // non-zero: priority present, 0:no priority defined int has_prio; // non-zero: priority present, 0:no priority defined
}; };
...@@ -93,36 +93,36 @@ struct rtu_request { ...@@ -93,36 +93,36 @@ struct rtu_request {
* \brief RTU Filtering Database Entry Object * \brief RTU Filtering Database Entry Object
*/ */
struct filtering_entry { 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) // invalid (empty)
int end_of_bucket; // bit: 1 = last entry in current bucket, stop int end_of_bucket; // bit: 1 = last entry in current bucket, stop
// search at this point // 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) // packet)
uint8_t mac[ETH_ALEN]; // MAC address (for searching the bucketed uint8_t mac[ETH_ALEN]; // MAC address (for searching the bucketed
// hashtable) // hashtable)
uint8_t fid; // Filtering database ID (for searching the uint8_t fid; // Filtering database ID (for searching the
// bucketed hashtable) // bucketed hashtable)
uint32_t port_mask_src; // port mask for source MAC addresses. Bits uint32_t port_mask_src; // port mask for source MAC addresses. Bits
// set to 1 indicate that packet having this // set to 1 indicate that packet having this
// MAC address can be forwarded from these // MAC address can be forwarded from these
// corresponding ports. Ports having their // corresponding ports. Ports having their
// bits set to 0 shall drop the packet. // bits set to 0 shall drop the packet.
uint32_t port_mask_dst; // port mask for destination MAC address. Bits uint32_t port_mask_dst; // port mask for destination MAC address. Bits
// set to 1 indicate to which physical ports // set to 1 indicate to which physical ports
// the packet with matching destination MAC // the packet with matching destination MAC
// address shall be routed // 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 // 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 // address matches
int drop_unmatched_src_ports; // bit: 1 = drop the packet when it comes from int drop_unmatched_src_ports; // bit: 1 = drop the packet when it comes from
// source port different than specified in // source port different than specified in
// port_mask_src // port_mask_src
uint32_t last_access_t; // time of last access to the rule (for aging) uint32_t last_access_t; // time of last access to the rule (for aging)
...@@ -134,10 +134,10 @@ struct filtering_entry { ...@@ -134,10 +134,10 @@ struct filtering_entry {
int has_prio_dst; // priority value valid int has_prio_dst; // priority value valid
int prio_override_dst; // priority override (force per-MAC priority) 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 // 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) // (2 words)
int dynamic; int dynamic;
...@@ -148,7 +148,7 @@ struct filtering_entry { ...@@ -148,7 +148,7 @@ struct filtering_entry {
*/ */
struct vlan_table_entry { struct vlan_table_entry {
uint32_t port_mask; // VLAN port mask: 1 = ports assigned to this VLAN 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 uint8_t prio; // VLAN priority
int has_prio; // priority defined; int has_prio; // priority defined;
int prio_override; // priority override (force per-VLAN priority) int prio_override; // priority override (force per-VLAN priority)
...@@ -159,9 +159,9 @@ struct vlan_table_entry { ...@@ -159,9 +159,9 @@ struct vlan_table_entry {
* \brief Copies src filtering entry body into dst filtering entry body. * \brief Copies src filtering entry body into dst filtering entry body.
* @return pointer to dst filtering entry. * @return pointer to dst filtering entry.
*/ */
static inline static inline
struct filtering_entry *rtu_fe_copy( struct filtering_entry *dst, struct filtering_entry *rtu_fe_copy( struct filtering_entry *dst,
struct filtering_entry *src ) struct filtering_entry *src )
{ {
return memcpy( dst, src, sizeof(*src) ); return memcpy( dst, src, sizeof(*src) );
} }
...@@ -171,8 +171,8 @@ struct filtering_entry *rtu_fe_copy( struct filtering_entry *dst, ...@@ -171,8 +171,8 @@ struct filtering_entry *rtu_fe_copy( struct filtering_entry *dst,
* @param ent pointer to entry to clean (either in HCAM or HTAB) * @param ent pointer to entry to clean (either in HCAM or HTAB)
* @return pointer to filtering entry that was cleaned * @return pointer to filtering entry that was cleaned
*/ */
static inline static inline
struct filtering_entry *rtu_fe_clean(struct filtering_entry *ent) struct filtering_entry *rtu_fe_clean(struct filtering_entry *ent)
{ {
return memset( ent, 0, sizeof(*ent) ); return memset( ent, 0, sizeof(*ent) );
} }
...@@ -180,13 +180,13 @@ struct filtering_entry *rtu_fe_clean(struct filtering_entry *ent) ...@@ -180,13 +180,13 @@ struct filtering_entry *rtu_fe_clean(struct filtering_entry *ent)
/** /**
* \brief Returns number of seconds since the epoch. * \brief Returns number of seconds since the epoch.
*/ */
static inline static inline
unsigned long now() unsigned long now()
{ {
return (unsigned long) time(NULL); return (unsigned long) time(NULL);
} }
int rtud_init_exports(); int rtud_init_exports();
void rtud_handle_wripc(); void rtud_handle_wripc();
#endif /*__WHITERABBIT_RTU_H*/ #endif /*__WHITERABBIT_RTU_H*/
...@@ -8,18 +8,18 @@ ...@@ -8,18 +8,18 @@
* Miguel Baizan (miguel.baizan@integrasys.es) * Miguel Baizan (miguel.baizan@integrasys.es)
* Maciej Lipinski (maciej.lipinski@cern.ch) * Maciej Lipinski (maciej.lipinski@cern.ch)
* *
* Description: RTU driver module in user space. Provides read/write access * Description: RTU driver module in user space. Provides read/write access
* to RTU_at_HW components including: * to RTU_at_HW components including:
* - UFIFO * - UFIFO
* - MFIFO * - MFIFO
* - HCAM * - HCAM
* - Aging RAM for Main Hashtable * - Aging RAM for Main Hashtable
* - Aging Register for HCAM * - Aging Register for HCAM
* - VLAN Table * - VLAN Table
* - RTU Global Control Register * - RTU Global Control Register
* - RTU Port settings * - RTU Port settings
* *
* Fixes: * Fixes:
* Alessandro Rubini * Alessandro Rubini
* Tomasz Wlostowski * Tomasz Wlostowski
* *
...@@ -82,7 +82,7 @@ int rtu_init(void) ...@@ -82,7 +82,7 @@ int rtu_init(void)
{ {
int err; int err;
if(halexp_client_init() < 0) if(halexp_client_init() < 0)
TRACE( TRACE(
TRACE_FATAL, TRACE_FATAL,
"WRSW_HAL is not responding... Are you sure it's running on your switch?\n" "WRSW_HAL is not responding... Are you sure it's running on your switch?\n"
...@@ -107,7 +107,7 @@ void rtu_exit(void) ...@@ -107,7 +107,7 @@ void rtu_exit(void)
{ {
if(fd >= 0) if(fd >= 0)
close(fd); close(fd);
TRACE(TRACE_INFO, "module cleanup\n"); TRACE(TRACE_INFO, "module cleanup\n");
} }
...@@ -153,7 +153,7 @@ int rtu_read_learning_queue(struct rtu_request *req) ...@@ -153,7 +153,7 @@ int rtu_read_learning_queue(struct rtu_request *req)
return err; return err;
} }
// read data from mapped IO memory // read data from mapped IO memory
uint32_t r0 = _fpga_readl(FPGA_BASE_RTU + RTU_REG_UFIFO_R0); uint32_t r0 = _fpga_readl(FPGA_BASE_RTU + RTU_REG_UFIFO_R0);
uint32_t r1 = _fpga_readl(FPGA_BASE_RTU + RTU_REG_UFIFO_R1); uint32_t r1 = _fpga_readl(FPGA_BASE_RTU + RTU_REG_UFIFO_R1);
uint32_t r2 = _fpga_readl(FPGA_BASE_RTU + RTU_REG_UFIFO_R2); uint32_t r2 = _fpga_readl(FPGA_BASE_RTU + RTU_REG_UFIFO_R2);
...@@ -168,12 +168,12 @@ int rtu_read_learning_queue(struct rtu_request *req) ...@@ -168,12 +168,12 @@ int rtu_read_learning_queue(struct rtu_request *req)
uint32_t dmac_lo = RTU_UFIFO_R0_DMAC_LO_R(r0); uint32_t dmac_lo = RTU_UFIFO_R0_DMAC_LO_R(r0);
uint32_t dmac_hi = RTU_UFIFO_R1_DMAC_HI_R(r1); uint32_t dmac_hi = RTU_UFIFO_R1_DMAC_HI_R(r1);
uint32_t smac_lo = RTU_UFIFO_R2_SMAC_LO_R(r2); uint32_t smac_lo = RTU_UFIFO_R2_SMAC_LO_R(r2);
uint32_t smac_hi = RTU_UFIFO_R3_SMAC_HI_R(r3); uint32_t smac_hi = RTU_UFIFO_R3_SMAC_HI_R(r3);
req->port_id = RTU_UFIFO_R4_PID_R(r4); req->port_id = RTU_UFIFO_R4_PID_R(r4);
req->has_prio = RTU_UFIFO_R4_HAS_PRIO & r4; req->has_prio = RTU_UFIFO_R4_HAS_PRIO & r4;
req->prio = RTU_UFIFO_R4_PRIO_R(r4); req->prio = RTU_UFIFO_R4_PRIO_R(r4);
req->has_vid = RTU_UFIFO_R4_HAS_VID & r4; req->has_vid = RTU_UFIFO_R4_HAS_VID & r4;
req->vid = RTU_UFIFO_R4_VID_R(r4); req->vid = RTU_UFIFO_R4_VID_R(r4);
// destination mac // destination mac
req->dst[5] = 0xFF & dmac_lo; req->dst[5] = 0xFF & dmac_lo;
...@@ -255,7 +255,7 @@ void rtu_write_htab_entry(uint16_t zbt_addr, struct filtering_entry *ent) ...@@ -255,7 +255,7 @@ void rtu_write_htab_entry(uint16_t zbt_addr, struct filtering_entry *ent)
TRACE_DBG( TRACE_DBG(
TRACE_INFO, TRACE_INFO,
"write htab entry: addr %x ent %08x %08x %08x %08x %08x", "write htab entry: addr %x ent %08x %08x %08x %08x %08x",
zbt_addr, zbt_addr,
mac_entry_word0_w(ent), mac_entry_word0_w(ent),
mac_entry_word1_w(ent), mac_entry_word1_w(ent),
mac_entry_word2_w(ent), mac_entry_word2_w(ent),
...@@ -287,7 +287,7 @@ void rtu_clean_htab(void) ...@@ -287,7 +287,7 @@ void rtu_clean_htab(void)
write_mfifo_data(0x00000000); write_mfifo_data(0x00000000);
write_mfifo_data(0x00000000); write_mfifo_data(0x00000000);
write_mfifo_data(0x00000000); write_mfifo_data(0x00000000);
write_mfifo_data(0x00000000); write_mfifo_data(0x00000000);
} }
} }
...@@ -301,7 +301,7 @@ void rtu_clean_htab(void) ...@@ -301,7 +301,7 @@ void rtu_clean_htab(void)
*/ */
void rtu_read_hcam_entry( uint16_t cam_addr, struct filtering_entry *ent ) void rtu_read_hcam_entry( uint16_t cam_addr, struct filtering_entry *ent )
{ {
// read data from mapped IO memory // read data from mapped IO memory
uint32_t w0 = _fpga_readl(FPGA_BASE_RTU + RTU_HCAM + 4*cam_addr ); uint32_t w0 = _fpga_readl(FPGA_BASE_RTU + RTU_HCAM + 4*cam_addr );
uint32_t w1 = _fpga_readl(FPGA_BASE_RTU + RTU_HCAM + 4*(cam_addr + 0x1)); uint32_t w1 = _fpga_readl(FPGA_BASE_RTU + RTU_HCAM + 4*(cam_addr + 0x1));
uint32_t w2 = _fpga_readl(FPGA_BASE_RTU + RTU_HCAM + 4*(cam_addr + 0x2)); uint32_t w2 = _fpga_readl(FPGA_BASE_RTU + RTU_HCAM + 4*(cam_addr + 0x2));
...@@ -310,7 +310,7 @@ void rtu_read_hcam_entry( uint16_t cam_addr, struct filtering_entry *ent ) ...@@ -310,7 +310,7 @@ void rtu_read_hcam_entry( uint16_t cam_addr, struct filtering_entry *ent )
TRACE_DBG( TRACE_DBG(
TRACE_INFO, TRACE_INFO,
"read hcam entry: addr %x ent %08x %08x %08x %08x %08x", "read hcam entry: addr %x ent %08x %08x %08x %08x %08x",
cam_addr, cam_addr,
w0, w0,
w1, w1,
w2, w2,
...@@ -340,7 +340,7 @@ void rtu_write_hcam_entry( uint16_t cam_addr, struct filtering_entry *ent) ...@@ -340,7 +340,7 @@ void rtu_write_hcam_entry( uint16_t cam_addr, struct filtering_entry *ent)
TRACE_DBG( TRACE_DBG(
TRACE_INFO, TRACE_INFO,
"write hcam entry: addr %x ent %08x %08x %08x %08x %08x", "write hcam entry: addr %x ent %08x %08x %08x %08x %08x",
cam_addr, cam_addr,
mac_entry_word0_w(ent), mac_entry_word0_w(ent),
mac_entry_word1_w(ent), mac_entry_word1_w(ent),
mac_entry_word2_w(ent), mac_entry_word2_w(ent),
...@@ -356,9 +356,9 @@ void rtu_write_hcam_entry( uint16_t cam_addr, struct filtering_entry *ent) ...@@ -356,9 +356,9 @@ void rtu_write_hcam_entry( uint16_t cam_addr, struct filtering_entry *ent)
void rtu_clean_hcam_entry( uint8_t cam_addr ) void rtu_clean_hcam_entry( uint8_t cam_addr )
{ {
_fpga_writel(FPGA_BASE_RTU + RTU_HCAM + 4*cam_addr , 0x00000000); _fpga_writel(FPGA_BASE_RTU + RTU_HCAM + 4*cam_addr , 0x00000000);
_fpga_writel(FPGA_BASE_RTU + RTU_HCAM + 4*(cam_addr + 0x1), 0x00000000); _fpga_writel(FPGA_BASE_RTU + RTU_HCAM + 4*(cam_addr + 0x1), 0x00000000);
_fpga_writel(FPGA_BASE_RTU + RTU_HCAM + 4*(cam_addr + 0x2), 0x00000000); _fpga_writel(FPGA_BASE_RTU + RTU_HCAM + 4*(cam_addr + 0x2), 0x00000000);
_fpga_writel(FPGA_BASE_RTU + RTU_HCAM + 4*(cam_addr + 0x3), 0x00000000); _fpga_writel(FPGA_BASE_RTU + RTU_HCAM + 4*(cam_addr + 0x3), 0x00000000);
_fpga_writel(FPGA_BASE_RTU + RTU_HCAM + 4*(cam_addr + 0x4), 0x00000000); _fpga_writel(FPGA_BASE_RTU + RTU_HCAM + 4*(cam_addr + 0x4), 0x00000000);
TRACE_DBG( TRACE_DBG(
TRACE_INFO, TRACE_INFO,
...@@ -383,7 +383,7 @@ void rtu_clean_hcam(void) ...@@ -383,7 +383,7 @@ void rtu_clean_hcam(void)
* \brief Read word from aging HTAB. * \brief Read word from aging HTAB.
* Aging RAM Size: 256 32-bit words * Aging RAM Size: 256 32-bit words
*/ */
uint32_t rtu_read_agr_htab( uint32_t addr ) uint32_t rtu_read_agr_htab( uint32_t addr )
{ {
return _fpga_readl(FPGA_BASE_RTU + RTU_ARAM_MAIN + 4*addr) ; return _fpga_readl(FPGA_BASE_RTU + RTU_ARAM_MAIN + 4*addr) ;
} }
...@@ -407,7 +407,7 @@ void rtu_clean_agr_htab(void) ...@@ -407,7 +407,7 @@ void rtu_clean_agr_htab(void)
* Each bit corresponds to one MAC entry in HCAM memory. * Each bit corresponds to one MAC entry in HCAM memory.
*/ */
uint32_t rtu_read_agr_hcam(void) uint32_t rtu_read_agr_hcam(void)
{ {
return _fpga_readl(FPGA_BASE_RTU + RTU_REG_AGR_HCAM); return _fpga_readl(FPGA_BASE_RTU + RTU_REG_AGR_HCAM);
} }
...@@ -435,7 +435,7 @@ void rtu_write_vlan_entry(uint32_t addr, struct vlan_table_entry *ent) ...@@ -435,7 +435,7 @@ void rtu_write_vlan_entry(uint32_t addr, struct vlan_table_entry *ent)
TRACE_DBG( TRACE_DBG(
TRACE_INFO, TRACE_INFO,
"write vlan entry: addr %x ent %08x %08x %08x %08x %08x", "write vlan entry: addr %x ent %08x %08x %08x %08x %08x",
addr, addr,
vlan_entry_word0_w(ent) vlan_entry_word0_w(ent)
); );
} }
...@@ -473,7 +473,7 @@ void rtu_enable(void) ...@@ -473,7 +473,7 @@ void rtu_enable(void)
uint32_t gcr = _fpga_readl(FPGA_BASE_RTU + RTU_REG_GCR); uint32_t gcr = _fpga_readl(FPGA_BASE_RTU + RTU_REG_GCR);
// Set G_ENA bit value = 1 // Set G_ENA bit value = 1
gcr = gcr | RTU_GCR_G_ENA; gcr = gcr | RTU_GCR_G_ENA;
// Update GCR // Update GCR
_fpga_writel(FPGA_BASE_RTU + RTU_REG_GCR, gcr ); _fpga_writel(FPGA_BASE_RTU + RTU_REG_GCR, gcr );
TRACE_DBG(TRACE_INFO,"updated gcr (enable): %x\n", gcr); TRACE_DBG(TRACE_INFO,"updated gcr (enable): %x\n", gcr);
} }
...@@ -486,8 +486,8 @@ void rtu_disable(void) ...@@ -486,8 +486,8 @@ void rtu_disable(void)
// Get current GCR // Get current GCR
uint32_t gcr = _fpga_readl(FPGA_BASE_RTU + RTU_REG_GCR); uint32_t gcr = _fpga_readl(FPGA_BASE_RTU + RTU_REG_GCR);
// Set G_ENA bit value = 0 // Set G_ENA bit value = 0
gcr = gcr & (~RTU_GCR_G_ENA); gcr = gcr & (~RTU_GCR_G_ENA);
// Update GCR // Update GCR
_fpga_writel(FPGA_BASE_RTU + RTU_REG_GCR, gcr ); _fpga_writel(FPGA_BASE_RTU + RTU_REG_GCR, gcr );
TRACE_DBG(TRACE_INFO,"updated gcr (disable): %x\n", gcr); TRACE_DBG(TRACE_INFO,"updated gcr (disable): %x\n", gcr);
} }
...@@ -500,7 +500,7 @@ uint16_t rtu_read_hash_poly(void) ...@@ -500,7 +500,7 @@ uint16_t rtu_read_hash_poly(void)
{ {
// Get current GCR // Get current GCR
uint32_t gcr = _fpga_readl(FPGA_BASE_RTU + RTU_REG_GCR); uint32_t gcr = _fpga_readl(FPGA_BASE_RTU + RTU_REG_GCR);
return RTU_GCR_POLY_VAL_R(gcr); return RTU_GCR_POLY_VAL_R(gcr);
} }
/** /**
...@@ -520,7 +520,7 @@ void rtu_write_hash_poly(uint16_t hash_poly) ...@@ -520,7 +520,7 @@ void rtu_write_hash_poly(uint16_t hash_poly)
/** /**
* \brief Set active ZBT bank. * \brief Set active ZBT bank.
* @param bank active ZBT bank (0 or 1). Other values will be evaluated as 1. * @param bank active ZBT bank (0 or 1). Other values will be evaluated as 1.
*/ */
void rtu_set_active_htab_bank(uint8_t bank) void rtu_set_active_htab_bank(uint8_t bank)
{ {
...@@ -533,7 +533,7 @@ void rtu_set_active_htab_bank(uint8_t bank) ...@@ -533,7 +533,7 @@ void rtu_set_active_htab_bank(uint8_t bank)
} }
/** /**
* \brief Set active CAM bank. * \brief Set active CAM bank.
* @param bank active CAM bank (0 or 1). Other values will be evaluated as 1. * @param bank active CAM bank (0 or 1). Other values will be evaluated as 1.
*/ */
void rtu_set_active_hcam_bank(uint8_t bank) void rtu_set_active_hcam_bank(uint8_t bank)
...@@ -547,7 +547,7 @@ void rtu_set_active_hcam_bank(uint8_t bank) ...@@ -547,7 +547,7 @@ void rtu_set_active_hcam_bank(uint8_t bank)
} }
/** /**
* \brief Set active ZBT and CAM banks at once. * \brief Set active ZBT and CAM banks at once.
* @param bank active ZBT and CAM bank (0 or 1). Other values will be evaluated as 1. * @param bank active ZBT and CAM bank (0 or 1). Other values will be evaluated as 1.
*/ */
void rtu_set_active_bank(uint8_t bank) void rtu_set_active_bank(uint8_t bank)
...@@ -577,7 +577,7 @@ int rtu_set_fixed_prio_on_port(int port, uint8_t prio) ...@@ -577,7 +577,7 @@ int rtu_set_fixed_prio_on_port(int port, uint8_t prio)
uint32_t pcr_addr = fpga_rtu_pcr_addr(port); uint32_t pcr_addr = fpga_rtu_pcr_addr(port);
uint32_t pcr = _fpga_readl(FPGA_BASE_RTU + pcr_addr); uint32_t pcr = _fpga_readl(FPGA_BASE_RTU + pcr_addr);
// Be careful! the following assumes every port control reg has same layout // Be careful! the following assumes every port control reg has same layout
pcr = pcr | RTU_PCR0_FIX_PRIO | RTU_PCR0_PRIO_VAL_W(prio); pcr = pcr | RTU_PCR0_FIX_PRIO | RTU_PCR0_PRIO_VAL_W(prio);
_fpga_writel(FPGA_BASE_RTU + pcr_addr, pcr); _fpga_writel(FPGA_BASE_RTU + pcr_addr, pcr);
return 0; return 0;
} }
...@@ -595,7 +595,7 @@ int rtu_unset_fixed_prio_on_port(int port) ...@@ -595,7 +595,7 @@ int rtu_unset_fixed_prio_on_port(int port)
uint32_t pcr_addr = fpga_rtu_pcr_addr(port); uint32_t pcr_addr = fpga_rtu_pcr_addr(port);
uint32_t pcr = _fpga_readl(FPGA_BASE_RTU + pcr_addr); uint32_t pcr = _fpga_readl(FPGA_BASE_RTU + pcr_addr);
// Be careful! the following assumes every port control reg has same layout // Be careful! the following assumes every port control reg has same layout
pcr = pcr & (RTU_PCR0_LEARN_EN | RTU_PCR0_PASS_ALL | RTU_PCR0_PASS_BPDU | RTU_PCR0_B_UNREC); pcr = pcr & (RTU_PCR0_LEARN_EN | RTU_PCR0_PASS_ALL | RTU_PCR0_PASS_BPDU | RTU_PCR0_B_UNREC);
_fpga_writel(FPGA_BASE_RTU + pcr_addr, pcr); _fpga_writel(FPGA_BASE_RTU + pcr_addr, pcr);
return 0; return 0;
} }
...@@ -603,7 +603,7 @@ int rtu_unset_fixed_prio_on_port(int port) ...@@ -603,7 +603,7 @@ int rtu_unset_fixed_prio_on_port(int port)
/** /**
* \brief Sets the LEARN_EN flag on indicated port. * \brief Sets the LEARN_EN flag on indicated port.
* @param port port number (0 to 9) * @param port port number (0 to 9)
* @param flag 0 disables learning. Otherwise: enables learning porcess on this port. * @param flag 0 disables learning. Otherwise: enables learning porcess on this port.
* @return error code. * @return error code.
*/ */
int rtu_learn_enable_on_port(int port, int flag) int rtu_learn_enable_on_port(int port, int flag)
...@@ -624,10 +624,10 @@ int rtu_learn_enable_on_port(int port, int flag) ...@@ -624,10 +624,10 @@ int rtu_learn_enable_on_port(int port, int flag)
* \brief Sets the PASS_BPDU flag on indicated port. * \brief Sets the PASS_BPDU flag on indicated port.
* @param port port number (0 to 9) * @param port port number (0 to 9)
* @param flag 0: BPDU packets are passed RTU rules only if PASS_ALL is set. * @param flag 0: BPDU packets are passed RTU rules only if PASS_ALL is set.
* Otherwise: BPDU packets are passed according to RTU rules. * Otherwise: BPDU packets are passed according to RTU rules.
* @return error code. * @return error code.
*/ */
int rtu_pass_bpdu_on_port(int port, int flag) int rtu_pass_bpdu_on_port(int port, int flag)
{ {
if( (port < MIN_PORT) || (port > MAX_PORT) ) if( (port < MIN_PORT) || (port > MAX_PORT) )
return -EINVAL; return -EINVAL;
...@@ -647,7 +647,7 @@ int rtu_pass_bpdu_on_port(int port, int flag) ...@@ -647,7 +647,7 @@ int rtu_pass_bpdu_on_port(int port, int flag)
* @param flag 0: all packets are dropped. Otherwise: all packets are passed. * @param flag 0: all packets are dropped. Otherwise: all packets are passed.
* @return error code. * @return error code.
*/ */
int rtu_pass_all_on_port(int port, int flag) int rtu_pass_all_on_port(int port, int flag)
{ {
if( (port < MIN_PORT) || (port > MAX_PORT) ) if( (port < MIN_PORT) || (port > MAX_PORT) )
return -EINVAL; return -EINVAL;
...@@ -664,10 +664,10 @@ int rtu_pass_all_on_port(int port, int flag) ...@@ -664,10 +664,10 @@ int rtu_pass_all_on_port(int port, int flag)
/** /**
* \brief Sets the B_UNREC flag on indicated port. * \brief Sets the B_UNREC flag on indicated port.
* @param port port number (0 to 9) * @param port port number (0 to 9)
* @param flag 0: packet is dropped. Otherwise: packet is broadcast. * @param flag 0: packet is dropped. Otherwise: packet is broadcast.
* @return error code. * @return error code.
*/ */
int rtu_set_unrecognised_behaviour_on_port(int port, int flag) int rtu_set_unrecognised_behaviour_on_port(int port, int flag)
{ {
if( (port < MIN_PORT) || (port > MAX_PORT) ) if( (port < MIN_PORT) || (port > MAX_PORT) )
return -EINVAL; return -EINVAL;
...@@ -725,14 +725,14 @@ static void write_mfifo_data(uint32_t word) ...@@ -725,14 +725,14 @@ static void write_mfifo_data(uint32_t word)
static uint32_t mac_entry_word0_w(struct filtering_entry *ent) static uint32_t mac_entry_word0_w(struct filtering_entry *ent)
{ {
return return
((0xFF & ent->mac[0]) << 24) | ((0xFF & ent->mac[0]) << 24) |
((0xFF & ent->mac[1]) << 16) | ((0xFF & ent->mac[1]) << 16) |
((0xFF & ent->fid) << 4) | ((0xFF & ent->fid) << 4) |
((0x1 & ent->go_to_cam) << 3) | ((0x1 & ent->go_to_cam) << 3) |
((0x1 & ent->is_bpdu) << 2) | ((0x1 & ent->is_bpdu) << 2) |
((0x1 & ent->end_of_bucket) << 1) | ((0x1 & ent->end_of_bucket) << 1) |
((0x1 & ent->valid ) ) ; ((0x1 & ent->valid ) ) ;
} }
static uint32_t mac_entry_word1_w(struct filtering_entry *ent) static uint32_t mac_entry_word1_w(struct filtering_entry *ent)
...@@ -747,28 +747,28 @@ static uint32_t mac_entry_word1_w(struct filtering_entry *ent) ...@@ -747,28 +747,28 @@ static uint32_t mac_entry_word1_w(struct filtering_entry *ent)
static uint32_t mac_entry_word2_w(struct filtering_entry *ent) static uint32_t mac_entry_word2_w(struct filtering_entry *ent)
{ {
return return
((0x1 & ent->drop_when_dest) << 28) | ((0x1 & ent->drop_when_dest) << 28) |
((0x1 & ent->prio_override_dst) << 27) | ((0x1 & ent->prio_override_dst) << 27) |
((0x7 & ent->prio_dst) << 24) | ((0x7 & ent->prio_dst) << 24) |
((0x1 & ent->has_prio_dst) << 23) | ((0x1 & ent->has_prio_dst) << 23) |
((0x1 & ent->drop_unmatched_src_ports) << 22) | ((0x1 & ent->drop_unmatched_src_ports) << 22) |
((0x1 & ent->drop_when_source) << 21) | ((0x1 & ent->drop_when_source) << 21) |
((0x1 & ent->prio_override_src) << 20) | ((0x1 & ent->prio_override_src) << 20) |
((0x7 & ent->prio_src) << 17) | ((0x7 & ent->prio_src) << 17) |
((0x1 & ent->has_prio_src) << 16) | ((0x1 & ent->has_prio_src) << 16) |
((0x01FF & ent->cam_addr) ) ; ((0x01FF & ent->cam_addr) ) ;
} }
static uint32_t mac_entry_word3_w(struct filtering_entry *ent) static uint32_t mac_entry_word3_w(struct filtering_entry *ent)
{ {
return return
((0xFFFF & ent->port_mask_dst) << 16) | ((0xFFFF & ent->port_mask_dst) << 16) |
((0xFFFF & ent->port_mask_src) ) ; ((0xFFFF & ent->port_mask_src) ) ;
} }
static uint32_t mac_entry_word4_w(struct filtering_entry *ent) static uint32_t mac_entry_word4_w(struct filtering_entry *ent)
{ {
return return
(ent->last_access_t); (ent->last_access_t);
} }
...@@ -824,8 +824,8 @@ static void mac_entry_word4_r(uint32_t word, struct filtering_entry *ent) ...@@ -824,8 +824,8 @@ static void mac_entry_word4_r(uint32_t word, struct filtering_entry *ent)
static uint32_t vlan_entry_word0_w(struct vlan_table_entry *ent) static uint32_t vlan_entry_word0_w(struct vlan_table_entry *ent)
{ {
return return
((0x1 & ent->drop) << 31) | ((0x1 & ent->drop) << 31) |
((0x1 & ent->prio_override) << 30) | ((0x1 & ent->prio_override) << 30) |
((0x7 & ent->prio) << 27) | ((0x7 & ent->prio) << 27) |
((0x1 & ent->has_prio) << 26) | ((0x1 & ent->has_prio) << 26) |
......
...@@ -36,7 +36,7 @@ ...@@ -36,7 +36,7 @@
// HW RTU (should be given by wrsw_rtu_wb.h) // HW RTU (should be given by wrsw_rtu_wb.h)
#define RTU_HCAM 0x4000 #define RTU_HCAM 0x4000
#define RTU_ARAM_MAIN 0x8000 #define RTU_ARAM_MAIN 0x8000
#define RTU_VLAN_TAB 0xc000 #define RTU_VLAN_TAB 0xc000
#define RTU_MFIFO_R0_DATA_SEL 0x00000000 #define RTU_MFIFO_R0_DATA_SEL 0x00000000
#define RTU_MFIFO_R1_ADDR_MASK 0x0007FFFF #define RTU_MFIFO_R1_ADDR_MASK 0x0007FFFF
......
...@@ -8,12 +8,12 @@ ...@@ -8,12 +8,12 @@
* Miguel Baizan (miguel.baizan@integrasys.es) * Miguel Baizan (miguel.baizan@integrasys.es)
* Maciej Lipinski (maciej.lipinski@cern.ch) * Maciej Lipinski (maciej.lipinski@cern.ch)
* *
* Description: RTU Filtering database. * Description: RTU Filtering database.
* Filtering database management related operations and filtering * Filtering database management related operations and filtering
* database mirror. Note there is a single Filtering Database * database mirror. Note there is a single Filtering Database
* object per Bridge (See 802.1Q - 12.7.1) * object per Bridge (See 802.1Q - 12.7.1)
* *
* Fixes: * Fixes:
* Alessandro Rubini * Alessandro Rubini
* Tomasz Wlostowski * Tomasz Wlostowski
* *
...@@ -60,7 +60,7 @@ ...@@ -60,7 +60,7 @@
/** /**
* \brief Filtering Database entry handle. * \brief Filtering Database entry handle.
*/ */
struct fd_handle { struct fd_handle {
int mem_type; // HTAB or HCAM int mem_type; // HTAB or HCAM
...@@ -96,14 +96,14 @@ static struct filtering_entry rtu_htab[HTAB_ENTRIES][RTU_BUCKETS]; ...@@ -96,14 +96,14 @@ static struct filtering_entry rtu_htab[HTAB_ENTRIES][RTU_BUCKETS];
*/ */
static struct filtering_entry rtu_hcam[CAM_ENTRIES]; static struct filtering_entry rtu_hcam[CAM_ENTRIES];
/** /**
* \brief Table bank to write entries to. * \brief Table bank to write entries to.
* HTAB and HCAM banks will be handled according to this single bank value. * HTAB and HCAM banks will be handled according to this single bank value.
*/ */
static uint8_t bank; static uint8_t bank;
/** /**
* \brief Mirror of Aging RAM. * \brief Mirror of Aging RAM.
*/ */
static uint32_t rtu_agr_htab[RTU_ARAM_MAIN_WORDS]; static uint32_t rtu_agr_htab[RTU_ARAM_MAIN_WORDS];
static uint32_t rtu_agr_hcam; static uint32_t rtu_agr_hcam;
...@@ -141,9 +141,9 @@ static inline int cam_bucket(uint16_t cam_addr); ...@@ -141,9 +141,9 @@ static inline int cam_bucket(uint16_t cam_addr);
static inline int matched(uint32_t word, int offset); static inline int matched(uint32_t word, int offset);
static int htab_contains(uint8_t mac[ETH_ALEN], uint8_t fid, int *bucket, static int htab_contains(uint8_t mac[ETH_ALEN], uint8_t fid, int *bucket,
struct filtering_entry **ent); struct filtering_entry **ent);
static int hcam_contains(uint8_t mac[ETH_ALEN], uint8_t fid, int *bucket, static int hcam_contains(uint8_t mac[ETH_ALEN], uint8_t fid, int *bucket,
struct filtering_entry **ent); struct filtering_entry **ent);
static int find_empty_bucket_in_hcam(void); static int find_empty_bucket_in_hcam(void);
...@@ -204,12 +204,12 @@ int rtu_fd_init(uint16_t poly, unsigned long aging) ...@@ -204,12 +204,12 @@ int rtu_fd_init(uint16_t poly, unsigned long aging)
* @param port_map a port map specification with a control element for each * @param port_map a port map specification with a control element for each
* outbound port to specify filtering for that MAC address specification and VID * outbound port to specify filtering for that MAC address specification and VID
* @param dynamic it indicates whether it's a dynamic entry * @param dynamic it indicates whether it's a dynamic entry
* @return 0 if entry was created or updated. -ENOMEM if no space is available. * @return 0 if entry was created or updated. -ENOMEM if no space is available.
*/ */
int rtu_fd_create_entry(uint8_t mac[ETH_ALEN], uint16_t vid, uint32_t port_map, int dynamic) int rtu_fd_create_entry(uint8_t mac[ETH_ALEN], uint16_t vid, uint32_t port_map, int dynamic)
{ {
struct filtering_entry *ent; // pointer to scan hashtable struct filtering_entry *ent; // pointer to scan hashtable
uint16_t hash; // hashtable key uint16_t hash; // hashtable key
uint8_t fid; // Filtering database identifier uint8_t fid; // Filtering database identifier
int bucket = 0; // bucket loop index int bucket = 0; // bucket loop index
int ret = 0; // return value int ret = 0; // return value
...@@ -224,8 +224,8 @@ int rtu_fd_create_entry(uint8_t mac[ETH_ALEN], uint16_t vid, uint32_t port_map, ...@@ -224,8 +224,8 @@ int rtu_fd_create_entry(uint8_t mac[ETH_ALEN], uint16_t vid, uint32_t port_map,
// Check HTAB // Check HTAB
ent = &rtu_htab[hash][bucket]; ent = &rtu_htab[hash][bucket];
switch(htab_contains(mac, fid, &bucket, &ent)){ switch(htab_contains(mac, fid, &bucket, &ent)){
case FOUND: case FOUND:
// update // update
mask_dst = ent->port_mask_dst | port_map; mask_dst = ent->port_mask_dst | port_map;
mask_src = ent->port_mask_src | vlan_tab[vid].port_mask; mask_src = ent->port_mask_src | vlan_tab[vid].port_mask;
if ((ent->port_mask_dst != mask_dst) || if ((ent->port_mask_dst != mask_dst) ||
...@@ -261,7 +261,7 @@ int rtu_fd_create_entry(uint8_t mac[ETH_ALEN], uint16_t vid, uint32_t port_map, ...@@ -261,7 +261,7 @@ int rtu_fd_create_entry(uint8_t mac[ETH_ALEN], uint16_t vid, uint32_t port_map,
write_htab_entry(zbt_addr(hash, LAST_RTU_BUCKET), ent); write_htab_entry(zbt_addr(hash, LAST_RTU_BUCKET), ent);
} }
// Check HCAM // Check HCAM
ent = &rtu_hcam[bucket]; ent = &rtu_hcam[bucket];
switch(hcam_contains(mac, fid, &bucket, &ent)){ switch(hcam_contains(mac, fid, &bucket, &ent)){
case FOUND: case FOUND:
...@@ -275,14 +275,14 @@ int rtu_fd_create_entry(uint8_t mac[ETH_ALEN], uint16_t vid, uint32_t port_map, ...@@ -275,14 +275,14 @@ int rtu_fd_create_entry(uint8_t mac[ETH_ALEN], uint16_t vid, uint32_t port_map,
write_hcam_entry(cam_addr(bucket), ent); write_hcam_entry(cam_addr(bucket), ent);
} }
break; break;
case NOT_FOUND: case NOT_FOUND:
// existing list does not contain the entry and is necessary to // existing list does not contain the entry and is necessary to
// append new entry at the end of current list // append new entry at the end of current list
ent->end_of_bucket = 0; ent->end_of_bucket = 0;
write_hcam_entry(cam_addr(bucket), ent); write_hcam_entry(cam_addr(bucket), ent);
ent++; ent++;
bucket++; bucket++;
case NOT_FOUND_AND_FIRST: case NOT_FOUND_AND_FIRST:
// First entry in HCAM for this hash. // First entry in HCAM for this hash.
ent->valid = 1; ent->valid = 1;
ent->end_of_bucket = 1; ent->end_of_bucket = 1;
...@@ -309,24 +309,24 @@ int rtu_fd_create_entry(uint8_t mac[ETH_ALEN], uint16_t vid, uint32_t port_map, ...@@ -309,24 +309,24 @@ int rtu_fd_create_entry(uint8_t mac[ETH_ALEN], uint16_t vid, uint32_t port_map,
* Changing the hash polynomial requires removing any existing * Changing the hash polynomial requires removing any existing
* entry from RTU table. * entry from RTU table.
* Note in case RTU table becomes full, this function may * Note in case RTU table becomes full, this function may
* be used to change hash polynomial (thus leading to a different hash * be used to change hash polynomial (thus leading to a different hash
* distribution). * distribution).
* @param poly binary polynomial representation. * @param poly binary polynomial representation.
* CRC-16-CCITT -> 1+x^5+x^12+x^16 -> 0x1021 * CRC-16-CCITT -> 1+x^5+x^12+x^16 -> 0x1021
* CRC-16-IBM -> 1+x^2+x^15+x^16 -> 0x8005 * 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 * CRC-16-DECT -> 1+x^3+x^7+x^8+x^10+x^16 -> 0x0589
*/ */
void rtu_fd_set_hash_poly(uint16_t poly) void rtu_fd_set_hash_poly(uint16_t poly)
{ {
pthread_mutex_lock(&fd_mutex); pthread_mutex_lock(&fd_mutex);
rtu_write_hash_poly(poly); rtu_write_hash_poly(poly);
rtu_hash_set_poly(poly); rtu_hash_set_poly(poly);
pthread_mutex_unlock(&fd_mutex); pthread_mutex_unlock(&fd_mutex);
} }
/** /**
* \brief Sets the aging time for dynamic filtering entries. * \brief Sets the aging time for dynamic filtering entries.
* @param t new aging time value [seconds]. * @param t new aging time value [seconds].
* @return -EINVAL if t < 10 or t > 1000000 (802.1Q, Table 8.3); 0 otherwise. * @return -EINVAL if t < 10 or t > 1000000 (802.1Q, Table 8.3); 0 otherwise.
*/ */
int rtu_fd_set_aging_time(unsigned long t) int rtu_fd_set_aging_time(unsigned long t)
...@@ -343,12 +343,12 @@ int rtu_fd_set_aging_time(unsigned long t) ...@@ -343,12 +343,12 @@ int rtu_fd_set_aging_time(unsigned long t)
* changes in active topology. * changes in active topology.
*/ */
void rtu_fd_flush(void) void rtu_fd_flush(void)
{ {
update_aging_map(); // Work with latest access info update_aging_map(); // Work with latest access info
rtu_fd_age_update(); // Update filtering entries age rtu_fd_age_update(); // Update filtering entries age
pthread_mutex_lock(&fd_mutex); pthread_mutex_lock(&fd_mutex);
rtu_fd_age_out(); // Remove old entries rtu_fd_age_out(); // Remove old entries
pthread_mutex_unlock(&fd_mutex); pthread_mutex_unlock(&fd_mutex);
clean_aging_map(); // Keep track of entries access in next period clean_aging_map(); // Keep track of entries access in next period
...@@ -365,9 +365,9 @@ struct filtering_entry *rtu_fd_lookup_htab_entry(int index) ...@@ -365,9 +365,9 @@ struct filtering_entry *rtu_fd_lookup_htab_entry(int index)
{ {
if(n == index) return &rtu_htab[i][j]; if(n == index) return &rtu_htab[i][j];
n++; n++;
} }
} }
} }
return NULL; return NULL;
} }
...@@ -408,7 +408,7 @@ static int add_hw_req(int type, int mem, uint16_t addr, struct filtering_entry * ...@@ -408,7 +408,7 @@ static int add_hw_req(int type, int mem, uint16_t addr, struct filtering_entry *
req = (struct hw_req*) malloc(sizeof(struct hw_req)); req = (struct hw_req*) malloc(sizeof(struct hw_req));
if(!req) if(!req)
return -ENOMEM; return -ENOMEM;
req->type = type; req->type = type;
req->handle.mem_type = mem; req->handle.mem_type = mem;
req->handle.addr = addr; req->handle.addr = addr;
...@@ -423,49 +423,49 @@ static int add_hw_req(int type, int mem, uint16_t addr, struct filtering_entry * ...@@ -423,49 +423,49 @@ static int add_hw_req(int type, int mem, uint16_t addr, struct filtering_entry *
return 0; return 0;
} }
static inline static inline
int write_htab_entry(uint16_t addr, struct filtering_entry *e) int write_htab_entry(uint16_t addr, struct filtering_entry *e)
{ {
return add_hw_req(HW_WRITE_REQ, HTAB, addr, e); return add_hw_req(HW_WRITE_REQ, HTAB, addr, e);
} }
static inline static inline
int write_hcam_entry(uint16_t addr, struct filtering_entry *e) int write_hcam_entry(uint16_t addr, struct filtering_entry *e)
{ {
return add_hw_req(HW_WRITE_REQ, HCAM, addr, e); return add_hw_req(HW_WRITE_REQ, HCAM, addr, e);
} }
static inline static inline
int clean_htab_entry(uint16_t addr) int clean_htab_entry(uint16_t addr)
{ {
return add_hw_req(HW_CLEAN_REQ, HTAB, addr, NULL); return add_hw_req(HW_CLEAN_REQ, HTAB, addr, NULL);
} }
static inline static inline
int clean_hcam_entry(uint16_t addr) int clean_hcam_entry(uint16_t addr)
{ {
return add_hw_req(HW_CLEAN_REQ, HCAM, addr, NULL); return add_hw_req(HW_CLEAN_REQ, HCAM, addr, NULL);
} }
static inline static inline
uint16_t zbt_addr(uint16_t hash, int bucket) uint16_t zbt_addr(uint16_t hash, int bucket)
{ {
return (( 0x07FF & hash ) << 5 ) | ((0x0003 & bucket) << 3); return (( 0x07FF & hash ) << 5 ) | ((0x0003 & bucket) << 3);
} }
static inline static inline
uint16_t cam_addr(int bucket) uint16_t cam_addr(int bucket)
{ {
return ((0x001F & bucket) << 3); return ((0x001F & bucket) << 3);
} }
static inline static inline
int cam_bucket(uint16_t cam_addr) int cam_bucket(uint16_t cam_addr)
{ {
return ((cam_addr >> 3) & 0x001F); return ((cam_addr >> 3) & 0x001F);
} }
static inline static inline
int matched(uint32_t word, int offset) int matched(uint32_t word, int offset)
{ {
return (word >> offset) & 0x00000001; return (word >> offset) & 0x00000001;
...@@ -481,9 +481,9 @@ int matched(uint32_t word, int offset) ...@@ -481,9 +481,9 @@ int matched(uint32_t word, int offset)
* HTAB was full for the corresponding hash. -EINVAL if bucket >= RTU_BUCKETS * HTAB was full for the corresponding hash. -EINVAL if bucket >= RTU_BUCKETS
*/ */
static int htab_contains( static int htab_contains(
uint8_t mac[ETH_ALEN], uint8_t mac[ETH_ALEN],
uint8_t fid, uint8_t fid,
int *bucket, int *bucket,
struct filtering_entry **ent) struct filtering_entry **ent)
{ {
for(; *bucket < RTU_BUCKETS; (*bucket)++, (*ent)++) { for(; *bucket < RTU_BUCKETS; (*bucket)++, (*ent)++) {
...@@ -492,9 +492,9 @@ static int htab_contains( ...@@ -492,9 +492,9 @@ static int htab_contains(
if(mac_equal((*ent)->mac, mac) && ((*ent)->fid == fid)) if(mac_equal((*ent)->mac, mac) && ((*ent)->fid == fid))
return FOUND; return FOUND;
if(*bucket == LAST_RTU_BUCKET) if(*bucket == LAST_RTU_BUCKET)
return NOT_FOUND_AND_FULL; return NOT_FOUND_AND_FULL;
} }
return -EINVAL; return -EINVAL;
} }
/** /**
...@@ -508,9 +508,9 @@ static int htab_contains( ...@@ -508,9 +508,9 @@ static int htab_contains(
* end of bucket. -EINVAL if bucket >= CAM_ENTRIES or HCAM inconsistent. * end of bucket. -EINVAL if bucket >= CAM_ENTRIES or HCAM inconsistent.
*/ */
static int hcam_contains( static int hcam_contains(
uint8_t mac[ETH_ALEN], uint8_t mac[ETH_ALEN],
uint8_t fid, uint8_t fid,
int *bucket, int *bucket,
struct filtering_entry **ent) struct filtering_entry **ent)
{ {
for(; *bucket < CAM_ENTRIES; (*bucket)++, (*ent)++) { for(; *bucket < CAM_ENTRIES; (*bucket)++, (*ent)++) {
...@@ -519,25 +519,25 @@ static int hcam_contains( ...@@ -519,25 +519,25 @@ static int hcam_contains(
if(mac_equal((*ent)->mac, mac) && ((*ent)->fid == fid)) if(mac_equal((*ent)->mac, mac) && ((*ent)->fid == fid))
return FOUND; return FOUND;
if((*ent)->end_of_bucket) if((*ent)->end_of_bucket)
return return
(*bucket+1 < CAM_ENTRIES) && !rtu_hcam[*bucket+1].valid ? (*bucket+1 < CAM_ENTRIES) && !rtu_hcam[*bucket+1].valid ?
NOT_FOUND:-ENOMEM; NOT_FOUND:-ENOMEM;
} }
return -EINVAL; return -EINVAL;
} }
/** /**
* \brief Find the most appropriate empty bucket to insert new hash collision * \brief Find the most appropriate empty bucket to insert new hash collision
* list. The algorithm first finds the fragment which contains the max number of * list. The algorithm first finds the fragment which contains the max number of
* consecutive empty positions. Then divides this fragment into two parts: first * consecutive empty positions. Then divides this fragment into two parts: first
* block is still available for possible increment of any existing list; The * block is still available for possible increment of any existing list; The
* second block will be available for the new list. * second block will be available for the new list.
* The algorithm keeps a fair and uniform distribution of fragments space. * The algorithm keeps a fair and uniform distribution of fragments space.
* @return bucket index or -1 if the HCAM table is full. * @return bucket index or -1 if the HCAM table is full.
*/ */
static int find_empty_bucket_in_hcam(void) static int find_empty_bucket_in_hcam(void)
{ {
int bucket = 0; // bucket loop index int bucket = 0; // bucket loop index
int res = 0; // result bucket int res = 0; // result bucket
int empty = 0; // consecutive empty buckets int empty = 0; // consecutive empty buckets
int max = 0; // max consecutive empty buckets int max = 0; // max consecutive empty buckets
...@@ -561,17 +561,17 @@ static int find_empty_bucket_in_hcam(void) ...@@ -561,17 +561,17 @@ static int find_empty_bucket_in_hcam(void)
} }
if(max == 0) // bank is full if(max == 0) // bank is full
return -1; return -1;
else if(max == CAM_ENTRIES) // bank is empty else if(max == CAM_ENTRIES) // bank is empty
return 0; return 0;
else // Divide max space in two blocks and take address of second block else // Divide max space in two blocks and take address of second block
return res + max/2; return res + max/2;
} }
/** /**
* \brief Set the filtering database active bank both in software and hardware. * \brief Set the filtering database active bank both in software and hardware.
* Note both HTAB and HCAM active banks are switched at once. * Note both HTAB and HCAM active banks are switched at once.
* Bank switching is delayed until MFIFO is empty (method remains blocked * Bank switching is delayed until MFIFO is empty (method remains blocked
* meanwhile). * meanwhile).
*/ */
static void set_active_bank(int b) static void set_active_bank(int b)
...@@ -601,7 +601,7 @@ static void clean_fd(void) ...@@ -601,7 +601,7 @@ static void clean_fd(void)
} }
/** /**
* VLAN database initialisation. VLANs are initially marked as disabled. * VLAN database initialisation. VLANs are initially marked as disabled.
*/ */
static void clean_vd(void) static void clean_vd(void)
{ {
...@@ -629,7 +629,7 @@ static void clean_vd(void) ...@@ -629,7 +629,7 @@ static void clean_vd(void)
static void clean_aging_map(void) static void clean_aging_map(void)
{ {
int i; int i;
rtu_agr_hcam = 0x00000000; rtu_agr_hcam = 0x00000000;
rtu_clean_agr_hcam(); rtu_clean_agr_hcam();
for(i = 0; i < RTU_ARAM_MAIN_WORDS; i++) { for(i = 0; i < RTU_ARAM_MAIN_WORDS; i++) {
...@@ -652,13 +652,13 @@ static void update_aging_map(void) ...@@ -652,13 +652,13 @@ static void update_aging_map(void)
} }
/** /**
* \brief Updates the age of filtering entries accessed in the last period. * \brief Updates the age of filtering entries accessed in the last period.
*/ */
static void rtu_fd_age_update(void) static void rtu_fd_age_update(void)
{ {
int i; // Aging Bitmap word loop index int i; // Aging Bitmap word loop index
int j; // Word bits loop index int j; // Word bits loop index
uint32_t agr_word; // Aux var for manipulating aging RAM uint32_t agr_word; // Aux var for manipulating aging RAM
uint16_t hash; // HTAB entry hash (index) uint16_t hash; // HTAB entry hash (index)
int bucket; // HTAB entry bucket int bucket; // HTAB entry bucket
int bit_cnt; // Absolute bit counter int bit_cnt; // Absolute bit counter
...@@ -671,16 +671,16 @@ static void rtu_fd_age_update(void) ...@@ -671,16 +671,16 @@ static void rtu_fd_age_update(void)
agr_word = rtu_agr_htab[i]; agr_word = rtu_agr_htab[i];
if(agr_word != 0x00000000) { if(agr_word != 0x00000000) {
for(j = 0; j < 32; j++){ for(j = 0; j < 32; j++){
if(matched(agr_word, j)) { if(matched(agr_word, j)) {
// ((word_pos x 32) + bit_pos) // ((word_pos x 32) + bit_pos)
bit_cnt = ((i & 0x00FF) << 5) | (j & 0x001F); bit_cnt = ((i & 0x00FF) << 5) | (j & 0x001F);
hash = bit_cnt >> 2; // 4 buckets per hash hash = bit_cnt >> 2; // 4 buckets per hash
bucket = bit_cnt & 0x03; // last 2 bits bucket = bit_cnt & 0x03; // last 2 bits
rtu_htab[hash][bucket].last_access_t = t; rtu_htab[hash][bucket].last_access_t = t;
TRACE( TRACE(
TRACE_INFO, TRACE_INFO,
"updated htab entry age: mac = %s, hash = %d, bucket = %d\n, t = %d", "updated htab entry age: mac = %s, hash = %d, bucket = %d\n, t = %d",
mac_to_string(rtu_htab[hash][bucket].mac), mac_to_string(rtu_htab[hash][bucket].mac),
hash, hash,
bucket, bucket,
...@@ -691,13 +691,13 @@ static void rtu_fd_age_update(void) ...@@ -691,13 +691,13 @@ static void rtu_fd_age_update(void)
} }
} }
// HCAM // HCAM
agr_word = rtu_agr_hcam; agr_word = rtu_agr_hcam;
for(j = 0; j < 32; j++){ for(j = 0; j < 32; j++){
if(matched(agr_word, j)) { if(matched(agr_word, j)) {
rtu_hcam[j].last_access_t = t; rtu_hcam[j].last_access_t = t;
TRACE( TRACE(
TRACE_INFO, TRACE_INFO,
"updated hcam entry age: mac = %s, bucket = %d\n", "updated hcam entry age: mac = %s, bucket = %d\n",
mac_to_string(rtu_hcam[j].mac), mac_to_string(rtu_hcam[j].mac),
j j
); );
...@@ -706,8 +706,8 @@ static void rtu_fd_age_update(void) ...@@ -706,8 +706,8 @@ static void rtu_fd_age_update(void)
} }
/** /**
* For each filtering entry in the filtering database, this method checks its * For each filtering entry in the filtering database, this method checks its
* last access time and removes it in case entry is older than the aging time. * last access time and removes it in case entry is older than the aging time.
*/ */
static void rtu_fd_age_out(void) static void rtu_fd_age_out(void)
{ {
...@@ -722,7 +722,7 @@ static void rtu_fd_age_out(void) ...@@ -722,7 +722,7 @@ static void rtu_fd_age_out(void)
ent = &rtu_hcam[j]; ent = &rtu_hcam[j];
if(ent->valid && ent->dynamic && time_after(t, ent->last_access_t)) { if(ent->valid && ent->dynamic && time_after(t, ent->last_access_t)) {
TRACE( TRACE(
TRACE_INFO, TRACE_INFO,
"deleting hcam entry: mac = %s, bucket = %d\n", "deleting hcam entry: mac = %s, bucket = %d\n",
mac_to_string(ent->mac), mac_to_string(ent->mac),
j j
...@@ -730,13 +730,13 @@ static void rtu_fd_age_out(void) ...@@ -730,13 +730,13 @@ static void rtu_fd_age_out(void)
delete_hcam_entry(j); delete_hcam_entry(j);
} }
} }
// HTAB // HTAB
for (i = HTAB_ENTRIES; i-- > 0;) { for (i = HTAB_ENTRIES; i-- > 0;) {
for (j = RTU_BUCKETS; j-- > 0;) { for (j = RTU_BUCKETS; j-- > 0;) {
ent = &rtu_htab[i][j]; ent = &rtu_htab[i][j];
if(ent->valid && ent->dynamic && time_after(t, ent->last_access_t)){ if(ent->valid && ent->dynamic && time_after(t, ent->last_access_t)){
TRACE( TRACE(
TRACE_INFO, TRACE_INFO,
"deleting htab entry: mac = %s, hash = %d, bucket = %d\n", "deleting htab entry: mac = %s, hash = %d, bucket = %d\n",
mac_to_string(ent->mac), mac_to_string(ent->mac),
i, i,
...@@ -751,7 +751,7 @@ static void rtu_fd_age_out(void) ...@@ -751,7 +751,7 @@ static void rtu_fd_age_out(void)
} }
/** /**
* \brief Read changes from hw_req_list and invoke RTU driver to efectively * \brief Read changes from hw_req_list and invoke RTU driver to efectively
* write or clean the entry. * write or clean the entry.
*/ */
static void rtu_hw_commit(void) static void rtu_hw_commit(void)
...@@ -771,9 +771,9 @@ static void rtu_hw_commit(void) ...@@ -771,9 +771,9 @@ static void rtu_hw_commit(void)
rtu_clean_htab_entry(req->handle.addr); rtu_clean_htab_entry(req->handle.addr);
else else
rtu_clean_hcam_entry(req->handle.addr); rtu_clean_hcam_entry(req->handle.addr);
break; break;
} }
} }
} }
/** /**
...@@ -787,7 +787,7 @@ static void rtu_fd_commit(void) ...@@ -787,7 +787,7 @@ static void rtu_fd_commit(void)
// write entries to inactive bank // write entries to inactive bank
rtu_hw_commit(); rtu_hw_commit();
// switch bank to make entries available to RTU at HW // switch bank to make entries available to RTU at HW
set_active_bank(bank); set_active_bank(bank);
// both banks need same content // both banks need same content
rtu_hw_commit(); rtu_hw_commit();
...@@ -797,7 +797,7 @@ static void rtu_fd_commit(void) ...@@ -797,7 +797,7 @@ static void rtu_fd_commit(void)
} }
/** /**
* \brief Shifts HTAB list one position, starting at bucket. * \brief Shifts HTAB list one position, starting at bucket.
*/ */
static void shift_htab_entries(uint16_t hash, int bucket) static void shift_htab_entries(uint16_t hash, int bucket)
{ {
...@@ -820,10 +820,10 @@ static void shift_htab_entries(uint16_t hash, int bucket) ...@@ -820,10 +820,10 @@ static void shift_htab_entries(uint16_t hash, int bucket)
} }
/** /**
* \brief Shifts HCAM list one position, starting at bucket. * \brief Shifts HCAM list one position, starting at bucket.
* If entry to remove is end of bucket, marks previous one (if exists) as the * If entry to remove is end of bucket, marks previous one (if exists) as the
* new end of bucket. * new end of bucket.
* @return -1 if more entries remain in HCAM. Otherwise, returns the hash for * @return -1 if more entries remain in HCAM. Otherwise, returns the hash for
* entry, in order to help modifying the last HTAB entry * entry, in order to help modifying the last HTAB entry
*/ */
static int shift_hcam_entries(int bucket) static int shift_hcam_entries(int bucket)
...@@ -839,17 +839,17 @@ static int shift_hcam_entries(int bucket) ...@@ -839,17 +839,17 @@ static int shift_hcam_entries(int bucket)
for(i = bucket; i < LAST_CAM_ENTRY; i++){ for(i = bucket; i < LAST_CAM_ENTRY; i++){
if(ent->end_of_bucket){ if(ent->end_of_bucket){
if(i > bucket) // entry to remove was not the last if(i > bucket) // entry to remove was not the last
break; break;
if(i == 0){ // entry to remove was last but there are no previous if(i == 0){ // entry to remove was last but there are no previous
ret = rtu_hash(ent->mac, ent->fid); ret = rtu_hash(ent->mac, ent->fid);
break; break;
} }
prev_ent = ent-1; prev_ent = ent-1;
if(!prev_ent->valid || prev_ent->end_of_bucket){ if(!prev_ent->valid || prev_ent->end_of_bucket){
// prev entry not valid or part of another list // prev entry not valid or part of another list
ret = rtu_hash(ent->mac, ent->fid); ret = rtu_hash(ent->mac, ent->fid);
break; break;
} }
// mark previous as end_of_bucket // mark previous as end_of_bucket
prev_ent->end_of_bucket = 1; prev_ent->end_of_bucket = 1;
write_hcam_entry(cam_addr(i-1), prev_ent); write_hcam_entry(cam_addr(i-1), prev_ent);
...@@ -886,7 +886,7 @@ static void delete_hcam_entry(int bucket) ...@@ -886,7 +886,7 @@ static void delete_hcam_entry(int bucket)
} }
/** /**
* \brief Deletes HTAB entry by shifting HTAB list. * \brief Deletes HTAB entry by shifting HTAB list.
* If HCAM is used, it also copies first HCAM entry to last HTAB bucket. * If HCAM is used, it also copies first HCAM entry to last HTAB bucket.
* @param hash hashcode for entry to remove. * @param hash hashcode for entry to remove.
* @param bucket HTAB bucket for entry to remove * @param bucket HTAB bucket for entry to remove
...@@ -897,7 +897,7 @@ static void delete_htab_entry(uint16_t hash, int bucket) ...@@ -897,7 +897,7 @@ static void delete_htab_entry(uint16_t hash, int bucket)
struct filtering_entry *prev_ent; struct filtering_entry *prev_ent;
struct filtering_entry *cam_ent; struct filtering_entry *cam_ent;
int hcam_bucket; int hcam_bucket;
shift_htab_entries(hash, bucket); shift_htab_entries(hash, bucket);
...@@ -909,7 +909,7 @@ static void delete_htab_entry(uint16_t hash, int bucket) ...@@ -909,7 +909,7 @@ static void delete_htab_entry(uint16_t hash, int bucket)
prev_ent->cam_addr = 0; prev_ent->cam_addr = 0;
// changes will be written to hw when shift operations are commited // changes will be written to hw when shift operations are commited
// copy first cam entry into last HTAB entry // copy first cam entry into last HTAB entry
hcam_bucket = cam_bucket(ent->cam_addr); hcam_bucket = cam_bucket(ent->cam_addr);
cam_ent = &rtu_hcam[hcam_bucket]; cam_ent = &rtu_hcam[hcam_bucket];
rtu_fe_copy(ent, cam_ent); rtu_fe_copy(ent, cam_ent);
......
...@@ -8,9 +8,9 @@ ...@@ -8,9 +8,9 @@
* Miguel Baizan (miguel.baizan@integrasys.es) * Miguel Baizan (miguel.baizan@integrasys.es)
* Maciej Lipinski (maciej.lipinski@cern.ch) * Maciej Lipinski (maciej.lipinski@cern.ch)
* *
* Description: RTU Filtering database header. * Description: RTU Filtering database header.
* Filtering database management related operations and filtering * Filtering database management related operations and filtering
* database mirror. Note there is a single Filtering Database * database mirror. Note there is a single Filtering Database
* object per Bridge (See 802.1Q - 12.7.1) * object per Bridge (See 802.1Q - 12.7.1)
* *
* Fixes: * Fixes:
...@@ -40,13 +40,13 @@ ...@@ -40,13 +40,13 @@
#define STATIC 0 #define STATIC 0
#define DYNAMIC 1 #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)); __attribute__((warn_unused_result));
int rtu_fd_create_entry( int rtu_fd_create_entry(
uint8_t mac[ETH_ALEN], uint8_t mac[ETH_ALEN],
uint16_t vid, uint16_t vid,
uint32_t port_map, uint32_t port_map,
int dynamic int dynamic
) __attribute__((warn_unused_result)); ) __attribute__((warn_unused_result));
......
...@@ -6,8 +6,8 @@ ...@@ -6,8 +6,8 @@
* *
* Authors: Maciej Lipinski (maciej.lipinski@cern.ch) * Authors: Maciej Lipinski (maciej.lipinski@cern.ch)
* *
* Description: Hash function presented below, produces hash which corresponds * Description: Hash function presented below, produces hash which corresponds
* to hash produced by VHDL generated on this page: * to hash produced by VHDL generated on this page:
* http://outputlogic.com/ * http://outputlogic.com/
* *
* Fixes: * Fixes:
...@@ -47,7 +47,7 @@ void rtu_hash_set_poly(uint16_t poly) ...@@ -47,7 +47,7 @@ void rtu_hash_set_poly(uint16_t poly)
uint16_t rtu_hash(uint8_t mac[ETH_ALEN], uint8_t fid) uint16_t rtu_hash(uint8_t mac[ETH_ALEN], uint8_t fid)
{ {
uint16_t hash = 0xFFFF; uint16_t hash = 0xFFFF;
hash = crc16(hash, (0xFFFF & fid)); hash = crc16(hash, (0xFFFF & fid));
hash = crc16(hash, ((uint16_t)mac[0] << 8) | mac[1]); 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[2] << 8) | mac[3]);
...@@ -60,40 +60,40 @@ uint16_t rtu_hash(uint8_t mac[ETH_ALEN], uint8_t fid) ...@@ -60,40 +60,40 @@ uint16_t rtu_hash(uint8_t mac[ETH_ALEN], uint8_t fid)
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
-- SOME EXPLANATION REGARDING VHDL vs C CRC IMPLEMENTATION BY ML -- 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/ . -- with http://outputlogic.com/ .
-- it uses naive method, it's not optimal at all -- it uses naive method, it's not optimal at all
-- but it's good enough to chech whether VHDL works OK -- but it's good enough to chech whether VHDL works OK
-- It was made (by maciej.lipinski@cern.ch) modifying source from here: -- It was made (by maciej.lipinski@cern.ch) modifying source from here:
-- http://www.netrino.com/Embedded-Systems/How-To/CRC-Calculation-C-Code -- http://www.netrino.com/Embedded-Systems/How-To/CRC-Calculation-C-Code
-- the website provides explanation of CRC -- the website provides explanation of CRC
-- --
-- To get the hex representation of POLY to be used with the C function, which -- 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 -- is different than hex representation of polly used to generate VHDL code
-- (i.e.:0x1021 <->0x88108), here is the trick: -- (i.e.:0x1021 <->0x88108), here is the trick:
-- --
-- 1) we are using the following poly equation: 1+x^5+x^12+x^16; -- 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 -- |-> it's the 16th bit |-> the wiki as description
-- of the polly equation -- of the polly equation
-- --
-- 3) we include the "default" bit into the polly and add zeroes at the end -- 3) we include the "default" bit into the polly and add zeroes at the end
-- creating 20 bit polly, like this -- 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 | --| name | polly equation | polly (hex) | our polly | tested |
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
--| CRC-16-CCITT | 1+x^5+x^12+x^16 | 0x1021 | 0x88108 | yes | --| 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-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) static uint16_t crc16(uint16_t const init_crc, uint16_t const message)
{ {
uint32_t remainder; uint32_t remainder;
int bit; int bit;
// Initially, the dividend is the remainder. // Initially, the dividend is the remainder.
......
...@@ -6,8 +6,8 @@ ...@@ -6,8 +6,8 @@
* *
* Authors: Maciej Lipinski (maciej.lipinski@cern.ch) * Authors: Maciej Lipinski (maciej.lipinski@cern.ch)
* *
* Description: Hash function presented below, produces hash which corresponds * Description: Hash function presented below, produces hash which corresponds
* to hash produced by VHDL generated on this page: * to hash produced by VHDL generated on this page:
* http://outputlogic.com/ * http://outputlogic.com/
* *
* Fixes: * Fixes:
...@@ -34,16 +34,16 @@ ...@@ -34,16 +34,16 @@
/* /*
Hash polynomials implemented by RTU 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-CCITT | 1+x^5+x^12+x^16 | 0x1021 |
| CRC-16-IBM | 1+x^2+x^15+x^16 | 0x8005 | | 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 | | CRC-16-DECT | 1+x^3+x^7+x^8+x^10+x^16 | 0x0589 |
--------------------------------------------------------- ---------------------------------------------------------
*/ */
#define HW_POLYNOMIAL_CCITT 0x1021 #define HW_POLYNOMIAL_CCITT 0x1021
#define HW_POLYNOMIAL_IBM 0x8005 #define HW_POLYNOMIAL_IBM 0x8005
#define HW_POLYNOMIAL_DECT 0x0589 #define HW_POLYNOMIAL_DECT 0x0589
void rtu_hash_set_poly(uint16_t poly); void rtu_hash_set_poly(uint16_t poly);
uint16_t rtu_hash(uint8_t mac[ETH_ALEN], uint8_t fid); uint16_t rtu_hash(uint8_t mac[ETH_ALEN], uint8_t fid);
......
...@@ -7,14 +7,14 @@ ...@@ -7,14 +7,14 @@
* Authors: Juan Luis Manas (juan.manas@integrasys.es) * Authors: Juan Luis Manas (juan.manas@integrasys.es)
* Miguel Baizan (miguel.baizan@integrasys.es) * Miguel Baizan (miguel.baizan@integrasys.es)
* *
* Description: RTU daemon. * Description: RTU daemon.
* Handles the learning and aging processes. * Handles the learning and aging processes.
* Manages the filtering and VLAN databases. * Manages the filtering and VLAN databases.
* *
* Fixes: * Fixes:
* Alessandro Rubini * Alessandro Rubini
* Tomasz Wlostowski * Tomasz Wlostowski
* *
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
...@@ -50,7 +50,7 @@ static pthread_t aging_process; ...@@ -50,7 +50,7 @@ static pthread_t aging_process;
static pthread_t wripc_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 * @return error code
*/ */
static int rtu_create_static_entries() static int rtu_create_static_entries()
...@@ -66,7 +66,7 @@ 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); err = rtu_fd_create_entry(bcast_mac, 0, 0xffffffff, STATIC);
if(err) if(err)
return err; return err;
// VLAN-aware Bridge reserved addresses (802.1Q-2005 Table 8.1) // VLAN-aware Bridge reserved addresses (802.1Q-2005 Table 8.1)
TRACE(TRACE_INFO,"adding static routes for slow protocols..."); TRACE(TRACE_INFO,"adding static routes for slow protocols...");
for(i = 0; i < NUM_RESERVED_ADDR; i++) { for(i = 0; i < NUM_RESERVED_ADDR; i++) {
...@@ -75,16 +75,16 @@ static int rtu_create_static_entries() ...@@ -75,16 +75,16 @@ static int rtu_create_static_entries()
if(err) if(err)
return err; return err;
} }
// packets addressed to WR card interfaces are forwarded to NIC virtual port // 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++) { 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(
TRACE_INFO, TRACE_INFO,
"adding static route for port %s index %d [mac %s]", "adding static route for port %s index %d [mac %s]",
plist.port_names[i], plist.port_names[i],
pstate.hw_index, pstate.hw_index,
mac_to_string(pstate.hw_addr) mac_to_string(pstate.hw_addr)
); );
err = rtu_fd_create_entry(pstate.hw_addr, 0, (1 << NIC_PORT), STATIC); err = rtu_fd_create_entry(pstate.hw_addr, 0, (1 << NIC_PORT), STATIC);
...@@ -128,12 +128,12 @@ static void *rtu_daemon_wripc_process(void *arg) ...@@ -128,12 +128,12 @@ static void *rtu_daemon_wripc_process(void *arg)
} }
/** /**
* \brief Handles the learning process. * \brief Handles the learning process.
* @return error code * @return error code
*/ */
static int rtu_daemon_learning_process() static int rtu_daemon_learning_process()
{ {
int err; int err;
struct rtu_request req; // Request read from learning queue struct rtu_request req; // Request read from learning queue
uint32_t port_map; // Destination port map uint32_t port_map; // Destination port map
uint16_t vid; // VLAN identifier uint16_t vid; // VLAN identifier
...@@ -144,8 +144,8 @@ static int rtu_daemon_learning_process() ...@@ -144,8 +144,8 @@ static int rtu_daemon_learning_process()
if (!err) { if (!err) {
TRACE_DBG( TRACE_DBG(
TRACE_INFO, TRACE_INFO,
"ureq: port %d src %s VID %d priority %d", "ureq: port %d src %s VID %d priority %d",
req.port_id, req.port_id,
mac_to_string(req.src), mac_to_string(req.src),
req.has_vid ? req.vid:0, req.has_vid ? req.vid:0,
req.has_prio ? req.prio:0 req.has_prio ? req.prio:0
...@@ -171,7 +171,7 @@ static int rtu_daemon_learning_process() ...@@ -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. * Initialises routing table cache and RTU at hardware.
* @param poly hash polinomial. * @param poly hash polinomial.
* @param aging_time Aging time in seconds. * @param aging_time Aging time in seconds.
...@@ -207,7 +207,7 @@ static int rtu_daemon_init(uint16_t poly, unsigned long aging_time) ...@@ -207,7 +207,7 @@ static int rtu_daemon_init(uint16_t poly, unsigned long aging_time)
// init filtering database // init filtering database
TRACE(TRACE_INFO, "init fd."); TRACE(TRACE_INFO, "init fd.");
err = rtu_fd_init(poly, aging_time); err = rtu_fd_init(poly, aging_time);
if (err) if (err)
return err; return err;
// create static filtering entries // create static filtering entries
...@@ -228,7 +228,7 @@ static int rtu_daemon_init(uint16_t poly, unsigned long aging_time) ...@@ -228,7 +228,7 @@ static int rtu_daemon_init(uint16_t poly, unsigned long aging_time)
* \brief RTU shutdown. * \brief RTU shutdown.
*/ */
static void rtu_daemon_destroy() static void rtu_daemon_destroy()
{ {
// Threads stuff // Threads stuff
pthread_cancel(wripc_process); pthread_cancel(wripc_process);
pthread_cancel(aging_process); pthread_cancel(aging_process);
...@@ -245,11 +245,11 @@ void sigint(int signum) { ...@@ -245,11 +245,11 @@ void sigint(int signum) {
/** /**
* \brief Starts up the learning and aging processes. * \brief Starts up the learning and aging processes.
*/ */
int main(int argc, char **argv) int main(int argc, char **argv)
{ {
int op, err; int op, err;
char *s, *name, *optstring; char *s, *name, *optstring;
int run_as_daemon = 0; int run_as_daemon = 0;
uint16_t poly = HW_POLYNOMIAL_CCITT; // Hash polinomial uint16_t poly = HW_POLYNOMIAL_CCITT; // Hash polinomial
unsigned long aging_res = DEFAULT_AGING_RES; // Aging resolution [sec.] unsigned long aging_res = DEFAULT_AGING_RES; // Aging resolution [sec.]
...@@ -272,7 +272,7 @@ int main(int argc, char **argv) ...@@ -272,7 +272,7 @@ int main(int argc, char **argv)
run_as_daemon = 1; run_as_daemon = 1;
break; break;
case 'h': case 'h':
usage(name); usage(name);
case 'p': case 'p':
if (strcmp(optarg, "CCITT") == 0) { if (strcmp(optarg, "CCITT") == 0) {
poly = HW_POLYNOMIAL_CCITT; poly = HW_POLYNOMIAL_CCITT;
...@@ -293,7 +293,7 @@ int main(int argc, char **argv) ...@@ -293,7 +293,7 @@ int main(int argc, char **argv)
break; break;
case 't': case 't':
aging_time = atol(optarg); aging_time = atol(optarg);
if ((aging_time < MIN_AGING_TIME) || if ((aging_time < MIN_AGING_TIME) ||
(aging_time > MAX_AGING_TIME)) { (aging_time > MAX_AGING_TIME)) {
fprintf(stderr, "Invalid aging time\n"); fprintf(stderr, "Invalid aging time\n");
usage(name); usage(name);
...@@ -305,7 +305,7 @@ int main(int argc, char **argv) ...@@ -305,7 +305,7 @@ int main(int argc, char **argv)
} }
} }
// Initialise RTU. // Initialise RTU.
if((err = rtu_daemon_init(poly, aging_time)) < 0) { if((err = rtu_daemon_init(poly, aging_time)) < 0) {
rtu_daemon_destroy(); rtu_daemon_destroy();
return err; return err;
...@@ -315,7 +315,7 @@ int main(int argc, char **argv) ...@@ -315,7 +315,7 @@ int main(int argc, char **argv)
signal(SIGINT, sigint); signal(SIGINT, sigint);
// daemonize _before_ creating threads // daemonize _before_ creating threads
if(run_as_daemon) if(run_as_daemon)
daemonize(); daemonize();
// Start up aging process and auxiliary WRIPC thread // Start up aging process and auxiliary WRIPC thread
...@@ -324,7 +324,7 @@ int main(int argc, char **argv) ...@@ -324,7 +324,7 @@ int main(int argc, char **argv)
rtu_daemon_destroy(); rtu_daemon_destroy();
return err; return err;
} }
// Start up learning process. // Start up learning process.
err = rtu_daemon_learning_process(); err = rtu_daemon_learning_process();
// On error, release RTU resources // On error, release RTU resources
......
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
* Description: Dump the filtering database. Based on libwripc * Description: Dump the filtering database. Based on libwripc
* *
* Fixes: * Fixes:
* *
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
...@@ -52,7 +52,7 @@ int rtud_init_exports() ...@@ -52,7 +52,7 @@ int rtud_init_exports()
return rtud_ipc; return rtud_ipc;
TRACE(TRACE_INFO,"wripc server created [fd %d]", rtud_ipc); TRACE(TRACE_INFO,"wripc server created [fd %d]", rtud_ipc);
wripc_export(rtud_ipc, T_STRUCT(rtudexp_fd_list_t), "rtudexp_get_fd_list", rtudexp_get_fd_list, 1, T_INT32); wripc_export(rtud_ipc, T_STRUCT(rtudexp_fd_list_t), "rtudexp_get_fd_list", rtudexp_get_fd_list, 1, T_INT32);
...@@ -62,14 +62,14 @@ int rtud_init_exports() ...@@ -62,14 +62,14 @@ int rtud_init_exports()
void rtudexp_get_fd_list(rtudexp_fd_list_t *list, int start_from) void rtudexp_get_fd_list(rtudexp_fd_list_t *list, int start_from)
{ {
int i; int i;
//TRACE(TRACE_INFO,"GetFDList start=%d",start_from); //TRACE(TRACE_INFO,"GetFDList start=%d",start_from);
for(i=0;i<8;i++) for(i=0;i<8;i++)
{ {
struct filtering_entry *ent = rtu_fd_lookup_htab_entry(start_from + i); struct filtering_entry *ent = rtu_fd_lookup_htab_entry(start_from + i);
if(!ent) break; if(!ent) break;
memcpy(list->list[i].mac, ent->mac, sizeof(ent->mac)); memcpy(list->list[i].mac, ent->mac, sizeof(ent->mac));
// printf("Ent: %s %x\n", mac_to_string(ent->mac), ent->port_mask_dst); // printf("Ent: %s %x\n", mac_to_string(ent->mac), ent->port_mask_dst);
......
...@@ -6,10 +6,10 @@ ...@@ -6,10 +6,10 @@
* *
* Authors: Tomasz Wlostowski (tomasz.wlostowski@cern.ch) * Authors: Tomasz Wlostowski (tomasz.wlostowski@cern.ch)
* *
* Description: Dump the filtering database. * Description: Dump the filtering database.
* *
* Fixes: * Fixes:
* *
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
...@@ -31,7 +31,7 @@ ...@@ -31,7 +31,7 @@
#include <stdint.h> #include <stdint.h>
typedef struct typedef struct
{ {
uint8_t mac[8]; uint8_t mac[8];
uint32_t dpm; uint32_t dpm;
...@@ -42,7 +42,7 @@ typedef struct ...@@ -42,7 +42,7 @@ typedef struct
typedef struct { typedef struct {
rtudexp_fd_entry_t list[8]; rtudexp_fd_entry_t list[8];
int num_rules; int num_rules;
int next; int next;
} rtudexp_fd_list_t; } rtudexp_fd_list_t;
......
...@@ -10,7 +10,7 @@ ...@@ -10,7 +10,7 @@
* background * background
* *
* Fixes: * Fixes:
* *
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
...@@ -79,10 +79,10 @@ void daemonize(void) ...@@ -79,10 +79,10 @@ void daemonize(void)
void usage(char *name) void usage(char *name)
{ {
fprintf(stderr, fprintf(stderr,
"Usage: %s [-dh] [-p <polly>] [-r <time>] [-t <time>]\n" "Usage: %s [-dh] [-p <polly>] [-r <time>] [-t <time>]\n"
"\t-d daemonize\n" "\t-d daemonize\n"
"\t-h help\n" "\t-h help\n"
"\t-p polynomial for hash calculation. Possible values are CCITT, IBM, DECT\n" "\t-p polynomial for hash calculation. Possible values are CCITT, IBM, DECT\n"
"\t-r aging resolution (in sec). 20 sec by default\n" "\t-r aging resolution (in sec). 20 sec by default\n"
"\t-t aging time (10 to 10000 sec). 300 sec by default.\n", "\t-t aging time (10 to 10000 sec). 300 sec by default.\n",
......
...@@ -10,7 +10,7 @@ ...@@ -10,7 +10,7 @@
* background * background
* *
* Fixes: * Fixes:
* *
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
......
#ifndef __WHITERABBIT_RTU_IRQ_H #ifndef __WHITERABBIT_RTU_IRQ_H
#define __WHITERABBIT_RTU_IRQ_H #define __WHITERABBIT_RTU_IRQ_H
#define __WR_IOC_MAGIC '4' #define __WR_IOC_MAGIC '4'
#define WR_RTU_IRQWAIT _IO(__WR_IOC_MAGIC, 4) #define WR_RTU_IRQWAIT _IO(__WR_IOC_MAGIC, 4)
#define WR_RTU_IRQENA _IO(__WR_IOC_MAGIC, 5) #define WR_RTU_IRQENA _IO(__WR_IOC_MAGIC, 5)
......
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