-
Notifications
You must be signed in to change notification settings - Fork 16
RMII dual port implementation #91
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: develop
Are you sure you want to change the base?
Conversation
* develop: (21 commits) Remove unused part of test FIx changelog changelog re-order Fix table saying RMII supported Remove slicekit MII example Test RMII in a MIPS constrained environment Added pytest option to specify the test level. Not used by most tests right now Set RANDOM_FAST_MODE to 0 so the filler threads are always running in fast mode Added wrapper functions for rmii tx and rx phy creation. Some more cleanup to address review comments Remove Ed's test app Tidy lib makefiles Update lib_ethernet.rst Update lib_ethernet.rst Changelog Fix IFG calculation. Document the reasoning behind the RMII_ETHERNET_IFG_AS_REF_CLOCK_COUNT_4b, RMII_ETHERNET_IFG_AS_REF_CLOCK_COUNT_1b_NO_TAIL_BYTES and RMII_ETHERNET_IFG_AS_REF_CLOCK_COUNT_1b_TAIL_BYTES defines in the code. Fix copyright notice Modify test_4_1_2.py to not test fragments less than 16 bytes in length for RMII Initial RMII docs Another round of cleanup on the tests Extend more tests to test rmii configs ...
…ual_phy_feasibility
2fd0361 to
552aebd
Compare
552aebd to
fb50876
Compare
32439d3 to
def3fa9
Compare
def3fa9 to
ab9645b
Compare
36e1ad1 to
bb0989b
Compare
bb0989b to
c9375e6
Compare
| */ | ||
| void disable_link_status_notification(size_t client_num); | ||
|
|
||
| /** When forwarding received packets, put them in the high priority queue, |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
| 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++) |
There was a problem hiding this comment.
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!
There was a problem hiding this comment.
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.
lib_ethernet/src/mii_buffering.c
Outdated
| memset(info->ptrs, 0, sizeof(info->ptrs)); | ||
| } | ||
|
|
||
| void mii_init_packet_queue_new(packet_queue_info_t *queue) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this something you intended to leave here? Looks the same as mii_init_packet_queue() and not sure what new means!?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just realised the type of queue is different - maybe improve the name to something other than _new.. I guess this is a backwards compatibility thing?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, I meant to remove that. I was just testing if it would be possible to directly pass packet_queue_info_t* ptr to the function rather than mii_packet_queue_t and then typecasting to packet_queue_info_t* inside the function.
I don't understand the purpose of the mii_packet_queue_t type. Maybe eventually we can change the buffering APIs to pass packet_queue_info_t* directly? For now, I'll just delete this function.
| select { | ||
| #pragma xta endpoint "rx_packet" | ||
| case c_conf :> int: | ||
| case c_conf :> int i: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Neat - we now use the notification token
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes, I extended the cfg commands that can be send to the filter to add one that says all packets need to be forwarded as high priority. This was just so I could test that forwarding packets as high priority works. I think in reality there'd be some other way to communicating to the mac that a given stream needs to be forwarded as high priority
| } | ||
|
|
||
| buf->src_port = 0; | ||
| buf->src_port = current_port; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ha - you can see the original code had multi-port in mind
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes!
| if (ethernet_filter_result_is_hp(filter_result)) { | ||
| if (!mii_packet_queue_full(rx_packets_hp)) { | ||
| mii_add_packet(rx_packets_hp, buf); | ||
| if(!buf->filter_result) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think at some point we will want to allow an external filter (via an API) to make this decision. But fine for now. Comments are helpful.
| client_wants_packet &= passed_etype_filter; | ||
| } | ||
|
|
||
| if (client_wants_packet) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah of course - RGMII needed to updated so it handles an array of 1
| phy_100mb_t phy_type); | ||
| chanend c_rx_pins_exit[], | ||
| phy_100mb_t phy_type, | ||
| static const unsigned num_mac_ports); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just wondering whether we can find a better term than num_mac_ports. Looks like we used master_ports before. num_phy_ports? Not sure...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure what the master in master_ports stands for. I could use num_ethernet_ports or num_phy_ports. Maybe num_ethernet_ports?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok, as discussed, leaving it as is for now.
tests/test_link_status/src/main.xc
Outdated
|
|
||
| size_t index = rx.get_index(); | ||
|
|
||
| index = 0; // This is the mac port index and not the client index |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Helpful comment but better to change the var name to make this clear?
| @@ -0,0 +1,6 @@ | |||
| { | |||
| "PROFILES": [ | |||
| {"phy":"rmii", "mac":"rt", "arch":["xs3"], "rx_width":"4b_lower", "tx_width":"4b_lower"}, | |||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could be an annoying amount of work but do we need "Mac":"rt_hp_dual"?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes, I guess that's the goal. Have the existing tests have the option to run with rt_hp_dual mac. I'll leave it for a later PR. For the dual mac would we still want to test all combinations of rx and tx widths for both the Macs?
| } | ||
|
|
||
| mii_free_current(packets_lp); | ||
| mii_free_current(pkt_queue); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this right? Are LP and HP all in the same queue?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, the code above that assigns pkt_queue to either packets_hp, forwarding_packets_hp, packets_lp or forwarding_packets_lp in that order
| def create_expect(packets, filename): | ||
| """ Create the expect file for what packets should be reported by the DUT | ||
| """ | ||
| ndim = np.array(packets).ndim |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
SOrry a naming thing again. ndim = number of packet streams?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ndim is number of ethernet ports. [num ethernet ports][packets seen on a givent port]. I'll change the name.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
actually ndim does make sense coz its literally finding the array dimension. I'll add comments explaining what ndim=1 vs ndim=2 mean
|
|
||
| // Store the index into the packet queue | ||
| client_state.fifo[wr_index] = (void *)rd_index; | ||
| client_state.fifo[current_port][wr_index] = (void *)rd_index; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
#pragma unsafe arrays may be worth considering with so much array bounds checking now (once we are confident it all works, which the tests should prove.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The array bound checking has helpfully pointed out issues when I added support for multiple queues so will keep it on till we're done implementing all the features. I agree it makes sense turning off once we're confident about the code.
| int client_wants_packet = 0; | ||
| if (buf->filter_result && ethernet_filter_result_is_hp(buf->filter_result)) { | ||
| client_wants_packet = (buf->filter_result & 1); | ||
| client_wants_packet = (buf->filter_result & 1); // there's only one hp client?? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes - I think this is a statement rather than a question- we only support 1 HP client.
| mii_commit(tx_mem_hp[dst_port], dptr); | ||
| mii_add_packet((mii_packet_queue_t)&tx_packets_hp[dst_port], buf); | ||
| tx_client_state_hp[0].send_buffer[dst_port] = null; | ||
| prioritize_rx = 3; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
WHat is the significance of 3 here? I see it is carried over from the previous codebase.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wonder if a enum is more appropriate?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
prioritize_rx I think lets the ethernet_server prioritise rx over tx. Its used as a counter, so something like do a tx once every 3 iterations of the while loop.
| // Establish types of data ports presented | ||
| unsafe{ | ||
| // Setup buffering | ||
| unsigned int rx_data[rx_bufsize_words ][2]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this needs documenting carefully - or perhaps each port gets half of the total?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes, each port gets half. It should be rx_data[2][rx_bufsize_words] ideally but xc wouldn't allow rx_bufsize_words in the inner dimension so left it like this. mem pool init only uses the start ptr and size so should be okay.
mii_init_mempool(&rx_data[0][0] + irx_bufsize_words, rx_bufsize_words4);
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is great - a huge amount of work and most of the machinery is now in place. Great that you added a reasonable amount of test coverage too and that the existing regressions are passing. I think we need to consider the forwarding path a little more - perhaps another look at sc_ethernet? But for now this is most of the leg work done.
It would be really great if you could produce a digram (or modify this https://xmosjira.atlassian.net/wiki/spaces/Ethernet/pages/4468867073/RMII+dual+port+feasibility#Proposed-lib_ethernet-dual-port-RMII-Architecture) to show how it really works under the hood. Especially the separate queues. Some basic notes on how it works on a confluence page would be good too, especially as we don't know when/who will be doing the next step of DP and the fact this feasibility has gone to stage where are amount of implementation is done. There a couple of items which would be good to clarify (see individual comments) first before approval if that's OK. Happy to discuss in person tomorrow if easier than comments on here.
I'm added some implementation details as part of the spec (https://xmosjira.atlassian.net/wiki/spaces/Ethernet/pages/4435902469/Ethernet+Milestone+A#%F0%9F%94%A7-Implementation-Detail) but you're right, we need more description of the queue handling which is quite complicated. I'll add this in a separate confluence page. |
https://xmosjira.atlassian.net/browse/ETH-27
Adds support for the RMII dual MAC with some basic testing.