dispatch_loop/dlsystems.h:
....
....
#ifndef MAC_TABLE_SRAM_BASE
#define MAC_TABLE_SRAM_BASE 0x80065000
#define MAC_TABLE_SRAM_BASE_UE 0x65000
#define MAC_ENTRIES 20
#define MAC_MASK (MAC_ENTRIES -1)
#define MAC_SIZE 6
#define MAC_TABLE_SRAM_SIZE (MAC_ENTRIES * 4 * MAC_SIZE) // Each entry is 3 unsigned ints
#endif
....
....
mac_table.h:
typedef struct mac_table_t{
unsigned int ip; //ip address
unsigned int mac0; //first 32 bit of mac addresss
unsigned int mac1; //last 16 bit of mac addresss
unsigned int port; //port number or interface
unsigned int sent; //how many times you have sent an arp req.
unsigned int valid; //is this a valid entry
} mac_table_t;
packet_echo.h:
#include "mac_table.h"
mac_table_t mac_entry;
__declspec(sram) mac_table_t *mac_base;
void init_hash();
int add_arp_entry(mac_table_t *ae);
int find_arp_entry(unsigned int ip);
mac_base = (struct mac_table_t *) MAC_TABLE_SRAM_BASE_UE;
init_hash();
mac_entry.mac0 = highmac; // higest 32 bit of mac adress
mac_entry.mac1 = lowmac; // lowest 16 bit of mac adress
mac_entry.ip = i; // ip adress
mac_entry.port = pMeta->inputPort; // port number host is on
mac_entry.valid = 1; // 1 so we know that it is a valid entry
add_arp_entry(&mac_entry); // enters ip in hash table
i = find_arp_entry(ip); // finds the index in the mac_base
// table
//How to initialize the hash unit from the microde:
void init_hash() {
__declspec(sram_write_reg) int hash_multiplier[4];
SIGNAL hash_init0, hash_init1; //signals to wait for writing to be done
hash_multiplier[0] = 0x12345678; //these numbers you choose as you like
hash_multiplier[1] = 0x87654321; //Just remember to fill a whole 32 bit number
hash_multiplier[2] = 0x7531abcd;
hash_multiplier[3] = 0x44444444;
// see ixp.h for cap scr hash adresses.
// we need to write to the registers in the hash unit. these registers tells
// the hash unit how to hash teh values.
// first we do the 48 bit multiplers:
cap_csr_write(&hash_multiplier[0], csr_hash_multiplier_48_0, sig_done,&hash_init0);
cap_csr_write(&hash_multiplier[1], csr_hash_multiplier_48_1, sig_done,&hash_init1);
wait_for_all(&hash_init0, &hash_init1);
// then we do the 128 bit multiplers:
cap_csr_write(&hash_multiplier[2], csr_hash_multiplier_128_0, sig_done,&hash_init0);
cap_csr_write(&hash_multiplier[3], csr_hash_multiplier_128_1, sig_done,&hash_init1);
wait_for_all(&hash_init0, &hash_init1);
}
/* Function to insert an entry into the ARP table. */
/* Note: because our code uses a simplified ARP table in which entries */
/* do not expire, there is no need to check for duplicate entries. */
int add_arp_entry(mac_table_t *ae) {
__declspec(sram_read_reg) unsigned int d_out[8]; /* hased data */
__declspec(sram_write_reg) unsigned int d_in[8]; /* data to hash */
int i,j;
SIGNAL_PAIR sig_h; // used as signal when hash is done
d_in[0] = ae->ip; // we hash with respect to ip adress.
d_in[1] = 0;
hash_48(&d_out[0], &d_in[0],2, sig_done, &sig_h); // the hash operation
wait_for_all(&sig_h); // wait until done
j = d_out[0] & MAC_MASK; // the mask makes sure we hash to a valid index
// in the has table.
for (i=0;i < MAC_ENTRIES;i++) { //if two ip's hash to the same index, we take
// the next one, and so on
if(ae->ip == mac_base[j].ip && mac_base[j].valid) // ip is already hashed
return(1); // exit
if(mac_base[j].valid == 0) { //something there that is not valid or empty
//enter our data there
mac_base[j].ip = ae->ip;
mac_base[j].mac0 = ae->mac0;
mac_base[j].mac1 = ae->mac1;
mac_base[j].port = ae->port;
mac_base[j].sent = ae->sent;
mac_base[j].valid= ae->valid;
return(1);
}
j=(j+1)&MAC_MASK; // look at next enrty, in case we had
// two ip adresses map to the same entry.
}
// there was no room in table, return 0
return(0);
}
// takes mac adress, returns index in mac_base table
int find_arp_entry(unsigned int ip) {
int i,j;
__declspec(sram_read_reg) unsigned int d_out[8]; /* hased data */
__declspec(sram_write_reg) unsigned int d_in[8]; /* data to hash */
SIGNAL_PAIR sig_h; // used as signal when hash is done
d_in[0] = ip; // we hash with respect to ip adress.
d_in[1] = 0;
hash_48(&d_out[0], &d_in[0],2, sig_done, &sig_h); // the hash operation
wait_for_all(&sig_h); // wait until done
j = d_out[0] & MAC_MASK; // the mask makes sure we hash to a valid index
// in the hash table.
for (i=0;i< MAC_ENTRIES;i++) { //if two ip's hash to the same index, we look
//at the next one, and so on
if(ip == mac_base[j].ip && mac_base[j].valid ) // we found it and
return(j); // exit
j=(j+1)&MAC_MASK; // look at next entry, in case we had
// two ip adresses map to the same entry.
}
return -1; // not found, return a not-found-value
}
|