Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
0c3625b
Initial API and test prog
ed-xmos Dec 17, 2024
326c263
Merge branch 'develop' into feature/dual_phy_feasibility
ed-xmos Dec 22, 2024
7e3d4a2
Initial API and pins for dual MAC
ed-xmos Dec 23, 2024
5c44988
Use setup helpers in rmii_ethernet_rt_mac too
ed-xmos Dec 23, 2024
d016936
Update initial local dual mac test app
ed-xmos Dec 23, 2024
defd772
Fix null pointer issue with init_rx_ports
ed-xmos Dec 23, 2024
c2f069d
Initial dual mac basic test
ed-xmos Dec 24, 2024
a9eb986
Add support for second RMII PHY in tests
ed-xmos Dec 24, 2024
febe6ab
Add extra PHYs to test_dual_basic
ed-xmos Dec 24, 2024
811cc80
More WIP dual rmii eval
ed-xmos Jan 2, 2025
a880f7c
Allocate memory pool and queues per ethernet port
Jan 10, 2025
ddb1e59
Modified rmii_master_tx_pins to pass forwarding queues
Jan 13, 2025
661fcf4
Add support for hp packets
Jan 14, 2025
8bf59f9
Fix tx timestamp andlink status update code to work with multiple mac…
Jan 15, 2025
cd0c227
Merge develop and resolve conflicts
Jan 15, 2025
3983959
Set NUM_ETHERNET_PORTS to 1 by default.
Jan 15, 2025
d4339dd
Changes to ensure the existing single port rmii tests are not broken
Jan 17, 2025
50c2317
Merge branch 'develop' of github.com:xmos/lib_ethernet into feature/d…
Jan 17, 2025
fb50876
Fix test failures
Jan 17, 2025
d28e70d
Merge develop and resolve conflicts
Jan 21, 2025
ab9645b
Added rmii dual phy forwarding only test
Jan 21, 2025
8f4288c
Sync between sim threads by writing to ports
Jan 21, 2025
17e9a5c
Use multiprocessing.Pipe for synchronisation between threads
Jan 22, 2025
7ab897c
Add filler thread
Jan 22, 2025
980fc1b
Remove dependence on NUM_ETHERNET_PORTS define
Jan 22, 2025
c05dae7
Pass mac_ports argument to rmii_master_tx_pins()
Jan 22, 2025
b3ec298
Remove dependence on NUM_ETHERNET_PORTS define
Jan 22, 2025
c9375e6
Removed examples/test_rmii_dual
Jan 22, 2025
50230da
review comments
Jan 23, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
63 changes: 57 additions & 6 deletions lib_ethernet/api/ethernet.h
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,12 @@ typedef interface ethernet_cfg_if {
*/
void disable_link_status_notification(size_t client_num);

/** When forwarding received packets, put them in the high priority queue,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't know yet if this the right thing to do. I'm concerned that forwarded LP traffic may block HP egress traffic from the internal port. However this is all still WIP so just noting that for now.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is only for testing. I added this cfg function so I could test forwarding in HP queues. One of the test config has the application enable this but its disabled by default. In reality, there must be some other way for the mac to learn what the priority of a forwarding stream is.

* which the tx pins prioritises when reading packets over the low priority queue
*
*/
void forward_packets_as_hp(unsigned forward_as_hp_flag);

/** Exit ethernet MAC. Quits all of the associated sub tasks and frees memory.
* Allows the resources previously used by the MAC to be re-used by other tasks.
* Only supported on RMII real-time MACs. This command is ignored for
Expand Down Expand Up @@ -270,10 +276,10 @@ typedef interface ethernet_tx_if {
/** Internal API call. Do not use. */
void _init_send_packet(size_t n, size_t ifnum);
/** Internal API call. Do not use. */
void _complete_send_packet(char packet[n], unsigned n,
unsigned _complete_send_packet(char packet[n], unsigned n,
int request_timestamp, size_t ifnum);
/** Internal API call. Do not use. */
unsigned _get_outgoing_timestamp();
unsigned _get_outgoing_timestamp(size_t ifnum);
#ifdef __XC__
} ethernet_tx_if;

Expand All @@ -293,7 +299,10 @@ extends client interface ethernet_tx_if : {
inline void send_packet(CLIENT_INTERFACE(ethernet_tx_if, i), char packet[n], unsigned n,
unsigned ifnum) {
i._init_send_packet(n, ifnum);
i._complete_send_packet(packet, n, 0, ifnum);
unsigned ready;
do {
ready = i._complete_send_packet(packet, n, 1, ifnum);
}while(!ready);
}

/** Function to send an Ethernet packet on the specified interface and return a timestamp
Expand All @@ -314,8 +323,16 @@ extends client interface ethernet_tx_if : {
unsigned n,
unsigned ifnum) {
i._init_send_packet(n, ifnum);
i._complete_send_packet(packet, n, 1, ifnum);
return i._get_outgoing_timestamp();
unsigned ready;
do {
ready = i._complete_send_packet(packet, n, 1, ifnum);
}while(!ready);
unsigned timestamp = 0;
while(!timestamp)
{
timestamp = i._get_outgoing_timestamp(ifnum);
}
return timestamp;
}
/**@}*/ // END: addtogroup ethernet_tx_if
#ifdef __XC__
Expand Down Expand Up @@ -413,7 +430,17 @@ inline void ethernet_send_hp_packet(streaming_chanend_t c_tx_hp,
unsigned n,
unsigned ifnum)
{
unsigned ready = 0;

c_tx_hp <: n;
c_tx_hp <: ifnum;
c_tx_hp :> ready;
while(!ready)
{
c_tx_hp <: n;
c_tx_hp <: ifnum;
c_tx_hp :> ready;
}
sout_char_array(c_tx_hp, packet, n);
}

Expand Down Expand Up @@ -610,7 +637,7 @@ void mii_ethernet_mac(SERVER_INTERFACE(ethernet_cfg_if, i_cfg[n_cfg]), static_co



/** ENUM to determine which two bits of a four bit port are to be used as data lines
/** ENUM to determine which two bits of a four bit port are to be used as data lines
* in the case that a four bit port is specified for RMII. The other two pins of the four bit
* port cannot be used. For Rx the input values are ignored. For Tx, the unused pins are always driven low. */
typedef enum rmii_data_4b_pin_assignment_t{
Expand Down Expand Up @@ -693,6 +720,30 @@ void rmii_ethernet_rt_mac(SERVER_INTERFACE(ethernet_cfg_if, i_cfg[n_cfg]), stati
static_const_unsigned_t tx_bufsize_words,
enum ethernet_enable_shaper_t shaper_enabled);


/** 100 Mbps RT RMII dual mac component.
* It creates two MAC instances, with each MAC connected to a separate, dedicated RMII PHY interface.
*
* Note: This is still WIP and requires additional testing.
*/
void rmii_ethernet_rt_mac_dual(SERVER_INTERFACE(ethernet_cfg_if, i_cfg[n_cfg]), static_const_unsigned_t n_cfg,
SERVER_INTERFACE(ethernet_rx_if, i_rx_lp[n_rx_lp]), static_const_unsigned_t n_rx_lp,
SERVER_INTERFACE(ethernet_tx_if, i_tx_lp[n_tx_lp]), static_const_unsigned_t n_tx_lp,
nullable_streaming_chanend_t c_rx_hp,
nullable_streaming_chanend_t c_tx_hp,
in_port_t p_clk,
rmii_data_port_t * unsafe p_rxd_0, in_port_t p_rxdv_0,
out_port_t p_txen_0, rmii_data_port_t * unsafe p_txd_0,
clock rxclk_0,
clock txclk_0,
rmii_data_port_t * unsafe p_rxd_1, in_port_t p_rxdv_1,
out_port_t p_txen_1, rmii_data_port_t * unsafe p_txd_1,
clock rxclk_1,
clock txclk_1,
static_const_unsigned_t rx_bufsize_words,
static_const_unsigned_t tx_bufsize_words,
enum ethernet_enable_shaper_t enable_shaper);

#endif // __XC__ || __DOXYGEN__

#endif // __ethernet__h__
15 changes: 8 additions & 7 deletions lib_ethernet/src/client_state.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,10 @@ enum status_update_state_t {
typedef struct
{
unsigned dropped_pkt_cnt;
unsigned rd_index;
unsigned wr_index;
void *fifo[ETHERNET_RX_CLIENT_QUEUE_SIZE];
int status_update_state;
unsigned rd_index[MAX_ETHERNET_PORTS];
unsigned wr_index[MAX_ETHERNET_PORTS];
void *fifo[MAX_ETHERNET_PORTS][ETHERNET_RX_CLIENT_QUEUE_SIZE];
int status_update_state[MAX_ETHERNET_PORTS];
size_t num_etype_filters;
int strip_vlan_tags;
uint16_t etype_filters[ETHERNET_MAX_ETHERTYPE_FILTERS];
Expand All @@ -37,9 +37,10 @@ typedef struct
typedef struct
{
int requested_send_buffer_size;
mii_packet_t *send_buffer;
int has_outgoing_timestamp_info;
unsigned outgoing_timestamp;
mii_packet_t *send_buffer[MAX_ETHERNET_PORTS];
int has_outgoing_timestamp_info[MAX_ETHERNET_PORTS];
unsigned outgoing_timestamp[MAX_ETHERNET_PORTS];
int dst_port;
} tx_client_state_t;

#ifdef __XC__
Expand Down
16 changes: 11 additions & 5 deletions lib_ethernet/src/client_state.xc
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,12 @@ void init_rx_client_state(rx_client_state_t client_state[n], unsigned n)
{
for (unsigned i = 0; i < n; i ++) {
client_state[i].dropped_pkt_cnt = 0;
client_state[i].rd_index = 0;
client_state[i].wr_index = 0;
client_state[i].status_update_state = STATUS_UPDATE_WAITING;
for(int p=0; p<MAX_ETHERNET_PORTS; p++)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah this looks like sc_ethernet!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, all of these need to be arrays of the max supported ethernet ports.

{
client_state[i].rd_index[p] = 0;
client_state[i].wr_index[p] = 0;
client_state[i].status_update_state[p] = STATUS_UPDATE_WAITING;
}
client_state[i].num_etype_filters = 0;
client_state[i].strip_vlan_tags = 0;
}
Expand All @@ -18,7 +21,10 @@ void init_tx_client_state(tx_client_state_t client_state[n], unsigned n)
{
for (unsigned i = 0; i < n; i ++) {
client_state[i].requested_send_buffer_size = 0;
client_state[i].send_buffer = null;
client_state[i].has_outgoing_timestamp_info = 0;
for(int p=0; p<MAX_ETHERNET_PORTS; p++)
{
client_state[i].send_buffer[p] = null;
client_state[i].has_outgoing_timestamp_info[p] = 0;
}
}
}
6 changes: 5 additions & 1 deletion lib_ethernet/src/default_ethernet_conf.h
Original file line number Diff line number Diff line change
Expand Up @@ -75,4 +75,8 @@
#define __SIMULATOR__ 0
#endif

#endif // __default_ethernet_conf_h__
#ifndef MAX_ETHERNET_PORTS
#define MAX_ETHERNET_PORTS (2)
#endif

#endif // __default_ethernet_conf_h__
3 changes: 3 additions & 0 deletions lib_ethernet/src/macaddr_filter.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,9 @@ void ethernet_del_filter_table_entry(eth_global_filter_info_t table,
void ethernet_clear_filter_table(eth_global_filter_info_t table,
unsigned client_num, int is_hp);

int ethernet_filter_result_is_forwarding_set(unsigned value);
unsigned ethernet_filter_result_set_forwarding(unsigned value, int is_forwarding_set);

#ifdef __XC__

unsigned ethernet_do_filtering(eth_global_filter_info_t table,
Expand Down
16 changes: 14 additions & 2 deletions lib_ethernet/src/macaddr_filter.xc
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,15 @@ int ethernet_filter_result_is_hp(unsigned value)
return (value >> 31) ? 1 : 0;
}

int ethernet_filter_result_is_forwarding_set(unsigned value)
{
return ((value >> 30) & 0x1) ? 1 : 0;
}

unsigned ethernet_filter_result_interfaces(unsigned value)
{
// Throw away bit 31
return (value << 1) >> 1;
// Throw away bit 30 and 31
return (value << 2) >> 2;
}

unsigned ethernet_filter_result_set_hp(unsigned value, int is_hp)
Expand All @@ -23,6 +28,13 @@ unsigned ethernet_filter_result_set_hp(unsigned value, int is_hp)
return value | (is_hp << 31);
}

unsigned ethernet_filter_result_set_forwarding(unsigned value, int is_forwarding_set)
{
// Ensure it is a single bit in the LSB
is_forwarding_set = is_forwarding_set ? 1 : 0;
return value | (is_forwarding_set << 30);
}

void ethernet_init_filter_table(eth_global_filter_info_t table)
{
for (size_t i = 0; i < ETHERNET_MACADDR_FILTER_TABLE_SIZE; i++) {
Expand Down
6 changes: 2 additions & 4 deletions lib_ethernet/src/mii_buffering.c
Original file line number Diff line number Diff line change
Expand Up @@ -173,10 +173,6 @@ void mii_commit(mii_mempool_t mempool, unsigned *end_ptr)
{
mempool_info_t *info = (mempool_info_t *) mempool;

#if 0 && (NUM_ETHERNET_PORTS > 1) && !defined(DISABLE_ETHERNET_PORT_FORWARDING)
buf->forwarding = 0;
#endif

if (end_ptr > info->last_safe_wrptr)
end_ptr = info->start;

Expand All @@ -188,6 +184,8 @@ void mii_add_packet(mii_packet_queue_t queue, mii_packet_t *buf)
packet_queue_info_t *info = (packet_queue_info_t *)queue;
unsigned wr_index = info->wr_index;

buf->forwarding = 0;

info->ptrs[wr_index] = (unsigned *)buf;
info->wr_index = increment_and_wrap_power_of_2(wr_index, ETHERNET_NUM_PACKET_POINTERS);
}
Expand Down
3 changes: 2 additions & 1 deletion lib_ethernet/src/mii_buffering.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ typedef struct mii_packet_t {
* The end of the buffer is used to contain a pointer to the start such that when the
* end is reached it is a simple load operation from that address to get the start
* address.
*/
*/
typedef struct mempool_info_t {
unsigned *wrptr;
unsigned *start;
Expand Down Expand Up @@ -92,6 +92,7 @@ typedef unsigned * mii_rdptr_t;
typedef unsigned * mii_packet_queue_t;

void mii_init_packet_queue(mii_packet_queue_t queue);

mii_mempool_t mii_init_mempool(unsigned *buffer, int size);
void mii_init_lock();
void mii_deinit_lock();
Expand Down
9 changes: 7 additions & 2 deletions lib_ethernet/src/mii_ethernet_mac.xc
Original file line number Diff line number Diff line change
Expand Up @@ -235,7 +235,7 @@ static void mii_ethernet_aux(client mii_if i_mii,
// Do nothing
break;

case i_tx[int i]._get_outgoing_timestamp() -> unsigned timestamp:
case i_tx[int i]._get_outgoing_timestamp(unsigned dst_port) -> unsigned timestamp:
fail("Outgoing timestamps are not supported in standard MII Ethernet MAC");
break;

Expand All @@ -257,14 +257,19 @@ static void mii_ethernet_aux(client mii_if i_mii,
client_state.status_update_state = STATUS_UPDATE_IGNORING;
break;

case i_cfg[int i].forward_packets_as_hp(unsigned forward_packets_in_hp_queue):
// Do nothing - not supported on this Mac
break;

case i_cfg[int i].exit(void): {
// Do nothing - exit not supported on this MAC
break;
}

case i_tx[int i]._complete_send_packet(char data[n], unsigned n,
int request_timestamp,
unsigned dst_port):
unsigned dst_port) -> unsigned ready:
ready = 1;
memcpy(txbuf, data, n);
i_mii.send_packet(txbuf, n);
// wait for the packet to be sent
Expand Down
Loading