RX Pause Termination - 2.7 English

1G/10G/25G Switching Ethernet Subsystem Product Guide (PG292)

Document ID
PG292
Release Date
2022-05-11
Version
2.7 English

The 1G/10G/25G Ethernet Subsystem terminates global and priority pause frames and provides a simple hand-shaking interface to allow user logic to respond to pause packets.

Determining Pause Packets

There are three steps in determining pause packets:

  1. Checks are performed to see if a packet is a global or a priority control packet.

    Packets that pass step one are forwarded to you only if ctl_rx_forward_control is set to 1.

  2. If step 1 passes, the packet is checked to determine if it is a global pause packet.
  3. If step 2 fails, the packet is checked to determine if it is a priority pause packet.

For step 1, the following pseudo code shows the checking function:

assign da_match_gcp = (!ctl_rx_check_mcast_gcp && !ctl_rx_check_ucast_gcp) || ((DA 
== ctl_rx_pause_da_ucast) && ctl_rx_check_ucast_gcp) || ((DA == 48'h0180c2000001) && 
ctl_rx_check_mcast_gcp);
assign sa_match_gcp = !ctl_rx_check_sa_gcp || (SA == ctl_rx_pause_sa);
assign etype_match_gcp = !ctl_rx_check_etype_gcp || (ETYPE == ctl_rx_etype_gcp);
assign opcode_match_gcp = !ctl_rx_check_opcode_gcp || ((OPCODE >= 
ctl_rx_opcode_min_gcp) && (OPCODE <= ctl_rx_opcode_max_gcp));
assign global_control_packet = da_match_gcp && sa_match_gcp && etype_match_gcp && 
opcode_match_gcp && ctl_rx_enable_gcp;
assign da_match_pcp = (!ctl_rx_check_mcast_pcp && !ctl_rx_check_ucast_pcp) || ((DA 
== ctl_rx_pause_da_ucast) && ctl_rx_check_ucast_pcp) || ((DA == 
ctl_rx_pause_da_mcast) && ctl_rx_check_mcast_pcp);
assign sa_match_pcp = !ctl_rx_check_sa_pcp || (SA == ctl_rx_pause_sa);
assign etype_match_pcp = !ctl_rx_check_etype_pcp || (ETYPE == ctl_rx_etype_pcp);
assign opcode_match_pcp = !ctl_rx_check_opcode_pcp || ((OPCODE >= 
ctl_rx_opcode_min_pcp) && (OPCODE <= ctl_rx_opcode_max_pcp));
assign priority_control_packet = da_match_pcp && sa_match_pcp && etype_match_pcp && 
opcode_match_pcp && ctl_rx_enable_pcp;
assign control_packet = global_control_packet || priority_control_packet;

where DA is the destination address, SA is the source address, OPCODE is the opcode and ETYPE is the ethertype/length field that is extracted from the incoming packet.

For step 2, the following pseudo code shows the checking function:

assign da_match_gpp = (!ctl_rx_check_mcast_gpp && !ctl_rx_check_ucast_gpp) || ((DA 
== ctl_rx_pause_da_ucast) && ctl_rx_check_ucast_gpp) || ((DA == 48'h0180c2000001) && 
ctl_rx_check_mcast_gpp);
assign sa_match_gpp = !ctl_rx_check_sa_gpp || (SA == ctl_rx_pause_sa);
assign etype_match_gpp = !ctl_rx_check_etype_gpp || (ETYPE == ctl_rx_etype_gpp);
assign opcode_match_gpp = !ctl_rx_check_opcode_gpp || (OPCODE == ctl_rx_opcode_gpp);
assign global_pause_packet = da_match_gpp && sa_match_gpp && etype_match_gpp && 
opcode_match_gpp && ctl_rx_enable_gpp;

where DA is the destination address, SA is the source address, OPCODE is the opcode and ETYPE is the ethertype/length field that are extracted from the incoming packet.

For step 3, the following pseudo code shows the checking function:

assign da_match_ppp = (!ctl_rx_check_mcast_ppp && !ctl_rx_check_ucast_ppp) || ((DA 
== ctl_rx_pause_da_ucast) && ctl_rx_check_ucast_ppp) || ((DA == 
ctl_rx_pause_da_mcast) && ctl_rx_check_mcast_ppp);
assign sa_match_ppp = !ctl_rx_check_sa_ppp || (SA == ctl_rx_pause_sa);
assign etype_match_ppp = !ctl_rx_check_etype_ppp || (ETYPE == ctl_rx_etype_ppp);
assign opcode_match_ppp = !ctl_rx_check_opcode_ppp || (OPCODE == ctl_rx_opcode_ppp);
assign priority_pause_packet = da_match_ppp && sa_match_ppp && etype_match_ppp && 
opcode_match_ppp && ctl_rx_enable_ppp;

where DA is the destination address, SA is the source address, OPCODE is the opcode and ETYPE is the ethertype/length field that are extracted from the incoming packet.

User Interface

A simple handshaking protocol is used to alert you of the reception of pause packets using the ctl_rx_pause_enable[8:0], stat_rx_pause_req[8:0] and ctl_rx_pause_ack[8:0] buses. For these buses, bit [8] corresponds to global pause packets and bits [7:0] correspond to priority pause packets.

The following steps occur when a pause packet is received:

  1. If the corresponding bit of ctl_rx_pause_enable[8:0] is 0, the quanta is ignored and the core stays in step 1. Otherwise, the corresponding bit of the stat_rx_pause_req[8:0] bus is set to 1, and the received quanta is loaded into a timer.

    If one of the bits of ctl_rx_pause_enable[8:0] is set to 0 (disabled) when the pause processing is in step 2 or later, the core completes the steps as normal until it comes back to step 1.

  2. If ctl_rx_check_ack input is 1, the core waits for you to set the appropriate bit of the ctl_rx_pause_ack[8:0] bus to 1.
  3. After you set the proper bit of ctl_rx_pause_ack[8:0] to 1, or if ctl_rx_check_ack is 0, the core starts counting down the timer.
  4. When the timer times out, the core sets the appropriate bit of stat_rx_pause_req[8:0] back to 0.
  5. If ctl_rx_check_ack input is 1, the operation is complete when you set the appropriate bit of ctl_rx_pause_ack[8:0] back to 0.

    If you do not set the appropriate bit of ctl_rx_pause_ack[8:0] back to 0, the core deems the operation complete after 32 clock cycles.

These steps are demonstrated in the following figure with each step shown on the waveform.

Figure 1. RX Pause Interface Example

If at any time during step 2 to step 5 a new pause packet is received, the timer is loaded with the newly acquired quanta value and the process continues.

Note: Transmitter MAC should not transmit frames/packets when it receives Pause frames from the receiver until the time duration specified in the Pause timer.