mirror of
https://github.com/logicog/RTLPlayground.git
synced 2026-08-30 14:52:51 +08:00
Add backend support for L2 entries in web
This commit is contained in:
@@ -16,6 +16,8 @@
|
||||
// #define DEBUG
|
||||
#include "debug.h"
|
||||
|
||||
#define L2_MAX_TRANSFER 2
|
||||
|
||||
#pragma codeseg BANK1
|
||||
#pragma constseg BANK1
|
||||
|
||||
@@ -283,6 +285,100 @@ void send_counters(char port)
|
||||
}
|
||||
|
||||
|
||||
void send_l2(uint16_t idx)
|
||||
{
|
||||
slen = strtox(outbuf, HTTP_RESPONCE_JSON);
|
||||
dbg_string("sending L2\n"); // TODO: Remove
|
||||
print_short(idx);
|
||||
__xdata uint8_t entries_left = L2_MAX_TRANSFER;
|
||||
|
||||
do {
|
||||
reg_read_m(RTL837X_TBL_CTRL);
|
||||
} while (sfr_data[3] & 0x01);
|
||||
|
||||
/* The L2 table in the ASIC can hold up to 4096 (0x1000) entries, which
|
||||
* are accessed using an index. The index is the hash of the MAC address
|
||||
* and forwarding ID (basically VID). The hash-table is 4-way associative,
|
||||
* i.e. for a given hash value, 4 entries with that same hash can be stored
|
||||
* (i.e. the hash points to a bucket with up to 4 entries).
|
||||
* When the table or a hash bucket is full, further entries will lead to
|
||||
* L2 flooding.
|
||||
* To find all entries, we start with entry-index 0 and iteratively search for
|
||||
* the next entry (with the next higher index), until we arrive again at the first
|
||||
* entry. The indices are sorted, so if an entry has a smaller index than
|
||||
* the previous one, we know that we have wrapped around the entire table.
|
||||
*/
|
||||
__xdata uint16_t entry = idx;
|
||||
__xdata uint16_t first_entry = 0xffff; // An illegal entry index
|
||||
char_to_html('[');
|
||||
while (1) {
|
||||
entries_left--;
|
||||
uint8_t port = 0;
|
||||
reg_read_m(RTL837x_TBL_DATA_0);
|
||||
REG_WRITE(RTL837x_TBL_DATA_0, sfr_data[0], sfr_data[1],sfr_data[2] | 0xc0, sfr_data[3]);
|
||||
|
||||
REG_WRITE(RTL837X_TBL_CTRL, entry >> 8, entry, TBL_L2_UNICAST, 0x1);
|
||||
do {
|
||||
reg_read_m(RTL837X_TBL_CTRL);
|
||||
} while (sfr_data[3] & 0x1);
|
||||
|
||||
reg_read_m(RTL837x_L2_DATA_OUT_B);
|
||||
if ((sfr_data[0] & 0x20)) { // Check entry is valid
|
||||
// MAC
|
||||
slen += strtox(outbuf + slen, "{\"mac\":\"");
|
||||
byte_to_html(sfr_data[2]); char_to_html(':');
|
||||
byte_to_html(sfr_data[3]); char_to_html(':');
|
||||
port = (sfr_data[0] >> 6) & 0x3;
|
||||
reg_read_m(RTL837x_L2_DATA_OUT_A);
|
||||
byte_to_html(sfr_data[0]); char_to_html(':');
|
||||
byte_to_html(sfr_data[1]); char_to_html(':');
|
||||
byte_to_html(sfr_data[2]); char_to_html(':');
|
||||
byte_to_html(sfr_data[3]);
|
||||
|
||||
// VLAN
|
||||
slen += strtox(outbuf + slen, "\", \"vlan\":\"");
|
||||
reg_read_m(RTL837x_L2_DATA_OUT_B);
|
||||
charhex_to_html(sfr_data[0] & 0x0f);
|
||||
byte_to_html(sfr_data[1]);
|
||||
|
||||
// type
|
||||
reg_read_m(RTL837x_L2_DATA_OUT_C);
|
||||
if (sfr_data[2] & 0x1)
|
||||
slen += strtox(outbuf + slen, "\",\"type\":\"s\", \"port\":");
|
||||
else
|
||||
slen += strtox(outbuf + slen, "\",\"type\":\"l\", \"port\":");
|
||||
|
||||
port |= (sfr_data[3] & 0x3) << 2;
|
||||
itoa_html(port);
|
||||
|
||||
// Index
|
||||
reg_read_m(RTL837x_TBL_DATA_0);
|
||||
entry = (((uint16_t)sfr_data[2] & 0x0f) << 8) | sfr_data[3];
|
||||
slen += strtox(outbuf + slen, ",\"idx\":\"");
|
||||
byte_to_html(entry >> 8);
|
||||
byte_to_html(entry);
|
||||
char_to_html('"');
|
||||
char_to_html('}');
|
||||
entry += 1; // We want the next entry following after the current entry
|
||||
} else {
|
||||
reg_read_m(RTL837x_TBL_DATA_0);
|
||||
entry = (((uint16_t)sfr_data[2] & 0x0f) << 8) | sfr_data[3] + 1;
|
||||
}
|
||||
if (first_entry == 0xffff) {
|
||||
char_to_html(',');
|
||||
first_entry = entry;
|
||||
} else {
|
||||
if (first_entry == entry || !entries_left) {
|
||||
char_to_html(']');
|
||||
break;
|
||||
} else {
|
||||
char_to_html(',');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void send_mirror(void)
|
||||
{
|
||||
dbg_string("send_mirror called\n");
|
||||
|
||||
Reference in New Issue
Block a user