# software/wrsw_rtud/rtu_fd.c File Reference

`#include <stdlib.h>`
`#include <unistd.h>`
`#include <pthread.h>`
`#include <hw/wrsw_rtu_wb.h>`
`#include <hw/trace.h>`
`#include "rtu_fd.h"`
`#include "rtu_drv.h"`
`#include "rtu_hash.h"`

## Data Structures

struct | fd_handle
| Filtering Database entry handle. More...
struct | hw_req
| HW (HTAB or HCAM) write request. More...

## Defines

#define | HTAB 0
#define | HCAM 1
#define | HW_WRITE_REQ 0
#define | HW_CLEAN_REQ 1
#define | FOUND 1
#define | NOT_FOUND 0
#define | NOT_FOUND_AND_FULL -1
#define | NOT_FOUND_AND_FIRST -1

## Functions

static struct hw_req * | tail (struct hw_req *head)
static void | clean_list (struct hw_req *head)
static int | add_hw_req (int type, int mem, uint16_t addr, struct filtering_entry *ent)
| Adds a new HW request at the end of the main hw request list.
static int | write_htab_entry (uint16_t addr, struct filtering_entry *e)
static int | write_hcam_entry (uint16_t addr, struct filtering_entry *e)
static int | clean_htab_entry (uint16_t addr)
static int | clean_hcam_entry (uint16_t addr)
static uint16_t | zbt_addr (uint16_t hash, int bucket)
static uint16_t | cam_addr (int bucket)
static int | cam_bucket (uint16_t cam_addr)
static int | matched (uint32_t word, int offset)
static int | htab_contains (uint8_t mac[ETH_ALEN], uint8_t fid, int *bucket, struct filtering_entry **ent)
| Checks whether a given pair (mac,fid) is at HTAB.
static int | hcam_contains (uint8_t mac[ETH_ALEN], uint8_t fid, int *bucket, struct filtering_entry **ent)
static int | find_empty_bucket_in_hcam (void)

Find the most appropriate empty bucket to insert new hash collision list. The algorithm first finds the fragment which contains the max number of consecutive empty positions. Then divides this fragment into two parts: first block is still available for possible increment of any existing list; The second block will be available for the new list. The algorithm keeps a fair and uniform distribution of fragments space.

static void | set_active_bank (int b)
| Set the filtering database active bank both in software and hardware. Note both HTAB and HCAM active banks are switched at once. Bank switching is delayed until MFIFO is empty (method remains blocked meanwhile).
static void | clean_fd (void)
static void | clean_vd (void)
static void | clean_aging_map (void)
| Clean HCAM aging register and HTAB aging bitmap.
static void | update_aging_map (void)
| Update aging map cache with contents read from aging registers at HW.
static void | rtu_hw_commit (void)
| Read changes from hw_req_list and invoke RTU driver to efectively write or clean the entry.
static void | rtu_fd_commit (void)
| Commits entry changes at software to hardware HTAB and HCAM.
static void | shift_htab_entries (uint16_t hash, int bucket)
| Shifts HTAB list one position, starting at bucket.
static int | shift_hcam_entries (int bucket)
| Shifts HCAM list one position, starting at bucket. If entry to remove is end of bucket, marks previous one (if exists) as the new end of bucket.
static void | delete_htab_entry (uint16_t hash, int bucket)
| Deletes HTAB entry by shifting HTAB list. If HCAM is used, it also copies first HCAM entry to last HTAB bucket.
static void | delete_hcam_entry (int bucket)
| Deletes HCAM entry by shifting HCAM list. Updates HTAB last entry if neccessary.
static void | rtu_fd_age_out (void)
static void | rtu_fd_age_update (void)
| Updates the age of filtering entries accessed in the last period.
int | rtu_fd_init (uint16_t poly, unsigned long aging)
| Initializes the RTU filtering database.
int | rtu_fd_create_entry (uint8_t mac[ETH_ALEN], uint16_t vid, uint32_t port_map, int dynamic)
| Creates or updates a filtering entry in the filtering database.
void | rtu_fd_set_hash_poly (uint16_t poly)
| Set the polynomial used for hash calculation. Changing the hash polynomial requires removing any existing entry from RTU table. Note in case RTU table becomes full, this function may be used to change hash polynomial (thus leading to a different hash distribution).
int | rtu_fd_set_aging_time (unsigned long t)
| Sets the aging time for dynamic filtering entries.
void | rtu_fd_flush (void)
| Deletes old filtering entries from filtering database to support changes in active topology.
struct filtering_entry * | rtu_fd_lookup_htab_entry (int index)

## Variables

struct hw_req * | hw_req_list
| HW write and clean requests list. Used to temporarily store entry changes performed at SW.
static struct filtering_entry | rtu_htab [HTAB_ENTRIES][RTU_BUCKETS]
| Mirror of ZBT SRAM memory MAC address table. Main filtering table organized as hash table with 4-entry buckets. Note both banks have the same content. Therefore SW only mirrors one bank.
static struct filtering_entry | rtu_hcam [CAM_ENTRIES]
| Mirror of CAM lookup table. For RTU entries with more than 4 matches.
static uint8_t | bank
| Table bank to write entries to. HTAB and HCAM banks will be handled according to this single bank value.
static uint32_t | rtu_agr_htab [RTU_ARAM_MAIN_WORDS]
| Mirror of Aging RAM.
static uint32_t | rtu_agr_hcam
static unsigned long | aging_time = DEFAULT_AGING_TIME
| Max time that a dynamic MAC entry can remain in the MAC table after being used. [seconds].
static struct vlan_table_entry | vlan_tab [NUM_VLANS]
static pthread_mutex_t | fd_mutex
| Mutex used to synchronise concurrent access to the filtering database.

## Define Documentation

#define FOUND 1

#define HCAM 1

#define HTAB 0

#define HW_CLEAN_REQ 1

#define HW_WRITE_REQ 0

#define NOT_FOUND 0

#define NOT_FOUND_AND_FIRST -1

#define NOT_FOUND_AND_FULL -1

## Function Documentation

static int add_hw_req | ( | int | type,
|  | int | mem,
|  | uint16_t | addr,
|  | struct filtering_entry * | ent
| ) |  | `[static]`

Adds a new HW request at the end of the main hw request list.

static uint16_t cam_addr | ( | int | bucket ) | `[inline, static]`

static int cam_bucket | ( | uint16_t | cam_addr ) | `[inline, static]`

static void clean_aging_map | ( | void | ) | `[static]`

Clean HCAM aging register and HTAB aging bitmap.

static void clean_fd | ( | void | ) | `[static]`

Filtering database initialisation.

static int clean_hcam_entry | ( | uint16_t | addr ) | `[inline, static]`

static int clean_htab_entry | ( | uint16_t | addr ) | `[inline, static]`

static void clean_list | ( | struct hw_req * | head ) | `[static]`

Removes all elements from the hw_req_list

static void clean_vd | ( | void | ) | `[static]`

VLAN database initialisation. VLANs are initially marked as disabled.

static void delete_hcam_entry | ( | int | bucket ) | `[static]`

Deletes HCAM entry by shifting HCAM list. Updates HTAB last entry if neccessary.

Parameters:

  bucket | CAM entry address

static void delete_htab_entry | ( | uint16_t | hash,
|  | int | bucket
| ) |  | `[static]`

Deletes HTAB entry by shifting HTAB list. If HCAM is used, it also copies first HCAM entry to last HTAB bucket.

Parameters:

  hash | hashcode for entry to remove.
  bucket | HTAB bucket for entry to remove

static int find_empty_bucket_in_hcam | ( | void | ) | `[static]`

Find the most appropriate empty bucket to insert new hash collision list. The algorithm first finds the fragment which contains the max number of consecutive empty positions. Then divides this fragment into two parts: first block is still available for possible increment of any existing list; The second block will be available for the new list. The algorithm keeps a fair and uniform distribution of fragments space.

Returns:
  bucket index or -1 if the HCAM table is full.

static int hcam_contains | ( | uint8_t | mac[ETH_ALEN],
|  | uint8_t | fid,
|  | int * | bucket,
|  | struct filtering_entry ** | ent
| ) |  | `[static]`

Checks whether a given pair (mac,fid) is at HCAM

Parameters:

  mac | mac address
  fid | filtering database identifier
  bucket | inout param.Returns the bucket number where the entry was found
  ent | pointer to entry found.

Returns:
  0 if entry was not found. 1 if entry was found. -1 if entry was not found and the end of bucket was reached. -ENOMEM if no more entries after the end of bucket. -EINVAL if bucket >= CAM_ENTRIES or HCAM inconsistent.

static int htab_contains | ( | uint8_t | mac[ETH_ALEN],
|  | uint8_t | fid,
|  | int * | bucket,
|  | struct filtering_entry ** | ent
| ) |  | `[static]`

Checks whether a given pair (mac,fid) is at HTAB.

Parameters:

  mac | mac address
  fid | filtering database identifier
  bucket | inout param.Returns the bucket number where the entry was found
  ent | pointer to entry found.

Returns:
  0 if entry was not found. 1 if entry was found. -1 if not found and HTAB was full for the corresponding hash. -EINVAL if bucket >= RTU_BUCKETS

static int matched | ( | uint32_t | word,
|  | int | offset
| ) |  | `[inline, static]`

static void rtu_fd_age_out | ( | void | ) | `[static]`

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.

static void rtu_fd_age_update | ( | void | ) | `[static]`

Updates the age of filtering entries accessed in the last period.

static void rtu_fd_commit | ( | void | ) | `[static]`

Commits entry changes at software to hardware HTAB and HCAM.

int rtu_fd_create_entry | ( | uint8_t | mac[ETH_ALEN],
|  | uint16_t | vid,
|  | uint32_t | port_map,
|  | int | dynamic
| ) |  |

Creates or updates a filtering entry in the filtering database.

Parameters:

  mac | MAC address specification
  vid | VLAN identifier
  port_map | a port map specification with a control element for each outbound port to specify filtering for that MAC address specification and VID
  dynamic | it indicates whether it's a dynamic entry

Returns:
  0 if entry was created or updated. -ENOMEM if no space is available.

void rtu_fd_flush | ( | void | ) |

Deletes old filtering entries from filtering database to support changes in active topology.

int rtu_fd_init | ( | uint16_t | poly,
|  | unsigned long | aging
| ) |  |

Initializes the RTU filtering database.

Parameters:

  poly | hash polinomial.
  aging | aging time

struct filtering_entry* rtu_fd_lookup_htab_entry | ( | int | index ) | `[read]`

int rtu_fd_set_aging_time | ( | unsigned long | t ) |

Sets the aging time for dynamic filtering entries.

Parameters:

  t | new aging time value [seconds].

Returns:
  -EINVAL if t < 10 or t > 1000000 (802.1Q, Table 8.3); 0 otherwise.

void rtu_fd_set_hash_poly | ( | uint16_t | poly ) |

Set the polynomial used for hash calculation. Changing the hash polynomial requires removing any existing entry from RTU table. Note in case RTU table becomes full, this function may be used to change hash polynomial (thus leading to a different hash distribution).

Parameters:

  poly | binary polynomial representation. 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

static void rtu_hw_commit | ( | void | ) | `[static]`

Read changes from hw_req_list and invoke RTU driver to efectively write or clean the entry.

static void set_active_bank | ( | int | n ) | `[static]`

Set the filtering database active bank both in software and hardware. Note both HTAB and HCAM active banks are switched at once. Bank switching is delayed until MFIFO is empty (method remains blocked meanwhile).

static int shift_hcam_entries | ( | int | bucket ) | `[static]`

Shifts HCAM list one position, starting at bucket. If entry to remove is end of bucket, marks previous one (if exists) as the new end of bucket.

Returns:
  -1 if more entries remain in HCAM. Otherwise, returns the hash for entry, in order to help modifying the last HTAB entry

static void shift_htab_entries | ( | uint16_t | hash,
|  | int | bucket
| ) |  | `[static]`

Shifts HTAB list one position, starting at bucket.

static struct hw_req * tail | ( | struct hw_req * | head ) | `[static, read]`

Returns pointer to last element in hw_req_list.

static void update_aging_map | ( | void | ) | `[static]`

Update aging map cache with contents read from aging registers at HW.

static int write_hcam_entry | ( | uint16_t | addr,
|  | struct filtering_entry * | e
| ) |  | `[inline, static]`

static int write_htab_entry | ( | uint16_t | addr,
|  | struct filtering_entry * | e
| ) |  | `[inline, static]`

static uint16_t zbt_addr | ( | uint16_t | hash,
|  | int | bucket
| ) |  | `[inline, static]`

## Variable Documentation

unsigned long aging_time = DEFAULT_AGING_TIME`[static]`

Max time that a dynamic MAC entry can remain in the MAC table after being used. [seconds].

uint8_t bank`[static]`

Table bank to write entries to. HTAB and HCAM banks will be handled according to this single bank value.

pthread_mutex_t fd_mutex`[static]`

Mutex used to synchronise concurrent access to the filtering database.

struct hw_req* hw_req_list

HW write and clean requests list. Used to temporarily store entry changes performed at SW.

uint32_t rtu_agr_hcam`[static]`

uint32_t rtu_agr_htab[RTU_ARAM_MAIN_WORDS]`[static]`

Mirror of Aging RAM.

struct filtering_entry rtu_hcam[CAM_ENTRIES]`[static]`

Mirror of CAM lookup table. For RTU entries with more than 4 matches.

struct filtering_entry rtu_htab[HTAB_ENTRIES][RTU_BUCKETS]`[static]`

Mirror of ZBT SRAM memory MAC address table. Main filtering table organized as hash table with 4-entry buckets. Note both banks have the same content. Therefore SW only mirrors one bank.

struct vlan_table_entry vlan_tab[NUM_VLANS]`[static]`

Mirror of VLAN table

All Data Structures Files Functions Variables Defines