diff --git a/docs/source/rb/if_ctrl.rst b/docs/source/rb/if_ctrl.rst index bad2486e4..355245d8d 100644 --- a/docs/source/rb/if_ctrl.rst +++ b/docs/source/rb/if_ctrl.rst @@ -62,6 +62,8 @@ See :ref:`rb_overview` for definitions of the standard register block header fie 8 TX checksum offloading 9 RX checksum offloading 10 RX flow hash offloading + 11 LFC (IEEE 802.3 annex 31B) + 12 PFC (IEEE 802.3 annex 31D) === ======================= .. object:: Port count diff --git a/docs/source/rb/port_ctrl.rst b/docs/source/rb/port_ctrl.rst index fb83a3f84..640cf14ed 100644 --- a/docs/source/rb/port_ctrl.rst +++ b/docs/source/rb/port_ctrl.rst @@ -19,10 +19,30 @@ The port control register block has a header with type 0x0000C003, version 0x000 -------- ------------- ------------------------------ ------------- RBB+0x0C Features Port feature bits RO - -------- ------------- ------------------------------ ------------- - RBB+0x10 TX status TX status RO - + RBB+0x10 TX control TX control/status RW 0x00000000 -------- ------------- ------------------------------ ------------- - RBB+0x14 RX status RX status RO - - ======== ============= ============================== ============= + RBB+0x14 RX control RX control/status RW 0x00000000 + -------- ------------- ------------------------------ ------------- + RBB+0x18 FC ctrl RX quanta step TX quanta step RW - + -------- ------------- -------------- -------------- ------------- + RBB+0x1C LFC ctrl ctrl LFC watermark RW 0x00000000 + -------- ------------- ------ ---------------------- ------------- + RBB+0x20 PFC ctrl 0 ctrl PFC watermark 0 RW 0x00000000 + -------- ------------- ------ ---------------------- ------------- + RBB+0x24 PFC ctrl 1 ctrl PFC watermark 1 RW 0x00000000 + -------- ------------- ------ ---------------------- ------------- + RBB+0x28 PFC ctrl 2 ctrl PFC watermark 2 RW 0x00000000 + -------- ------------- ------ ---------------------- ------------- + RBB+0x2C PFC ctrl 3 ctrl PFC watermark 3 RW 0x00000000 + -------- ------------- ------ ---------------------- ------------- + RBB+0x30 PFC ctrl 4 ctrl PFC watermark 4 RW 0x00000000 + -------- ------------- ------ ---------------------- ------------- + RBB+0x34 PFC ctrl 5 ctrl PFC watermark 5 RW 0x00000000 + -------- ------------- ------ ---------------------- ------------- + RBB+0x38 PFC ctrl 6 ctrl PFC watermark 6 RW 0x00000000 + -------- ------------- ------ ---------------------- ------------- + RBB+0x3C PFC ctrl 7 ctrl PFC watermark 7 RW 0x00000000 + ======== ============= ====== ====================== ============= See :ref:`rb_overview` for definitions of the standard register block header fields. @@ -45,19 +65,48 @@ See :ref:`rb_overview` for definitions of the standard register block header fie === ======================= Bit Feature === ======================= - \- None implemented + 0 LFC (IEEE 802.3 annex 31B) + 1 PFC (IEEE 802.3 annex 31D) + 2 Internal MAC control === ======================= -.. object:: TX status +.. object:: TX control/status - The TX status field contains some high-level status information about the transmit size of the link associated with the port. + The TX control/status field contains some high-level control and status registers for the transmit side of the link associated with the port. .. table:: ======== ====== ====== ====== ====== ============= Address 31..24 23..16 15..8 7..0 Reset value ======== ====== ====== ====== ====== ============= - RBB+0x10 TX status RO - + RBB+0x10 TX control/status RW 0x00000000 + ======== ============================== ============= + + Control bits: + + .. table:: + + === ======================= + Bit Function + === ======================= + 0 TX enable + 8 TX pause control (halt TX traffic) + 16 TX status (link is ready) + 17 TX reset status (MAC TX is in reset) + 24 TX pause req status + 25 TX pause ack status + === ======================= + +.. object:: RX control/status + + The RX control/status field contains some high-level control and status registers for the receive side of the link associated with the port. + + .. table:: + + ======== ====== ====== ====== ====== ============= + Address 31..24 23..16 15..8 7..0 Reset value + ======== ====== ====== ====== ====== ============= + RBB+0x14 RX control/status RO - ======== ============================== ============= Status bits: @@ -67,29 +116,72 @@ See :ref:`rb_overview` for definitions of the standard register block header fie === ======================= Bit Function === ======================= - 0 TX status (link is ready) - 1 TX reset status (MAC TX is in reset) + 0 RX enable + 8 RX pause control (halt RX traffic) + 16 RX status (link is ready) + 17 RX reset status (MAC RX is in reset) + 24 RX pause req status + 25 RX pause ack status === ======================= -.. object:: RX status +.. object:: FC control - The RX status field contains some high-level status information about the receive side of the link associated with the port. + The FC control field contains the quanta step size per clock cycle in units of 1/256 of one quanta for the internal MAC control layer. Default value is based on the MAC interface width. .. table:: ======== ====== ====== ====== ====== ============= Address 31..24 23..16 15..8 7..0 Reset value ======== ====== ====== ====== ====== ============= - RBB+0x14 RX status RO - - ======== ============================== ============= + RBB+0x18 RX quanta step TX quanta step RW - + ======== ============== ============== ============= - Status bits: +.. object:: LFC control + + The LFC control field contains control and status registers for link-level flow control (LFC) (IEEE 802.3 annex 31B pause frames). + + .. table:: + + ======== ====== ====== ====== ====== ============= + Address 31..24 23..16 15..8 7..0 Reset value + ======== ====== ====== ====== ====== ============= + RBB+0x1C ctrl LFC watermark RW 0x00000000 + ======== ====== ====================== ============= + + control bits: .. table:: === ======================= Bit Function === ======================= - 0 RX status (link is ready) - 1 RX reset status (MAC RX is in reset) + 24 TX LFC en + 25 RX LFC en + 28 TX LFC req + 29 RX LFC req + === ======================= + +.. object:: PFC control N + + The PFC control field contains control and status registers for priority flow control (PFC) (IEEE 802.3 annex 31D PFC). + + .. table:: + + ======== ====== ====== ====== ====== ============= + Address 31..24 23..16 15..8 7..0 Reset value + ======== ====== ====== ====== ====== ============= + RBB+0x20 ctrl PFC watermark RW 0x00000000 + ======== ====== ====================== ============= + + control bits: + + .. table:: + + === ======================= + Bit Function + === ======================= + 24 TX PFC en + 25 RX PFC en + 28 TX PFC req + 29 RX PFC req === ======================= diff --git a/fpga/app/dma_bench/tb/mqnic_core_pcie_us/Makefile b/fpga/app/dma_bench/tb/mqnic_core_pcie_us/Makefile index 8f2c326a5..dd0d2282c 100644 --- a/fpga/app/dma_bench/tb/mqnic_core_pcie_us/Makefile +++ b/fpga/app/dma_bench/tb/mqnic_core_pcie_us/Makefile @@ -56,6 +56,10 @@ VERILOG_SOURCES += ../../rtl/common/tx_scheduler_rr.v VERILOG_SOURCES += ../../rtl/mqnic_app_block_dma_bench.v VERILOG_SOURCES += ../../rtl/dma_bench.v VERILOG_SOURCES += ../../rtl/dram_test_ch.v +VERILOG_SOURCES += ../../lib/eth/rtl/mac_ctrl_rx.v +VERILOG_SOURCES += ../../lib/eth/rtl/mac_ctrl_tx.v +VERILOG_SOURCES += ../../lib/eth/rtl/mac_pause_ctrl_rx.v +VERILOG_SOURCES += ../../lib/eth/rtl/mac_pause_ctrl_tx.v VERILOG_SOURCES += ../../lib/eth/rtl/ptp_clock.v VERILOG_SOURCES += ../../lib/eth/rtl/ptp_clock_cdc.v VERILOG_SOURCES += ../../lib/eth/rtl/ptp_perout.v @@ -167,6 +171,9 @@ export PARAM_TX_TAG_WIDTH := 16 export PARAM_TX_CHECKSUM_ENABLE := 1 export PARAM_RX_HASH_ENABLE := 1 export PARAM_RX_CHECKSUM_ENABLE := 1 +export PARAM_LFC_ENABLE := 1 +export PARAM_PFC_ENABLE := $(PARAM_LFC_ENABLE) +export PARAM_MAC_CTRL_ENABLE := 1 export PARAM_TX_FIFO_DEPTH := 32768 export PARAM_RX_FIFO_DEPTH := 131072 export PARAM_MAX_TX_SIZE := 9214 diff --git a/fpga/app/dma_bench/tb/mqnic_core_pcie_us/test_mqnic_core_pcie_us.py b/fpga/app/dma_bench/tb/mqnic_core_pcie_us/test_mqnic_core_pcie_us.py index dd1247773..8365e1d84 100644 --- a/fpga/app/dma_bench/tb/mqnic_core_pcie_us/test_mqnic_core_pcie_us.py +++ b/fpga/app/dma_bench/tb/mqnic_core_pcie_us/test_mqnic_core_pcie_us.py @@ -3,6 +3,7 @@ import logging import os +import struct import sys import scapy.utils @@ -321,7 +322,11 @@ class TB(object): self.port_mac.append(mac) dut.eth_tx_status.setimmediatevalue(2**len(core_inst.m_axis_tx_tvalid)-1) + dut.eth_tx_fc_quanta_clk_en.setimmediatevalue(2**len(core_inst.m_axis_tx_tvalid)-1) dut.eth_rx_status.setimmediatevalue(2**len(core_inst.m_axis_tx_tvalid)-1) + dut.eth_rx_lfc_req.setimmediatevalue(0) + dut.eth_rx_pfc_req.setimmediatevalue(0) + dut.eth_rx_fc_quanta_clk_en.setimmediatevalue(2**len(core_inst.m_axis_tx_tvalid)-1) # DDR self.ddr_group_size = core_inst.DDR_GROUP_SIZE.value @@ -645,13 +650,16 @@ async def run_test_nic(dut): for block in tb.driver.interfaces[0].sched_blocks: await block.schedulers[0].rb.write_dword(mqnic.MQNIC_RB_SCHED_RR_REG_CTRL, 0x00000001) - await tb.driver.interfaces[0].set_rx_queue_map_indir_table(block.index, 0, block.index) + await block.interface.set_rx_queue_map_indir_table(block.index, 0, block.index) for k in range(len(block.interface.txq)): - if k % len(tb.driver.interfaces[0].sched_blocks) == block.index: + if k % len(block.interface.sched_blocks) == block.index: await block.schedulers[0].hw_regs.write_dword(4*k, 0x00000003) else: await block.schedulers[0].hw_regs.write_dword(4*k, 0x00000000) + await block.interface.ports[block.index].set_tx_ctrl(mqnic.MQNIC_PORT_TX_CTRL_EN) + await block.interface.ports[block.index].set_rx_ctrl(mqnic.MQNIC_PORT_RX_CTRL_EN) + count = 64 pkts = [bytearray([(x+k) % 256 for x in range(1514)]) for k in range(count)] @@ -681,6 +689,35 @@ async def run_test_nic(dut): await block.schedulers[0].rb.write_dword(mqnic.MQNIC_RB_SCHED_RR_REG_CTRL, 0x00000000) await tb.driver.interfaces[0].set_rx_queue_map_indir_table(block.index, 0, 0) + if tb.driver.interfaces[0].if_feature_lfc: + tb.log.info("Test LFC pause frame RX") + + await tb.driver.interfaces[0].ports[0].set_lfc_ctrl(mqnic.MQNIC_PORT_LFC_CTRL_TX_LFC_EN | mqnic.MQNIC_PORT_LFC_CTRL_RX_LFC_EN) + await tb.driver.hw_regs.read_dword(0) + + lfc_xoff = Ether(src='DA:D1:D2:D3:D4:D5', dst='01:80:C2:00:00:01', type=0x8808) / struct.pack('!HH', 0x0001, 2000) + + await tb.port_mac[0].rx.send(bytes(lfc_xoff)) + + count = 16 + + pkts = [bytearray([(x+k) % 256 for x in range(1514)]) for k in range(count)] + + tb.loopback_enable = True + + for p in pkts: + await tb.driver.interfaces[0].start_xmit(p, 0) + + for k in range(count): + pkt = await tb.driver.interfaces[0].recv() + + tb.log.info("Packet: %s", pkt) + assert pkt.data == pkts[k] + if tb.driver.interfaces[0].if_feature_rx_csum: + assert pkt.rx_checksum == ~scapy.utils.checksum(bytes(pkt.data[14:])) & 0xffff + + tb.loopback_enable = False + app_reg_blocks = mqnic.RegBlockList() await app_reg_blocks.enumerate_reg_blocks(tb.driver.app_hw_regs) @@ -974,6 +1011,10 @@ def test_mqnic_core_pcie_us(request, if_count, ports_per_if, axis_pcie_data_widt os.path.join(rtl_dir, "mqnic_app_block_dma_bench.v"), os.path.join(rtl_dir, "dma_bench.v"), os.path.join(rtl_dir, "dram_test_ch.v"), + os.path.join(eth_rtl_dir, "mac_ctrl_rx.v"), + os.path.join(eth_rtl_dir, "mac_ctrl_tx.v"), + os.path.join(eth_rtl_dir, "mac_pause_ctrl_rx.v"), + os.path.join(eth_rtl_dir, "mac_pause_ctrl_tx.v"), os.path.join(eth_rtl_dir, "ptp_clock.v"), os.path.join(eth_rtl_dir, "ptp_clock_cdc.v"), os.path.join(eth_rtl_dir, "ptp_perout.v"), @@ -1085,6 +1126,9 @@ def test_mqnic_core_pcie_us(request, if_count, ports_per_if, axis_pcie_data_widt parameters['TX_CHECKSUM_ENABLE'] = 1 parameters['RX_HASH_ENABLE'] = 1 parameters['RX_CHECKSUM_ENABLE'] = 1 + parameters['LFC_ENABLE'] = 1 + parameters['PFC_ENABLE'] = parameters['LFC_ENABLE'] + parameters['MAC_CTRL_ENABLE'] = 1 parameters['TX_FIFO_DEPTH'] = 32768 parameters['RX_FIFO_DEPTH'] = 131072 parameters['MAX_TX_SIZE'] = 9214 diff --git a/fpga/app/template/tb/mqnic_core_pcie_us/Makefile b/fpga/app/template/tb/mqnic_core_pcie_us/Makefile index dd68ad86c..ae30eb0ba 100644 --- a/fpga/app/template/tb/mqnic_core_pcie_us/Makefile +++ b/fpga/app/template/tb/mqnic_core_pcie_us/Makefile @@ -54,6 +54,10 @@ VERILOG_SOURCES += ../../rtl/common/stats_dma_latency.v VERILOG_SOURCES += ../../rtl/common/mqnic_tx_scheduler_block_rr.v VERILOG_SOURCES += ../../rtl/common/tx_scheduler_rr.v VERILOG_SOURCES += ../../rtl/mqnic_app_block.v +VERILOG_SOURCES += ../../lib/eth/rtl/mac_ctrl_rx.v +VERILOG_SOURCES += ../../lib/eth/rtl/mac_ctrl_tx.v +VERILOG_SOURCES += ../../lib/eth/rtl/mac_pause_ctrl_rx.v +VERILOG_SOURCES += ../../lib/eth/rtl/mac_pause_ctrl_tx.v VERILOG_SOURCES += ../../lib/eth/rtl/ptp_clock.v VERILOG_SOURCES += ../../lib/eth/rtl/ptp_clock_cdc.v VERILOG_SOURCES += ../../lib/eth/rtl/ptp_perout.v @@ -161,6 +165,9 @@ export PARAM_TX_TAG_WIDTH := 16 export PARAM_TX_CHECKSUM_ENABLE := 1 export PARAM_RX_HASH_ENABLE := 1 export PARAM_RX_CHECKSUM_ENABLE := 1 +export PARAM_LFC_ENABLE := 1 +export PARAM_PFC_ENABLE := $(PARAM_LFC_ENABLE) +export PARAM_MAC_CTRL_ENABLE := 1 export PARAM_TX_FIFO_DEPTH := 32768 export PARAM_RX_FIFO_DEPTH := 131072 export PARAM_MAX_TX_SIZE := 9214 diff --git a/fpga/app/template/tb/mqnic_core_pcie_us/test_mqnic_core_pcie_us.py b/fpga/app/template/tb/mqnic_core_pcie_us/test_mqnic_core_pcie_us.py index 5889c838e..c2ecc0c21 100644 --- a/fpga/app/template/tb/mqnic_core_pcie_us/test_mqnic_core_pcie_us.py +++ b/fpga/app/template/tb/mqnic_core_pcie_us/test_mqnic_core_pcie_us.py @@ -3,6 +3,7 @@ import logging import os +import struct import sys import scapy.utils @@ -321,7 +322,11 @@ class TB(object): self.port_mac.append(mac) dut.eth_tx_status.setimmediatevalue(2**len(core_inst.m_axis_tx_tvalid)-1) + dut.eth_tx_fc_quanta_clk_en.setimmediatevalue(2**len(core_inst.m_axis_tx_tvalid)-1) dut.eth_rx_status.setimmediatevalue(2**len(core_inst.m_axis_tx_tvalid)-1) + dut.eth_rx_lfc_req.setimmediatevalue(0) + dut.eth_rx_pfc_req.setimmediatevalue(0) + dut.eth_rx_fc_quanta_clk_en.setimmediatevalue(2**len(core_inst.m_axis_tx_tvalid)-1) # DDR self.ddr_group_size = core_inst.DDR_GROUP_SIZE.value @@ -645,13 +650,16 @@ async def run_test_nic(dut): for block in tb.driver.interfaces[0].sched_blocks: await block.schedulers[0].rb.write_dword(mqnic.MQNIC_RB_SCHED_RR_REG_CTRL, 0x00000001) - await tb.driver.interfaces[0].set_rx_queue_map_indir_table(block.index, 0, block.index) + await block.interface.set_rx_queue_map_indir_table(block.index, 0, block.index) for k in range(len(block.interface.txq)): - if k % len(tb.driver.interfaces[0].sched_blocks) == block.index: + if k % len(block.interface.sched_blocks) == block.index: await block.schedulers[0].hw_regs.write_dword(4*k, 0x00000003) else: await block.schedulers[0].hw_regs.write_dword(4*k, 0x00000000) + await block.interface.ports[block.index].set_tx_ctrl(mqnic.MQNIC_PORT_TX_CTRL_EN) + await block.interface.ports[block.index].set_rx_ctrl(mqnic.MQNIC_PORT_RX_CTRL_EN) + count = 64 pkts = [bytearray([(x+k) % 256 for x in range(1514)]) for k in range(count)] @@ -681,6 +689,35 @@ async def run_test_nic(dut): await block.schedulers[0].rb.write_dword(mqnic.MQNIC_RB_SCHED_RR_REG_CTRL, 0x00000000) await tb.driver.interfaces[0].set_rx_queue_map_indir_table(block.index, 0, 0) + if tb.driver.interfaces[0].if_feature_lfc: + tb.log.info("Test LFC pause frame RX") + + await tb.driver.interfaces[0].ports[0].set_lfc_ctrl(mqnic.MQNIC_PORT_LFC_CTRL_TX_LFC_EN | mqnic.MQNIC_PORT_LFC_CTRL_RX_LFC_EN) + await tb.driver.hw_regs.read_dword(0) + + lfc_xoff = Ether(src='DA:D1:D2:D3:D4:D5', dst='01:80:C2:00:00:01', type=0x8808) / struct.pack('!HH', 0x0001, 2000) + + await tb.port_mac[0].rx.send(bytes(lfc_xoff)) + + count = 16 + + pkts = [bytearray([(x+k) % 256 for x in range(1514)]) for k in range(count)] + + tb.loopback_enable = True + + for p in pkts: + await tb.driver.interfaces[0].start_xmit(p, 0) + + for k in range(count): + pkt = await tb.driver.interfaces[0].recv() + + tb.log.info("Packet: %s", pkt) + assert pkt.data == pkts[k] + if tb.driver.interfaces[0].if_feature_rx_csum: + assert pkt.rx_checksum == ~scapy.utils.checksum(bytes(pkt.data[14:])) & 0xffff + + tb.loopback_enable = False + tb.log.info("Read statistics counters") await Timer(2000, 'ns') @@ -773,6 +810,10 @@ def test_mqnic_core_pcie_us(request, if_count, ports_per_if, axis_pcie_data_widt os.path.join(rtl_dir, "common", "mqnic_tx_scheduler_block_rr.v"), os.path.join(rtl_dir, "common", "tx_scheduler_rr.v"), os.path.join(rtl_dir, "mqnic_app_block.v"), + os.path.join(eth_rtl_dir, "mac_ctrl_rx.v"), + os.path.join(eth_rtl_dir, "mac_ctrl_tx.v"), + os.path.join(eth_rtl_dir, "mac_pause_ctrl_rx.v"), + os.path.join(eth_rtl_dir, "mac_pause_ctrl_tx.v"), os.path.join(eth_rtl_dir, "ptp_clock.v"), os.path.join(eth_rtl_dir, "ptp_clock_cdc.v"), os.path.join(eth_rtl_dir, "ptp_perout.v"), @@ -881,6 +922,9 @@ def test_mqnic_core_pcie_us(request, if_count, ports_per_if, axis_pcie_data_widt parameters['TX_CHECKSUM_ENABLE'] = 1 parameters['RX_HASH_ENABLE'] = 1 parameters['RX_CHECKSUM_ENABLE'] = 1 + parameters['LFC_ENABLE'] = 1 + parameters['PFC_ENABLE'] = parameters['LFC_ENABLE'] + parameters['MAC_CTRL_ENABLE'] = 1 parameters['TX_FIFO_DEPTH'] = 32768 parameters['RX_FIFO_DEPTH'] = 131072 parameters['MAX_TX_SIZE'] = 9214 diff --git a/fpga/common/rtl/cmac_gty_wrapper.v b/fpga/common/rtl/cmac_gty_wrapper.v index 6a833cc2f..2d08536af 100644 --- a/fpga/common/rtl/cmac_gty_wrapper.v +++ b/fpga/common/rtl/cmac_gty_wrapper.v @@ -130,6 +130,12 @@ module cmac_gty_wrapper # output wire [15:0] tx_ptp_ts_tag, output wire tx_ptp_ts_valid, + input wire tx_enable, + input wire tx_lfc_en, + input wire tx_lfc_req, + input wire [7:0] tx_pfc_en, + input wire [7:0] tx_pfc_req, + output wire rx_clk, output wire rx_rst, @@ -143,7 +149,14 @@ module cmac_gty_wrapper # output wire rx_ptp_rst, input wire [79:0] rx_ptp_time, - output wire rx_status + input wire rx_enable, + output wire rx_status, + input wire rx_lfc_en, + output wire rx_lfc_req, + input wire rx_lfc_ack, + input wire [7:0] rx_pfc_en, + output wire [7:0] rx_pfc_req, + input wire [7:0] rx_pfc_ack ); reg [23:0] drp_addr_reg = 24'd0; @@ -1578,7 +1591,48 @@ cmac_usplus cmac_inst ( .stat_rx_packet_large(cmac_stat_rx_packet_large), .stat_rx_packet_small(cmac_stat_rx_packet_small), - .ctl_rx_enable(cmac_ctl_rx_enable_reg), + .stat_rx_pause(), + .stat_rx_pause_quanta0(), + .stat_rx_pause_quanta1(), + .stat_rx_pause_quanta2(), + .stat_rx_pause_quanta3(), + .stat_rx_pause_quanta4(), + .stat_rx_pause_quanta5(), + .stat_rx_pause_quanta6(), + .stat_rx_pause_quanta7(), + .stat_rx_pause_quanta8(), + .stat_rx_pause_req({rx_lfc_req, rx_pfc_req}), + .stat_rx_pause_valid(), + .stat_rx_user_pause(), + + .ctl_rx_check_etype_gcp(1'b1), + .ctl_rx_check_etype_gpp(1'b1), + .ctl_rx_check_etype_pcp(1'b1), + .ctl_rx_check_etype_ppp(1'b1), + .ctl_rx_check_mcast_gcp(1'b1), + .ctl_rx_check_mcast_gpp(1'b1), + .ctl_rx_check_mcast_pcp(1'b1), + .ctl_rx_check_mcast_ppp(1'b1), + .ctl_rx_check_opcode_gcp(1'b1), + .ctl_rx_check_opcode_gpp(1'b1), + .ctl_rx_check_opcode_pcp(1'b1), + .ctl_rx_check_opcode_ppp(1'b1), + .ctl_rx_check_sa_gcp(1'b0), + .ctl_rx_check_sa_gpp(1'b0), + .ctl_rx_check_sa_pcp(1'b0), + .ctl_rx_check_sa_ppp(1'b0), + .ctl_rx_check_ucast_gcp(1'b0), + .ctl_rx_check_ucast_gpp(1'b0), + .ctl_rx_check_ucast_pcp(1'b0), + .ctl_rx_check_ucast_ppp(1'b0), + .ctl_rx_enable_gcp(rx_lfc_en), + .ctl_rx_enable_gpp(rx_lfc_en), + .ctl_rx_enable_pcp(rx_pfc_en != 0), + .ctl_rx_enable_ppp(rx_pfc_en != 0), + .ctl_rx_pause_ack({rx_lfc_ack, rx_pfc_ack}), + .ctl_rx_pause_enable({rx_lfc_en, rx_pfc_en}), + + .ctl_rx_enable(cmac_ctl_rx_enable_reg && rx_enable), .ctl_rx_force_resync(cmac_ctl_rx_force_resync_reg), .ctl_rx_test_pattern(cmac_ctl_rx_test_pattern_reg), @@ -1658,7 +1712,7 @@ cmac_usplus cmac_inst ( .stat_tx_unicast(cmac_stat_tx_unicast), .stat_tx_vlan(cmac_stat_tx_vlan), - .ctl_tx_enable(cmac_ctl_tx_enable_reg), + .ctl_tx_enable(cmac_ctl_tx_enable_reg && tx_enable), .ctl_tx_send_idle(cmac_ctl_tx_send_idle_reg), .ctl_tx_send_rfi(cmac_ctl_tx_send_rfi_reg), .ctl_tx_send_lfi(cmac_ctl_tx_send_lfi_reg), @@ -1666,6 +1720,32 @@ cmac_usplus cmac_inst ( .tx_clk(tx_clk), + .stat_tx_pause_valid(), + .stat_tx_pause(), + .stat_tx_user_pause(), + + .ctl_tx_pause_enable({tx_lfc_en, tx_pfc_en}), + .ctl_tx_pause_quanta0(16'hffff), + .ctl_tx_pause_quanta1(16'hffff), + .ctl_tx_pause_quanta2(16'hffff), + .ctl_tx_pause_quanta3(16'hffff), + .ctl_tx_pause_quanta4(16'hffff), + .ctl_tx_pause_quanta5(16'hffff), + .ctl_tx_pause_quanta6(16'hffff), + .ctl_tx_pause_quanta7(16'hffff), + .ctl_tx_pause_quanta8(16'hffff), + .ctl_tx_pause_refresh_timer0(16'h7fff), + .ctl_tx_pause_refresh_timer1(16'h7fff), + .ctl_tx_pause_refresh_timer2(16'h7fff), + .ctl_tx_pause_refresh_timer3(16'h7fff), + .ctl_tx_pause_refresh_timer4(16'h7fff), + .ctl_tx_pause_refresh_timer5(16'h7fff), + .ctl_tx_pause_refresh_timer6(16'h7fff), + .ctl_tx_pause_refresh_timer7(16'h7fff), + .ctl_tx_pause_refresh_timer8(16'h7fff), + .ctl_tx_pause_req({tx_lfc_req, tx_pfc_req}), + .ctl_tx_resend_pause(1'b0), + .tx_axis_tready(cmac_tx_axis_tready), .tx_axis_tvalid(cmac_tx_axis_tvalid), .tx_axis_tdata(cmac_tx_axis_tdata), diff --git a/fpga/common/rtl/mqnic_core.v b/fpga/common/rtl/mqnic_core.v index 5f8f625b3..78ace7b93 100644 --- a/fpga/common/rtl/mqnic_core.v +++ b/fpga/common/rtl/mqnic_core.v @@ -80,6 +80,9 @@ module mqnic_core # parameter TX_CHECKSUM_ENABLE = 1, parameter RX_HASH_ENABLE = 1, parameter RX_CHECKSUM_ENABLE = 1, + parameter PFC_ENABLE = 1, + parameter LFC_ENABLE = PFC_ENABLE, + parameter MAC_CTRL_ENABLE = 0, parameter TX_FIFO_DEPTH = 32768, parameter RX_FIFO_DEPTH = 32768, parameter MAX_TX_SIZE = 9214, @@ -410,7 +413,13 @@ module mqnic_core # input wire [PORT_COUNT-1:0] s_axis_tx_cpl_valid, output wire [PORT_COUNT-1:0] s_axis_tx_cpl_ready, + output wire [PORT_COUNT-1:0] tx_enable, input wire [PORT_COUNT-1:0] tx_status, + output wire [PORT_COUNT-1:0] tx_lfc_en, + output wire [PORT_COUNT-1:0] tx_lfc_req, + output wire [PORT_COUNT*8-1:0] tx_pfc_en, + output wire [PORT_COUNT*8-1:0] tx_pfc_req, + input wire [PORT_COUNT-1:0] tx_fc_quanta_clk_en, input wire [PORT_COUNT-1:0] rx_clk, input wire [PORT_COUNT-1:0] rx_rst, @@ -427,7 +436,15 @@ module mqnic_core # input wire [PORT_COUNT-1:0] s_axis_rx_tlast, input wire [PORT_COUNT*AXIS_RX_USER_WIDTH-1:0] s_axis_rx_tuser, + output wire [PORT_COUNT-1:0] rx_enable, input wire [PORT_COUNT-1:0] rx_status, + output wire [PORT_COUNT-1:0] rx_lfc_en, + input wire [PORT_COUNT-1:0] rx_lfc_req, + output wire [PORT_COUNT-1:0] rx_lfc_ack, + output wire [PORT_COUNT*8-1:0] rx_pfc_en, + input wire [PORT_COUNT*8-1:0] rx_pfc_req, + output wire [PORT_COUNT*8-1:0] rx_pfc_ack, + input wire [PORT_COUNT-1:0] rx_fc_quanta_clk_en, /* * DDR @@ -3060,6 +3077,9 @@ generate .TX_CHECKSUM_ENABLE(TX_CHECKSUM_ENABLE), .RX_HASH_ENABLE(RX_HASH_ENABLE), .RX_CHECKSUM_ENABLE(RX_CHECKSUM_ENABLE), + .PFC_ENABLE(PFC_ENABLE), + .LFC_ENABLE(LFC_ENABLE), + .MAC_CTRL_ENABLE(MAC_CTRL_ENABLE), .TX_FIFO_DEPTH(TX_FIFO_DEPTH), .RX_FIFO_DEPTH(RX_FIFO_DEPTH), .MAX_TX_SIZE(MAX_TX_SIZE), @@ -3433,7 +3453,13 @@ generate .s_axis_tx_cpl_valid(s_axis_tx_cpl_valid[n*PORTS_PER_IF +: PORTS_PER_IF]), .s_axis_tx_cpl_ready(s_axis_tx_cpl_ready[n*PORTS_PER_IF +: PORTS_PER_IF]), + .tx_enable(tx_enable[n*PORTS_PER_IF +: PORTS_PER_IF]), .tx_status(tx_status[n*PORTS_PER_IF +: PORTS_PER_IF]), + .tx_lfc_en(tx_lfc_en[n*PORTS_PER_IF +: PORTS_PER_IF]), + .tx_lfc_req(tx_lfc_req[n*PORTS_PER_IF +: PORTS_PER_IF]), + .tx_pfc_en(tx_pfc_en[n*PORTS_PER_IF*8 +: PORTS_PER_IF*8]), + .tx_pfc_req(tx_pfc_req[n*PORTS_PER_IF*8 +: PORTS_PER_IF*8]), + .tx_fc_quanta_clk_en(tx_fc_quanta_clk_en[n*PORTS_PER_IF +: PORTS_PER_IF]), /* * Receive data input @@ -3448,7 +3474,15 @@ generate .s_axis_rx_tlast(s_axis_rx_tlast[n*PORTS_PER_IF +: PORTS_PER_IF]), .s_axis_rx_tuser(s_axis_rx_tuser[n*PORTS_PER_IF*AXIS_RX_USER_WIDTH +: PORTS_PER_IF*AXIS_RX_USER_WIDTH]), + .rx_enable(rx_enable[n*PORTS_PER_IF +: PORTS_PER_IF]), .rx_status(rx_status[n*PORTS_PER_IF +: PORTS_PER_IF]), + .rx_lfc_en(rx_lfc_en[n*PORTS_PER_IF +: PORTS_PER_IF]), + .rx_lfc_req(rx_lfc_req[n*PORTS_PER_IF +: PORTS_PER_IF]), + .rx_lfc_ack(rx_lfc_ack[n*PORTS_PER_IF +: PORTS_PER_IF]), + .rx_pfc_en(rx_pfc_en[n*PORTS_PER_IF*8 +: PORTS_PER_IF*8]), + .rx_pfc_req(rx_pfc_req[n*PORTS_PER_IF*8 +: PORTS_PER_IF*8]), + .rx_pfc_ack(rx_pfc_ack[n*PORTS_PER_IF*8 +: PORTS_PER_IF*8]), + .rx_fc_quanta_clk_en(rx_fc_quanta_clk_en[n*PORTS_PER_IF +: PORTS_PER_IF]), /* * PTP clock diff --git a/fpga/common/rtl/mqnic_core_axi.v b/fpga/common/rtl/mqnic_core_axi.v index 875224fa7..785a01c0d 100644 --- a/fpga/common/rtl/mqnic_core_axi.v +++ b/fpga/common/rtl/mqnic_core_axi.v @@ -80,6 +80,9 @@ module mqnic_core_axi # parameter TX_CHECKSUM_ENABLE = 1, parameter RX_HASH_ENABLE = 1, parameter RX_CHECKSUM_ENABLE = 1, + parameter PFC_ENABLE = 1, + parameter LFC_ENABLE = PFC_ENABLE, + parameter MAC_CTRL_ENABLE = 0, parameter TX_FIFO_DEPTH = 32768, parameter RX_FIFO_DEPTH = 32768, parameter MAX_TX_SIZE = 9214, @@ -372,7 +375,13 @@ module mqnic_core_axi # input wire [PORT_COUNT-1:0] s_axis_tx_cpl_valid, output wire [PORT_COUNT-1:0] s_axis_tx_cpl_ready, + output wire [PORT_COUNT-1:0] tx_enable, input wire [PORT_COUNT-1:0] tx_status, + output wire [PORT_COUNT-1:0] tx_lfc_en, + output wire [PORT_COUNT-1:0] tx_lfc_req, + output wire [PORT_COUNT*8-1:0] tx_pfc_en, + output wire [PORT_COUNT*8-1:0] tx_pfc_req, + input wire [PORT_COUNT-1:0] tx_fc_quanta_clk_en, input wire [PORT_COUNT-1:0] rx_clk, input wire [PORT_COUNT-1:0] rx_rst, @@ -389,7 +398,15 @@ module mqnic_core_axi # input wire [PORT_COUNT-1:0] s_axis_rx_tlast, input wire [PORT_COUNT*AXIS_RX_USER_WIDTH-1:0] s_axis_rx_tuser, + output wire [PORT_COUNT-1:0] rx_enable, input wire [PORT_COUNT-1:0] rx_status, + output wire [PORT_COUNT-1:0] rx_lfc_en, + input wire [PORT_COUNT-1:0] rx_lfc_req, + output wire [PORT_COUNT-1:0] rx_lfc_ack, + output wire [PORT_COUNT*8-1:0] rx_pfc_en, + input wire [PORT_COUNT*8-1:0] rx_pfc_req, + output wire [PORT_COUNT*8-1:0] rx_pfc_ack, + input wire [PORT_COUNT-1:0] rx_fc_quanta_clk_en, /* * DDR @@ -994,6 +1011,9 @@ mqnic_core #( .TX_CHECKSUM_ENABLE(TX_CHECKSUM_ENABLE), .RX_HASH_ENABLE(RX_HASH_ENABLE), .RX_CHECKSUM_ENABLE(RX_CHECKSUM_ENABLE), + .PFC_ENABLE(PFC_ENABLE), + .LFC_ENABLE(LFC_ENABLE), + .MAC_CTRL_ENABLE(MAC_CTRL_ENABLE), .TX_FIFO_DEPTH(TX_FIFO_DEPTH), .RX_FIFO_DEPTH(RX_FIFO_DEPTH), .MAX_TX_SIZE(MAX_TX_SIZE), @@ -1298,7 +1318,13 @@ core_inst ( .s_axis_tx_cpl_valid(s_axis_tx_cpl_valid), .s_axis_tx_cpl_ready(s_axis_tx_cpl_ready), + .tx_enable(tx_enable), .tx_status(tx_status), + .tx_lfc_en(tx_lfc_en), + .tx_lfc_req(tx_lfc_req), + .tx_pfc_en(tx_pfc_en), + .tx_pfc_req(tx_pfc_req), + .tx_fc_quanta_clk_en(tx_fc_quanta_clk_en), .rx_clk(rx_clk), .rx_rst(rx_rst), @@ -1315,7 +1341,15 @@ core_inst ( .s_axis_rx_tlast(s_axis_rx_tlast), .s_axis_rx_tuser(s_axis_rx_tuser), + .rx_enable(rx_enable), .rx_status(rx_status), + .rx_lfc_en(rx_lfc_en), + .rx_lfc_req(rx_lfc_req), + .rx_lfc_ack(rx_lfc_ack), + .rx_pfc_en(rx_pfc_en), + .rx_pfc_req(rx_pfc_req), + .rx_pfc_ack(rx_pfc_ack), + .rx_fc_quanta_clk_en(rx_fc_quanta_clk_en), /* * DDR diff --git a/fpga/common/rtl/mqnic_core_pcie.v b/fpga/common/rtl/mqnic_core_pcie.v index 6b44adf67..b8bdc4073 100644 --- a/fpga/common/rtl/mqnic_core_pcie.v +++ b/fpga/common/rtl/mqnic_core_pcie.v @@ -80,6 +80,9 @@ module mqnic_core_pcie # parameter TX_CHECKSUM_ENABLE = 1, parameter RX_HASH_ENABLE = 1, parameter RX_CHECKSUM_ENABLE = 1, + parameter PFC_ENABLE = 1, + parameter LFC_ENABLE = PFC_ENABLE, + parameter MAC_CTRL_ENABLE = 0, parameter TX_FIFO_DEPTH = 32768, parameter RX_FIFO_DEPTH = 32768, parameter MAX_TX_SIZE = 9214, @@ -389,7 +392,13 @@ module mqnic_core_pcie # input wire [PORT_COUNT-1:0] s_axis_tx_cpl_valid, output wire [PORT_COUNT-1:0] s_axis_tx_cpl_ready, + output wire [PORT_COUNT-1:0] tx_enable, input wire [PORT_COUNT-1:0] tx_status, + output wire [PORT_COUNT-1:0] tx_lfc_en, + output wire [PORT_COUNT-1:0] tx_lfc_req, + output wire [PORT_COUNT*8-1:0] tx_pfc_en, + output wire [PORT_COUNT*8-1:0] tx_pfc_req, + input wire [PORT_COUNT-1:0] tx_fc_quanta_clk_en, input wire [PORT_COUNT-1:0] rx_clk, input wire [PORT_COUNT-1:0] rx_rst, @@ -406,7 +415,15 @@ module mqnic_core_pcie # input wire [PORT_COUNT-1:0] s_axis_rx_tlast, input wire [PORT_COUNT*AXIS_RX_USER_WIDTH-1:0] s_axis_rx_tuser, + output wire [PORT_COUNT-1:0] rx_enable, input wire [PORT_COUNT-1:0] rx_status, + output wire [PORT_COUNT-1:0] rx_lfc_en, + input wire [PORT_COUNT-1:0] rx_lfc_req, + output wire [PORT_COUNT-1:0] rx_lfc_ack, + output wire [PORT_COUNT*8-1:0] rx_pfc_en, + input wire [PORT_COUNT*8-1:0] rx_pfc_req, + output wire [PORT_COUNT*8-1:0] rx_pfc_ack, + input wire [PORT_COUNT-1:0] rx_fc_quanta_clk_en, /* * DDR @@ -1626,6 +1643,9 @@ mqnic_core #( .TX_CHECKSUM_ENABLE(TX_CHECKSUM_ENABLE), .RX_HASH_ENABLE(RX_HASH_ENABLE), .RX_CHECKSUM_ENABLE(RX_CHECKSUM_ENABLE), + .PFC_ENABLE(PFC_ENABLE), + .LFC_ENABLE(LFC_ENABLE), + .MAC_CTRL_ENABLE(MAC_CTRL_ENABLE), .TX_FIFO_DEPTH(TX_FIFO_DEPTH), .RX_FIFO_DEPTH(RX_FIFO_DEPTH), .MAX_TX_SIZE(MAX_TX_SIZE), @@ -1954,7 +1974,13 @@ core_inst ( .s_axis_tx_cpl_valid(s_axis_tx_cpl_valid), .s_axis_tx_cpl_ready(s_axis_tx_cpl_ready), + .tx_enable(tx_enable), .tx_status(tx_status), + .tx_lfc_en(tx_lfc_en), + .tx_lfc_req(tx_lfc_req), + .tx_pfc_en(tx_pfc_en), + .tx_pfc_req(tx_pfc_req), + .tx_fc_quanta_clk_en(tx_fc_quanta_clk_en), .rx_clk(rx_clk), .rx_rst(rx_rst), @@ -1971,7 +1997,15 @@ core_inst ( .s_axis_rx_tlast(s_axis_rx_tlast), .s_axis_rx_tuser(s_axis_rx_tuser), + .rx_enable(rx_enable), .rx_status(rx_status), + .rx_lfc_en(rx_lfc_en), + .rx_lfc_req(rx_lfc_req), + .rx_lfc_ack(rx_lfc_ack), + .rx_pfc_en(rx_pfc_en), + .rx_pfc_req(rx_pfc_req), + .rx_pfc_ack(rx_pfc_ack), + .rx_fc_quanta_clk_en(rx_fc_quanta_clk_en), /* * DDR diff --git a/fpga/common/rtl/mqnic_core_pcie_ptile.v b/fpga/common/rtl/mqnic_core_pcie_ptile.v index f774014c9..fd885c7a1 100644 --- a/fpga/common/rtl/mqnic_core_pcie_ptile.v +++ b/fpga/common/rtl/mqnic_core_pcie_ptile.v @@ -80,6 +80,9 @@ module mqnic_core_pcie_ptile # parameter TX_CHECKSUM_ENABLE = 1, parameter RX_HASH_ENABLE = 1, parameter RX_CHECKSUM_ENABLE = 1, + parameter PFC_ENABLE = 1, + parameter LFC_ENABLE = PFC_ENABLE, + parameter MAC_CTRL_ENABLE = 0, parameter TX_FIFO_DEPTH = 32768, parameter RX_FIFO_DEPTH = 32768, parameter MAX_TX_SIZE = 9214, @@ -337,7 +340,13 @@ module mqnic_core_pcie_ptile # input wire [PORT_COUNT-1:0] s_axis_eth_tx_cpl_valid, output wire [PORT_COUNT-1:0] s_axis_eth_tx_cpl_ready, + output wire [PORT_COUNT-1:0] eth_tx_enable, input wire [PORT_COUNT-1:0] eth_tx_status, + output wire [PORT_COUNT-1:0] eth_tx_lfc_en, + output wire [PORT_COUNT-1:0] eth_tx_lfc_req, + output wire [PORT_COUNT*8-1:0] eth_tx_pfc_en, + output wire [PORT_COUNT*8-1:0] eth_tx_pfc_req, + input wire [PORT_COUNT-1:0] eth_tx_fc_quanta_clk_en, input wire [PORT_COUNT-1:0] eth_rx_clk, input wire [PORT_COUNT-1:0] eth_rx_rst, @@ -354,7 +363,15 @@ module mqnic_core_pcie_ptile # input wire [PORT_COUNT-1:0] s_axis_eth_rx_tlast, input wire [PORT_COUNT*AXIS_ETH_RX_USER_WIDTH-1:0] s_axis_eth_rx_tuser, + output wire [PORT_COUNT-1:0] eth_rx_enable, input wire [PORT_COUNT-1:0] eth_rx_status, + output wire [PORT_COUNT-1:0] eth_rx_lfc_en, + input wire [PORT_COUNT-1:0] eth_rx_lfc_req, + output wire [PORT_COUNT-1:0] eth_rx_lfc_ack, + output wire [PORT_COUNT*8-1:0] eth_rx_pfc_en, + input wire [PORT_COUNT*8-1:0] eth_rx_pfc_req, + output wire [PORT_COUNT*8-1:0] eth_rx_pfc_ack, + input wire [PORT_COUNT-1:0] eth_rx_fc_quanta_clk_en, /* * DDR @@ -788,6 +805,9 @@ mqnic_core_pcie #( .TX_CHECKSUM_ENABLE(TX_CHECKSUM_ENABLE), .RX_HASH_ENABLE(RX_HASH_ENABLE), .RX_CHECKSUM_ENABLE(RX_CHECKSUM_ENABLE), + .PFC_ENABLE(PFC_ENABLE), + .LFC_ENABLE(LFC_ENABLE), + .MAC_CTRL_ENABLE(MAC_CTRL_ENABLE), .TX_FIFO_DEPTH(TX_FIFO_DEPTH), .RX_FIFO_DEPTH(RX_FIFO_DEPTH), .MAX_TX_SIZE(MAX_TX_SIZE), @@ -1095,7 +1115,13 @@ core_pcie_inst ( .s_axis_tx_cpl_valid(s_axis_eth_tx_cpl_valid), .s_axis_tx_cpl_ready(s_axis_eth_tx_cpl_ready), + .tx_enable(eth_tx_enable), .tx_status(eth_tx_status), + .tx_lfc_en(eth_tx_lfc_en), + .tx_lfc_req(eth_tx_lfc_req), + .tx_pfc_en(eth_tx_pfc_en), + .tx_pfc_req(eth_tx_pfc_req), + .tx_fc_quanta_clk_en(eth_tx_fc_quanta_clk_en), .rx_clk(eth_rx_clk), .rx_rst(eth_rx_rst), @@ -1112,7 +1138,15 @@ core_pcie_inst ( .s_axis_rx_tlast(s_axis_eth_rx_tlast), .s_axis_rx_tuser(s_axis_eth_rx_tuser), + .rx_enable(eth_rx_enable), .rx_status(eth_rx_status), + .rx_lfc_en(eth_rx_lfc_en), + .rx_lfc_req(eth_rx_lfc_req), + .rx_lfc_ack(eth_rx_lfc_ack), + .rx_pfc_en(eth_rx_pfc_en), + .rx_pfc_req(eth_rx_pfc_req), + .rx_pfc_ack(eth_rx_pfc_ack), + .rx_fc_quanta_clk_en(eth_rx_fc_quanta_clk_en), /* * DDR diff --git a/fpga/common/rtl/mqnic_core_pcie_s10.v b/fpga/common/rtl/mqnic_core_pcie_s10.v index 1d1d590ea..f185719ba 100644 --- a/fpga/common/rtl/mqnic_core_pcie_s10.v +++ b/fpga/common/rtl/mqnic_core_pcie_s10.v @@ -80,6 +80,9 @@ module mqnic_core_pcie_s10 # parameter TX_CHECKSUM_ENABLE = 1, parameter RX_HASH_ENABLE = 1, parameter RX_CHECKSUM_ENABLE = 1, + parameter PFC_ENABLE = 1, + parameter LFC_ENABLE = PFC_ENABLE, + parameter MAC_CTRL_ENABLE = 0, parameter TX_FIFO_DEPTH = 32768, parameter RX_FIFO_DEPTH = 32768, parameter MAX_TX_SIZE = 9214, @@ -333,7 +336,13 @@ module mqnic_core_pcie_s10 # input wire [PORT_COUNT-1:0] s_axis_eth_tx_cpl_valid, output wire [PORT_COUNT-1:0] s_axis_eth_tx_cpl_ready, + output wire [PORT_COUNT-1:0] eth_tx_enable, input wire [PORT_COUNT-1:0] eth_tx_status, + output wire [PORT_COUNT-1:0] eth_tx_lfc_en, + output wire [PORT_COUNT-1:0] eth_tx_lfc_req, + output wire [PORT_COUNT*8-1:0] eth_tx_pfc_en, + output wire [PORT_COUNT*8-1:0] eth_tx_pfc_req, + input wire [PORT_COUNT-1:0] eth_tx_fc_quanta_clk_en, input wire [PORT_COUNT-1:0] eth_rx_clk, input wire [PORT_COUNT-1:0] eth_rx_rst, @@ -350,7 +359,15 @@ module mqnic_core_pcie_s10 # input wire [PORT_COUNT-1:0] s_axis_eth_rx_tlast, input wire [PORT_COUNT*AXIS_ETH_RX_USER_WIDTH-1:0] s_axis_eth_rx_tuser, + output wire [PORT_COUNT-1:0] eth_rx_enable, input wire [PORT_COUNT-1:0] eth_rx_status, + output wire [PORT_COUNT-1:0] eth_rx_lfc_en, + input wire [PORT_COUNT-1:0] eth_rx_lfc_req, + output wire [PORT_COUNT-1:0] eth_rx_lfc_ack, + output wire [PORT_COUNT*8-1:0] eth_rx_pfc_en, + input wire [PORT_COUNT*8-1:0] eth_rx_pfc_req, + output wire [PORT_COUNT*8-1:0] eth_rx_pfc_ack, + input wire [PORT_COUNT-1:0] eth_rx_fc_quanta_clk_en, /* * DDR @@ -797,6 +814,9 @@ mqnic_core_pcie #( .TX_CHECKSUM_ENABLE(TX_CHECKSUM_ENABLE), .RX_HASH_ENABLE(RX_HASH_ENABLE), .RX_CHECKSUM_ENABLE(RX_CHECKSUM_ENABLE), + .PFC_ENABLE(PFC_ENABLE), + .LFC_ENABLE(LFC_ENABLE), + .MAC_CTRL_ENABLE(MAC_CTRL_ENABLE), .TX_FIFO_DEPTH(TX_FIFO_DEPTH), .RX_FIFO_DEPTH(RX_FIFO_DEPTH), .MAX_TX_SIZE(MAX_TX_SIZE), @@ -1104,7 +1124,13 @@ core_pcie_inst ( .s_axis_tx_cpl_valid(s_axis_eth_tx_cpl_valid), .s_axis_tx_cpl_ready(s_axis_eth_tx_cpl_ready), + .tx_enable(eth_tx_enable), .tx_status(eth_tx_status), + .tx_lfc_en(eth_tx_lfc_en), + .tx_lfc_req(eth_tx_lfc_req), + .tx_pfc_en(eth_tx_pfc_en), + .tx_pfc_req(eth_tx_pfc_req), + .tx_fc_quanta_clk_en(eth_tx_fc_quanta_clk_en), .rx_clk(eth_rx_clk), .rx_rst(eth_rx_rst), @@ -1121,7 +1147,15 @@ core_pcie_inst ( .s_axis_rx_tlast(s_axis_eth_rx_tlast), .s_axis_rx_tuser(s_axis_eth_rx_tuser), + .rx_enable(eth_rx_enable), .rx_status(eth_rx_status), + .rx_lfc_en(eth_rx_lfc_en), + .rx_lfc_req(eth_rx_lfc_req), + .rx_lfc_ack(eth_rx_lfc_ack), + .rx_pfc_en(eth_rx_pfc_en), + .rx_pfc_req(eth_rx_pfc_req), + .rx_pfc_ack(eth_rx_pfc_ack), + .rx_fc_quanta_clk_en(eth_rx_fc_quanta_clk_en), /* * DDR diff --git a/fpga/common/rtl/mqnic_core_pcie_us.v b/fpga/common/rtl/mqnic_core_pcie_us.v index f535b87b7..3b1472983 100644 --- a/fpga/common/rtl/mqnic_core_pcie_us.v +++ b/fpga/common/rtl/mqnic_core_pcie_us.v @@ -80,6 +80,9 @@ module mqnic_core_pcie_us # parameter TX_CHECKSUM_ENABLE = 1, parameter RX_HASH_ENABLE = 1, parameter RX_CHECKSUM_ENABLE = 1, + parameter PFC_ENABLE = 1, + parameter LFC_ENABLE = PFC_ENABLE, + parameter MAC_CTRL_ENABLE = 0, parameter TX_FIFO_DEPTH = 32768, parameter RX_FIFO_DEPTH = 32768, parameter MAX_TX_SIZE = 9214, @@ -393,7 +396,13 @@ module mqnic_core_pcie_us # input wire [PORT_COUNT-1:0] s_axis_eth_tx_cpl_valid, output wire [PORT_COUNT-1:0] s_axis_eth_tx_cpl_ready, + output wire [PORT_COUNT-1:0] eth_tx_enable, input wire [PORT_COUNT-1:0] eth_tx_status, + output wire [PORT_COUNT-1:0] eth_tx_lfc_en, + output wire [PORT_COUNT-1:0] eth_tx_lfc_req, + output wire [PORT_COUNT*8-1:0] eth_tx_pfc_en, + output wire [PORT_COUNT*8-1:0] eth_tx_pfc_req, + input wire [PORT_COUNT-1:0] eth_tx_fc_quanta_clk_en, input wire [PORT_COUNT-1:0] eth_rx_clk, input wire [PORT_COUNT-1:0] eth_rx_rst, @@ -410,7 +419,15 @@ module mqnic_core_pcie_us # input wire [PORT_COUNT-1:0] s_axis_eth_rx_tlast, input wire [PORT_COUNT*AXIS_ETH_RX_USER_WIDTH-1:0] s_axis_eth_rx_tuser, + output wire [PORT_COUNT-1:0] eth_rx_enable, input wire [PORT_COUNT-1:0] eth_rx_status, + output wire [PORT_COUNT-1:0] eth_rx_lfc_en, + input wire [PORT_COUNT-1:0] eth_rx_lfc_req, + output wire [PORT_COUNT-1:0] eth_rx_lfc_ack, + output wire [PORT_COUNT*8-1:0] eth_rx_pfc_en, + input wire [PORT_COUNT*8-1:0] eth_rx_pfc_req, + output wire [PORT_COUNT*8-1:0] eth_rx_pfc_ack, + input wire [PORT_COUNT-1:0] eth_rx_fc_quanta_clk_en, /* * DDR @@ -917,6 +934,9 @@ mqnic_core_pcie #( .TX_CHECKSUM_ENABLE(TX_CHECKSUM_ENABLE), .RX_HASH_ENABLE(RX_HASH_ENABLE), .RX_CHECKSUM_ENABLE(RX_CHECKSUM_ENABLE), + .PFC_ENABLE(PFC_ENABLE), + .LFC_ENABLE(LFC_ENABLE), + .MAC_CTRL_ENABLE(MAC_CTRL_ENABLE), .TX_FIFO_DEPTH(TX_FIFO_DEPTH), .RX_FIFO_DEPTH(RX_FIFO_DEPTH), .MAX_TX_SIZE(MAX_TX_SIZE), @@ -1224,7 +1244,13 @@ core_pcie_inst ( .s_axis_tx_cpl_valid(s_axis_eth_tx_cpl_valid), .s_axis_tx_cpl_ready(s_axis_eth_tx_cpl_ready), + .tx_enable(eth_tx_enable), .tx_status(eth_tx_status), + .tx_lfc_en(eth_tx_lfc_en), + .tx_lfc_req(eth_tx_lfc_req), + .tx_pfc_en(eth_tx_pfc_en), + .tx_pfc_req(eth_tx_pfc_req), + .tx_fc_quanta_clk_en(eth_tx_fc_quanta_clk_en), .rx_clk(eth_rx_clk), .rx_rst(eth_rx_rst), @@ -1241,7 +1267,15 @@ core_pcie_inst ( .s_axis_rx_tlast(s_axis_eth_rx_tlast), .s_axis_rx_tuser(s_axis_eth_rx_tuser), + .rx_enable(eth_rx_enable), .rx_status(eth_rx_status), + .rx_lfc_en(eth_rx_lfc_en), + .rx_lfc_req(eth_rx_lfc_req), + .rx_lfc_ack(eth_rx_lfc_ack), + .rx_pfc_en(eth_rx_pfc_en), + .rx_pfc_req(eth_rx_pfc_req), + .rx_pfc_ack(eth_rx_pfc_ack), + .rx_fc_quanta_clk_en(eth_rx_fc_quanta_clk_en), /* * DDR diff --git a/fpga/common/rtl/mqnic_interface.v b/fpga/common/rtl/mqnic_interface.v index d6771bd90..d55b83958 100644 --- a/fpga/common/rtl/mqnic_interface.v +++ b/fpga/common/rtl/mqnic_interface.v @@ -62,6 +62,9 @@ module mqnic_interface # parameter TX_CHECKSUM_ENABLE = 1, parameter RX_HASH_ENABLE = 1, parameter RX_CHECKSUM_ENABLE = 1, + parameter PFC_ENABLE = 0, + parameter LFC_ENABLE = PFC_ENABLE, + parameter MAC_CTRL_ENABLE = 0, parameter TX_FIFO_DEPTH = 32768, parameter RX_FIFO_DEPTH = 32768, parameter MAX_TX_SIZE = 9214, @@ -435,7 +438,13 @@ module mqnic_interface # input wire [PORTS-1:0] s_axis_tx_cpl_valid, output wire [PORTS-1:0] s_axis_tx_cpl_ready, + output wire [PORTS-1:0] tx_enable, input wire [PORTS-1:0] tx_status, + output wire [PORTS-1:0] tx_lfc_en, + output wire [PORTS-1:0] tx_lfc_req, + output wire [PORTS*8-1:0] tx_pfc_en, + output wire [PORTS*8-1:0] tx_pfc_req, + input wire [PORTS-1:0] tx_fc_quanta_clk_en, /* * Receive data input @@ -450,7 +459,15 @@ module mqnic_interface # input wire [PORTS-1:0] s_axis_rx_tlast, input wire [PORTS*AXIS_RX_USER_WIDTH-1:0] s_axis_rx_tuser, + output wire [PORTS-1:0] rx_enable, input wire [PORTS-1:0] rx_status, + output wire [PORTS-1:0] rx_lfc_en, + input wire [PORTS-1:0] rx_lfc_req, + output wire [PORTS-1:0] rx_lfc_ack, + output wire [PORTS*8-1:0] rx_pfc_en, + input wire [PORTS*8-1:0] rx_pfc_req, + output wire [PORTS*8-1:0] rx_pfc_ack, + input wire [PORTS-1:0] rx_fc_quanta_clk_en, /* * PTP clock @@ -1084,6 +1101,8 @@ always @(posedge clk) begin ctrl_reg_rd_data_reg[8] <= TX_CHECKSUM_ENABLE; ctrl_reg_rd_data_reg[9] <= RX_CHECKSUM_ENABLE; ctrl_reg_rd_data_reg[10] <= RX_HASH_ENABLE; + ctrl_reg_rd_data_reg[11] <= LFC_ENABLE; + ctrl_reg_rd_data_reg[12] <= PFC_ENABLE; end RBB+8'h10: ctrl_reg_rd_data_reg <= PORTS; // IF ctrl: Port count RBB+8'h14: ctrl_reg_rd_data_reg <= SCHEDULERS; // IF ctrl: Scheduler count @@ -3101,6 +3120,9 @@ for (n = 0; n < PORTS; n = n + 1) begin : port .TX_CPL_ENABLE(TX_CPL_ENABLE), .TX_CPL_FIFO_DEPTH(TX_CPL_FIFO_DEPTH), .TX_TAG_WIDTH(TX_TAG_WIDTH), + .PFC_ENABLE(PFC_ENABLE), + .LFC_ENABLE(LFC_ENABLE), + .MAC_CTRL_ENABLE(MAC_CTRL_ENABLE), .MAX_TX_SIZE(MAX_TX_SIZE), .MAX_RX_SIZE(MAX_RX_SIZE), @@ -3275,7 +3297,13 @@ for (n = 0; n < PORTS; n = n + 1) begin : port .s_axis_tx_cpl_valid(s_axis_tx_cpl_valid[n +: 1]), .s_axis_tx_cpl_ready(s_axis_tx_cpl_ready[n +: 1]), + .tx_enable(tx_enable[n +: 1]), .tx_status(tx_status[n +: 1]), + .tx_lfc_en(tx_lfc_en[n +: 1]), + .tx_lfc_req(tx_lfc_req[n +: 1]), + .tx_pfc_en(tx_pfc_en[n*8 +: 8]), + .tx_pfc_req(tx_pfc_req[n*8 +: 8]), + .tx_fc_quanta_clk_en(tx_fc_quanta_clk_en[n +: 1]), /* * Receive data input @@ -3290,7 +3318,15 @@ for (n = 0; n < PORTS; n = n + 1) begin : port .s_axis_rx_tlast(s_axis_rx_tlast[n +: 1]), .s_axis_rx_tuser(s_axis_rx_tuser[n*AXIS_RX_USER_WIDTH +: AXIS_RX_USER_WIDTH]), - .rx_status(rx_status[n +: 1]) + .rx_enable(rx_enable[n +: 1]), + .rx_status(rx_status[n +: 1]), + .rx_lfc_en(rx_lfc_en[n +: 1]), + .rx_lfc_req(rx_lfc_req[n +: 1]), + .rx_lfc_ack(rx_lfc_ack[n +: 1]), + .rx_pfc_en(rx_pfc_en[n*8 +: 8]), + .rx_pfc_req(rx_pfc_req[n*8 +: 8]), + .rx_pfc_ack(rx_pfc_ack[n*8 +: 8]), + .rx_fc_quanta_clk_en(rx_fc_quanta_clk_en[n +: 1]) ); end diff --git a/fpga/common/rtl/mqnic_l2_egress.v b/fpga/common/rtl/mqnic_l2_egress.v index dc9fc74fb..3e24ff265 100644 --- a/fpga/common/rtl/mqnic_l2_egress.v +++ b/fpga/common/rtl/mqnic_l2_egress.v @@ -14,11 +14,14 @@ */ module mqnic_l2_egress # ( - // Width of AXI stream interfaces in bits + // Interface configuration + parameter PFC_ENABLE = 0, + parameter LFC_ENABLE = PFC_ENABLE, + parameter MAC_CTRL_ENABLE = 0, + + // Streaming interface configuration parameter AXIS_DATA_WIDTH = 256, - // AXI stream tkeep signal width (words per cycle) parameter AXIS_KEEP_WIDTH = AXIS_DATA_WIDTH/8, - // AXI stream tuser signal width parameter AXIS_USER_WIDTH = 1 ) ( @@ -43,16 +46,173 @@ module mqnic_l2_egress # output wire m_axis_tvalid, input wire m_axis_tready, output wire m_axis_tlast, - output wire [AXIS_USER_WIDTH-1:0] m_axis_tuser + output wire [AXIS_USER_WIDTH-1:0] m_axis_tuser, + + /* + * Flow control + */ + input wire tx_lfc_en, + input wire tx_lfc_req, + input wire [7:0] tx_pfc_en, + input wire [7:0] tx_pfc_req, + input wire tx_pause_req, + output wire tx_pause_ack, + input wire [9:0] tx_fc_quanta_step, + input wire tx_fc_quanta_clk_en ); -// placeholder -assign m_axis_tdata = s_axis_tdata; -assign m_axis_tkeep = s_axis_tkeep; -assign m_axis_tvalid = s_axis_tvalid; -assign s_axis_tready = m_axis_tready; -assign m_axis_tlast = s_axis_tlast; -assign m_axis_tuser = s_axis_tuser; +if ((LFC_ENABLE || PFC_ENABLE) && MAC_CTRL_ENABLE) begin : mac_ctrl + + localparam MCF_PARAMS_SIZE = PFC_ENABLE ? 18 : 2; + + wire tx_mcf_valid; + wire tx_mcf_ready; + wire [47:0] tx_mcf_eth_dst; + wire [47:0] tx_mcf_eth_src; + wire [15:0] tx_mcf_eth_type; + wire [15:0] tx_mcf_opcode; + wire [MCF_PARAMS_SIZE*8-1:0] tx_mcf_params; + + mac_ctrl_tx #( + .DATA_WIDTH(AXIS_DATA_WIDTH), + .KEEP_ENABLE(AXIS_KEEP_WIDTH > 1), + .KEEP_WIDTH(AXIS_KEEP_WIDTH), + .ID_ENABLE(0), + .DEST_ENABLE(0), + .USER_ENABLE(1), + .USER_WIDTH(AXIS_USER_WIDTH), + .MCF_PARAMS_SIZE(MCF_PARAMS_SIZE) + ) + mac_ctrl_tx_inst ( + .clk(clk), + .rst(rst), + + /* + * AXI stream input + */ + .s_axis_tdata(s_axis_tdata), + .s_axis_tkeep(s_axis_tkeep), + .s_axis_tvalid(s_axis_tvalid), + .s_axis_tready(s_axis_tready), + .s_axis_tlast(s_axis_tlast), + .s_axis_tid(0), + .s_axis_tdest(0), + .s_axis_tuser(s_axis_tuser), + + /* + * AXI stream output + */ + .m_axis_tdata(m_axis_tdata), + .m_axis_tkeep(m_axis_tkeep), + .m_axis_tvalid(m_axis_tvalid), + .m_axis_tready(m_axis_tready), + .m_axis_tlast(m_axis_tlast), + .m_axis_tid(), + .m_axis_tdest(), + .m_axis_tuser(m_axis_tuser), + + /* + * MAC control frame interface + */ + .mcf_valid(tx_mcf_valid), + .mcf_ready(tx_mcf_ready), + .mcf_eth_dst(tx_mcf_eth_dst), + .mcf_eth_src(tx_mcf_eth_src), + .mcf_eth_type(tx_mcf_eth_type), + .mcf_opcode(tx_mcf_opcode), + .mcf_params(tx_mcf_params), + .mcf_id(0), + .mcf_dest(0), + .mcf_user(0), + + /* + * Pause interface + */ + .tx_pause_req(tx_pause_req), + .tx_pause_ack(tx_pause_ack), + + /* + * Status + */ + .stat_tx_mcf() + ); + + mac_pause_ctrl_tx #( + .MCF_PARAMS_SIZE(MCF_PARAMS_SIZE), + .PFC_ENABLE(PFC_ENABLE) + ) + mac_pause_ctrl_tx_inst ( + .clk(clk), + .rst(rst), + + /* + * MAC control frame interface + */ + .mcf_valid(tx_mcf_valid), + .mcf_ready(tx_mcf_ready), + .mcf_eth_dst(tx_mcf_eth_dst), + .mcf_eth_src(tx_mcf_eth_src), + .mcf_eth_type(tx_mcf_eth_type), + .mcf_opcode(tx_mcf_opcode), + .mcf_params(tx_mcf_params), + + /* + * Pause (IEEE 802.3 annex 31B) + */ + .tx_lfc_req(tx_lfc_req), + .tx_lfc_resend(1'b0), + + /* + * Priority Flow Control (PFC) (IEEE 802.3 annex 31D) + */ + .tx_pfc_req(tx_pfc_req), + .tx_pfc_resend(1'b0), + + /* + * Configuration + */ + .cfg_tx_lfc_eth_dst(48'h01_80_C2_00_00_01), + .cfg_tx_lfc_eth_src(48'h80_23_31_43_54_4C), + .cfg_tx_lfc_eth_type(16'h8808), + .cfg_tx_lfc_opcode(16'h0001), + .cfg_tx_lfc_en(tx_lfc_en), + .cfg_tx_lfc_quanta(16'hffff), + .cfg_tx_lfc_refresh(16'h7fff), + .cfg_tx_pfc_eth_dst(48'h01_80_C2_00_00_01), + .cfg_tx_pfc_eth_src(48'h80_23_31_43_54_4C), + .cfg_tx_pfc_eth_type(16'h8808), + .cfg_tx_pfc_opcode(16'h0101), + .cfg_tx_pfc_en(tx_pfc_en), + .cfg_tx_pfc_quanta({8{16'hffff}}), + .cfg_tx_pfc_refresh({8{16'h7fff}}), + .cfg_quanta_step(tx_fc_quanta_step), + .cfg_quanta_clk_en(tx_fc_quanta_clk_en), + + /* + * Status + */ + .stat_tx_lfc_pkt(), + .stat_tx_lfc_xon(), + .stat_tx_lfc_xoff(), + .stat_tx_lfc_paused(), + .stat_tx_pfc_pkt(), + .stat_tx_pfc_xon(), + .stat_tx_pfc_xoff(), + .stat_tx_pfc_paused() + ); + +end else begin + + assign m_axis_tdata = s_axis_tdata; + assign m_axis_tkeep = s_axis_tkeep; + assign m_axis_tvalid = s_axis_tvalid; + assign s_axis_tready = m_axis_tready; + assign m_axis_tlast = s_axis_tlast; + assign m_axis_tuser = s_axis_tuser; + + assign tx_pause_ack = 1'b0; + +end endmodule diff --git a/fpga/common/rtl/mqnic_l2_ingress.v b/fpga/common/rtl/mqnic_l2_ingress.v index 2190bb974..4b2f33dab 100644 --- a/fpga/common/rtl/mqnic_l2_ingress.v +++ b/fpga/common/rtl/mqnic_l2_ingress.v @@ -14,47 +14,208 @@ */ module mqnic_l2_ingress # ( - // Width of AXI stream interfaces in bits + // Interface configuration + parameter PFC_ENABLE = 0, + parameter LFC_ENABLE = PFC_ENABLE, + parameter MAC_CTRL_ENABLE = 0, + + // Streaming interface configuration parameter AXIS_DATA_WIDTH = 256, - // AXI stream tkeep signal width (words per cycle) parameter AXIS_KEEP_WIDTH = AXIS_DATA_WIDTH/8, - // AXI stream tuser signal width parameter AXIS_USER_WIDTH = 1, - // Can apply backpressure with tready parameter AXIS_USE_READY = 0 ) ( - input wire clk, - input wire rst, + input wire clk, + input wire rst, /* * Receive data input */ - input wire [AXIS_DATA_WIDTH-1:0] s_axis_tdata, - input wire [AXIS_KEEP_WIDTH-1:0] s_axis_tkeep, - input wire s_axis_tvalid, - output wire s_axis_tready, - input wire s_axis_tlast, - input wire [AXIS_USER_WIDTH-1:0] s_axis_tuser, + input wire [AXIS_DATA_WIDTH-1:0] s_axis_tdata, + input wire [AXIS_KEEP_WIDTH-1:0] s_axis_tkeep, + input wire s_axis_tvalid, + output wire s_axis_tready, + input wire s_axis_tlast, + input wire [AXIS_USER_WIDTH-1:0] s_axis_tuser, /* * Receive data output */ - output wire [AXIS_DATA_WIDTH-1:0] m_axis_tdata, - output wire [AXIS_KEEP_WIDTH-1:0] m_axis_tkeep, - output wire m_axis_tvalid, - input wire m_axis_tready, - output wire m_axis_tlast, - output wire [AXIS_USER_WIDTH-1:0] m_axis_tuser + output wire [AXIS_DATA_WIDTH-1:0] m_axis_tdata, + output wire [AXIS_KEEP_WIDTH-1:0] m_axis_tkeep, + output wire m_axis_tvalid, + input wire m_axis_tready, + output wire m_axis_tlast, + output wire [AXIS_USER_WIDTH-1:0] m_axis_tuser, + + /* + * Flow control + */ + input wire rx_lfc_en, + output wire rx_lfc_req, + input wire rx_lfc_ack, + input wire [7:0] rx_pfc_en, + output wire [7:0] rx_pfc_req, + input wire [7:0] rx_pfc_ack, + input wire [9:0] rx_fc_quanta_step, + input wire rx_fc_quanta_clk_en ); -// placeholder -assign m_axis_tdata = s_axis_tdata; -assign m_axis_tkeep = s_axis_tkeep; -assign m_axis_tvalid = s_axis_tvalid; -assign s_axis_tready = m_axis_tready; -assign m_axis_tlast = s_axis_tlast; -assign m_axis_tuser = s_axis_tuser; +if ((LFC_ENABLE || PFC_ENABLE) && MAC_CTRL_ENABLE) begin : mac_ctrl + + localparam MCF_PARAMS_SIZE = PFC_ENABLE ? 18 : 2; + + wire rx_mcf_valid; + wire [47:0] rx_mcf_eth_dst; + wire [47:0] rx_mcf_eth_src; + wire [15:0] rx_mcf_eth_type; + wire [15:0] rx_mcf_opcode; + wire [MCF_PARAMS_SIZE*8-1:0] rx_mcf_params; + + mac_ctrl_rx #( + .DATA_WIDTH(AXIS_DATA_WIDTH), + .KEEP_ENABLE(AXIS_KEEP_WIDTH > 1), + .KEEP_WIDTH(AXIS_KEEP_WIDTH), + .ID_ENABLE(0), + .DEST_ENABLE(0), + .USER_ENABLE(1), + .USER_WIDTH(AXIS_USER_WIDTH), + .USE_READY(AXIS_USE_READY), + .MCF_PARAMS_SIZE(MCF_PARAMS_SIZE) + ) + mac_ctrl_rx_inst ( + .clk(clk), + .rst(rst), + + /* + * AXI stream input + */ + .s_axis_tdata(s_axis_tdata), + .s_axis_tkeep(s_axis_tkeep), + .s_axis_tvalid(s_axis_tvalid), + .s_axis_tready(s_axis_tready), + .s_axis_tlast(s_axis_tlast), + .s_axis_tid(0), + .s_axis_tdest(0), + .s_axis_tuser(s_axis_tuser), + + /* + * AXI stream output + */ + .m_axis_tdata(m_axis_tdata), + .m_axis_tkeep(m_axis_tkeep), + .m_axis_tvalid(m_axis_tvalid), + .m_axis_tready(m_axis_tready), + .m_axis_tlast(m_axis_tlast), + .m_axis_tid(), + .m_axis_tdest(), + .m_axis_tuser(m_axis_tuser), + + /* + * MAC control frame interface + */ + .mcf_valid(rx_mcf_valid), + .mcf_eth_dst(rx_mcf_eth_dst), + .mcf_eth_src(rx_mcf_eth_src), + .mcf_eth_type(rx_mcf_eth_type), + .mcf_opcode(rx_mcf_opcode), + .mcf_params(rx_mcf_params), + .mcf_id(), + .mcf_dest(), + .mcf_user(), + + /* + * Configuration + */ + .cfg_mcf_rx_eth_dst_mcast(48'h01_80_C2_00_00_01), + .cfg_mcf_rx_check_eth_dst_mcast(1'b1), + .cfg_mcf_rx_eth_dst_ucast(48'd0), + .cfg_mcf_rx_check_eth_dst_ucast(1'b0), + .cfg_mcf_rx_eth_src(48'd0), + .cfg_mcf_rx_check_eth_src(1'b0), + .cfg_mcf_rx_eth_type(16'h8808), + .cfg_mcf_rx_opcode_lfc(16'h0001), + .cfg_mcf_rx_check_opcode_lfc(rx_lfc_en), + .cfg_mcf_rx_opcode_pfc(16'h0101), + .cfg_mcf_rx_check_opcode_pfc(rx_pfc_en != 0), + .cfg_mcf_rx_forward(1'b0), + .cfg_mcf_rx_enable(rx_lfc_en || rx_pfc_en), + + /* + * Status + */ + .stat_rx_mcf() + ); + + mac_pause_ctrl_rx #( + .MCF_PARAMS_SIZE(18), + .PFC_ENABLE(PFC_ENABLE) + ) + mac_pause_ctrl_rx_inst ( + .clk(clk), + .rst(rst), + + /* + * MAC control frame interface + */ + .mcf_valid(rx_mcf_valid), + .mcf_eth_dst(rx_mcf_eth_dst), + .mcf_eth_src(rx_mcf_eth_src), + .mcf_eth_type(rx_mcf_eth_type), + .mcf_opcode(rx_mcf_opcode), + .mcf_params(rx_mcf_params), + + /* + * Pause (IEEE 802.3 annex 31B) + */ + .rx_lfc_en(rx_lfc_en), + .rx_lfc_req(rx_lfc_req), + .rx_lfc_ack(rx_lfc_ack), + + /* + * Priority Flow Control (PFC) (IEEE 802.3 annex 31D) + */ + .rx_pfc_en(rx_pfc_en), + .rx_pfc_req(rx_pfc_req), + .rx_pfc_ack(rx_pfc_ack), + + /* + * Configuration + */ + .cfg_rx_lfc_opcode(16'h0001), + .cfg_rx_lfc_en(rx_lfc_en), + .cfg_rx_pfc_opcode(16'h0101), + .cfg_rx_pfc_en(rx_pfc_en), + .cfg_quanta_step(rx_fc_quanta_step), + .cfg_quanta_clk_en(rx_fc_quanta_clk_en), + + /* + * Status + */ + .stat_rx_lfc_pkt(), + .stat_rx_lfc_xon(), + .stat_rx_lfc_xoff(), + .stat_rx_lfc_paused(), + .stat_rx_pfc_pkt(), + .stat_rx_pfc_xon(), + .stat_rx_pfc_xoff(), + .stat_rx_pfc_paused() + ); + +end else begin + + assign m_axis_tdata = s_axis_tdata; + assign m_axis_tkeep = s_axis_tkeep; + assign m_axis_tvalid = s_axis_tvalid; + assign s_axis_tready = m_axis_tready; + assign m_axis_tlast = s_axis_tlast; + assign m_axis_tuser = s_axis_tuser; + + assign rx_lfc_req = 1'b0; + assign rx_pfc_req = 8'd0; + +end endmodule diff --git a/fpga/common/rtl/mqnic_port.v b/fpga/common/rtl/mqnic_port.v index be5c244c2..f54a461a4 100644 --- a/fpga/common/rtl/mqnic_port.v +++ b/fpga/common/rtl/mqnic_port.v @@ -22,6 +22,9 @@ module mqnic_port # parameter TX_CPL_ENABLE = 1, parameter TX_CPL_FIFO_DEPTH = 32, parameter TX_TAG_WIDTH = 16, + parameter PFC_ENABLE = 1, + parameter LFC_ENABLE = PFC_ENABLE, + parameter MAC_CTRL_ENABLE = 0, parameter MAX_TX_SIZE = 9214, parameter MAX_RX_SIZE = 9214, @@ -196,7 +199,13 @@ module mqnic_port # input wire s_axis_tx_cpl_valid, output wire s_axis_tx_cpl_ready, + output wire tx_enable, input wire tx_status, + output wire tx_lfc_en, + output wire tx_lfc_req, + output wire [7:0] tx_pfc_en, + output wire [7:0] tx_pfc_req, + input wire tx_fc_quanta_clk_en, /* * Receive data input @@ -211,7 +220,15 @@ module mqnic_port # input wire s_axis_rx_tlast, input wire [AXIS_RX_USER_WIDTH-1:0] s_axis_rx_tuser, - input wire rx_status + output wire rx_enable, + input wire rx_status, + output wire rx_lfc_en, + input wire rx_lfc_req, + output wire rx_lfc_ack, + output wire [7:0] rx_pfc_en, + input wire [7:0] rx_pfc_req, + output wire [7:0] rx_pfc_ack, + input wire rx_fc_quanta_clk_en ); localparam RBB = RB_BASE_ADDR & {REG_ADDR_WIDTH{1'b1}}; @@ -239,6 +256,52 @@ initial begin end end +wire rx_lfc_req_int; +wire [7:0] rx_pfc_req_int; + +// TX control +reg tx_enable_reg = 1'b0; +reg tx_pause_reg = 1'b0; +reg tx_lfc_en_reg = 1'b0; +reg tx_lfc_req_reg = 1'b0; +reg [7:0] tx_pfc_en_reg = 8'd0; +reg [7:0] tx_pfc_req_reg = 8'd0; +reg [9:0] tx_fc_quanta_step_reg = (AXIS_DATA_WIDTH*256)/512; + +reg tx_enable_sync_1_reg = 1'b0; +reg tx_enable_sync_2_reg = 1'b0; +reg tx_lfc_en_sync_1_reg = 1'b0; +reg tx_lfc_en_sync_2_reg = 1'b0; +reg tx_lfc_req_sync_1_reg = 1'b0; +reg tx_lfc_req_sync_2_reg = 1'b0; +reg [7:0] tx_pfc_en_sync_1_reg = 8'd0; +reg [7:0] tx_pfc_en_sync_2_reg = 8'd0; +reg [7:0] tx_pfc_req_sync_1_reg = 8'd0; +reg [7:0] tx_pfc_req_sync_2_reg = 8'd0; +reg [9:0] tx_fc_quanta_step_sync_1_reg = 10'd0; +reg [9:0] tx_fc_quanta_step_sync_2_reg = 10'd0; + +assign tx_enable = tx_enable_sync_2_reg; +assign tx_lfc_en = LFC_ENABLE ? tx_lfc_en_sync_2_reg : 1'b0; +assign tx_lfc_req = LFC_ENABLE ? tx_lfc_req_sync_2_reg : 1'b0; +assign tx_pfc_en = PFC_ENABLE ? tx_pfc_en_sync_2_reg : 8'd0; +assign tx_pfc_req = PFC_ENABLE ? tx_pfc_req_sync_2_reg : 8'd0; + +always @(posedge tx_clk) begin + tx_enable_sync_1_reg <= tx_enable_reg; + tx_enable_sync_2_reg <= tx_enable_sync_1_reg; + tx_lfc_en_sync_1_reg <= tx_lfc_en_reg; + tx_lfc_en_sync_2_reg <= tx_lfc_en_sync_1_reg; + tx_lfc_req_sync_1_reg <= tx_lfc_req_reg; + tx_lfc_req_sync_2_reg <= tx_lfc_req_sync_1_reg; + tx_pfc_en_sync_1_reg <= tx_pfc_en_reg; + tx_pfc_en_sync_2_reg <= tx_pfc_en_sync_1_reg; + tx_pfc_req_sync_1_reg <= tx_pfc_req_reg; + tx_pfc_req_sync_2_reg <= tx_pfc_req_sync_1_reg; + tx_fc_quanta_step_sync_1_reg <= tx_fc_quanta_step_reg; + tx_fc_quanta_step_sync_2_reg <= tx_fc_quanta_step_sync_1_reg; +end + // TX status reg tx_rst_sync_1_reg = 1'b0; reg tx_rst_sync_2_reg = 1'b0; @@ -264,6 +327,49 @@ always @(posedge clk) begin tx_status_sync_3_reg <= tx_status_sync_2_reg; end +// RX control +reg rx_enable_reg = 1'b0; +reg rx_pause_reg = 1'b0; +reg rx_lfc_en_reg = 1'b0; +reg rx_lfc_ack_reg = 1'b0; +reg [7:0] rx_pfc_en_reg = 8'd0; +reg [7:0] rx_pfc_ack_reg = 8'd0; +reg [9:0] rx_fc_quanta_step_reg = (AXIS_DATA_WIDTH*256)/512; + +reg rx_enable_sync_1_reg = 1'b0; +reg rx_enable_sync_2_reg = 1'b0; +reg rx_lfc_en_sync_1_reg = 1'b0; +reg rx_lfc_en_sync_2_reg = 1'b0; +reg rx_lfc_ack_sync_1_reg = 1'b0; +reg rx_lfc_ack_sync_2_reg = 1'b0; +reg [7:0] rx_pfc_en_sync_1_reg = 8'd0; +reg [7:0] rx_pfc_en_sync_2_reg = 8'd0; +reg [7:0] rx_pfc_ack_sync_1_reg = 8'd0; +reg [7:0] rx_pfc_ack_sync_2_reg = 8'd0; +reg [9:0] rx_fc_quanta_step_sync_1_reg = 10'd0; +reg [9:0] rx_fc_quanta_step_sync_2_reg = 10'd0; + +assign rx_enable = rx_enable_sync_2_reg; +assign rx_lfc_en = LFC_ENABLE ? rx_lfc_en_sync_2_reg : 1'b0; +assign rx_lfc_ack = LFC_ENABLE ? rx_lfc_ack_sync_2_reg : 1'b0; +assign rx_pfc_en = PFC_ENABLE ? rx_pfc_en_sync_2_reg : 8'd0; +assign rx_pfc_ack = PFC_ENABLE ? rx_pfc_ack_sync_2_reg : 8'd0; + +always @(posedge rx_clk) begin + rx_enable_sync_1_reg <= rx_enable_reg; + rx_enable_sync_2_reg <= rx_enable_sync_1_reg; + rx_lfc_en_sync_1_reg <= rx_lfc_en_reg; + rx_lfc_en_sync_2_reg <= rx_lfc_en_sync_1_reg; + rx_lfc_ack_sync_1_reg <= rx_lfc_ack_reg; + rx_lfc_ack_sync_2_reg <= rx_lfc_ack_sync_1_reg; + rx_pfc_en_sync_1_reg <= rx_pfc_en_reg; + rx_pfc_en_sync_2_reg <= rx_pfc_en_sync_1_reg; + rx_pfc_ack_sync_1_reg <= rx_pfc_ack_reg; + rx_pfc_ack_sync_2_reg <= rx_pfc_ack_sync_1_reg; + rx_fc_quanta_step_sync_1_reg <= rx_fc_quanta_step_reg; + rx_fc_quanta_step_sync_2_reg <= rx_fc_quanta_step_sync_1_reg; +end + // RX status reg rx_rst_sync_1_reg = 1'b0; reg rx_rst_sync_2_reg = 1'b0; @@ -271,14 +377,24 @@ reg rx_rst_sync_3_reg = 1'b0; reg rx_status_sync_1_reg = 1'b0; reg rx_status_sync_2_reg = 1'b0; reg rx_status_sync_3_reg = 1'b0; +reg rx_lfc_req_sync_1_reg = 1'b0; +reg rx_lfc_req_sync_2_reg = 1'b0; +reg rx_lfc_req_sync_3_reg = 1'b0; +reg [7:0] rx_pfc_req_sync_1_reg = 8'd0; +reg [7:0] rx_pfc_req_sync_2_reg = 8'd0; +reg [7:0] rx_pfc_req_sync_3_reg = 8'd0; always @(posedge rx_clk or posedge rx_rst) begin if (rx_rst) begin rx_rst_sync_1_reg <= 1'b1; rx_status_sync_1_reg <= 1'b0; + rx_lfc_req_sync_1_reg <= 1'b0; + rx_pfc_req_sync_1_reg <= 8'd0; end else begin rx_rst_sync_1_reg <= 1'b0; rx_status_sync_1_reg <= rx_status; + rx_lfc_req_sync_1_reg <= MAC_CTRL_ENABLE ? rx_lfc_req_int : rx_lfc_req; + rx_pfc_req_sync_1_reg <= MAC_CTRL_ENABLE ? rx_pfc_req_int : rx_pfc_req; end end @@ -287,6 +403,10 @@ always @(posedge clk) begin rx_rst_sync_3_reg <= rx_rst_sync_2_reg; rx_status_sync_2_reg <= rx_status_sync_1_reg; rx_status_sync_3_reg <= rx_status_sync_2_reg; + rx_lfc_req_sync_2_reg <= rx_lfc_req_sync_1_reg; + rx_lfc_req_sync_3_reg <= rx_lfc_req_sync_2_reg; + rx_pfc_req_sync_2_reg <= rx_pfc_req_sync_1_reg; + rx_pfc_req_sync_3_reg <= rx_pfc_req_sync_2_reg; end // control registers @@ -294,24 +414,76 @@ reg ctrl_reg_wr_ack_reg = 1'b0; reg [REG_DATA_WIDTH-1:0] ctrl_reg_rd_data_reg = {REG_DATA_WIDTH{1'b0}}; reg ctrl_reg_rd_ack_reg = 1'b0; +wire tx_pause_status; +wire rx_pause_status; + +wire tx_fifo_pause_req = !tx_enable_reg || tx_pause_reg || (LFC_ENABLE && rx_lfc_en_reg && rx_lfc_req_sync_3_reg); +wire tx_fifo_pause_ack; +wire rx_fifo_pause_req = !rx_enable_reg || rx_pause_reg; +wire rx_fifo_pause_ack; + assign ctrl_reg_wr_wait = 1'b0; assign ctrl_reg_wr_ack = ctrl_reg_wr_ack_reg; assign ctrl_reg_rd_data = ctrl_reg_rd_data_reg; assign ctrl_reg_rd_wait = 1'b0; assign ctrl_reg_rd_ack = ctrl_reg_rd_ack_reg; +integer i; + always @(posedge clk) begin ctrl_reg_wr_ack_reg <= 1'b0; ctrl_reg_rd_data_reg <= {REG_DATA_WIDTH{1'b0}}; ctrl_reg_rd_ack_reg <= 1'b0; + tx_lfc_req_reg <= 1'b0; + tx_pfc_req_reg <= 8'd0; + + rx_lfc_ack_reg <= tx_fifo_pause_ack; + rx_pfc_ack_reg <= 8'd0; + if (ctrl_reg_wr_en && !ctrl_reg_wr_ack_reg) begin // write operation ctrl_reg_wr_ack_reg <= 1'b1; case ({ctrl_reg_wr_addr >> 2, 2'b00}) // Port control + RBB+8'h20: begin + // Port ctrl: TX control/status + tx_enable_reg <= ctrl_reg_wr_data[0]; + tx_pause_reg <= ctrl_reg_wr_data[8]; + end + RBB+8'h24: begin + // Port ctrl: RX control/status + rx_enable_reg <= ctrl_reg_wr_data[0]; + rx_pause_reg <= ctrl_reg_wr_data[8]; + end default: ctrl_reg_wr_ack_reg <= 1'b0; endcase + if (MAC_CTRL_ENABLE) begin + if ({ctrl_reg_wr_addr >> 2, 2'b00} == RBB+8'h28) begin + // Port ctrl: FC control + tx_fc_quanta_step_reg <= ctrl_reg_wr_data[15:0]; + rx_fc_quanta_step_reg <= ctrl_reg_wr_data[31:16]; + ctrl_reg_wr_ack_reg <= 1'b1; + end + end + if (LFC_ENABLE) begin + if ({ctrl_reg_wr_addr >> 2, 2'b00} == RBB+8'h2C) begin + // Port ctrl: LFC control + tx_lfc_en_reg <= ctrl_reg_wr_data[24]; + rx_lfc_en_reg <= ctrl_reg_wr_data[25]; + ctrl_reg_wr_ack_reg <= 1'b1; + end + end + if (PFC_ENABLE) begin + for (i = 0; i < 8; i = i + 1) begin + if ({ctrl_reg_wr_addr >> 2, 2'b00} == RBB+8'h30+i*4) begin + // Port ctrl: PFC control N + tx_pfc_en_reg[i] <= ctrl_reg_wr_data[24]; + rx_pfc_en_reg[i] <= ctrl_reg_wr_data[25]; + ctrl_reg_wr_ack_reg <= 1'b1; + end + end + end end if (ctrl_reg_rd_en && !ctrl_reg_rd_ack_reg) begin @@ -325,28 +497,85 @@ always @(posedge clk) begin RBB+8'h0C: ctrl_reg_rd_data_reg <= RB_BASE_ADDR+8'h10; // Port: Offset // Port control RBB+8'h10: ctrl_reg_rd_data_reg <= 32'h0000C003; // Port ctrl: Type - RBB+8'h14: ctrl_reg_rd_data_reg <= 32'h00000200; // Port ctrl: Version + RBB+8'h14: ctrl_reg_rd_data_reg <= 32'h00000300; // Port ctrl: Version RBB+8'h18: ctrl_reg_rd_data_reg <= 0; // Port ctrl: Next header RBB+8'h1C: begin // Port ctrl: features + ctrl_reg_rd_data_reg[0] <= LFC_ENABLE; + ctrl_reg_rd_data_reg[1] <= PFC_ENABLE; + ctrl_reg_rd_data_reg[2] <= MAC_CTRL_ENABLE; end RBB+8'h20: begin - // Port ctrl: TX status - ctrl_reg_rd_data_reg[0] <= tx_status_sync_3_reg; - ctrl_reg_rd_data_reg[1] <= tx_rst_sync_3_reg; + // Port ctrl: TX control/status + ctrl_reg_rd_data_reg[0] <= tx_enable_reg; + ctrl_reg_rd_data_reg[8] <= tx_pause_reg; + ctrl_reg_rd_data_reg[16] <= tx_status_sync_3_reg; + ctrl_reg_rd_data_reg[17] <= tx_rst_sync_3_reg; + ctrl_reg_rd_data_reg[24] <= tx_fifo_pause_req; + ctrl_reg_rd_data_reg[25] <= tx_fifo_pause_ack; end RBB+8'h24: begin - // Port ctrl: RX status - ctrl_reg_rd_data_reg[0] <= rx_status_sync_3_reg; - ctrl_reg_rd_data_reg[1] <= rx_rst_sync_3_reg; + // Port ctrl: RX control/status + ctrl_reg_rd_data_reg[0] <= rx_enable_reg; + ctrl_reg_rd_data_reg[8] <= rx_pause_reg; + ctrl_reg_rd_data_reg[16] <= rx_status_sync_3_reg; + ctrl_reg_rd_data_reg[17] <= rx_rst_sync_3_reg; + ctrl_reg_rd_data_reg[24] <= rx_fifo_pause_req; + ctrl_reg_rd_data_reg[25] <= rx_fifo_pause_ack; end default: ctrl_reg_rd_ack_reg <= 1'b0; endcase + if (MAC_CTRL_ENABLE) begin + if ({ctrl_reg_rd_addr >> 2, 2'b00} == RBB+8'h28) begin + // Port ctrl: FC control + ctrl_reg_rd_data_reg[15:0] <= tx_fc_quanta_step_reg; + ctrl_reg_rd_data_reg[31:16] <= rx_fc_quanta_step_reg; + ctrl_reg_rd_ack_reg <= 1'b1; + end + end + if (LFC_ENABLE) begin + if ({ctrl_reg_rd_addr >> 2, 2'b00} == RBB+8'h2C) begin + // Port ctrl: LFC control + ctrl_reg_rd_data_reg[24] <= tx_lfc_en_reg; + ctrl_reg_rd_data_reg[25] <= rx_lfc_en_reg; + ctrl_reg_rd_data_reg[28] <= tx_lfc_req_reg; + ctrl_reg_rd_data_reg[29] <= rx_lfc_req_sync_3_reg; + ctrl_reg_rd_ack_reg <= 1'b1; + end + end + if (PFC_ENABLE) begin + for (i = 0; i < 8; i = i + 1) begin + if ({ctrl_reg_rd_addr >> 2, 2'b00} == RBB+8'h30+i*4) begin + // Port ctrl: PFC control N + ctrl_reg_rd_data_reg[24] <= tx_pfc_en_reg[i]; + ctrl_reg_rd_data_reg[25] <= rx_pfc_en_reg[i]; + ctrl_reg_rd_data_reg[28] <= tx_pfc_req_reg[i]; + ctrl_reg_rd_data_reg[29] <= rx_pfc_req_sync_3_reg[i]; + ctrl_reg_rd_ack_reg <= 1'b1; + end + end + end end if (rst) begin ctrl_reg_wr_ack_reg <= 1'b0; ctrl_reg_rd_ack_reg <= 1'b0; + + tx_enable_reg <= 1'b0; + tx_pause_reg <= 1'b0; + tx_lfc_en_reg <= 1'b0; + tx_lfc_req_reg <= 1'b0; + tx_pfc_en_reg <= 8'd0; + tx_pfc_req_reg <= 8'd0; + tx_fc_quanta_step_reg <= (AXIS_DATA_WIDTH*256)/512; + + rx_enable_reg <= 1'b0; + rx_pause_reg <= 1'b0; + rx_lfc_en_reg <= 1'b0; + rx_lfc_ack_reg <= 1'b0; + rx_pfc_en_reg <= 8'd0; + rx_pfc_ack_reg <= 8'd0; + rx_fc_quanta_step_reg <= (AXIS_DATA_WIDTH*256)/512; end end @@ -359,6 +588,9 @@ mqnic_port_tx #( .TX_CPL_ENABLE(TX_CPL_ENABLE), .TX_CPL_FIFO_DEPTH(TX_CPL_FIFO_DEPTH), .TX_TAG_WIDTH(TX_TAG_WIDTH), + .PFC_ENABLE(PFC_ENABLE), + .LFC_ENABLE(LFC_ENABLE), + .MAC_CTRL_ENABLE(MAC_CTRL_ENABLE), .MAX_TX_SIZE(MAX_TX_SIZE), // Application block configuration @@ -465,7 +697,21 @@ port_tx_inst ( .s_axis_tx_cpl_ts(s_axis_tx_cpl_ts), .s_axis_tx_cpl_tag(s_axis_tx_cpl_tag), .s_axis_tx_cpl_valid(s_axis_tx_cpl_valid), - .s_axis_tx_cpl_ready(s_axis_tx_cpl_ready) + .s_axis_tx_cpl_ready(s_axis_tx_cpl_ready), + + /* + * Flow control + */ + .tx_lfc_en(tx_lfc_en), + .tx_lfc_req(tx_lfc_req), + .tx_pfc_en(tx_pfc_en), + .tx_pfc_req(tx_pfc_req), + .tx_pause_req(1'b0), + .tx_pause_ack(), + .tx_fc_quanta_step(tx_fc_quanta_step_reg), + .tx_fc_quanta_clk_en(tx_fc_quanta_clk_en), + .fifo_pause_req(tx_fifo_pause_req), + .fifo_pause_ack(tx_fifo_pause_ack) ); mqnic_port_rx #( @@ -474,6 +720,9 @@ mqnic_port_rx #( // Interface configuration .PTP_TS_ENABLE(PTP_TS_ENABLE), + .PFC_ENABLE(PFC_ENABLE), + .LFC_ENABLE(LFC_ENABLE), + .MAC_CTRL_ENABLE(MAC_CTRL_ENABLE), .MAX_RX_SIZE(MAX_RX_SIZE), // Application block configuration @@ -550,7 +799,21 @@ port_rx_inst ( .s_axis_rx_tvalid(s_axis_rx_tvalid), .s_axis_rx_tready(s_axis_rx_tready), .s_axis_rx_tlast(s_axis_rx_tlast), - .s_axis_rx_tuser(s_axis_rx_tuser) + .s_axis_rx_tuser(s_axis_rx_tuser), + + /* + * Flow control + */ + .rx_lfc_en(rx_lfc_en), + .rx_lfc_req(rx_lfc_req_int), + .rx_lfc_ack(rx_lfc_ack), + .rx_pfc_en(rx_pfc_en), + .rx_pfc_req(rx_pfc_req_int), + .rx_pfc_ack(rx_pfc_ack), + .rx_fc_quanta_step(rx_fc_quanta_step_reg), + .rx_fc_quanta_clk_en(rx_fc_quanta_clk_en), + .fifo_pause_req(rx_fifo_pause_req), + .fifo_pause_ack(rx_fifo_pause_ack) ); endmodule diff --git a/fpga/common/rtl/mqnic_port_map_mac_axis.v b/fpga/common/rtl/mqnic_port_map_mac_axis.v index c80928bf1..0696ef201 100644 --- a/fpga/common/rtl/mqnic_port_map_mac_axis.v +++ b/fpga/common/rtl/mqnic_port_map_mac_axis.v @@ -52,7 +52,12 @@ module mqnic_port_map_mac_axis # input wire [MAC_COUNT-1:0] s_axis_mac_tx_ptp_ts_valid, output wire [MAC_COUNT-1:0] s_axis_mac_tx_ptp_ts_ready, + output wire [MAC_COUNT-1:0] mac_tx_enable, input wire [MAC_COUNT-1:0] mac_tx_status, + output wire [MAC_COUNT-1:0] mac_tx_lfc_en, + output wire [MAC_COUNT-1:0] mac_tx_lfc_req, + output wire [MAC_COUNT*8-1:0] mac_tx_pfc_en, + output wire [MAC_COUNT*8-1:0] mac_tx_pfc_req, input wire [MAC_COUNT-1:0] mac_rx_clk, input wire [MAC_COUNT-1:0] mac_rx_rst, @@ -69,7 +74,14 @@ module mqnic_port_map_mac_axis # input wire [MAC_COUNT-1:0] s_axis_mac_rx_tlast, input wire [MAC_COUNT*AXIS_RX_USER_WIDTH-1:0] s_axis_mac_rx_tuser, + output wire [MAC_COUNT-1:0] mac_rx_enable, input wire [MAC_COUNT-1:0] mac_rx_status, + output wire [MAC_COUNT-1:0] mac_rx_lfc_en, + input wire [MAC_COUNT-1:0] mac_rx_lfc_req, + output wire [MAC_COUNT-1:0] mac_rx_lfc_ack, + output wire [MAC_COUNT*8-1:0] mac_rx_pfc_en, + input wire [MAC_COUNT*8-1:0] mac_rx_pfc_req, + output wire [MAC_COUNT*8-1:0] mac_rx_pfc_ack, // towards datapath output wire [PORT_COUNT-1:0] tx_clk, @@ -92,7 +104,12 @@ module mqnic_port_map_mac_axis # output wire [PORT_COUNT-1:0] m_axis_tx_ptp_ts_valid, input wire [PORT_COUNT-1:0] m_axis_tx_ptp_ts_ready, + input wire [PORT_COUNT-1:0] tx_enable, output wire [PORT_COUNT-1:0] tx_status, + input wire [PORT_COUNT-1:0] tx_lfc_en, + input wire [PORT_COUNT-1:0] tx_lfc_req, + input wire [PORT_COUNT*8-1:0] tx_pfc_en, + input wire [PORT_COUNT*8-1:0] tx_pfc_req, output wire [PORT_COUNT-1:0] rx_clk, output wire [PORT_COUNT-1:0] rx_rst, @@ -109,7 +126,14 @@ module mqnic_port_map_mac_axis # output wire [PORT_COUNT-1:0] m_axis_rx_tlast, output wire [PORT_COUNT*AXIS_RX_USER_WIDTH-1:0] m_axis_rx_tuser, - output wire [PORT_COUNT-1:0] rx_status + input wire [PORT_COUNT-1:0] rx_enable, + output wire [PORT_COUNT-1:0] rx_status, + input wire [PORT_COUNT-1:0] rx_lfc_en, + output wire [PORT_COUNT-1:0] rx_lfc_req, + input wire [PORT_COUNT-1:0] rx_lfc_ack, + input wire [PORT_COUNT*8-1:0] rx_pfc_en, + output wire [PORT_COUNT*8-1:0] rx_pfc_req, + input wire [PORT_COUNT*8-1:0] rx_pfc_ack ); initial begin @@ -205,7 +229,12 @@ generate assign mac_tx_ptp_ts_96[n*PTP_TS_WIDTH +: PTP_TS_WIDTH] = tx_ptp_ts_96[IND[n*8 +: 8]*PTP_TS_WIDTH +: PTP_TS_WIDTH]; assign mac_tx_ptp_ts_step[n] = tx_ptp_ts_step[IND[n*8 +: 8]]; + assign mac_tx_enable[n] = tx_enable[IND[n*8 +: 8]]; assign tx_status[IND[n*8 +: 8]] = mac_tx_status[n]; + assign mac_tx_lfc_en[n] = tx_lfc_en[IND[n*8 +: 8]]; + assign mac_tx_lfc_req[n] = tx_lfc_req[IND[n*8 +: 8]]; + assign mac_tx_pfc_en[n*8 +: 8] = tx_pfc_en[IND[n*8 +: 8]*8 +: 8]; + assign mac_tx_pfc_req[n*8 +: 8] = tx_pfc_req[IND[n*8 +: 8]*8 +: 8]; assign rx_clk[IND[n*8 +: 8]] = mac_rx_clk[n]; assign rx_rst[IND[n*8 +: 8]] = mac_rx_rst[n]; @@ -223,7 +252,14 @@ generate assign mac_rx_ptp_ts_96[n*PTP_TS_WIDTH +: PTP_TS_WIDTH] = rx_ptp_ts_96[IND[n*8 +: 8]*PTP_TS_WIDTH +: PTP_TS_WIDTH]; assign mac_rx_ptp_ts_step[n] = rx_ptp_ts_step[IND[n*8 +: 8]]; + assign mac_rx_enable[n] = rx_enable[IND[n*8 +: 8]]; assign rx_status[IND[n*8 +: 8]] = mac_rx_status[n]; + assign mac_rx_lfc_en[n] = rx_lfc_en[IND[n*8 +: 8]]; + assign rx_lfc_req[IND[n*8 +: 8]] = mac_rx_lfc_req[n]; + assign mac_rx_lfc_ack[n] = rx_lfc_ack[IND[n*8 +: 8]]; + assign mac_rx_pfc_en[n*8 +: 8] = rx_pfc_en[IND[n*8 +: 8]*8 +: 8]; + assign rx_pfc_req[IND[n*8 +: 8]*8 +: 8] = mac_rx_pfc_req[n*8 +: 8]; + assign mac_rx_pfc_ack[n*8 +: 8] = rx_pfc_ack[IND[n*8 +: 8]*8 +: 8]; end else begin assign m_axis_mac_tx_tdata[n*AXIS_DATA_WIDTH +: AXIS_DATA_WIDTH] = {AXIS_DATA_WIDTH{1'b0}}; assign m_axis_mac_tx_tkeep[n*AXIS_KEEP_WIDTH +: AXIS_KEEP_WIDTH] = {AXIS_KEEP_WIDTH{1'b0}}; @@ -234,8 +270,20 @@ generate assign mac_tx_ptp_ts_96[n*PTP_TS_WIDTH +: PTP_TS_WIDTH] = {PTP_TS_WIDTH{1'b0}}; assign mac_tx_ptp_ts_step[n] = 1'b0; + assign mac_tx_enable[n] = 1'b0; + assign mac_tx_lfc_en[n] = 1'b0; + assign mac_tx_lfc_req[n] = 1'b0; + assign mac_tx_pfc_en[n*8 +: 8] = 8'd0; + assign mac_tx_pfc_req[n*8 +: 8] = 8'd0; + assign mac_rx_ptp_ts_96[n*PTP_TS_WIDTH +: PTP_TS_WIDTH] = {PTP_TS_WIDTH{1'b0}}; assign mac_rx_ptp_ts_step[n] = 1'b0; + + assign mac_rx_enable[n] = 1'b0; + assign mac_rx_lfc_en[n] = 1'b0; + assign mac_rx_lfc_ack[n] = 1'b0; + assign mac_rx_pfc_en[n*8 +: 8] = 8'd0; + assign mac_rx_pfc_ack[n*8 +: 8] = 8'd0; end end endgenerate diff --git a/fpga/common/rtl/mqnic_port_rx.v b/fpga/common/rtl/mqnic_port_rx.v index 1f2d761c1..7131af58a 100644 --- a/fpga/common/rtl/mqnic_port_rx.v +++ b/fpga/common/rtl/mqnic_port_rx.v @@ -19,6 +19,9 @@ module mqnic_port_rx # // Interface configuration parameter PTP_TS_ENABLE = 1, + parameter PFC_ENABLE = 0, + parameter LFC_ENABLE = PFC_ENABLE, + parameter MAC_CTRL_ENABLE = 0, parameter MAX_RX_SIZE = 9214, // Application block configuration @@ -95,7 +98,21 @@ module mqnic_port_rx # input wire s_axis_rx_tvalid, output wire s_axis_rx_tready, input wire s_axis_rx_tlast, - input wire [AXIS_RX_USER_WIDTH-1:0] s_axis_rx_tuser + input wire [AXIS_RX_USER_WIDTH-1:0] s_axis_rx_tuser, + + /* + * Flow control + */ + input wire rx_lfc_en, + output wire rx_lfc_req, + input wire rx_lfc_ack, + input wire [7:0] rx_pfc_en, + output wire [7:0] rx_pfc_req, + input wire [7:0] rx_pfc_ack, + input wire [9:0] rx_fc_quanta_step, + input wire rx_fc_quanta_clk_en, + input wire fifo_pause_req, + output wire fifo_pause_ack ); generate @@ -137,6 +154,12 @@ wire axis_if_rx_tlast; wire [AXIS_RX_USER_WIDTH-1:0] axis_if_rx_tuser; mqnic_l2_ingress #( + // Interface configuration + .PFC_ENABLE(PFC_ENABLE), + .LFC_ENABLE(LFC_ENABLE), + .MAC_CTRL_ENABLE(MAC_CTRL_ENABLE), + + // Streaming interface configuration .AXIS_DATA_WIDTH(AXIS_DATA_WIDTH), .AXIS_KEEP_WIDTH(AXIS_KEEP_WIDTH), .AXIS_USER_WIDTH(AXIS_RX_USER_WIDTH), @@ -164,7 +187,19 @@ mqnic_l2_ingress_inst ( .m_axis_tvalid(axis_rx_l2_tvalid), .m_axis_tready(axis_rx_l2_tready), .m_axis_tlast(axis_rx_l2_tlast), - .m_axis_tuser(axis_rx_l2_tuser) + .m_axis_tuser(axis_rx_l2_tuser), + + /* + * Flow control + */ + .rx_lfc_en(rx_lfc_en), + .rx_lfc_req(rx_lfc_req), + .rx_lfc_ack(rx_lfc_ack), + .rx_pfc_en(rx_pfc_en), + .rx_pfc_req(rx_pfc_req), + .rx_pfc_ack(rx_pfc_ack), + .rx_fc_quanta_step(rx_fc_quanta_step), + .rx_fc_quanta_clk_en(rx_fc_quanta_clk_en) ); if (APP_AXIS_DIRECT_ENABLE) begin @@ -253,8 +288,8 @@ rx_async_fifo_inst ( // Pause .s_pause_req(1'b0), .s_pause_ack(), - .m_pause_req(1'b0), - .m_pause_ack(), + .m_pause_req(fifo_pause_req), + .m_pause_ack(fifo_pause_ack), // Status .s_status_depth(), diff --git a/fpga/common/rtl/mqnic_port_tx.v b/fpga/common/rtl/mqnic_port_tx.v index 9efb47ecc..92579d2ed 100644 --- a/fpga/common/rtl/mqnic_port_tx.v +++ b/fpga/common/rtl/mqnic_port_tx.v @@ -22,6 +22,9 @@ module mqnic_port_tx # parameter TX_CPL_ENABLE = 1, parameter TX_CPL_FIFO_DEPTH = 32, parameter TX_TAG_WIDTH = 16, + parameter PFC_ENABLE = 0, + parameter LFC_ENABLE = PFC_ENABLE, + parameter MAC_CTRL_ENABLE = 0, parameter MAX_TX_SIZE = 9214, // Application block configuration @@ -128,7 +131,21 @@ module mqnic_port_tx # input wire [PTP_TS_WIDTH-1:0] s_axis_tx_cpl_ts, input wire [TX_TAG_WIDTH-1:0] s_axis_tx_cpl_tag, input wire s_axis_tx_cpl_valid, - output wire s_axis_tx_cpl_ready + output wire s_axis_tx_cpl_ready, + + /* + * Flow control + */ + input wire tx_lfc_en, + input wire tx_lfc_req, + input wire [7:0] tx_pfc_en, + input wire [7:0] tx_pfc_req, + input wire tx_pause_req, + output wire tx_pause_ack, + input wire [9:0] tx_fc_quanta_step, + input wire tx_fc_quanta_clk_en, + input wire fifo_pause_req, + output wire fifo_pause_ack ); initial begin @@ -463,8 +480,8 @@ tx_async_fifo_inst ( .m_axis_tuser(axis_tx_out_tuser), // Pause - .s_pause_req(1'b0), - .s_pause_ack(), + .s_pause_req(fifo_pause_req), + .s_pause_ack(fifo_pause_ack), .m_pause_req(1'b0), .m_pause_ack(), @@ -517,6 +534,12 @@ end else begin end mqnic_l2_egress #( + // Interface configuration + .PFC_ENABLE(PFC_ENABLE), + .LFC_ENABLE(LFC_ENABLE), + .MAC_CTRL_ENABLE(MAC_CTRL_ENABLE), + + // Streaming interface configuration .AXIS_DATA_WIDTH(AXIS_DATA_WIDTH), .AXIS_KEEP_WIDTH(AXIS_KEEP_WIDTH), .AXIS_USER_WIDTH(AXIS_TX_USER_WIDTH) @@ -543,7 +566,19 @@ mqnic_l2_egress_inst ( .m_axis_tvalid(m_axis_tx_tvalid), .m_axis_tready(m_axis_tx_tready), .m_axis_tlast(m_axis_tx_tlast), - .m_axis_tuser(m_axis_tx_tuser) + .m_axis_tuser(m_axis_tx_tuser), + + /* + * Flow control + */ + .tx_lfc_en(tx_lfc_en), + .tx_lfc_req(tx_lfc_req), + .tx_pfc_en(tx_pfc_en), + .tx_pfc_req(tx_pfc_req), + .tx_pause_req(tx_pause_req), + .tx_pause_ack(tx_pause_ack), + .tx_fc_quanta_step(tx_fc_quanta_step), + .tx_fc_quanta_clk_en(tx_fc_quanta_clk_en) ); endgenerate diff --git a/fpga/common/syn/vivado/mqnic_port.tcl b/fpga/common/syn/vivado/mqnic_port.tcl index 74f634c8a..706063c7a 100644 --- a/fpga/common/syn/vivado/mqnic_port.tcl +++ b/fpga/common/syn/vivado/mqnic_port.tcl @@ -6,18 +6,35 @@ foreach inst [get_cells -hier -filter {(ORIG_REF_NAME == mqnic_port || REF_NAME == mqnic_port)}] { puts "Inserting timing constraints for mqnic_port instance $inst" - proc constrain_slow_sync {inst driver args} { - set sync_ffs [get_cells -hier $args -filter "PARENT == $inst"] + proc constrain_sync_chain_async {inst driver args} { + set sync_ffs [get_cells -hier [concat $driver $args] -filter "PARENT == $inst"] if {[llength $sync_ffs]} { set_property ASYNC_REG TRUE $sync_ffs - set_false_path -from [get_cells "$inst/$driver"] -to [get_cells "$inst/[lindex $args 0]"] + set_false_path -to [get_pins "$inst/$driver/D"] } } - constrain_slow_sync $inst "rx_rst_sync_1_reg_reg" "rx_rst_sync_2_reg_reg" "rx_rst_sync_3_reg_reg" - constrain_slow_sync $inst "rx_status_sync_1_reg_reg" "rx_status_sync_2_reg_reg" "rx_status_sync_3_reg_reg" - constrain_slow_sync $inst "tx_rst_sync_1_reg_reg" "tx_rst_sync_2_reg_reg" "tx_rst_sync_3_reg_reg" - constrain_slow_sync $inst "tx_status_sync_1_reg_reg" "tx_status_sync_2_reg_reg" "tx_status_sync_3_reg_reg" + constrain_sync_chain_async $inst "tx_enable_sync_1_reg_reg" "tx_enable_sync_2_reg_reg" + constrain_sync_chain_async $inst "tx_lfc_en_sync_1_reg_reg" "tx_lfc_en_sync_2_reg_reg" + constrain_sync_chain_async $inst "tx_lfc_req_sync_1_reg_reg" "tx_lfc_req_sync_2_reg_reg" + constrain_sync_chain_async $inst "tx_pfc_en_sync_1_reg_reg[*]" "tx_pfc_en_sync_2_reg_reg[*]" + constrain_sync_chain_async $inst "tx_pfc_req_sync_1_reg_reg[*]" "tx_pfc_req_sync_2_reg_reg[*]" + constrain_sync_chain_async $inst "tx_fc_quanta_step_sync_1_reg_reg[*]" "tx_fc_quanta_step_sync_2_reg_reg[*]" + + constrain_sync_chain_async $inst "tx_rst_sync_2_reg_reg" "tx_rst_sync_3_reg_reg" + constrain_sync_chain_async $inst "tx_status_sync_2_reg_reg" "tx_status_sync_3_reg_reg" + + constrain_sync_chain_async $inst "rx_enable_sync_1_reg_reg" "rx_enable_sync_2_reg_reg" + constrain_sync_chain_async $inst "rx_lfc_en_sync_1_reg_reg" "rx_lfc_en_sync_2_reg_reg" + constrain_sync_chain_async $inst "rx_lfc_ack_sync_1_reg_reg" "rx_lfc_ack_sync_2_reg_reg" + constrain_sync_chain_async $inst "rx_pfc_en_sync_1_reg_reg[*]" "rx_pfc_en_sync_2_reg_reg[*]" + constrain_sync_chain_async $inst "rx_pfc_ack_sync_1_reg_reg[*]" "rx_pfc_ack_sync_2_reg_reg[*]" + + constrain_sync_chain_async $inst "rx_rst_sync_2_reg_reg" "rx_rst_sync_3_reg_reg" + constrain_sync_chain_async $inst "rx_status_sync_2_reg_reg" "rx_status_sync_3_reg_reg" + constrain_sync_chain_async $inst "rx_lfc_req_sync_2_reg_reg" "rx_lfc_req_sync_3_reg_reg" + constrain_sync_chain_async $inst "rx_pfc_req_sync_2_reg_reg[*]" "rx_pfc_req_sync_3_reg_reg[*]" + constrain_sync_chain_async $inst "rx_fc_quanta_step_sync_1_reg_reg[*]" "rx_fc_quanta_step_sync_2_reg_reg[*]" } diff --git a/fpga/common/tb/mqnic.py b/fpga/common/tb/mqnic.py index 1f109933a..e5cdac7a1 100644 --- a/fpga/common/tb/mqnic.py +++ b/fpga/common/tb/mqnic.py @@ -147,6 +147,8 @@ MQNIC_IF_FEATURE_PTP_TS = (1 << 4) MQNIC_IF_FEATURE_TX_CSUM = (1 << 8) MQNIC_IF_FEATURE_RX_CSUM = (1 << 9) MQNIC_IF_FEATURE_RX_HASH = (1 << 10) +MQNIC_IF_FEATURE_LFC = (1 << 11) +MQNIC_IF_FEATURE_PFC = (1 << 12) MQNIC_RB_RX_QUEUE_MAP_TYPE = 0x0000C090 MQNIC_RB_RX_QUEUE_MAP_VER = 0x00000200 @@ -186,10 +188,47 @@ MQNIC_RB_PORT_VER = 0x00000200 MQNIC_RB_PORT_REG_OFFSET = 0x0C MQNIC_RB_PORT_CTRL_TYPE = 0x0000C003 -MQNIC_RB_PORT_CTRL_VER = 0x00000200 +MQNIC_RB_PORT_CTRL_VER = 0x00000300 MQNIC_RB_PORT_CTRL_REG_FEATURES = 0x0C -MQNIC_RB_PORT_CTRL_REG_TX_STATUS = 0x10 -MQNIC_RB_PORT_CTRL_REG_RX_STATUS = 0x14 +MQNIC_RB_PORT_CTRL_REG_TX_CTRL = 0x10 +MQNIC_RB_PORT_CTRL_REG_RX_CTRL = 0x14 +MQNIC_RB_PORT_CTRL_REG_LFC_CTRL = 0x1C +MQNIC_RB_PORT_CTRL_REG_PFC_CTRL0 = 0x20 +MQNIC_RB_PORT_CTRL_REG_PFC_CTRL1 = 0x24 +MQNIC_RB_PORT_CTRL_REG_PFC_CTRL2 = 0x28 +MQNIC_RB_PORT_CTRL_REG_PFC_CTRL3 = 0x2C +MQNIC_RB_PORT_CTRL_REG_PFC_CTRL4 = 0x30 +MQNIC_RB_PORT_CTRL_REG_PFC_CTRL5 = 0x34 +MQNIC_RB_PORT_CTRL_REG_PFC_CTRL6 = 0x38 +MQNIC_RB_PORT_CTRL_REG_PFC_CTRL7 = 0x3C + +MQNIC_PORT_FEATURE_LFC = (1 << 0) +MQNIC_PORT_FEATURE_PFC = (1 << 1) +MQNIC_PORT_FEATURE_INT_MAC_CTRL = (1 << 2) + +MQNIC_PORT_TX_CTRL_EN = (1 << 0) +MQNIC_PORT_TX_CTRL_PAUSE = (1 << 8) +MQNIC_PORT_TX_CTRL_STATUS = (1 << 16) +MQNIC_PORT_TX_CTRL_RESET = (1 << 17) +MQNIC_PORT_TX_CTRL_PAUSE_REQ = (1 << 24) +MQNIC_PORT_TX_CTRL_PAUSE_ACK = (1 << 25) + +MQNIC_PORT_RX_CTRL_EN = (1 << 0) +MQNIC_PORT_RX_CTRL_PAUSE = (1 << 8) +MQNIC_PORT_RX_CTRL_STATUS = (1 << 16) +MQNIC_PORT_RX_CTRL_RESET = (1 << 17) +MQNIC_PORT_RX_CTRL_PAUSE_REQ = (1 << 24) +MQNIC_PORT_RX_CTRL_PAUSE_ACK = (1 << 25) + +MQNIC_PORT_LFC_CTRL_TX_LFC_EN = (1 << 24) +MQNIC_PORT_LFC_CTRL_RX_LFC_EN = (1 << 25) +MQNIC_PORT_LFC_CTRL_TX_LFC_REQ = (1 << 28) +MQNIC_PORT_LFC_CTRL_RX_LFC_REQ = (1 << 29) + +MQNIC_PORT_PFC_CTRL_TX_PFC_EN = (1 << 24) +MQNIC_PORT_PFC_CTRL_RX_PFC_EN = (1 << 25) +MQNIC_PORT_PFC_CTRL_TX_PFC_REQ = (1 << 28) +MQNIC_PORT_PFC_CTRL_RX_PFC_REQ = (1 << 29) MQNIC_RB_SCHED_BLOCK_TYPE = 0x0000C004 MQNIC_RB_SCHED_BLOCK_VER = 0x00000300 @@ -1119,6 +1158,9 @@ class Port: self.port_ctrl_rb = None self.port_features = None + self.port_feature_lfc = None + self.port_feature_pfc = None + self.port_feature_int_mac_ctrl = None async def init(self): # Read ID registers @@ -1129,14 +1171,42 @@ class Port: self.port_ctrl_rb = self.reg_blocks.find(MQNIC_RB_PORT_CTRL_TYPE, MQNIC_RB_PORT_CTRL_VER) self.port_features = await self.port_ctrl_rb.read_dword(MQNIC_RB_PORT_CTRL_REG_FEATURES) + self.port_feature_lfc = bool(self.port_features & MQNIC_PORT_FEATURE_LFC) + self.port_feature_pfc = bool(self.port_features & MQNIC_PORT_FEATURE_PFC) + self.port_feature_int_mac_ctrl = bool(self.port_features & MQNIC_PORT_FEATURE_INT_MAC_CTRL) self.log.info("Port features: 0x%08x", self.port_features) - async def get_tx_status(self, port): - return await self.port_ctrl_rb.read_dword(MQNIC_RB_PORT_CTRL_REG_TX_STATUS) + await self.set_tx_ctrl(0) + await self.set_rx_ctrl(0) + await self.set_lfc_ctrl(0) - async def get_rx_status(self, port): - return await self.port_ctrl_rb.read_dword(MQNIC_RB_PORT_CTRL_REG_RX_STATUS) + for k in range(8): + await self.set_pfc_ctrl(k, 0) + + async def get_tx_ctrl(self): + return await self.port_ctrl_rb.read_dword(MQNIC_RB_PORT_CTRL_REG_TX_CTRL) + + async def set_tx_ctrl(self, val): + await self.port_ctrl_rb.write_dword(MQNIC_RB_PORT_CTRL_REG_TX_CTRL, val) + + async def get_rx_ctrl(self): + return await self.port_ctrl_rb.read_dword(MQNIC_RB_PORT_CTRL_REG_RX_CTRL) + + async def set_rx_ctrl(self, val): + await self.port_ctrl_rb.write_dword(MQNIC_RB_PORT_CTRL_REG_RX_CTRL, val) + + async def get_lfc_ctrl(self): + return await self.port_ctrl_rb.read_dword(MQNIC_RB_PORT_CTRL_REG_LFC_CTRL) + + async def set_lfc_ctrl(self, val): + await self.port_ctrl_rb.write_dword(MQNIC_RB_PORT_CTRL_REG_LFC_CTRL, val) + + async def get_pfc_ctrl(self, index): + return await self.port_ctrl_rb.read_dword(MQNIC_RB_PORT_CTRL_REG_PFC_CTRL0 + 4*index) + + async def set_pfc_ctrl(self, index, val): + await self.port_ctrl_rb.write_dword(MQNIC_RB_PORT_CTRL_REG_PFC_CTRL0 + 4*index, val) class Interface: @@ -1209,6 +1279,8 @@ class Interface: self.if_feature_tx_csum = bool(self.if_features & MQNIC_IF_FEATURE_TX_CSUM) self.if_feature_rx_csum = bool(self.if_features & MQNIC_IF_FEATURE_RX_CSUM) self.if_feature_rx_hash = bool(self.if_features & MQNIC_IF_FEATURE_RX_HASH) + self.if_feature_lfc = bool(self.if_features & MQNIC_IF_FEATURE_LFC) + self.if_feature_pfc = bool(self.if_features & MQNIC_IF_FEATURE_PFC) self.log.info("IF features: 0x%08x", self.if_features) self.log.info("Port count: %d", self.port_count) @@ -1357,11 +1429,16 @@ class Interface: # wait for all writes to complete await self.hw_regs.read_dword(0) + await self.ports[0].set_tx_ctrl(MQNIC_PORT_TX_CTRL_EN) + await self.ports[0].set_rx_ctrl(MQNIC_PORT_RX_CTRL_EN) + self.port_up = True async def close(self): self.port_up = False + await self.ports[0].set_rx_ctrl(0) + for q in self.txq: q.disable() @@ -1386,6 +1463,8 @@ class Interface: self.txq = [] self.rxq = [] + await self.ports[0].set_tx_ctrl(0) + async def start_xmit(self, skb, tx_ring=None, csum_start=None, csum_offset=None): if not self.port_up: return diff --git a/fpga/common/tb/mqnic_core_axi/Makefile b/fpga/common/tb/mqnic_core_axi/Makefile index 86e36b5c1..add7f81b8 100644 --- a/fpga/common/tb/mqnic_core_axi/Makefile +++ b/fpga/common/tb/mqnic_core_axi/Makefile @@ -52,6 +52,10 @@ VERILOG_SOURCES += ../../rtl/stats_dma_if_axi.v VERILOG_SOURCES += ../../rtl/stats_dma_latency.v VERILOG_SOURCES += ../../rtl/mqnic_tx_scheduler_block_rr.v VERILOG_SOURCES += ../../rtl/tx_scheduler_rr.v +VERILOG_SOURCES += ../../lib/eth/rtl/mac_ctrl_rx.v +VERILOG_SOURCES += ../../lib/eth/rtl/mac_ctrl_tx.v +VERILOG_SOURCES += ../../lib/eth/rtl/mac_pause_ctrl_rx.v +VERILOG_SOURCES += ../../lib/eth/rtl/mac_pause_ctrl_tx.v VERILOG_SOURCES += ../../lib/eth/rtl/ptp_clock.v VERILOG_SOURCES += ../../lib/eth/rtl/ptp_clock_cdc.v VERILOG_SOURCES += ../../lib/eth/rtl/ptp_perout.v @@ -145,6 +149,9 @@ export PARAM_TX_TAG_WIDTH := 16 export PARAM_TX_CHECKSUM_ENABLE := 1 export PARAM_RX_HASH_ENABLE := 1 export PARAM_RX_CHECKSUM_ENABLE := 1 +export PARAM_LFC_ENABLE := 1 +export PARAM_PFC_ENABLE := $(PARAM_LFC_ENABLE) +export PARAM_MAC_CTRL_ENABLE := 1 export PARAM_TX_FIFO_DEPTH := 32768 export PARAM_RX_FIFO_DEPTH := 131072 export PARAM_MAX_TX_SIZE := 9214 diff --git a/fpga/common/tb/mqnic_core_axi/test_mqnic_core_axi.py b/fpga/common/tb/mqnic_core_axi/test_mqnic_core_axi.py index ce1390e68..474783e89 100644 --- a/fpga/common/tb/mqnic_core_axi/test_mqnic_core_axi.py +++ b/fpga/common/tb/mqnic_core_axi/test_mqnic_core_axi.py @@ -3,6 +3,7 @@ import logging import os +import struct import sys import scapy.utils @@ -103,7 +104,11 @@ class TB(object): self.port_mac.append(mac) dut.tx_status.setimmediatevalue(2**len(core_inst.m_axis_tx_tvalid)-1) + dut.tx_fc_quanta_clk_en.setimmediatevalue(2**len(core_inst.m_axis_tx_tvalid)-1) dut.rx_status.setimmediatevalue(2**len(core_inst.m_axis_tx_tvalid)-1) + dut.rx_lfc_req.setimmediatevalue(0) + dut.rx_pfc_req.setimmediatevalue(0) + dut.rx_fc_quanta_clk_en.setimmediatevalue(2**len(core_inst.m_axis_tx_tvalid)-1) # DDR self.ddr_group_size = core_inst.DDR_GROUP_SIZE.value @@ -445,13 +450,16 @@ async def run_test_nic(dut): for block in tb.driver.interfaces[0].sched_blocks: await block.schedulers[0].rb.write_dword(mqnic.MQNIC_RB_SCHED_RR_REG_CTRL, 0x00000001) - await tb.driver.interfaces[0].set_rx_queue_map_indir_table(block.index, 0, block.index) + await block.interface.set_rx_queue_map_indir_table(block.index, 0, block.index) for k in range(len(block.interface.txq)): - if k % len(tb.driver.interfaces[0].sched_blocks) == block.index: + if k % len(block.interface.sched_blocks) == block.index: await block.schedulers[0].hw_regs.write_dword(4*k, 0x00000003) else: await block.schedulers[0].hw_regs.write_dword(4*k, 0x00000000) + await block.interface.ports[block.index].set_tx_ctrl(mqnic.MQNIC_PORT_TX_CTRL_EN) + await block.interface.ports[block.index].set_rx_ctrl(mqnic.MQNIC_PORT_RX_CTRL_EN) + count = 64 pkts = [bytearray([(x+k) % 256 for x in range(1514)]) for k in range(count)] @@ -481,6 +489,35 @@ async def run_test_nic(dut): await block.schedulers[0].rb.write_dword(mqnic.MQNIC_RB_SCHED_RR_REG_CTRL, 0x00000000) await tb.driver.interfaces[0].set_rx_queue_map_indir_table(block.index, 0, 0) + if tb.driver.interfaces[0].if_feature_lfc: + tb.log.info("Test LFC pause frame RX") + + await tb.driver.interfaces[0].ports[0].set_lfc_ctrl(mqnic.MQNIC_PORT_LFC_CTRL_TX_LFC_EN | mqnic.MQNIC_PORT_LFC_CTRL_RX_LFC_EN) + await tb.driver.hw_regs.read_dword(0) + + lfc_xoff = Ether(src='DA:D1:D2:D3:D4:D5', dst='01:80:C2:00:00:01', type=0x8808) / struct.pack('!HH', 0x0001, 2000) + + await tb.port_mac[0].rx.send(bytes(lfc_xoff)) + + count = 16 + + pkts = [bytearray([(x+k) % 256 for x in range(1514)]) for k in range(count)] + + tb.loopback_enable = True + + for p in pkts: + await tb.driver.interfaces[0].start_xmit(p, 0) + + for k in range(count): + pkt = await tb.driver.interfaces[0].recv() + + tb.log.info("Packet: %s", pkt) + assert pkt.data == pkts[k] + if tb.driver.interfaces[0].if_feature_rx_csum: + assert pkt.rx_checksum == ~scapy.utils.checksum(bytes(pkt.data[14:])) & 0xffff + + tb.loopback_enable = False + tb.log.info("Read statistics counters") await Timer(2000, 'ns') @@ -562,6 +599,10 @@ def test_mqnic_core_axi(request, if_count, ports_per_if, axi_data_width, os.path.join(rtl_dir, "stats_dma_latency.v"), os.path.join(rtl_dir, "mqnic_tx_scheduler_block_rr.v"), os.path.join(rtl_dir, "tx_scheduler_rr.v"), + os.path.join(eth_rtl_dir, "mac_ctrl_rx.v"), + os.path.join(eth_rtl_dir, "mac_ctrl_tx.v"), + os.path.join(eth_rtl_dir, "mac_pause_ctrl_rx.v"), + os.path.join(eth_rtl_dir, "mac_pause_ctrl_tx.v"), os.path.join(eth_rtl_dir, "ptp_clock.v"), os.path.join(eth_rtl_dir, "ptp_clock_cdc.v"), os.path.join(eth_rtl_dir, "ptp_perout.v"), @@ -656,6 +697,9 @@ def test_mqnic_core_axi(request, if_count, ports_per_if, axi_data_width, parameters['TX_CHECKSUM_ENABLE'] = 1 parameters['RX_HASH_ENABLE'] = 1 parameters['RX_CHECKSUM_ENABLE'] = 1 + parameters['LFC_ENABLE'] = 1 + parameters['PFC_ENABLE'] = parameters['LFC_ENABLE'] + parameters['MAC_CTRL_ENABLE'] = 1 parameters['TX_FIFO_DEPTH'] = 32768 parameters['RX_FIFO_DEPTH'] = 131072 parameters['MAX_TX_SIZE'] = 9214 diff --git a/fpga/common/tb/mqnic_core_pcie_ptile/Makefile b/fpga/common/tb/mqnic_core_pcie_ptile/Makefile index bb7c74855..bb614ccf2 100644 --- a/fpga/common/tb/mqnic_core_pcie_ptile/Makefile +++ b/fpga/common/tb/mqnic_core_pcie_ptile/Makefile @@ -53,6 +53,10 @@ VERILOG_SOURCES += ../../rtl/stats_dma_if_pcie.v VERILOG_SOURCES += ../../rtl/stats_dma_latency.v VERILOG_SOURCES += ../../rtl/mqnic_tx_scheduler_block_rr.v VERILOG_SOURCES += ../../rtl/tx_scheduler_rr.v +VERILOG_SOURCES += ../../lib/eth/rtl/mac_ctrl_rx.v +VERILOG_SOURCES += ../../lib/eth/rtl/mac_ctrl_tx.v +VERILOG_SOURCES += ../../lib/eth/rtl/mac_pause_ctrl_rx.v +VERILOG_SOURCES += ../../lib/eth/rtl/mac_pause_ctrl_tx.v VERILOG_SOURCES += ../../lib/eth/rtl/ptp_clock.v VERILOG_SOURCES += ../../lib/eth/rtl/ptp_clock_cdc.v VERILOG_SOURCES += ../../lib/eth/rtl/ptp_perout.v @@ -160,6 +164,9 @@ export PARAM_TX_TAG_WIDTH := 16 export PARAM_TX_CHECKSUM_ENABLE := 1 export PARAM_RX_HASH_ENABLE := 1 export PARAM_RX_CHECKSUM_ENABLE := 1 +export PARAM_LFC_ENABLE := 1 +export PARAM_PFC_ENABLE := $(PARAM_LFC_ENABLE) +export PARAM_MAC_CTRL_ENABLE := 1 export PARAM_TX_FIFO_DEPTH := 32768 export PARAM_RX_FIFO_DEPTH := 131072 export PARAM_MAX_TX_SIZE := 9214 diff --git a/fpga/common/tb/mqnic_core_pcie_ptile/test_mqnic_core_pcie_ptile.py b/fpga/common/tb/mqnic_core_pcie_ptile/test_mqnic_core_pcie_ptile.py index 57f3934df..bb6337941 100644 --- a/fpga/common/tb/mqnic_core_pcie_ptile/test_mqnic_core_pcie_ptile.py +++ b/fpga/common/tb/mqnic_core_pcie_ptile/test_mqnic_core_pcie_ptile.py @@ -3,6 +3,7 @@ import logging import os +import struct import sys import scapy.utils @@ -299,7 +300,11 @@ class TB(object): self.port_mac.append(mac) dut.eth_tx_status.setimmediatevalue(2**len(core_inst.m_axis_tx_tvalid)-1) + dut.eth_tx_fc_quanta_clk_en.setimmediatevalue(2**len(core_inst.m_axis_tx_tvalid)-1) dut.eth_rx_status.setimmediatevalue(2**len(core_inst.m_axis_tx_tvalid)-1) + dut.eth_rx_lfc_req.setimmediatevalue(0) + dut.eth_rx_pfc_req.setimmediatevalue(0) + dut.eth_rx_fc_quanta_clk_en.setimmediatevalue(2**len(core_inst.m_axis_tx_tvalid)-1) # DDR self.ddr_group_size = core_inst.DDR_GROUP_SIZE.value @@ -643,13 +648,16 @@ async def run_test_nic(dut): for block in tb.driver.interfaces[0].sched_blocks: await block.schedulers[0].rb.write_dword(mqnic.MQNIC_RB_SCHED_RR_REG_CTRL, 0x00000001) - await tb.driver.interfaces[0].set_rx_queue_map_indir_table(block.index, 0, block.index) + await block.interface.set_rx_queue_map_indir_table(block.index, 0, block.index) for k in range(len(block.interface.txq)): - if k % len(tb.driver.interfaces[0].sched_blocks) == block.index: + if k % len(block.interface.sched_blocks) == block.index: await block.schedulers[0].hw_regs.write_dword(4*k, 0x00000003) else: await block.schedulers[0].hw_regs.write_dword(4*k, 0x00000000) + await block.interface.ports[block.index].set_tx_ctrl(mqnic.MQNIC_PORT_TX_CTRL_EN) + await block.interface.ports[block.index].set_rx_ctrl(mqnic.MQNIC_PORT_RX_CTRL_EN) + count = 64 pkts = [bytearray([(x+k) % 256 for x in range(1514)]) for k in range(count)] @@ -679,6 +687,35 @@ async def run_test_nic(dut): await block.schedulers[0].rb.write_dword(mqnic.MQNIC_RB_SCHED_RR_REG_CTRL, 0x00000000) await tb.driver.interfaces[0].set_rx_queue_map_indir_table(block.index, 0, 0) + if tb.driver.interfaces[0].if_feature_lfc: + tb.log.info("Test LFC pause frame RX") + + await tb.driver.interfaces[0].ports[0].set_lfc_ctrl(mqnic.MQNIC_PORT_LFC_CTRL_TX_LFC_EN | mqnic.MQNIC_PORT_LFC_CTRL_RX_LFC_EN) + await tb.driver.hw_regs.read_dword(0) + + lfc_xoff = Ether(src='DA:D1:D2:D3:D4:D5', dst='01:80:C2:00:00:01', type=0x8808) / struct.pack('!HH', 0x0001, 2000) + + await tb.port_mac[0].rx.send(bytes(lfc_xoff)) + + count = 16 + + pkts = [bytearray([(x+k) % 256 for x in range(1514)]) for k in range(count)] + + tb.loopback_enable = True + + for p in pkts: + await tb.driver.interfaces[0].start_xmit(p, 0) + + for k in range(count): + pkt = await tb.driver.interfaces[0].recv() + + tb.log.info("Packet: %s", pkt) + assert pkt.data == pkts[k] + if tb.driver.interfaces[0].if_feature_rx_csum: + assert pkt.rx_checksum == ~scapy.utils.checksum(bytes(pkt.data[14:])) & 0xffff + + tb.loopback_enable = False + tb.log.info("Read statistics counters") await Timer(2000, 'ns') @@ -764,6 +801,10 @@ def test_mqnic_core_pcie_ptile(request, if_count, ports_per_if, pcie_data_width, os.path.join(rtl_dir, "stats_dma_latency.v"), os.path.join(rtl_dir, "mqnic_tx_scheduler_block_rr.v"), os.path.join(rtl_dir, "tx_scheduler_rr.v"), + os.path.join(eth_rtl_dir, "mac_ctrl_rx.v"), + os.path.join(eth_rtl_dir, "mac_ctrl_tx.v"), + os.path.join(eth_rtl_dir, "mac_pause_ctrl_rx.v"), + os.path.join(eth_rtl_dir, "mac_pause_ctrl_tx.v"), os.path.join(eth_rtl_dir, "ptp_clock.v"), os.path.join(eth_rtl_dir, "ptp_clock_cdc.v"), os.path.join(eth_rtl_dir, "ptp_perout.v"), @@ -872,6 +913,9 @@ def test_mqnic_core_pcie_ptile(request, if_count, ports_per_if, pcie_data_width, parameters['TX_CHECKSUM_ENABLE'] = 1 parameters['RX_HASH_ENABLE'] = 1 parameters['RX_CHECKSUM_ENABLE'] = 1 + parameters['LFC_ENABLE'] = 1 + parameters['PFC_ENABLE'] = parameters['LFC_ENABLE'] + parameters['MAC_CTRL_ENABLE'] = 1 parameters['TX_FIFO_DEPTH'] = 32768 parameters['RX_FIFO_DEPTH'] = 131072 parameters['MAX_TX_SIZE'] = 9214 diff --git a/fpga/common/tb/mqnic_core_pcie_s10/Makefile b/fpga/common/tb/mqnic_core_pcie_s10/Makefile index 58834e293..0bc8071ce 100644 --- a/fpga/common/tb/mqnic_core_pcie_s10/Makefile +++ b/fpga/common/tb/mqnic_core_pcie_s10/Makefile @@ -53,6 +53,10 @@ VERILOG_SOURCES += ../../rtl/stats_dma_if_pcie.v VERILOG_SOURCES += ../../rtl/stats_dma_latency.v VERILOG_SOURCES += ../../rtl/mqnic_tx_scheduler_block_rr.v VERILOG_SOURCES += ../../rtl/tx_scheduler_rr.v +VERILOG_SOURCES += ../../lib/eth/rtl/mac_ctrl_rx.v +VERILOG_SOURCES += ../../lib/eth/rtl/mac_ctrl_tx.v +VERILOG_SOURCES += ../../lib/eth/rtl/mac_pause_ctrl_rx.v +VERILOG_SOURCES += ../../lib/eth/rtl/mac_pause_ctrl_tx.v VERILOG_SOURCES += ../../lib/eth/rtl/ptp_clock.v VERILOG_SOURCES += ../../lib/eth/rtl/ptp_clock_cdc.v VERILOG_SOURCES += ../../lib/eth/rtl/ptp_perout.v @@ -159,6 +163,9 @@ export PARAM_TX_TAG_WIDTH := 16 export PARAM_TX_CHECKSUM_ENABLE := 1 export PARAM_RX_HASH_ENABLE := 1 export PARAM_RX_CHECKSUM_ENABLE := 1 +export PARAM_LFC_ENABLE := 1 +export PARAM_PFC_ENABLE := $(PARAM_LFC_ENABLE) +export PARAM_MAC_CTRL_ENABLE := 1 export PARAM_TX_FIFO_DEPTH := 32768 export PARAM_RX_FIFO_DEPTH := 131072 export PARAM_MAX_TX_SIZE := 9214 diff --git a/fpga/common/tb/mqnic_core_pcie_s10/test_mqnic_core_pcie_s10.py b/fpga/common/tb/mqnic_core_pcie_s10/test_mqnic_core_pcie_s10.py index f9d35560f..72b1ba3fa 100644 --- a/fpga/common/tb/mqnic_core_pcie_s10/test_mqnic_core_pcie_s10.py +++ b/fpga/common/tb/mqnic_core_pcie_s10/test_mqnic_core_pcie_s10.py @@ -3,6 +3,7 @@ import logging import os +import struct import sys import scapy.utils @@ -247,7 +248,11 @@ class TB(object): self.port_mac.append(mac) dut.eth_tx_status.setimmediatevalue(2**len(core_inst.m_axis_tx_tvalid)-1) + dut.eth_tx_fc_quanta_clk_en.setimmediatevalue(2**len(core_inst.m_axis_tx_tvalid)-1) dut.eth_rx_status.setimmediatevalue(2**len(core_inst.m_axis_tx_tvalid)-1) + dut.eth_rx_lfc_req.setimmediatevalue(0) + dut.eth_rx_pfc_req.setimmediatevalue(0) + dut.eth_rx_fc_quanta_clk_en.setimmediatevalue(2**len(core_inst.m_axis_tx_tvalid)-1) # DDR self.ddr_group_size = core_inst.DDR_GROUP_SIZE.value @@ -591,13 +596,16 @@ async def run_test_nic(dut): for block in tb.driver.interfaces[0].sched_blocks: await block.schedulers[0].rb.write_dword(mqnic.MQNIC_RB_SCHED_RR_REG_CTRL, 0x00000001) - await tb.driver.interfaces[0].set_rx_queue_map_indir_table(block.index, 0, block.index) + await block.interface.set_rx_queue_map_indir_table(block.index, 0, block.index) for k in range(len(block.interface.txq)): - if k % len(tb.driver.interfaces[0].sched_blocks) == block.index: + if k % len(block.interface.sched_blocks) == block.index: await block.schedulers[0].hw_regs.write_dword(4*k, 0x00000003) else: await block.schedulers[0].hw_regs.write_dword(4*k, 0x00000000) + await block.interface.ports[block.index].set_tx_ctrl(mqnic.MQNIC_PORT_TX_CTRL_EN) + await block.interface.ports[block.index].set_rx_ctrl(mqnic.MQNIC_PORT_RX_CTRL_EN) + count = 64 pkts = [bytearray([(x+k) % 256 for x in range(1514)]) for k in range(count)] @@ -627,6 +635,35 @@ async def run_test_nic(dut): await block.schedulers[0].rb.write_dword(mqnic.MQNIC_RB_SCHED_RR_REG_CTRL, 0x00000000) await tb.driver.interfaces[0].set_rx_queue_map_indir_table(block.index, 0, 0) + if tb.driver.interfaces[0].if_feature_lfc: + tb.log.info("Test LFC pause frame RX") + + await tb.driver.interfaces[0].ports[0].set_lfc_ctrl(mqnic.MQNIC_PORT_LFC_CTRL_TX_LFC_EN | mqnic.MQNIC_PORT_LFC_CTRL_RX_LFC_EN) + await tb.driver.hw_regs.read_dword(0) + + lfc_xoff = Ether(src='DA:D1:D2:D3:D4:D5', dst='01:80:C2:00:00:01', type=0x8808) / struct.pack('!HH', 0x0001, 2000) + + await tb.port_mac[0].rx.send(bytes(lfc_xoff)) + + count = 16 + + pkts = [bytearray([(x+k) % 256 for x in range(1514)]) for k in range(count)] + + tb.loopback_enable = True + + for p in pkts: + await tb.driver.interfaces[0].start_xmit(p, 0) + + for k in range(count): + pkt = await tb.driver.interfaces[0].recv() + + tb.log.info("Packet: %s", pkt) + assert pkt.data == pkts[k] + if tb.driver.interfaces[0].if_feature_rx_csum: + assert pkt.rx_checksum == ~scapy.utils.checksum(bytes(pkt.data[14:])) & 0xffff + + tb.loopback_enable = False + tb.log.info("Read statistics counters") await Timer(2000, 'ns') @@ -712,6 +749,10 @@ def test_mqnic_core_pcie_s10(request, if_count, ports_per_if, pcie_data_width, os.path.join(rtl_dir, "stats_dma_latency.v"), os.path.join(rtl_dir, "mqnic_tx_scheduler_block_rr.v"), os.path.join(rtl_dir, "tx_scheduler_rr.v"), + os.path.join(eth_rtl_dir, "mac_ctrl_rx.v"), + os.path.join(eth_rtl_dir, "mac_ctrl_tx.v"), + os.path.join(eth_rtl_dir, "mac_pause_ctrl_rx.v"), + os.path.join(eth_rtl_dir, "mac_pause_ctrl_tx.v"), os.path.join(eth_rtl_dir, "ptp_clock.v"), os.path.join(eth_rtl_dir, "ptp_clock_cdc.v"), os.path.join(eth_rtl_dir, "ptp_perout.v"), @@ -819,6 +860,9 @@ def test_mqnic_core_pcie_s10(request, if_count, ports_per_if, pcie_data_width, parameters['TX_CHECKSUM_ENABLE'] = 1 parameters['RX_HASH_ENABLE'] = 1 parameters['RX_CHECKSUM_ENABLE'] = 1 + parameters['LFC_ENABLE'] = 1 + parameters['PFC_ENABLE'] = parameters['LFC_ENABLE'] + parameters['MAC_CTRL_ENABLE'] = 1 parameters['TX_FIFO_DEPTH'] = 32768 parameters['RX_FIFO_DEPTH'] = 131072 parameters['MAX_TX_SIZE'] = 9214 diff --git a/fpga/common/tb/mqnic_core_pcie_us/Makefile b/fpga/common/tb/mqnic_core_pcie_us/Makefile index b2598be80..a389a36b2 100644 --- a/fpga/common/tb/mqnic_core_pcie_us/Makefile +++ b/fpga/common/tb/mqnic_core_pcie_us/Makefile @@ -53,6 +53,10 @@ VERILOG_SOURCES += ../../rtl/stats_dma_if_pcie.v VERILOG_SOURCES += ../../rtl/stats_dma_latency.v VERILOG_SOURCES += ../../rtl/mqnic_tx_scheduler_block_rr.v VERILOG_SOURCES += ../../rtl/tx_scheduler_rr.v +VERILOG_SOURCES += ../../lib/eth/rtl/mac_ctrl_rx.v +VERILOG_SOURCES += ../../lib/eth/rtl/mac_ctrl_tx.v +VERILOG_SOURCES += ../../lib/eth/rtl/mac_pause_ctrl_rx.v +VERILOG_SOURCES += ../../lib/eth/rtl/mac_pause_ctrl_tx.v VERILOG_SOURCES += ../../lib/eth/rtl/ptp_clock.v VERILOG_SOURCES += ../../lib/eth/rtl/ptp_clock_cdc.v VERILOG_SOURCES += ../../lib/eth/rtl/ptp_perout.v @@ -159,6 +163,9 @@ export PARAM_TX_TAG_WIDTH := 16 export PARAM_TX_CHECKSUM_ENABLE := 1 export PARAM_RX_HASH_ENABLE := 1 export PARAM_RX_CHECKSUM_ENABLE := 1 +export PARAM_LFC_ENABLE := 1 +export PARAM_PFC_ENABLE := $(PARAM_LFC_ENABLE) +export PARAM_MAC_CTRL_ENABLE := 1 export PARAM_TX_FIFO_DEPTH := 32768 export PARAM_RX_FIFO_DEPTH := 131072 export PARAM_MAX_TX_SIZE := 9214 diff --git a/fpga/common/tb/mqnic_core_pcie_us/test_mqnic_core_pcie_us.py b/fpga/common/tb/mqnic_core_pcie_us/test_mqnic_core_pcie_us.py index 7a0669a58..9b5d8dc77 100644 --- a/fpga/common/tb/mqnic_core_pcie_us/test_mqnic_core_pcie_us.py +++ b/fpga/common/tb/mqnic_core_pcie_us/test_mqnic_core_pcie_us.py @@ -3,6 +3,7 @@ import logging import os +import struct import sys import scapy.utils @@ -321,7 +322,11 @@ class TB(object): self.port_mac.append(mac) dut.eth_tx_status.setimmediatevalue(2**len(core_inst.m_axis_tx_tvalid)-1) + dut.eth_tx_fc_quanta_clk_en.setimmediatevalue(2**len(core_inst.m_axis_tx_tvalid)-1) dut.eth_rx_status.setimmediatevalue(2**len(core_inst.m_axis_tx_tvalid)-1) + dut.eth_rx_lfc_req.setimmediatevalue(0) + dut.eth_rx_pfc_req.setimmediatevalue(0) + dut.eth_rx_fc_quanta_clk_en.setimmediatevalue(2**len(core_inst.m_axis_tx_tvalid)-1) # DDR self.ddr_group_size = core_inst.DDR_GROUP_SIZE.value @@ -665,13 +670,16 @@ async def run_test_nic(dut): for block in tb.driver.interfaces[0].sched_blocks: await block.schedulers[0].rb.write_dword(mqnic.MQNIC_RB_SCHED_RR_REG_CTRL, 0x00000001) - await tb.driver.interfaces[0].set_rx_queue_map_indir_table(block.index, 0, block.index) + await block.interface.set_rx_queue_map_indir_table(block.index, 0, block.index) for k in range(len(block.interface.txq)): - if k % len(tb.driver.interfaces[0].sched_blocks) == block.index: + if k % len(block.interface.sched_blocks) == block.index: await block.schedulers[0].hw_regs.write_dword(4*k, 0x00000003) else: await block.schedulers[0].hw_regs.write_dword(4*k, 0x00000000) + await block.interface.ports[block.index].set_tx_ctrl(mqnic.MQNIC_PORT_TX_CTRL_EN) + await block.interface.ports[block.index].set_rx_ctrl(mqnic.MQNIC_PORT_RX_CTRL_EN) + count = 64 pkts = [bytearray([(x+k) % 256 for x in range(1514)]) for k in range(count)] @@ -701,6 +709,35 @@ async def run_test_nic(dut): await block.schedulers[0].rb.write_dword(mqnic.MQNIC_RB_SCHED_RR_REG_CTRL, 0x00000000) await tb.driver.interfaces[0].set_rx_queue_map_indir_table(block.index, 0, 0) + if tb.driver.interfaces[0].if_feature_lfc: + tb.log.info("Test LFC pause frame RX") + + await tb.driver.interfaces[0].ports[0].set_lfc_ctrl(mqnic.MQNIC_PORT_LFC_CTRL_TX_LFC_EN | mqnic.MQNIC_PORT_LFC_CTRL_RX_LFC_EN) + await tb.driver.hw_regs.read_dword(0) + + lfc_xoff = Ether(src='DA:D1:D2:D3:D4:D5', dst='01:80:C2:00:00:01', type=0x8808) / struct.pack('!HH', 0x0001, 2000) + + await tb.port_mac[0].rx.send(bytes(lfc_xoff)) + + count = 16 + + pkts = [bytearray([(x+k) % 256 for x in range(1514)]) for k in range(count)] + + tb.loopback_enable = True + + for p in pkts: + await tb.driver.interfaces[0].start_xmit(p, 0) + + for k in range(count): + pkt = await tb.driver.interfaces[0].recv() + + tb.log.info("Packet: %s", pkt) + assert pkt.data == pkts[k] + if tb.driver.interfaces[0].if_feature_rx_csum: + assert pkt.rx_checksum == ~scapy.utils.checksum(bytes(pkt.data[14:])) & 0xffff + + tb.loopback_enable = False + tb.log.info("Read statistics counters") await Timer(2000, 'ns') @@ -786,6 +823,10 @@ def test_mqnic_core_pcie_us(request, if_count, ports_per_if, axis_pcie_data_widt os.path.join(rtl_dir, "stats_dma_latency.v"), os.path.join(rtl_dir, "mqnic_tx_scheduler_block_rr.v"), os.path.join(rtl_dir, "tx_scheduler_rr.v"), + os.path.join(eth_rtl_dir, "mac_ctrl_rx.v"), + os.path.join(eth_rtl_dir, "mac_ctrl_tx.v"), + os.path.join(eth_rtl_dir, "mac_pause_ctrl_rx.v"), + os.path.join(eth_rtl_dir, "mac_pause_ctrl_tx.v"), os.path.join(eth_rtl_dir, "ptp_clock.v"), os.path.join(eth_rtl_dir, "ptp_clock_cdc.v"), os.path.join(eth_rtl_dir, "ptp_perout.v"), @@ -893,6 +934,9 @@ def test_mqnic_core_pcie_us(request, if_count, ports_per_if, axis_pcie_data_widt parameters['TX_CHECKSUM_ENABLE'] = 1 parameters['RX_HASH_ENABLE'] = 1 parameters['RX_CHECKSUM_ENABLE'] = 1 + parameters['LFC_ENABLE'] = 1 + parameters['PFC_ENABLE'] = parameters['LFC_ENABLE'] + parameters['MAC_CTRL_ENABLE'] = 1 parameters['TX_FIFO_DEPTH'] = 32768 parameters['RX_FIFO_DEPTH'] = 131072 parameters['MAX_TX_SIZE'] = 9214 diff --git a/fpga/common/tb/mqnic_core_pcie_us_tdma/Makefile b/fpga/common/tb/mqnic_core_pcie_us_tdma/Makefile index d70fd778a..4ccfef3a4 100644 --- a/fpga/common/tb/mqnic_core_pcie_us_tdma/Makefile +++ b/fpga/common/tb/mqnic_core_pcie_us_tdma/Makefile @@ -55,6 +55,10 @@ VERILOG_SOURCES += ../../rtl/mqnic_tx_scheduler_block_rr_tdma.v VERILOG_SOURCES += ../../rtl/tx_scheduler_rr.v VERILOG_SOURCES += ../../rtl/tx_scheduler_ctrl_tdma.v VERILOG_SOURCES += ../../rtl/tdma_scheduler.v +VERILOG_SOURCES += ../../lib/eth/rtl/mac_ctrl_rx.v +VERILOG_SOURCES += ../../lib/eth/rtl/mac_ctrl_tx.v +VERILOG_SOURCES += ../../lib/eth/rtl/mac_pause_ctrl_rx.v +VERILOG_SOURCES += ../../lib/eth/rtl/mac_pause_ctrl_tx.v VERILOG_SOURCES += ../../lib/eth/rtl/ptp_clock.v VERILOG_SOURCES += ../../lib/eth/rtl/ptp_clock_cdc.v VERILOG_SOURCES += ../../lib/eth/rtl/ptp_perout.v @@ -161,6 +165,9 @@ export PARAM_TX_TAG_WIDTH := 16 export PARAM_TX_CHECKSUM_ENABLE := 1 export PARAM_RX_HASH_ENABLE := 1 export PARAM_RX_CHECKSUM_ENABLE := 1 +export PARAM_LFC_ENABLE := 1 +export PARAM_PFC_ENABLE := $(PARAM_LFC_ENABLE) +export PARAM_MAC_CTRL_ENABLE := 1 export PARAM_TX_FIFO_DEPTH := 32768 export PARAM_RX_FIFO_DEPTH := 131072 export PARAM_MAX_TX_SIZE := 9214 diff --git a/fpga/common/tb/mqnic_core_pcie_us_tdma/test_mqnic_core_pcie_us.py b/fpga/common/tb/mqnic_core_pcie_us_tdma/test_mqnic_core_pcie_us.py index 3003ccb9a..b11a4e3a5 100644 --- a/fpga/common/tb/mqnic_core_pcie_us_tdma/test_mqnic_core_pcie_us.py +++ b/fpga/common/tb/mqnic_core_pcie_us_tdma/test_mqnic_core_pcie_us.py @@ -3,6 +3,7 @@ import logging import os +import struct import sys import scapy.utils @@ -321,7 +322,11 @@ class TB(object): self.port_mac.append(mac) dut.eth_tx_status.setimmediatevalue(2**len(core_inst.m_axis_tx_tvalid)-1) + dut.eth_tx_fc_quanta_clk_en.setimmediatevalue(2**len(core_inst.m_axis_tx_tvalid)-1) dut.eth_rx_status.setimmediatevalue(2**len(core_inst.m_axis_tx_tvalid)-1) + dut.eth_rx_lfc_req.setimmediatevalue(0) + dut.eth_rx_pfc_req.setimmediatevalue(0) + dut.eth_rx_fc_quanta_clk_en.setimmediatevalue(2**len(core_inst.m_axis_tx_tvalid)-1) # DDR self.ddr_group_size = core_inst.DDR_GROUP_SIZE.value @@ -665,13 +670,16 @@ async def run_test_nic(dut): for block in tb.driver.interfaces[0].sched_blocks: await block.schedulers[0].rb.write_dword(mqnic.MQNIC_RB_SCHED_RR_REG_CTRL, 0x00000001) - await tb.driver.interfaces[0].set_rx_queue_map_indir_table(block.index, 0, block.index) + await block.interface.set_rx_queue_map_indir_table(block.index, 0, block.index) for k in range(len(block.interface.txq)): - if k % len(tb.driver.interfaces[0].sched_blocks) == block.index: + if k % len(block.interface.sched_blocks) == block.index: await block.schedulers[0].hw_regs.write_dword(4*k, 0x00000003) else: await block.schedulers[0].hw_regs.write_dword(4*k, 0x00000000) + await block.interface.ports[block.index].set_tx_ctrl(mqnic.MQNIC_PORT_TX_CTRL_EN) + await block.interface.ports[block.index].set_rx_ctrl(mqnic.MQNIC_PORT_RX_CTRL_EN) + count = 64 pkts = [bytearray([(x+k) % 256 for x in range(1514)]) for k in range(count)] @@ -701,6 +709,35 @@ async def run_test_nic(dut): await block.schedulers[0].rb.write_dword(mqnic.MQNIC_RB_SCHED_RR_REG_CTRL, 0x00000000) await tb.driver.interfaces[0].set_rx_queue_map_indir_table(block.index, 0, 0) + if tb.driver.interfaces[0].if_feature_lfc: + tb.log.info("Test LFC pause frame RX") + + await tb.driver.interfaces[0].ports[0].set_lfc_ctrl(mqnic.MQNIC_PORT_LFC_CTRL_TX_LFC_EN | mqnic.MQNIC_PORT_LFC_CTRL_RX_LFC_EN) + await tb.driver.hw_regs.read_dword(0) + + lfc_xoff = Ether(src='DA:D1:D2:D3:D4:D5', dst='01:80:C2:00:00:01', type=0x8808) / struct.pack('!HH', 0x0001, 2000) + + await tb.port_mac[0].rx.send(bytes(lfc_xoff)) + + count = 16 + + pkts = [bytearray([(x+k) % 256 for x in range(1514)]) for k in range(count)] + + tb.loopback_enable = True + + for p in pkts: + await tb.driver.interfaces[0].start_xmit(p, 0) + + for k in range(count): + pkt = await tb.driver.interfaces[0].recv() + + tb.log.info("Packet: %s", pkt) + assert pkt.data == pkts[k] + if tb.driver.interfaces[0].if_feature_rx_csum: + assert pkt.rx_checksum == ~scapy.utils.checksum(bytes(pkt.data[14:])) & 0xffff + + tb.loopback_enable = False + await Timer(1000, 'ns') tb.log.info("TDMA") @@ -841,6 +878,10 @@ def test_mqnic_core_pcie_us(request, if_count, ports_per_if, axis_pcie_data_widt os.path.join(rtl_dir, "tx_scheduler_rr.v"), os.path.join(rtl_dir, "tx_scheduler_ctrl_tdma.v"), os.path.join(rtl_dir, "tdma_scheduler.v"), + os.path.join(eth_rtl_dir, "mac_ctrl_rx.v"), + os.path.join(eth_rtl_dir, "mac_ctrl_tx.v"), + os.path.join(eth_rtl_dir, "mac_pause_ctrl_rx.v"), + os.path.join(eth_rtl_dir, "mac_pause_ctrl_tx.v"), os.path.join(eth_rtl_dir, "ptp_clock.v"), os.path.join(eth_rtl_dir, "ptp_clock_cdc.v"), os.path.join(eth_rtl_dir, "ptp_perout.v"), @@ -948,6 +989,9 @@ def test_mqnic_core_pcie_us(request, if_count, ports_per_if, axis_pcie_data_widt parameters['TX_CHECKSUM_ENABLE'] = 1 parameters['RX_HASH_ENABLE'] = 1 parameters['RX_CHECKSUM_ENABLE'] = 1 + parameters['LFC_ENABLE'] = 1 + parameters['PFC_ENABLE'] = parameters['LFC_ENABLE'] + parameters['MAC_CTRL_ENABLE'] = 1 parameters['TX_FIFO_DEPTH'] = 32768 parameters['RX_FIFO_DEPTH'] = 131072 parameters['MAX_TX_SIZE'] = 9214 diff --git a/fpga/mqnic/250_SoC/fpga_100g/fpga/config.tcl b/fpga/mqnic/250_SoC/fpga_100g/fpga/config.tcl index 5bc35f8f0..17c671f8d 100644 --- a/fpga/mqnic/250_SoC/fpga_100g/fpga/config.tcl +++ b/fpga/mqnic/250_SoC/fpga_100g/fpga/config.tcl @@ -101,6 +101,8 @@ dict set params TX_CPL_FIFO_DEPTH "32" dict set params TX_CHECKSUM_ENABLE "1" dict set params RX_HASH_ENABLE "1" dict set params RX_CHECKSUM_ENABLE "1" +dict set params PFC_ENABLE "1" +dict set params LFC_ENABLE [dict get $params PFC_ENABLE] dict set params TX_FIFO_DEPTH "32768" dict set params RX_FIFO_DEPTH "131072" dict set params MAX_TX_SIZE "9214" diff --git a/fpga/mqnic/250_SoC/fpga_100g/fpga_app_dma_bench/config.tcl b/fpga/mqnic/250_SoC/fpga_100g/fpga_app_dma_bench/config.tcl index 23ba9af58..5f2531b45 100644 --- a/fpga/mqnic/250_SoC/fpga_100g/fpga_app_dma_bench/config.tcl +++ b/fpga/mqnic/250_SoC/fpga_100g/fpga_app_dma_bench/config.tcl @@ -101,6 +101,8 @@ dict set params TX_CPL_FIFO_DEPTH "32" dict set params TX_CHECKSUM_ENABLE "1" dict set params RX_HASH_ENABLE "1" dict set params RX_CHECKSUM_ENABLE "1" +dict set params PFC_ENABLE "1" +dict set params LFC_ENABLE [dict get $params PFC_ENABLE] dict set params TX_FIFO_DEPTH "32768" dict set params RX_FIFO_DEPTH "131072" dict set params MAX_TX_SIZE "9214" diff --git a/fpga/mqnic/250_SoC/fpga_100g/ip/cmac_usplus.tcl b/fpga/mqnic/250_SoC/fpga_100g/ip/cmac_usplus.tcl index b86d4ea5e..af9cc8265 100644 --- a/fpga/mqnic/250_SoC/fpga_100g/ip/cmac_usplus.tcl +++ b/fpga/mqnic/250_SoC/fpga_100g/ip/cmac_usplus.tcl @@ -7,8 +7,10 @@ set_property -dict [list \ CONFIG.USER_INTERFACE {AXIS} \ CONFIG.GT_DRP_CLK {125} \ CONFIG.GT_LOCATION {0} \ - CONFIG.TX_FLOW_CONTROL {0} \ - CONFIG.RX_FLOW_CONTROL {0} \ + CONFIG.TX_FLOW_CONTROL {1} \ + CONFIG.RX_FLOW_CONTROL {1} \ + CONFIG.RX_FORWARD_CONTROL_FRAMES {0} \ + CONFIG.RX_CHECK_ACK {1} \ CONFIG.INCLUDE_RS_FEC {1} \ CONFIG.ENABLE_TIME_STAMPING {1} ] [get_ips cmac_usplus] diff --git a/fpga/mqnic/250_SoC/fpga_100g/rtl/fpga.v b/fpga/mqnic/250_SoC/fpga_100g/rtl/fpga.v index a631f89e5..bad7d7bb7 100644 --- a/fpga/mqnic/250_SoC/fpga_100g/rtl/fpga.v +++ b/fpga/mqnic/250_SoC/fpga_100g/rtl/fpga.v @@ -71,6 +71,8 @@ module fpga # parameter TX_CHECKSUM_ENABLE = 1, parameter RX_HASH_ENABLE = 1, parameter RX_CHECKSUM_ENABLE = 1, + parameter PFC_ENABLE = 1, + parameter LFC_ENABLE = PFC_ENABLE, parameter TX_FIFO_DEPTH = 32768, parameter RX_FIFO_DEPTH = 131072, parameter MAX_TX_SIZE = 9214, @@ -720,7 +722,20 @@ wire qsfp0_drp_we; wire [15:0] qsfp0_drp_do; wire qsfp0_drp_rdy; -wire qsfp0_rx_status; +wire qsfp0_tx_enable; +wire qsfp0_tx_lfc_en; +wire qsfp0_tx_lfc_req; +wire [7:0] qsfp0_tx_pfc_en; +wire [7:0] qsfp0_tx_pfc_req; + +wire qsfp0_rx_enable; +wire qsfp0_rx_status; +wire qsfp0_rx_lfc_en; +wire qsfp0_rx_lfc_req; +wire qsfp0_rx_lfc_ack; +wire [7:0] qsfp0_rx_pfc_en; +wire [7:0] qsfp0_rx_pfc_req; +wire [7:0] qsfp0_rx_pfc_ack; wire qsfp0_gtpowergood; @@ -813,6 +828,12 @@ qsfp0_cmac_inst ( .tx_ptp_ts_tag(qsfp0_tx_ptp_ts_tag_int), .tx_ptp_ts_valid(qsfp0_tx_ptp_ts_valid_int), + .tx_enable(qsfp0_tx_enable), + .tx_lfc_en(qsfp0_tx_lfc_en), + .tx_lfc_req(qsfp0_tx_lfc_req), + .tx_pfc_en(qsfp0_tx_pfc_en), + .tx_pfc_req(qsfp0_tx_pfc_req), + .rx_clk(qsfp0_rx_clk_int), .rx_rst(qsfp0_rx_rst_int), @@ -826,7 +847,14 @@ qsfp0_cmac_inst ( .rx_ptp_rst(qsfp0_rx_ptp_rst_int), .rx_ptp_time(qsfp0_rx_ptp_time_int), - .rx_status(qsfp0_rx_status) + .rx_enable(qsfp0_rx_enable), + .rx_status(qsfp0_rx_status), + .rx_lfc_en(qsfp0_rx_lfc_en), + .rx_lfc_req(qsfp0_rx_lfc_req), + .rx_lfc_ack(qsfp0_rx_lfc_ack), + .rx_pfc_en(qsfp0_rx_pfc_en), + .rx_pfc_req(qsfp0_rx_pfc_req), + .rx_pfc_ack(qsfp0_rx_pfc_ack) ); // QSFP1 CMAC @@ -867,7 +895,20 @@ wire qsfp1_drp_we; wire [15:0] qsfp1_drp_do; wire qsfp1_drp_rdy; -wire qsfp1_rx_status; +wire qsfp1_tx_enable; +wire qsfp1_tx_lfc_en; +wire qsfp1_tx_lfc_req; +wire [7:0] qsfp1_tx_pfc_en; +wire [7:0] qsfp1_tx_pfc_req; + +wire qsfp1_rx_enable; +wire qsfp1_rx_status; +wire qsfp1_rx_lfc_en; +wire qsfp1_rx_lfc_req; +wire qsfp1_rx_lfc_ack; +wire [7:0] qsfp1_rx_pfc_en; +wire [7:0] qsfp1_rx_pfc_req; +wire [7:0] qsfp1_rx_pfc_ack; wire qsfp1_gtpowergood; @@ -960,6 +1001,12 @@ qsfp1_cmac_inst ( .tx_ptp_ts_tag(qsfp1_tx_ptp_ts_tag_int), .tx_ptp_ts_valid(qsfp1_tx_ptp_ts_valid_int), + .tx_enable(qsfp1_tx_enable), + .tx_lfc_en(qsfp1_tx_lfc_en), + .tx_lfc_req(qsfp1_tx_lfc_req), + .tx_pfc_en(qsfp1_tx_pfc_en), + .tx_pfc_req(qsfp1_tx_pfc_req), + .rx_clk(qsfp1_rx_clk_int), .rx_rst(qsfp1_rx_rst_int), @@ -973,7 +1020,14 @@ qsfp1_cmac_inst ( .rx_ptp_rst(qsfp1_rx_ptp_rst_int), .rx_ptp_time(qsfp1_rx_ptp_time_int), - .rx_status(qsfp1_rx_status) + .rx_enable(qsfp1_rx_enable), + .rx_status(qsfp1_rx_status), + .rx_lfc_en(qsfp1_rx_lfc_en), + .rx_lfc_req(qsfp1_rx_lfc_req), + .rx_lfc_ack(qsfp1_rx_lfc_ack), + .rx_pfc_en(qsfp1_rx_pfc_en), + .rx_pfc_req(qsfp1_rx_pfc_req), + .rx_pfc_ack(qsfp1_rx_pfc_ack) ); wire ptp_clk; @@ -1241,6 +1295,8 @@ fpga_core #( .TX_CHECKSUM_ENABLE(TX_CHECKSUM_ENABLE), .RX_HASH_ENABLE(RX_HASH_ENABLE), .RX_CHECKSUM_ENABLE(RX_CHECKSUM_ENABLE), + .PFC_ENABLE(PFC_ENABLE), + .LFC_ENABLE(LFC_ENABLE), .TX_FIFO_DEPTH(TX_FIFO_DEPTH), .RX_FIFO_DEPTH(RX_FIFO_DEPTH), .MAX_TX_SIZE(MAX_TX_SIZE), @@ -1458,6 +1514,12 @@ core_inst ( .qsfp0_tx_ptp_ts_tag(qsfp0_tx_ptp_ts_tag_int), .qsfp0_tx_ptp_ts_valid(qsfp0_tx_ptp_ts_valid_int), + .qsfp0_tx_enable(qsfp0_tx_enable), + .qsfp0_tx_lfc_en(qsfp0_tx_lfc_en), + .qsfp0_tx_lfc_req(qsfp0_tx_lfc_req), + .qsfp0_tx_pfc_en(qsfp0_tx_pfc_en), + .qsfp0_tx_pfc_req(qsfp0_tx_pfc_req), + .qsfp0_rx_clk(qsfp0_rx_clk_int), .qsfp0_rx_rst(qsfp0_rx_rst_int), .qsfp0_rx_axis_tdata(qsfp0_rx_axis_tdata_int), @@ -1469,7 +1531,14 @@ core_inst ( .qsfp0_rx_ptp_rst(qsfp0_rx_ptp_rst_int), .qsfp0_rx_ptp_time(qsfp0_rx_ptp_time_int), + .qsfp0_rx_enable(qsfp0_rx_enable), .qsfp0_rx_status(qsfp0_rx_status), + .qsfp0_rx_lfc_en(qsfp0_rx_lfc_en), + .qsfp0_rx_lfc_req(qsfp0_rx_lfc_req), + .qsfp0_rx_lfc_ack(qsfp0_rx_lfc_ack), + .qsfp0_rx_pfc_en(qsfp0_rx_pfc_en), + .qsfp0_rx_pfc_req(qsfp0_rx_pfc_req), + .qsfp0_rx_pfc_ack(qsfp0_rx_pfc_ack), .qsfp0_drp_clk(qsfp0_drp_clk), .qsfp0_drp_rst(qsfp0_drp_rst), @@ -1498,6 +1567,12 @@ core_inst ( .qsfp1_tx_ptp_ts_tag(qsfp1_tx_ptp_ts_tag_int), .qsfp1_tx_ptp_ts_valid(qsfp1_tx_ptp_ts_valid_int), + .qsfp1_tx_enable(qsfp1_tx_enable), + .qsfp1_tx_lfc_en(qsfp1_tx_lfc_en), + .qsfp1_tx_lfc_req(qsfp1_tx_lfc_req), + .qsfp1_tx_pfc_en(qsfp1_tx_pfc_en), + .qsfp1_tx_pfc_req(qsfp1_tx_pfc_req), + .qsfp1_rx_clk(qsfp1_rx_clk_int), .qsfp1_rx_rst(qsfp1_rx_rst_int), .qsfp1_rx_axis_tdata(qsfp1_rx_axis_tdata_int), @@ -1509,7 +1584,14 @@ core_inst ( .qsfp1_rx_ptp_rst(qsfp1_rx_ptp_rst_int), .qsfp1_rx_ptp_time(qsfp1_rx_ptp_time_int), + .qsfp1_rx_enable(qsfp1_rx_enable), .qsfp1_rx_status(qsfp1_rx_status), + .qsfp1_rx_lfc_en(qsfp1_rx_lfc_en), + .qsfp1_rx_lfc_req(qsfp1_rx_lfc_req), + .qsfp1_rx_lfc_ack(qsfp1_rx_lfc_ack), + .qsfp1_rx_pfc_en(qsfp1_rx_pfc_en), + .qsfp1_rx_pfc_req(qsfp1_rx_pfc_req), + .qsfp1_rx_pfc_ack(qsfp1_rx_pfc_ack), .qsfp1_drp_clk(qsfp1_drp_clk), .qsfp1_drp_rst(qsfp1_drp_rst), diff --git a/fpga/mqnic/250_SoC/fpga_100g/rtl/fpga_core.v b/fpga/mqnic/250_SoC/fpga_100g/rtl/fpga_core.v index 69cddcf90..c0848225b 100644 --- a/fpga/mqnic/250_SoC/fpga_100g/rtl/fpga_core.v +++ b/fpga/mqnic/250_SoC/fpga_100g/rtl/fpga_core.v @@ -77,6 +77,8 @@ module fpga_core # parameter TX_CHECKSUM_ENABLE = 1, parameter RX_HASH_ENABLE = 1, parameter RX_CHECKSUM_ENABLE = 1, + parameter PFC_ENABLE = 1, + parameter LFC_ENABLE = PFC_ENABLE, parameter TX_FIFO_DEPTH = 32768, parameter RX_FIFO_DEPTH = 131072, parameter MAX_TX_SIZE = 9214, @@ -296,6 +298,12 @@ module fpga_core # input wire [15:0] qsfp0_tx_ptp_ts_tag, input wire qsfp0_tx_ptp_ts_valid, + output wire qsfp0_tx_enable, + output wire qsfp0_tx_lfc_en, + output wire qsfp0_tx_lfc_req, + output wire [7:0] qsfp0_tx_pfc_en, + output wire [7:0] qsfp0_tx_pfc_req, + input wire qsfp0_rx_clk, input wire qsfp0_rx_rst, @@ -309,7 +317,14 @@ module fpga_core # input wire qsfp0_rx_ptp_rst, output wire [79:0] qsfp0_rx_ptp_time, + output wire qsfp0_rx_enable, input wire qsfp0_rx_status, + output wire qsfp0_rx_lfc_en, + input wire qsfp0_rx_lfc_req, + output wire qsfp0_rx_lfc_ack, + output wire [7:0] qsfp0_rx_pfc_en, + input wire [7:0] qsfp0_rx_pfc_req, + output wire [7:0] qsfp0_rx_pfc_ack, input wire qsfp0_drp_clk, input wire qsfp0_drp_rst, @@ -340,6 +355,12 @@ module fpga_core # input wire [15:0] qsfp1_tx_ptp_ts_tag, input wire qsfp1_tx_ptp_ts_valid, + output wire qsfp1_tx_enable, + output wire qsfp1_tx_lfc_en, + output wire qsfp1_tx_lfc_req, + output wire [7:0] qsfp1_tx_pfc_en, + output wire [7:0] qsfp1_tx_pfc_req, + input wire qsfp1_rx_clk, input wire qsfp1_rx_rst, @@ -353,7 +374,14 @@ module fpga_core # input wire qsfp1_rx_ptp_rst, output wire [79:0] qsfp1_rx_ptp_time, + output wire qsfp1_rx_enable, input wire qsfp1_rx_status, + output wire qsfp1_rx_lfc_en, + input wire qsfp1_rx_lfc_req, + output wire qsfp1_rx_lfc_ack, + output wire [7:0] qsfp1_rx_pfc_en, + input wire [7:0] qsfp1_rx_pfc_req, + output wire [7:0] qsfp1_rx_pfc_ack, input wire qsfp1_drp_clk, input wire qsfp1_drp_rst, @@ -760,7 +788,12 @@ wire [PORT_COUNT*TX_TAG_WIDTH-1:0] axis_eth_tx_ptp_ts_tag; wire [PORT_COUNT-1:0] axis_eth_tx_ptp_ts_valid; wire [PORT_COUNT-1:0] axis_eth_tx_ptp_ts_ready; +wire [PORT_COUNT-1:0] eth_tx_enable; wire [PORT_COUNT-1:0] eth_tx_status; +wire [PORT_COUNT-1:0] eth_tx_lfc_en; +wire [PORT_COUNT-1:0] eth_tx_lfc_req; +wire [PORT_COUNT*8-1:0] eth_tx_pfc_en; +wire [PORT_COUNT*8-1:0] eth_tx_pfc_req; wire [PORT_COUNT-1:0] eth_rx_clk; wire [PORT_COUNT-1:0] eth_rx_rst; @@ -777,7 +810,14 @@ wire [PORT_COUNT-1:0] axis_eth_rx_tready; wire [PORT_COUNT-1:0] axis_eth_rx_tlast; wire [PORT_COUNT*AXIS_ETH_RX_USER_WIDTH-1:0] axis_eth_rx_tuser; +wire [PORT_COUNT-1:0] eth_rx_enable; wire [PORT_COUNT-1:0] eth_rx_status; +wire [PORT_COUNT-1:0] eth_rx_lfc_en; +wire [PORT_COUNT-1:0] eth_rx_lfc_req; +wire [PORT_COUNT-1:0] eth_rx_lfc_ack; +wire [PORT_COUNT*8-1:0] eth_rx_pfc_en; +wire [PORT_COUNT*8-1:0] eth_rx_pfc_req; +wire [PORT_COUNT*8-1:0] eth_rx_pfc_ack; wire [PTP_TS_WIDTH-1:0] qsfp0_tx_ptp_time_int; wire [PTP_TS_WIDTH-1:0] qsfp1_tx_ptp_time_int; @@ -828,7 +868,12 @@ mqnic_port_map_mac_axis_inst ( .s_axis_mac_tx_ptp_ts_valid({qsfp1_tx_ptp_ts_valid, qsfp0_tx_ptp_ts_valid}), .s_axis_mac_tx_ptp_ts_ready(), + .mac_tx_enable({qsfp1_tx_enable, qsfp0_tx_enable}), .mac_tx_status(2'b11), + .mac_tx_lfc_en({qsfp1_tx_lfc_en, qsfp0_tx_lfc_en}), + .mac_tx_lfc_req({qsfp1_tx_lfc_req, qsfp0_tx_lfc_req}), + .mac_tx_pfc_en({qsfp1_tx_pfc_en, qsfp0_tx_pfc_en}), + .mac_tx_pfc_req({qsfp1_tx_pfc_req, qsfp0_tx_pfc_req}), .mac_rx_clk({qsfp1_rx_clk, qsfp0_rx_clk}), .mac_rx_rst({qsfp1_rx_rst, qsfp0_rx_rst}), @@ -845,7 +890,14 @@ mqnic_port_map_mac_axis_inst ( .s_axis_mac_rx_tlast({qsfp1_rx_axis_tlast, qsfp0_rx_axis_tlast}), .s_axis_mac_rx_tuser({{qsfp1_rx_axis_tuser[80:1], 16'd0, qsfp1_rx_axis_tuser[0]}, {qsfp0_rx_axis_tuser[80:1], 16'd0, qsfp0_rx_axis_tuser[0]}}), + .mac_rx_enable({qsfp1_rx_enable, qsfp0_rx_enable}), .mac_rx_status({qsfp1_rx_status, qsfp0_rx_status}), + .mac_rx_lfc_en({qsfp1_rx_lfc_en, qsfp0_rx_lfc_en}), + .mac_rx_lfc_req({qsfp1_rx_lfc_req, qsfp0_rx_lfc_req}), + .mac_rx_lfc_ack({qsfp1_rx_lfc_ack, qsfp0_rx_lfc_ack}), + .mac_rx_pfc_en({qsfp1_rx_pfc_en, qsfp0_rx_pfc_en}), + .mac_rx_pfc_req({qsfp1_rx_pfc_req, qsfp0_rx_pfc_req}), + .mac_rx_pfc_ack({qsfp1_rx_pfc_ack, qsfp0_rx_pfc_ack}), // towards datapath .tx_clk(eth_tx_clk), @@ -868,7 +920,12 @@ mqnic_port_map_mac_axis_inst ( .m_axis_tx_ptp_ts_valid(axis_eth_tx_ptp_ts_valid), .m_axis_tx_ptp_ts_ready(axis_eth_tx_ptp_ts_ready), + .tx_enable(eth_tx_enable), .tx_status(eth_tx_status), + .tx_lfc_en(eth_tx_lfc_en), + .tx_lfc_req(eth_tx_lfc_req), + .tx_pfc_en(eth_tx_pfc_en), + .tx_pfc_req(eth_tx_pfc_req), .rx_clk(eth_rx_clk), .rx_rst(eth_rx_rst), @@ -885,7 +942,14 @@ mqnic_port_map_mac_axis_inst ( .m_axis_rx_tlast(axis_eth_rx_tlast), .m_axis_rx_tuser(axis_eth_rx_tuser), - .rx_status(eth_rx_status) + .rx_enable(eth_rx_enable), + .rx_status(eth_rx_status), + .rx_lfc_en(eth_rx_lfc_en), + .rx_lfc_req(eth_rx_lfc_req), + .rx_lfc_ack(eth_rx_lfc_ack), + .rx_pfc_en(eth_rx_pfc_en), + .rx_pfc_req(eth_rx_pfc_req), + .rx_pfc_ack(eth_rx_pfc_ack) ); mqnic_core_pcie_us #( @@ -955,6 +1019,9 @@ mqnic_core_pcie_us #( .TX_CHECKSUM_ENABLE(TX_CHECKSUM_ENABLE), .RX_HASH_ENABLE(RX_HASH_ENABLE), .RX_CHECKSUM_ENABLE(RX_CHECKSUM_ENABLE), + .PFC_ENABLE(PFC_ENABLE), + .LFC_ENABLE(LFC_ENABLE), + .MAC_CTRL_ENABLE(0), .TX_FIFO_DEPTH(TX_FIFO_DEPTH), .RX_FIFO_DEPTH(RX_FIFO_DEPTH), .MAX_TX_SIZE(MAX_TX_SIZE), @@ -1236,7 +1303,13 @@ core_inst ( .s_axis_eth_tx_cpl_valid(axis_eth_tx_ptp_ts_valid), .s_axis_eth_tx_cpl_ready(axis_eth_tx_ptp_ts_ready), + .eth_tx_enable(eth_tx_enable), .eth_tx_status(eth_tx_status), + .eth_tx_lfc_en(eth_tx_lfc_en), + .eth_tx_lfc_req(eth_tx_lfc_req), + .eth_tx_pfc_en(eth_tx_pfc_en), + .eth_tx_pfc_req(eth_tx_pfc_req), + .eth_tx_fc_quanta_clk_en(0), .eth_rx_clk(eth_rx_clk), .eth_rx_rst(eth_rx_rst), @@ -1253,7 +1326,15 @@ core_inst ( .s_axis_eth_rx_tlast(axis_eth_rx_tlast), .s_axis_eth_rx_tuser(axis_eth_rx_tuser), + .eth_rx_enable(eth_rx_enable), .eth_rx_status(eth_rx_status), + .eth_rx_lfc_en(eth_rx_lfc_en), + .eth_rx_lfc_req(eth_rx_lfc_req), + .eth_rx_lfc_ack(eth_rx_lfc_ack), + .eth_rx_pfc_en(eth_rx_pfc_en), + .eth_rx_pfc_req(eth_rx_pfc_req), + .eth_rx_pfc_ack(eth_rx_pfc_ack), + .eth_rx_fc_quanta_clk_en(0), /* * DDR diff --git a/fpga/mqnic/250_SoC/fpga_100g/tb/fpga_core/Makefile b/fpga/mqnic/250_SoC/fpga_100g/tb/fpga_core/Makefile index 3464f2294..e0a17fb58 100644 --- a/fpga/mqnic/250_SoC/fpga_100g/tb/fpga_core/Makefile +++ b/fpga/mqnic/250_SoC/fpga_100g/tb/fpga_core/Makefile @@ -161,6 +161,8 @@ export PARAM_TX_CPL_FIFO_DEPTH := 32 export PARAM_TX_CHECKSUM_ENABLE := 1 export PARAM_RX_HASH_ENABLE := 1 export PARAM_RX_CHECKSUM_ENABLE := 1 +export PARAM_LFC_ENABLE := 1 +export PARAM_PFC_ENABLE := $(PARAM_LFC_ENABLE) export PARAM_TX_FIFO_DEPTH := 32768 export PARAM_RX_FIFO_DEPTH := 131072 export PARAM_MAX_TX_SIZE := 9214 diff --git a/fpga/mqnic/250_SoC/fpga_100g/tb/fpga_core/test_fpga_core.py b/fpga/mqnic/250_SoC/fpga_100g/tb/fpga_core/test_fpga_core.py index 6154ae2c8..463b97a66 100644 --- a/fpga/mqnic/250_SoC/fpga_100g/tb/fpga_core/test_fpga_core.py +++ b/fpga/mqnic/250_SoC/fpga_100g/tb/fpga_core/test_fpga_core.py @@ -300,6 +300,8 @@ class TB(object): self.qsfp_mac.append(mac) getattr(dut, f"qsfp{k}_rx_status").setimmediatevalue(1) + getattr(dut, f"qsfp{k}_rx_lfc_req").setimmediatevalue(0) + getattr(dut, f"qsfp{k}_rx_pfc_req").setimmediatevalue(0) cocotb.start_soon(Clock(getattr(dut, f"qsfp{k}_drp_clk"), 8, units="ns").start()) getattr(dut, f"qsfp{k}_drp_rst").setimmediatevalue(0) @@ -723,6 +725,8 @@ def test_fpga_core(request): parameters['TX_CHECKSUM_ENABLE'] = 1 parameters['RX_HASH_ENABLE'] = 1 parameters['RX_CHECKSUM_ENABLE'] = 1 + parameters['LFC_ENABLE'] = 1 + parameters['PFC_ENABLE'] = parameters['LFC_ENABLE'] parameters['TX_FIFO_DEPTH'] = 32768 parameters['RX_FIFO_DEPTH'] = 131072 parameters['MAX_TX_SIZE'] = 9214 diff --git a/fpga/mqnic/250_SoC/fpga_25g/fpga/Makefile b/fpga/mqnic/250_SoC/fpga_25g/fpga/Makefile index dd60d684a..54894f575 100644 --- a/fpga/mqnic/250_SoC/fpga_25g/fpga/Makefile +++ b/fpga/mqnic/250_SoC/fpga_25g/fpga/Makefile @@ -61,6 +61,10 @@ SYN_FILES += rtl/common/tdma_ber_ch.v SYN_FILES += lib/eth/rtl/eth_mac_10g.v SYN_FILES += lib/eth/rtl/axis_xgmii_rx_64.v SYN_FILES += lib/eth/rtl/axis_xgmii_tx_64.v +SYN_FILES += lib/eth/rtl/mac_ctrl_rx.v +SYN_FILES += lib/eth/rtl/mac_ctrl_tx.v +SYN_FILES += lib/eth/rtl/mac_pause_ctrl_rx.v +SYN_FILES += lib/eth/rtl/mac_pause_ctrl_tx.v SYN_FILES += lib/eth/rtl/eth_phy_10g.v SYN_FILES += lib/eth/rtl/eth_phy_10g_rx.v SYN_FILES += lib/eth/rtl/eth_phy_10g_rx_if.v diff --git a/fpga/mqnic/250_SoC/fpga_25g/fpga/config.tcl b/fpga/mqnic/250_SoC/fpga_25g/fpga/config.tcl index daced677a..8150f3ab3 100644 --- a/fpga/mqnic/250_SoC/fpga_25g/fpga/config.tcl +++ b/fpga/mqnic/250_SoC/fpga_25g/fpga/config.tcl @@ -113,6 +113,8 @@ dict set params TX_CPL_FIFO_DEPTH "32" dict set params TX_CHECKSUM_ENABLE "1" dict set params RX_HASH_ENABLE "1" dict set params RX_CHECKSUM_ENABLE "1" +dict set params PFC_ENABLE "1" +dict set params LFC_ENABLE [dict get $params PFC_ENABLE] dict set params ENABLE_PADDING "1" dict set params ENABLE_DIC "1" dict set params MIN_FRAME_LENGTH "64" diff --git a/fpga/mqnic/250_SoC/fpga_25g/fpga_10g/Makefile b/fpga/mqnic/250_SoC/fpga_25g/fpga_10g/Makefile index dd60d684a..54894f575 100644 --- a/fpga/mqnic/250_SoC/fpga_25g/fpga_10g/Makefile +++ b/fpga/mqnic/250_SoC/fpga_25g/fpga_10g/Makefile @@ -61,6 +61,10 @@ SYN_FILES += rtl/common/tdma_ber_ch.v SYN_FILES += lib/eth/rtl/eth_mac_10g.v SYN_FILES += lib/eth/rtl/axis_xgmii_rx_64.v SYN_FILES += lib/eth/rtl/axis_xgmii_tx_64.v +SYN_FILES += lib/eth/rtl/mac_ctrl_rx.v +SYN_FILES += lib/eth/rtl/mac_ctrl_tx.v +SYN_FILES += lib/eth/rtl/mac_pause_ctrl_rx.v +SYN_FILES += lib/eth/rtl/mac_pause_ctrl_tx.v SYN_FILES += lib/eth/rtl/eth_phy_10g.v SYN_FILES += lib/eth/rtl/eth_phy_10g_rx.v SYN_FILES += lib/eth/rtl/eth_phy_10g_rx_if.v diff --git a/fpga/mqnic/250_SoC/fpga_25g/fpga_10g/config.tcl b/fpga/mqnic/250_SoC/fpga_25g/fpga_10g/config.tcl index 01acc3f42..01a8239e7 100644 --- a/fpga/mqnic/250_SoC/fpga_25g/fpga_10g/config.tcl +++ b/fpga/mqnic/250_SoC/fpga_25g/fpga_10g/config.tcl @@ -113,6 +113,8 @@ dict set params TX_CPL_FIFO_DEPTH "32" dict set params TX_CHECKSUM_ENABLE "1" dict set params RX_HASH_ENABLE "1" dict set params RX_CHECKSUM_ENABLE "1" +dict set params PFC_ENABLE "1" +dict set params LFC_ENABLE [dict get $params PFC_ENABLE] dict set params ENABLE_PADDING "1" dict set params ENABLE_DIC "1" dict set params MIN_FRAME_LENGTH "64" diff --git a/fpga/mqnic/250_SoC/fpga_25g/rtl/fpga.v b/fpga/mqnic/250_SoC/fpga_25g/rtl/fpga.v index 50a45fb0c..5fdf2c0d7 100644 --- a/fpga/mqnic/250_SoC/fpga_25g/rtl/fpga.v +++ b/fpga/mqnic/250_SoC/fpga_25g/rtl/fpga.v @@ -74,6 +74,8 @@ module fpga # parameter TX_CHECKSUM_ENABLE = 1, parameter RX_HASH_ENABLE = 1, parameter RX_CHECKSUM_ENABLE = 1, + parameter PFC_ENABLE = 1, + parameter LFC_ENABLE = PFC_ENABLE, parameter ENABLE_PADDING = 1, parameter ENABLE_DIC = 1, parameter MIN_FRAME_LENGTH = 64, @@ -1376,6 +1378,8 @@ fpga_core #( .TX_CHECKSUM_ENABLE(TX_CHECKSUM_ENABLE), .RX_HASH_ENABLE(RX_HASH_ENABLE), .RX_CHECKSUM_ENABLE(RX_CHECKSUM_ENABLE), + .PFC_ENABLE(PFC_ENABLE), + .LFC_ENABLE(LFC_ENABLE), .ENABLE_PADDING(ENABLE_PADDING), .ENABLE_DIC(ENABLE_DIC), .MIN_FRAME_LENGTH(MIN_FRAME_LENGTH), diff --git a/fpga/mqnic/250_SoC/fpga_25g/rtl/fpga_core.v b/fpga/mqnic/250_SoC/fpga_25g/rtl/fpga_core.v index 1beb6097a..787ef125c 100644 --- a/fpga/mqnic/250_SoC/fpga_25g/rtl/fpga_core.v +++ b/fpga/mqnic/250_SoC/fpga_25g/rtl/fpga_core.v @@ -81,6 +81,8 @@ module fpga_core # parameter TX_CHECKSUM_ENABLE = 1, parameter RX_HASH_ENABLE = 1, parameter RX_CHECKSUM_ENABLE = 1, + parameter PFC_ENABLE = 1, + parameter LFC_ENABLE = PFC_ENABLE, parameter ENABLE_PADDING = 1, parameter ENABLE_DIC = 1, parameter MIN_FRAME_LENGTH = 64, @@ -902,7 +904,12 @@ wire [PORT_COUNT*TX_TAG_WIDTH-1:0] axis_eth_tx_ptp_ts_tag; wire [PORT_COUNT-1:0] axis_eth_tx_ptp_ts_valid; wire [PORT_COUNT-1:0] axis_eth_tx_ptp_ts_ready; +wire [PORT_COUNT-1:0] eth_tx_enable; wire [PORT_COUNT-1:0] eth_tx_status; +wire [PORT_COUNT-1:0] eth_tx_lfc_en; +wire [PORT_COUNT-1:0] eth_tx_lfc_req; +wire [PORT_COUNT*8-1:0] eth_tx_pfc_en; +wire [PORT_COUNT*8-1:0] eth_tx_pfc_req; wire [PORT_COUNT-1:0] eth_rx_clk; wire [PORT_COUNT-1:0] eth_rx_rst; @@ -917,7 +924,14 @@ wire [PORT_COUNT-1:0] axis_eth_rx_tready; wire [PORT_COUNT-1:0] axis_eth_rx_tlast; wire [PORT_COUNT*AXIS_ETH_RX_USER_WIDTH-1:0] axis_eth_rx_tuser; +wire [PORT_COUNT-1:0] eth_rx_enable; wire [PORT_COUNT-1:0] eth_rx_status; +wire [PORT_COUNT-1:0] eth_rx_lfc_en; +wire [PORT_COUNT-1:0] eth_rx_lfc_req; +wire [PORT_COUNT-1:0] eth_rx_lfc_ack; +wire [PORT_COUNT*8-1:0] eth_rx_pfc_en; +wire [PORT_COUNT*8-1:0] eth_rx_pfc_req; +wire [PORT_COUNT*8-1:0] eth_rx_pfc_ack; wire [PORT_COUNT-1:0] port_xgmii_tx_clk; wire [PORT_COUNT-1:0] port_xgmii_tx_rst; @@ -990,12 +1004,15 @@ generate .PTP_PERIOD_FNS(IF_PTP_PERIOD_FNS), .TX_PTP_TS_ENABLE(PTP_TS_ENABLE), .TX_PTP_TS_WIDTH(PTP_TS_WIDTH), + .TX_PTP_TS_CTRL_IN_TUSER(0), .TX_PTP_TAG_ENABLE(PTP_TS_ENABLE), .TX_PTP_TAG_WIDTH(TX_TAG_WIDTH), .RX_PTP_TS_ENABLE(PTP_TS_ENABLE), .RX_PTP_TS_WIDTH(PTP_TS_WIDTH), .TX_USER_WIDTH(AXIS_ETH_TX_USER_WIDTH), - .RX_USER_WIDTH(AXIS_ETH_RX_USER_WIDTH) + .RX_USER_WIDTH(AXIS_ETH_RX_USER_WIDTH), + .PFC_ENABLE(PFC_ENABLE), + .PAUSE_ENABLE(LFC_ENABLE) ) eth_mac_inst ( .tx_clk(port_xgmii_tx_clk[n]), @@ -1003,6 +1020,9 @@ generate .rx_clk(port_xgmii_rx_clk[n]), .rx_rst(port_xgmii_rx_rst[n]), + /* + * AXI input + */ .tx_axis_tdata(axis_eth_tx_tdata[n*AXIS_ETH_DATA_WIDTH +: AXIS_ETH_DATA_WIDTH]), .tx_axis_tkeep(axis_eth_tx_tkeep[n*AXIS_ETH_KEEP_WIDTH +: AXIS_ETH_KEEP_WIDTH]), .tx_axis_tvalid(axis_eth_tx_tvalid[n +: 1]), @@ -1010,30 +1030,121 @@ generate .tx_axis_tlast(axis_eth_tx_tlast[n +: 1]), .tx_axis_tuser(axis_eth_tx_tuser[n*AXIS_ETH_TX_USER_WIDTH +: AXIS_ETH_TX_USER_WIDTH]), + /* + * AXI output + */ .rx_axis_tdata(axis_eth_rx_tdata[n*AXIS_ETH_DATA_WIDTH +: AXIS_ETH_DATA_WIDTH]), .rx_axis_tkeep(axis_eth_rx_tkeep[n*AXIS_ETH_KEEP_WIDTH +: AXIS_ETH_KEEP_WIDTH]), .rx_axis_tvalid(axis_eth_rx_tvalid[n +: 1]), .rx_axis_tlast(axis_eth_rx_tlast[n +: 1]), .rx_axis_tuser(axis_eth_rx_tuser[n*AXIS_ETH_RX_USER_WIDTH +: AXIS_ETH_RX_USER_WIDTH]), + /* + * XGMII interface + */ .xgmii_rxd(port_xgmii_rxd[n*XGMII_DATA_WIDTH +: XGMII_DATA_WIDTH]), .xgmii_rxc(port_xgmii_rxc[n*XGMII_CTRL_WIDTH +: XGMII_CTRL_WIDTH]), .xgmii_txd(port_xgmii_txd[n*XGMII_DATA_WIDTH +: XGMII_DATA_WIDTH]), .xgmii_txc(port_xgmii_txc[n*XGMII_CTRL_WIDTH +: XGMII_CTRL_WIDTH]), + /* + * PTP + */ .tx_ptp_ts(eth_tx_ptp_ts_96[n*PTP_TS_WIDTH +: PTP_TS_WIDTH]), .rx_ptp_ts(eth_rx_ptp_ts_96[n*PTP_TS_WIDTH +: PTP_TS_WIDTH]), .tx_axis_ptp_ts(axis_eth_tx_ptp_ts[n*PTP_TS_WIDTH +: PTP_TS_WIDTH]), .tx_axis_ptp_ts_tag(axis_eth_tx_ptp_ts_tag[n*TX_TAG_WIDTH +: TX_TAG_WIDTH]), .tx_axis_ptp_ts_valid(axis_eth_tx_ptp_ts_valid[n +: 1]), + /* + * Link-level Flow Control (LFC) (IEEE 802.3 annex 31B PAUSE) + */ + .tx_lfc_req(eth_tx_lfc_req[n +: 1]), + .tx_lfc_resend(1'b0), + .rx_lfc_en(eth_rx_lfc_en[n +: 1]), + .rx_lfc_req(eth_rx_lfc_req[n +: 1]), + .rx_lfc_ack(eth_rx_lfc_ack[n +: 1]), + + /* + * Priority Flow Control (PFC) (IEEE 802.3 annex 31D PFC) + */ + .tx_pfc_req(eth_tx_pfc_req[n*8 +: 8]), + .tx_pfc_resend(1'b0), + .rx_pfc_en(eth_rx_pfc_en[n*8 +: 8]), + .rx_pfc_req(eth_rx_pfc_req[n*8 +: 8]), + .rx_pfc_ack(eth_rx_pfc_ack[n*8 +: 8]), + + /* + * Pause interface + */ + .tx_lfc_pause_en(1'b1), + .tx_pause_req(1'b0), + .tx_pause_ack(), + + /* + * Status + */ + .tx_start_packet(), .tx_error_underflow(), + .rx_start_packet(), .rx_error_bad_frame(), .rx_error_bad_fcs(), + .stat_tx_mcf(), + .stat_rx_mcf(), + .stat_tx_lfc_pkt(), + .stat_tx_lfc_xon(), + .stat_tx_lfc_xoff(), + .stat_tx_lfc_paused(), + .stat_tx_pfc_pkt(), + .stat_tx_pfc_xon(), + .stat_tx_pfc_xoff(), + .stat_tx_pfc_paused(), + .stat_rx_lfc_pkt(), + .stat_rx_lfc_xon(), + .stat_rx_lfc_xoff(), + .stat_rx_lfc_paused(), + .stat_rx_pfc_pkt(), + .stat_rx_pfc_xon(), + .stat_rx_pfc_xoff(), + .stat_rx_pfc_paused(), + /* + * Configuration + */ .cfg_ifg(8'd12), - .cfg_tx_enable(1'b1), - .cfg_rx_enable(1'b1) + .cfg_tx_enable(eth_tx_enable[n +: 1]), + .cfg_rx_enable(eth_rx_enable[n +: 1]), + .cfg_mcf_rx_eth_dst_mcast(48'h01_80_C2_00_00_01), + .cfg_mcf_rx_check_eth_dst_mcast(1'b1), + .cfg_mcf_rx_eth_dst_ucast(48'd0), + .cfg_mcf_rx_check_eth_dst_ucast(1'b0), + .cfg_mcf_rx_eth_src(48'd0), + .cfg_mcf_rx_check_eth_src(1'b0), + .cfg_mcf_rx_eth_type(16'h8808), + .cfg_mcf_rx_opcode_lfc(16'h0001), + .cfg_mcf_rx_check_opcode_lfc(eth_rx_lfc_en[n +: 1]), + .cfg_mcf_rx_opcode_pfc(16'h0101), + .cfg_mcf_rx_check_opcode_pfc(eth_rx_pfc_en[n*8 +: 8] != 0), + .cfg_mcf_rx_forward(1'b0), + .cfg_mcf_rx_enable(eth_rx_lfc_en[n +: 1] || eth_rx_pfc_en[n*8 +: 8]), + .cfg_tx_lfc_eth_dst(48'h01_80_C2_00_00_01), + .cfg_tx_lfc_eth_src(48'h80_23_31_43_54_4C), + .cfg_tx_lfc_eth_type(16'h8808), + .cfg_tx_lfc_opcode(16'h0001), + .cfg_tx_lfc_en(eth_tx_lfc_en[n +: 1]), + .cfg_tx_lfc_quanta(16'hffff), + .cfg_tx_lfc_refresh(16'h7fff), + .cfg_tx_pfc_eth_dst(48'h01_80_C2_00_00_01), + .cfg_tx_pfc_eth_src(48'h80_23_31_43_54_4C), + .cfg_tx_pfc_eth_type(16'h8808), + .cfg_tx_pfc_opcode(16'h0101), + .cfg_tx_pfc_en(eth_tx_pfc_en[n*8 +: 8] != 0), + .cfg_tx_pfc_quanta({8{16'hffff}}), + .cfg_tx_pfc_refresh({8{16'h7fff}}), + .cfg_rx_lfc_opcode(16'h0001), + .cfg_rx_lfc_en(eth_rx_lfc_en[n +: 1]), + .cfg_rx_pfc_opcode(16'h0101), + .cfg_rx_pfc_en(eth_rx_pfc_en[n*8 +: 8] != 0) ); end @@ -1107,6 +1218,9 @@ mqnic_core_pcie_us #( .TX_CHECKSUM_ENABLE(TX_CHECKSUM_ENABLE), .RX_HASH_ENABLE(RX_HASH_ENABLE), .RX_CHECKSUM_ENABLE(RX_CHECKSUM_ENABLE), + .PFC_ENABLE(PFC_ENABLE), + .LFC_ENABLE(LFC_ENABLE), + .MAC_CTRL_ENABLE(0), .TX_FIFO_DEPTH(TX_FIFO_DEPTH), .RX_FIFO_DEPTH(RX_FIFO_DEPTH), .MAX_TX_SIZE(MAX_TX_SIZE), @@ -1388,7 +1502,13 @@ core_inst ( .s_axis_eth_tx_cpl_valid(axis_eth_tx_ptp_ts_valid), .s_axis_eth_tx_cpl_ready(axis_eth_tx_ptp_ts_ready), + .eth_tx_enable(eth_tx_enable), .eth_tx_status(eth_tx_status), + .eth_tx_lfc_en(eth_tx_lfc_en), + .eth_tx_lfc_req(eth_tx_lfc_req), + .eth_tx_pfc_en(eth_tx_pfc_en), + .eth_tx_pfc_req(eth_tx_pfc_req), + .eth_tx_fc_quanta_clk_en(0), .eth_rx_clk(eth_rx_clk), .eth_rx_rst(eth_rx_rst), @@ -1405,7 +1525,15 @@ core_inst ( .s_axis_eth_rx_tlast(axis_eth_rx_tlast), .s_axis_eth_rx_tuser(axis_eth_rx_tuser), + .eth_rx_enable(eth_rx_enable), .eth_rx_status(eth_rx_status), + .eth_rx_lfc_en(eth_rx_lfc_en), + .eth_rx_lfc_req(eth_rx_lfc_req), + .eth_rx_lfc_ack(eth_rx_lfc_ack), + .eth_rx_pfc_en(eth_rx_pfc_en), + .eth_rx_pfc_req(eth_rx_pfc_req), + .eth_rx_pfc_ack(eth_rx_pfc_ack), + .eth_rx_fc_quanta_clk_en(0), /* * DDR diff --git a/fpga/mqnic/250_SoC/fpga_25g/tb/fpga_core/Makefile b/fpga/mqnic/250_SoC/fpga_25g/tb/fpga_core/Makefile index f4e303c0f..efbf27821 100644 --- a/fpga/mqnic/250_SoC/fpga_25g/tb/fpga_core/Makefile +++ b/fpga/mqnic/250_SoC/fpga_25g/tb/fpga_core/Makefile @@ -62,6 +62,10 @@ VERILOG_SOURCES += ../../rtl/common/tdma_ber_ch.v VERILOG_SOURCES += ../../lib/eth/rtl/eth_mac_10g.v VERILOG_SOURCES += ../../lib/eth/rtl/axis_xgmii_rx_64.v VERILOG_SOURCES += ../../lib/eth/rtl/axis_xgmii_tx_64.v +VERILOG_SOURCES += ../../lib/eth/rtl/mac_ctrl_rx.v +VERILOG_SOURCES += ../../lib/eth/rtl/mac_ctrl_tx.v +VERILOG_SOURCES += ../../lib/eth/rtl/mac_pause_ctrl_rx.v +VERILOG_SOURCES += ../../lib/eth/rtl/mac_pause_ctrl_tx.v VERILOG_SOURCES += ../../lib/eth/rtl/lfsr.v VERILOG_SOURCES += ../../lib/eth/rtl/ptp_clock.v VERILOG_SOURCES += ../../lib/eth/rtl/ptp_clock_cdc.v @@ -167,6 +171,8 @@ export PARAM_TX_CPL_FIFO_DEPTH := 32 export PARAM_TX_CHECKSUM_ENABLE := 1 export PARAM_RX_HASH_ENABLE := 1 export PARAM_RX_CHECKSUM_ENABLE := 1 +export PARAM_LFC_ENABLE := 1 +export PARAM_PFC_ENABLE := $(PARAM_LFC_ENABLE) export PARAM_TX_FIFO_DEPTH := 32768 export PARAM_RX_FIFO_DEPTH := 32768 export PARAM_MAX_TX_SIZE := 9214 diff --git a/fpga/mqnic/250_SoC/fpga_25g/tb/fpga_core/test_fpga_core.py b/fpga/mqnic/250_SoC/fpga_25g/tb/fpga_core/test_fpga_core.py index 1b9e5f2ed..47e9de27a 100644 --- a/fpga/mqnic/250_SoC/fpga_25g/tb/fpga_core/test_fpga_core.py +++ b/fpga/mqnic/250_SoC/fpga_25g/tb/fpga_core/test_fpga_core.py @@ -3,6 +3,7 @@ import logging import os +import struct import sys import scapy.utils @@ -17,7 +18,7 @@ from cocotb.clock import Clock from cocotb.triggers import RisingEdge, FallingEdge, Timer from cocotbext.axi import AxiStreamBus -from cocotbext.eth import XgmiiSource, XgmiiSink +from cocotbext.eth import XgmiiSource, XgmiiSink, XgmiiFrame from cocotbext.pcie.core import RootComplex from cocotbext.pcie.xilinx.us import UltraScalePlusPcieDevice @@ -396,7 +397,7 @@ async def run_test_nic(dut): # await tb.driver.interfaces[1].start_xmit(data, 0) - # pkt = await tb.qsfp_sink.r[1][0]ecv() + # pkt = await tb.qsfp_sink[1][0].recv() # tb.log.info("Packet: %s", pkt) # await tb.qsfp_source[1][0].send(pkt) @@ -528,6 +529,35 @@ async def run_test_nic(dut): tb.loopback_enable = False + if tb.driver.interfaces[0].if_feature_lfc: + tb.log.info("Test LFC pause frame RX") + + await tb.driver.interfaces[0].ports[0].set_lfc_ctrl(mqnic.MQNIC_PORT_LFC_CTRL_TX_LFC_EN | mqnic.MQNIC_PORT_LFC_CTRL_RX_LFC_EN) + await tb.driver.hw_regs.read_dword(0) + + lfc_xoff = Ether(src='DA:D1:D2:D3:D4:D5', dst='01:80:C2:00:00:01', type=0x8808) / struct.pack('!HH', 0x0001, 2000) + + await tb.qsfp_source[0][0].send(XgmiiFrame.from_payload(bytes(lfc_xoff))) + + count = 16 + + pkts = [bytearray([(x+k) % 256 for x in range(1514)]) for k in range(count)] + + tb.loopback_enable = True + + for p in pkts: + await tb.driver.interfaces[0].start_xmit(p, 0) + + for k in range(count): + pkt = await tb.driver.interfaces[0].recv() + + tb.log.info("Packet: %s", pkt) + assert pkt.data == pkts[k] + if tb.driver.interfaces[0].if_feature_rx_csum: + assert pkt.rx_checksum == ~scapy.utils.checksum(bytes(pkt.data[14:])) & 0xffff + + tb.loopback_enable = False + await RisingEdge(dut.clk_250mhz) await RisingEdge(dut.clk_250mhz) @@ -600,6 +630,10 @@ def test_fpga_core(request): os.path.join(eth_rtl_dir, "eth_mac_10g.v"), os.path.join(eth_rtl_dir, "axis_xgmii_rx_64.v"), os.path.join(eth_rtl_dir, "axis_xgmii_tx_64.v"), + os.path.join(eth_rtl_dir, "mac_ctrl_rx.v"), + os.path.join(eth_rtl_dir, "mac_ctrl_tx.v"), + os.path.join(eth_rtl_dir, "mac_pause_ctrl_rx.v"), + os.path.join(eth_rtl_dir, "mac_pause_ctrl_tx.v"), os.path.join(eth_rtl_dir, "lfsr.v"), os.path.join(eth_rtl_dir, "ptp_clock.v"), os.path.join(eth_rtl_dir, "ptp_clock_cdc.v"), @@ -706,6 +740,8 @@ def test_fpga_core(request): parameters['TX_CHECKSUM_ENABLE'] = 1 parameters['RX_HASH_ENABLE'] = 1 parameters['RX_CHECKSUM_ENABLE'] = 1 + parameters['LFC_ENABLE'] = 1 + parameters['PFC_ENABLE'] = parameters['LFC_ENABLE'] parameters['TX_FIFO_DEPTH'] = 32768 parameters['RX_FIFO_DEPTH'] = 32768 parameters['MAX_TX_SIZE'] = 9214 diff --git a/fpga/mqnic/520N_MX/fpga_25g/fpga/Makefile b/fpga/mqnic/520N_MX/fpga_25g/fpga/Makefile index 170b2887e..4a079b871 100644 --- a/fpga/mqnic/520N_MX/fpga_25g/fpga/Makefile +++ b/fpga/mqnic/520N_MX/fpga_25g/fpga/Makefile @@ -59,6 +59,10 @@ SYN_FILES += rtl/common/tdma_ber_ch.v SYN_FILES += lib/eth/rtl/eth_mac_10g.v SYN_FILES += lib/eth/rtl/axis_xgmii_rx_64.v SYN_FILES += lib/eth/rtl/axis_xgmii_tx_64.v +SYN_FILES += lib/eth/rtl/mac_ctrl_rx.v +SYN_FILES += lib/eth/rtl/mac_ctrl_tx.v +SYN_FILES += lib/eth/rtl/mac_pause_ctrl_rx.v +SYN_FILES += lib/eth/rtl/mac_pause_ctrl_tx.v SYN_FILES += lib/eth/rtl/eth_phy_10g.v SYN_FILES += lib/eth/rtl/eth_phy_10g_rx.v SYN_FILES += lib/eth/rtl/eth_phy_10g_rx_if.v diff --git a/fpga/mqnic/520N_MX/fpga_25g/fpga/config.tcl b/fpga/mqnic/520N_MX/fpga_25g/fpga/config.tcl index 6e1e0e5a3..8dec7741d 100644 --- a/fpga/mqnic/520N_MX/fpga_25g/fpga/config.tcl +++ b/fpga/mqnic/520N_MX/fpga_25g/fpga/config.tcl @@ -104,6 +104,8 @@ dict set params TX_CPL_FIFO_DEPTH "32" dict set params TX_CHECKSUM_ENABLE "1" dict set params RX_HASH_ENABLE "1" dict set params RX_CHECKSUM_ENABLE "1" +dict set params PFC_ENABLE "1" +dict set params LFC_ENABLE [dict get $params PFC_ENABLE] dict set params ENABLE_PADDING "1" dict set params ENABLE_DIC "1" dict set params MIN_FRAME_LENGTH "64" diff --git a/fpga/mqnic/520N_MX/fpga_25g/fpga_10g/Makefile b/fpga/mqnic/520N_MX/fpga_25g/fpga_10g/Makefile index 6e4ebcfa9..ef69d548f 100644 --- a/fpga/mqnic/520N_MX/fpga_25g/fpga_10g/Makefile +++ b/fpga/mqnic/520N_MX/fpga_25g/fpga_10g/Makefile @@ -59,6 +59,10 @@ SYN_FILES += rtl/common/tdma_ber_ch.v SYN_FILES += lib/eth/rtl/eth_mac_10g.v SYN_FILES += lib/eth/rtl/axis_xgmii_rx_64.v SYN_FILES += lib/eth/rtl/axis_xgmii_tx_64.v +SYN_FILES += lib/eth/rtl/mac_ctrl_rx.v +SYN_FILES += lib/eth/rtl/mac_ctrl_tx.v +SYN_FILES += lib/eth/rtl/mac_pause_ctrl_rx.v +SYN_FILES += lib/eth/rtl/mac_pause_ctrl_tx.v SYN_FILES += lib/eth/rtl/eth_phy_10g.v SYN_FILES += lib/eth/rtl/eth_phy_10g_rx.v SYN_FILES += lib/eth/rtl/eth_phy_10g_rx_if.v diff --git a/fpga/mqnic/520N_MX/fpga_25g/fpga_10g/config.tcl b/fpga/mqnic/520N_MX/fpga_25g/fpga_10g/config.tcl index 519681555..09f8e37f6 100644 --- a/fpga/mqnic/520N_MX/fpga_25g/fpga_10g/config.tcl +++ b/fpga/mqnic/520N_MX/fpga_25g/fpga_10g/config.tcl @@ -104,6 +104,8 @@ dict set params TX_CPL_FIFO_DEPTH "32" dict set params TX_CHECKSUM_ENABLE "1" dict set params RX_HASH_ENABLE "1" dict set params RX_CHECKSUM_ENABLE "1" +dict set params PFC_ENABLE "1" +dict set params LFC_ENABLE [dict get $params PFC_ENABLE] dict set params ENABLE_PADDING "1" dict set params ENABLE_DIC "1" dict set params MIN_FRAME_LENGTH "64" diff --git a/fpga/mqnic/520N_MX/fpga_25g/rtl/fpga.v b/fpga/mqnic/520N_MX/fpga_25g/rtl/fpga.v index 623f19e50..0208f5aca 100644 --- a/fpga/mqnic/520N_MX/fpga_25g/rtl/fpga.v +++ b/fpga/mqnic/520N_MX/fpga_25g/rtl/fpga.v @@ -74,6 +74,8 @@ module fpga # parameter TX_CHECKSUM_ENABLE = 1, parameter RX_HASH_ENABLE = 1, parameter RX_CHECKSUM_ENABLE = 1, + parameter PFC_ENABLE = 1, + parameter LFC_ENABLE = PFC_ENABLE, parameter ENABLE_PADDING = 1, parameter ENABLE_DIC = 1, parameter MIN_FRAME_LENGTH = 64, @@ -1321,6 +1323,8 @@ fpga_core #( .TX_CHECKSUM_ENABLE(TX_CHECKSUM_ENABLE), .RX_HASH_ENABLE(RX_HASH_ENABLE), .RX_CHECKSUM_ENABLE(RX_CHECKSUM_ENABLE), + .PFC_ENABLE(PFC_ENABLE), + .LFC_ENABLE(LFC_ENABLE), .ENABLE_PADDING(ENABLE_PADDING), .ENABLE_DIC(ENABLE_DIC), .MIN_FRAME_LENGTH(MIN_FRAME_LENGTH), diff --git a/fpga/mqnic/520N_MX/fpga_25g/rtl/fpga_core.v b/fpga/mqnic/520N_MX/fpga_25g/rtl/fpga_core.v index 61f1cb257..09c15f22d 100644 --- a/fpga/mqnic/520N_MX/fpga_25g/rtl/fpga_core.v +++ b/fpga/mqnic/520N_MX/fpga_25g/rtl/fpga_core.v @@ -81,6 +81,8 @@ module fpga_core # parameter TX_CHECKSUM_ENABLE = 1, parameter RX_HASH_ENABLE = 1, parameter RX_CHECKSUM_ENABLE = 1, + parameter PFC_ENABLE = 1, + parameter LFC_ENABLE = PFC_ENABLE, parameter ENABLE_PADDING = 1, parameter ENABLE_DIC = 1, parameter MIN_FRAME_LENGTH = 64, @@ -676,7 +678,12 @@ wire [PORT_COUNT*TX_TAG_WIDTH-1:0] axis_eth_tx_ptp_ts_tag; wire [PORT_COUNT-1:0] axis_eth_tx_ptp_ts_valid; wire [PORT_COUNT-1:0] axis_eth_tx_ptp_ts_ready; +wire [PORT_COUNT-1:0] eth_tx_enable; wire [PORT_COUNT-1:0] eth_tx_status; +wire [PORT_COUNT-1:0] eth_tx_lfc_en; +wire [PORT_COUNT-1:0] eth_tx_lfc_req; +wire [PORT_COUNT*8-1:0] eth_tx_pfc_en; +wire [PORT_COUNT*8-1:0] eth_tx_pfc_req; wire [PORT_COUNT-1:0] eth_rx_clk; wire [PORT_COUNT-1:0] eth_rx_rst; @@ -691,7 +698,14 @@ wire [PORT_COUNT-1:0] axis_eth_rx_tready; wire [PORT_COUNT-1:0] axis_eth_rx_tlast; wire [PORT_COUNT*AXIS_ETH_RX_USER_WIDTH-1:0] axis_eth_rx_tuser; +wire [PORT_COUNT-1:0] eth_rx_enable; wire [PORT_COUNT-1:0] eth_rx_status; +wire [PORT_COUNT-1:0] eth_rx_lfc_en; +wire [PORT_COUNT-1:0] eth_rx_lfc_req; +wire [PORT_COUNT-1:0] eth_rx_lfc_ack; +wire [PORT_COUNT*8-1:0] eth_rx_pfc_en; +wire [PORT_COUNT*8-1:0] eth_rx_pfc_req; +wire [PORT_COUNT*8-1:0] eth_rx_pfc_ack; wire [PORT_COUNT-1:0] port_xgmii_tx_clk; wire [PORT_COUNT-1:0] port_xgmii_tx_rst; @@ -764,12 +778,15 @@ generate .PTP_PERIOD_FNS(IF_PTP_PERIOD_FNS), .TX_PTP_TS_ENABLE(PTP_TS_ENABLE), .TX_PTP_TS_WIDTH(PTP_TS_WIDTH), + .TX_PTP_TS_CTRL_IN_TUSER(0), .TX_PTP_TAG_ENABLE(PTP_TS_ENABLE), .TX_PTP_TAG_WIDTH(TX_TAG_WIDTH), .RX_PTP_TS_ENABLE(PTP_TS_ENABLE), .RX_PTP_TS_WIDTH(PTP_TS_WIDTH), .TX_USER_WIDTH(AXIS_ETH_TX_USER_WIDTH), - .RX_USER_WIDTH(AXIS_ETH_RX_USER_WIDTH) + .RX_USER_WIDTH(AXIS_ETH_RX_USER_WIDTH), + .PFC_ENABLE(PFC_ENABLE), + .PAUSE_ENABLE(LFC_ENABLE) ) eth_mac_inst ( .tx_clk(port_xgmii_tx_clk[n]), @@ -777,6 +794,9 @@ generate .rx_clk(port_xgmii_rx_clk[n]), .rx_rst(port_xgmii_rx_rst[n]), + /* + * AXI input + */ .tx_axis_tdata(axis_eth_tx_tdata[n*AXIS_ETH_DATA_WIDTH +: AXIS_ETH_DATA_WIDTH]), .tx_axis_tkeep(axis_eth_tx_tkeep[n*AXIS_ETH_KEEP_WIDTH +: AXIS_ETH_KEEP_WIDTH]), .tx_axis_tvalid(axis_eth_tx_tvalid[n +: 1]), @@ -784,30 +804,121 @@ generate .tx_axis_tlast(axis_eth_tx_tlast[n +: 1]), .tx_axis_tuser(axis_eth_tx_tuser[n*AXIS_ETH_TX_USER_WIDTH +: AXIS_ETH_TX_USER_WIDTH]), + /* + * AXI output + */ .rx_axis_tdata(axis_eth_rx_tdata[n*AXIS_ETH_DATA_WIDTH +: AXIS_ETH_DATA_WIDTH]), .rx_axis_tkeep(axis_eth_rx_tkeep[n*AXIS_ETH_KEEP_WIDTH +: AXIS_ETH_KEEP_WIDTH]), .rx_axis_tvalid(axis_eth_rx_tvalid[n +: 1]), .rx_axis_tlast(axis_eth_rx_tlast[n +: 1]), .rx_axis_tuser(axis_eth_rx_tuser[n*AXIS_ETH_RX_USER_WIDTH +: AXIS_ETH_RX_USER_WIDTH]), + /* + * XGMII interface + */ .xgmii_rxd(port_xgmii_rxd[n*XGMII_DATA_WIDTH +: XGMII_DATA_WIDTH]), .xgmii_rxc(port_xgmii_rxc[n*XGMII_CTRL_WIDTH +: XGMII_CTRL_WIDTH]), .xgmii_txd(port_xgmii_txd[n*XGMII_DATA_WIDTH +: XGMII_DATA_WIDTH]), .xgmii_txc(port_xgmii_txc[n*XGMII_CTRL_WIDTH +: XGMII_CTRL_WIDTH]), + /* + * PTP + */ .tx_ptp_ts(eth_tx_ptp_ts_96[n*PTP_TS_WIDTH +: PTP_TS_WIDTH]), .rx_ptp_ts(eth_rx_ptp_ts_96[n*PTP_TS_WIDTH +: PTP_TS_WIDTH]), .tx_axis_ptp_ts(axis_eth_tx_ptp_ts[n*PTP_TS_WIDTH +: PTP_TS_WIDTH]), .tx_axis_ptp_ts_tag(axis_eth_tx_ptp_ts_tag[n*TX_TAG_WIDTH +: TX_TAG_WIDTH]), .tx_axis_ptp_ts_valid(axis_eth_tx_ptp_ts_valid[n +: 1]), + /* + * Link-level Flow Control (LFC) (IEEE 802.3 annex 31B PAUSE) + */ + .tx_lfc_req(eth_tx_lfc_req[n +: 1]), + .tx_lfc_resend(1'b0), + .rx_lfc_en(eth_rx_lfc_en[n +: 1]), + .rx_lfc_req(eth_rx_lfc_req[n +: 1]), + .rx_lfc_ack(eth_rx_lfc_ack[n +: 1]), + + /* + * Priority Flow Control (PFC) (IEEE 802.3 annex 31D PFC) + */ + .tx_pfc_req(eth_tx_pfc_req[n*8 +: 8]), + .tx_pfc_resend(1'b0), + .rx_pfc_en(eth_rx_pfc_en[n*8 +: 8]), + .rx_pfc_req(eth_rx_pfc_req[n*8 +: 8]), + .rx_pfc_ack(eth_rx_pfc_ack[n*8 +: 8]), + + /* + * Pause interface + */ + .tx_lfc_pause_en(1'b1), + .tx_pause_req(1'b0), + .tx_pause_ack(), + + /* + * Status + */ + .tx_start_packet(), .tx_error_underflow(), + .rx_start_packet(), .rx_error_bad_frame(), .rx_error_bad_fcs(), + .stat_tx_mcf(), + .stat_rx_mcf(), + .stat_tx_lfc_pkt(), + .stat_tx_lfc_xon(), + .stat_tx_lfc_xoff(), + .stat_tx_lfc_paused(), + .stat_tx_pfc_pkt(), + .stat_tx_pfc_xon(), + .stat_tx_pfc_xoff(), + .stat_tx_pfc_paused(), + .stat_rx_lfc_pkt(), + .stat_rx_lfc_xon(), + .stat_rx_lfc_xoff(), + .stat_rx_lfc_paused(), + .stat_rx_pfc_pkt(), + .stat_rx_pfc_xon(), + .stat_rx_pfc_xoff(), + .stat_rx_pfc_paused(), + /* + * Configuration + */ .cfg_ifg(8'd12), - .cfg_tx_enable(1'b1), - .cfg_rx_enable(1'b1) + .cfg_tx_enable(eth_tx_enable[n +: 1]), + .cfg_rx_enable(eth_rx_enable[n +: 1]), + .cfg_mcf_rx_eth_dst_mcast(48'h01_80_C2_00_00_01), + .cfg_mcf_rx_check_eth_dst_mcast(1'b1), + .cfg_mcf_rx_eth_dst_ucast(48'd0), + .cfg_mcf_rx_check_eth_dst_ucast(1'b0), + .cfg_mcf_rx_eth_src(48'd0), + .cfg_mcf_rx_check_eth_src(1'b0), + .cfg_mcf_rx_eth_type(16'h8808), + .cfg_mcf_rx_opcode_lfc(16'h0001), + .cfg_mcf_rx_check_opcode_lfc(eth_rx_lfc_en[n +: 1]), + .cfg_mcf_rx_opcode_pfc(16'h0101), + .cfg_mcf_rx_check_opcode_pfc(eth_rx_pfc_en[n*8 +: 8] != 0), + .cfg_mcf_rx_forward(1'b0), + .cfg_mcf_rx_enable(eth_rx_lfc_en[n +: 1] || eth_rx_pfc_en[n*8 +: 8]), + .cfg_tx_lfc_eth_dst(48'h01_80_C2_00_00_01), + .cfg_tx_lfc_eth_src(48'h80_23_31_43_54_4C), + .cfg_tx_lfc_eth_type(16'h8808), + .cfg_tx_lfc_opcode(16'h0001), + .cfg_tx_lfc_en(eth_tx_lfc_en[n +: 1]), + .cfg_tx_lfc_quanta(16'hffff), + .cfg_tx_lfc_refresh(16'h7fff), + .cfg_tx_pfc_eth_dst(48'h01_80_C2_00_00_01), + .cfg_tx_pfc_eth_src(48'h80_23_31_43_54_4C), + .cfg_tx_pfc_eth_type(16'h8808), + .cfg_tx_pfc_opcode(16'h0101), + .cfg_tx_pfc_en(eth_tx_pfc_en[n*8 +: 8] != 0), + .cfg_tx_pfc_quanta({8{16'hffff}}), + .cfg_tx_pfc_refresh({8{16'h7fff}}), + .cfg_rx_lfc_opcode(16'h0001), + .cfg_rx_lfc_en(eth_rx_lfc_en[n +: 1]), + .cfg_rx_pfc_opcode(16'h0101), + .cfg_rx_pfc_en(eth_rx_pfc_en[n*8 +: 8] != 0) ); end @@ -881,6 +992,9 @@ mqnic_core_pcie_s10 #( .TX_CHECKSUM_ENABLE(TX_CHECKSUM_ENABLE), .RX_HASH_ENABLE(RX_HASH_ENABLE), .RX_CHECKSUM_ENABLE(RX_CHECKSUM_ENABLE), + .PFC_ENABLE(PFC_ENABLE), + .LFC_ENABLE(LFC_ENABLE), + .MAC_CTRL_ENABLE(0), .TX_FIFO_DEPTH(TX_FIFO_DEPTH), .RX_FIFO_DEPTH(RX_FIFO_DEPTH), .MAX_TX_SIZE(MAX_TX_SIZE), @@ -1087,7 +1201,13 @@ core_inst ( .s_axis_eth_tx_cpl_valid(axis_eth_tx_ptp_ts_valid), .s_axis_eth_tx_cpl_ready(axis_eth_tx_ptp_ts_ready), + .eth_tx_enable(eth_tx_enable), .eth_tx_status(eth_tx_status), + .eth_tx_lfc_en(eth_tx_lfc_en), + .eth_tx_lfc_req(eth_tx_lfc_req), + .eth_tx_pfc_en(eth_tx_pfc_en), + .eth_tx_pfc_req(eth_tx_pfc_req), + .eth_tx_fc_quanta_clk_en(0), .eth_rx_clk(eth_rx_clk), .eth_rx_rst(eth_rx_rst), @@ -1104,7 +1224,15 @@ core_inst ( .s_axis_eth_rx_tlast(axis_eth_rx_tlast), .s_axis_eth_rx_tuser(axis_eth_rx_tuser), + .eth_rx_enable(eth_rx_enable), .eth_rx_status(eth_rx_status), + .eth_rx_lfc_en(eth_rx_lfc_en), + .eth_rx_lfc_req(eth_rx_lfc_req), + .eth_rx_lfc_ack(eth_rx_lfc_ack), + .eth_rx_pfc_en(eth_rx_pfc_en), + .eth_rx_pfc_req(eth_rx_pfc_req), + .eth_rx_pfc_ack(eth_rx_pfc_ack), + .eth_rx_fc_quanta_clk_en(0), /* * DDR diff --git a/fpga/mqnic/520N_MX/fpga_25g/tb/fpga_core/Makefile b/fpga/mqnic/520N_MX/fpga_25g/tb/fpga_core/Makefile index 0bc1d49a7..d44c27650 100644 --- a/fpga/mqnic/520N_MX/fpga_25g/tb/fpga_core/Makefile +++ b/fpga/mqnic/520N_MX/fpga_25g/tb/fpga_core/Makefile @@ -60,6 +60,10 @@ VERILOG_SOURCES += ../../rtl/common/tdma_ber_ch.v VERILOG_SOURCES += ../../lib/eth/rtl/eth_mac_10g.v VERILOG_SOURCES += ../../lib/eth/rtl/axis_xgmii_rx_64.v VERILOG_SOURCES += ../../lib/eth/rtl/axis_xgmii_tx_64.v +VERILOG_SOURCES += ../../lib/eth/rtl/mac_ctrl_rx.v +VERILOG_SOURCES += ../../lib/eth/rtl/mac_ctrl_tx.v +VERILOG_SOURCES += ../../lib/eth/rtl/mac_pause_ctrl_rx.v +VERILOG_SOURCES += ../../lib/eth/rtl/mac_pause_ctrl_tx.v VERILOG_SOURCES += ../../lib/eth/rtl/lfsr.v VERILOG_SOURCES += ../../lib/eth/rtl/ptp_clock.v VERILOG_SOURCES += ../../lib/eth/rtl/ptp_clock_cdc.v @@ -165,6 +169,8 @@ export PARAM_TX_CPL_FIFO_DEPTH := 32 export PARAM_TX_CHECKSUM_ENABLE := 1 export PARAM_RX_HASH_ENABLE := 1 export PARAM_RX_CHECKSUM_ENABLE := 1 +export PARAM_LFC_ENABLE := 1 +export PARAM_PFC_ENABLE := $(PARAM_LFC_ENABLE) export PARAM_TX_FIFO_DEPTH := 32768 export PARAM_RX_FIFO_DEPTH := 32768 export PARAM_MAX_TX_SIZE := 9214 diff --git a/fpga/mqnic/520N_MX/fpga_25g/tb/fpga_core/test_fpga_core.py b/fpga/mqnic/520N_MX/fpga_25g/tb/fpga_core/test_fpga_core.py index 43c9e6bce..0cea9b98b 100644 --- a/fpga/mqnic/520N_MX/fpga_25g/tb/fpga_core/test_fpga_core.py +++ b/fpga/mqnic/520N_MX/fpga_25g/tb/fpga_core/test_fpga_core.py @@ -3,6 +3,7 @@ import logging import os +import struct import sys import scapy.utils @@ -16,7 +17,7 @@ from cocotb.log import SimLog from cocotb.clock import Clock from cocotb.triggers import RisingEdge, FallingEdge, Timer -from cocotbext.eth import XgmiiSource, XgmiiSink +from cocotbext.eth import XgmiiSource, XgmiiSink, XgmiiFrame from cocotbext.pcie.core import RootComplex from cocotbext.pcie.intel.s10 import S10PcieDevice, S10RxBus, S10TxBus @@ -438,6 +439,35 @@ async def run_test_nic(dut): tb.loopback_enable = False + if tb.driver.interfaces[0].if_feature_lfc: + tb.log.info("Test LFC pause frame RX") + + await tb.driver.interfaces[0].ports[0].set_lfc_ctrl(mqnic.MQNIC_PORT_LFC_CTRL_TX_LFC_EN | mqnic.MQNIC_PORT_LFC_CTRL_RX_LFC_EN) + await tb.driver.hw_regs.read_dword(0) + + lfc_xoff = Ether(src='DA:D1:D2:D3:D4:D5', dst='01:80:C2:00:00:01', type=0x8808) / struct.pack('!HH', 0x0001, 2000) + + await tb.qsfp_source[0][0].send(XgmiiFrame.from_payload(bytes(lfc_xoff))) + + count = 16 + + pkts = [bytearray([(x+k) % 256 for x in range(1514)]) for k in range(count)] + + tb.loopback_enable = True + + for p in pkts: + await tb.driver.interfaces[0].start_xmit(p, 0) + + for k in range(count): + pkt = await tb.driver.interfaces[0].recv() + + tb.log.info("Packet: %s", pkt) + assert pkt.data == pkts[k] + if tb.driver.interfaces[0].if_feature_rx_csum: + assert pkt.rx_checksum == ~scapy.utils.checksum(bytes(pkt.data[14:])) & 0xffff + + tb.loopback_enable = False + await RisingEdge(dut.clk_250mhz) await RisingEdge(dut.clk_250mhz) @@ -508,6 +538,10 @@ def test_fpga_core(request): os.path.join(eth_rtl_dir, "eth_mac_10g.v"), os.path.join(eth_rtl_dir, "axis_xgmii_rx_64.v"), os.path.join(eth_rtl_dir, "axis_xgmii_tx_64.v"), + os.path.join(eth_rtl_dir, "mac_ctrl_rx.v"), + os.path.join(eth_rtl_dir, "mac_ctrl_tx.v"), + os.path.join(eth_rtl_dir, "mac_pause_ctrl_rx.v"), + os.path.join(eth_rtl_dir, "mac_pause_ctrl_tx.v"), os.path.join(eth_rtl_dir, "lfsr.v"), os.path.join(eth_rtl_dir, "ptp_clock.v"), os.path.join(eth_rtl_dir, "ptp_clock_cdc.v"), @@ -614,6 +648,8 @@ def test_fpga_core(request): parameters['TX_CHECKSUM_ENABLE'] = 1 parameters['RX_HASH_ENABLE'] = 1 parameters['RX_CHECKSUM_ENABLE'] = 1 + parameters['LFC_ENABLE'] = 1 + parameters['PFC_ENABLE'] = parameters['LFC_ENABLE'] parameters['TX_FIFO_DEPTH'] = 32768 parameters['RX_FIFO_DEPTH'] = 32768 parameters['MAX_TX_SIZE'] = 9214 diff --git a/fpga/mqnic/ADM_PCIE_9V3/fpga_100g/fpga/config.tcl b/fpga/mqnic/ADM_PCIE_9V3/fpga_100g/fpga/config.tcl index 7d2cd8cc7..6b3657d37 100644 --- a/fpga/mqnic/ADM_PCIE_9V3/fpga_100g/fpga/config.tcl +++ b/fpga/mqnic/ADM_PCIE_9V3/fpga_100g/fpga/config.tcl @@ -101,6 +101,8 @@ dict set params TX_CPL_FIFO_DEPTH "32" dict set params TX_CHECKSUM_ENABLE "1" dict set params RX_HASH_ENABLE "1" dict set params RX_CHECKSUM_ENABLE "1" +dict set params PFC_ENABLE "1" +dict set params LFC_ENABLE [dict get $params PFC_ENABLE] dict set params TX_FIFO_DEPTH "32768" dict set params RX_FIFO_DEPTH "131072" dict set params MAX_TX_SIZE "9214" diff --git a/fpga/mqnic/ADM_PCIE_9V3/fpga_100g/fpga_app_dma_bench/config.tcl b/fpga/mqnic/ADM_PCIE_9V3/fpga_100g/fpga_app_dma_bench/config.tcl index a16dd6299..7e20282cf 100644 --- a/fpga/mqnic/ADM_PCIE_9V3/fpga_100g/fpga_app_dma_bench/config.tcl +++ b/fpga/mqnic/ADM_PCIE_9V3/fpga_100g/fpga_app_dma_bench/config.tcl @@ -101,6 +101,8 @@ dict set params TX_CPL_FIFO_DEPTH "32" dict set params TX_CHECKSUM_ENABLE "1" dict set params RX_HASH_ENABLE "1" dict set params RX_CHECKSUM_ENABLE "1" +dict set params PFC_ENABLE "1" +dict set params LFC_ENABLE [dict get $params PFC_ENABLE] dict set params TX_FIFO_DEPTH "32768" dict set params RX_FIFO_DEPTH "131072" dict set params MAX_TX_SIZE "9214" diff --git a/fpga/mqnic/ADM_PCIE_9V3/fpga_100g/fpga_tdma/config.tcl b/fpga/mqnic/ADM_PCIE_9V3/fpga_100g/fpga_tdma/config.tcl index 750eadb7a..2c7f5767c 100644 --- a/fpga/mqnic/ADM_PCIE_9V3/fpga_100g/fpga_tdma/config.tcl +++ b/fpga/mqnic/ADM_PCIE_9V3/fpga_100g/fpga_tdma/config.tcl @@ -101,6 +101,8 @@ dict set params TX_CPL_FIFO_DEPTH "32" dict set params TX_CHECKSUM_ENABLE "1" dict set params RX_HASH_ENABLE "1" dict set params RX_CHECKSUM_ENABLE "1" +dict set params PFC_ENABLE "1" +dict set params LFC_ENABLE [dict get $params PFC_ENABLE] dict set params TX_FIFO_DEPTH "32768" dict set params RX_FIFO_DEPTH "131072" dict set params MAX_TX_SIZE "9214" diff --git a/fpga/mqnic/ADM_PCIE_9V3/fpga_100g/ip/cmac_usplus.tcl b/fpga/mqnic/ADM_PCIE_9V3/fpga_100g/ip/cmac_usplus.tcl index b86d4ea5e..af9cc8265 100644 --- a/fpga/mqnic/ADM_PCIE_9V3/fpga_100g/ip/cmac_usplus.tcl +++ b/fpga/mqnic/ADM_PCIE_9V3/fpga_100g/ip/cmac_usplus.tcl @@ -7,8 +7,10 @@ set_property -dict [list \ CONFIG.USER_INTERFACE {AXIS} \ CONFIG.GT_DRP_CLK {125} \ CONFIG.GT_LOCATION {0} \ - CONFIG.TX_FLOW_CONTROL {0} \ - CONFIG.RX_FLOW_CONTROL {0} \ + CONFIG.TX_FLOW_CONTROL {1} \ + CONFIG.RX_FLOW_CONTROL {1} \ + CONFIG.RX_FORWARD_CONTROL_FRAMES {0} \ + CONFIG.RX_CHECK_ACK {1} \ CONFIG.INCLUDE_RS_FEC {1} \ CONFIG.ENABLE_TIME_STAMPING {1} ] [get_ips cmac_usplus] diff --git a/fpga/mqnic/ADM_PCIE_9V3/fpga_100g/rtl/fpga.v b/fpga/mqnic/ADM_PCIE_9V3/fpga_100g/rtl/fpga.v index 775482fde..52d142b6b 100644 --- a/fpga/mqnic/ADM_PCIE_9V3/fpga_100g/rtl/fpga.v +++ b/fpga/mqnic/ADM_PCIE_9V3/fpga_100g/rtl/fpga.v @@ -71,6 +71,8 @@ module fpga # parameter TX_CHECKSUM_ENABLE = 1, parameter RX_HASH_ENABLE = 1, parameter RX_CHECKSUM_ENABLE = 1, + parameter PFC_ENABLE = 1, + parameter LFC_ENABLE = PFC_ENABLE, parameter TX_FIFO_DEPTH = 32768, parameter RX_FIFO_DEPTH = 131072, parameter MAX_TX_SIZE = 9214, @@ -955,7 +957,20 @@ wire qsfp_0_drp_we; wire [15:0] qsfp_0_drp_do; wire qsfp_0_drp_rdy; -wire qsfp_0_rx_status; +wire qsfp_0_tx_enable; +wire qsfp_0_tx_lfc_en; +wire qsfp_0_tx_lfc_req; +wire [7:0] qsfp_0_tx_pfc_en; +wire [7:0] qsfp_0_tx_pfc_req; + +wire qsfp_0_rx_enable; +wire qsfp_0_rx_status; +wire qsfp_0_rx_lfc_en; +wire qsfp_0_rx_lfc_req; +wire qsfp_0_rx_lfc_ack; +wire [7:0] qsfp_0_rx_pfc_en; +wire [7:0] qsfp_0_rx_pfc_req; +wire [7:0] qsfp_0_rx_pfc_ack; wire qsfp_0_gtpowergood; @@ -1048,6 +1063,12 @@ qsfp_0_cmac_inst ( .tx_ptp_ts_tag(qsfp_0_tx_ptp_ts_tag_int), .tx_ptp_ts_valid(qsfp_0_tx_ptp_ts_valid_int), + .tx_enable(qsfp_0_tx_enable), + .tx_lfc_en(qsfp_0_tx_lfc_en), + .tx_lfc_req(qsfp_0_tx_lfc_req), + .tx_pfc_en(qsfp_0_tx_pfc_en), + .tx_pfc_req(qsfp_0_tx_pfc_req), + .rx_clk(qsfp_0_rx_clk_int), .rx_rst(qsfp_0_rx_rst_int), @@ -1061,7 +1082,14 @@ qsfp_0_cmac_inst ( .rx_ptp_rst(qsfp_0_rx_ptp_rst_int), .rx_ptp_time(qsfp_0_rx_ptp_time_int), - .rx_status(qsfp_0_rx_status) + .rx_enable(qsfp_0_rx_enable), + .rx_status(qsfp_0_rx_status), + .rx_lfc_en(qsfp_0_rx_lfc_en), + .rx_lfc_req(qsfp_0_rx_lfc_req), + .rx_lfc_ack(qsfp_0_rx_lfc_ack), + .rx_pfc_en(qsfp_0_rx_pfc_en), + .rx_pfc_req(qsfp_0_rx_pfc_req), + .rx_pfc_ack(qsfp_0_rx_pfc_ack) ); // QSFP1 CMAC @@ -1102,7 +1130,20 @@ wire qsfp_1_drp_we; wire [15:0] qsfp_1_drp_do; wire qsfp_1_drp_rdy; -wire qsfp_1_rx_status; +wire qsfp_1_tx_enable; +wire qsfp_1_tx_lfc_en; +wire qsfp_1_tx_lfc_req; +wire [7:0] qsfp_1_tx_pfc_en; +wire [7:0] qsfp_1_tx_pfc_req; + +wire qsfp_1_rx_enable; +wire qsfp_1_rx_status; +wire qsfp_1_rx_lfc_en; +wire qsfp_1_rx_lfc_req; +wire qsfp_1_rx_lfc_ack; +wire [7:0] qsfp_1_rx_pfc_en; +wire [7:0] qsfp_1_rx_pfc_req; +wire [7:0] qsfp_1_rx_pfc_ack; wire qsfp_1_gtpowergood; @@ -1195,6 +1236,12 @@ qsfp_1_cmac_inst ( .tx_ptp_ts_tag(qsfp_1_tx_ptp_ts_tag_int), .tx_ptp_ts_valid(qsfp_1_tx_ptp_ts_valid_int), + .tx_enable(qsfp_1_tx_enable), + .tx_lfc_en(qsfp_1_tx_lfc_en), + .tx_lfc_req(qsfp_1_tx_lfc_req), + .tx_pfc_en(qsfp_1_tx_pfc_en), + .tx_pfc_req(qsfp_1_tx_pfc_req), + .rx_clk(qsfp_1_rx_clk_int), .rx_rst(qsfp_1_rx_rst_int), @@ -1208,7 +1255,14 @@ qsfp_1_cmac_inst ( .rx_ptp_rst(qsfp_1_rx_ptp_rst_int), .rx_ptp_time(qsfp_1_rx_ptp_time_int), - .rx_status(qsfp_1_rx_status) + .rx_enable(qsfp_1_rx_enable), + .rx_status(qsfp_1_rx_status), + .rx_lfc_en(qsfp_1_rx_lfc_en), + .rx_lfc_req(qsfp_1_rx_lfc_req), + .rx_lfc_ack(qsfp_1_rx_lfc_ack), + .rx_pfc_en(qsfp_1_rx_pfc_en), + .rx_pfc_req(qsfp_1_rx_pfc_req), + .rx_pfc_ack(qsfp_1_rx_pfc_ack) ); wire ptp_clk; @@ -1601,6 +1655,8 @@ fpga_core #( .TX_CHECKSUM_ENABLE(TX_CHECKSUM_ENABLE), .RX_HASH_ENABLE(RX_HASH_ENABLE), .RX_CHECKSUM_ENABLE(RX_CHECKSUM_ENABLE), + .PFC_ENABLE(PFC_ENABLE), + .LFC_ENABLE(LFC_ENABLE), .TX_FIFO_DEPTH(TX_FIFO_DEPTH), .RX_FIFO_DEPTH(RX_FIFO_DEPTH), .MAX_TX_SIZE(MAX_TX_SIZE), @@ -1797,6 +1853,12 @@ core_inst ( .qsfp_0_tx_ptp_ts_tag(qsfp_0_tx_ptp_ts_tag_int), .qsfp_0_tx_ptp_ts_valid(qsfp_0_tx_ptp_ts_valid_int), + .qsfp_0_tx_enable(qsfp_0_tx_enable), + .qsfp_0_tx_lfc_en(qsfp_0_tx_lfc_en), + .qsfp_0_tx_lfc_req(qsfp_0_tx_lfc_req), + .qsfp_0_tx_pfc_en(qsfp_0_tx_pfc_en), + .qsfp_0_tx_pfc_req(qsfp_0_tx_pfc_req), + .qsfp_0_rx_clk(qsfp_0_rx_clk_int), .qsfp_0_rx_rst(qsfp_0_rx_rst_int), .qsfp_0_rx_axis_tdata(qsfp_0_rx_axis_tdata_int), @@ -1808,7 +1870,14 @@ core_inst ( .qsfp_0_rx_ptp_rst(qsfp_0_rx_ptp_rst_int), .qsfp_0_rx_ptp_time(qsfp_0_rx_ptp_time_int), + .qsfp_0_rx_enable(qsfp_0_rx_enable), .qsfp_0_rx_status(qsfp_0_rx_status), + .qsfp_0_rx_lfc_en(qsfp_0_rx_lfc_en), + .qsfp_0_rx_lfc_req(qsfp_0_rx_lfc_req), + .qsfp_0_rx_lfc_ack(qsfp_0_rx_lfc_ack), + .qsfp_0_rx_pfc_en(qsfp_0_rx_pfc_en), + .qsfp_0_rx_pfc_req(qsfp_0_rx_pfc_req), + .qsfp_0_rx_pfc_ack(qsfp_0_rx_pfc_ack), .qsfp_0_drp_clk(qsfp_0_drp_clk), .qsfp_0_drp_rst(qsfp_0_drp_rst), @@ -1835,6 +1904,12 @@ core_inst ( .qsfp_1_tx_ptp_ts_tag(qsfp_1_tx_ptp_ts_tag_int), .qsfp_1_tx_ptp_ts_valid(qsfp_1_tx_ptp_ts_valid_int), + .qsfp_1_tx_enable(qsfp_1_tx_enable), + .qsfp_1_tx_lfc_en(qsfp_1_tx_lfc_en), + .qsfp_1_tx_lfc_req(qsfp_1_tx_lfc_req), + .qsfp_1_tx_pfc_en(qsfp_1_tx_pfc_en), + .qsfp_1_tx_pfc_req(qsfp_1_tx_pfc_req), + .qsfp_1_rx_clk(qsfp_1_rx_clk_int), .qsfp_1_rx_rst(qsfp_1_rx_rst_int), .qsfp_1_rx_axis_tdata(qsfp_1_rx_axis_tdata_int), @@ -1846,7 +1921,14 @@ core_inst ( .qsfp_1_rx_ptp_rst(qsfp_1_rx_ptp_rst_int), .qsfp_1_rx_ptp_time(qsfp_1_rx_ptp_time_int), + .qsfp_1_rx_enable(qsfp_1_rx_enable), .qsfp_1_rx_status(qsfp_1_rx_status), + .qsfp_1_rx_lfc_en(qsfp_1_rx_lfc_en), + .qsfp_1_rx_lfc_req(qsfp_1_rx_lfc_req), + .qsfp_1_rx_lfc_ack(qsfp_1_rx_lfc_ack), + .qsfp_1_rx_pfc_en(qsfp_1_rx_pfc_en), + .qsfp_1_rx_pfc_req(qsfp_1_rx_pfc_req), + .qsfp_1_rx_pfc_ack(qsfp_1_rx_pfc_ack), .qsfp_1_drp_clk(qsfp_1_drp_clk), .qsfp_1_drp_rst(qsfp_1_drp_rst), diff --git a/fpga/mqnic/ADM_PCIE_9V3/fpga_100g/rtl/fpga_core.v b/fpga/mqnic/ADM_PCIE_9V3/fpga_100g/rtl/fpga_core.v index cec6a467a..ff64b228b 100644 --- a/fpga/mqnic/ADM_PCIE_9V3/fpga_100g/rtl/fpga_core.v +++ b/fpga/mqnic/ADM_PCIE_9V3/fpga_100g/rtl/fpga_core.v @@ -77,6 +77,8 @@ module fpga_core # parameter TX_CHECKSUM_ENABLE = 1, parameter RX_HASH_ENABLE = 1, parameter RX_CHECKSUM_ENABLE = 1, + parameter PFC_ENABLE = 1, + parameter LFC_ENABLE = PFC_ENABLE, parameter TX_FIFO_DEPTH = 32768, parameter RX_FIFO_DEPTH = 131072, parameter MAX_TX_SIZE = 9214, @@ -275,6 +277,12 @@ module fpga_core # input wire [15:0] qsfp_0_tx_ptp_ts_tag, input wire qsfp_0_tx_ptp_ts_valid, + output wire qsfp_0_tx_enable, + output wire qsfp_0_tx_lfc_en, + output wire qsfp_0_tx_lfc_req, + output wire [7:0] qsfp_0_tx_pfc_en, + output wire [7:0] qsfp_0_tx_pfc_req, + input wire qsfp_0_rx_clk, input wire qsfp_0_rx_rst, @@ -288,7 +296,14 @@ module fpga_core # input wire qsfp_0_rx_ptp_rst, output wire [79:0] qsfp_0_rx_ptp_time, + output wire qsfp_0_rx_enable, input wire qsfp_0_rx_status, + output wire qsfp_0_rx_lfc_en, + input wire qsfp_0_rx_lfc_req, + output wire qsfp_0_rx_lfc_ack, + output wire [7:0] qsfp_0_rx_pfc_en, + input wire [7:0] qsfp_0_rx_pfc_req, + output wire [7:0] qsfp_0_rx_pfc_ack, input wire qsfp_0_drp_clk, input wire qsfp_0_drp_rst, @@ -317,8 +332,12 @@ module fpga_core # input wire [15:0] qsfp_1_tx_ptp_ts_tag, input wire qsfp_1_tx_ptp_ts_valid, - input wire qsfp_1_rx_ptp_clk, - input wire qsfp_1_rx_ptp_rst, + output wire qsfp_1_tx_enable, + output wire qsfp_1_tx_lfc_en, + output wire qsfp_1_tx_lfc_req, + output wire [7:0] qsfp_1_tx_pfc_en, + output wire [7:0] qsfp_1_tx_pfc_req, + input wire qsfp_1_rx_clk, input wire qsfp_1_rx_rst, @@ -328,9 +347,18 @@ module fpga_core # input wire qsfp_1_rx_axis_tlast, input wire [80+1-1:0] qsfp_1_rx_axis_tuser, + input wire qsfp_1_rx_ptp_clk, + input wire qsfp_1_rx_ptp_rst, output wire [79:0] qsfp_1_rx_ptp_time, + output wire qsfp_1_rx_enable, input wire qsfp_1_rx_status, + output wire qsfp_1_rx_lfc_en, + input wire qsfp_1_rx_lfc_req, + output wire qsfp_1_rx_lfc_ack, + output wire [7:0] qsfp_1_rx_pfc_en, + input wire [7:0] qsfp_1_rx_pfc_req, + output wire [7:0] qsfp_1_rx_pfc_ack, input wire qsfp_1_drp_clk, input wire qsfp_1_drp_rst, @@ -850,7 +878,12 @@ wire [PORT_COUNT*TX_TAG_WIDTH-1:0] axis_eth_tx_ptp_ts_tag; wire [PORT_COUNT-1:0] axis_eth_tx_ptp_ts_valid; wire [PORT_COUNT-1:0] axis_eth_tx_ptp_ts_ready; +wire [PORT_COUNT-1:0] eth_tx_enable; wire [PORT_COUNT-1:0] eth_tx_status; +wire [PORT_COUNT-1:0] eth_tx_lfc_en; +wire [PORT_COUNT-1:0] eth_tx_lfc_req; +wire [PORT_COUNT*8-1:0] eth_tx_pfc_en; +wire [PORT_COUNT*8-1:0] eth_tx_pfc_req; wire [PORT_COUNT-1:0] eth_rx_clk; wire [PORT_COUNT-1:0] eth_rx_rst; @@ -867,7 +900,14 @@ wire [PORT_COUNT-1:0] axis_eth_rx_tready; wire [PORT_COUNT-1:0] axis_eth_rx_tlast; wire [PORT_COUNT*AXIS_ETH_RX_USER_WIDTH-1:0] axis_eth_rx_tuser; +wire [PORT_COUNT-1:0] eth_rx_enable; wire [PORT_COUNT-1:0] eth_rx_status; +wire [PORT_COUNT-1:0] eth_rx_lfc_en; +wire [PORT_COUNT-1:0] eth_rx_lfc_req; +wire [PORT_COUNT-1:0] eth_rx_lfc_ack; +wire [PORT_COUNT*8-1:0] eth_rx_pfc_en; +wire [PORT_COUNT*8-1:0] eth_rx_pfc_req; +wire [PORT_COUNT*8-1:0] eth_rx_pfc_ack; wire [PTP_TS_WIDTH-1:0] qsfp_0_tx_ptp_time_int; wire [PTP_TS_WIDTH-1:0] qsfp_1_tx_ptp_time_int; @@ -918,7 +958,12 @@ mqnic_port_map_mac_axis_inst ( .s_axis_mac_tx_ptp_ts_valid({qsfp_1_tx_ptp_ts_valid, qsfp_0_tx_ptp_ts_valid}), .s_axis_mac_tx_ptp_ts_ready(), + .mac_tx_enable({qsfp_1_tx_enable, qsfp_0_tx_enable}), .mac_tx_status(2'b11), + .mac_tx_lfc_en({qsfp_1_tx_lfc_en, qsfp_0_tx_lfc_en}), + .mac_tx_lfc_req({qsfp_1_tx_lfc_req, qsfp_0_tx_lfc_req}), + .mac_tx_pfc_en({qsfp_1_tx_pfc_en, qsfp_0_tx_pfc_en}), + .mac_tx_pfc_req({qsfp_1_tx_pfc_req, qsfp_0_tx_pfc_req}), .mac_rx_clk({qsfp_1_rx_clk, qsfp_0_rx_clk}), .mac_rx_rst({qsfp_1_rx_rst, qsfp_0_rx_rst}), @@ -935,7 +980,14 @@ mqnic_port_map_mac_axis_inst ( .s_axis_mac_rx_tlast({qsfp_1_rx_axis_tlast, qsfp_0_rx_axis_tlast}), .s_axis_mac_rx_tuser({{qsfp_1_rx_axis_tuser[80:1], 16'd0, qsfp_1_rx_axis_tuser[0]}, {qsfp_0_rx_axis_tuser[80:1], 16'd0, qsfp_0_rx_axis_tuser[0]}}), + .mac_rx_enable({qsfp_1_rx_enable, qsfp_0_rx_enable}), .mac_rx_status({qsfp_1_rx_status, qsfp_0_rx_status}), + .mac_rx_lfc_en({qsfp_1_rx_lfc_en, qsfp_0_rx_lfc_en}), + .mac_rx_lfc_req({qsfp_1_rx_lfc_req, qsfp_0_rx_lfc_req}), + .mac_rx_lfc_ack({qsfp_1_rx_lfc_ack, qsfp_0_rx_lfc_ack}), + .mac_rx_pfc_en({qsfp_1_rx_pfc_en, qsfp_0_rx_pfc_en}), + .mac_rx_pfc_req({qsfp_1_rx_pfc_req, qsfp_0_rx_pfc_req}), + .mac_rx_pfc_ack({qsfp_1_rx_pfc_ack, qsfp_0_rx_pfc_ack}), // towards datapath .tx_clk(eth_tx_clk), @@ -958,7 +1010,12 @@ mqnic_port_map_mac_axis_inst ( .m_axis_tx_ptp_ts_valid(axis_eth_tx_ptp_ts_valid), .m_axis_tx_ptp_ts_ready(axis_eth_tx_ptp_ts_ready), + .tx_enable(eth_tx_enable), .tx_status(eth_tx_status), + .tx_lfc_en(eth_tx_lfc_en), + .tx_lfc_req(eth_tx_lfc_req), + .tx_pfc_en(eth_tx_pfc_en), + .tx_pfc_req(eth_tx_pfc_req), .rx_clk(eth_rx_clk), .rx_rst(eth_rx_rst), @@ -975,7 +1032,14 @@ mqnic_port_map_mac_axis_inst ( .m_axis_rx_tlast(axis_eth_rx_tlast), .m_axis_rx_tuser(axis_eth_rx_tuser), - .rx_status(eth_rx_status) + .rx_enable(eth_rx_enable), + .rx_status(eth_rx_status), + .rx_lfc_en(eth_rx_lfc_en), + .rx_lfc_req(eth_rx_lfc_req), + .rx_lfc_ack(eth_rx_lfc_ack), + .rx_pfc_en(eth_rx_pfc_en), + .rx_pfc_req(eth_rx_pfc_req), + .rx_pfc_ack(eth_rx_pfc_ack) ); mqnic_core_pcie_us #( @@ -1045,6 +1109,9 @@ mqnic_core_pcie_us #( .TX_CHECKSUM_ENABLE(TX_CHECKSUM_ENABLE), .RX_HASH_ENABLE(RX_HASH_ENABLE), .RX_CHECKSUM_ENABLE(RX_CHECKSUM_ENABLE), + .PFC_ENABLE(PFC_ENABLE), + .LFC_ENABLE(LFC_ENABLE), + .MAC_CTRL_ENABLE(0), .TX_FIFO_DEPTH(TX_FIFO_DEPTH), .RX_FIFO_DEPTH(RX_FIFO_DEPTH), .MAX_TX_SIZE(MAX_TX_SIZE), @@ -1326,7 +1393,13 @@ core_inst ( .s_axis_eth_tx_cpl_valid(axis_eth_tx_ptp_ts_valid), .s_axis_eth_tx_cpl_ready(axis_eth_tx_ptp_ts_ready), + .eth_tx_enable(eth_tx_enable), .eth_tx_status(eth_tx_status), + .eth_tx_lfc_en(eth_tx_lfc_en), + .eth_tx_lfc_req(eth_tx_lfc_req), + .eth_tx_pfc_en(eth_tx_pfc_en), + .eth_tx_pfc_req(eth_tx_pfc_req), + .eth_tx_fc_quanta_clk_en(0), .eth_rx_clk(eth_rx_clk), .eth_rx_rst(eth_rx_rst), @@ -1343,7 +1416,15 @@ core_inst ( .s_axis_eth_rx_tlast(axis_eth_rx_tlast), .s_axis_eth_rx_tuser(axis_eth_rx_tuser), + .eth_rx_enable(eth_rx_enable), .eth_rx_status(eth_rx_status), + .eth_rx_lfc_en(eth_rx_lfc_en), + .eth_rx_lfc_req(eth_rx_lfc_req), + .eth_rx_lfc_ack(eth_rx_lfc_ack), + .eth_rx_pfc_en(eth_rx_pfc_en), + .eth_rx_pfc_req(eth_rx_pfc_req), + .eth_rx_pfc_ack(eth_rx_pfc_ack), + .eth_rx_fc_quanta_clk_en(0), /* * DDR diff --git a/fpga/mqnic/ADM_PCIE_9V3/fpga_100g/tb/fpga_core/Makefile b/fpga/mqnic/ADM_PCIE_9V3/fpga_100g/tb/fpga_core/Makefile index 06bcd666c..234a9b657 100644 --- a/fpga/mqnic/ADM_PCIE_9V3/fpga_100g/tb/fpga_core/Makefile +++ b/fpga/mqnic/ADM_PCIE_9V3/fpga_100g/tb/fpga_core/Makefile @@ -162,6 +162,8 @@ export PARAM_TX_CPL_FIFO_DEPTH := 32 export PARAM_TX_CHECKSUM_ENABLE := 1 export PARAM_RX_HASH_ENABLE := 1 export PARAM_RX_CHECKSUM_ENABLE := 1 +export PARAM_LFC_ENABLE := 1 +export PARAM_PFC_ENABLE := $(PARAM_LFC_ENABLE) export PARAM_TX_FIFO_DEPTH := 32768 export PARAM_RX_FIFO_DEPTH := 131072 export PARAM_MAX_TX_SIZE := 9214 diff --git a/fpga/mqnic/ADM_PCIE_9V3/fpga_100g/tb/fpga_core/test_fpga_core.py b/fpga/mqnic/ADM_PCIE_9V3/fpga_100g/tb/fpga_core/test_fpga_core.py index 7a9c3842b..2b8147214 100644 --- a/fpga/mqnic/ADM_PCIE_9V3/fpga_100g/tb/fpga_core/test_fpga_core.py +++ b/fpga/mqnic/ADM_PCIE_9V3/fpga_100g/tb/fpga_core/test_fpga_core.py @@ -300,6 +300,8 @@ class TB(object): self.qsfp_mac.append(mac) getattr(dut, f"qsfp_{k}_rx_status").setimmediatevalue(1) + getattr(dut, f"qsfp_{k}_rx_lfc_req").setimmediatevalue(0) + getattr(dut, f"qsfp_{k}_rx_pfc_req").setimmediatevalue(0) cocotb.start_soon(Clock(getattr(dut, f"qsfp_{k}_drp_clk"), 8, units="ns").start()) getattr(dut, f"qsfp_{k}_drp_rst").setimmediatevalue(0) @@ -726,6 +728,8 @@ def test_fpga_core(request): parameters['TX_CHECKSUM_ENABLE'] = 1 parameters['RX_HASH_ENABLE'] = 1 parameters['RX_CHECKSUM_ENABLE'] = 1 + parameters['LFC_ENABLE'] = 1 + parameters['PFC_ENABLE'] = parameters['LFC_ENABLE'] parameters['TX_FIFO_DEPTH'] = 32768 parameters['RX_FIFO_DEPTH'] = 131072 parameters['MAX_TX_SIZE'] = 9214 diff --git a/fpga/mqnic/ADM_PCIE_9V3/fpga_25g/fpga/Makefile b/fpga/mqnic/ADM_PCIE_9V3/fpga_25g/fpga/Makefile index 6520d85d1..689393774 100644 --- a/fpga/mqnic/ADM_PCIE_9V3/fpga_25g/fpga/Makefile +++ b/fpga/mqnic/ADM_PCIE_9V3/fpga_25g/fpga/Makefile @@ -63,6 +63,10 @@ SYN_FILES += rtl/common/i2c_single_reg.v SYN_FILES += lib/eth/rtl/eth_mac_10g.v SYN_FILES += lib/eth/rtl/axis_xgmii_rx_64.v SYN_FILES += lib/eth/rtl/axis_xgmii_tx_64.v +SYN_FILES += lib/eth/rtl/mac_ctrl_rx.v +SYN_FILES += lib/eth/rtl/mac_ctrl_tx.v +SYN_FILES += lib/eth/rtl/mac_pause_ctrl_rx.v +SYN_FILES += lib/eth/rtl/mac_pause_ctrl_tx.v SYN_FILES += lib/eth/rtl/eth_phy_10g.v SYN_FILES += lib/eth/rtl/eth_phy_10g_rx.v SYN_FILES += lib/eth/rtl/eth_phy_10g_rx_if.v diff --git a/fpga/mqnic/ADM_PCIE_9V3/fpga_25g/fpga/config.tcl b/fpga/mqnic/ADM_PCIE_9V3/fpga_25g/fpga/config.tcl index 0edcf84fd..1ba3cbb1e 100644 --- a/fpga/mqnic/ADM_PCIE_9V3/fpga_25g/fpga/config.tcl +++ b/fpga/mqnic/ADM_PCIE_9V3/fpga_25g/fpga/config.tcl @@ -113,6 +113,8 @@ dict set params TX_CPL_FIFO_DEPTH "32" dict set params TX_CHECKSUM_ENABLE "1" dict set params RX_HASH_ENABLE "1" dict set params RX_CHECKSUM_ENABLE "1" +dict set params PFC_ENABLE "1" +dict set params LFC_ENABLE [dict get $params PFC_ENABLE] dict set params ENABLE_PADDING "1" dict set params ENABLE_DIC "1" dict set params MIN_FRAME_LENGTH "64" diff --git a/fpga/mqnic/ADM_PCIE_9V3/fpga_25g/fpga_10g/Makefile b/fpga/mqnic/ADM_PCIE_9V3/fpga_25g/fpga_10g/Makefile index 6520d85d1..689393774 100644 --- a/fpga/mqnic/ADM_PCIE_9V3/fpga_25g/fpga_10g/Makefile +++ b/fpga/mqnic/ADM_PCIE_9V3/fpga_25g/fpga_10g/Makefile @@ -63,6 +63,10 @@ SYN_FILES += rtl/common/i2c_single_reg.v SYN_FILES += lib/eth/rtl/eth_mac_10g.v SYN_FILES += lib/eth/rtl/axis_xgmii_rx_64.v SYN_FILES += lib/eth/rtl/axis_xgmii_tx_64.v +SYN_FILES += lib/eth/rtl/mac_ctrl_rx.v +SYN_FILES += lib/eth/rtl/mac_ctrl_tx.v +SYN_FILES += lib/eth/rtl/mac_pause_ctrl_rx.v +SYN_FILES += lib/eth/rtl/mac_pause_ctrl_tx.v SYN_FILES += lib/eth/rtl/eth_phy_10g.v SYN_FILES += lib/eth/rtl/eth_phy_10g_rx.v SYN_FILES += lib/eth/rtl/eth_phy_10g_rx_if.v diff --git a/fpga/mqnic/ADM_PCIE_9V3/fpga_25g/fpga_10g/config.tcl b/fpga/mqnic/ADM_PCIE_9V3/fpga_25g/fpga_10g/config.tcl index 55cd4605c..28aee3fbd 100644 --- a/fpga/mqnic/ADM_PCIE_9V3/fpga_25g/fpga_10g/config.tcl +++ b/fpga/mqnic/ADM_PCIE_9V3/fpga_25g/fpga_10g/config.tcl @@ -113,6 +113,8 @@ dict set params TX_CPL_FIFO_DEPTH "32" dict set params TX_CHECKSUM_ENABLE "1" dict set params RX_HASH_ENABLE "1" dict set params RX_CHECKSUM_ENABLE "1" +dict set params PFC_ENABLE "1" +dict set params LFC_ENABLE [dict get $params PFC_ENABLE] dict set params ENABLE_PADDING "1" dict set params ENABLE_DIC "1" dict set params MIN_FRAME_LENGTH "64" diff --git a/fpga/mqnic/ADM_PCIE_9V3/fpga_25g/fpga_tdma/Makefile b/fpga/mqnic/ADM_PCIE_9V3/fpga_25g/fpga_tdma/Makefile index 72acf132c..557016e18 100644 --- a/fpga/mqnic/ADM_PCIE_9V3/fpga_25g/fpga_tdma/Makefile +++ b/fpga/mqnic/ADM_PCIE_9V3/fpga_25g/fpga_tdma/Makefile @@ -60,10 +60,14 @@ SYN_FILES += rtl/common/tx_scheduler_ctrl_tdma.v SYN_FILES += rtl/common/tdma_scheduler.v SYN_FILES += rtl/common/tdma_ber.v SYN_FILES += rtl/common/tdma_ber_ch.v -SYN_FILES += lib/eth/rtl/eth_mac_10g.v SYN_FILES += rtl/common/i2c_single_reg.v +SYN_FILES += lib/eth/rtl/eth_mac_10g.v SYN_FILES += lib/eth/rtl/axis_xgmii_rx_64.v SYN_FILES += lib/eth/rtl/axis_xgmii_tx_64.v +SYN_FILES += lib/eth/rtl/mac_ctrl_rx.v +SYN_FILES += lib/eth/rtl/mac_ctrl_tx.v +SYN_FILES += lib/eth/rtl/mac_pause_ctrl_rx.v +SYN_FILES += lib/eth/rtl/mac_pause_ctrl_tx.v SYN_FILES += lib/eth/rtl/eth_phy_10g.v SYN_FILES += lib/eth/rtl/eth_phy_10g_rx.v SYN_FILES += lib/eth/rtl/eth_phy_10g_rx_if.v diff --git a/fpga/mqnic/ADM_PCIE_9V3/fpga_25g/fpga_tdma/config.tcl b/fpga/mqnic/ADM_PCIE_9V3/fpga_25g/fpga_tdma/config.tcl index e47ee50bf..f36decd13 100644 --- a/fpga/mqnic/ADM_PCIE_9V3/fpga_25g/fpga_tdma/config.tcl +++ b/fpga/mqnic/ADM_PCIE_9V3/fpga_25g/fpga_tdma/config.tcl @@ -113,6 +113,8 @@ dict set params TX_CPL_FIFO_DEPTH "32" dict set params TX_CHECKSUM_ENABLE "1" dict set params RX_HASH_ENABLE "1" dict set params RX_CHECKSUM_ENABLE "1" +dict set params PFC_ENABLE "1" +dict set params LFC_ENABLE [dict get $params PFC_ENABLE] dict set params ENABLE_PADDING "1" dict set params ENABLE_DIC "1" dict set params MIN_FRAME_LENGTH "64" diff --git a/fpga/mqnic/ADM_PCIE_9V3/fpga_25g/rtl/fpga.v b/fpga/mqnic/ADM_PCIE_9V3/fpga_25g/rtl/fpga.v index f37cf4df7..9c31ba2d3 100644 --- a/fpga/mqnic/ADM_PCIE_9V3/fpga_25g/rtl/fpga.v +++ b/fpga/mqnic/ADM_PCIE_9V3/fpga_25g/rtl/fpga.v @@ -74,6 +74,8 @@ module fpga # parameter TX_CHECKSUM_ENABLE = 1, parameter RX_HASH_ENABLE = 1, parameter RX_CHECKSUM_ENABLE = 1, + parameter PFC_ENABLE = 1, + parameter LFC_ENABLE = PFC_ENABLE, parameter ENABLE_PADDING = 1, parameter ENABLE_DIC = 1, parameter MIN_FRAME_LENGTH = 64, @@ -1740,6 +1742,8 @@ fpga_core #( .TX_CHECKSUM_ENABLE(TX_CHECKSUM_ENABLE), .RX_HASH_ENABLE(RX_HASH_ENABLE), .RX_CHECKSUM_ENABLE(RX_CHECKSUM_ENABLE), + .PFC_ENABLE(PFC_ENABLE), + .LFC_ENABLE(LFC_ENABLE), .ENABLE_PADDING(ENABLE_PADDING), .ENABLE_DIC(ENABLE_DIC), .MIN_FRAME_LENGTH(MIN_FRAME_LENGTH), diff --git a/fpga/mqnic/ADM_PCIE_9V3/fpga_25g/rtl/fpga_core.v b/fpga/mqnic/ADM_PCIE_9V3/fpga_25g/rtl/fpga_core.v index 9e9d2f828..236d5909b 100644 --- a/fpga/mqnic/ADM_PCIE_9V3/fpga_25g/rtl/fpga_core.v +++ b/fpga/mqnic/ADM_PCIE_9V3/fpga_25g/rtl/fpga_core.v @@ -81,6 +81,8 @@ module fpga_core # parameter TX_CHECKSUM_ENABLE = 1, parameter RX_HASH_ENABLE = 1, parameter RX_CHECKSUM_ENABLE = 1, + parameter PFC_ENABLE = 1, + parameter LFC_ENABLE = PFC_ENABLE, parameter ENABLE_PADDING = 1, parameter ENABLE_DIC = 1, parameter MIN_FRAME_LENGTH = 64, @@ -997,7 +999,12 @@ wire [PORT_COUNT*TX_TAG_WIDTH-1:0] axis_eth_tx_ptp_ts_tag; wire [PORT_COUNT-1:0] axis_eth_tx_ptp_ts_valid; wire [PORT_COUNT-1:0] axis_eth_tx_ptp_ts_ready; +wire [PORT_COUNT-1:0] eth_tx_enable; wire [PORT_COUNT-1:0] eth_tx_status; +wire [PORT_COUNT-1:0] eth_tx_lfc_en; +wire [PORT_COUNT-1:0] eth_tx_lfc_req; +wire [PORT_COUNT*8-1:0] eth_tx_pfc_en; +wire [PORT_COUNT*8-1:0] eth_tx_pfc_req; wire [PORT_COUNT-1:0] eth_rx_clk; wire [PORT_COUNT-1:0] eth_rx_rst; @@ -1012,7 +1019,14 @@ wire [PORT_COUNT-1:0] axis_eth_rx_tready; wire [PORT_COUNT-1:0] axis_eth_rx_tlast; wire [PORT_COUNT*AXIS_ETH_RX_USER_WIDTH-1:0] axis_eth_rx_tuser; +wire [PORT_COUNT-1:0] eth_rx_enable; wire [PORT_COUNT-1:0] eth_rx_status; +wire [PORT_COUNT-1:0] eth_rx_lfc_en; +wire [PORT_COUNT-1:0] eth_rx_lfc_req; +wire [PORT_COUNT-1:0] eth_rx_lfc_ack; +wire [PORT_COUNT*8-1:0] eth_rx_pfc_en; +wire [PORT_COUNT*8-1:0] eth_rx_pfc_req; +wire [PORT_COUNT*8-1:0] eth_rx_pfc_ack; wire [PORT_COUNT-1:0] port_xgmii_tx_clk; wire [PORT_COUNT-1:0] port_xgmii_tx_rst; @@ -1085,12 +1099,15 @@ generate .PTP_PERIOD_FNS(IF_PTP_PERIOD_FNS), .TX_PTP_TS_ENABLE(PTP_TS_ENABLE), .TX_PTP_TS_WIDTH(PTP_TS_WIDTH), + .TX_PTP_TS_CTRL_IN_TUSER(0), .TX_PTP_TAG_ENABLE(PTP_TS_ENABLE), .TX_PTP_TAG_WIDTH(TX_TAG_WIDTH), .RX_PTP_TS_ENABLE(PTP_TS_ENABLE), .RX_PTP_TS_WIDTH(PTP_TS_WIDTH), .TX_USER_WIDTH(AXIS_ETH_TX_USER_WIDTH), - .RX_USER_WIDTH(AXIS_ETH_RX_USER_WIDTH) + .RX_USER_WIDTH(AXIS_ETH_RX_USER_WIDTH), + .PFC_ENABLE(PFC_ENABLE), + .PAUSE_ENABLE(LFC_ENABLE) ) eth_mac_inst ( .tx_clk(port_xgmii_tx_clk[n]), @@ -1098,6 +1115,9 @@ generate .rx_clk(port_xgmii_rx_clk[n]), .rx_rst(port_xgmii_rx_rst[n]), + /* + * AXI input + */ .tx_axis_tdata(axis_eth_tx_tdata[n*AXIS_ETH_DATA_WIDTH +: AXIS_ETH_DATA_WIDTH]), .tx_axis_tkeep(axis_eth_tx_tkeep[n*AXIS_ETH_KEEP_WIDTH +: AXIS_ETH_KEEP_WIDTH]), .tx_axis_tvalid(axis_eth_tx_tvalid[n +: 1]), @@ -1105,30 +1125,121 @@ generate .tx_axis_tlast(axis_eth_tx_tlast[n +: 1]), .tx_axis_tuser(axis_eth_tx_tuser[n*AXIS_ETH_TX_USER_WIDTH +: AXIS_ETH_TX_USER_WIDTH]), + /* + * AXI output + */ .rx_axis_tdata(axis_eth_rx_tdata[n*AXIS_ETH_DATA_WIDTH +: AXIS_ETH_DATA_WIDTH]), .rx_axis_tkeep(axis_eth_rx_tkeep[n*AXIS_ETH_KEEP_WIDTH +: AXIS_ETH_KEEP_WIDTH]), .rx_axis_tvalid(axis_eth_rx_tvalid[n +: 1]), .rx_axis_tlast(axis_eth_rx_tlast[n +: 1]), .rx_axis_tuser(axis_eth_rx_tuser[n*AXIS_ETH_RX_USER_WIDTH +: AXIS_ETH_RX_USER_WIDTH]), + /* + * XGMII interface + */ .xgmii_rxd(port_xgmii_rxd[n*XGMII_DATA_WIDTH +: XGMII_DATA_WIDTH]), .xgmii_rxc(port_xgmii_rxc[n*XGMII_CTRL_WIDTH +: XGMII_CTRL_WIDTH]), .xgmii_txd(port_xgmii_txd[n*XGMII_DATA_WIDTH +: XGMII_DATA_WIDTH]), .xgmii_txc(port_xgmii_txc[n*XGMII_CTRL_WIDTH +: XGMII_CTRL_WIDTH]), + /* + * PTP + */ .tx_ptp_ts(eth_tx_ptp_ts_96[n*PTP_TS_WIDTH +: PTP_TS_WIDTH]), .rx_ptp_ts(eth_rx_ptp_ts_96[n*PTP_TS_WIDTH +: PTP_TS_WIDTH]), .tx_axis_ptp_ts(axis_eth_tx_ptp_ts[n*PTP_TS_WIDTH +: PTP_TS_WIDTH]), .tx_axis_ptp_ts_tag(axis_eth_tx_ptp_ts_tag[n*TX_TAG_WIDTH +: TX_TAG_WIDTH]), .tx_axis_ptp_ts_valid(axis_eth_tx_ptp_ts_valid[n +: 1]), + /* + * Link-level Flow Control (LFC) (IEEE 802.3 annex 31B PAUSE) + */ + .tx_lfc_req(eth_tx_lfc_req[n +: 1]), + .tx_lfc_resend(1'b0), + .rx_lfc_en(eth_rx_lfc_en[n +: 1]), + .rx_lfc_req(eth_rx_lfc_req[n +: 1]), + .rx_lfc_ack(eth_rx_lfc_ack[n +: 1]), + + /* + * Priority Flow Control (PFC) (IEEE 802.3 annex 31D PFC) + */ + .tx_pfc_req(eth_tx_pfc_req[n*8 +: 8]), + .tx_pfc_resend(1'b0), + .rx_pfc_en(eth_rx_pfc_en[n*8 +: 8]), + .rx_pfc_req(eth_rx_pfc_req[n*8 +: 8]), + .rx_pfc_ack(eth_rx_pfc_ack[n*8 +: 8]), + + /* + * Pause interface + */ + .tx_lfc_pause_en(1'b1), + .tx_pause_req(1'b0), + .tx_pause_ack(), + + /* + * Status + */ + .tx_start_packet(), .tx_error_underflow(), + .rx_start_packet(), .rx_error_bad_frame(), .rx_error_bad_fcs(), + .stat_tx_mcf(), + .stat_rx_mcf(), + .stat_tx_lfc_pkt(), + .stat_tx_lfc_xon(), + .stat_tx_lfc_xoff(), + .stat_tx_lfc_paused(), + .stat_tx_pfc_pkt(), + .stat_tx_pfc_xon(), + .stat_tx_pfc_xoff(), + .stat_tx_pfc_paused(), + .stat_rx_lfc_pkt(), + .stat_rx_lfc_xon(), + .stat_rx_lfc_xoff(), + .stat_rx_lfc_paused(), + .stat_rx_pfc_pkt(), + .stat_rx_pfc_xon(), + .stat_rx_pfc_xoff(), + .stat_rx_pfc_paused(), + /* + * Configuration + */ .cfg_ifg(8'd12), - .cfg_tx_enable(1'b1), - .cfg_rx_enable(1'b1) + .cfg_tx_enable(eth_tx_enable[n +: 1]), + .cfg_rx_enable(eth_rx_enable[n +: 1]), + .cfg_mcf_rx_eth_dst_mcast(48'h01_80_C2_00_00_01), + .cfg_mcf_rx_check_eth_dst_mcast(1'b1), + .cfg_mcf_rx_eth_dst_ucast(48'd0), + .cfg_mcf_rx_check_eth_dst_ucast(1'b0), + .cfg_mcf_rx_eth_src(48'd0), + .cfg_mcf_rx_check_eth_src(1'b0), + .cfg_mcf_rx_eth_type(16'h8808), + .cfg_mcf_rx_opcode_lfc(16'h0001), + .cfg_mcf_rx_check_opcode_lfc(eth_rx_lfc_en[n +: 1]), + .cfg_mcf_rx_opcode_pfc(16'h0101), + .cfg_mcf_rx_check_opcode_pfc(eth_rx_pfc_en[n*8 +: 8] != 0), + .cfg_mcf_rx_forward(1'b0), + .cfg_mcf_rx_enable(eth_rx_lfc_en[n +: 1] || eth_rx_pfc_en[n*8 +: 8]), + .cfg_tx_lfc_eth_dst(48'h01_80_C2_00_00_01), + .cfg_tx_lfc_eth_src(48'h80_23_31_43_54_4C), + .cfg_tx_lfc_eth_type(16'h8808), + .cfg_tx_lfc_opcode(16'h0001), + .cfg_tx_lfc_en(eth_tx_lfc_en[n +: 1]), + .cfg_tx_lfc_quanta(16'hffff), + .cfg_tx_lfc_refresh(16'h7fff), + .cfg_tx_pfc_eth_dst(48'h01_80_C2_00_00_01), + .cfg_tx_pfc_eth_src(48'h80_23_31_43_54_4C), + .cfg_tx_pfc_eth_type(16'h8808), + .cfg_tx_pfc_opcode(16'h0101), + .cfg_tx_pfc_en(eth_tx_pfc_en[n*8 +: 8] != 0), + .cfg_tx_pfc_quanta({8{16'hffff}}), + .cfg_tx_pfc_refresh({8{16'h7fff}}), + .cfg_rx_lfc_opcode(16'h0001), + .cfg_rx_lfc_en(eth_rx_lfc_en[n +: 1]), + .cfg_rx_pfc_opcode(16'h0101), + .cfg_rx_pfc_en(eth_rx_pfc_en[n*8 +: 8] != 0) ); end @@ -1202,6 +1313,9 @@ mqnic_core_pcie_us #( .TX_CHECKSUM_ENABLE(TX_CHECKSUM_ENABLE), .RX_HASH_ENABLE(RX_HASH_ENABLE), .RX_CHECKSUM_ENABLE(RX_CHECKSUM_ENABLE), + .PFC_ENABLE(PFC_ENABLE), + .LFC_ENABLE(LFC_ENABLE), + .MAC_CTRL_ENABLE(0), .TX_FIFO_DEPTH(TX_FIFO_DEPTH), .RX_FIFO_DEPTH(RX_FIFO_DEPTH), .MAX_TX_SIZE(MAX_TX_SIZE), @@ -1483,7 +1597,13 @@ core_inst ( .s_axis_eth_tx_cpl_valid(axis_eth_tx_ptp_ts_valid), .s_axis_eth_tx_cpl_ready(axis_eth_tx_ptp_ts_ready), + .eth_tx_enable(eth_tx_enable), .eth_tx_status(eth_tx_status), + .eth_tx_lfc_en(eth_tx_lfc_en), + .eth_tx_lfc_req(eth_tx_lfc_req), + .eth_tx_pfc_en(eth_tx_pfc_en), + .eth_tx_pfc_req(eth_tx_pfc_req), + .eth_tx_fc_quanta_clk_en(0), .eth_rx_clk(eth_rx_clk), .eth_rx_rst(eth_rx_rst), @@ -1500,7 +1620,15 @@ core_inst ( .s_axis_eth_rx_tlast(axis_eth_rx_tlast), .s_axis_eth_rx_tuser(axis_eth_rx_tuser), + .eth_rx_enable(eth_rx_enable), .eth_rx_status(eth_rx_status), + .eth_rx_lfc_en(eth_rx_lfc_en), + .eth_rx_lfc_req(eth_rx_lfc_req), + .eth_rx_lfc_ack(eth_rx_lfc_ack), + .eth_rx_pfc_en(eth_rx_pfc_en), + .eth_rx_pfc_req(eth_rx_pfc_req), + .eth_rx_pfc_ack(eth_rx_pfc_ack), + .eth_rx_fc_quanta_clk_en(0), /* * DDR diff --git a/fpga/mqnic/ADM_PCIE_9V3/fpga_25g/tb/fpga_core/Makefile b/fpga/mqnic/ADM_PCIE_9V3/fpga_25g/tb/fpga_core/Makefile index 138b6c194..b0060d1eb 100644 --- a/fpga/mqnic/ADM_PCIE_9V3/fpga_25g/tb/fpga_core/Makefile +++ b/fpga/mqnic/ADM_PCIE_9V3/fpga_25g/tb/fpga_core/Makefile @@ -63,6 +63,10 @@ VERILOG_SOURCES += ../../rtl/common/i2c_single_reg.v VERILOG_SOURCES += ../../lib/eth/rtl/eth_mac_10g.v VERILOG_SOURCES += ../../lib/eth/rtl/axis_xgmii_rx_64.v VERILOG_SOURCES += ../../lib/eth/rtl/axis_xgmii_tx_64.v +VERILOG_SOURCES += ../../lib/eth/rtl/mac_ctrl_rx.v +VERILOG_SOURCES += ../../lib/eth/rtl/mac_ctrl_tx.v +VERILOG_SOURCES += ../../lib/eth/rtl/mac_pause_ctrl_rx.v +VERILOG_SOURCES += ../../lib/eth/rtl/mac_pause_ctrl_tx.v VERILOG_SOURCES += ../../lib/eth/rtl/lfsr.v VERILOG_SOURCES += ../../lib/eth/rtl/ptp_clock.v VERILOG_SOURCES += ../../lib/eth/rtl/ptp_clock_cdc.v @@ -168,6 +172,8 @@ export PARAM_TX_CPL_FIFO_DEPTH := 32 export PARAM_TX_CHECKSUM_ENABLE := 1 export PARAM_RX_HASH_ENABLE := 1 export PARAM_RX_CHECKSUM_ENABLE := 1 +export PARAM_LFC_ENABLE := 1 +export PARAM_PFC_ENABLE := $(PARAM_LFC_ENABLE) export PARAM_TX_FIFO_DEPTH := 32768 export PARAM_RX_FIFO_DEPTH := 32768 export PARAM_MAX_TX_SIZE := 9214 diff --git a/fpga/mqnic/ADM_PCIE_9V3/fpga_25g/tb/fpga_core/test_fpga_core.py b/fpga/mqnic/ADM_PCIE_9V3/fpga_25g/tb/fpga_core/test_fpga_core.py index ee749f1ab..fd781499b 100644 --- a/fpga/mqnic/ADM_PCIE_9V3/fpga_25g/tb/fpga_core/test_fpga_core.py +++ b/fpga/mqnic/ADM_PCIE_9V3/fpga_25g/tb/fpga_core/test_fpga_core.py @@ -3,6 +3,7 @@ import logging import os +import struct import sys import scapy.utils @@ -17,7 +18,7 @@ from cocotb.clock import Clock from cocotb.triggers import RisingEdge, FallingEdge, Timer from cocotbext.axi import AxiStreamBus -from cocotbext.eth import XgmiiSource, XgmiiSink +from cocotbext.eth import XgmiiSource, XgmiiSink, XgmiiFrame from cocotbext.pcie.core import RootComplex from cocotbext.pcie.xilinx.us import UltraScalePlusPcieDevice @@ -530,6 +531,35 @@ async def run_test_nic(dut): tb.loopback_enable = False + if tb.driver.interfaces[0].if_feature_lfc: + tb.log.info("Test LFC pause frame RX") + + await tb.driver.interfaces[0].ports[0].set_lfc_ctrl(mqnic.MQNIC_PORT_LFC_CTRL_TX_LFC_EN | mqnic.MQNIC_PORT_LFC_CTRL_RX_LFC_EN) + await tb.driver.hw_regs.read_dword(0) + + lfc_xoff = Ether(src='DA:D1:D2:D3:D4:D5', dst='01:80:C2:00:00:01', type=0x8808) / struct.pack('!HH', 0x0001, 2000) + + await tb.qsfp_source[0][0].send(XgmiiFrame.from_payload(bytes(lfc_xoff))) + + count = 16 + + pkts = [bytearray([(x+k) % 256 for x in range(1514)]) for k in range(count)] + + tb.loopback_enable = True + + for p in pkts: + await tb.driver.interfaces[0].start_xmit(p, 0) + + for k in range(count): + pkt = await tb.driver.interfaces[0].recv() + + tb.log.info("Packet: %s", pkt) + assert pkt.data == pkts[k] + if tb.driver.interfaces[0].if_feature_rx_csum: + assert pkt.rx_checksum == ~scapy.utils.checksum(bytes(pkt.data[14:])) & 0xffff + + tb.loopback_enable = False + await RisingEdge(dut.clk_250mhz) await RisingEdge(dut.clk_250mhz) @@ -603,6 +633,10 @@ def test_fpga_core(request): os.path.join(eth_rtl_dir, "eth_mac_10g.v"), os.path.join(eth_rtl_dir, "axis_xgmii_rx_64.v"), os.path.join(eth_rtl_dir, "axis_xgmii_tx_64.v"), + os.path.join(eth_rtl_dir, "mac_ctrl_rx.v"), + os.path.join(eth_rtl_dir, "mac_ctrl_tx.v"), + os.path.join(eth_rtl_dir, "mac_pause_ctrl_rx.v"), + os.path.join(eth_rtl_dir, "mac_pause_ctrl_tx.v"), os.path.join(eth_rtl_dir, "lfsr.v"), os.path.join(eth_rtl_dir, "ptp_clock.v"), os.path.join(eth_rtl_dir, "ptp_clock_cdc.v"), @@ -709,6 +743,8 @@ def test_fpga_core(request): parameters['TX_CHECKSUM_ENABLE'] = 1 parameters['RX_HASH_ENABLE'] = 1 parameters['RX_CHECKSUM_ENABLE'] = 1 + parameters['LFC_ENABLE'] = 1 + parameters['PFC_ENABLE'] = parameters['LFC_ENABLE'] parameters['TX_FIFO_DEPTH'] = 32768 parameters['RX_FIFO_DEPTH'] = 32768 parameters['MAX_TX_SIZE'] = 9214 diff --git a/fpga/mqnic/AU200/fpga_100g/fpga/config.tcl b/fpga/mqnic/AU200/fpga_100g/fpga/config.tcl index 00ffac47e..51ac43431 100644 --- a/fpga/mqnic/AU200/fpga_100g/fpga/config.tcl +++ b/fpga/mqnic/AU200/fpga_100g/fpga/config.tcl @@ -101,6 +101,8 @@ dict set params TX_CPL_FIFO_DEPTH "32" dict set params TX_CHECKSUM_ENABLE "1" dict set params RX_HASH_ENABLE "1" dict set params RX_CHECKSUM_ENABLE "1" +dict set params PFC_ENABLE "1" +dict set params LFC_ENABLE [dict get $params PFC_ENABLE] dict set params TX_FIFO_DEPTH "32768" dict set params RX_FIFO_DEPTH "131072" dict set params MAX_TX_SIZE "9214" diff --git a/fpga/mqnic/AU200/fpga_100g/fpga_app_dma_bench/config.tcl b/fpga/mqnic/AU200/fpga_100g/fpga_app_dma_bench/config.tcl index 615398a2b..8ef19482b 100644 --- a/fpga/mqnic/AU200/fpga_100g/fpga_app_dma_bench/config.tcl +++ b/fpga/mqnic/AU200/fpga_100g/fpga_app_dma_bench/config.tcl @@ -101,6 +101,8 @@ dict set params TX_CPL_FIFO_DEPTH "32" dict set params TX_CHECKSUM_ENABLE "1" dict set params RX_HASH_ENABLE "1" dict set params RX_CHECKSUM_ENABLE "1" +dict set params PFC_ENABLE "1" +dict set params LFC_ENABLE [dict get $params PFC_ENABLE] dict set params TX_FIFO_DEPTH "32768" dict set params RX_FIFO_DEPTH "131072" dict set params MAX_TX_SIZE "9214" diff --git a/fpga/mqnic/AU200/fpga_100g/ip/cmac_usplus.tcl b/fpga/mqnic/AU200/fpga_100g/ip/cmac_usplus.tcl index b86d4ea5e..af9cc8265 100644 --- a/fpga/mqnic/AU200/fpga_100g/ip/cmac_usplus.tcl +++ b/fpga/mqnic/AU200/fpga_100g/ip/cmac_usplus.tcl @@ -7,8 +7,10 @@ set_property -dict [list \ CONFIG.USER_INTERFACE {AXIS} \ CONFIG.GT_DRP_CLK {125} \ CONFIG.GT_LOCATION {0} \ - CONFIG.TX_FLOW_CONTROL {0} \ - CONFIG.RX_FLOW_CONTROL {0} \ + CONFIG.TX_FLOW_CONTROL {1} \ + CONFIG.RX_FLOW_CONTROL {1} \ + CONFIG.RX_FORWARD_CONTROL_FRAMES {0} \ + CONFIG.RX_CHECK_ACK {1} \ CONFIG.INCLUDE_RS_FEC {1} \ CONFIG.ENABLE_TIME_STAMPING {1} ] [get_ips cmac_usplus] diff --git a/fpga/mqnic/AU200/fpga_100g/rtl/fpga.v b/fpga/mqnic/AU200/fpga_100g/rtl/fpga.v index ca7336bef..b8cce68b7 100644 --- a/fpga/mqnic/AU200/fpga_100g/rtl/fpga.v +++ b/fpga/mqnic/AU200/fpga_100g/rtl/fpga.v @@ -71,6 +71,8 @@ module fpga # parameter TX_CHECKSUM_ENABLE = 1, parameter RX_HASH_ENABLE = 1, parameter RX_CHECKSUM_ENABLE = 1, + parameter PFC_ENABLE = 1, + parameter LFC_ENABLE = PFC_ENABLE, parameter TX_FIFO_DEPTH = 32768, parameter RX_FIFO_DEPTH = 131072, parameter MAX_TX_SIZE = 9214, @@ -1109,7 +1111,20 @@ wire qsfp0_drp_we; wire [15:0] qsfp0_drp_do; wire qsfp0_drp_rdy; -wire qsfp0_rx_status; +wire qsfp0_tx_enable; +wire qsfp0_tx_lfc_en; +wire qsfp0_tx_lfc_req; +wire [7:0] qsfp0_tx_pfc_en; +wire [7:0] qsfp0_tx_pfc_req; + +wire qsfp0_rx_enable; +wire qsfp0_rx_status; +wire qsfp0_rx_lfc_en; +wire qsfp0_rx_lfc_req; +wire qsfp0_rx_lfc_ack; +wire [7:0] qsfp0_rx_pfc_en; +wire [7:0] qsfp0_rx_pfc_req; +wire [7:0] qsfp0_rx_pfc_ack; wire qsfp0_gtpowergood; @@ -1204,6 +1219,12 @@ qsfp0_cmac_inst ( .tx_ptp_ts_tag(qsfp0_tx_ptp_ts_tag_int), .tx_ptp_ts_valid(qsfp0_tx_ptp_ts_valid_int), + .tx_enable(qsfp0_tx_enable), + .tx_lfc_en(qsfp0_tx_lfc_en), + .tx_lfc_req(qsfp0_tx_lfc_req), + .tx_pfc_en(qsfp0_tx_pfc_en), + .tx_pfc_req(qsfp0_tx_pfc_req), + .rx_clk(qsfp0_rx_clk_int), .rx_rst(qsfp0_rx_rst_int), @@ -1217,7 +1238,14 @@ qsfp0_cmac_inst ( .rx_ptp_rst(qsfp0_rx_ptp_rst_int), .rx_ptp_time(qsfp0_rx_ptp_time_int), - .rx_status(qsfp0_rx_status) + .rx_enable(qsfp0_rx_enable), + .rx_status(qsfp0_rx_status), + .rx_lfc_en(qsfp0_rx_lfc_en), + .rx_lfc_req(qsfp0_rx_lfc_req), + .rx_lfc_ack(qsfp0_rx_lfc_ack), + .rx_pfc_en(qsfp0_rx_pfc_en), + .rx_pfc_req(qsfp0_rx_pfc_req), + .rx_pfc_ack(qsfp0_rx_pfc_ack) ); // QSFP1 CMAC @@ -1261,7 +1289,20 @@ wire qsfp1_drp_we; wire [15:0] qsfp1_drp_do; wire qsfp1_drp_rdy; -wire qsfp1_rx_status; +wire qsfp1_tx_enable; +wire qsfp1_tx_lfc_en; +wire qsfp1_tx_lfc_req; +wire [7:0] qsfp1_tx_pfc_en; +wire [7:0] qsfp1_tx_pfc_req; + +wire qsfp1_rx_enable; +wire qsfp1_rx_status; +wire qsfp1_rx_lfc_en; +wire qsfp1_rx_lfc_req; +wire qsfp1_rx_lfc_ack; +wire [7:0] qsfp1_rx_pfc_en; +wire [7:0] qsfp1_rx_pfc_req; +wire [7:0] qsfp1_rx_pfc_ack; wire qsfp1_gtpowergood; @@ -1354,6 +1395,12 @@ qsfp1_cmac_inst ( .tx_ptp_ts_tag(qsfp1_tx_ptp_ts_tag_int), .tx_ptp_ts_valid(qsfp1_tx_ptp_ts_valid_int), + .tx_enable(qsfp1_tx_enable), + .tx_lfc_en(qsfp1_tx_lfc_en), + .tx_lfc_req(qsfp1_tx_lfc_req), + .tx_pfc_en(qsfp1_tx_pfc_en), + .tx_pfc_req(qsfp1_tx_pfc_req), + .rx_clk(qsfp1_rx_clk_int), .rx_rst(qsfp1_rx_rst_int), @@ -1367,7 +1414,14 @@ qsfp1_cmac_inst ( .rx_ptp_rst(qsfp1_rx_ptp_rst_int), .rx_ptp_time(qsfp1_rx_ptp_time_int), - .rx_status(qsfp1_rx_status) + .rx_enable(qsfp1_rx_enable), + .rx_status(qsfp1_rx_status), + .rx_lfc_en(qsfp1_rx_lfc_en), + .rx_lfc_req(qsfp1_rx_lfc_req), + .rx_lfc_ack(qsfp1_rx_lfc_ack), + .rx_pfc_en(qsfp1_rx_pfc_en), + .rx_pfc_req(qsfp1_rx_pfc_req), + .rx_pfc_ack(qsfp1_rx_pfc_ack) ); wire ptp_clk; @@ -2001,6 +2055,8 @@ fpga_core #( .TX_CHECKSUM_ENABLE(TX_CHECKSUM_ENABLE), .RX_HASH_ENABLE(RX_HASH_ENABLE), .RX_CHECKSUM_ENABLE(RX_CHECKSUM_ENABLE), + .PFC_ENABLE(PFC_ENABLE), + .LFC_ENABLE(LFC_ENABLE), .TX_FIFO_DEPTH(TX_FIFO_DEPTH), .RX_FIFO_DEPTH(RX_FIFO_DEPTH), .MAX_TX_SIZE(MAX_TX_SIZE), @@ -2205,6 +2261,12 @@ core_inst ( .qsfp0_tx_ptp_ts_tag(qsfp0_tx_ptp_ts_tag_int), .qsfp0_tx_ptp_ts_valid(qsfp0_tx_ptp_ts_valid_int), + .qsfp0_tx_enable(qsfp0_tx_enable), + .qsfp0_tx_lfc_en(qsfp0_tx_lfc_en), + .qsfp0_tx_lfc_req(qsfp0_tx_lfc_req), + .qsfp0_tx_pfc_en(qsfp0_tx_pfc_en), + .qsfp0_tx_pfc_req(qsfp0_tx_pfc_req), + .qsfp0_rx_clk(qsfp0_rx_clk_int), .qsfp0_rx_rst(qsfp0_rx_rst_int), .qsfp0_rx_axis_tdata(qsfp0_rx_axis_tdata_int), @@ -2216,7 +2278,14 @@ core_inst ( .qsfp0_rx_ptp_rst(qsfp0_rx_ptp_rst_int), .qsfp0_rx_ptp_time(qsfp0_rx_ptp_time_int), + .qsfp0_rx_enable(qsfp0_rx_enable), .qsfp0_rx_status(qsfp0_rx_status), + .qsfp0_rx_lfc_en(qsfp0_rx_lfc_en), + .qsfp0_rx_lfc_req(qsfp0_rx_lfc_req), + .qsfp0_rx_lfc_ack(qsfp0_rx_lfc_ack), + .qsfp0_rx_pfc_en(qsfp0_rx_pfc_en), + .qsfp0_rx_pfc_req(qsfp0_rx_pfc_req), + .qsfp0_rx_pfc_ack(qsfp0_rx_pfc_ack), .qsfp0_drp_clk(qsfp0_drp_clk), .qsfp0_drp_rst(qsfp0_drp_rst), @@ -2246,6 +2315,12 @@ core_inst ( .qsfp1_tx_ptp_ts_tag(qsfp1_tx_ptp_ts_tag_int), .qsfp1_tx_ptp_ts_valid(qsfp1_tx_ptp_ts_valid_int), + .qsfp1_tx_enable(qsfp1_tx_enable), + .qsfp1_tx_lfc_en(qsfp1_tx_lfc_en), + .qsfp1_tx_lfc_req(qsfp1_tx_lfc_req), + .qsfp1_tx_pfc_en(qsfp1_tx_pfc_en), + .qsfp1_tx_pfc_req(qsfp1_tx_pfc_req), + .qsfp1_rx_clk(qsfp1_rx_clk_int), .qsfp1_rx_rst(qsfp1_rx_rst_int), .qsfp1_rx_axis_tdata(qsfp1_rx_axis_tdata_int), @@ -2257,7 +2332,14 @@ core_inst ( .qsfp1_rx_ptp_rst(qsfp1_rx_ptp_rst_int), .qsfp1_rx_ptp_time(qsfp1_rx_ptp_time_int), + .qsfp1_rx_enable(qsfp1_rx_enable), .qsfp1_rx_status(qsfp1_rx_status), + .qsfp1_rx_lfc_en(qsfp1_rx_lfc_en), + .qsfp1_rx_lfc_req(qsfp1_rx_lfc_req), + .qsfp1_rx_lfc_ack(qsfp1_rx_lfc_ack), + .qsfp1_rx_pfc_en(qsfp1_rx_pfc_en), + .qsfp1_rx_pfc_req(qsfp1_rx_pfc_req), + .qsfp1_rx_pfc_ack(qsfp1_rx_pfc_ack), .qsfp1_drp_clk(qsfp1_drp_clk), .qsfp1_drp_rst(qsfp1_drp_rst), diff --git a/fpga/mqnic/AU200/fpga_100g/rtl/fpga_core.v b/fpga/mqnic/AU200/fpga_100g/rtl/fpga_core.v index 7e5310fb1..96317fd1b 100644 --- a/fpga/mqnic/AU200/fpga_100g/rtl/fpga_core.v +++ b/fpga/mqnic/AU200/fpga_100g/rtl/fpga_core.v @@ -77,6 +77,8 @@ module fpga_core # parameter TX_CHECKSUM_ENABLE = 1, parameter RX_HASH_ENABLE = 1, parameter RX_CHECKSUM_ENABLE = 1, + parameter PFC_ENABLE = 1, + parameter LFC_ENABLE = PFC_ENABLE, parameter TX_FIFO_DEPTH = 32768, parameter RX_FIFO_DEPTH = 131072, parameter MAX_TX_SIZE = 9214, @@ -283,6 +285,12 @@ module fpga_core # input wire [15:0] qsfp0_tx_ptp_ts_tag, input wire qsfp0_tx_ptp_ts_valid, + output wire qsfp0_tx_enable, + output wire qsfp0_tx_lfc_en, + output wire qsfp0_tx_lfc_req, + output wire [7:0] qsfp0_tx_pfc_en, + output wire [7:0] qsfp0_tx_pfc_req, + input wire qsfp0_rx_clk, input wire qsfp0_rx_rst, @@ -296,7 +304,14 @@ module fpga_core # input wire qsfp0_rx_ptp_rst, output wire [79:0] qsfp0_rx_ptp_time, + output wire qsfp0_rx_enable, input wire qsfp0_rx_status, + output wire qsfp0_rx_lfc_en, + input wire qsfp0_rx_lfc_req, + output wire qsfp0_rx_lfc_ack, + output wire [7:0] qsfp0_rx_pfc_en, + input wire [7:0] qsfp0_rx_pfc_req, + output wire [7:0] qsfp0_rx_pfc_ack, input wire qsfp0_drp_clk, input wire qsfp0_drp_rst, @@ -328,6 +343,12 @@ module fpga_core # input wire [15:0] qsfp1_tx_ptp_ts_tag, input wire qsfp1_tx_ptp_ts_valid, + output wire qsfp1_tx_enable, + output wire qsfp1_tx_lfc_en, + output wire qsfp1_tx_lfc_req, + output wire [7:0] qsfp1_tx_pfc_en, + output wire [7:0] qsfp1_tx_pfc_req, + input wire qsfp1_rx_clk, input wire qsfp1_rx_rst, @@ -341,7 +362,14 @@ module fpga_core # input wire qsfp1_rx_ptp_rst, output wire [79:0] qsfp1_rx_ptp_time, + output wire qsfp1_rx_enable, input wire qsfp1_rx_status, + output wire qsfp1_rx_lfc_en, + input wire qsfp1_rx_lfc_req, + output wire qsfp1_rx_lfc_ack, + output wire [7:0] qsfp1_rx_pfc_en, + input wire [7:0] qsfp1_rx_pfc_req, + output wire [7:0] qsfp1_rx_pfc_ack, input wire qsfp1_drp_clk, input wire qsfp1_drp_rst, @@ -837,7 +865,12 @@ wire [PORT_COUNT*TX_TAG_WIDTH-1:0] axis_eth_tx_ptp_ts_tag; wire [PORT_COUNT-1:0] axis_eth_tx_ptp_ts_valid; wire [PORT_COUNT-1:0] axis_eth_tx_ptp_ts_ready; +wire [PORT_COUNT-1:0] eth_tx_enable; wire [PORT_COUNT-1:0] eth_tx_status; +wire [PORT_COUNT-1:0] eth_tx_lfc_en; +wire [PORT_COUNT-1:0] eth_tx_lfc_req; +wire [PORT_COUNT*8-1:0] eth_tx_pfc_en; +wire [PORT_COUNT*8-1:0] eth_tx_pfc_req; wire [PORT_COUNT-1:0] eth_rx_clk; wire [PORT_COUNT-1:0] eth_rx_rst; @@ -854,7 +887,14 @@ wire [PORT_COUNT-1:0] axis_eth_rx_tready; wire [PORT_COUNT-1:0] axis_eth_rx_tlast; wire [PORT_COUNT*AXIS_ETH_RX_USER_WIDTH-1:0] axis_eth_rx_tuser; +wire [PORT_COUNT-1:0] eth_rx_enable; wire [PORT_COUNT-1:0] eth_rx_status; +wire [PORT_COUNT-1:0] eth_rx_lfc_en; +wire [PORT_COUNT-1:0] eth_rx_lfc_req; +wire [PORT_COUNT-1:0] eth_rx_lfc_ack; +wire [PORT_COUNT*8-1:0] eth_rx_pfc_en; +wire [PORT_COUNT*8-1:0] eth_rx_pfc_req; +wire [PORT_COUNT*8-1:0] eth_rx_pfc_ack; wire [PTP_TS_WIDTH-1:0] qsfp0_tx_ptp_time_int; wire [PTP_TS_WIDTH-1:0] qsfp1_tx_ptp_time_int; @@ -905,7 +945,12 @@ mqnic_port_map_mac_axis_inst ( .s_axis_mac_tx_ptp_ts_valid({qsfp1_tx_ptp_ts_valid, qsfp0_tx_ptp_ts_valid}), .s_axis_mac_tx_ptp_ts_ready(), + .mac_tx_enable({qsfp1_tx_enable, qsfp0_tx_enable}), .mac_tx_status(2'b11), + .mac_tx_lfc_en({qsfp1_tx_lfc_en, qsfp0_tx_lfc_en}), + .mac_tx_lfc_req({qsfp1_tx_lfc_req, qsfp0_tx_lfc_req}), + .mac_tx_pfc_en({qsfp1_tx_pfc_en, qsfp0_tx_pfc_en}), + .mac_tx_pfc_req({qsfp1_tx_pfc_req, qsfp0_tx_pfc_req}), .mac_rx_clk({qsfp1_rx_clk, qsfp0_rx_clk}), .mac_rx_rst({qsfp1_rx_rst, qsfp0_rx_rst}), @@ -922,7 +967,14 @@ mqnic_port_map_mac_axis_inst ( .s_axis_mac_rx_tlast({qsfp1_rx_axis_tlast, qsfp0_rx_axis_tlast}), .s_axis_mac_rx_tuser({{qsfp1_rx_axis_tuser[80:1], 16'd0, qsfp1_rx_axis_tuser[0]}, {qsfp0_rx_axis_tuser[80:1], 16'd0, qsfp0_rx_axis_tuser[0]}}), + .mac_rx_enable({qsfp1_rx_enable, qsfp0_rx_enable}), .mac_rx_status({qsfp1_rx_status, qsfp0_rx_status}), + .mac_rx_lfc_en({qsfp1_rx_lfc_en, qsfp0_rx_lfc_en}), + .mac_rx_lfc_req({qsfp1_rx_lfc_req, qsfp0_rx_lfc_req}), + .mac_rx_lfc_ack({qsfp1_rx_lfc_ack, qsfp0_rx_lfc_ack}), + .mac_rx_pfc_en({qsfp1_rx_pfc_en, qsfp0_rx_pfc_en}), + .mac_rx_pfc_req({qsfp1_rx_pfc_req, qsfp0_rx_pfc_req}), + .mac_rx_pfc_ack({qsfp1_rx_pfc_ack, qsfp0_rx_pfc_ack}), // towards datapath .tx_clk(eth_tx_clk), @@ -945,7 +997,12 @@ mqnic_port_map_mac_axis_inst ( .m_axis_tx_ptp_ts_valid(axis_eth_tx_ptp_ts_valid), .m_axis_tx_ptp_ts_ready(axis_eth_tx_ptp_ts_ready), + .tx_enable(eth_tx_enable), .tx_status(eth_tx_status), + .tx_lfc_en(eth_tx_lfc_en), + .tx_lfc_req(eth_tx_lfc_req), + .tx_pfc_en(eth_tx_pfc_en), + .tx_pfc_req(eth_tx_pfc_req), .rx_clk(eth_rx_clk), .rx_rst(eth_rx_rst), @@ -962,7 +1019,14 @@ mqnic_port_map_mac_axis_inst ( .m_axis_rx_tlast(axis_eth_rx_tlast), .m_axis_rx_tuser(axis_eth_rx_tuser), - .rx_status(eth_rx_status) + .rx_enable(eth_rx_enable), + .rx_status(eth_rx_status), + .rx_lfc_en(eth_rx_lfc_en), + .rx_lfc_req(eth_rx_lfc_req), + .rx_lfc_ack(eth_rx_lfc_ack), + .rx_pfc_en(eth_rx_pfc_en), + .rx_pfc_req(eth_rx_pfc_req), + .rx_pfc_ack(eth_rx_pfc_ack) ); mqnic_core_pcie_us #( @@ -1032,6 +1096,9 @@ mqnic_core_pcie_us #( .TX_CHECKSUM_ENABLE(TX_CHECKSUM_ENABLE), .RX_HASH_ENABLE(RX_HASH_ENABLE), .RX_CHECKSUM_ENABLE(RX_CHECKSUM_ENABLE), + .PFC_ENABLE(PFC_ENABLE), + .LFC_ENABLE(LFC_ENABLE), + .MAC_CTRL_ENABLE(0), .TX_FIFO_DEPTH(TX_FIFO_DEPTH), .RX_FIFO_DEPTH(RX_FIFO_DEPTH), .MAX_TX_SIZE(MAX_TX_SIZE), @@ -1313,7 +1380,13 @@ core_inst ( .s_axis_eth_tx_cpl_valid(axis_eth_tx_ptp_ts_valid), .s_axis_eth_tx_cpl_ready(axis_eth_tx_ptp_ts_ready), + .eth_tx_enable(eth_tx_enable), .eth_tx_status(eth_tx_status), + .eth_tx_lfc_en(eth_tx_lfc_en), + .eth_tx_lfc_req(eth_tx_lfc_req), + .eth_tx_pfc_en(eth_tx_pfc_en), + .eth_tx_pfc_req(eth_tx_pfc_req), + .eth_tx_fc_quanta_clk_en(0), .eth_rx_clk(eth_rx_clk), .eth_rx_rst(eth_rx_rst), @@ -1330,7 +1403,15 @@ core_inst ( .s_axis_eth_rx_tlast(axis_eth_rx_tlast), .s_axis_eth_rx_tuser(axis_eth_rx_tuser), + .eth_rx_enable(eth_rx_enable), .eth_rx_status(eth_rx_status), + .eth_rx_lfc_en(eth_rx_lfc_en), + .eth_rx_lfc_req(eth_rx_lfc_req), + .eth_rx_lfc_ack(eth_rx_lfc_ack), + .eth_rx_pfc_en(eth_rx_pfc_en), + .eth_rx_pfc_req(eth_rx_pfc_req), + .eth_rx_pfc_ack(eth_rx_pfc_ack), + .eth_rx_fc_quanta_clk_en(0), /* * DDR diff --git a/fpga/mqnic/AU200/fpga_100g/tb/fpga_core/Makefile b/fpga/mqnic/AU200/fpga_100g/tb/fpga_core/Makefile index 67d20a951..e8de2d7d3 100644 --- a/fpga/mqnic/AU200/fpga_100g/tb/fpga_core/Makefile +++ b/fpga/mqnic/AU200/fpga_100g/tb/fpga_core/Makefile @@ -161,6 +161,8 @@ export PARAM_TX_CPL_FIFO_DEPTH := 32 export PARAM_TX_CHECKSUM_ENABLE := 1 export PARAM_RX_HASH_ENABLE := 1 export PARAM_RX_CHECKSUM_ENABLE := 1 +export PARAM_LFC_ENABLE := 1 +export PARAM_PFC_ENABLE := $(PARAM_LFC_ENABLE) export PARAM_TX_FIFO_DEPTH := 32768 export PARAM_RX_FIFO_DEPTH := 131072 export PARAM_MAX_TX_SIZE := 9214 diff --git a/fpga/mqnic/AU200/fpga_100g/tb/fpga_core/test_fpga_core.py b/fpga/mqnic/AU200/fpga_100g/tb/fpga_core/test_fpga_core.py index 1160702cc..c43b5c299 100644 --- a/fpga/mqnic/AU200/fpga_100g/tb/fpga_core/test_fpga_core.py +++ b/fpga/mqnic/AU200/fpga_100g/tb/fpga_core/test_fpga_core.py @@ -300,6 +300,8 @@ class TB(object): self.qsfp_mac.append(mac) getattr(dut, f"qsfp{k}_rx_status").setimmediatevalue(1) + getattr(dut, f"qsfp{k}_rx_lfc_req").setimmediatevalue(0) + getattr(dut, f"qsfp{k}_rx_pfc_req").setimmediatevalue(0) cocotb.start_soon(Clock(getattr(dut, f"qsfp{k}_drp_clk"), 8, units="ns").start()) getattr(dut, f"qsfp{k}_drp_rst").setimmediatevalue(0) @@ -307,7 +309,7 @@ class TB(object): getattr(dut, f"qsfp{k}_drp_rdy").setimmediatevalue(0) getattr(dut, f"qsfp{k}_modprsl").setimmediatevalue(0) - getattr(dut, f"qsfp{k}_intl").setimmediatevalue(0) + getattr(dut, f"qsfp{k}_intl").setimmediatevalue(1) dut.sw.setimmediatevalue(0) @@ -723,6 +725,8 @@ def test_fpga_core(request): parameters['TX_CHECKSUM_ENABLE'] = 1 parameters['RX_HASH_ENABLE'] = 1 parameters['RX_CHECKSUM_ENABLE'] = 1 + parameters['LFC_ENABLE'] = 1 + parameters['PFC_ENABLE'] = parameters['LFC_ENABLE'] parameters['TX_FIFO_DEPTH'] = 32768 parameters['RX_FIFO_DEPTH'] = 131072 parameters['MAX_TX_SIZE'] = 9214 diff --git a/fpga/mqnic/AU200/fpga_25g/fpga/Makefile b/fpga/mqnic/AU200/fpga_25g/fpga/Makefile index 5821fa711..363f3d8a6 100644 --- a/fpga/mqnic/AU200/fpga_25g/fpga/Makefile +++ b/fpga/mqnic/AU200/fpga_25g/fpga/Makefile @@ -62,6 +62,10 @@ SYN_FILES += rtl/common/tdma_ber_ch.v SYN_FILES += lib/eth/rtl/eth_mac_10g.v SYN_FILES += lib/eth/rtl/axis_xgmii_rx_64.v SYN_FILES += lib/eth/rtl/axis_xgmii_tx_64.v +SYN_FILES += lib/eth/rtl/mac_ctrl_rx.v +SYN_FILES += lib/eth/rtl/mac_ctrl_tx.v +SYN_FILES += lib/eth/rtl/mac_pause_ctrl_rx.v +SYN_FILES += lib/eth/rtl/mac_pause_ctrl_tx.v SYN_FILES += lib/eth/rtl/eth_phy_10g.v SYN_FILES += lib/eth/rtl/eth_phy_10g_rx.v SYN_FILES += lib/eth/rtl/eth_phy_10g_rx_if.v diff --git a/fpga/mqnic/AU200/fpga_25g/fpga/config.tcl b/fpga/mqnic/AU200/fpga_25g/fpga/config.tcl index e8a6e4004..d01d29915 100644 --- a/fpga/mqnic/AU200/fpga_25g/fpga/config.tcl +++ b/fpga/mqnic/AU200/fpga_25g/fpga/config.tcl @@ -113,6 +113,8 @@ dict set params TX_CPL_FIFO_DEPTH "32" dict set params TX_CHECKSUM_ENABLE "1" dict set params RX_HASH_ENABLE "1" dict set params RX_CHECKSUM_ENABLE "1" +dict set params PFC_ENABLE "1" +dict set params LFC_ENABLE [dict get $params PFC_ENABLE] dict set params ENABLE_PADDING "1" dict set params ENABLE_DIC "1" dict set params MIN_FRAME_LENGTH "64" diff --git a/fpga/mqnic/AU200/fpga_25g/fpga_10g/Makefile b/fpga/mqnic/AU200/fpga_25g/fpga_10g/Makefile index 5821fa711..363f3d8a6 100644 --- a/fpga/mqnic/AU200/fpga_25g/fpga_10g/Makefile +++ b/fpga/mqnic/AU200/fpga_25g/fpga_10g/Makefile @@ -62,6 +62,10 @@ SYN_FILES += rtl/common/tdma_ber_ch.v SYN_FILES += lib/eth/rtl/eth_mac_10g.v SYN_FILES += lib/eth/rtl/axis_xgmii_rx_64.v SYN_FILES += lib/eth/rtl/axis_xgmii_tx_64.v +SYN_FILES += lib/eth/rtl/mac_ctrl_rx.v +SYN_FILES += lib/eth/rtl/mac_ctrl_tx.v +SYN_FILES += lib/eth/rtl/mac_pause_ctrl_rx.v +SYN_FILES += lib/eth/rtl/mac_pause_ctrl_tx.v SYN_FILES += lib/eth/rtl/eth_phy_10g.v SYN_FILES += lib/eth/rtl/eth_phy_10g_rx.v SYN_FILES += lib/eth/rtl/eth_phy_10g_rx_if.v diff --git a/fpga/mqnic/AU200/fpga_25g/fpga_10g/config.tcl b/fpga/mqnic/AU200/fpga_25g/fpga_10g/config.tcl index 50e894601..7c879953b 100644 --- a/fpga/mqnic/AU200/fpga_25g/fpga_10g/config.tcl +++ b/fpga/mqnic/AU200/fpga_25g/fpga_10g/config.tcl @@ -113,6 +113,8 @@ dict set params TX_CPL_FIFO_DEPTH "32" dict set params TX_CHECKSUM_ENABLE "1" dict set params RX_HASH_ENABLE "1" dict set params RX_CHECKSUM_ENABLE "1" +dict set params PFC_ENABLE "1" +dict set params LFC_ENABLE [dict get $params PFC_ENABLE] dict set params ENABLE_PADDING "1" dict set params ENABLE_DIC "1" dict set params MIN_FRAME_LENGTH "64" diff --git a/fpga/mqnic/AU200/fpga_25g/rtl/fpga.v b/fpga/mqnic/AU200/fpga_25g/rtl/fpga.v index 95b0715de..7437e3147 100644 --- a/fpga/mqnic/AU200/fpga_25g/rtl/fpga.v +++ b/fpga/mqnic/AU200/fpga_25g/rtl/fpga.v @@ -74,6 +74,8 @@ module fpga # parameter TX_CHECKSUM_ENABLE = 1, parameter RX_HASH_ENABLE = 1, parameter RX_CHECKSUM_ENABLE = 1, + parameter PFC_ENABLE = 1, + parameter LFC_ENABLE = PFC_ENABLE, parameter ENABLE_PADDING = 1, parameter ENABLE_DIC = 1, parameter MIN_FRAME_LENGTH = 64, @@ -2137,6 +2139,8 @@ fpga_core #( .TX_CHECKSUM_ENABLE(TX_CHECKSUM_ENABLE), .RX_HASH_ENABLE(RX_HASH_ENABLE), .RX_CHECKSUM_ENABLE(RX_CHECKSUM_ENABLE), + .PFC_ENABLE(PFC_ENABLE), + .LFC_ENABLE(LFC_ENABLE), .ENABLE_PADDING(ENABLE_PADDING), .ENABLE_DIC(ENABLE_DIC), .MIN_FRAME_LENGTH(MIN_FRAME_LENGTH), diff --git a/fpga/mqnic/AU200/fpga_25g/rtl/fpga_core.v b/fpga/mqnic/AU200/fpga_25g/rtl/fpga_core.v index a3de4e63a..3e9c5021c 100644 --- a/fpga/mqnic/AU200/fpga_25g/rtl/fpga_core.v +++ b/fpga/mqnic/AU200/fpga_25g/rtl/fpga_core.v @@ -81,6 +81,8 @@ module fpga_core # parameter TX_CHECKSUM_ENABLE = 1, parameter RX_HASH_ENABLE = 1, parameter RX_CHECKSUM_ENABLE = 1, + parameter PFC_ENABLE = 1, + parameter LFC_ENABLE = PFC_ENABLE, parameter ENABLE_PADDING = 1, parameter ENABLE_DIC = 1, parameter MIN_FRAME_LENGTH = 64, @@ -979,7 +981,12 @@ wire [PORT_COUNT*TX_TAG_WIDTH-1:0] axis_eth_tx_ptp_ts_tag; wire [PORT_COUNT-1:0] axis_eth_tx_ptp_ts_valid; wire [PORT_COUNT-1:0] axis_eth_tx_ptp_ts_ready; +wire [PORT_COUNT-1:0] eth_tx_enable; wire [PORT_COUNT-1:0] eth_tx_status; +wire [PORT_COUNT-1:0] eth_tx_lfc_en; +wire [PORT_COUNT-1:0] eth_tx_lfc_req; +wire [PORT_COUNT*8-1:0] eth_tx_pfc_en; +wire [PORT_COUNT*8-1:0] eth_tx_pfc_req; wire [PORT_COUNT-1:0] eth_rx_clk; wire [PORT_COUNT-1:0] eth_rx_rst; @@ -994,7 +1001,14 @@ wire [PORT_COUNT-1:0] axis_eth_rx_tready; wire [PORT_COUNT-1:0] axis_eth_rx_tlast; wire [PORT_COUNT*AXIS_ETH_RX_USER_WIDTH-1:0] axis_eth_rx_tuser; +wire [PORT_COUNT-1:0] eth_rx_enable; wire [PORT_COUNT-1:0] eth_rx_status; +wire [PORT_COUNT-1:0] eth_rx_lfc_en; +wire [PORT_COUNT-1:0] eth_rx_lfc_req; +wire [PORT_COUNT-1:0] eth_rx_lfc_ack; +wire [PORT_COUNT*8-1:0] eth_rx_pfc_en; +wire [PORT_COUNT*8-1:0] eth_rx_pfc_req; +wire [PORT_COUNT*8-1:0] eth_rx_pfc_ack; wire [PORT_COUNT-1:0] port_xgmii_tx_clk; wire [PORT_COUNT-1:0] port_xgmii_tx_rst; @@ -1067,12 +1081,15 @@ generate .PTP_PERIOD_FNS(IF_PTP_PERIOD_FNS), .TX_PTP_TS_ENABLE(PTP_TS_ENABLE), .TX_PTP_TS_WIDTH(PTP_TS_WIDTH), + .TX_PTP_TS_CTRL_IN_TUSER(0), .TX_PTP_TAG_ENABLE(PTP_TS_ENABLE), .TX_PTP_TAG_WIDTH(TX_TAG_WIDTH), .RX_PTP_TS_ENABLE(PTP_TS_ENABLE), .RX_PTP_TS_WIDTH(PTP_TS_WIDTH), .TX_USER_WIDTH(AXIS_ETH_TX_USER_WIDTH), - .RX_USER_WIDTH(AXIS_ETH_RX_USER_WIDTH) + .RX_USER_WIDTH(AXIS_ETH_RX_USER_WIDTH), + .PFC_ENABLE(PFC_ENABLE), + .PAUSE_ENABLE(LFC_ENABLE) ) eth_mac_inst ( .tx_clk(port_xgmii_tx_clk[n]), @@ -1080,6 +1097,9 @@ generate .rx_clk(port_xgmii_rx_clk[n]), .rx_rst(port_xgmii_rx_rst[n]), + /* + * AXI input + */ .tx_axis_tdata(axis_eth_tx_tdata[n*AXIS_ETH_DATA_WIDTH +: AXIS_ETH_DATA_WIDTH]), .tx_axis_tkeep(axis_eth_tx_tkeep[n*AXIS_ETH_KEEP_WIDTH +: AXIS_ETH_KEEP_WIDTH]), .tx_axis_tvalid(axis_eth_tx_tvalid[n +: 1]), @@ -1087,30 +1107,121 @@ generate .tx_axis_tlast(axis_eth_tx_tlast[n +: 1]), .tx_axis_tuser(axis_eth_tx_tuser[n*AXIS_ETH_TX_USER_WIDTH +: AXIS_ETH_TX_USER_WIDTH]), + /* + * AXI output + */ .rx_axis_tdata(axis_eth_rx_tdata[n*AXIS_ETH_DATA_WIDTH +: AXIS_ETH_DATA_WIDTH]), .rx_axis_tkeep(axis_eth_rx_tkeep[n*AXIS_ETH_KEEP_WIDTH +: AXIS_ETH_KEEP_WIDTH]), .rx_axis_tvalid(axis_eth_rx_tvalid[n +: 1]), .rx_axis_tlast(axis_eth_rx_tlast[n +: 1]), .rx_axis_tuser(axis_eth_rx_tuser[n*AXIS_ETH_RX_USER_WIDTH +: AXIS_ETH_RX_USER_WIDTH]), + /* + * XGMII interface + */ .xgmii_rxd(port_xgmii_rxd[n*XGMII_DATA_WIDTH +: XGMII_DATA_WIDTH]), .xgmii_rxc(port_xgmii_rxc[n*XGMII_CTRL_WIDTH +: XGMII_CTRL_WIDTH]), .xgmii_txd(port_xgmii_txd[n*XGMII_DATA_WIDTH +: XGMII_DATA_WIDTH]), .xgmii_txc(port_xgmii_txc[n*XGMII_CTRL_WIDTH +: XGMII_CTRL_WIDTH]), + /* + * PTP + */ .tx_ptp_ts(eth_tx_ptp_ts_96[n*PTP_TS_WIDTH +: PTP_TS_WIDTH]), .rx_ptp_ts(eth_rx_ptp_ts_96[n*PTP_TS_WIDTH +: PTP_TS_WIDTH]), .tx_axis_ptp_ts(axis_eth_tx_ptp_ts[n*PTP_TS_WIDTH +: PTP_TS_WIDTH]), .tx_axis_ptp_ts_tag(axis_eth_tx_ptp_ts_tag[n*TX_TAG_WIDTH +: TX_TAG_WIDTH]), .tx_axis_ptp_ts_valid(axis_eth_tx_ptp_ts_valid[n +: 1]), + /* + * Link-level Flow Control (LFC) (IEEE 802.3 annex 31B PAUSE) + */ + .tx_lfc_req(eth_tx_lfc_req[n +: 1]), + .tx_lfc_resend(1'b0), + .rx_lfc_en(eth_rx_lfc_en[n +: 1]), + .rx_lfc_req(eth_rx_lfc_req[n +: 1]), + .rx_lfc_ack(eth_rx_lfc_ack[n +: 1]), + + /* + * Priority Flow Control (PFC) (IEEE 802.3 annex 31D PFC) + */ + .tx_pfc_req(eth_tx_pfc_req[n*8 +: 8]), + .tx_pfc_resend(1'b0), + .rx_pfc_en(eth_rx_pfc_en[n*8 +: 8]), + .rx_pfc_req(eth_rx_pfc_req[n*8 +: 8]), + .rx_pfc_ack(eth_rx_pfc_ack[n*8 +: 8]), + + /* + * Pause interface + */ + .tx_lfc_pause_en(1'b1), + .tx_pause_req(1'b0), + .tx_pause_ack(), + + /* + * Status + */ + .tx_start_packet(), .tx_error_underflow(), + .rx_start_packet(), .rx_error_bad_frame(), .rx_error_bad_fcs(), + .stat_tx_mcf(), + .stat_rx_mcf(), + .stat_tx_lfc_pkt(), + .stat_tx_lfc_xon(), + .stat_tx_lfc_xoff(), + .stat_tx_lfc_paused(), + .stat_tx_pfc_pkt(), + .stat_tx_pfc_xon(), + .stat_tx_pfc_xoff(), + .stat_tx_pfc_paused(), + .stat_rx_lfc_pkt(), + .stat_rx_lfc_xon(), + .stat_rx_lfc_xoff(), + .stat_rx_lfc_paused(), + .stat_rx_pfc_pkt(), + .stat_rx_pfc_xon(), + .stat_rx_pfc_xoff(), + .stat_rx_pfc_paused(), + /* + * Configuration + */ .cfg_ifg(8'd12), - .cfg_tx_enable(1'b1), - .cfg_rx_enable(1'b1) + .cfg_tx_enable(eth_tx_enable[n +: 1]), + .cfg_rx_enable(eth_rx_enable[n +: 1]), + .cfg_mcf_rx_eth_dst_mcast(48'h01_80_C2_00_00_01), + .cfg_mcf_rx_check_eth_dst_mcast(1'b1), + .cfg_mcf_rx_eth_dst_ucast(48'd0), + .cfg_mcf_rx_check_eth_dst_ucast(1'b0), + .cfg_mcf_rx_eth_src(48'd0), + .cfg_mcf_rx_check_eth_src(1'b0), + .cfg_mcf_rx_eth_type(16'h8808), + .cfg_mcf_rx_opcode_lfc(16'h0001), + .cfg_mcf_rx_check_opcode_lfc(eth_rx_lfc_en[n +: 1]), + .cfg_mcf_rx_opcode_pfc(16'h0101), + .cfg_mcf_rx_check_opcode_pfc(eth_rx_pfc_en[n*8 +: 8] != 0), + .cfg_mcf_rx_forward(1'b0), + .cfg_mcf_rx_enable(eth_rx_lfc_en[n +: 1] || eth_rx_pfc_en[n*8 +: 8]), + .cfg_tx_lfc_eth_dst(48'h01_80_C2_00_00_01), + .cfg_tx_lfc_eth_src(48'h80_23_31_43_54_4C), + .cfg_tx_lfc_eth_type(16'h8808), + .cfg_tx_lfc_opcode(16'h0001), + .cfg_tx_lfc_en(eth_tx_lfc_en[n +: 1]), + .cfg_tx_lfc_quanta(16'hffff), + .cfg_tx_lfc_refresh(16'h7fff), + .cfg_tx_pfc_eth_dst(48'h01_80_C2_00_00_01), + .cfg_tx_pfc_eth_src(48'h80_23_31_43_54_4C), + .cfg_tx_pfc_eth_type(16'h8808), + .cfg_tx_pfc_opcode(16'h0101), + .cfg_tx_pfc_en(eth_tx_pfc_en[n*8 +: 8] != 0), + .cfg_tx_pfc_quanta({8{16'hffff}}), + .cfg_tx_pfc_refresh({8{16'h7fff}}), + .cfg_rx_lfc_opcode(16'h0001), + .cfg_rx_lfc_en(eth_rx_lfc_en[n +: 1]), + .cfg_rx_pfc_opcode(16'h0101), + .cfg_rx_pfc_en(eth_rx_pfc_en[n*8 +: 8] != 0) ); end @@ -1184,6 +1295,9 @@ mqnic_core_pcie_us #( .TX_CHECKSUM_ENABLE(TX_CHECKSUM_ENABLE), .RX_HASH_ENABLE(RX_HASH_ENABLE), .RX_CHECKSUM_ENABLE(RX_CHECKSUM_ENABLE), + .PFC_ENABLE(PFC_ENABLE), + .LFC_ENABLE(LFC_ENABLE), + .MAC_CTRL_ENABLE(0), .TX_FIFO_DEPTH(TX_FIFO_DEPTH), .RX_FIFO_DEPTH(RX_FIFO_DEPTH), .MAX_TX_SIZE(MAX_TX_SIZE), @@ -1465,7 +1579,13 @@ core_inst ( .s_axis_eth_tx_cpl_valid(axis_eth_tx_ptp_ts_valid), .s_axis_eth_tx_cpl_ready(axis_eth_tx_ptp_ts_ready), + .eth_tx_enable(eth_tx_enable), .eth_tx_status(eth_tx_status), + .eth_tx_lfc_en(eth_tx_lfc_en), + .eth_tx_lfc_req(eth_tx_lfc_req), + .eth_tx_pfc_en(eth_tx_pfc_en), + .eth_tx_pfc_req(eth_tx_pfc_req), + .eth_tx_fc_quanta_clk_en(0), .eth_rx_clk(eth_rx_clk), .eth_rx_rst(eth_rx_rst), @@ -1482,7 +1602,15 @@ core_inst ( .s_axis_eth_rx_tlast(axis_eth_rx_tlast), .s_axis_eth_rx_tuser(axis_eth_rx_tuser), + .eth_rx_enable(eth_rx_enable), .eth_rx_status(eth_rx_status), + .eth_rx_lfc_en(eth_rx_lfc_en), + .eth_rx_lfc_req(eth_rx_lfc_req), + .eth_rx_lfc_ack(eth_rx_lfc_ack), + .eth_rx_pfc_en(eth_rx_pfc_en), + .eth_rx_pfc_req(eth_rx_pfc_req), + .eth_rx_pfc_ack(eth_rx_pfc_ack), + .eth_rx_fc_quanta_clk_en(0), /* * DDR diff --git a/fpga/mqnic/AU200/fpga_25g/tb/fpga_core/Makefile b/fpga/mqnic/AU200/fpga_25g/tb/fpga_core/Makefile index d9702a197..78a21e1ad 100644 --- a/fpga/mqnic/AU200/fpga_25g/tb/fpga_core/Makefile +++ b/fpga/mqnic/AU200/fpga_25g/tb/fpga_core/Makefile @@ -62,6 +62,10 @@ VERILOG_SOURCES += ../../rtl/common/tdma_ber_ch.v VERILOG_SOURCES += ../../lib/eth/rtl/eth_mac_10g.v VERILOG_SOURCES += ../../lib/eth/rtl/axis_xgmii_rx_64.v VERILOG_SOURCES += ../../lib/eth/rtl/axis_xgmii_tx_64.v +VERILOG_SOURCES += ../../lib/eth/rtl/mac_ctrl_rx.v +VERILOG_SOURCES += ../../lib/eth/rtl/mac_ctrl_tx.v +VERILOG_SOURCES += ../../lib/eth/rtl/mac_pause_ctrl_rx.v +VERILOG_SOURCES += ../../lib/eth/rtl/mac_pause_ctrl_tx.v VERILOG_SOURCES += ../../lib/eth/rtl/lfsr.v VERILOG_SOURCES += ../../lib/eth/rtl/ptp_clock.v VERILOG_SOURCES += ../../lib/eth/rtl/ptp_clock_cdc.v @@ -167,6 +171,8 @@ export PARAM_TX_CPL_FIFO_DEPTH := 32 export PARAM_TX_CHECKSUM_ENABLE := 1 export PARAM_RX_HASH_ENABLE := 1 export PARAM_RX_CHECKSUM_ENABLE := 1 +export PARAM_LFC_ENABLE := 1 +export PARAM_PFC_ENABLE := $(PARAM_LFC_ENABLE) export PARAM_TX_FIFO_DEPTH := 32768 export PARAM_RX_FIFO_DEPTH := 32768 export PARAM_MAX_TX_SIZE := 9214 diff --git a/fpga/mqnic/AU200/fpga_25g/tb/fpga_core/test_fpga_core.py b/fpga/mqnic/AU200/fpga_25g/tb/fpga_core/test_fpga_core.py index 58137deb2..ccdbd64c8 100644 --- a/fpga/mqnic/AU200/fpga_25g/tb/fpga_core/test_fpga_core.py +++ b/fpga/mqnic/AU200/fpga_25g/tb/fpga_core/test_fpga_core.py @@ -3,6 +3,7 @@ import logging import os +import struct import sys import scapy.utils @@ -17,7 +18,7 @@ from cocotb.clock import Clock from cocotb.triggers import RisingEdge, FallingEdge, Timer from cocotbext.axi import AxiStreamBus, AxiLiteBus, AxiLiteRam -from cocotbext.eth import XgmiiSource, XgmiiSink +from cocotbext.eth import XgmiiSource, XgmiiSink, XgmiiFrame from cocotbext.pcie.core import RootComplex from cocotbext.pcie.xilinx.us import UltraScalePlusPcieDevice @@ -528,6 +529,35 @@ async def run_test_nic(dut): tb.loopback_enable = False + if tb.driver.interfaces[0].if_feature_lfc: + tb.log.info("Test LFC pause frame RX") + + await tb.driver.interfaces[0].ports[0].set_lfc_ctrl(mqnic.MQNIC_PORT_LFC_CTRL_TX_LFC_EN | mqnic.MQNIC_PORT_LFC_CTRL_RX_LFC_EN) + await tb.driver.hw_regs.read_dword(0) + + lfc_xoff = Ether(src='DA:D1:D2:D3:D4:D5', dst='01:80:C2:00:00:01', type=0x8808) / struct.pack('!HH', 0x0001, 2000) + + await tb.qsfp_source[0][0].send(XgmiiFrame.from_payload(bytes(lfc_xoff))) + + count = 16 + + pkts = [bytearray([(x+k) % 256 for x in range(1514)]) for k in range(count)] + + tb.loopback_enable = True + + for p in pkts: + await tb.driver.interfaces[0].start_xmit(p, 0) + + for k in range(count): + pkt = await tb.driver.interfaces[0].recv() + + tb.log.info("Packet: %s", pkt) + assert pkt.data == pkts[k] + if tb.driver.interfaces[0].if_feature_rx_csum: + assert pkt.rx_checksum == ~scapy.utils.checksum(bytes(pkt.data[14:])) & 0xffff + + tb.loopback_enable = False + await RisingEdge(dut.clk_250mhz) await RisingEdge(dut.clk_250mhz) @@ -600,6 +630,10 @@ def test_fpga_core(request): os.path.join(eth_rtl_dir, "eth_mac_10g.v"), os.path.join(eth_rtl_dir, "axis_xgmii_rx_64.v"), os.path.join(eth_rtl_dir, "axis_xgmii_tx_64.v"), + os.path.join(eth_rtl_dir, "mac_ctrl_rx.v"), + os.path.join(eth_rtl_dir, "mac_ctrl_tx.v"), + os.path.join(eth_rtl_dir, "mac_pause_ctrl_rx.v"), + os.path.join(eth_rtl_dir, "mac_pause_ctrl_tx.v"), os.path.join(eth_rtl_dir, "lfsr.v"), os.path.join(eth_rtl_dir, "ptp_clock.v"), os.path.join(eth_rtl_dir, "ptp_clock_cdc.v"), @@ -706,6 +740,8 @@ def test_fpga_core(request): parameters['TX_CHECKSUM_ENABLE'] = 1 parameters['RX_HASH_ENABLE'] = 1 parameters['RX_CHECKSUM_ENABLE'] = 1 + parameters['LFC_ENABLE'] = 1 + parameters['PFC_ENABLE'] = parameters['LFC_ENABLE'] parameters['TX_FIFO_DEPTH'] = 32768 parameters['RX_FIFO_DEPTH'] = 32768 parameters['MAX_TX_SIZE'] = 9214 diff --git a/fpga/mqnic/AU250/fpga_100g/fpga/config.tcl b/fpga/mqnic/AU250/fpga_100g/fpga/config.tcl index d27253dea..4dbd0886e 100644 --- a/fpga/mqnic/AU250/fpga_100g/fpga/config.tcl +++ b/fpga/mqnic/AU250/fpga_100g/fpga/config.tcl @@ -101,6 +101,8 @@ dict set params TX_CPL_FIFO_DEPTH "32" dict set params TX_CHECKSUM_ENABLE "1" dict set params RX_HASH_ENABLE "1" dict set params RX_CHECKSUM_ENABLE "1" +dict set params PFC_ENABLE "1" +dict set params LFC_ENABLE [dict get $params PFC_ENABLE] dict set params TX_FIFO_DEPTH "32768" dict set params RX_FIFO_DEPTH "131072" dict set params MAX_TX_SIZE "9214" diff --git a/fpga/mqnic/AU250/fpga_100g/fpga_app_dma_bench/config.tcl b/fpga/mqnic/AU250/fpga_100g/fpga_app_dma_bench/config.tcl index 11e3a02ed..abfea2b14 100644 --- a/fpga/mqnic/AU250/fpga_100g/fpga_app_dma_bench/config.tcl +++ b/fpga/mqnic/AU250/fpga_100g/fpga_app_dma_bench/config.tcl @@ -101,6 +101,8 @@ dict set params TX_CPL_FIFO_DEPTH "32" dict set params TX_CHECKSUM_ENABLE "1" dict set params RX_HASH_ENABLE "1" dict set params RX_CHECKSUM_ENABLE "1" +dict set params PFC_ENABLE "1" +dict set params LFC_ENABLE [dict get $params PFC_ENABLE] dict set params TX_FIFO_DEPTH "32768" dict set params RX_FIFO_DEPTH "131072" dict set params MAX_TX_SIZE "9214" diff --git a/fpga/mqnic/AU250/fpga_100g/ip/cmac_usplus.tcl b/fpga/mqnic/AU250/fpga_100g/ip/cmac_usplus.tcl index b86d4ea5e..af9cc8265 100644 --- a/fpga/mqnic/AU250/fpga_100g/ip/cmac_usplus.tcl +++ b/fpga/mqnic/AU250/fpga_100g/ip/cmac_usplus.tcl @@ -7,8 +7,10 @@ set_property -dict [list \ CONFIG.USER_INTERFACE {AXIS} \ CONFIG.GT_DRP_CLK {125} \ CONFIG.GT_LOCATION {0} \ - CONFIG.TX_FLOW_CONTROL {0} \ - CONFIG.RX_FLOW_CONTROL {0} \ + CONFIG.TX_FLOW_CONTROL {1} \ + CONFIG.RX_FLOW_CONTROL {1} \ + CONFIG.RX_FORWARD_CONTROL_FRAMES {0} \ + CONFIG.RX_CHECK_ACK {1} \ CONFIG.INCLUDE_RS_FEC {1} \ CONFIG.ENABLE_TIME_STAMPING {1} ] [get_ips cmac_usplus] diff --git a/fpga/mqnic/AU250/fpga_100g/rtl/fpga.v b/fpga/mqnic/AU250/fpga_100g/rtl/fpga.v index d11e66d63..c1b6d8a0f 100644 --- a/fpga/mqnic/AU250/fpga_100g/rtl/fpga.v +++ b/fpga/mqnic/AU250/fpga_100g/rtl/fpga.v @@ -71,6 +71,8 @@ module fpga # parameter TX_CHECKSUM_ENABLE = 1, parameter RX_HASH_ENABLE = 1, parameter RX_CHECKSUM_ENABLE = 1, + parameter PFC_ENABLE = 1, + parameter LFC_ENABLE = PFC_ENABLE, parameter TX_FIFO_DEPTH = 32768, parameter RX_FIFO_DEPTH = 131072, parameter MAX_TX_SIZE = 9214, @@ -1109,7 +1111,20 @@ wire qsfp0_drp_we; wire [15:0] qsfp0_drp_do; wire qsfp0_drp_rdy; -wire qsfp0_rx_status; +wire qsfp0_tx_enable; +wire qsfp0_tx_lfc_en; +wire qsfp0_tx_lfc_req; +wire [7:0] qsfp0_tx_pfc_en; +wire [7:0] qsfp0_tx_pfc_req; + +wire qsfp0_rx_enable; +wire qsfp0_rx_status; +wire qsfp0_rx_lfc_en; +wire qsfp0_rx_lfc_req; +wire qsfp0_rx_lfc_ack; +wire [7:0] qsfp0_rx_pfc_en; +wire [7:0] qsfp0_rx_pfc_req; +wire [7:0] qsfp0_rx_pfc_ack; wire qsfp0_gtpowergood; @@ -1204,6 +1219,12 @@ qsfp0_cmac_inst ( .tx_ptp_ts_tag(qsfp0_tx_ptp_ts_tag_int), .tx_ptp_ts_valid(qsfp0_tx_ptp_ts_valid_int), + .tx_enable(qsfp0_tx_enable), + .tx_lfc_en(qsfp0_tx_lfc_en), + .tx_lfc_req(qsfp0_tx_lfc_req), + .tx_pfc_en(qsfp0_tx_pfc_en), + .tx_pfc_req(qsfp0_tx_pfc_req), + .rx_clk(qsfp0_rx_clk_int), .rx_rst(qsfp0_rx_rst_int), @@ -1217,7 +1238,14 @@ qsfp0_cmac_inst ( .rx_ptp_rst(qsfp0_rx_ptp_rst_int), .rx_ptp_time(qsfp0_rx_ptp_time_int), - .rx_status(qsfp0_rx_status) + .rx_enable(qsfp0_rx_enable), + .rx_status(qsfp0_rx_status), + .rx_lfc_en(qsfp0_rx_lfc_en), + .rx_lfc_req(qsfp0_rx_lfc_req), + .rx_lfc_ack(qsfp0_rx_lfc_ack), + .rx_pfc_en(qsfp0_rx_pfc_en), + .rx_pfc_req(qsfp0_rx_pfc_req), + .rx_pfc_ack(qsfp0_rx_pfc_ack) ); // QSFP1 CMAC @@ -1261,7 +1289,20 @@ wire qsfp1_drp_we; wire [15:0] qsfp1_drp_do; wire qsfp1_drp_rdy; -wire qsfp1_rx_status; +wire qsfp1_tx_enable; +wire qsfp1_tx_lfc_en; +wire qsfp1_tx_lfc_req; +wire [7:0] qsfp1_tx_pfc_en; +wire [7:0] qsfp1_tx_pfc_req; + +wire qsfp1_rx_enable; +wire qsfp1_rx_status; +wire qsfp1_rx_lfc_en; +wire qsfp1_rx_lfc_req; +wire qsfp1_rx_lfc_ack; +wire [7:0] qsfp1_rx_pfc_en; +wire [7:0] qsfp1_rx_pfc_req; +wire [7:0] qsfp1_rx_pfc_ack; wire qsfp1_gtpowergood; @@ -1354,6 +1395,12 @@ qsfp1_cmac_inst ( .tx_ptp_ts_tag(qsfp1_tx_ptp_ts_tag_int), .tx_ptp_ts_valid(qsfp1_tx_ptp_ts_valid_int), + .tx_enable(qsfp1_tx_enable), + .tx_lfc_en(qsfp1_tx_lfc_en), + .tx_lfc_req(qsfp1_tx_lfc_req), + .tx_pfc_en(qsfp1_tx_pfc_en), + .tx_pfc_req(qsfp1_tx_pfc_req), + .rx_clk(qsfp1_rx_clk_int), .rx_rst(qsfp1_rx_rst_int), @@ -1367,7 +1414,14 @@ qsfp1_cmac_inst ( .rx_ptp_rst(qsfp1_rx_ptp_rst_int), .rx_ptp_time(qsfp1_rx_ptp_time_int), - .rx_status(qsfp1_rx_status) + .rx_enable(qsfp1_rx_enable), + .rx_status(qsfp1_rx_status), + .rx_lfc_en(qsfp1_rx_lfc_en), + .rx_lfc_req(qsfp1_rx_lfc_req), + .rx_lfc_ack(qsfp1_rx_lfc_ack), + .rx_pfc_en(qsfp1_rx_pfc_en), + .rx_pfc_req(qsfp1_rx_pfc_req), + .rx_pfc_ack(qsfp1_rx_pfc_ack) ); wire ptp_clk; @@ -2001,6 +2055,8 @@ fpga_core #( .TX_CHECKSUM_ENABLE(TX_CHECKSUM_ENABLE), .RX_HASH_ENABLE(RX_HASH_ENABLE), .RX_CHECKSUM_ENABLE(RX_CHECKSUM_ENABLE), + .PFC_ENABLE(PFC_ENABLE), + .LFC_ENABLE(LFC_ENABLE), .TX_FIFO_DEPTH(TX_FIFO_DEPTH), .RX_FIFO_DEPTH(RX_FIFO_DEPTH), .MAX_TX_SIZE(MAX_TX_SIZE), @@ -2205,6 +2261,12 @@ core_inst ( .qsfp0_tx_ptp_ts_tag(qsfp0_tx_ptp_ts_tag_int), .qsfp0_tx_ptp_ts_valid(qsfp0_tx_ptp_ts_valid_int), + .qsfp0_tx_enable(qsfp0_tx_enable), + .qsfp0_tx_lfc_en(qsfp0_tx_lfc_en), + .qsfp0_tx_lfc_req(qsfp0_tx_lfc_req), + .qsfp0_tx_pfc_en(qsfp0_tx_pfc_en), + .qsfp0_tx_pfc_req(qsfp0_tx_pfc_req), + .qsfp0_rx_clk(qsfp0_rx_clk_int), .qsfp0_rx_rst(qsfp0_rx_rst_int), .qsfp0_rx_axis_tdata(qsfp0_rx_axis_tdata_int), @@ -2216,7 +2278,14 @@ core_inst ( .qsfp0_rx_ptp_rst(qsfp0_rx_ptp_rst_int), .qsfp0_rx_ptp_time(qsfp0_rx_ptp_time_int), + .qsfp0_rx_enable(qsfp0_rx_enable), .qsfp0_rx_status(qsfp0_rx_status), + .qsfp0_rx_lfc_en(qsfp0_rx_lfc_en), + .qsfp0_rx_lfc_req(qsfp0_rx_lfc_req), + .qsfp0_rx_lfc_ack(qsfp0_rx_lfc_ack), + .qsfp0_rx_pfc_en(qsfp0_rx_pfc_en), + .qsfp0_rx_pfc_req(qsfp0_rx_pfc_req), + .qsfp0_rx_pfc_ack(qsfp0_rx_pfc_ack), .qsfp0_drp_clk(qsfp0_drp_clk), .qsfp0_drp_rst(qsfp0_drp_rst), @@ -2246,6 +2315,12 @@ core_inst ( .qsfp1_tx_ptp_ts_tag(qsfp1_tx_ptp_ts_tag_int), .qsfp1_tx_ptp_ts_valid(qsfp1_tx_ptp_ts_valid_int), + .qsfp1_tx_enable(qsfp1_tx_enable), + .qsfp1_tx_lfc_en(qsfp1_tx_lfc_en), + .qsfp1_tx_lfc_req(qsfp1_tx_lfc_req), + .qsfp1_tx_pfc_en(qsfp1_tx_pfc_en), + .qsfp1_tx_pfc_req(qsfp1_tx_pfc_req), + .qsfp1_rx_clk(qsfp1_rx_clk_int), .qsfp1_rx_rst(qsfp1_rx_rst_int), .qsfp1_rx_axis_tdata(qsfp1_rx_axis_tdata_int), @@ -2257,7 +2332,14 @@ core_inst ( .qsfp1_rx_ptp_rst(qsfp1_rx_ptp_rst_int), .qsfp1_rx_ptp_time(qsfp1_rx_ptp_time_int), + .qsfp1_rx_enable(qsfp1_rx_enable), .qsfp1_rx_status(qsfp1_rx_status), + .qsfp1_rx_lfc_en(qsfp1_rx_lfc_en), + .qsfp1_rx_lfc_req(qsfp1_rx_lfc_req), + .qsfp1_rx_lfc_ack(qsfp1_rx_lfc_ack), + .qsfp1_rx_pfc_en(qsfp1_rx_pfc_en), + .qsfp1_rx_pfc_req(qsfp1_rx_pfc_req), + .qsfp1_rx_pfc_ack(qsfp1_rx_pfc_ack), .qsfp1_drp_clk(qsfp1_drp_clk), .qsfp1_drp_rst(qsfp1_drp_rst), diff --git a/fpga/mqnic/AU250/fpga_100g/rtl/fpga_core.v b/fpga/mqnic/AU250/fpga_100g/rtl/fpga_core.v index 6460dbed9..9b1a58769 100644 --- a/fpga/mqnic/AU250/fpga_100g/rtl/fpga_core.v +++ b/fpga/mqnic/AU250/fpga_100g/rtl/fpga_core.v @@ -77,6 +77,8 @@ module fpga_core # parameter TX_CHECKSUM_ENABLE = 1, parameter RX_HASH_ENABLE = 1, parameter RX_CHECKSUM_ENABLE = 1, + parameter PFC_ENABLE = 1, + parameter LFC_ENABLE = PFC_ENABLE, parameter TX_FIFO_DEPTH = 32768, parameter RX_FIFO_DEPTH = 131072, parameter MAX_TX_SIZE = 9214, @@ -283,6 +285,12 @@ module fpga_core # input wire [15:0] qsfp0_tx_ptp_ts_tag, input wire qsfp0_tx_ptp_ts_valid, + output wire qsfp0_tx_enable, + output wire qsfp0_tx_lfc_en, + output wire qsfp0_tx_lfc_req, + output wire [7:0] qsfp0_tx_pfc_en, + output wire [7:0] qsfp0_tx_pfc_req, + input wire qsfp0_rx_clk, input wire qsfp0_rx_rst, @@ -296,7 +304,14 @@ module fpga_core # input wire qsfp0_rx_ptp_rst, output wire [79:0] qsfp0_rx_ptp_time, + output wire qsfp0_rx_enable, input wire qsfp0_rx_status, + output wire qsfp0_rx_lfc_en, + input wire qsfp0_rx_lfc_req, + output wire qsfp0_rx_lfc_ack, + output wire [7:0] qsfp0_rx_pfc_en, + input wire [7:0] qsfp0_rx_pfc_req, + output wire [7:0] qsfp0_rx_pfc_ack, input wire qsfp0_drp_clk, input wire qsfp0_drp_rst, @@ -328,6 +343,12 @@ module fpga_core # input wire [15:0] qsfp1_tx_ptp_ts_tag, input wire qsfp1_tx_ptp_ts_valid, + output wire qsfp1_tx_enable, + output wire qsfp1_tx_lfc_en, + output wire qsfp1_tx_lfc_req, + output wire [7:0] qsfp1_tx_pfc_en, + output wire [7:0] qsfp1_tx_pfc_req, + input wire qsfp1_rx_clk, input wire qsfp1_rx_rst, @@ -341,7 +362,14 @@ module fpga_core # input wire qsfp1_rx_ptp_rst, output wire [79:0] qsfp1_rx_ptp_time, + output wire qsfp1_rx_enable, input wire qsfp1_rx_status, + output wire qsfp1_rx_lfc_en, + input wire qsfp1_rx_lfc_req, + output wire qsfp1_rx_lfc_ack, + output wire [7:0] qsfp1_rx_pfc_en, + input wire [7:0] qsfp1_rx_pfc_req, + output wire [7:0] qsfp1_rx_pfc_ack, input wire qsfp1_drp_clk, input wire qsfp1_drp_rst, @@ -837,7 +865,12 @@ wire [PORT_COUNT*TX_TAG_WIDTH-1:0] axis_eth_tx_ptp_ts_tag; wire [PORT_COUNT-1:0] axis_eth_tx_ptp_ts_valid; wire [PORT_COUNT-1:0] axis_eth_tx_ptp_ts_ready; +wire [PORT_COUNT-1:0] eth_tx_enable; wire [PORT_COUNT-1:0] eth_tx_status; +wire [PORT_COUNT-1:0] eth_tx_lfc_en; +wire [PORT_COUNT-1:0] eth_tx_lfc_req; +wire [PORT_COUNT*8-1:0] eth_tx_pfc_en; +wire [PORT_COUNT*8-1:0] eth_tx_pfc_req; wire [PORT_COUNT-1:0] eth_rx_clk; wire [PORT_COUNT-1:0] eth_rx_rst; @@ -854,7 +887,14 @@ wire [PORT_COUNT-1:0] axis_eth_rx_tready; wire [PORT_COUNT-1:0] axis_eth_rx_tlast; wire [PORT_COUNT*AXIS_ETH_RX_USER_WIDTH-1:0] axis_eth_rx_tuser; +wire [PORT_COUNT-1:0] eth_rx_enable; wire [PORT_COUNT-1:0] eth_rx_status; +wire [PORT_COUNT-1:0] eth_rx_lfc_en; +wire [PORT_COUNT-1:0] eth_rx_lfc_req; +wire [PORT_COUNT-1:0] eth_rx_lfc_ack; +wire [PORT_COUNT*8-1:0] eth_rx_pfc_en; +wire [PORT_COUNT*8-1:0] eth_rx_pfc_req; +wire [PORT_COUNT*8-1:0] eth_rx_pfc_ack; wire [PTP_TS_WIDTH-1:0] qsfp0_tx_ptp_time_int; wire [PTP_TS_WIDTH-1:0] qsfp1_tx_ptp_time_int; @@ -905,7 +945,12 @@ mqnic_port_map_mac_axis_inst ( .s_axis_mac_tx_ptp_ts_valid({qsfp1_tx_ptp_ts_valid, qsfp0_tx_ptp_ts_valid}), .s_axis_mac_tx_ptp_ts_ready(), + .mac_tx_enable({qsfp1_tx_enable, qsfp0_tx_enable}), .mac_tx_status(2'b11), + .mac_tx_lfc_en({qsfp1_tx_lfc_en, qsfp0_tx_lfc_en}), + .mac_tx_lfc_req({qsfp1_tx_lfc_req, qsfp0_tx_lfc_req}), + .mac_tx_pfc_en({qsfp1_tx_pfc_en, qsfp0_tx_pfc_en}), + .mac_tx_pfc_req({qsfp1_tx_pfc_req, qsfp0_tx_pfc_req}), .mac_rx_clk({qsfp1_rx_clk, qsfp0_rx_clk}), .mac_rx_rst({qsfp1_rx_rst, qsfp0_rx_rst}), @@ -922,7 +967,14 @@ mqnic_port_map_mac_axis_inst ( .s_axis_mac_rx_tlast({qsfp1_rx_axis_tlast, qsfp0_rx_axis_tlast}), .s_axis_mac_rx_tuser({{qsfp1_rx_axis_tuser[80:1], 16'd0, qsfp1_rx_axis_tuser[0]}, {qsfp0_rx_axis_tuser[80:1], 16'd0, qsfp0_rx_axis_tuser[0]}}), + .mac_rx_enable({qsfp1_rx_enable, qsfp0_rx_enable}), .mac_rx_status({qsfp1_rx_status, qsfp0_rx_status}), + .mac_rx_lfc_en({qsfp1_rx_lfc_en, qsfp0_rx_lfc_en}), + .mac_rx_lfc_req({qsfp1_rx_lfc_req, qsfp0_rx_lfc_req}), + .mac_rx_lfc_ack({qsfp1_rx_lfc_ack, qsfp0_rx_lfc_ack}), + .mac_rx_pfc_en({qsfp1_rx_pfc_en, qsfp0_rx_pfc_en}), + .mac_rx_pfc_req({qsfp1_rx_pfc_req, qsfp0_rx_pfc_req}), + .mac_rx_pfc_ack({qsfp1_rx_pfc_ack, qsfp0_rx_pfc_ack}), // towards datapath .tx_clk(eth_tx_clk), @@ -945,7 +997,12 @@ mqnic_port_map_mac_axis_inst ( .m_axis_tx_ptp_ts_valid(axis_eth_tx_ptp_ts_valid), .m_axis_tx_ptp_ts_ready(axis_eth_tx_ptp_ts_ready), + .tx_enable(eth_tx_enable), .tx_status(eth_tx_status), + .tx_lfc_en(eth_tx_lfc_en), + .tx_lfc_req(eth_tx_lfc_req), + .tx_pfc_en(eth_tx_pfc_en), + .tx_pfc_req(eth_tx_pfc_req), .rx_clk(eth_rx_clk), .rx_rst(eth_rx_rst), @@ -962,7 +1019,14 @@ mqnic_port_map_mac_axis_inst ( .m_axis_rx_tlast(axis_eth_rx_tlast), .m_axis_rx_tuser(axis_eth_rx_tuser), - .rx_status(eth_rx_status) + .rx_enable(eth_rx_enable), + .rx_status(eth_rx_status), + .rx_lfc_en(eth_rx_lfc_en), + .rx_lfc_req(eth_rx_lfc_req), + .rx_lfc_ack(eth_rx_lfc_ack), + .rx_pfc_en(eth_rx_pfc_en), + .rx_pfc_req(eth_rx_pfc_req), + .rx_pfc_ack(eth_rx_pfc_ack) ); mqnic_core_pcie_us #( @@ -1032,6 +1096,9 @@ mqnic_core_pcie_us #( .TX_CHECKSUM_ENABLE(TX_CHECKSUM_ENABLE), .RX_HASH_ENABLE(RX_HASH_ENABLE), .RX_CHECKSUM_ENABLE(RX_CHECKSUM_ENABLE), + .PFC_ENABLE(PFC_ENABLE), + .LFC_ENABLE(LFC_ENABLE), + .MAC_CTRL_ENABLE(0), .TX_FIFO_DEPTH(TX_FIFO_DEPTH), .RX_FIFO_DEPTH(RX_FIFO_DEPTH), .MAX_TX_SIZE(MAX_TX_SIZE), @@ -1313,7 +1380,13 @@ core_inst ( .s_axis_eth_tx_cpl_valid(axis_eth_tx_ptp_ts_valid), .s_axis_eth_tx_cpl_ready(axis_eth_tx_ptp_ts_ready), + .eth_tx_enable(eth_tx_enable), .eth_tx_status(eth_tx_status), + .eth_tx_lfc_en(eth_tx_lfc_en), + .eth_tx_lfc_req(eth_tx_lfc_req), + .eth_tx_pfc_en(eth_tx_pfc_en), + .eth_tx_pfc_req(eth_tx_pfc_req), + .eth_tx_fc_quanta_clk_en(0), .eth_rx_clk(eth_rx_clk), .eth_rx_rst(eth_rx_rst), @@ -1330,7 +1403,15 @@ core_inst ( .s_axis_eth_rx_tlast(axis_eth_rx_tlast), .s_axis_eth_rx_tuser(axis_eth_rx_tuser), + .eth_rx_enable(eth_rx_enable), .eth_rx_status(eth_rx_status), + .eth_rx_lfc_en(eth_rx_lfc_en), + .eth_rx_lfc_req(eth_rx_lfc_req), + .eth_rx_lfc_ack(eth_rx_lfc_ack), + .eth_rx_pfc_en(eth_rx_pfc_en), + .eth_rx_pfc_req(eth_rx_pfc_req), + .eth_rx_pfc_ack(eth_rx_pfc_ack), + .eth_rx_fc_quanta_clk_en(0), /* * DDR diff --git a/fpga/mqnic/AU250/fpga_100g/tb/fpga_core/Makefile b/fpga/mqnic/AU250/fpga_100g/tb/fpga_core/Makefile index 67d20a951..e8de2d7d3 100644 --- a/fpga/mqnic/AU250/fpga_100g/tb/fpga_core/Makefile +++ b/fpga/mqnic/AU250/fpga_100g/tb/fpga_core/Makefile @@ -161,6 +161,8 @@ export PARAM_TX_CPL_FIFO_DEPTH := 32 export PARAM_TX_CHECKSUM_ENABLE := 1 export PARAM_RX_HASH_ENABLE := 1 export PARAM_RX_CHECKSUM_ENABLE := 1 +export PARAM_LFC_ENABLE := 1 +export PARAM_PFC_ENABLE := $(PARAM_LFC_ENABLE) export PARAM_TX_FIFO_DEPTH := 32768 export PARAM_RX_FIFO_DEPTH := 131072 export PARAM_MAX_TX_SIZE := 9214 diff --git a/fpga/mqnic/AU250/fpga_100g/tb/fpga_core/test_fpga_core.py b/fpga/mqnic/AU250/fpga_100g/tb/fpga_core/test_fpga_core.py index 1160702cc..c43b5c299 100644 --- a/fpga/mqnic/AU250/fpga_100g/tb/fpga_core/test_fpga_core.py +++ b/fpga/mqnic/AU250/fpga_100g/tb/fpga_core/test_fpga_core.py @@ -300,6 +300,8 @@ class TB(object): self.qsfp_mac.append(mac) getattr(dut, f"qsfp{k}_rx_status").setimmediatevalue(1) + getattr(dut, f"qsfp{k}_rx_lfc_req").setimmediatevalue(0) + getattr(dut, f"qsfp{k}_rx_pfc_req").setimmediatevalue(0) cocotb.start_soon(Clock(getattr(dut, f"qsfp{k}_drp_clk"), 8, units="ns").start()) getattr(dut, f"qsfp{k}_drp_rst").setimmediatevalue(0) @@ -307,7 +309,7 @@ class TB(object): getattr(dut, f"qsfp{k}_drp_rdy").setimmediatevalue(0) getattr(dut, f"qsfp{k}_modprsl").setimmediatevalue(0) - getattr(dut, f"qsfp{k}_intl").setimmediatevalue(0) + getattr(dut, f"qsfp{k}_intl").setimmediatevalue(1) dut.sw.setimmediatevalue(0) @@ -723,6 +725,8 @@ def test_fpga_core(request): parameters['TX_CHECKSUM_ENABLE'] = 1 parameters['RX_HASH_ENABLE'] = 1 parameters['RX_CHECKSUM_ENABLE'] = 1 + parameters['LFC_ENABLE'] = 1 + parameters['PFC_ENABLE'] = parameters['LFC_ENABLE'] parameters['TX_FIFO_DEPTH'] = 32768 parameters['RX_FIFO_DEPTH'] = 131072 parameters['MAX_TX_SIZE'] = 9214 diff --git a/fpga/mqnic/AU250/fpga_25g/fpga/Makefile b/fpga/mqnic/AU250/fpga_25g/fpga/Makefile index 3bd6201e7..ceb90616f 100644 --- a/fpga/mqnic/AU250/fpga_25g/fpga/Makefile +++ b/fpga/mqnic/AU250/fpga_25g/fpga/Makefile @@ -62,6 +62,10 @@ SYN_FILES += rtl/common/tdma_ber_ch.v SYN_FILES += lib/eth/rtl/eth_mac_10g.v SYN_FILES += lib/eth/rtl/axis_xgmii_rx_64.v SYN_FILES += lib/eth/rtl/axis_xgmii_tx_64.v +SYN_FILES += lib/eth/rtl/mac_ctrl_rx.v +SYN_FILES += lib/eth/rtl/mac_ctrl_tx.v +SYN_FILES += lib/eth/rtl/mac_pause_ctrl_rx.v +SYN_FILES += lib/eth/rtl/mac_pause_ctrl_tx.v SYN_FILES += lib/eth/rtl/eth_phy_10g.v SYN_FILES += lib/eth/rtl/eth_phy_10g_rx.v SYN_FILES += lib/eth/rtl/eth_phy_10g_rx_if.v diff --git a/fpga/mqnic/AU250/fpga_25g/fpga/config.tcl b/fpga/mqnic/AU250/fpga_25g/fpga/config.tcl index 1cab136b4..cd7b6e8bd 100644 --- a/fpga/mqnic/AU250/fpga_25g/fpga/config.tcl +++ b/fpga/mqnic/AU250/fpga_25g/fpga/config.tcl @@ -113,6 +113,8 @@ dict set params TX_CPL_FIFO_DEPTH "32" dict set params TX_CHECKSUM_ENABLE "1" dict set params RX_HASH_ENABLE "1" dict set params RX_CHECKSUM_ENABLE "1" +dict set params PFC_ENABLE "1" +dict set params LFC_ENABLE [dict get $params PFC_ENABLE] dict set params ENABLE_PADDING "1" dict set params ENABLE_DIC "1" dict set params MIN_FRAME_LENGTH "64" diff --git a/fpga/mqnic/AU250/fpga_25g/fpga_10g/Makefile b/fpga/mqnic/AU250/fpga_25g/fpga_10g/Makefile index 3bd6201e7..ceb90616f 100644 --- a/fpga/mqnic/AU250/fpga_25g/fpga_10g/Makefile +++ b/fpga/mqnic/AU250/fpga_25g/fpga_10g/Makefile @@ -62,6 +62,10 @@ SYN_FILES += rtl/common/tdma_ber_ch.v SYN_FILES += lib/eth/rtl/eth_mac_10g.v SYN_FILES += lib/eth/rtl/axis_xgmii_rx_64.v SYN_FILES += lib/eth/rtl/axis_xgmii_tx_64.v +SYN_FILES += lib/eth/rtl/mac_ctrl_rx.v +SYN_FILES += lib/eth/rtl/mac_ctrl_tx.v +SYN_FILES += lib/eth/rtl/mac_pause_ctrl_rx.v +SYN_FILES += lib/eth/rtl/mac_pause_ctrl_tx.v SYN_FILES += lib/eth/rtl/eth_phy_10g.v SYN_FILES += lib/eth/rtl/eth_phy_10g_rx.v SYN_FILES += lib/eth/rtl/eth_phy_10g_rx_if.v diff --git a/fpga/mqnic/AU250/fpga_25g/fpga_10g/config.tcl b/fpga/mqnic/AU250/fpga_25g/fpga_10g/config.tcl index 8076cb78c..abd557ac8 100644 --- a/fpga/mqnic/AU250/fpga_25g/fpga_10g/config.tcl +++ b/fpga/mqnic/AU250/fpga_25g/fpga_10g/config.tcl @@ -113,6 +113,8 @@ dict set params TX_CPL_FIFO_DEPTH "32" dict set params TX_CHECKSUM_ENABLE "1" dict set params RX_HASH_ENABLE "1" dict set params RX_CHECKSUM_ENABLE "1" +dict set params PFC_ENABLE "1" +dict set params LFC_ENABLE [dict get $params PFC_ENABLE] dict set params ENABLE_PADDING "1" dict set params ENABLE_DIC "1" dict set params MIN_FRAME_LENGTH "64" diff --git a/fpga/mqnic/AU250/fpga_25g/rtl/fpga.v b/fpga/mqnic/AU250/fpga_25g/rtl/fpga.v index e1f0733fd..89a1a32ed 100644 --- a/fpga/mqnic/AU250/fpga_25g/rtl/fpga.v +++ b/fpga/mqnic/AU250/fpga_25g/rtl/fpga.v @@ -74,6 +74,8 @@ module fpga # parameter TX_CHECKSUM_ENABLE = 1, parameter RX_HASH_ENABLE = 1, parameter RX_CHECKSUM_ENABLE = 1, + parameter PFC_ENABLE = 1, + parameter LFC_ENABLE = PFC_ENABLE, parameter ENABLE_PADDING = 1, parameter ENABLE_DIC = 1, parameter MIN_FRAME_LENGTH = 64, @@ -2137,6 +2139,8 @@ fpga_core #( .TX_CHECKSUM_ENABLE(TX_CHECKSUM_ENABLE), .RX_HASH_ENABLE(RX_HASH_ENABLE), .RX_CHECKSUM_ENABLE(RX_CHECKSUM_ENABLE), + .PFC_ENABLE(PFC_ENABLE), + .LFC_ENABLE(LFC_ENABLE), .ENABLE_PADDING(ENABLE_PADDING), .ENABLE_DIC(ENABLE_DIC), .MIN_FRAME_LENGTH(MIN_FRAME_LENGTH), diff --git a/fpga/mqnic/AU250/fpga_25g/rtl/fpga_core.v b/fpga/mqnic/AU250/fpga_25g/rtl/fpga_core.v index 65af70413..101e0c751 100644 --- a/fpga/mqnic/AU250/fpga_25g/rtl/fpga_core.v +++ b/fpga/mqnic/AU250/fpga_25g/rtl/fpga_core.v @@ -81,6 +81,8 @@ module fpga_core # parameter TX_CHECKSUM_ENABLE = 1, parameter RX_HASH_ENABLE = 1, parameter RX_CHECKSUM_ENABLE = 1, + parameter PFC_ENABLE = 1, + parameter LFC_ENABLE = PFC_ENABLE, parameter ENABLE_PADDING = 1, parameter ENABLE_DIC = 1, parameter MIN_FRAME_LENGTH = 64, @@ -979,7 +981,12 @@ wire [PORT_COUNT*TX_TAG_WIDTH-1:0] axis_eth_tx_ptp_ts_tag; wire [PORT_COUNT-1:0] axis_eth_tx_ptp_ts_valid; wire [PORT_COUNT-1:0] axis_eth_tx_ptp_ts_ready; +wire [PORT_COUNT-1:0] eth_tx_enable; wire [PORT_COUNT-1:0] eth_tx_status; +wire [PORT_COUNT-1:0] eth_tx_lfc_en; +wire [PORT_COUNT-1:0] eth_tx_lfc_req; +wire [PORT_COUNT*8-1:0] eth_tx_pfc_en; +wire [PORT_COUNT*8-1:0] eth_tx_pfc_req; wire [PORT_COUNT-1:0] eth_rx_clk; wire [PORT_COUNT-1:0] eth_rx_rst; @@ -994,7 +1001,14 @@ wire [PORT_COUNT-1:0] axis_eth_rx_tready; wire [PORT_COUNT-1:0] axis_eth_rx_tlast; wire [PORT_COUNT*AXIS_ETH_RX_USER_WIDTH-1:0] axis_eth_rx_tuser; +wire [PORT_COUNT-1:0] eth_rx_enable; wire [PORT_COUNT-1:0] eth_rx_status; +wire [PORT_COUNT-1:0] eth_rx_lfc_en; +wire [PORT_COUNT-1:0] eth_rx_lfc_req; +wire [PORT_COUNT-1:0] eth_rx_lfc_ack; +wire [PORT_COUNT*8-1:0] eth_rx_pfc_en; +wire [PORT_COUNT*8-1:0] eth_rx_pfc_req; +wire [PORT_COUNT*8-1:0] eth_rx_pfc_ack; wire [PORT_COUNT-1:0] port_xgmii_tx_clk; wire [PORT_COUNT-1:0] port_xgmii_tx_rst; @@ -1067,12 +1081,15 @@ generate .PTP_PERIOD_FNS(IF_PTP_PERIOD_FNS), .TX_PTP_TS_ENABLE(PTP_TS_ENABLE), .TX_PTP_TS_WIDTH(PTP_TS_WIDTH), + .TX_PTP_TS_CTRL_IN_TUSER(0), .TX_PTP_TAG_ENABLE(PTP_TS_ENABLE), .TX_PTP_TAG_WIDTH(TX_TAG_WIDTH), .RX_PTP_TS_ENABLE(PTP_TS_ENABLE), .RX_PTP_TS_WIDTH(PTP_TS_WIDTH), .TX_USER_WIDTH(AXIS_ETH_TX_USER_WIDTH), - .RX_USER_WIDTH(AXIS_ETH_RX_USER_WIDTH) + .RX_USER_WIDTH(AXIS_ETH_RX_USER_WIDTH), + .PFC_ENABLE(PFC_ENABLE), + .PAUSE_ENABLE(LFC_ENABLE) ) eth_mac_inst ( .tx_clk(port_xgmii_tx_clk[n]), @@ -1080,6 +1097,9 @@ generate .rx_clk(port_xgmii_rx_clk[n]), .rx_rst(port_xgmii_rx_rst[n]), + /* + * AXI input + */ .tx_axis_tdata(axis_eth_tx_tdata[n*AXIS_ETH_DATA_WIDTH +: AXIS_ETH_DATA_WIDTH]), .tx_axis_tkeep(axis_eth_tx_tkeep[n*AXIS_ETH_KEEP_WIDTH +: AXIS_ETH_KEEP_WIDTH]), .tx_axis_tvalid(axis_eth_tx_tvalid[n +: 1]), @@ -1087,30 +1107,121 @@ generate .tx_axis_tlast(axis_eth_tx_tlast[n +: 1]), .tx_axis_tuser(axis_eth_tx_tuser[n*AXIS_ETH_TX_USER_WIDTH +: AXIS_ETH_TX_USER_WIDTH]), + /* + * AXI output + */ .rx_axis_tdata(axis_eth_rx_tdata[n*AXIS_ETH_DATA_WIDTH +: AXIS_ETH_DATA_WIDTH]), .rx_axis_tkeep(axis_eth_rx_tkeep[n*AXIS_ETH_KEEP_WIDTH +: AXIS_ETH_KEEP_WIDTH]), .rx_axis_tvalid(axis_eth_rx_tvalid[n +: 1]), .rx_axis_tlast(axis_eth_rx_tlast[n +: 1]), .rx_axis_tuser(axis_eth_rx_tuser[n*AXIS_ETH_RX_USER_WIDTH +: AXIS_ETH_RX_USER_WIDTH]), + /* + * XGMII interface + */ .xgmii_rxd(port_xgmii_rxd[n*XGMII_DATA_WIDTH +: XGMII_DATA_WIDTH]), .xgmii_rxc(port_xgmii_rxc[n*XGMII_CTRL_WIDTH +: XGMII_CTRL_WIDTH]), .xgmii_txd(port_xgmii_txd[n*XGMII_DATA_WIDTH +: XGMII_DATA_WIDTH]), .xgmii_txc(port_xgmii_txc[n*XGMII_CTRL_WIDTH +: XGMII_CTRL_WIDTH]), + /* + * PTP + */ .tx_ptp_ts(eth_tx_ptp_ts_96[n*PTP_TS_WIDTH +: PTP_TS_WIDTH]), .rx_ptp_ts(eth_rx_ptp_ts_96[n*PTP_TS_WIDTH +: PTP_TS_WIDTH]), .tx_axis_ptp_ts(axis_eth_tx_ptp_ts[n*PTP_TS_WIDTH +: PTP_TS_WIDTH]), .tx_axis_ptp_ts_tag(axis_eth_tx_ptp_ts_tag[n*TX_TAG_WIDTH +: TX_TAG_WIDTH]), .tx_axis_ptp_ts_valid(axis_eth_tx_ptp_ts_valid[n +: 1]), + /* + * Link-level Flow Control (LFC) (IEEE 802.3 annex 31B PAUSE) + */ + .tx_lfc_req(eth_tx_lfc_req[n +: 1]), + .tx_lfc_resend(1'b0), + .rx_lfc_en(eth_rx_lfc_en[n +: 1]), + .rx_lfc_req(eth_rx_lfc_req[n +: 1]), + .rx_lfc_ack(eth_rx_lfc_ack[n +: 1]), + + /* + * Priority Flow Control (PFC) (IEEE 802.3 annex 31D PFC) + */ + .tx_pfc_req(eth_tx_pfc_req[n*8 +: 8]), + .tx_pfc_resend(1'b0), + .rx_pfc_en(eth_rx_pfc_en[n*8 +: 8]), + .rx_pfc_req(eth_rx_pfc_req[n*8 +: 8]), + .rx_pfc_ack(eth_rx_pfc_ack[n*8 +: 8]), + + /* + * Pause interface + */ + .tx_lfc_pause_en(1'b1), + .tx_pause_req(1'b0), + .tx_pause_ack(), + + /* + * Status + */ + .tx_start_packet(), .tx_error_underflow(), + .rx_start_packet(), .rx_error_bad_frame(), .rx_error_bad_fcs(), + .stat_tx_mcf(), + .stat_rx_mcf(), + .stat_tx_lfc_pkt(), + .stat_tx_lfc_xon(), + .stat_tx_lfc_xoff(), + .stat_tx_lfc_paused(), + .stat_tx_pfc_pkt(), + .stat_tx_pfc_xon(), + .stat_tx_pfc_xoff(), + .stat_tx_pfc_paused(), + .stat_rx_lfc_pkt(), + .stat_rx_lfc_xon(), + .stat_rx_lfc_xoff(), + .stat_rx_lfc_paused(), + .stat_rx_pfc_pkt(), + .stat_rx_pfc_xon(), + .stat_rx_pfc_xoff(), + .stat_rx_pfc_paused(), + /* + * Configuration + */ .cfg_ifg(8'd12), - .cfg_tx_enable(1'b1), - .cfg_rx_enable(1'b1) + .cfg_tx_enable(eth_tx_enable[n +: 1]), + .cfg_rx_enable(eth_rx_enable[n +: 1]), + .cfg_mcf_rx_eth_dst_mcast(48'h01_80_C2_00_00_01), + .cfg_mcf_rx_check_eth_dst_mcast(1'b1), + .cfg_mcf_rx_eth_dst_ucast(48'd0), + .cfg_mcf_rx_check_eth_dst_ucast(1'b0), + .cfg_mcf_rx_eth_src(48'd0), + .cfg_mcf_rx_check_eth_src(1'b0), + .cfg_mcf_rx_eth_type(16'h8808), + .cfg_mcf_rx_opcode_lfc(16'h0001), + .cfg_mcf_rx_check_opcode_lfc(eth_rx_lfc_en[n +: 1]), + .cfg_mcf_rx_opcode_pfc(16'h0101), + .cfg_mcf_rx_check_opcode_pfc(eth_rx_pfc_en[n*8 +: 8] != 0), + .cfg_mcf_rx_forward(1'b0), + .cfg_mcf_rx_enable(eth_rx_lfc_en[n +: 1] || eth_rx_pfc_en[n*8 +: 8]), + .cfg_tx_lfc_eth_dst(48'h01_80_C2_00_00_01), + .cfg_tx_lfc_eth_src(48'h80_23_31_43_54_4C), + .cfg_tx_lfc_eth_type(16'h8808), + .cfg_tx_lfc_opcode(16'h0001), + .cfg_tx_lfc_en(eth_tx_lfc_en[n +: 1]), + .cfg_tx_lfc_quanta(16'hffff), + .cfg_tx_lfc_refresh(16'h7fff), + .cfg_tx_pfc_eth_dst(48'h01_80_C2_00_00_01), + .cfg_tx_pfc_eth_src(48'h80_23_31_43_54_4C), + .cfg_tx_pfc_eth_type(16'h8808), + .cfg_tx_pfc_opcode(16'h0101), + .cfg_tx_pfc_en(eth_tx_pfc_en[n*8 +: 8] != 0), + .cfg_tx_pfc_quanta({8{16'hffff}}), + .cfg_tx_pfc_refresh({8{16'h7fff}}), + .cfg_rx_lfc_opcode(16'h0001), + .cfg_rx_lfc_en(eth_rx_lfc_en[n +: 1]), + .cfg_rx_pfc_opcode(16'h0101), + .cfg_rx_pfc_en(eth_rx_pfc_en[n*8 +: 8] != 0) ); end @@ -1184,6 +1295,9 @@ mqnic_core_pcie_us #( .TX_CHECKSUM_ENABLE(TX_CHECKSUM_ENABLE), .RX_HASH_ENABLE(RX_HASH_ENABLE), .RX_CHECKSUM_ENABLE(RX_CHECKSUM_ENABLE), + .PFC_ENABLE(PFC_ENABLE), + .LFC_ENABLE(LFC_ENABLE), + .MAC_CTRL_ENABLE(0), .TX_FIFO_DEPTH(TX_FIFO_DEPTH), .RX_FIFO_DEPTH(RX_FIFO_DEPTH), .MAX_TX_SIZE(MAX_TX_SIZE), @@ -1465,7 +1579,13 @@ core_inst ( .s_axis_eth_tx_cpl_valid(axis_eth_tx_ptp_ts_valid), .s_axis_eth_tx_cpl_ready(axis_eth_tx_ptp_ts_ready), + .eth_tx_enable(eth_tx_enable), .eth_tx_status(eth_tx_status), + .eth_tx_lfc_en(eth_tx_lfc_en), + .eth_tx_lfc_req(eth_tx_lfc_req), + .eth_tx_pfc_en(eth_tx_pfc_en), + .eth_tx_pfc_req(eth_tx_pfc_req), + .eth_tx_fc_quanta_clk_en(0), .eth_rx_clk(eth_rx_clk), .eth_rx_rst(eth_rx_rst), @@ -1482,7 +1602,15 @@ core_inst ( .s_axis_eth_rx_tlast(axis_eth_rx_tlast), .s_axis_eth_rx_tuser(axis_eth_rx_tuser), + .eth_rx_enable(eth_rx_enable), .eth_rx_status(eth_rx_status), + .eth_rx_lfc_en(eth_rx_lfc_en), + .eth_rx_lfc_req(eth_rx_lfc_req), + .eth_rx_lfc_ack(eth_rx_lfc_ack), + .eth_rx_pfc_en(eth_rx_pfc_en), + .eth_rx_pfc_req(eth_rx_pfc_req), + .eth_rx_pfc_ack(eth_rx_pfc_ack), + .eth_rx_fc_quanta_clk_en(0), /* * DDR diff --git a/fpga/mqnic/AU250/fpga_25g/tb/fpga_core/Makefile b/fpga/mqnic/AU250/fpga_25g/tb/fpga_core/Makefile index d9702a197..78a21e1ad 100644 --- a/fpga/mqnic/AU250/fpga_25g/tb/fpga_core/Makefile +++ b/fpga/mqnic/AU250/fpga_25g/tb/fpga_core/Makefile @@ -62,6 +62,10 @@ VERILOG_SOURCES += ../../rtl/common/tdma_ber_ch.v VERILOG_SOURCES += ../../lib/eth/rtl/eth_mac_10g.v VERILOG_SOURCES += ../../lib/eth/rtl/axis_xgmii_rx_64.v VERILOG_SOURCES += ../../lib/eth/rtl/axis_xgmii_tx_64.v +VERILOG_SOURCES += ../../lib/eth/rtl/mac_ctrl_rx.v +VERILOG_SOURCES += ../../lib/eth/rtl/mac_ctrl_tx.v +VERILOG_SOURCES += ../../lib/eth/rtl/mac_pause_ctrl_rx.v +VERILOG_SOURCES += ../../lib/eth/rtl/mac_pause_ctrl_tx.v VERILOG_SOURCES += ../../lib/eth/rtl/lfsr.v VERILOG_SOURCES += ../../lib/eth/rtl/ptp_clock.v VERILOG_SOURCES += ../../lib/eth/rtl/ptp_clock_cdc.v @@ -167,6 +171,8 @@ export PARAM_TX_CPL_FIFO_DEPTH := 32 export PARAM_TX_CHECKSUM_ENABLE := 1 export PARAM_RX_HASH_ENABLE := 1 export PARAM_RX_CHECKSUM_ENABLE := 1 +export PARAM_LFC_ENABLE := 1 +export PARAM_PFC_ENABLE := $(PARAM_LFC_ENABLE) export PARAM_TX_FIFO_DEPTH := 32768 export PARAM_RX_FIFO_DEPTH := 32768 export PARAM_MAX_TX_SIZE := 9214 diff --git a/fpga/mqnic/AU250/fpga_25g/tb/fpga_core/test_fpga_core.py b/fpga/mqnic/AU250/fpga_25g/tb/fpga_core/test_fpga_core.py index 58137deb2..ccdbd64c8 100644 --- a/fpga/mqnic/AU250/fpga_25g/tb/fpga_core/test_fpga_core.py +++ b/fpga/mqnic/AU250/fpga_25g/tb/fpga_core/test_fpga_core.py @@ -3,6 +3,7 @@ import logging import os +import struct import sys import scapy.utils @@ -17,7 +18,7 @@ from cocotb.clock import Clock from cocotb.triggers import RisingEdge, FallingEdge, Timer from cocotbext.axi import AxiStreamBus, AxiLiteBus, AxiLiteRam -from cocotbext.eth import XgmiiSource, XgmiiSink +from cocotbext.eth import XgmiiSource, XgmiiSink, XgmiiFrame from cocotbext.pcie.core import RootComplex from cocotbext.pcie.xilinx.us import UltraScalePlusPcieDevice @@ -528,6 +529,35 @@ async def run_test_nic(dut): tb.loopback_enable = False + if tb.driver.interfaces[0].if_feature_lfc: + tb.log.info("Test LFC pause frame RX") + + await tb.driver.interfaces[0].ports[0].set_lfc_ctrl(mqnic.MQNIC_PORT_LFC_CTRL_TX_LFC_EN | mqnic.MQNIC_PORT_LFC_CTRL_RX_LFC_EN) + await tb.driver.hw_regs.read_dword(0) + + lfc_xoff = Ether(src='DA:D1:D2:D3:D4:D5', dst='01:80:C2:00:00:01', type=0x8808) / struct.pack('!HH', 0x0001, 2000) + + await tb.qsfp_source[0][0].send(XgmiiFrame.from_payload(bytes(lfc_xoff))) + + count = 16 + + pkts = [bytearray([(x+k) % 256 for x in range(1514)]) for k in range(count)] + + tb.loopback_enable = True + + for p in pkts: + await tb.driver.interfaces[0].start_xmit(p, 0) + + for k in range(count): + pkt = await tb.driver.interfaces[0].recv() + + tb.log.info("Packet: %s", pkt) + assert pkt.data == pkts[k] + if tb.driver.interfaces[0].if_feature_rx_csum: + assert pkt.rx_checksum == ~scapy.utils.checksum(bytes(pkt.data[14:])) & 0xffff + + tb.loopback_enable = False + await RisingEdge(dut.clk_250mhz) await RisingEdge(dut.clk_250mhz) @@ -600,6 +630,10 @@ def test_fpga_core(request): os.path.join(eth_rtl_dir, "eth_mac_10g.v"), os.path.join(eth_rtl_dir, "axis_xgmii_rx_64.v"), os.path.join(eth_rtl_dir, "axis_xgmii_tx_64.v"), + os.path.join(eth_rtl_dir, "mac_ctrl_rx.v"), + os.path.join(eth_rtl_dir, "mac_ctrl_tx.v"), + os.path.join(eth_rtl_dir, "mac_pause_ctrl_rx.v"), + os.path.join(eth_rtl_dir, "mac_pause_ctrl_tx.v"), os.path.join(eth_rtl_dir, "lfsr.v"), os.path.join(eth_rtl_dir, "ptp_clock.v"), os.path.join(eth_rtl_dir, "ptp_clock_cdc.v"), @@ -706,6 +740,8 @@ def test_fpga_core(request): parameters['TX_CHECKSUM_ENABLE'] = 1 parameters['RX_HASH_ENABLE'] = 1 parameters['RX_CHECKSUM_ENABLE'] = 1 + parameters['LFC_ENABLE'] = 1 + parameters['PFC_ENABLE'] = parameters['LFC_ENABLE'] parameters['TX_FIFO_DEPTH'] = 32768 parameters['RX_FIFO_DEPTH'] = 32768 parameters['MAX_TX_SIZE'] = 9214 diff --git a/fpga/mqnic/AU280/fpga_100g/fpga/config.tcl b/fpga/mqnic/AU280/fpga_100g/fpga/config.tcl index 4d1993ff6..826a08e09 100644 --- a/fpga/mqnic/AU280/fpga_100g/fpga/config.tcl +++ b/fpga/mqnic/AU280/fpga_100g/fpga/config.tcl @@ -101,6 +101,8 @@ dict set params TX_CPL_FIFO_DEPTH "32" dict set params TX_CHECKSUM_ENABLE "1" dict set params RX_HASH_ENABLE "1" dict set params RX_CHECKSUM_ENABLE "1" +dict set params PFC_ENABLE "1" +dict set params LFC_ENABLE [dict get $params PFC_ENABLE] dict set params TX_FIFO_DEPTH "32768" dict set params RX_FIFO_DEPTH "131072" dict set params MAX_TX_SIZE "9214" diff --git a/fpga/mqnic/AU280/fpga_100g/fpga_app_dma_bench/config.tcl b/fpga/mqnic/AU280/fpga_100g/fpga_app_dma_bench/config.tcl index bc9982533..0b4e9447c 100644 --- a/fpga/mqnic/AU280/fpga_100g/fpga_app_dma_bench/config.tcl +++ b/fpga/mqnic/AU280/fpga_100g/fpga_app_dma_bench/config.tcl @@ -101,6 +101,8 @@ dict set params TX_CPL_FIFO_DEPTH "32" dict set params TX_CHECKSUM_ENABLE "1" dict set params RX_HASH_ENABLE "1" dict set params RX_CHECKSUM_ENABLE "1" +dict set params PFC_ENABLE "1" +dict set params LFC_ENABLE [dict get $params PFC_ENABLE] dict set params TX_FIFO_DEPTH "32768" dict set params RX_FIFO_DEPTH "131072" dict set params MAX_TX_SIZE "9214" diff --git a/fpga/mqnic/AU280/fpga_100g/ip/cmac_usplus.tcl b/fpga/mqnic/AU280/fpga_100g/ip/cmac_usplus.tcl index b86d4ea5e..af9cc8265 100644 --- a/fpga/mqnic/AU280/fpga_100g/ip/cmac_usplus.tcl +++ b/fpga/mqnic/AU280/fpga_100g/ip/cmac_usplus.tcl @@ -7,8 +7,10 @@ set_property -dict [list \ CONFIG.USER_INTERFACE {AXIS} \ CONFIG.GT_DRP_CLK {125} \ CONFIG.GT_LOCATION {0} \ - CONFIG.TX_FLOW_CONTROL {0} \ - CONFIG.RX_FLOW_CONTROL {0} \ + CONFIG.TX_FLOW_CONTROL {1} \ + CONFIG.RX_FLOW_CONTROL {1} \ + CONFIG.RX_FORWARD_CONTROL_FRAMES {0} \ + CONFIG.RX_CHECK_ACK {1} \ CONFIG.INCLUDE_RS_FEC {1} \ CONFIG.ENABLE_TIME_STAMPING {1} ] [get_ips cmac_usplus] diff --git a/fpga/mqnic/AU280/fpga_100g/rtl/fpga.v b/fpga/mqnic/AU280/fpga_100g/rtl/fpga.v index fd994efee..2191a08ac 100644 --- a/fpga/mqnic/AU280/fpga_100g/rtl/fpga.v +++ b/fpga/mqnic/AU280/fpga_100g/rtl/fpga.v @@ -71,6 +71,8 @@ module fpga # parameter TX_CHECKSUM_ENABLE = 1, parameter RX_HASH_ENABLE = 1, parameter RX_CHECKSUM_ENABLE = 1, + parameter PFC_ENABLE = 1, + parameter LFC_ENABLE = PFC_ENABLE, parameter TX_FIFO_DEPTH = 32768, parameter RX_FIFO_DEPTH = 131072, parameter MAX_TX_SIZE = 9214, @@ -994,7 +996,20 @@ wire qsfp0_drp_we; wire [15:0] qsfp0_drp_do; wire qsfp0_drp_rdy; -wire qsfp0_rx_status; +wire qsfp0_tx_enable; +wire qsfp0_tx_lfc_en; +wire qsfp0_tx_lfc_req; +wire [7:0] qsfp0_tx_pfc_en; +wire [7:0] qsfp0_tx_pfc_req; + +wire qsfp0_rx_enable; +wire qsfp0_rx_status; +wire qsfp0_rx_lfc_en; +wire qsfp0_rx_lfc_req; +wire qsfp0_rx_lfc_ack; +wire [7:0] qsfp0_rx_pfc_en; +wire [7:0] qsfp0_rx_pfc_req; +wire [7:0] qsfp0_rx_pfc_ack; wire qsfp0_gtpowergood; @@ -1089,6 +1104,12 @@ qsfp0_cmac_inst ( .tx_ptp_ts_tag(qsfp0_tx_ptp_ts_tag_int), .tx_ptp_ts_valid(qsfp0_tx_ptp_ts_valid_int), + .tx_enable(qsfp0_tx_enable), + .tx_lfc_en(qsfp0_tx_lfc_en), + .tx_lfc_req(qsfp0_tx_lfc_req), + .tx_pfc_en(qsfp0_tx_pfc_en), + .tx_pfc_req(qsfp0_tx_pfc_req), + .rx_clk(qsfp0_rx_clk_int), .rx_rst(qsfp0_rx_rst_int), @@ -1102,7 +1123,14 @@ qsfp0_cmac_inst ( .rx_ptp_rst(qsfp0_rx_ptp_rst_int), .rx_ptp_time(qsfp0_rx_ptp_time_int), - .rx_status(qsfp0_rx_status) + .rx_enable(qsfp0_rx_enable), + .rx_status(qsfp0_rx_status), + .rx_lfc_en(qsfp0_rx_lfc_en), + .rx_lfc_req(qsfp0_rx_lfc_req), + .rx_lfc_ack(qsfp0_rx_lfc_ack), + .rx_pfc_en(qsfp0_rx_pfc_en), + .rx_pfc_req(qsfp0_rx_pfc_req), + .rx_pfc_ack(qsfp0_rx_pfc_ack) ); // QSFP1 CMAC @@ -1146,7 +1174,20 @@ wire qsfp1_drp_we; wire [15:0] qsfp1_drp_do; wire qsfp1_drp_rdy; -wire qsfp1_rx_status; +wire qsfp1_tx_enable; +wire qsfp1_tx_lfc_en; +wire qsfp1_tx_lfc_req; +wire [7:0] qsfp1_tx_pfc_en; +wire [7:0] qsfp1_tx_pfc_req; + +wire qsfp1_rx_enable; +wire qsfp1_rx_status; +wire qsfp1_rx_lfc_en; +wire qsfp1_rx_lfc_req; +wire qsfp1_rx_lfc_ack; +wire [7:0] qsfp1_rx_pfc_en; +wire [7:0] qsfp1_rx_pfc_req; +wire [7:0] qsfp1_rx_pfc_ack; wire qsfp1_gtpowergood; @@ -1239,6 +1280,12 @@ qsfp1_cmac_inst ( .tx_ptp_ts_tag(qsfp1_tx_ptp_ts_tag_int), .tx_ptp_ts_valid(qsfp1_tx_ptp_ts_valid_int), + .tx_enable(qsfp1_tx_enable), + .tx_lfc_en(qsfp1_tx_lfc_en), + .tx_lfc_req(qsfp1_tx_lfc_req), + .tx_pfc_en(qsfp1_tx_pfc_en), + .tx_pfc_req(qsfp1_tx_pfc_req), + .rx_clk(qsfp1_rx_clk_int), .rx_rst(qsfp1_rx_rst_int), @@ -1252,7 +1299,14 @@ qsfp1_cmac_inst ( .rx_ptp_rst(qsfp1_rx_ptp_rst_int), .rx_ptp_time(qsfp1_rx_ptp_time_int), - .rx_status(qsfp1_rx_status) + .rx_enable(qsfp1_rx_enable), + .rx_status(qsfp1_rx_status), + .rx_lfc_en(qsfp1_rx_lfc_en), + .rx_lfc_req(qsfp1_rx_lfc_req), + .rx_lfc_ack(qsfp1_rx_lfc_ack), + .rx_pfc_en(qsfp1_rx_pfc_en), + .rx_pfc_req(qsfp1_rx_pfc_req), + .rx_pfc_ack(qsfp1_rx_pfc_ack) ); wire ptp_clk; @@ -3128,6 +3182,8 @@ fpga_core #( .TX_CHECKSUM_ENABLE(TX_CHECKSUM_ENABLE), .RX_HASH_ENABLE(RX_HASH_ENABLE), .RX_CHECKSUM_ENABLE(RX_CHECKSUM_ENABLE), + .PFC_ENABLE(PFC_ENABLE), + .LFC_ENABLE(LFC_ENABLE), .TX_FIFO_DEPTH(TX_FIFO_DEPTH), .RX_FIFO_DEPTH(RX_FIFO_DEPTH), .MAX_TX_SIZE(MAX_TX_SIZE), @@ -3324,6 +3380,12 @@ core_inst ( .qsfp0_tx_ptp_ts_tag(qsfp0_tx_ptp_ts_tag_int), .qsfp0_tx_ptp_ts_valid(qsfp0_tx_ptp_ts_valid_int), + .qsfp0_tx_enable(qsfp0_tx_enable), + .qsfp0_tx_lfc_en(qsfp0_tx_lfc_en), + .qsfp0_tx_lfc_req(qsfp0_tx_lfc_req), + .qsfp0_tx_pfc_en(qsfp0_tx_pfc_en), + .qsfp0_tx_pfc_req(qsfp0_tx_pfc_req), + .qsfp0_rx_clk(qsfp0_rx_clk_int), .qsfp0_rx_rst(qsfp0_rx_rst_int), .qsfp0_rx_axis_tdata(qsfp0_rx_axis_tdata_int), @@ -3335,7 +3397,14 @@ core_inst ( .qsfp0_rx_ptp_rst(qsfp0_rx_ptp_rst_int), .qsfp0_rx_ptp_time(qsfp0_rx_ptp_time_int), + .qsfp0_rx_enable(qsfp0_rx_enable), .qsfp0_rx_status(qsfp0_rx_status), + .qsfp0_rx_lfc_en(qsfp0_rx_lfc_en), + .qsfp0_rx_lfc_req(qsfp0_rx_lfc_req), + .qsfp0_rx_lfc_ack(qsfp0_rx_lfc_ack), + .qsfp0_rx_pfc_en(qsfp0_rx_pfc_en), + .qsfp0_rx_pfc_req(qsfp0_rx_pfc_req), + .qsfp0_rx_pfc_ack(qsfp0_rx_pfc_ack), .qsfp0_drp_clk(qsfp0_drp_clk), .qsfp0_drp_rst(qsfp0_drp_rst), @@ -3359,6 +3428,12 @@ core_inst ( .qsfp1_tx_ptp_ts_tag(qsfp1_tx_ptp_ts_tag_int), .qsfp1_tx_ptp_ts_valid(qsfp1_tx_ptp_ts_valid_int), + .qsfp1_tx_enable(qsfp1_tx_enable), + .qsfp1_tx_lfc_en(qsfp1_tx_lfc_en), + .qsfp1_tx_lfc_req(qsfp1_tx_lfc_req), + .qsfp1_tx_pfc_en(qsfp1_tx_pfc_en), + .qsfp1_tx_pfc_req(qsfp1_tx_pfc_req), + .qsfp1_rx_clk(qsfp1_rx_clk_int), .qsfp1_rx_rst(qsfp1_rx_rst_int), .qsfp1_rx_axis_tdata(qsfp1_rx_axis_tdata_int), @@ -3370,7 +3445,14 @@ core_inst ( .qsfp1_rx_ptp_rst(qsfp1_rx_ptp_rst_int), .qsfp1_rx_ptp_time(qsfp1_rx_ptp_time_int), + .qsfp1_rx_enable(qsfp1_rx_enable), .qsfp1_rx_status(qsfp1_rx_status), + .qsfp1_rx_lfc_en(qsfp1_rx_lfc_en), + .qsfp1_rx_lfc_req(qsfp1_rx_lfc_req), + .qsfp1_rx_lfc_ack(qsfp1_rx_lfc_ack), + .qsfp1_rx_pfc_en(qsfp1_rx_pfc_en), + .qsfp1_rx_pfc_req(qsfp1_rx_pfc_req), + .qsfp1_rx_pfc_ack(qsfp1_rx_pfc_ack), .qsfp1_drp_clk(qsfp1_drp_clk), .qsfp1_drp_rst(qsfp1_drp_rst), diff --git a/fpga/mqnic/AU280/fpga_100g/rtl/fpga_core.v b/fpga/mqnic/AU280/fpga_100g/rtl/fpga_core.v index ac9767868..4399a693d 100644 --- a/fpga/mqnic/AU280/fpga_100g/rtl/fpga_core.v +++ b/fpga/mqnic/AU280/fpga_100g/rtl/fpga_core.v @@ -77,6 +77,8 @@ module fpga_core # parameter TX_CHECKSUM_ENABLE = 1, parameter RX_HASH_ENABLE = 1, parameter RX_CHECKSUM_ENABLE = 1, + parameter PFC_ENABLE = 1, + parameter LFC_ENABLE = PFC_ENABLE, parameter TX_FIFO_DEPTH = 32768, parameter RX_FIFO_DEPTH = 131072, parameter MAX_TX_SIZE = 9214, @@ -275,6 +277,12 @@ module fpga_core # input wire [15:0] qsfp0_tx_ptp_ts_tag, input wire qsfp0_tx_ptp_ts_valid, + output wire qsfp0_tx_enable, + output wire qsfp0_tx_lfc_en, + output wire qsfp0_tx_lfc_req, + output wire [7:0] qsfp0_tx_pfc_en, + output wire [7:0] qsfp0_tx_pfc_req, + input wire qsfp0_rx_clk, input wire qsfp0_rx_rst, @@ -288,7 +296,14 @@ module fpga_core # input wire qsfp0_rx_ptp_rst, output wire [79:0] qsfp0_rx_ptp_time, + output wire qsfp0_rx_enable, input wire qsfp0_rx_status, + output wire qsfp0_rx_lfc_en, + input wire qsfp0_rx_lfc_req, + output wire qsfp0_rx_lfc_ack, + output wire [7:0] qsfp0_rx_pfc_en, + input wire [7:0] qsfp0_rx_pfc_req, + output wire [7:0] qsfp0_rx_pfc_ack, input wire qsfp0_drp_clk, input wire qsfp0_drp_rst, @@ -314,6 +329,12 @@ module fpga_core # input wire [15:0] qsfp1_tx_ptp_ts_tag, input wire qsfp1_tx_ptp_ts_valid, + output wire qsfp1_tx_enable, + output wire qsfp1_tx_lfc_en, + output wire qsfp1_tx_lfc_req, + output wire [7:0] qsfp1_tx_pfc_en, + output wire [7:0] qsfp1_tx_pfc_req, + input wire qsfp1_rx_clk, input wire qsfp1_rx_rst, @@ -327,7 +348,14 @@ module fpga_core # input wire qsfp1_rx_ptp_rst, output wire [79:0] qsfp1_rx_ptp_time, + output wire qsfp1_rx_enable, input wire qsfp1_rx_status, + output wire qsfp1_rx_lfc_en, + input wire qsfp1_rx_lfc_req, + output wire qsfp1_rx_lfc_ack, + output wire [7:0] qsfp1_rx_pfc_en, + input wire [7:0] qsfp1_rx_pfc_req, + output wire [7:0] qsfp1_rx_pfc_ack, input wire qsfp1_drp_clk, input wire qsfp1_drp_rst, @@ -780,7 +808,12 @@ wire [PORT_COUNT*TX_TAG_WIDTH-1:0] axis_eth_tx_ptp_ts_tag; wire [PORT_COUNT-1:0] axis_eth_tx_ptp_ts_valid; wire [PORT_COUNT-1:0] axis_eth_tx_ptp_ts_ready; +wire [PORT_COUNT-1:0] eth_tx_enable; wire [PORT_COUNT-1:0] eth_tx_status; +wire [PORT_COUNT-1:0] eth_tx_lfc_en; +wire [PORT_COUNT-1:0] eth_tx_lfc_req; +wire [PORT_COUNT*8-1:0] eth_tx_pfc_en; +wire [PORT_COUNT*8-1:0] eth_tx_pfc_req; wire [PORT_COUNT-1:0] eth_rx_clk; wire [PORT_COUNT-1:0] eth_rx_rst; @@ -797,7 +830,14 @@ wire [PORT_COUNT-1:0] axis_eth_rx_tready; wire [PORT_COUNT-1:0] axis_eth_rx_tlast; wire [PORT_COUNT*AXIS_ETH_RX_USER_WIDTH-1:0] axis_eth_rx_tuser; +wire [PORT_COUNT-1:0] eth_rx_enable; wire [PORT_COUNT-1:0] eth_rx_status; +wire [PORT_COUNT-1:0] eth_rx_lfc_en; +wire [PORT_COUNT-1:0] eth_rx_lfc_req; +wire [PORT_COUNT-1:0] eth_rx_lfc_ack; +wire [PORT_COUNT*8-1:0] eth_rx_pfc_en; +wire [PORT_COUNT*8-1:0] eth_rx_pfc_req; +wire [PORT_COUNT*8-1:0] eth_rx_pfc_ack; wire [PTP_TS_WIDTH-1:0] qsfp0_tx_ptp_time_int; wire [PTP_TS_WIDTH-1:0] qsfp1_tx_ptp_time_int; @@ -848,7 +888,12 @@ mqnic_port_map_mac_axis_inst ( .s_axis_mac_tx_ptp_ts_valid({qsfp1_tx_ptp_ts_valid, qsfp0_tx_ptp_ts_valid}), .s_axis_mac_tx_ptp_ts_ready(), + .mac_tx_enable({qsfp1_tx_enable, qsfp0_tx_enable}), .mac_tx_status(2'b11), + .mac_tx_lfc_en({qsfp1_tx_lfc_en, qsfp0_tx_lfc_en}), + .mac_tx_lfc_req({qsfp1_tx_lfc_req, qsfp0_tx_lfc_req}), + .mac_tx_pfc_en({qsfp1_tx_pfc_en, qsfp0_tx_pfc_en}), + .mac_tx_pfc_req({qsfp1_tx_pfc_req, qsfp0_tx_pfc_req}), .mac_rx_clk({qsfp1_rx_clk, qsfp0_rx_clk}), .mac_rx_rst({qsfp1_rx_rst, qsfp0_rx_rst}), @@ -865,7 +910,14 @@ mqnic_port_map_mac_axis_inst ( .s_axis_mac_rx_tlast({qsfp1_rx_axis_tlast, qsfp0_rx_axis_tlast}), .s_axis_mac_rx_tuser({{qsfp1_rx_axis_tuser[80:1], 16'd0, qsfp1_rx_axis_tuser[0]}, {qsfp0_rx_axis_tuser[80:1], 16'd0, qsfp0_rx_axis_tuser[0]}}), + .mac_rx_enable({qsfp1_rx_enable, qsfp0_rx_enable}), .mac_rx_status({qsfp1_rx_status, qsfp0_rx_status}), + .mac_rx_lfc_en({qsfp1_rx_lfc_en, qsfp0_rx_lfc_en}), + .mac_rx_lfc_req({qsfp1_rx_lfc_req, qsfp0_rx_lfc_req}), + .mac_rx_lfc_ack({qsfp1_rx_lfc_ack, qsfp0_rx_lfc_ack}), + .mac_rx_pfc_en({qsfp1_rx_pfc_en, qsfp0_rx_pfc_en}), + .mac_rx_pfc_req({qsfp1_rx_pfc_req, qsfp0_rx_pfc_req}), + .mac_rx_pfc_ack({qsfp1_rx_pfc_ack, qsfp0_rx_pfc_ack}), // towards datapath .tx_clk(eth_tx_clk), @@ -888,7 +940,12 @@ mqnic_port_map_mac_axis_inst ( .m_axis_tx_ptp_ts_valid(axis_eth_tx_ptp_ts_valid), .m_axis_tx_ptp_ts_ready(axis_eth_tx_ptp_ts_ready), + .tx_enable(eth_tx_enable), .tx_status(eth_tx_status), + .tx_lfc_en(eth_tx_lfc_en), + .tx_lfc_req(eth_tx_lfc_req), + .tx_pfc_en(eth_tx_pfc_en), + .tx_pfc_req(eth_tx_pfc_req), .rx_clk(eth_rx_clk), .rx_rst(eth_rx_rst), @@ -905,7 +962,14 @@ mqnic_port_map_mac_axis_inst ( .m_axis_rx_tlast(axis_eth_rx_tlast), .m_axis_rx_tuser(axis_eth_rx_tuser), - .rx_status(eth_rx_status) + .rx_enable(eth_rx_enable), + .rx_status(eth_rx_status), + .rx_lfc_en(eth_rx_lfc_en), + .rx_lfc_req(eth_rx_lfc_req), + .rx_lfc_ack(eth_rx_lfc_ack), + .rx_pfc_en(eth_rx_pfc_en), + .rx_pfc_req(eth_rx_pfc_req), + .rx_pfc_ack(eth_rx_pfc_ack) ); mqnic_core_pcie_us #( @@ -975,6 +1039,9 @@ mqnic_core_pcie_us #( .TX_CHECKSUM_ENABLE(TX_CHECKSUM_ENABLE), .RX_HASH_ENABLE(RX_HASH_ENABLE), .RX_CHECKSUM_ENABLE(RX_CHECKSUM_ENABLE), + .PFC_ENABLE(PFC_ENABLE), + .LFC_ENABLE(LFC_ENABLE), + .MAC_CTRL_ENABLE(0), .TX_FIFO_DEPTH(TX_FIFO_DEPTH), .RX_FIFO_DEPTH(RX_FIFO_DEPTH), .MAX_TX_SIZE(MAX_TX_SIZE), @@ -1271,7 +1338,13 @@ core_inst ( .s_axis_eth_tx_cpl_valid(axis_eth_tx_ptp_ts_valid), .s_axis_eth_tx_cpl_ready(axis_eth_tx_ptp_ts_ready), + .eth_tx_enable(eth_tx_enable), .eth_tx_status(eth_tx_status), + .eth_tx_lfc_en(eth_tx_lfc_en), + .eth_tx_lfc_req(eth_tx_lfc_req), + .eth_tx_pfc_en(eth_tx_pfc_en), + .eth_tx_pfc_req(eth_tx_pfc_req), + .eth_tx_fc_quanta_clk_en(0), .eth_rx_clk(eth_rx_clk), .eth_rx_rst(eth_rx_rst), @@ -1288,7 +1361,15 @@ core_inst ( .s_axis_eth_rx_tlast(axis_eth_rx_tlast), .s_axis_eth_rx_tuser(axis_eth_rx_tuser), + .eth_rx_enable(eth_rx_enable), .eth_rx_status(eth_rx_status), + .eth_rx_lfc_en(eth_rx_lfc_en), + .eth_rx_lfc_req(eth_rx_lfc_req), + .eth_rx_lfc_ack(eth_rx_lfc_ack), + .eth_rx_pfc_en(eth_rx_pfc_en), + .eth_rx_pfc_req(eth_rx_pfc_req), + .eth_rx_pfc_ack(eth_rx_pfc_ack), + .eth_rx_fc_quanta_clk_en(0), /* * DDR diff --git a/fpga/mqnic/AU280/fpga_100g/tb/fpga_core/Makefile b/fpga/mqnic/AU280/fpga_100g/tb/fpga_core/Makefile index 67b393f14..2f8a0cc7e 100644 --- a/fpga/mqnic/AU280/fpga_100g/tb/fpga_core/Makefile +++ b/fpga/mqnic/AU280/fpga_100g/tb/fpga_core/Makefile @@ -161,6 +161,8 @@ export PARAM_TX_CPL_FIFO_DEPTH := 32 export PARAM_TX_CHECKSUM_ENABLE := 1 export PARAM_RX_HASH_ENABLE := 1 export PARAM_RX_CHECKSUM_ENABLE := 1 +export PARAM_LFC_ENABLE := 1 +export PARAM_PFC_ENABLE := $(PARAM_LFC_ENABLE) export PARAM_TX_FIFO_DEPTH := 32768 export PARAM_RX_FIFO_DEPTH := 131072 export PARAM_MAX_TX_SIZE := 9214 diff --git a/fpga/mqnic/AU280/fpga_100g/tb/fpga_core/test_fpga_core.py b/fpga/mqnic/AU280/fpga_100g/tb/fpga_core/test_fpga_core.py index 3bd366155..48d175ed2 100644 --- a/fpga/mqnic/AU280/fpga_100g/tb/fpga_core/test_fpga_core.py +++ b/fpga/mqnic/AU280/fpga_100g/tb/fpga_core/test_fpga_core.py @@ -300,6 +300,8 @@ class TB(object): self.qsfp_mac.append(mac) getattr(dut, f"qsfp{k}_rx_status").setimmediatevalue(1) + getattr(dut, f"qsfp{k}_rx_lfc_req").setimmediatevalue(0) + getattr(dut, f"qsfp{k}_rx_pfc_req").setimmediatevalue(0) cocotb.start_soon(Clock(getattr(dut, f"qsfp{k}_drp_clk"), 8, units="ns").start()) getattr(dut, f"qsfp{k}_drp_rst").setimmediatevalue(0) @@ -715,6 +717,8 @@ def test_fpga_core(request): parameters['TX_CHECKSUM_ENABLE'] = 1 parameters['RX_HASH_ENABLE'] = 1 parameters['RX_CHECKSUM_ENABLE'] = 1 + parameters['LFC_ENABLE'] = 1 + parameters['PFC_ENABLE'] = parameters['LFC_ENABLE'] parameters['TX_FIFO_DEPTH'] = 32768 parameters['RX_FIFO_DEPTH'] = 131072 parameters['MAX_TX_SIZE'] = 9214 diff --git a/fpga/mqnic/AU280/fpga_25g/fpga/Makefile b/fpga/mqnic/AU280/fpga_25g/fpga/Makefile index 3ae84fcc1..f838d19e0 100644 --- a/fpga/mqnic/AU280/fpga_25g/fpga/Makefile +++ b/fpga/mqnic/AU280/fpga_25g/fpga/Makefile @@ -61,6 +61,10 @@ SYN_FILES += rtl/common/tdma_ber_ch.v SYN_FILES += lib/eth/rtl/eth_mac_10g.v SYN_FILES += lib/eth/rtl/axis_xgmii_rx_64.v SYN_FILES += lib/eth/rtl/axis_xgmii_tx_64.v +SYN_FILES += lib/eth/rtl/mac_ctrl_rx.v +SYN_FILES += lib/eth/rtl/mac_ctrl_tx.v +SYN_FILES += lib/eth/rtl/mac_pause_ctrl_rx.v +SYN_FILES += lib/eth/rtl/mac_pause_ctrl_tx.v SYN_FILES += lib/eth/rtl/eth_phy_10g.v SYN_FILES += lib/eth/rtl/eth_phy_10g_rx.v SYN_FILES += lib/eth/rtl/eth_phy_10g_rx_if.v diff --git a/fpga/mqnic/AU280/fpga_25g/fpga/config.tcl b/fpga/mqnic/AU280/fpga_25g/fpga/config.tcl index c06962a61..bd506d862 100644 --- a/fpga/mqnic/AU280/fpga_25g/fpga/config.tcl +++ b/fpga/mqnic/AU280/fpga_25g/fpga/config.tcl @@ -113,6 +113,8 @@ dict set params TX_CPL_FIFO_DEPTH "32" dict set params TX_CHECKSUM_ENABLE "1" dict set params RX_HASH_ENABLE "1" dict set params RX_CHECKSUM_ENABLE "1" +dict set params PFC_ENABLE "1" +dict set params LFC_ENABLE [dict get $params PFC_ENABLE] dict set params ENABLE_PADDING "1" dict set params ENABLE_DIC "1" dict set params MIN_FRAME_LENGTH "64" diff --git a/fpga/mqnic/AU280/fpga_25g/fpga_10g/Makefile b/fpga/mqnic/AU280/fpga_25g/fpga_10g/Makefile index 3ae84fcc1..f838d19e0 100644 --- a/fpga/mqnic/AU280/fpga_25g/fpga_10g/Makefile +++ b/fpga/mqnic/AU280/fpga_25g/fpga_10g/Makefile @@ -61,6 +61,10 @@ SYN_FILES += rtl/common/tdma_ber_ch.v SYN_FILES += lib/eth/rtl/eth_mac_10g.v SYN_FILES += lib/eth/rtl/axis_xgmii_rx_64.v SYN_FILES += lib/eth/rtl/axis_xgmii_tx_64.v +SYN_FILES += lib/eth/rtl/mac_ctrl_rx.v +SYN_FILES += lib/eth/rtl/mac_ctrl_tx.v +SYN_FILES += lib/eth/rtl/mac_pause_ctrl_rx.v +SYN_FILES += lib/eth/rtl/mac_pause_ctrl_tx.v SYN_FILES += lib/eth/rtl/eth_phy_10g.v SYN_FILES += lib/eth/rtl/eth_phy_10g_rx.v SYN_FILES += lib/eth/rtl/eth_phy_10g_rx_if.v diff --git a/fpga/mqnic/AU280/fpga_25g/fpga_10g/config.tcl b/fpga/mqnic/AU280/fpga_25g/fpga_10g/config.tcl index 720ebded5..0b31e7e85 100644 --- a/fpga/mqnic/AU280/fpga_25g/fpga_10g/config.tcl +++ b/fpga/mqnic/AU280/fpga_25g/fpga_10g/config.tcl @@ -113,6 +113,8 @@ dict set params TX_CPL_FIFO_DEPTH "32" dict set params TX_CHECKSUM_ENABLE "1" dict set params RX_HASH_ENABLE "1" dict set params RX_CHECKSUM_ENABLE "1" +dict set params PFC_ENABLE "1" +dict set params LFC_ENABLE [dict get $params PFC_ENABLE] dict set params ENABLE_PADDING "1" dict set params ENABLE_DIC "1" dict set params MIN_FRAME_LENGTH "64" diff --git a/fpga/mqnic/AU280/fpga_25g/rtl/fpga.v b/fpga/mqnic/AU280/fpga_25g/rtl/fpga.v index 4eab1d9ed..be42e650f 100644 --- a/fpga/mqnic/AU280/fpga_25g/rtl/fpga.v +++ b/fpga/mqnic/AU280/fpga_25g/rtl/fpga.v @@ -74,6 +74,8 @@ module fpga # parameter TX_CHECKSUM_ENABLE = 1, parameter RX_HASH_ENABLE = 1, parameter RX_CHECKSUM_ENABLE = 1, + parameter PFC_ENABLE = 1, + parameter LFC_ENABLE = PFC_ENABLE, parameter ENABLE_PADDING = 1, parameter ENABLE_DIC = 1, parameter MIN_FRAME_LENGTH = 64, @@ -3272,6 +3274,8 @@ fpga_core #( .TX_CHECKSUM_ENABLE(TX_CHECKSUM_ENABLE), .RX_HASH_ENABLE(RX_HASH_ENABLE), .RX_CHECKSUM_ENABLE(RX_CHECKSUM_ENABLE), + .PFC_ENABLE(PFC_ENABLE), + .LFC_ENABLE(LFC_ENABLE), .ENABLE_PADDING(ENABLE_PADDING), .ENABLE_DIC(ENABLE_DIC), .MIN_FRAME_LENGTH(MIN_FRAME_LENGTH), diff --git a/fpga/mqnic/AU280/fpga_25g/rtl/fpga_core.v b/fpga/mqnic/AU280/fpga_25g/rtl/fpga_core.v index 0beec0e05..6a0adfc31 100644 --- a/fpga/mqnic/AU280/fpga_25g/rtl/fpga_core.v +++ b/fpga/mqnic/AU280/fpga_25g/rtl/fpga_core.v @@ -81,6 +81,8 @@ module fpga_core # parameter TX_CHECKSUM_ENABLE = 1, parameter RX_HASH_ENABLE = 1, parameter RX_CHECKSUM_ENABLE = 1, + parameter PFC_ENABLE = 1, + parameter LFC_ENABLE = PFC_ENABLE, parameter ENABLE_PADDING = 1, parameter ENABLE_DIC = 1, parameter MIN_FRAME_LENGTH = 64, @@ -922,7 +924,12 @@ wire [PORT_COUNT*TX_TAG_WIDTH-1:0] axis_eth_tx_ptp_ts_tag; wire [PORT_COUNT-1:0] axis_eth_tx_ptp_ts_valid; wire [PORT_COUNT-1:0] axis_eth_tx_ptp_ts_ready; +wire [PORT_COUNT-1:0] eth_tx_enable; wire [PORT_COUNT-1:0] eth_tx_status; +wire [PORT_COUNT-1:0] eth_tx_lfc_en; +wire [PORT_COUNT-1:0] eth_tx_lfc_req; +wire [PORT_COUNT*8-1:0] eth_tx_pfc_en; +wire [PORT_COUNT*8-1:0] eth_tx_pfc_req; wire [PORT_COUNT-1:0] eth_rx_clk; wire [PORT_COUNT-1:0] eth_rx_rst; @@ -937,7 +944,14 @@ wire [PORT_COUNT-1:0] axis_eth_rx_tready; wire [PORT_COUNT-1:0] axis_eth_rx_tlast; wire [PORT_COUNT*AXIS_ETH_RX_USER_WIDTH-1:0] axis_eth_rx_tuser; +wire [PORT_COUNT-1:0] eth_rx_enable; wire [PORT_COUNT-1:0] eth_rx_status; +wire [PORT_COUNT-1:0] eth_rx_lfc_en; +wire [PORT_COUNT-1:0] eth_rx_lfc_req; +wire [PORT_COUNT-1:0] eth_rx_lfc_ack; +wire [PORT_COUNT*8-1:0] eth_rx_pfc_en; +wire [PORT_COUNT*8-1:0] eth_rx_pfc_req; +wire [PORT_COUNT*8-1:0] eth_rx_pfc_ack; wire [PORT_COUNT-1:0] port_xgmii_tx_clk; wire [PORT_COUNT-1:0] port_xgmii_tx_rst; @@ -1010,12 +1024,15 @@ generate .PTP_PERIOD_FNS(IF_PTP_PERIOD_FNS), .TX_PTP_TS_ENABLE(PTP_TS_ENABLE), .TX_PTP_TS_WIDTH(PTP_TS_WIDTH), + .TX_PTP_TS_CTRL_IN_TUSER(0), .TX_PTP_TAG_ENABLE(PTP_TS_ENABLE), .TX_PTP_TAG_WIDTH(TX_TAG_WIDTH), .RX_PTP_TS_ENABLE(PTP_TS_ENABLE), .RX_PTP_TS_WIDTH(PTP_TS_WIDTH), .TX_USER_WIDTH(AXIS_ETH_TX_USER_WIDTH), - .RX_USER_WIDTH(AXIS_ETH_RX_USER_WIDTH) + .RX_USER_WIDTH(AXIS_ETH_RX_USER_WIDTH), + .PFC_ENABLE(PFC_ENABLE), + .PAUSE_ENABLE(LFC_ENABLE) ) eth_mac_inst ( .tx_clk(port_xgmii_tx_clk[n]), @@ -1023,6 +1040,9 @@ generate .rx_clk(port_xgmii_rx_clk[n]), .rx_rst(port_xgmii_rx_rst[n]), + /* + * AXI input + */ .tx_axis_tdata(axis_eth_tx_tdata[n*AXIS_ETH_DATA_WIDTH +: AXIS_ETH_DATA_WIDTH]), .tx_axis_tkeep(axis_eth_tx_tkeep[n*AXIS_ETH_KEEP_WIDTH +: AXIS_ETH_KEEP_WIDTH]), .tx_axis_tvalid(axis_eth_tx_tvalid[n +: 1]), @@ -1030,30 +1050,121 @@ generate .tx_axis_tlast(axis_eth_tx_tlast[n +: 1]), .tx_axis_tuser(axis_eth_tx_tuser[n*AXIS_ETH_TX_USER_WIDTH +: AXIS_ETH_TX_USER_WIDTH]), + /* + * AXI output + */ .rx_axis_tdata(axis_eth_rx_tdata[n*AXIS_ETH_DATA_WIDTH +: AXIS_ETH_DATA_WIDTH]), .rx_axis_tkeep(axis_eth_rx_tkeep[n*AXIS_ETH_KEEP_WIDTH +: AXIS_ETH_KEEP_WIDTH]), .rx_axis_tvalid(axis_eth_rx_tvalid[n +: 1]), .rx_axis_tlast(axis_eth_rx_tlast[n +: 1]), .rx_axis_tuser(axis_eth_rx_tuser[n*AXIS_ETH_RX_USER_WIDTH +: AXIS_ETH_RX_USER_WIDTH]), + /* + * XGMII interface + */ .xgmii_rxd(port_xgmii_rxd[n*XGMII_DATA_WIDTH +: XGMII_DATA_WIDTH]), .xgmii_rxc(port_xgmii_rxc[n*XGMII_CTRL_WIDTH +: XGMII_CTRL_WIDTH]), .xgmii_txd(port_xgmii_txd[n*XGMII_DATA_WIDTH +: XGMII_DATA_WIDTH]), .xgmii_txc(port_xgmii_txc[n*XGMII_CTRL_WIDTH +: XGMII_CTRL_WIDTH]), + /* + * PTP + */ .tx_ptp_ts(eth_tx_ptp_ts_96[n*PTP_TS_WIDTH +: PTP_TS_WIDTH]), .rx_ptp_ts(eth_rx_ptp_ts_96[n*PTP_TS_WIDTH +: PTP_TS_WIDTH]), .tx_axis_ptp_ts(axis_eth_tx_ptp_ts[n*PTP_TS_WIDTH +: PTP_TS_WIDTH]), .tx_axis_ptp_ts_tag(axis_eth_tx_ptp_ts_tag[n*TX_TAG_WIDTH +: TX_TAG_WIDTH]), .tx_axis_ptp_ts_valid(axis_eth_tx_ptp_ts_valid[n +: 1]), + /* + * Link-level Flow Control (LFC) (IEEE 802.3 annex 31B PAUSE) + */ + .tx_lfc_req(eth_tx_lfc_req[n +: 1]), + .tx_lfc_resend(1'b0), + .rx_lfc_en(eth_rx_lfc_en[n +: 1]), + .rx_lfc_req(eth_rx_lfc_req[n +: 1]), + .rx_lfc_ack(eth_rx_lfc_ack[n +: 1]), + + /* + * Priority Flow Control (PFC) (IEEE 802.3 annex 31D PFC) + */ + .tx_pfc_req(eth_tx_pfc_req[n*8 +: 8]), + .tx_pfc_resend(1'b0), + .rx_pfc_en(eth_rx_pfc_en[n*8 +: 8]), + .rx_pfc_req(eth_rx_pfc_req[n*8 +: 8]), + .rx_pfc_ack(eth_rx_pfc_ack[n*8 +: 8]), + + /* + * Pause interface + */ + .tx_lfc_pause_en(1'b1), + .tx_pause_req(1'b0), + .tx_pause_ack(), + + /* + * Status + */ + .tx_start_packet(), .tx_error_underflow(), + .rx_start_packet(), .rx_error_bad_frame(), .rx_error_bad_fcs(), + .stat_tx_mcf(), + .stat_rx_mcf(), + .stat_tx_lfc_pkt(), + .stat_tx_lfc_xon(), + .stat_tx_lfc_xoff(), + .stat_tx_lfc_paused(), + .stat_tx_pfc_pkt(), + .stat_tx_pfc_xon(), + .stat_tx_pfc_xoff(), + .stat_tx_pfc_paused(), + .stat_rx_lfc_pkt(), + .stat_rx_lfc_xon(), + .stat_rx_lfc_xoff(), + .stat_rx_lfc_paused(), + .stat_rx_pfc_pkt(), + .stat_rx_pfc_xon(), + .stat_rx_pfc_xoff(), + .stat_rx_pfc_paused(), + /* + * Configuration + */ .cfg_ifg(8'd12), - .cfg_tx_enable(1'b1), - .cfg_rx_enable(1'b1) + .cfg_tx_enable(eth_tx_enable[n +: 1]), + .cfg_rx_enable(eth_rx_enable[n +: 1]), + .cfg_mcf_rx_eth_dst_mcast(48'h01_80_C2_00_00_01), + .cfg_mcf_rx_check_eth_dst_mcast(1'b1), + .cfg_mcf_rx_eth_dst_ucast(48'd0), + .cfg_mcf_rx_check_eth_dst_ucast(1'b0), + .cfg_mcf_rx_eth_src(48'd0), + .cfg_mcf_rx_check_eth_src(1'b0), + .cfg_mcf_rx_eth_type(16'h8808), + .cfg_mcf_rx_opcode_lfc(16'h0001), + .cfg_mcf_rx_check_opcode_lfc(eth_rx_lfc_en[n +: 1]), + .cfg_mcf_rx_opcode_pfc(16'h0101), + .cfg_mcf_rx_check_opcode_pfc(eth_rx_pfc_en[n*8 +: 8] != 0), + .cfg_mcf_rx_forward(1'b0), + .cfg_mcf_rx_enable(eth_rx_lfc_en[n +: 1] || eth_rx_pfc_en[n*8 +: 8]), + .cfg_tx_lfc_eth_dst(48'h01_80_C2_00_00_01), + .cfg_tx_lfc_eth_src(48'h80_23_31_43_54_4C), + .cfg_tx_lfc_eth_type(16'h8808), + .cfg_tx_lfc_opcode(16'h0001), + .cfg_tx_lfc_en(eth_tx_lfc_en[n +: 1]), + .cfg_tx_lfc_quanta(16'hffff), + .cfg_tx_lfc_refresh(16'h7fff), + .cfg_tx_pfc_eth_dst(48'h01_80_C2_00_00_01), + .cfg_tx_pfc_eth_src(48'h80_23_31_43_54_4C), + .cfg_tx_pfc_eth_type(16'h8808), + .cfg_tx_pfc_opcode(16'h0101), + .cfg_tx_pfc_en(eth_tx_pfc_en[n*8 +: 8] != 0), + .cfg_tx_pfc_quanta({8{16'hffff}}), + .cfg_tx_pfc_refresh({8{16'h7fff}}), + .cfg_rx_lfc_opcode(16'h0001), + .cfg_rx_lfc_en(eth_rx_lfc_en[n +: 1]), + .cfg_rx_pfc_opcode(16'h0101), + .cfg_rx_pfc_en(eth_rx_pfc_en[n*8 +: 8] != 0) ); end @@ -1127,6 +1238,9 @@ mqnic_core_pcie_us #( .TX_CHECKSUM_ENABLE(TX_CHECKSUM_ENABLE), .RX_HASH_ENABLE(RX_HASH_ENABLE), .RX_CHECKSUM_ENABLE(RX_CHECKSUM_ENABLE), + .PFC_ENABLE(PFC_ENABLE), + .LFC_ENABLE(LFC_ENABLE), + .MAC_CTRL_ENABLE(0), .TX_FIFO_DEPTH(TX_FIFO_DEPTH), .RX_FIFO_DEPTH(RX_FIFO_DEPTH), .MAX_TX_SIZE(MAX_TX_SIZE), @@ -1423,7 +1537,13 @@ core_inst ( .s_axis_eth_tx_cpl_valid(axis_eth_tx_ptp_ts_valid), .s_axis_eth_tx_cpl_ready(axis_eth_tx_ptp_ts_ready), + .eth_tx_enable(eth_tx_enable), .eth_tx_status(eth_tx_status), + .eth_tx_lfc_en(eth_tx_lfc_en), + .eth_tx_lfc_req(eth_tx_lfc_req), + .eth_tx_pfc_en(eth_tx_pfc_en), + .eth_tx_pfc_req(eth_tx_pfc_req), + .eth_tx_fc_quanta_clk_en(0), .eth_rx_clk(eth_rx_clk), .eth_rx_rst(eth_rx_rst), @@ -1440,7 +1560,15 @@ core_inst ( .s_axis_eth_rx_tlast(axis_eth_rx_tlast), .s_axis_eth_rx_tuser(axis_eth_rx_tuser), + .eth_rx_enable(eth_rx_enable), .eth_rx_status(eth_rx_status), + .eth_rx_lfc_en(eth_rx_lfc_en), + .eth_rx_lfc_req(eth_rx_lfc_req), + .eth_rx_lfc_ack(eth_rx_lfc_ack), + .eth_rx_pfc_en(eth_rx_pfc_en), + .eth_rx_pfc_req(eth_rx_pfc_req), + .eth_rx_pfc_ack(eth_rx_pfc_ack), + .eth_rx_fc_quanta_clk_en(0), /* * DDR diff --git a/fpga/mqnic/AU280/fpga_25g/tb/fpga_core/Makefile b/fpga/mqnic/AU280/fpga_25g/tb/fpga_core/Makefile index 474d63215..be03d8c5d 100644 --- a/fpga/mqnic/AU280/fpga_25g/tb/fpga_core/Makefile +++ b/fpga/mqnic/AU280/fpga_25g/tb/fpga_core/Makefile @@ -62,6 +62,10 @@ VERILOG_SOURCES += ../../rtl/common/tdma_ber_ch.v VERILOG_SOURCES += ../../lib/eth/rtl/eth_mac_10g.v VERILOG_SOURCES += ../../lib/eth/rtl/axis_xgmii_rx_64.v VERILOG_SOURCES += ../../lib/eth/rtl/axis_xgmii_tx_64.v +VERILOG_SOURCES += ../../lib/eth/rtl/mac_ctrl_rx.v +VERILOG_SOURCES += ../../lib/eth/rtl/mac_ctrl_tx.v +VERILOG_SOURCES += ../../lib/eth/rtl/mac_pause_ctrl_rx.v +VERILOG_SOURCES += ../../lib/eth/rtl/mac_pause_ctrl_tx.v VERILOG_SOURCES += ../../lib/eth/rtl/lfsr.v VERILOG_SOURCES += ../../lib/eth/rtl/ptp_clock.v VERILOG_SOURCES += ../../lib/eth/rtl/ptp_clock_cdc.v @@ -167,6 +171,8 @@ export PARAM_TX_CPL_FIFO_DEPTH := 32 export PARAM_TX_CHECKSUM_ENABLE := 1 export PARAM_RX_HASH_ENABLE := 1 export PARAM_RX_CHECKSUM_ENABLE := 1 +export PARAM_LFC_ENABLE := 1 +export PARAM_PFC_ENABLE := $(PARAM_LFC_ENABLE) export PARAM_TX_FIFO_DEPTH := 32768 export PARAM_RX_FIFO_DEPTH := 32768 export PARAM_MAX_TX_SIZE := 9214 diff --git a/fpga/mqnic/AU280/fpga_25g/tb/fpga_core/test_fpga_core.py b/fpga/mqnic/AU280/fpga_25g/tb/fpga_core/test_fpga_core.py index 72cf3220e..cba21d76e 100644 --- a/fpga/mqnic/AU280/fpga_25g/tb/fpga_core/test_fpga_core.py +++ b/fpga/mqnic/AU280/fpga_25g/tb/fpga_core/test_fpga_core.py @@ -3,6 +3,7 @@ import logging import os +import struct import sys import scapy.utils @@ -17,7 +18,7 @@ from cocotb.clock import Clock from cocotb.triggers import RisingEdge, FallingEdge, Timer from cocotbext.axi import AxiStreamBus, AxiLiteBus, AxiLiteRam -from cocotbext.eth import XgmiiSource, XgmiiSink +from cocotbext.eth import XgmiiSource, XgmiiSink, XgmiiFrame from cocotbext.pcie.core import RootComplex from cocotbext.pcie.xilinx.us import UltraScalePlusPcieDevice @@ -520,6 +521,35 @@ async def run_test_nic(dut): tb.loopback_enable = False + if tb.driver.interfaces[0].if_feature_lfc: + tb.log.info("Test LFC pause frame RX") + + await tb.driver.interfaces[0].ports[0].set_lfc_ctrl(mqnic.MQNIC_PORT_LFC_CTRL_TX_LFC_EN | mqnic.MQNIC_PORT_LFC_CTRL_RX_LFC_EN) + await tb.driver.hw_regs.read_dword(0) + + lfc_xoff = Ether(src='DA:D1:D2:D3:D4:D5', dst='01:80:C2:00:00:01', type=0x8808) / struct.pack('!HH', 0x0001, 2000) + + await tb.qsfp_source[0][0].send(XgmiiFrame.from_payload(bytes(lfc_xoff))) + + count = 16 + + pkts = [bytearray([(x+k) % 256 for x in range(1514)]) for k in range(count)] + + tb.loopback_enable = True + + for p in pkts: + await tb.driver.interfaces[0].start_xmit(p, 0) + + for k in range(count): + pkt = await tb.driver.interfaces[0].recv() + + tb.log.info("Packet: %s", pkt) + assert pkt.data == pkts[k] + if tb.driver.interfaces[0].if_feature_rx_csum: + assert pkt.rx_checksum == ~scapy.utils.checksum(bytes(pkt.data[14:])) & 0xffff + + tb.loopback_enable = False + await RisingEdge(dut.clk_250mhz) await RisingEdge(dut.clk_250mhz) @@ -592,6 +622,10 @@ def test_fpga_core(request): os.path.join(eth_rtl_dir, "eth_mac_10g.v"), os.path.join(eth_rtl_dir, "axis_xgmii_rx_64.v"), os.path.join(eth_rtl_dir, "axis_xgmii_tx_64.v"), + os.path.join(eth_rtl_dir, "mac_ctrl_rx.v"), + os.path.join(eth_rtl_dir, "mac_ctrl_tx.v"), + os.path.join(eth_rtl_dir, "mac_pause_ctrl_rx.v"), + os.path.join(eth_rtl_dir, "mac_pause_ctrl_tx.v"), os.path.join(eth_rtl_dir, "lfsr.v"), os.path.join(eth_rtl_dir, "ptp_clock.v"), os.path.join(eth_rtl_dir, "ptp_clock_cdc.v"), @@ -698,6 +732,8 @@ def test_fpga_core(request): parameters['TX_CHECKSUM_ENABLE'] = 1 parameters['RX_HASH_ENABLE'] = 1 parameters['RX_CHECKSUM_ENABLE'] = 1 + parameters['LFC_ENABLE'] = 1 + parameters['PFC_ENABLE'] = parameters['LFC_ENABLE'] parameters['TX_FIFO_DEPTH'] = 32768 parameters['RX_FIFO_DEPTH'] = 32768 parameters['MAX_TX_SIZE'] = 9214 diff --git a/fpga/mqnic/AU50/fpga_100g/fpga/config.tcl b/fpga/mqnic/AU50/fpga_100g/fpga/config.tcl index 0b5c537b7..de975787d 100644 --- a/fpga/mqnic/AU50/fpga_100g/fpga/config.tcl +++ b/fpga/mqnic/AU50/fpga_100g/fpga/config.tcl @@ -101,6 +101,8 @@ dict set params TX_CPL_FIFO_DEPTH "32" dict set params TX_CHECKSUM_ENABLE "1" dict set params RX_HASH_ENABLE "1" dict set params RX_CHECKSUM_ENABLE "1" +dict set params PFC_ENABLE "1" +dict set params LFC_ENABLE [dict get $params PFC_ENABLE] dict set params TX_FIFO_DEPTH "32768" dict set params RX_FIFO_DEPTH "131072" dict set params MAX_TX_SIZE "9214" diff --git a/fpga/mqnic/AU50/fpga_100g/fpga_app_dma_bench/config.tcl b/fpga/mqnic/AU50/fpga_100g/fpga_app_dma_bench/config.tcl index ecd786950..930d45d2b 100644 --- a/fpga/mqnic/AU50/fpga_100g/fpga_app_dma_bench/config.tcl +++ b/fpga/mqnic/AU50/fpga_100g/fpga_app_dma_bench/config.tcl @@ -101,6 +101,8 @@ dict set params TX_CPL_FIFO_DEPTH "32" dict set params TX_CHECKSUM_ENABLE "1" dict set params RX_HASH_ENABLE "1" dict set params RX_CHECKSUM_ENABLE "1" +dict set params PFC_ENABLE "1" +dict set params LFC_ENABLE [dict get $params PFC_ENABLE] dict set params TX_FIFO_DEPTH "32768" dict set params RX_FIFO_DEPTH "131072" dict set params MAX_TX_SIZE "9214" diff --git a/fpga/mqnic/AU50/fpga_100g/ip/cmac_usplus.tcl b/fpga/mqnic/AU50/fpga_100g/ip/cmac_usplus.tcl index b86d4ea5e..af9cc8265 100644 --- a/fpga/mqnic/AU50/fpga_100g/ip/cmac_usplus.tcl +++ b/fpga/mqnic/AU50/fpga_100g/ip/cmac_usplus.tcl @@ -7,8 +7,10 @@ set_property -dict [list \ CONFIG.USER_INTERFACE {AXIS} \ CONFIG.GT_DRP_CLK {125} \ CONFIG.GT_LOCATION {0} \ - CONFIG.TX_FLOW_CONTROL {0} \ - CONFIG.RX_FLOW_CONTROL {0} \ + CONFIG.TX_FLOW_CONTROL {1} \ + CONFIG.RX_FLOW_CONTROL {1} \ + CONFIG.RX_FORWARD_CONTROL_FRAMES {0} \ + CONFIG.RX_CHECK_ACK {1} \ CONFIG.INCLUDE_RS_FEC {1} \ CONFIG.ENABLE_TIME_STAMPING {1} ] [get_ips cmac_usplus] diff --git a/fpga/mqnic/AU50/fpga_100g/rtl/fpga.v b/fpga/mqnic/AU50/fpga_100g/rtl/fpga.v index fbcbecf60..3ed345f0a 100644 --- a/fpga/mqnic/AU50/fpga_100g/rtl/fpga.v +++ b/fpga/mqnic/AU50/fpga_100g/rtl/fpga.v @@ -71,6 +71,8 @@ module fpga # parameter TX_CHECKSUM_ENABLE = 1, parameter RX_HASH_ENABLE = 1, parameter RX_CHECKSUM_ENABLE = 1, + parameter PFC_ENABLE = 1, + parameter LFC_ENABLE = PFC_ENABLE, parameter TX_FIFO_DEPTH = 32768, parameter RX_FIFO_DEPTH = 131072, parameter MAX_TX_SIZE = 9214, @@ -938,7 +940,20 @@ wire qsfp_drp_we; wire [15:0] qsfp_drp_do; wire qsfp_drp_rdy; -wire qsfp_rx_status; +wire qsfp_tx_enable; +wire qsfp_tx_lfc_en; +wire qsfp_tx_lfc_req; +wire [7:0] qsfp_tx_pfc_en; +wire [7:0] qsfp_tx_pfc_req; + +wire qsfp_rx_enable; +wire qsfp_rx_status; +wire qsfp_rx_lfc_en; +wire qsfp_rx_lfc_req; +wire qsfp_rx_lfc_ack; +wire [7:0] qsfp_rx_pfc_en; +wire [7:0] qsfp_rx_pfc_req; +wire [7:0] qsfp_rx_pfc_ack; wire qsfp_gtpowergood; @@ -1033,6 +1048,12 @@ qsfp_cmac_inst ( .tx_ptp_ts_tag(qsfp_tx_ptp_ts_tag_int), .tx_ptp_ts_valid(qsfp_tx_ptp_ts_valid_int), + .tx_enable(qsfp_tx_enable), + .tx_lfc_en(qsfp_tx_lfc_en), + .tx_lfc_req(qsfp_tx_lfc_req), + .tx_pfc_en(qsfp_tx_pfc_en), + .tx_pfc_req(qsfp_tx_pfc_req), + .rx_clk(qsfp_rx_clk_int), .rx_rst(qsfp_rx_rst_int), @@ -1046,7 +1067,14 @@ qsfp_cmac_inst ( .rx_ptp_rst(qsfp_rx_ptp_rst_int), .rx_ptp_time(qsfp_rx_ptp_time_int), - .rx_status(qsfp_rx_status) + .rx_enable(qsfp_rx_enable), + .rx_status(qsfp_rx_status), + .rx_lfc_en(qsfp_rx_lfc_en), + .rx_lfc_req(qsfp_rx_lfc_req), + .rx_lfc_ack(qsfp_rx_lfc_ack), + .rx_pfc_en(qsfp_rx_pfc_en), + .rx_pfc_req(qsfp_rx_pfc_req), + .rx_pfc_ack(qsfp_rx_pfc_ack) ); wire ptp_clk; @@ -2605,6 +2633,8 @@ fpga_core #( .TX_CHECKSUM_ENABLE(TX_CHECKSUM_ENABLE), .RX_HASH_ENABLE(RX_HASH_ENABLE), .RX_CHECKSUM_ENABLE(RX_CHECKSUM_ENABLE), + .PFC_ENABLE(PFC_ENABLE), + .LFC_ENABLE(LFC_ENABLE), .TX_FIFO_DEPTH(TX_FIFO_DEPTH), .RX_FIFO_DEPTH(RX_FIFO_DEPTH), .MAX_TX_SIZE(MAX_TX_SIZE), @@ -2800,6 +2830,12 @@ core_inst ( .qsfp_tx_ptp_ts_tag(qsfp_tx_ptp_ts_tag_int), .qsfp_tx_ptp_ts_valid(qsfp_tx_ptp_ts_valid_int), + .qsfp_tx_enable(qsfp_tx_enable), + .qsfp_tx_lfc_en(qsfp_tx_lfc_en), + .qsfp_tx_lfc_req(qsfp_tx_lfc_req), + .qsfp_tx_pfc_en(qsfp_tx_pfc_en), + .qsfp_tx_pfc_req(qsfp_tx_pfc_req), + .qsfp_rx_clk(qsfp_rx_clk_int), .qsfp_rx_rst(qsfp_rx_rst_int), .qsfp_rx_axis_tdata(qsfp_rx_axis_tdata_int), @@ -2811,7 +2847,14 @@ core_inst ( .qsfp_rx_ptp_rst(qsfp_rx_ptp_rst_int), .qsfp_rx_ptp_time(qsfp_rx_ptp_time_int), + .qsfp_rx_enable(qsfp_rx_enable), .qsfp_rx_status(qsfp_rx_status), + .qsfp_rx_lfc_en(qsfp_rx_lfc_en), + .qsfp_rx_lfc_req(qsfp_rx_lfc_req), + .qsfp_rx_lfc_ack(qsfp_rx_lfc_ack), + .qsfp_rx_pfc_en(qsfp_rx_pfc_en), + .qsfp_rx_pfc_req(qsfp_rx_pfc_req), + .qsfp_rx_pfc_ack(qsfp_rx_pfc_ack), .qsfp_drp_clk(qsfp_drp_clk), .qsfp_drp_rst(qsfp_drp_rst), diff --git a/fpga/mqnic/AU50/fpga_100g/rtl/fpga_core.v b/fpga/mqnic/AU50/fpga_100g/rtl/fpga_core.v index 4a9ef8cfd..c79db94fe 100644 --- a/fpga/mqnic/AU50/fpga_100g/rtl/fpga_core.v +++ b/fpga/mqnic/AU50/fpga_100g/rtl/fpga_core.v @@ -77,6 +77,8 @@ module fpga_core # parameter TX_CHECKSUM_ENABLE = 1, parameter RX_HASH_ENABLE = 1, parameter RX_CHECKSUM_ENABLE = 1, + parameter PFC_ENABLE = 1, + parameter LFC_ENABLE = PFC_ENABLE, parameter TX_FIFO_DEPTH = 32768, parameter RX_FIFO_DEPTH = 131072, parameter MAX_TX_SIZE = 9214, @@ -274,6 +276,12 @@ module fpga_core # input wire [15:0] qsfp_tx_ptp_ts_tag, input wire qsfp_tx_ptp_ts_valid, + output wire qsfp_tx_enable, + output wire qsfp_tx_lfc_en, + output wire qsfp_tx_lfc_req, + output wire [7:0] qsfp_tx_pfc_en, + output wire [7:0] qsfp_tx_pfc_req, + input wire qsfp_rx_clk, input wire qsfp_rx_rst, @@ -287,7 +295,14 @@ module fpga_core # input wire qsfp_rx_ptp_rst, output wire [79:0] qsfp_rx_ptp_time, + output wire qsfp_rx_enable, input wire qsfp_rx_status, + output wire qsfp_rx_lfc_en, + input wire qsfp_rx_lfc_req, + output wire qsfp_rx_lfc_ack, + output wire [7:0] qsfp_rx_pfc_en, + input wire [7:0] qsfp_rx_pfc_req, + output wire [7:0] qsfp_rx_pfc_ack, input wire qsfp_drp_clk, input wire qsfp_drp_rst, @@ -649,7 +664,12 @@ wire [PORT_COUNT*TX_TAG_WIDTH-1:0] axis_eth_tx_ptp_ts_tag; wire [PORT_COUNT-1:0] axis_eth_tx_ptp_ts_valid; wire [PORT_COUNT-1:0] axis_eth_tx_ptp_ts_ready; +wire [PORT_COUNT-1:0] eth_tx_enable; wire [PORT_COUNT-1:0] eth_tx_status; +wire [PORT_COUNT-1:0] eth_tx_lfc_en; +wire [PORT_COUNT-1:0] eth_tx_lfc_req; +wire [PORT_COUNT*8-1:0] eth_tx_pfc_en; +wire [PORT_COUNT*8-1:0] eth_tx_pfc_req; wire [PORT_COUNT-1:0] eth_rx_clk; wire [PORT_COUNT-1:0] eth_rx_rst; @@ -666,7 +686,14 @@ wire [PORT_COUNT-1:0] axis_eth_rx_tready; wire [PORT_COUNT-1:0] axis_eth_rx_tlast; wire [PORT_COUNT*AXIS_ETH_RX_USER_WIDTH-1:0] axis_eth_rx_tuser; +wire [PORT_COUNT-1:0] eth_rx_enable; wire [PORT_COUNT-1:0] eth_rx_status; +wire [PORT_COUNT-1:0] eth_rx_lfc_en; +wire [PORT_COUNT-1:0] eth_rx_lfc_req; +wire [PORT_COUNT-1:0] eth_rx_lfc_ack; +wire [PORT_COUNT*8-1:0] eth_rx_pfc_en; +wire [PORT_COUNT*8-1:0] eth_rx_pfc_req; +wire [PORT_COUNT*8-1:0] eth_rx_pfc_ack; wire [PTP_TS_WIDTH-1:0] qsfp_tx_ptp_time_int; wire [PTP_TS_WIDTH-1:0] qsfp_rx_ptp_time_int; @@ -713,7 +740,12 @@ mqnic_port_map_mac_axis_inst ( .s_axis_mac_tx_ptp_ts_valid({qsfp_tx_ptp_ts_valid}), .s_axis_mac_tx_ptp_ts_ready(), + .mac_tx_enable({qsfp_tx_enable}), .mac_tx_status(1'b1), + .mac_tx_lfc_en({qsfp_tx_lfc_en}), + .mac_tx_lfc_req({qsfp_tx_lfc_req}), + .mac_tx_pfc_en({qsfp_tx_pfc_en}), + .mac_tx_pfc_req({qsfp_tx_pfc_req}), .mac_rx_clk({qsfp_rx_clk}), .mac_rx_rst({qsfp_rx_rst}), @@ -730,7 +762,14 @@ mqnic_port_map_mac_axis_inst ( .s_axis_mac_rx_tlast({qsfp_rx_axis_tlast}), .s_axis_mac_rx_tuser({{qsfp_rx_axis_tuser[80:1], 16'd0, qsfp_rx_axis_tuser[0]}}), + .mac_rx_enable({qsfp_rx_enable}), .mac_rx_status({qsfp_rx_status}), + .mac_rx_lfc_en({qsfp_rx_lfc_en}), + .mac_rx_lfc_req({qsfp_rx_lfc_req}), + .mac_rx_lfc_ack({qsfp_rx_lfc_ack}), + .mac_rx_pfc_en({qsfp_rx_pfc_en}), + .mac_rx_pfc_req({qsfp_rx_pfc_req}), + .mac_rx_pfc_ack({qsfp_rx_pfc_ack}), // towards datapath .tx_clk(eth_tx_clk), @@ -753,7 +792,12 @@ mqnic_port_map_mac_axis_inst ( .m_axis_tx_ptp_ts_valid(axis_eth_tx_ptp_ts_valid), .m_axis_tx_ptp_ts_ready(axis_eth_tx_ptp_ts_ready), + .tx_enable(eth_tx_enable), .tx_status(eth_tx_status), + .tx_lfc_en(eth_tx_lfc_en), + .tx_lfc_req(eth_tx_lfc_req), + .tx_pfc_en(eth_tx_pfc_en), + .tx_pfc_req(eth_tx_pfc_req), .rx_clk(eth_rx_clk), .rx_rst(eth_rx_rst), @@ -770,7 +814,14 @@ mqnic_port_map_mac_axis_inst ( .m_axis_rx_tlast(axis_eth_rx_tlast), .m_axis_rx_tuser(axis_eth_rx_tuser), - .rx_status(eth_rx_status) + .rx_enable(eth_rx_enable), + .rx_status(eth_rx_status), + .rx_lfc_en(eth_rx_lfc_en), + .rx_lfc_req(eth_rx_lfc_req), + .rx_lfc_ack(eth_rx_lfc_ack), + .rx_pfc_en(eth_rx_pfc_en), + .rx_pfc_req(eth_rx_pfc_req), + .rx_pfc_ack(eth_rx_pfc_ack) ); mqnic_core_pcie_us #( @@ -840,6 +891,9 @@ mqnic_core_pcie_us #( .TX_CHECKSUM_ENABLE(TX_CHECKSUM_ENABLE), .RX_HASH_ENABLE(RX_HASH_ENABLE), .RX_CHECKSUM_ENABLE(RX_CHECKSUM_ENABLE), + .PFC_ENABLE(PFC_ENABLE), + .LFC_ENABLE(LFC_ENABLE), + .MAC_CTRL_ENABLE(0), .TX_FIFO_DEPTH(TX_FIFO_DEPTH), .RX_FIFO_DEPTH(RX_FIFO_DEPTH), .MAX_TX_SIZE(MAX_TX_SIZE), @@ -1121,7 +1175,13 @@ core_inst ( .s_axis_eth_tx_cpl_valid(axis_eth_tx_ptp_ts_valid), .s_axis_eth_tx_cpl_ready(axis_eth_tx_ptp_ts_ready), + .eth_tx_enable(eth_tx_enable), .eth_tx_status(eth_tx_status), + .eth_tx_lfc_en(eth_tx_lfc_en), + .eth_tx_lfc_req(eth_tx_lfc_req), + .eth_tx_pfc_en(eth_tx_pfc_en), + .eth_tx_pfc_req(eth_tx_pfc_req), + .eth_tx_fc_quanta_clk_en(0), .eth_rx_clk(eth_rx_clk), .eth_rx_rst(eth_rx_rst), @@ -1138,7 +1198,15 @@ core_inst ( .s_axis_eth_rx_tlast(axis_eth_rx_tlast), .s_axis_eth_rx_tuser(axis_eth_rx_tuser), + .eth_rx_enable(eth_rx_enable), .eth_rx_status(eth_rx_status), + .eth_rx_lfc_en(eth_rx_lfc_en), + .eth_rx_lfc_req(eth_rx_lfc_req), + .eth_rx_lfc_ack(eth_rx_lfc_ack), + .eth_rx_pfc_en(eth_rx_pfc_en), + .eth_rx_pfc_req(eth_rx_pfc_req), + .eth_rx_pfc_ack(eth_rx_pfc_ack), + .eth_rx_fc_quanta_clk_en(0), /* * DDR diff --git a/fpga/mqnic/AU50/fpga_100g/tb/fpga_core/Makefile b/fpga/mqnic/AU50/fpga_100g/tb/fpga_core/Makefile index 4fc450d4e..136a99609 100644 --- a/fpga/mqnic/AU50/fpga_100g/tb/fpga_core/Makefile +++ b/fpga/mqnic/AU50/fpga_100g/tb/fpga_core/Makefile @@ -161,6 +161,8 @@ export PARAM_TX_CPL_FIFO_DEPTH := 32 export PARAM_TX_CHECKSUM_ENABLE := 1 export PARAM_RX_HASH_ENABLE := 1 export PARAM_RX_CHECKSUM_ENABLE := 1 +export PARAM_LFC_ENABLE := 1 +export PARAM_PFC_ENABLE := $(PARAM_LFC_ENABLE) export PARAM_TX_FIFO_DEPTH := 32768 export PARAM_RX_FIFO_DEPTH := 131072 export PARAM_MAX_TX_SIZE := 9214 diff --git a/fpga/mqnic/AU50/fpga_100g/tb/fpga_core/test_fpga_core.py b/fpga/mqnic/AU50/fpga_100g/tb/fpga_core/test_fpga_core.py index 1f221d07a..ed7a64181 100644 --- a/fpga/mqnic/AU50/fpga_100g/tb/fpga_core/test_fpga_core.py +++ b/fpga/mqnic/AU50/fpga_100g/tb/fpga_core/test_fpga_core.py @@ -295,6 +295,8 @@ class TB(object): ) dut.qsfp_rx_status.setimmediatevalue(1) + dut.qsfp_rx_lfc_req.setimmediatevalue(1) + dut.qsfp_rx_pfc_req.setimmediatevalue(1) cocotb.start_soon(Clock(dut.qsfp_drp_clk, 8, units="ns").start()) dut.qsfp_drp_rst.setimmediatevalue(0) @@ -693,6 +695,8 @@ def test_fpga_core(request): parameters['TX_CHECKSUM_ENABLE'] = 1 parameters['RX_HASH_ENABLE'] = 1 parameters['RX_CHECKSUM_ENABLE'] = 1 + parameters['LFC_ENABLE'] = 1 + parameters['PFC_ENABLE'] = parameters['LFC_ENABLE'] parameters['TX_FIFO_DEPTH'] = 32768 parameters['RX_FIFO_DEPTH'] = 131072 parameters['MAX_TX_SIZE'] = 9214 diff --git a/fpga/mqnic/AU50/fpga_25g/fpga/Makefile b/fpga/mqnic/AU50/fpga_25g/fpga/Makefile index 3afa8dd8f..62da8db25 100644 --- a/fpga/mqnic/AU50/fpga_25g/fpga/Makefile +++ b/fpga/mqnic/AU50/fpga_25g/fpga/Makefile @@ -61,6 +61,10 @@ SYN_FILES += rtl/common/tdma_ber_ch.v SYN_FILES += lib/eth/rtl/eth_mac_10g.v SYN_FILES += lib/eth/rtl/axis_xgmii_rx_64.v SYN_FILES += lib/eth/rtl/axis_xgmii_tx_64.v +SYN_FILES += lib/eth/rtl/mac_ctrl_rx.v +SYN_FILES += lib/eth/rtl/mac_ctrl_tx.v +SYN_FILES += lib/eth/rtl/mac_pause_ctrl_rx.v +SYN_FILES += lib/eth/rtl/mac_pause_ctrl_tx.v SYN_FILES += lib/eth/rtl/eth_phy_10g.v SYN_FILES += lib/eth/rtl/eth_phy_10g_rx.v SYN_FILES += lib/eth/rtl/eth_phy_10g_rx_if.v diff --git a/fpga/mqnic/AU50/fpga_25g/fpga/config.tcl b/fpga/mqnic/AU50/fpga_25g/fpga/config.tcl index e2cf917c9..27ff31142 100644 --- a/fpga/mqnic/AU50/fpga_25g/fpga/config.tcl +++ b/fpga/mqnic/AU50/fpga_25g/fpga/config.tcl @@ -113,6 +113,8 @@ dict set params TX_CPL_FIFO_DEPTH "32" dict set params TX_CHECKSUM_ENABLE "1" dict set params RX_HASH_ENABLE "1" dict set params RX_CHECKSUM_ENABLE "1" +dict set params PFC_ENABLE "1" +dict set params LFC_ENABLE [dict get $params PFC_ENABLE] dict set params ENABLE_PADDING "1" dict set params ENABLE_DIC "1" dict set params MIN_FRAME_LENGTH "64" diff --git a/fpga/mqnic/AU50/fpga_25g/fpga_10g/Makefile b/fpga/mqnic/AU50/fpga_25g/fpga_10g/Makefile index 3afa8dd8f..62da8db25 100644 --- a/fpga/mqnic/AU50/fpga_25g/fpga_10g/Makefile +++ b/fpga/mqnic/AU50/fpga_25g/fpga_10g/Makefile @@ -61,6 +61,10 @@ SYN_FILES += rtl/common/tdma_ber_ch.v SYN_FILES += lib/eth/rtl/eth_mac_10g.v SYN_FILES += lib/eth/rtl/axis_xgmii_rx_64.v SYN_FILES += lib/eth/rtl/axis_xgmii_tx_64.v +SYN_FILES += lib/eth/rtl/mac_ctrl_rx.v +SYN_FILES += lib/eth/rtl/mac_ctrl_tx.v +SYN_FILES += lib/eth/rtl/mac_pause_ctrl_rx.v +SYN_FILES += lib/eth/rtl/mac_pause_ctrl_tx.v SYN_FILES += lib/eth/rtl/eth_phy_10g.v SYN_FILES += lib/eth/rtl/eth_phy_10g_rx.v SYN_FILES += lib/eth/rtl/eth_phy_10g_rx_if.v diff --git a/fpga/mqnic/AU50/fpga_25g/fpga_10g/config.tcl b/fpga/mqnic/AU50/fpga_25g/fpga_10g/config.tcl index a1d92bb25..08399de10 100644 --- a/fpga/mqnic/AU50/fpga_25g/fpga_10g/config.tcl +++ b/fpga/mqnic/AU50/fpga_25g/fpga_10g/config.tcl @@ -113,6 +113,8 @@ dict set params TX_CPL_FIFO_DEPTH "32" dict set params TX_CHECKSUM_ENABLE "1" dict set params RX_HASH_ENABLE "1" dict set params RX_CHECKSUM_ENABLE "1" +dict set params PFC_ENABLE "1" +dict set params LFC_ENABLE [dict get $params PFC_ENABLE] dict set params ENABLE_PADDING "1" dict set params ENABLE_DIC "1" dict set params MIN_FRAME_LENGTH "64" diff --git a/fpga/mqnic/AU50/fpga_25g/rtl/fpga.v b/fpga/mqnic/AU50/fpga_25g/rtl/fpga.v index 8e87cd5eb..2689ebf1b 100644 --- a/fpga/mqnic/AU50/fpga_25g/rtl/fpga.v +++ b/fpga/mqnic/AU50/fpga_25g/rtl/fpga.v @@ -74,6 +74,8 @@ module fpga # parameter TX_CHECKSUM_ENABLE = 1, parameter RX_HASH_ENABLE = 1, parameter RX_CHECKSUM_ENABLE = 1, + parameter PFC_ENABLE = 1, + parameter LFC_ENABLE = PFC_ENABLE, parameter ENABLE_PADDING = 1, parameter ENABLE_DIC = 1, parameter MIN_FRAME_LENGTH = 64, @@ -2679,6 +2681,8 @@ fpga_core #( .TX_CHECKSUM_ENABLE(TX_CHECKSUM_ENABLE), .RX_HASH_ENABLE(RX_HASH_ENABLE), .RX_CHECKSUM_ENABLE(RX_CHECKSUM_ENABLE), + .PFC_ENABLE(PFC_ENABLE), + .LFC_ENABLE(LFC_ENABLE), .ENABLE_PADDING(ENABLE_PADDING), .ENABLE_DIC(ENABLE_DIC), .MIN_FRAME_LENGTH(MIN_FRAME_LENGTH), diff --git a/fpga/mqnic/AU50/fpga_25g/rtl/fpga_core.v b/fpga/mqnic/AU50/fpga_25g/rtl/fpga_core.v index 8107489f7..e1e99803e 100644 --- a/fpga/mqnic/AU50/fpga_25g/rtl/fpga_core.v +++ b/fpga/mqnic/AU50/fpga_25g/rtl/fpga_core.v @@ -81,6 +81,8 @@ module fpga_core # parameter TX_CHECKSUM_ENABLE = 1, parameter RX_HASH_ENABLE = 1, parameter RX_CHECKSUM_ENABLE = 1, + parameter PFC_ENABLE = 1, + parameter LFC_ENABLE = PFC_ENABLE, parameter ENABLE_PADDING = 1, parameter ENABLE_DIC = 1, parameter MIN_FRAME_LENGTH = 64, @@ -764,7 +766,12 @@ wire [PORT_COUNT*TX_TAG_WIDTH-1:0] axis_eth_tx_ptp_ts_tag; wire [PORT_COUNT-1:0] axis_eth_tx_ptp_ts_valid; wire [PORT_COUNT-1:0] axis_eth_tx_ptp_ts_ready; +wire [PORT_COUNT-1:0] eth_tx_enable; wire [PORT_COUNT-1:0] eth_tx_status; +wire [PORT_COUNT-1:0] eth_tx_lfc_en; +wire [PORT_COUNT-1:0] eth_tx_lfc_req; +wire [PORT_COUNT*8-1:0] eth_tx_pfc_en; +wire [PORT_COUNT*8-1:0] eth_tx_pfc_req; wire [PORT_COUNT-1:0] eth_rx_clk; wire [PORT_COUNT-1:0] eth_rx_rst; @@ -779,7 +786,14 @@ wire [PORT_COUNT-1:0] axis_eth_rx_tready; wire [PORT_COUNT-1:0] axis_eth_rx_tlast; wire [PORT_COUNT*AXIS_ETH_RX_USER_WIDTH-1:0] axis_eth_rx_tuser; +wire [PORT_COUNT-1:0] eth_rx_enable; wire [PORT_COUNT-1:0] eth_rx_status; +wire [PORT_COUNT-1:0] eth_rx_lfc_en; +wire [PORT_COUNT-1:0] eth_rx_lfc_req; +wire [PORT_COUNT-1:0] eth_rx_lfc_ack; +wire [PORT_COUNT*8-1:0] eth_rx_pfc_en; +wire [PORT_COUNT*8-1:0] eth_rx_pfc_req; +wire [PORT_COUNT*8-1:0] eth_rx_pfc_ack; wire [PORT_COUNT-1:0] port_xgmii_tx_clk; wire [PORT_COUNT-1:0] port_xgmii_tx_rst; @@ -852,12 +866,15 @@ generate .PTP_PERIOD_FNS(IF_PTP_PERIOD_FNS), .TX_PTP_TS_ENABLE(PTP_TS_ENABLE), .TX_PTP_TS_WIDTH(PTP_TS_WIDTH), + .TX_PTP_TS_CTRL_IN_TUSER(0), .TX_PTP_TAG_ENABLE(PTP_TS_ENABLE), .TX_PTP_TAG_WIDTH(TX_TAG_WIDTH), .RX_PTP_TS_ENABLE(PTP_TS_ENABLE), .RX_PTP_TS_WIDTH(PTP_TS_WIDTH), .TX_USER_WIDTH(AXIS_ETH_TX_USER_WIDTH), - .RX_USER_WIDTH(AXIS_ETH_RX_USER_WIDTH) + .RX_USER_WIDTH(AXIS_ETH_RX_USER_WIDTH), + .PFC_ENABLE(PFC_ENABLE), + .PAUSE_ENABLE(LFC_ENABLE) ) eth_mac_inst ( .tx_clk(port_xgmii_tx_clk[n]), @@ -865,6 +882,9 @@ generate .rx_clk(port_xgmii_rx_clk[n]), .rx_rst(port_xgmii_rx_rst[n]), + /* + * AXI input + */ .tx_axis_tdata(axis_eth_tx_tdata[n*AXIS_ETH_DATA_WIDTH +: AXIS_ETH_DATA_WIDTH]), .tx_axis_tkeep(axis_eth_tx_tkeep[n*AXIS_ETH_KEEP_WIDTH +: AXIS_ETH_KEEP_WIDTH]), .tx_axis_tvalid(axis_eth_tx_tvalid[n +: 1]), @@ -872,30 +892,121 @@ generate .tx_axis_tlast(axis_eth_tx_tlast[n +: 1]), .tx_axis_tuser(axis_eth_tx_tuser[n*AXIS_ETH_TX_USER_WIDTH +: AXIS_ETH_TX_USER_WIDTH]), + /* + * AXI output + */ .rx_axis_tdata(axis_eth_rx_tdata[n*AXIS_ETH_DATA_WIDTH +: AXIS_ETH_DATA_WIDTH]), .rx_axis_tkeep(axis_eth_rx_tkeep[n*AXIS_ETH_KEEP_WIDTH +: AXIS_ETH_KEEP_WIDTH]), .rx_axis_tvalid(axis_eth_rx_tvalid[n +: 1]), .rx_axis_tlast(axis_eth_rx_tlast[n +: 1]), .rx_axis_tuser(axis_eth_rx_tuser[n*AXIS_ETH_RX_USER_WIDTH +: AXIS_ETH_RX_USER_WIDTH]), + /* + * XGMII interface + */ .xgmii_rxd(port_xgmii_rxd[n*XGMII_DATA_WIDTH +: XGMII_DATA_WIDTH]), .xgmii_rxc(port_xgmii_rxc[n*XGMII_CTRL_WIDTH +: XGMII_CTRL_WIDTH]), .xgmii_txd(port_xgmii_txd[n*XGMII_DATA_WIDTH +: XGMII_DATA_WIDTH]), .xgmii_txc(port_xgmii_txc[n*XGMII_CTRL_WIDTH +: XGMII_CTRL_WIDTH]), + /* + * PTP + */ .tx_ptp_ts(eth_tx_ptp_ts_96[n*PTP_TS_WIDTH +: PTP_TS_WIDTH]), .rx_ptp_ts(eth_rx_ptp_ts_96[n*PTP_TS_WIDTH +: PTP_TS_WIDTH]), .tx_axis_ptp_ts(axis_eth_tx_ptp_ts[n*PTP_TS_WIDTH +: PTP_TS_WIDTH]), .tx_axis_ptp_ts_tag(axis_eth_tx_ptp_ts_tag[n*TX_TAG_WIDTH +: TX_TAG_WIDTH]), .tx_axis_ptp_ts_valid(axis_eth_tx_ptp_ts_valid[n +: 1]), + /* + * Link-level Flow Control (LFC) (IEEE 802.3 annex 31B PAUSE) + */ + .tx_lfc_req(eth_tx_lfc_req[n +: 1]), + .tx_lfc_resend(1'b0), + .rx_lfc_en(eth_rx_lfc_en[n +: 1]), + .rx_lfc_req(eth_rx_lfc_req[n +: 1]), + .rx_lfc_ack(eth_rx_lfc_ack[n +: 1]), + + /* + * Priority Flow Control (PFC) (IEEE 802.3 annex 31D PFC) + */ + .tx_pfc_req(eth_tx_pfc_req[n*8 +: 8]), + .tx_pfc_resend(1'b0), + .rx_pfc_en(eth_rx_pfc_en[n*8 +: 8]), + .rx_pfc_req(eth_rx_pfc_req[n*8 +: 8]), + .rx_pfc_ack(eth_rx_pfc_ack[n*8 +: 8]), + + /* + * Pause interface + */ + .tx_lfc_pause_en(1'b1), + .tx_pause_req(1'b0), + .tx_pause_ack(), + + /* + * Status + */ + .tx_start_packet(), .tx_error_underflow(), + .rx_start_packet(), .rx_error_bad_frame(), .rx_error_bad_fcs(), + .stat_tx_mcf(), + .stat_rx_mcf(), + .stat_tx_lfc_pkt(), + .stat_tx_lfc_xon(), + .stat_tx_lfc_xoff(), + .stat_tx_lfc_paused(), + .stat_tx_pfc_pkt(), + .stat_tx_pfc_xon(), + .stat_tx_pfc_xoff(), + .stat_tx_pfc_paused(), + .stat_rx_lfc_pkt(), + .stat_rx_lfc_xon(), + .stat_rx_lfc_xoff(), + .stat_rx_lfc_paused(), + .stat_rx_pfc_pkt(), + .stat_rx_pfc_xon(), + .stat_rx_pfc_xoff(), + .stat_rx_pfc_paused(), + /* + * Configuration + */ .cfg_ifg(8'd12), - .cfg_tx_enable(1'b1), - .cfg_rx_enable(1'b1) + .cfg_tx_enable(eth_tx_enable[n +: 1]), + .cfg_rx_enable(eth_rx_enable[n +: 1]), + .cfg_mcf_rx_eth_dst_mcast(48'h01_80_C2_00_00_01), + .cfg_mcf_rx_check_eth_dst_mcast(1'b1), + .cfg_mcf_rx_eth_dst_ucast(48'd0), + .cfg_mcf_rx_check_eth_dst_ucast(1'b0), + .cfg_mcf_rx_eth_src(48'd0), + .cfg_mcf_rx_check_eth_src(1'b0), + .cfg_mcf_rx_eth_type(16'h8808), + .cfg_mcf_rx_opcode_lfc(16'h0001), + .cfg_mcf_rx_check_opcode_lfc(eth_rx_lfc_en[n +: 1]), + .cfg_mcf_rx_opcode_pfc(16'h0101), + .cfg_mcf_rx_check_opcode_pfc(eth_rx_pfc_en[n*8 +: 8] != 0), + .cfg_mcf_rx_forward(1'b0), + .cfg_mcf_rx_enable(eth_rx_lfc_en[n +: 1] || eth_rx_pfc_en[n*8 +: 8]), + .cfg_tx_lfc_eth_dst(48'h01_80_C2_00_00_01), + .cfg_tx_lfc_eth_src(48'h80_23_31_43_54_4C), + .cfg_tx_lfc_eth_type(16'h8808), + .cfg_tx_lfc_opcode(16'h0001), + .cfg_tx_lfc_en(eth_tx_lfc_en[n +: 1]), + .cfg_tx_lfc_quanta(16'hffff), + .cfg_tx_lfc_refresh(16'h7fff), + .cfg_tx_pfc_eth_dst(48'h01_80_C2_00_00_01), + .cfg_tx_pfc_eth_src(48'h80_23_31_43_54_4C), + .cfg_tx_pfc_eth_type(16'h8808), + .cfg_tx_pfc_opcode(16'h0101), + .cfg_tx_pfc_en(eth_tx_pfc_en[n*8 +: 8] != 0), + .cfg_tx_pfc_quanta({8{16'hffff}}), + .cfg_tx_pfc_refresh({8{16'h7fff}}), + .cfg_rx_lfc_opcode(16'h0001), + .cfg_rx_lfc_en(eth_rx_lfc_en[n +: 1]), + .cfg_rx_pfc_opcode(16'h0101), + .cfg_rx_pfc_en(eth_rx_pfc_en[n*8 +: 8] != 0) ); end @@ -969,6 +1080,9 @@ mqnic_core_pcie_us #( .TX_CHECKSUM_ENABLE(TX_CHECKSUM_ENABLE), .RX_HASH_ENABLE(RX_HASH_ENABLE), .RX_CHECKSUM_ENABLE(RX_CHECKSUM_ENABLE), + .PFC_ENABLE(PFC_ENABLE), + .LFC_ENABLE(LFC_ENABLE), + .MAC_CTRL_ENABLE(0), .TX_FIFO_DEPTH(TX_FIFO_DEPTH), .RX_FIFO_DEPTH(RX_FIFO_DEPTH), .MAX_TX_SIZE(MAX_TX_SIZE), @@ -1250,7 +1364,13 @@ core_inst ( .s_axis_eth_tx_cpl_valid(axis_eth_tx_ptp_ts_valid), .s_axis_eth_tx_cpl_ready(axis_eth_tx_ptp_ts_ready), + .eth_tx_enable(eth_tx_enable), .eth_tx_status(eth_tx_status), + .eth_tx_lfc_en(eth_tx_lfc_en), + .eth_tx_lfc_req(eth_tx_lfc_req), + .eth_tx_pfc_en(eth_tx_pfc_en), + .eth_tx_pfc_req(eth_tx_pfc_req), + .eth_tx_fc_quanta_clk_en(0), .eth_rx_clk(eth_rx_clk), .eth_rx_rst(eth_rx_rst), @@ -1267,7 +1387,15 @@ core_inst ( .s_axis_eth_rx_tlast(axis_eth_rx_tlast), .s_axis_eth_rx_tuser(axis_eth_rx_tuser), + .eth_rx_enable(eth_rx_enable), .eth_rx_status(eth_rx_status), + .eth_rx_lfc_en(eth_rx_lfc_en), + .eth_rx_lfc_req(eth_rx_lfc_req), + .eth_rx_lfc_ack(eth_rx_lfc_ack), + .eth_rx_pfc_en(eth_rx_pfc_en), + .eth_rx_pfc_req(eth_rx_pfc_req), + .eth_rx_pfc_ack(eth_rx_pfc_ack), + .eth_rx_fc_quanta_clk_en(0), /* * DDR diff --git a/fpga/mqnic/AU50/fpga_25g/tb/fpga_core/Makefile b/fpga/mqnic/AU50/fpga_25g/tb/fpga_core/Makefile index e2dad76a0..633185f56 100644 --- a/fpga/mqnic/AU50/fpga_25g/tb/fpga_core/Makefile +++ b/fpga/mqnic/AU50/fpga_25g/tb/fpga_core/Makefile @@ -62,6 +62,10 @@ VERILOG_SOURCES += ../../rtl/common/tdma_ber_ch.v VERILOG_SOURCES += ../../lib/eth/rtl/eth_mac_10g.v VERILOG_SOURCES += ../../lib/eth/rtl/axis_xgmii_rx_64.v VERILOG_SOURCES += ../../lib/eth/rtl/axis_xgmii_tx_64.v +VERILOG_SOURCES += ../../lib/eth/rtl/mac_ctrl_rx.v +VERILOG_SOURCES += ../../lib/eth/rtl/mac_ctrl_tx.v +VERILOG_SOURCES += ../../lib/eth/rtl/mac_pause_ctrl_rx.v +VERILOG_SOURCES += ../../lib/eth/rtl/mac_pause_ctrl_tx.v VERILOG_SOURCES += ../../lib/eth/rtl/lfsr.v VERILOG_SOURCES += ../../lib/eth/rtl/ptp_clock.v VERILOG_SOURCES += ../../lib/eth/rtl/ptp_clock_cdc.v @@ -167,6 +171,8 @@ export PARAM_TX_CPL_FIFO_DEPTH := 32 export PARAM_TX_CHECKSUM_ENABLE := 1 export PARAM_RX_HASH_ENABLE := 1 export PARAM_RX_CHECKSUM_ENABLE := 1 +export PARAM_LFC_ENABLE := 1 +export PARAM_PFC_ENABLE := $(PARAM_LFC_ENABLE) export PARAM_TX_FIFO_DEPTH := 32768 export PARAM_RX_FIFO_DEPTH := 32768 export PARAM_MAX_TX_SIZE := 9214 diff --git a/fpga/mqnic/AU50/fpga_25g/tb/fpga_core/test_fpga_core.py b/fpga/mqnic/AU50/fpga_25g/tb/fpga_core/test_fpga_core.py index 405c56c8b..0d6c45b25 100644 --- a/fpga/mqnic/AU50/fpga_25g/tb/fpga_core/test_fpga_core.py +++ b/fpga/mqnic/AU50/fpga_25g/tb/fpga_core/test_fpga_core.py @@ -3,6 +3,7 @@ import logging import os +import struct import sys import scapy.utils @@ -17,7 +18,7 @@ from cocotb.clock import Clock from cocotb.triggers import RisingEdge, FallingEdge, Timer from cocotbext.axi import AxiStreamBus, AxiLiteBus, AxiLiteRam -from cocotbext.eth import XgmiiSource, XgmiiSink +from cocotbext.eth import XgmiiSource, XgmiiSink, XgmiiFrame from cocotbext.pcie.core import RootComplex from cocotbext.pcie.xilinx.us import UltraScalePlusPcieDevice @@ -498,6 +499,35 @@ async def run_test_nic(dut): tb.loopback_enable = False + if tb.driver.interfaces[0].if_feature_lfc: + tb.log.info("Test LFC pause frame RX") + + await tb.driver.interfaces[0].ports[0].set_lfc_ctrl(mqnic.MQNIC_PORT_LFC_CTRL_TX_LFC_EN | mqnic.MQNIC_PORT_LFC_CTRL_RX_LFC_EN) + await tb.driver.hw_regs.read_dword(0) + + lfc_xoff = Ether(src='DA:D1:D2:D3:D4:D5', dst='01:80:C2:00:00:01', type=0x8808) / struct.pack('!HH', 0x0001, 2000) + + await tb.qsfp_source[0].send(XgmiiFrame.from_payload(bytes(lfc_xoff))) + + count = 16 + + pkts = [bytearray([(x+k) % 256 for x in range(1514)]) for k in range(count)] + + tb.loopback_enable = True + + for p in pkts: + await tb.driver.interfaces[0].start_xmit(p, 0) + + for k in range(count): + pkt = await tb.driver.interfaces[0].recv() + + tb.log.info("Packet: %s", pkt) + assert pkt.data == pkts[k] + if tb.driver.interfaces[0].if_feature_rx_csum: + assert pkt.rx_checksum == ~scapy.utils.checksum(bytes(pkt.data[14:])) & 0xffff + + tb.loopback_enable = False + await RisingEdge(dut.clk_250mhz) await RisingEdge(dut.clk_250mhz) @@ -570,6 +600,10 @@ def test_fpga_core(request): os.path.join(eth_rtl_dir, "eth_mac_10g.v"), os.path.join(eth_rtl_dir, "axis_xgmii_rx_64.v"), os.path.join(eth_rtl_dir, "axis_xgmii_tx_64.v"), + os.path.join(eth_rtl_dir, "mac_ctrl_rx.v"), + os.path.join(eth_rtl_dir, "mac_ctrl_tx.v"), + os.path.join(eth_rtl_dir, "mac_pause_ctrl_rx.v"), + os.path.join(eth_rtl_dir, "mac_pause_ctrl_tx.v"), os.path.join(eth_rtl_dir, "lfsr.v"), os.path.join(eth_rtl_dir, "ptp_clock.v"), os.path.join(eth_rtl_dir, "ptp_clock_cdc.v"), @@ -676,6 +710,8 @@ def test_fpga_core(request): parameters['TX_CHECKSUM_ENABLE'] = 1 parameters['RX_HASH_ENABLE'] = 1 parameters['RX_CHECKSUM_ENABLE'] = 1 + parameters['LFC_ENABLE'] = 1 + parameters['PFC_ENABLE'] = parameters['LFC_ENABLE'] parameters['TX_FIFO_DEPTH'] = 32768 parameters['RX_FIFO_DEPTH'] = 32768 parameters['MAX_TX_SIZE'] = 9214 diff --git a/fpga/mqnic/DE10_Agilex/fpga_100g/fpga/config.tcl b/fpga/mqnic/DE10_Agilex/fpga_100g/fpga/config.tcl index bdd61435f..423b949f7 100644 --- a/fpga/mqnic/DE10_Agilex/fpga_100g/fpga/config.tcl +++ b/fpga/mqnic/DE10_Agilex/fpga_100g/fpga/config.tcl @@ -100,6 +100,8 @@ dict set params TX_CPL_FIFO_DEPTH "32" dict set params TX_CHECKSUM_ENABLE "1" dict set params RX_HASH_ENABLE "1" dict set params RX_CHECKSUM_ENABLE "1" +dict set params PFC_ENABLE "1" +dict set params LFC_ENABLE [dict get $params PFC_ENABLE] dict set params TX_FIFO_DEPTH "32768" dict set params RX_FIFO_DEPTH "131072" dict set params MAX_TX_SIZE "9214" diff --git a/fpga/mqnic/DE10_Agilex/fpga_100g/fpga_24AR0/config.tcl b/fpga/mqnic/DE10_Agilex/fpga_100g/fpga_24AR0/config.tcl index e87855725..0415200d2 100644 --- a/fpga/mqnic/DE10_Agilex/fpga_100g/fpga_24AR0/config.tcl +++ b/fpga/mqnic/DE10_Agilex/fpga_100g/fpga_24AR0/config.tcl @@ -100,6 +100,8 @@ dict set params TX_CPL_FIFO_DEPTH "32" dict set params TX_CHECKSUM_ENABLE "1" dict set params RX_HASH_ENABLE "1" dict set params RX_CHECKSUM_ENABLE "1" +dict set params PFC_ENABLE "1" +dict set params LFC_ENABLE [dict get $params PFC_ENABLE] dict set params TX_FIFO_DEPTH "32768" dict set params RX_FIFO_DEPTH "131072" dict set params MAX_TX_SIZE "9214" diff --git a/fpga/mqnic/DE10_Agilex/fpga_100g/fpga_app_dma_bench/config.tcl b/fpga/mqnic/DE10_Agilex/fpga_100g/fpga_app_dma_bench/config.tcl index 96187beac..ed3552aa7 100644 --- a/fpga/mqnic/DE10_Agilex/fpga_100g/fpga_app_dma_bench/config.tcl +++ b/fpga/mqnic/DE10_Agilex/fpga_100g/fpga_app_dma_bench/config.tcl @@ -100,6 +100,8 @@ dict set params TX_CPL_FIFO_DEPTH "32" dict set params TX_CHECKSUM_ENABLE "1" dict set params RX_HASH_ENABLE "1" dict set params RX_CHECKSUM_ENABLE "1" +dict set params PFC_ENABLE "1" +dict set params LFC_ENABLE [dict get $params PFC_ENABLE] dict set params TX_FIFO_DEPTH "32768" dict set params RX_FIFO_DEPTH "131072" dict set params MAX_TX_SIZE "9214" diff --git a/fpga/mqnic/DE10_Agilex/fpga_100g/fpga_app_dma_bench_24AR0/config.tcl b/fpga/mqnic/DE10_Agilex/fpga_100g/fpga_app_dma_bench_24AR0/config.tcl index 7de020985..aec0e8560 100644 --- a/fpga/mqnic/DE10_Agilex/fpga_100g/fpga_app_dma_bench_24AR0/config.tcl +++ b/fpga/mqnic/DE10_Agilex/fpga_100g/fpga_app_dma_bench_24AR0/config.tcl @@ -100,6 +100,8 @@ dict set params TX_CPL_FIFO_DEPTH "32" dict set params TX_CHECKSUM_ENABLE "1" dict set params RX_HASH_ENABLE "1" dict set params RX_CHECKSUM_ENABLE "1" +dict set params PFC_ENABLE "1" +dict set params LFC_ENABLE [dict get $params PFC_ENABLE] dict set params TX_FIFO_DEPTH "32768" dict set params RX_FIFO_DEPTH "131072" dict set params MAX_TX_SIZE "9214" diff --git a/fpga/mqnic/DE10_Agilex/fpga_100g/rtl/eth_mac_dual_wrapper.v b/fpga/mqnic/DE10_Agilex/fpga_100g/rtl/eth_mac_dual_wrapper.v index 326b3aa75..63978d10a 100644 --- a/fpga/mqnic/DE10_Agilex/fpga_100g/rtl/eth_mac_dual_wrapper.v +++ b/fpga/mqnic/DE10_Agilex/fpga_100g/rtl/eth_mac_dual_wrapper.v @@ -66,6 +66,10 @@ module eth_mac_dual_wrapper # input wire mac_1_tx_axis_tlast, input wire [TX_USER_WIDTH-1:0] mac_1_tx_axis_tuser, + output wire mac_1_tx_status, + input wire mac_1_tx_lfc_req, + input wire [7:0] mac_1_tx_pfc_req, + output wire [DATA_WIDTH-1:0] mac_1_rx_axis_tdata, output wire [KEEP_WIDTH-1:0] mac_1_rx_axis_tkeep, output wire mac_1_rx_axis_tvalid, @@ -73,6 +77,8 @@ module eth_mac_dual_wrapper # output wire [RX_USER_WIDTH-1:0] mac_1_rx_axis_tuser, output wire mac_1_rx_status, + output wire mac_1_rx_lfc_req, + output wire [7:0] mac_1_rx_pfc_req, output wire mac_2_clk, output wire mac_2_rst, @@ -90,13 +96,19 @@ module eth_mac_dual_wrapper # input wire mac_2_tx_axis_tlast, input wire [TX_USER_WIDTH-1:0] mac_2_tx_axis_tuser, + output wire mac_2_tx_status, + input wire mac_2_tx_lfc_req, + input wire [7:0] mac_2_tx_pfc_req, + output wire [DATA_WIDTH-1:0] mac_2_rx_axis_tdata, output wire [KEEP_WIDTH-1:0] mac_2_rx_axis_tkeep, output wire mac_2_rx_axis_tvalid, output wire mac_2_rx_axis_tlast, output wire [RX_USER_WIDTH-1:0] mac_2_rx_axis_tuser, - output wire mac_2_rx_status + output wire mac_2_rx_status, + output wire mac_2_rx_lfc_req, + output wire [7:0] mac_2_rx_pfc_req ); parameter N_CH = 2; @@ -146,6 +158,11 @@ wire [N_CH-1:0] mac_rx_endofpacket; wire [N_CH*6-1:0] mac_rx_empty; wire [N_CH*6-1:0] mac_rx_error; +wire [N_CH*8-1:0] mac_tx_pfc; +wire [N_CH*8-1:0] mac_rx_pfc; +wire [N_CH-1:0] mac_tx_pause; +wire [N_CH-1:0] mac_rx_pause; + mac_02 mac_02_inst ( .i_stats_snapshot (1'b0), .o_cdr_lock (), @@ -234,10 +251,10 @@ mac_02 mac_02_inst ( .o_rx_error (mac_rx_error[0*6 +: 6]), .o_rxstatus_data (), .o_rxstatus_valid (), - .i_tx_pfc (8'd0), - .o_rx_pfc (), - .i_tx_pause (1'b0), - .o_rx_pause () + .i_tx_pfc (mac_tx_pfc[0*8 +: 8]), + .o_rx_pfc (mac_rx_pfc[0*8 +: 8]), + .i_tx_pause (mac_tx_pause[0*1 +: 1]), + .o_rx_pause (mac_rx_pause[0*1 +: 1]) ); mac_13 mac_13_inst ( @@ -328,10 +345,10 @@ mac_13 mac_13_inst ( .o_rx_error (mac_rx_error[1*6 +: 6]), .o_rxstatus_data (), .o_rxstatus_valid (), - .i_tx_pfc (8'd0), - .o_rx_pfc (), - .i_tx_pause (1'b0), - .o_rx_pause () + .i_tx_pfc (mac_tx_pfc[1*8 +: 8]), + .o_rx_pfc (mac_rx_pfc[1*8 +: 8]), + .i_tx_pause (mac_tx_pause[1*1 +: 1]), + .o_rx_pause (mac_rx_pause[1*1 +: 1]) ); wire [N_CH*DATA_WIDTH-1:0] mac_rx_axis_tdata; @@ -366,13 +383,19 @@ assign mac_1_tx_axis_tready = mac_tx_axis_tready[0]; assign mac_tx_axis_tlast[0] = mac_1_tx_axis_tlast; assign mac_tx_axis_tuser[0*TX_USER_WIDTH +: TX_USER_WIDTH] = mac_1_tx_axis_tuser; +assign mac_1_tx_status = mac_tx_lanes_stable[0*1 +: 1]; +assign mac_tx_pause[0*1 +: 1] = mac_1_tx_lfc_req; +assign mac_tx_pfc[0*8 +: 8] = mac_1_tx_pfc_req; + assign mac_1_rx_axis_tdata = mac_rx_axis_tdata[0*DATA_WIDTH +: DATA_WIDTH]; assign mac_1_rx_axis_tkeep = mac_rx_axis_tkeep[0*KEEP_WIDTH +: KEEP_WIDTH]; assign mac_1_rx_axis_tvalid = mac_rx_axis_tvalid[0]; assign mac_1_rx_axis_tlast = mac_rx_axis_tlast[0]; assign mac_1_rx_axis_tuser = mac_rx_axis_tuser[0*RX_USER_WIDTH +: RX_USER_WIDTH]; -assign mac_1_rx_status = mac_rx_pcs_ready[0]; +assign mac_1_rx_status = mac_rx_pcs_ready[0*1 +: 1]; +assign mac_1_rx_lfc_req = mac_rx_pause[0*1 +: 1]; +assign mac_1_rx_pfc_req = mac_rx_pfc[0*8 +: 8]; assign mac_2_clk = mac_clk[1]; assign mac_2_rst = mac_rst[1]; @@ -390,13 +413,19 @@ assign mac_2_tx_axis_tready = mac_tx_axis_tready[1]; assign mac_tx_axis_tlast[1] = mac_2_tx_axis_tlast; assign mac_tx_axis_tuser[1*TX_USER_WIDTH +: TX_USER_WIDTH] = mac_2_tx_axis_tuser; +assign mac_2_tx_status = mac_tx_lanes_stable[1*1 +: 1]; +assign mac_tx_pause[1*1 +: 1] = mac_2_tx_lfc_req; +assign mac_tx_pfc[1*8 +: 8] = mac_2_tx_pfc_req; + assign mac_2_rx_axis_tdata = mac_rx_axis_tdata[1*DATA_WIDTH +: DATA_WIDTH]; assign mac_2_rx_axis_tkeep = mac_rx_axis_tkeep[1*KEEP_WIDTH +: KEEP_WIDTH]; assign mac_2_rx_axis_tvalid = mac_rx_axis_tvalid[1]; assign mac_2_rx_axis_tlast = mac_rx_axis_tlast[1]; assign mac_2_rx_axis_tuser = mac_rx_axis_tuser[1*RX_USER_WIDTH +: RX_USER_WIDTH]; -assign mac_2_rx_status = mac_rx_pcs_ready[1]; +assign mac_2_rx_status = mac_rx_pcs_ready[1*1 +: 1]; +assign mac_2_rx_lfc_req = mac_rx_pause[1*1 +: 1]; +assign mac_2_rx_pfc_req = mac_rx_pfc[1*8 +: 8]; generate diff --git a/fpga/mqnic/DE10_Agilex/fpga_100g/rtl/fpga.v b/fpga/mqnic/DE10_Agilex/fpga_100g/rtl/fpga.v index 22848a4f0..18b240ff8 100644 --- a/fpga/mqnic/DE10_Agilex/fpga_100g/rtl/fpga.v +++ b/fpga/mqnic/DE10_Agilex/fpga_100g/rtl/fpga.v @@ -71,6 +71,8 @@ module fpga # parameter TX_CHECKSUM_ENABLE = 1, parameter RX_HASH_ENABLE = 1, parameter RX_CHECKSUM_ENABLE = 1, + parameter PFC_ENABLE = 1, + parameter LFC_ENABLE = PFC_ENABLE, parameter TX_FIFO_DEPTH = 32768, parameter RX_FIFO_DEPTH = 131072, parameter MAX_TX_SIZE = 9214, @@ -464,6 +466,10 @@ wire qsfpdda_mac_1_tx_axis_tready_int; wire qsfpdda_mac_1_tx_axis_tlast_int; wire [AXIS_ETH_TX_USER_WIDTH-1:0] qsfpdda_mac_1_tx_axis_tuser_int; +wire qsfpdda_mac_1_tx_status_int; +wire qsfpdda_mac_1_tx_lfc_req_int; +wire [7:0] qsfpdda_mac_1_tx_pfc_req_int; + wire [AXIS_ETH_DATA_WIDTH-1:0] qsfpdda_mac_1_rx_axis_tdata_int; wire [AXIS_ETH_KEEP_WIDTH-1:0] qsfpdda_mac_1_rx_axis_tkeep_int; wire qsfpdda_mac_1_rx_axis_tvalid_int; @@ -471,6 +477,8 @@ wire qsfpdda_mac_1_rx_axis_tlast_int; wire [AXIS_ETH_RX_USER_WIDTH-1:0] qsfpdda_mac_1_rx_axis_tuser_int; wire qsfpdda_mac_1_rx_status_int; +wire qsfpdda_mac_1_rx_lfc_req_int; +wire [7:0] qsfpdda_mac_1_rx_pfc_req_int; wire qsfpdda_mac_2_clk_int; wire qsfpdda_mac_2_rst_int; @@ -488,6 +496,10 @@ wire qsfpdda_mac_2_tx_axis_tready_int; wire qsfpdda_mac_2_tx_axis_tlast_int; wire [AXIS_ETH_TX_USER_WIDTH-1:0] qsfpdda_mac_2_tx_axis_tuser_int; +wire qsfpdda_mac_2_tx_status_int; +wire qsfpdda_mac_2_tx_lfc_req_int; +wire [7:0] qsfpdda_mac_2_tx_pfc_req_int; + wire [AXIS_ETH_DATA_WIDTH-1:0] qsfpdda_mac_2_rx_axis_tdata_int; wire [AXIS_ETH_KEEP_WIDTH-1:0] qsfpdda_mac_2_rx_axis_tkeep_int; wire qsfpdda_mac_2_rx_axis_tvalid_int; @@ -495,6 +507,8 @@ wire qsfpdda_mac_2_rx_axis_tlast_int; wire [AXIS_ETH_RX_USER_WIDTH-1:0] qsfpdda_mac_2_rx_axis_tuser_int; wire qsfpdda_mac_2_rx_status_int; +wire qsfpdda_mac_2_rx_lfc_req_int; +wire [7:0] qsfpdda_mac_2_rx_pfc_req_int; eth_mac_dual_wrapper #( .PTP_TS_WIDTH(PTP_TS_WIDTH), @@ -530,6 +544,10 @@ qsfpdda_mac_inst ( .mac_1_tx_axis_tlast(qsfpdda_mac_1_tx_axis_tlast_int), .mac_1_tx_axis_tuser(qsfpdda_mac_1_tx_axis_tuser_int), + .mac_1_tx_status(qsfpdda_mac_1_tx_status_int), + .mac_1_tx_lfc_req(qsfpdda_mac_1_tx_lfc_req_int), + .mac_1_tx_pfc_req(qsfpdda_mac_1_tx_pfc_req_int), + .mac_1_rx_axis_tdata(qsfpdda_mac_1_rx_axis_tdata_int), .mac_1_rx_axis_tkeep(qsfpdda_mac_1_rx_axis_tkeep_int), .mac_1_rx_axis_tvalid(qsfpdda_mac_1_rx_axis_tvalid_int), @@ -537,6 +555,8 @@ qsfpdda_mac_inst ( .mac_1_rx_axis_tuser(qsfpdda_mac_1_rx_axis_tuser_int), .mac_1_rx_status(qsfpdda_mac_1_rx_status_int), + .mac_1_rx_lfc_req(qsfpdda_mac_1_rx_lfc_req_int), + .mac_1_rx_pfc_req(qsfpdda_mac_1_rx_pfc_req_int), .mac_2_clk(qsfpdda_mac_2_clk_int), .mac_2_rst(qsfpdda_mac_2_rst_int), @@ -554,13 +574,19 @@ qsfpdda_mac_inst ( .mac_2_tx_axis_tlast(qsfpdda_mac_2_tx_axis_tlast_int), .mac_2_tx_axis_tuser(qsfpdda_mac_2_tx_axis_tuser_int), + .mac_2_tx_status(qsfpdda_mac_2_tx_status_int), + .mac_2_tx_lfc_req(qsfpdda_mac_2_tx_lfc_req_int), + .mac_2_tx_pfc_req(qsfpdda_mac_2_tx_pfc_req_int), + .mac_2_rx_axis_tdata(qsfpdda_mac_2_rx_axis_tdata_int), .mac_2_rx_axis_tkeep(qsfpdda_mac_2_rx_axis_tkeep_int), .mac_2_rx_axis_tvalid(qsfpdda_mac_2_rx_axis_tvalid_int), .mac_2_rx_axis_tlast(qsfpdda_mac_2_rx_axis_tlast_int), .mac_2_rx_axis_tuser(qsfpdda_mac_2_rx_axis_tuser_int), - .mac_2_rx_status(qsfpdda_mac_2_rx_status_int) + .mac_2_rx_status(qsfpdda_mac_2_rx_status_int), + .mac_2_rx_lfc_req(qsfpdda_mac_2_rx_lfc_req_int), + .mac_2_rx_pfc_req(qsfpdda_mac_2_rx_pfc_req_int) ); // QSFP-DD B @@ -580,6 +606,10 @@ wire qsfpddb_mac_1_tx_axis_tready_int; wire qsfpddb_mac_1_tx_axis_tlast_int; wire [AXIS_ETH_TX_USER_WIDTH-1:0] qsfpddb_mac_1_tx_axis_tuser_int; +wire qsfpddb_mac_1_tx_status_int; +wire qsfpddb_mac_1_tx_lfc_req_int; +wire [7:0] qsfpddb_mac_1_tx_pfc_req_int; + wire [AXIS_ETH_DATA_WIDTH-1:0] qsfpddb_mac_1_rx_axis_tdata_int; wire [AXIS_ETH_KEEP_WIDTH-1:0] qsfpddb_mac_1_rx_axis_tkeep_int; wire qsfpddb_mac_1_rx_axis_tvalid_int; @@ -587,6 +617,8 @@ wire qsfpddb_mac_1_rx_axis_tlast_int; wire [AXIS_ETH_RX_USER_WIDTH-1:0] qsfpddb_mac_1_rx_axis_tuser_int; wire qsfpddb_mac_1_rx_status_int; +wire qsfpddb_mac_1_rx_lfc_req_int; +wire [7:0] qsfpddb_mac_1_rx_pfc_req_int; wire qsfpddb_mac_2_clk_int; wire qsfpddb_mac_2_rst_int; @@ -604,6 +636,10 @@ wire qsfpddb_mac_2_tx_axis_tready_int; wire qsfpddb_mac_2_tx_axis_tlast_int; wire [AXIS_ETH_TX_USER_WIDTH-1:0] qsfpddb_mac_2_tx_axis_tuser_int; +wire qsfpddb_mac_2_tx_status_int; +wire qsfpddb_mac_2_tx_lfc_req_int; +wire [7:0] qsfpddb_mac_2_tx_pfc_req_int; + wire [AXIS_ETH_DATA_WIDTH-1:0] qsfpddb_mac_2_rx_axis_tdata_int; wire [AXIS_ETH_KEEP_WIDTH-1:0] qsfpddb_mac_2_rx_axis_tkeep_int; wire qsfpddb_mac_2_rx_axis_tvalid_int; @@ -611,6 +647,8 @@ wire qsfpddb_mac_2_rx_axis_tlast_int; wire [AXIS_ETH_RX_USER_WIDTH-1:0] qsfpddb_mac_2_rx_axis_tuser_int; wire qsfpddb_mac_2_rx_status_int; +wire qsfpddb_mac_2_rx_lfc_req_int; +wire [7:0] qsfpddb_mac_2_rx_pfc_req_int; eth_mac_dual_wrapper #( .PTP_TS_WIDTH(PTP_TS_WIDTH), @@ -646,6 +684,10 @@ qsfpddb_mac_inst ( .mac_1_tx_axis_tlast(qsfpddb_mac_1_tx_axis_tlast_int), .mac_1_tx_axis_tuser(qsfpddb_mac_1_tx_axis_tuser_int), + .mac_1_tx_status(qsfpddb_mac_1_tx_status_int), + .mac_1_tx_lfc_req(qsfpddb_mac_1_tx_lfc_req_int), + .mac_1_tx_pfc_req(qsfpddb_mac_1_tx_pfc_req_int), + .mac_1_rx_axis_tdata(qsfpddb_mac_1_rx_axis_tdata_int), .mac_1_rx_axis_tkeep(qsfpddb_mac_1_rx_axis_tkeep_int), .mac_1_rx_axis_tvalid(qsfpddb_mac_1_rx_axis_tvalid_int), @@ -653,6 +695,8 @@ qsfpddb_mac_inst ( .mac_1_rx_axis_tuser(qsfpddb_mac_1_rx_axis_tuser_int), .mac_1_rx_status(qsfpddb_mac_1_rx_status_int), + .mac_1_rx_lfc_req(qsfpddb_mac_1_rx_lfc_req_int), + .mac_1_rx_pfc_req(qsfpddb_mac_1_rx_pfc_req_int), .mac_2_clk(qsfpddb_mac_2_clk_int), .mac_2_rst(qsfpddb_mac_2_rst_int), @@ -670,13 +714,19 @@ qsfpddb_mac_inst ( .mac_2_tx_axis_tlast(qsfpddb_mac_2_tx_axis_tlast_int), .mac_2_tx_axis_tuser(qsfpddb_mac_2_tx_axis_tuser_int), + .mac_2_tx_status(qsfpddb_mac_2_tx_status_int), + .mac_2_tx_lfc_req(qsfpddb_mac_2_tx_lfc_req_int), + .mac_2_tx_pfc_req(qsfpddb_mac_2_tx_pfc_req_int), + .mac_2_rx_axis_tdata(qsfpddb_mac_2_rx_axis_tdata_int), .mac_2_rx_axis_tkeep(qsfpddb_mac_2_rx_axis_tkeep_int), .mac_2_rx_axis_tvalid(qsfpddb_mac_2_rx_axis_tvalid_int), .mac_2_rx_axis_tlast(qsfpddb_mac_2_rx_axis_tlast_int), .mac_2_rx_axis_tuser(qsfpddb_mac_2_rx_axis_tuser_int), - .mac_2_rx_status(qsfpddb_mac_2_rx_status_int) + .mac_2_rx_status(qsfpddb_mac_2_rx_status_int), + .mac_2_rx_lfc_req(qsfpddb_mac_2_rx_lfc_req_int), + .mac_2_rx_pfc_req(qsfpddb_mac_2_rx_pfc_req_int) ); wire ptp_clk; @@ -751,6 +801,8 @@ fpga_core #( .TX_CHECKSUM_ENABLE(TX_CHECKSUM_ENABLE), .RX_HASH_ENABLE(RX_HASH_ENABLE), .RX_CHECKSUM_ENABLE(RX_CHECKSUM_ENABLE), + .PFC_ENABLE(PFC_ENABLE), + .LFC_ENABLE(LFC_ENABLE), .TX_FIFO_DEPTH(TX_FIFO_DEPTH), .RX_FIFO_DEPTH(RX_FIFO_DEPTH), .MAX_TX_SIZE(MAX_TX_SIZE), @@ -895,6 +947,10 @@ core_inst ( .qsfpdda_mac_1_tx_axis_tlast(qsfpdda_mac_1_tx_axis_tlast_int), .qsfpdda_mac_1_tx_axis_tuser(qsfpdda_mac_1_tx_axis_tuser_int), + .qsfpdda_mac_1_tx_status(qsfpdda_mac_1_tx_status_int), + .qsfpdda_mac_1_tx_lfc_req(qsfpdda_mac_1_tx_lfc_req_int), + .qsfpdda_mac_1_tx_pfc_req(qsfpdda_mac_1_tx_pfc_req_int), + .qsfpdda_mac_1_rx_axis_tdata(qsfpdda_mac_1_rx_axis_tdata_int), .qsfpdda_mac_1_rx_axis_tkeep(qsfpdda_mac_1_rx_axis_tkeep_int), .qsfpdda_mac_1_rx_axis_tvalid(qsfpdda_mac_1_rx_axis_tvalid_int), @@ -902,6 +958,8 @@ core_inst ( .qsfpdda_mac_1_rx_axis_tuser(qsfpdda_mac_1_rx_axis_tuser_int), .qsfpdda_mac_1_rx_status(qsfpdda_mac_1_rx_status_int), + .qsfpdda_mac_1_rx_lfc_req(qsfpdda_mac_1_rx_lfc_req_int), + .qsfpdda_mac_1_rx_pfc_req(qsfpdda_mac_1_rx_pfc_req_int), .qsfpdda_mac_2_clk(qsfpdda_mac_2_clk_int), .qsfpdda_mac_2_rst(qsfpdda_mac_2_rst_int), @@ -919,6 +977,10 @@ core_inst ( .qsfpdda_mac_2_tx_axis_tlast(qsfpdda_mac_2_tx_axis_tlast_int), .qsfpdda_mac_2_tx_axis_tuser(qsfpdda_mac_2_tx_axis_tuser_int), + .qsfpdda_mac_2_tx_status(qsfpdda_mac_2_tx_status_int), + .qsfpdda_mac_2_tx_lfc_req(qsfpdda_mac_2_tx_lfc_req_int), + .qsfpdda_mac_2_tx_pfc_req(qsfpdda_mac_2_tx_pfc_req_int), + .qsfpdda_mac_2_rx_axis_tdata(qsfpdda_mac_2_rx_axis_tdata_int), .qsfpdda_mac_2_rx_axis_tkeep(qsfpdda_mac_2_rx_axis_tkeep_int), .qsfpdda_mac_2_rx_axis_tvalid(qsfpdda_mac_2_rx_axis_tvalid_int), @@ -926,6 +988,8 @@ core_inst ( .qsfpdda_mac_2_rx_axis_tuser(qsfpdda_mac_2_rx_axis_tuser_int), .qsfpdda_mac_2_rx_status(qsfpdda_mac_2_rx_status_int), + .qsfpdda_mac_2_rx_lfc_req(qsfpdda_mac_2_rx_lfc_req_int), + .qsfpdda_mac_2_rx_pfc_req(qsfpdda_mac_2_rx_pfc_req_int), .qsfpdda_initmode(qsfpdda_initmode), .qsfpdda_interrupt_n(qsfpdda_interrupt_n_int), @@ -955,6 +1019,10 @@ core_inst ( .qsfpddb_mac_1_tx_axis_tlast(qsfpddb_mac_1_tx_axis_tlast_int), .qsfpddb_mac_1_tx_axis_tuser(qsfpddb_mac_1_tx_axis_tuser_int), + .qsfpddb_mac_1_tx_status(qsfpddb_mac_1_tx_status_int), + .qsfpddb_mac_1_tx_lfc_req(qsfpddb_mac_1_tx_lfc_req_int), + .qsfpddb_mac_1_tx_pfc_req(qsfpddb_mac_1_tx_pfc_req_int), + .qsfpddb_mac_1_rx_axis_tdata(qsfpddb_mac_1_rx_axis_tdata_int), .qsfpddb_mac_1_rx_axis_tkeep(qsfpddb_mac_1_rx_axis_tkeep_int), .qsfpddb_mac_1_rx_axis_tvalid(qsfpddb_mac_1_rx_axis_tvalid_int), @@ -962,6 +1030,8 @@ core_inst ( .qsfpddb_mac_1_rx_axis_tuser(qsfpddb_mac_1_rx_axis_tuser_int), .qsfpddb_mac_1_rx_status(qsfpddb_mac_1_rx_status_int), + .qsfpddb_mac_1_rx_lfc_req(qsfpddb_mac_1_rx_lfc_req_int), + .qsfpddb_mac_1_rx_pfc_req(qsfpddb_mac_1_rx_pfc_req_int), .qsfpddb_mac_2_clk(qsfpddb_mac_2_clk_int), .qsfpddb_mac_2_rst(qsfpddb_mac_2_rst_int), @@ -979,6 +1049,10 @@ core_inst ( .qsfpddb_mac_2_tx_axis_tlast(qsfpddb_mac_2_tx_axis_tlast_int), .qsfpddb_mac_2_tx_axis_tuser(qsfpddb_mac_2_tx_axis_tuser_int), + .qsfpddb_mac_2_tx_status(qsfpddb_mac_2_tx_status_int), + .qsfpddb_mac_2_tx_lfc_req(qsfpddb_mac_2_tx_lfc_req_int), + .qsfpddb_mac_2_tx_pfc_req(qsfpddb_mac_2_tx_pfc_req_int), + .qsfpddb_mac_2_rx_axis_tdata(qsfpddb_mac_2_rx_axis_tdata_int), .qsfpddb_mac_2_rx_axis_tkeep(qsfpddb_mac_2_rx_axis_tkeep_int), .qsfpddb_mac_2_rx_axis_tvalid(qsfpddb_mac_2_rx_axis_tvalid_int), @@ -986,6 +1060,8 @@ core_inst ( .qsfpddb_mac_2_rx_axis_tuser(qsfpddb_mac_2_rx_axis_tuser_int), .qsfpddb_mac_2_rx_status(qsfpddb_mac_2_rx_status_int), + .qsfpddb_mac_2_rx_lfc_req(qsfpddb_mac_2_rx_lfc_req_int), + .qsfpddb_mac_2_rx_pfc_req(qsfpddb_mac_2_rx_pfc_req_int), .qsfpddb_initmode(qsfpddb_initmode), .qsfpddb_interrupt_n(qsfpddb_interrupt_n_int), diff --git a/fpga/mqnic/DE10_Agilex/fpga_100g/rtl/fpga_core.v b/fpga/mqnic/DE10_Agilex/fpga_100g/rtl/fpga_core.v index 7bf33cc09..cdd72620a 100644 --- a/fpga/mqnic/DE10_Agilex/fpga_100g/rtl/fpga_core.v +++ b/fpga/mqnic/DE10_Agilex/fpga_100g/rtl/fpga_core.v @@ -76,9 +76,8 @@ module fpga_core # parameter TX_CHECKSUM_ENABLE = 1, parameter RX_HASH_ENABLE = 1, parameter RX_CHECKSUM_ENABLE = 1, - parameter ENABLE_PADDING = 1, - parameter ENABLE_DIC = 1, - parameter MIN_FRAME_LENGTH = 64, + parameter PFC_ENABLE = 1, + parameter LFC_ENABLE = PFC_ENABLE, parameter TX_FIFO_DEPTH = 32768, parameter RX_FIFO_DEPTH = 131072, parameter MAX_TX_SIZE = 9214, @@ -223,6 +222,10 @@ module fpga_core # output wire qsfpdda_mac_1_tx_axis_tlast, output wire [AXIS_ETH_TX_USER_WIDTH-1:0] qsfpdda_mac_1_tx_axis_tuser, + input wire qsfpdda_mac_1_tx_status, + output wire qsfpdda_mac_1_tx_lfc_req, + output wire [7:0] qsfpdda_mac_1_tx_pfc_req, + input wire [AXIS_ETH_DATA_WIDTH-1:0] qsfpdda_mac_1_rx_axis_tdata, input wire [AXIS_ETH_KEEP_WIDTH-1:0] qsfpdda_mac_1_rx_axis_tkeep, input wire qsfpdda_mac_1_rx_axis_tvalid, @@ -230,6 +233,8 @@ module fpga_core # input wire [AXIS_ETH_RX_USER_WIDTH-1:0] qsfpdda_mac_1_rx_axis_tuser, input wire qsfpdda_mac_1_rx_status, + input wire qsfpdda_mac_1_rx_lfc_req, + input wire [7:0] qsfpdda_mac_1_rx_pfc_req, input wire qsfpdda_mac_2_clk, input wire qsfpdda_mac_2_rst, @@ -247,6 +252,10 @@ module fpga_core # output wire qsfpdda_mac_2_tx_axis_tlast, output wire [AXIS_ETH_TX_USER_WIDTH-1:0] qsfpdda_mac_2_tx_axis_tuser, + input wire qsfpdda_mac_2_tx_status, + output wire qsfpdda_mac_2_tx_lfc_req, + output wire [7:0] qsfpdda_mac_2_tx_pfc_req, + input wire [AXIS_ETH_DATA_WIDTH-1:0] qsfpdda_mac_2_rx_axis_tdata, input wire [AXIS_ETH_KEEP_WIDTH-1:0] qsfpdda_mac_2_rx_axis_tkeep, input wire qsfpdda_mac_2_rx_axis_tvalid, @@ -254,6 +263,8 @@ module fpga_core # input wire [AXIS_ETH_RX_USER_WIDTH-1:0] qsfpdda_mac_2_rx_axis_tuser, input wire qsfpdda_mac_2_rx_status, + input wire qsfpdda_mac_2_rx_lfc_req, + input wire [7:0] qsfpdda_mac_2_rx_pfc_req, output wire qsfpdda_initmode, input wire qsfpdda_interrupt_n, @@ -283,6 +294,10 @@ module fpga_core # output wire qsfpddb_mac_1_tx_axis_tlast, output wire [AXIS_ETH_TX_USER_WIDTH-1:0] qsfpddb_mac_1_tx_axis_tuser, + input wire qsfpddb_mac_1_tx_status, + output wire qsfpddb_mac_1_tx_lfc_req, + output wire [7:0] qsfpddb_mac_1_tx_pfc_req, + input wire [AXIS_ETH_DATA_WIDTH-1:0] qsfpddb_mac_1_rx_axis_tdata, input wire [AXIS_ETH_KEEP_WIDTH-1:0] qsfpddb_mac_1_rx_axis_tkeep, input wire qsfpddb_mac_1_rx_axis_tvalid, @@ -290,6 +305,8 @@ module fpga_core # input wire [AXIS_ETH_RX_USER_WIDTH-1:0] qsfpddb_mac_1_rx_axis_tuser, input wire qsfpddb_mac_1_rx_status, + input wire qsfpddb_mac_1_rx_lfc_req, + input wire [7:0] qsfpddb_mac_1_rx_pfc_req, input wire qsfpddb_mac_2_clk, input wire qsfpddb_mac_2_rst, @@ -307,6 +324,10 @@ module fpga_core # output wire qsfpddb_mac_2_tx_axis_tlast, output wire [AXIS_ETH_TX_USER_WIDTH-1:0] qsfpddb_mac_2_tx_axis_tuser, + input wire qsfpddb_mac_2_tx_status, + output wire qsfpddb_mac_2_tx_lfc_req, + output wire [7:0] qsfpddb_mac_2_tx_pfc_req, + input wire [AXIS_ETH_DATA_WIDTH-1:0] qsfpddb_mac_2_rx_axis_tdata, input wire [AXIS_ETH_KEEP_WIDTH-1:0] qsfpddb_mac_2_rx_axis_tkeep, input wire qsfpddb_mac_2_rx_axis_tvalid, @@ -314,6 +335,8 @@ module fpga_core # input wire [AXIS_ETH_RX_USER_WIDTH-1:0] qsfpddb_mac_2_rx_axis_tuser, input wire qsfpddb_mac_2_rx_status, + input wire qsfpddb_mac_2_rx_lfc_req, + input wire [7:0] qsfpddb_mac_2_rx_pfc_req, output wire qsfpddb_initmode, input wire qsfpddb_interrupt_n, @@ -640,7 +663,12 @@ mqnic_port_map_mac_axis_inst ( .s_axis_mac_tx_ptp_ts_valid({qsfpddb_mac_2_tx_ptp_ts_valid, qsfpddb_mac_1_tx_ptp_ts_valid, qsfpdda_mac_2_tx_ptp_ts_valid, qsfpdda_mac_1_tx_ptp_ts_valid}), .s_axis_mac_tx_ptp_ts_ready(), - .mac_tx_status(4'hf), + .mac_tx_enable(), + .mac_tx_status({qsfpddb_mac_2_tx_status, qsfpddb_mac_1_tx_status, qsfpdda_mac_2_tx_status, qsfpdda_mac_1_tx_status}), + .mac_tx_lfc_en(), + .mac_tx_lfc_req({qsfpddb_mac_2_tx_lfc_req, qsfpddb_mac_1_tx_lfc_req, qsfpdda_mac_2_tx_lfc_req, qsfpdda_mac_1_tx_lfc_req}), + .mac_tx_pfc_en(), + .mac_tx_pfc_req({qsfpddb_mac_2_tx_pfc_req, qsfpddb_mac_1_tx_pfc_req, qsfpdda_mac_2_tx_pfc_req, qsfpdda_mac_1_tx_pfc_req}), .mac_rx_clk({qsfpddb_mac_2_clk, qsfpddb_mac_1_clk, qsfpdda_mac_2_clk, qsfpdda_mac_1_clk}), .mac_rx_rst({qsfpddb_mac_2_rst, qsfpddb_mac_1_rst, qsfpdda_mac_2_rst, qsfpdda_mac_1_rst}), @@ -657,7 +685,14 @@ mqnic_port_map_mac_axis_inst ( .s_axis_mac_rx_tlast({qsfpddb_mac_2_rx_axis_tlast, qsfpddb_mac_1_rx_axis_tlast, qsfpdda_mac_2_rx_axis_tlast, qsfpdda_mac_1_rx_axis_tlast}), .s_axis_mac_rx_tuser({qsfpddb_mac_2_rx_axis_tuser, qsfpddb_mac_1_rx_axis_tuser, qsfpdda_mac_2_rx_axis_tuser, qsfpdda_mac_1_rx_axis_tuser}), + .mac_rx_enable(), .mac_rx_status({qsfpddb_mac_2_rx_status, qsfpddb_mac_1_rx_status, qsfpdda_mac_2_rx_status, qsfpdda_mac_1_rx_status}), + .mac_rx_lfc_en(), + .mac_rx_lfc_req({qsfpddb_mac_2_rx_lfc_req, qsfpddb_mac_1_rx_lfc_req, qsfpdda_mac_2_rx_lfc_req, qsfpdda_mac_1_rx_lfc_req}), + .mac_rx_lfc_ack(), + .mac_rx_pfc_en(), + .mac_rx_pfc_req({qsfpddb_mac_2_rx_pfc_req, qsfpddb_mac_1_rx_pfc_req, qsfpdda_mac_2_rx_pfc_req, qsfpdda_mac_1_rx_pfc_req}), + .mac_rx_pfc_ack(), // towards datapath .tx_clk(eth_tx_clk), @@ -767,6 +802,9 @@ mqnic_core_pcie_ptile #( .TX_CHECKSUM_ENABLE(TX_CHECKSUM_ENABLE), .RX_HASH_ENABLE(RX_HASH_ENABLE), .RX_CHECKSUM_ENABLE(RX_CHECKSUM_ENABLE), + .PFC_ENABLE(PFC_ENABLE), + .LFC_ENABLE(LFC_ENABLE), + .MAC_CTRL_ENABLE(0), .TX_FIFO_DEPTH(TX_FIFO_DEPTH), .RX_FIFO_DEPTH(RX_FIFO_DEPTH), .MAX_TX_SIZE(MAX_TX_SIZE), diff --git a/fpga/mqnic/DE10_Agilex/fpga_100g/tb/fpga_core/Makefile b/fpga/mqnic/DE10_Agilex/fpga_100g/tb/fpga_core/Makefile index c348eceef..959c3c35d 100644 --- a/fpga/mqnic/DE10_Agilex/fpga_100g/tb/fpga_core/Makefile +++ b/fpga/mqnic/DE10_Agilex/fpga_100g/tb/fpga_core/Makefile @@ -166,6 +166,8 @@ export PARAM_TX_CPL_FIFO_DEPTH := 32 export PARAM_TX_CHECKSUM_ENABLE := 1 export PARAM_RX_HASH_ENABLE := 1 export PARAM_RX_CHECKSUM_ENABLE := 1 +export PARAM_LFC_ENABLE := 1 +export PARAM_PFC_ENABLE := $(PARAM_LFC_ENABLE) export PARAM_TX_FIFO_DEPTH := 32768 export PARAM_RX_FIFO_DEPTH := 131072 export PARAM_MAX_TX_SIZE := 9214 diff --git a/fpga/mqnic/DE10_Agilex/fpga_100g/tb/fpga_core/test_fpga_core.py b/fpga/mqnic/DE10_Agilex/fpga_100g/tb/fpga_core/test_fpga_core.py index 3c6f4e02d..980f96717 100644 --- a/fpga/mqnic/DE10_Agilex/fpga_100g/tb/fpga_core/test_fpga_core.py +++ b/fpga/mqnic/DE10_Agilex/fpga_100g/tb/fpga_core/test_fpga_core.py @@ -279,6 +279,8 @@ class TB(object): macs.append(mac) getattr(dut, f"qsfpdd{x}_mac_{y}_rx_status").setimmediatevalue(1) + getattr(dut, f"qsfpdd{x}_mac_{y}_rx_lfc_req").setimmediatevalue(0) + getattr(dut, f"qsfpdd{x}_mac_{y}_rx_pfc_req").setimmediatevalue(0) self.qsfpdd_mac.append(macs) @@ -703,6 +705,8 @@ def test_fpga_core(request): parameters['TX_CHECKSUM_ENABLE'] = 1 parameters['RX_HASH_ENABLE'] = 1 parameters['RX_CHECKSUM_ENABLE'] = 1 + parameters['LFC_ENABLE'] = 1 + parameters['PFC_ENABLE'] = parameters['LFC_ENABLE'] parameters['TX_FIFO_DEPTH'] = 32768 parameters['RX_FIFO_DEPTH'] = 131072 parameters['MAX_TX_SIZE'] = 9214 diff --git a/fpga/mqnic/DE10_Agilex/fpga_25g/fpga/config.tcl b/fpga/mqnic/DE10_Agilex/fpga_25g/fpga/config.tcl index 73d1ea647..ef47cf431 100644 --- a/fpga/mqnic/DE10_Agilex/fpga_25g/fpga/config.tcl +++ b/fpga/mqnic/DE10_Agilex/fpga_25g/fpga/config.tcl @@ -100,6 +100,8 @@ dict set params TX_CPL_FIFO_DEPTH "32" dict set params TX_CHECKSUM_ENABLE "1" dict set params RX_HASH_ENABLE "1" dict set params RX_CHECKSUM_ENABLE "1" +dict set params PFC_ENABLE "1" +dict set params LFC_ENABLE [dict get $params PFC_ENABLE] dict set params TX_FIFO_DEPTH "32768" dict set params RX_FIFO_DEPTH "32768" dict set params MAX_TX_SIZE "9214" diff --git a/fpga/mqnic/DE10_Agilex/fpga_25g/fpga_10g/config.tcl b/fpga/mqnic/DE10_Agilex/fpga_25g/fpga_10g/config.tcl index d7178479c..34ba745d3 100644 --- a/fpga/mqnic/DE10_Agilex/fpga_25g/fpga_10g/config.tcl +++ b/fpga/mqnic/DE10_Agilex/fpga_25g/fpga_10g/config.tcl @@ -100,6 +100,8 @@ dict set params TX_CPL_FIFO_DEPTH "32" dict set params TX_CHECKSUM_ENABLE "1" dict set params RX_HASH_ENABLE "1" dict set params RX_CHECKSUM_ENABLE "1" +dict set params PFC_ENABLE "1" +dict set params LFC_ENABLE [dict get $params PFC_ENABLE] dict set params TX_FIFO_DEPTH "32768" dict set params RX_FIFO_DEPTH "32768" dict set params MAX_TX_SIZE "9214" diff --git a/fpga/mqnic/DE10_Agilex/fpga_25g/fpga_10g_24AR0/config.tcl b/fpga/mqnic/DE10_Agilex/fpga_25g/fpga_10g_24AR0/config.tcl index 2378a5797..7ce174ca7 100644 --- a/fpga/mqnic/DE10_Agilex/fpga_25g/fpga_10g_24AR0/config.tcl +++ b/fpga/mqnic/DE10_Agilex/fpga_25g/fpga_10g_24AR0/config.tcl @@ -100,6 +100,8 @@ dict set params TX_CPL_FIFO_DEPTH "32" dict set params TX_CHECKSUM_ENABLE "1" dict set params RX_HASH_ENABLE "1" dict set params RX_CHECKSUM_ENABLE "1" +dict set params PFC_ENABLE "1" +dict set params LFC_ENABLE [dict get $params PFC_ENABLE] dict set params TX_FIFO_DEPTH "32768" dict set params RX_FIFO_DEPTH "32768" dict set params MAX_TX_SIZE "9214" diff --git a/fpga/mqnic/DE10_Agilex/fpga_25g/fpga_24AR0/config.tcl b/fpga/mqnic/DE10_Agilex/fpga_25g/fpga_24AR0/config.tcl index cdc908ea6..6eefebbc3 100644 --- a/fpga/mqnic/DE10_Agilex/fpga_25g/fpga_24AR0/config.tcl +++ b/fpga/mqnic/DE10_Agilex/fpga_25g/fpga_24AR0/config.tcl @@ -100,6 +100,8 @@ dict set params TX_CPL_FIFO_DEPTH "32" dict set params TX_CHECKSUM_ENABLE "1" dict set params RX_HASH_ENABLE "1" dict set params RX_CHECKSUM_ENABLE "1" +dict set params PFC_ENABLE "1" +dict set params LFC_ENABLE [dict get $params PFC_ENABLE] dict set params TX_FIFO_DEPTH "32768" dict set params RX_FIFO_DEPTH "32768" dict set params MAX_TX_SIZE "9214" diff --git a/fpga/mqnic/DE10_Agilex/fpga_25g/rtl/eth_mac_dual_quad_wrapper.v b/fpga/mqnic/DE10_Agilex/fpga_25g/rtl/eth_mac_dual_quad_wrapper.v index d7f29c044..ce159801a 100644 --- a/fpga/mqnic/DE10_Agilex/fpga_25g/rtl/eth_mac_dual_quad_wrapper.v +++ b/fpga/mqnic/DE10_Agilex/fpga_25g/rtl/eth_mac_dual_quad_wrapper.v @@ -70,6 +70,10 @@ module eth_mac_dual_quad_wrapper # input wire mac_1_tx_axis_tlast, input wire [TX_USER_WIDTH-1:0] mac_1_tx_axis_tuser, + output wire mac_1_tx_status, + input wire mac_1_tx_lfc_req, + input wire [7:0] mac_1_tx_pfc_req, + output wire mac_1_rx_clk, output wire mac_1_rx_rst, @@ -84,6 +88,8 @@ module eth_mac_dual_quad_wrapper # output wire [RX_USER_WIDTH-1:0] mac_1_rx_axis_tuser, output wire mac_1_rx_status, + output wire mac_1_rx_lfc_req, + output wire [7:0] mac_1_rx_pfc_req, output wire mac_2_tx_clk, output wire mac_2_tx_rst, @@ -103,6 +109,10 @@ module eth_mac_dual_quad_wrapper # input wire mac_2_tx_axis_tlast, input wire [TX_USER_WIDTH-1:0] mac_2_tx_axis_tuser, + output wire mac_2_tx_status, + input wire mac_2_tx_lfc_req, + input wire [7:0] mac_2_tx_pfc_req, + output wire mac_2_rx_clk, output wire mac_2_rx_rst, @@ -117,6 +127,8 @@ module eth_mac_dual_quad_wrapper # output wire [RX_USER_WIDTH-1:0] mac_2_rx_axis_tuser, output wire mac_2_rx_status, + output wire mac_2_rx_lfc_req, + output wire [7:0] mac_2_rx_pfc_req, output wire mac_3_tx_clk, output wire mac_3_tx_rst, @@ -136,6 +148,10 @@ module eth_mac_dual_quad_wrapper # input wire mac_3_tx_axis_tlast, input wire [TX_USER_WIDTH-1:0] mac_3_tx_axis_tuser, + output wire mac_3_tx_status, + input wire mac_3_tx_lfc_req, + input wire [7:0] mac_3_tx_pfc_req, + output wire mac_3_rx_clk, output wire mac_3_rx_rst, @@ -150,6 +166,8 @@ module eth_mac_dual_quad_wrapper # output wire [RX_USER_WIDTH-1:0] mac_3_rx_axis_tuser, output wire mac_3_rx_status, + output wire mac_3_rx_lfc_req, + output wire [7:0] mac_3_rx_pfc_req, output wire mac_4_tx_clk, output wire mac_4_tx_rst, @@ -169,12 +187,16 @@ module eth_mac_dual_quad_wrapper # input wire mac_4_tx_axis_tlast, input wire [TX_USER_WIDTH-1:0] mac_4_tx_axis_tuser, + output wire mac_4_tx_status, + input wire mac_4_tx_lfc_req, + input wire [7:0] mac_4_tx_pfc_req, + output wire mac_4_rx_clk, output wire mac_4_rx_rst, output wire mac_4_rx_ptp_clk, output wire mac_4_rx_ptp_rst, - output wire [PTP_TS_WIDTH-1:0] mac_4_rx_ptp_time, + input wire [PTP_TS_WIDTH-1:0] mac_4_rx_ptp_time, output wire [DATA_WIDTH-1:0] mac_4_rx_axis_tdata, output wire [KEEP_WIDTH-1:0] mac_4_rx_axis_tkeep, @@ -183,6 +205,8 @@ module eth_mac_dual_quad_wrapper # output wire [RX_USER_WIDTH-1:0] mac_4_rx_axis_tuser, output wire mac_4_rx_status, + output wire mac_4_rx_lfc_req, + output wire [7:0] mac_4_rx_pfc_req, output wire mac_5_tx_clk, output wire mac_5_tx_rst, @@ -202,6 +226,10 @@ module eth_mac_dual_quad_wrapper # input wire mac_5_tx_axis_tlast, input wire [TX_USER_WIDTH-1:0] mac_5_tx_axis_tuser, + output wire mac_5_tx_status, + input wire mac_5_tx_lfc_req, + input wire [7:0] mac_5_tx_pfc_req, + output wire mac_5_rx_clk, output wire mac_5_rx_rst, @@ -216,6 +244,8 @@ module eth_mac_dual_quad_wrapper # output wire [RX_USER_WIDTH-1:0] mac_5_rx_axis_tuser, output wire mac_5_rx_status, + output wire mac_5_rx_lfc_req, + output wire [7:0] mac_5_rx_pfc_req, output wire mac_6_tx_clk, output wire mac_6_tx_rst, @@ -235,6 +265,10 @@ module eth_mac_dual_quad_wrapper # input wire mac_6_tx_axis_tlast, input wire [TX_USER_WIDTH-1:0] mac_6_tx_axis_tuser, + output wire mac_6_tx_status, + input wire mac_6_tx_lfc_req, + input wire [7:0] mac_6_tx_pfc_req, + output wire mac_6_rx_clk, output wire mac_6_rx_rst, @@ -249,6 +283,8 @@ module eth_mac_dual_quad_wrapper # output wire [RX_USER_WIDTH-1:0] mac_6_rx_axis_tuser, output wire mac_6_rx_status, + output wire mac_6_rx_lfc_req, + output wire [7:0] mac_6_rx_pfc_req, output wire mac_7_tx_clk, output wire mac_7_tx_rst, @@ -268,6 +304,10 @@ module eth_mac_dual_quad_wrapper # input wire mac_7_tx_axis_tlast, input wire [TX_USER_WIDTH-1:0] mac_7_tx_axis_tuser, + output wire mac_7_tx_status, + input wire mac_7_tx_lfc_req, + input wire [7:0] mac_7_tx_pfc_req, + output wire mac_7_rx_clk, output wire mac_7_rx_rst, @@ -282,6 +322,8 @@ module eth_mac_dual_quad_wrapper # output wire [RX_USER_WIDTH-1:0] mac_7_rx_axis_tuser, output wire mac_7_rx_status, + output wire mac_7_rx_lfc_req, + output wire [7:0] mac_7_rx_pfc_req, output wire mac_8_tx_clk, output wire mac_8_tx_rst, @@ -301,12 +343,16 @@ module eth_mac_dual_quad_wrapper # input wire mac_8_tx_axis_tlast, input wire [TX_USER_WIDTH-1:0] mac_8_tx_axis_tuser, + output wire mac_8_tx_status, + input wire mac_8_tx_lfc_req, + input wire [7:0] mac_8_tx_pfc_req, + output wire mac_8_rx_clk, output wire mac_8_rx_rst, output wire mac_8_rx_ptp_clk, output wire mac_8_rx_ptp_rst, - output wire [PTP_TS_WIDTH-1:0] mac_8_rx_ptp_time, + input wire [PTP_TS_WIDTH-1:0] mac_8_rx_ptp_time, output wire [DATA_WIDTH-1:0] mac_8_rx_axis_tdata, output wire [KEEP_WIDTH-1:0] mac_8_rx_axis_tkeep, @@ -314,7 +360,9 @@ module eth_mac_dual_quad_wrapper # output wire mac_8_rx_axis_tlast, output wire [RX_USER_WIDTH-1:0] mac_8_rx_axis_tuser, - output wire mac_8_rx_status + output wire mac_8_rx_status, + output wire mac_8_rx_lfc_req, + output wire [7:0] mac_8_rx_pfc_req ); parameter N_CH = 8; @@ -370,6 +418,11 @@ wire [N_CH-1:0] mac_rx_endofpacket; wire [N_CH*3-1:0] mac_rx_empty; wire [N_CH*6-1:0] mac_rx_error; +wire [N_CH*8-1:0] mac_tx_pfc; +wire [N_CH*8-1:0] mac_rx_pfc; +wire [N_CH-1:0] mac_tx_pause; +wire [N_CH-1:0] mac_rx_pause; + generate if (MAC_RSFEC) begin @@ -456,10 +509,10 @@ if (MAC_RSFEC) begin .o_sl_rx_error (mac_rx_error[0*4*6 +: 4*6]), .o_sl_rxstatus_data (), .o_sl_rxstatus_valid (), - .i_sl_tx_pfc ({4{8'd0}}), - .o_sl_rx_pfc (), - .i_sl_tx_pause ({4{1'b0}}), - .o_sl_rx_pause (), + .i_sl_tx_pfc (mac_tx_pfc[0*4*8 +: 4*8]), + .o_sl_rx_pfc (mac_rx_pfc[0*4*8 +: 4*8]), + .i_sl_tx_pause (mac_tx_pause[0*4*1 +: 4*1]), + .o_sl_rx_pause (mac_rx_pause[0*4*1 +: 4*1]), .i_sl_ptp_tx_tod (mac_ptp_tx_tod[0*4*PTP_TS_WIDTH +: 4*PTP_TS_WIDTH]), .i_sl_ptp_rx_tod (mac_ptp_rx_tod[0*4*PTP_TS_WIDTH +: 4*PTP_TS_WIDTH]), .i_sl_ptp_ts_req ({4{1'b1}}), @@ -565,10 +618,10 @@ if (MAC_RSFEC) begin .o_sl_rx_error (mac_rx_error[1*4*6 +: 4*6]), .o_sl_rxstatus_data (), .o_sl_rxstatus_valid (), - .i_sl_tx_pfc ({4{8'd0}}), - .o_sl_rx_pfc (), - .i_sl_tx_pause ({4{1'b0}}), - .o_sl_rx_pause (), + .i_sl_tx_pfc (mac_tx_pfc[1*4*8 +: 4*8]), + .o_sl_rx_pfc (mac_rx_pfc[1*4*8 +: 4*8]), + .i_sl_tx_pause (mac_tx_pause[1*4*1 +: 4*1]), + .o_sl_rx_pause (mac_rx_pause[1*4*1 +: 4*1]), .i_sl_ptp_tx_tod (mac_ptp_tx_tod[1*4*PTP_TS_WIDTH +: 4*PTP_TS_WIDTH]), .i_sl_ptp_rx_tod (mac_ptp_rx_tod[1*4*PTP_TS_WIDTH +: 4*PTP_TS_WIDTH]), .i_sl_ptp_ts_req ({4{1'b1}}), @@ -670,10 +723,10 @@ end else begin .o_sl_rx_error (mac_rx_error[0*4*6 +: 4*6]), .o_sl_rxstatus_data (), .o_sl_rxstatus_valid (), - .i_sl_tx_pfc ({4{8'd0}}), - .o_sl_rx_pfc (), - .i_sl_tx_pause ({4{1'b0}}), - .o_sl_rx_pause (), + .i_sl_tx_pfc (mac_tx_pfc[0*4*8 +: 4*8]), + .o_sl_rx_pfc (mac_rx_pfc[0*4*8 +: 4*8]), + .i_sl_tx_pause (mac_tx_pause[0*4*1 +: 4*1]), + .o_sl_rx_pause (mac_rx_pause[0*4*1 +: 4*1]), .i_sl_ptp_tx_tod (mac_ptp_tx_tod[0*4*PTP_TS_WIDTH +: 4*PTP_TS_WIDTH]), .i_sl_ptp_rx_tod (mac_ptp_rx_tod[0*4*PTP_TS_WIDTH +: 4*PTP_TS_WIDTH]), .i_sl_ptp_ts_req ({4{1'b1}}), @@ -773,10 +826,10 @@ end else begin .o_sl_rx_error (mac_rx_error[1*4*6 +: 4*6]), .o_sl_rxstatus_data (), .o_sl_rxstatus_valid (), - .i_sl_tx_pfc ({4{8'd0}}), - .o_sl_rx_pfc (), - .i_sl_tx_pause ({4{1'b0}}), - .o_sl_rx_pause (), + .i_sl_tx_pfc (mac_tx_pfc[1*4*8 +: 4*8]), + .o_sl_rx_pfc (mac_rx_pfc[1*4*8 +: 4*8]), + .i_sl_tx_pause (mac_tx_pause[1*4*1 +: 4*1]), + .o_sl_rx_pause (mac_rx_pause[1*4*1 +: 4*1]), .i_sl_ptp_tx_tod (mac_ptp_tx_tod[1*4*PTP_TS_WIDTH +: 4*PTP_TS_WIDTH]), .i_sl_ptp_rx_tod (mac_ptp_rx_tod[1*4*PTP_TS_WIDTH +: 4*PTP_TS_WIDTH]), .i_sl_ptp_ts_req ({4{1'b1}}), @@ -847,6 +900,10 @@ assign mac_1_tx_axis_tready = mac_tx_axis_tready[0]; assign mac_tx_axis_tlast[0] = mac_1_tx_axis_tlast; assign mac_tx_axis_tuser[0*TX_USER_WIDTH +: TX_USER_WIDTH] = mac_1_tx_axis_tuser; +assign mac_1_tx_status = mac_tx_lanes_stable[0*1 +: 1]; +assign mac_tx_pause[0*1 +: 1] = mac_1_tx_lfc_req; +assign mac_tx_pfc[0*8 +: 8] = mac_1_tx_pfc_req; + assign mac_1_rx_clk = mac_rx_clk[0]; assign mac_1_rx_rst = mac_rx_rst[0]; @@ -860,7 +917,9 @@ assign mac_1_rx_axis_tvalid = mac_rx_axis_tvalid[0]; assign mac_1_rx_axis_tlast = mac_rx_axis_tlast[0]; assign mac_1_rx_axis_tuser = mac_rx_axis_tuser[0*RX_USER_WIDTH +: RX_USER_WIDTH]; -assign mac_1_rx_status = mac_rx_pcs_ready[0]; +assign mac_1_rx_status = mac_rx_pcs_ready[0*1 +: 1]; +assign mac_1_rx_lfc_req = mac_rx_pause[0*1 +: 1]; +assign mac_1_rx_pfc_req = mac_rx_pfc[0*8 +: 8]; assign mac_2_tx_clk = mac_tx_clk[1]; assign mac_2_tx_rst = mac_tx_rst[1]; @@ -880,6 +939,10 @@ assign mac_2_tx_axis_tready = mac_tx_axis_tready[1]; assign mac_tx_axis_tlast[1] = mac_2_tx_axis_tlast; assign mac_tx_axis_tuser[1*TX_USER_WIDTH +: TX_USER_WIDTH] = mac_2_tx_axis_tuser; +assign mac_2_tx_status = mac_tx_lanes_stable[1*1 +: 1]; +assign mac_tx_pause[1*1 +: 1] = mac_2_tx_lfc_req; +assign mac_tx_pfc[1*8 +: 8] = mac_2_tx_pfc_req; + assign mac_2_rx_clk = mac_rx_clk[1]; assign mac_2_rx_rst = mac_rx_rst[1]; @@ -893,7 +956,9 @@ assign mac_2_rx_axis_tvalid = mac_rx_axis_tvalid[1]; assign mac_2_rx_axis_tlast = mac_rx_axis_tlast[1]; assign mac_2_rx_axis_tuser = mac_rx_axis_tuser[1*RX_USER_WIDTH +: RX_USER_WIDTH]; -assign mac_2_rx_status = mac_rx_pcs_ready[1]; +assign mac_2_rx_status = mac_rx_pcs_ready[1*1 +: 1]; +assign mac_2_rx_lfc_req = mac_rx_pause[1*1 +: 1]; +assign mac_2_rx_pfc_req = mac_rx_pfc[1*8 +: 8]; assign mac_3_tx_clk = mac_tx_clk[2]; assign mac_3_tx_rst = mac_tx_rst[2]; @@ -913,6 +978,10 @@ assign mac_3_tx_axis_tready = mac_tx_axis_tready[2]; assign mac_tx_axis_tlast[2] = mac_3_tx_axis_tlast; assign mac_tx_axis_tuser[2*TX_USER_WIDTH +: TX_USER_WIDTH] = mac_3_tx_axis_tuser; +assign mac_3_tx_status = mac_tx_lanes_stable[2*1 +: 1]; +assign mac_tx_pause[2*1 +: 1] = mac_3_tx_lfc_req; +assign mac_tx_pfc[2*8 +: 8] = mac_3_tx_pfc_req; + assign mac_3_rx_clk = mac_rx_clk[2]; assign mac_3_rx_rst = mac_rx_rst[2]; @@ -926,7 +995,9 @@ assign mac_3_rx_axis_tvalid = mac_rx_axis_tvalid[2]; assign mac_3_rx_axis_tlast = mac_rx_axis_tlast[2]; assign mac_3_rx_axis_tuser = mac_rx_axis_tuser[2*RX_USER_WIDTH +: RX_USER_WIDTH]; -assign mac_3_rx_status = mac_rx_pcs_ready[2]; +assign mac_3_rx_status = mac_rx_pcs_ready[2*1 +: 1]; +assign mac_3_rx_lfc_req = mac_rx_pause[2*1 +: 1]; +assign mac_3_rx_pfc_req = mac_rx_pfc[2*8 +: 8]; assign mac_4_tx_clk = mac_tx_clk[3]; assign mac_4_tx_rst = mac_tx_rst[3]; @@ -946,6 +1017,10 @@ assign mac_4_tx_axis_tready = mac_tx_axis_tready[3]; assign mac_tx_axis_tlast[3] = mac_4_tx_axis_tlast; assign mac_tx_axis_tuser[3*TX_USER_WIDTH +: TX_USER_WIDTH] = mac_4_tx_axis_tuser; +assign mac_4_tx_status = mac_tx_lanes_stable[3*1 +: 1]; +assign mac_tx_pause[3*1 +: 1] = mac_4_tx_lfc_req; +assign mac_tx_pfc[3*8 +: 8] = mac_4_tx_pfc_req; + assign mac_4_rx_clk = mac_rx_clk[3]; assign mac_4_rx_rst = mac_rx_rst[3]; @@ -959,7 +1034,9 @@ assign mac_4_rx_axis_tvalid = mac_rx_axis_tvalid[3]; assign mac_4_rx_axis_tlast = mac_rx_axis_tlast[3]; assign mac_4_rx_axis_tuser = mac_rx_axis_tuser[3*RX_USER_WIDTH +: RX_USER_WIDTH]; -assign mac_4_rx_status = mac_rx_pcs_ready[3]; +assign mac_4_rx_status = mac_rx_pcs_ready[3*1 +: 1]; +assign mac_4_rx_lfc_req = mac_rx_pause[3*1 +: 1]; +assign mac_4_rx_pfc_req = mac_rx_pfc[3*8 +: 8]; assign mac_5_tx_clk = mac_tx_clk[4]; assign mac_5_tx_rst = mac_tx_rst[4]; @@ -979,6 +1056,10 @@ assign mac_5_tx_axis_tready = mac_tx_axis_tready[4]; assign mac_tx_axis_tlast[4] = mac_5_tx_axis_tlast; assign mac_tx_axis_tuser[4*TX_USER_WIDTH +: TX_USER_WIDTH] = mac_5_tx_axis_tuser; +assign mac_5_tx_status = mac_tx_lanes_stable[4*1 +: 1]; +assign mac_tx_pause[4*1 +: 1] = mac_5_tx_lfc_req; +assign mac_tx_pfc[4*8 +: 8] = mac_5_tx_pfc_req; + assign mac_5_rx_clk = mac_rx_clk[4]; assign mac_5_rx_rst = mac_rx_rst[4]; @@ -992,7 +1073,9 @@ assign mac_5_rx_axis_tvalid = mac_rx_axis_tvalid[4]; assign mac_5_rx_axis_tlast = mac_rx_axis_tlast[4]; assign mac_5_rx_axis_tuser = mac_rx_axis_tuser[4*RX_USER_WIDTH +: RX_USER_WIDTH]; -assign mac_5_rx_status = mac_rx_pcs_ready[4]; +assign mac_5_rx_status = mac_rx_pcs_ready[4*1 +: 1]; +assign mac_5_rx_lfc_req = mac_rx_pause[4*1 +: 1]; +assign mac_5_rx_pfc_req = mac_rx_pfc[4*8 +: 8]; assign mac_6_tx_clk = mac_tx_clk[5]; assign mac_6_tx_rst = mac_tx_rst[5]; @@ -1012,6 +1095,10 @@ assign mac_6_tx_axis_tready = mac_tx_axis_tready[5]; assign mac_tx_axis_tlast[5] = mac_6_tx_axis_tlast; assign mac_tx_axis_tuser[5*TX_USER_WIDTH +: TX_USER_WIDTH] = mac_6_tx_axis_tuser; +assign mac_6_tx_status = mac_tx_lanes_stable[5*1 +: 1]; +assign mac_tx_pause[5*1 +: 1] = mac_6_tx_lfc_req; +assign mac_tx_pfc[5*8 +: 8] = mac_6_tx_pfc_req; + assign mac_6_rx_clk = mac_rx_clk[5]; assign mac_6_rx_rst = mac_rx_rst[5]; @@ -1025,7 +1112,9 @@ assign mac_6_rx_axis_tvalid = mac_rx_axis_tvalid[5]; assign mac_6_rx_axis_tlast = mac_rx_axis_tlast[5]; assign mac_6_rx_axis_tuser = mac_rx_axis_tuser[5*RX_USER_WIDTH +: RX_USER_WIDTH]; -assign mac_6_rx_status = mac_rx_pcs_ready[5]; +assign mac_6_rx_status = mac_rx_pcs_ready[5*1 +: 1]; +assign mac_6_rx_lfc_req = mac_rx_pause[5*1 +: 1]; +assign mac_6_rx_pfc_req = mac_rx_pfc[5*8 +: 8]; assign mac_7_tx_clk = mac_tx_clk[6]; assign mac_7_tx_rst = mac_tx_rst[6]; @@ -1045,6 +1134,10 @@ assign mac_7_tx_axis_tready = mac_tx_axis_tready[6]; assign mac_tx_axis_tlast[6] = mac_7_tx_axis_tlast; assign mac_tx_axis_tuser[6*TX_USER_WIDTH +: TX_USER_WIDTH] = mac_7_tx_axis_tuser; +assign mac_7_tx_status = mac_tx_lanes_stable[6*1 +: 1]; +assign mac_tx_pause[6*1 +: 1] = mac_7_tx_lfc_req; +assign mac_tx_pfc[6*8 +: 8] = mac_7_tx_pfc_req; + assign mac_7_rx_clk = mac_rx_clk[6]; assign mac_7_rx_rst = mac_rx_rst[6]; @@ -1058,7 +1151,9 @@ assign mac_7_rx_axis_tvalid = mac_rx_axis_tvalid[6]; assign mac_7_rx_axis_tlast = mac_rx_axis_tlast[6]; assign mac_7_rx_axis_tuser = mac_rx_axis_tuser[6*RX_USER_WIDTH +: RX_USER_WIDTH]; -assign mac_7_rx_status = mac_rx_pcs_ready[6]; +assign mac_7_rx_status = mac_rx_pcs_ready[6*1 +: 1]; +assign mac_7_rx_lfc_req = mac_rx_pause[6*1 +: 1]; +assign mac_7_rx_pfc_req = mac_rx_pfc[6*8 +: 8]; assign mac_8_tx_clk = mac_tx_clk[7]; assign mac_8_tx_rst = mac_tx_rst[7]; @@ -1078,6 +1173,10 @@ assign mac_8_tx_axis_tready = mac_tx_axis_tready[7]; assign mac_tx_axis_tlast[7] = mac_8_tx_axis_tlast; assign mac_tx_axis_tuser[7*TX_USER_WIDTH +: TX_USER_WIDTH] = mac_8_tx_axis_tuser; +assign mac_8_tx_status = mac_tx_lanes_stable[7*1 +: 1]; +assign mac_tx_pause[7*1 +: 1] = mac_8_tx_lfc_req; +assign mac_tx_pfc[7*8 +: 8] = mac_8_tx_pfc_req; + assign mac_8_rx_clk = mac_rx_clk[7]; assign mac_8_rx_rst = mac_rx_rst[7]; @@ -1091,7 +1190,9 @@ assign mac_8_rx_axis_tvalid = mac_rx_axis_tvalid[7]; assign mac_8_rx_axis_tlast = mac_rx_axis_tlast[7]; assign mac_8_rx_axis_tuser = mac_rx_axis_tuser[7*RX_USER_WIDTH +: RX_USER_WIDTH]; -assign mac_8_rx_status = mac_rx_pcs_ready[7]; +assign mac_8_rx_status = mac_rx_pcs_ready[7*1 +: 1]; +assign mac_8_rx_lfc_req = mac_rx_pause[7*1 +: 1]; +assign mac_8_rx_pfc_req = mac_rx_pfc[7*8 +: 8]; generate diff --git a/fpga/mqnic/DE10_Agilex/fpga_25g/rtl/fpga.v b/fpga/mqnic/DE10_Agilex/fpga_25g/rtl/fpga.v index e976b5818..660766825 100644 --- a/fpga/mqnic/DE10_Agilex/fpga_25g/rtl/fpga.v +++ b/fpga/mqnic/DE10_Agilex/fpga_25g/rtl/fpga.v @@ -71,6 +71,8 @@ module fpga # parameter TX_CHECKSUM_ENABLE = 1, parameter RX_HASH_ENABLE = 1, parameter RX_CHECKSUM_ENABLE = 1, + parameter PFC_ENABLE = 1, + parameter LFC_ENABLE = PFC_ENABLE, parameter TX_FIFO_DEPTH = 32768, parameter RX_FIFO_DEPTH = 32768, parameter MAX_TX_SIZE = 9214, @@ -478,6 +480,10 @@ wire qsfpdda_mac_1_tx_axis_tready_int; wire qsfpdda_mac_1_tx_axis_tlast_int; wire [AXIS_ETH_TX_USER_WIDTH-1:0] qsfpdda_mac_1_tx_axis_tuser_int; +wire qsfpdda_mac_1_tx_status_int; +wire qsfpdda_mac_1_tx_lfc_req_int; +wire [7:0] qsfpdda_mac_1_tx_pfc_req_int; + wire qsfpdda_mac_1_rx_clk_int; wire qsfpdda_mac_1_rx_rst_int; @@ -492,6 +498,8 @@ wire qsfpdda_mac_1_rx_axis_tlast_int; wire [AXIS_ETH_RX_USER_WIDTH-1:0] qsfpdda_mac_1_rx_axis_tuser_int; wire qsfpdda_mac_1_rx_status_int; +wire qsfpdda_mac_1_rx_lfc_req_int; +wire [7:0] qsfpdda_mac_1_rx_pfc_req_int; wire qsfpdda_mac_2_tx_clk_int; wire qsfpdda_mac_2_tx_rst_int; @@ -511,6 +519,10 @@ wire qsfpdda_mac_2_tx_axis_tready_int; wire qsfpdda_mac_2_tx_axis_tlast_int; wire [AXIS_ETH_TX_USER_WIDTH-1:0] qsfpdda_mac_2_tx_axis_tuser_int; +wire qsfpdda_mac_2_tx_status_int; +wire qsfpdda_mac_2_tx_lfc_req_int; +wire [7:0] qsfpdda_mac_2_tx_pfc_req_int; + wire qsfpdda_mac_2_rx_clk_int; wire qsfpdda_mac_2_rx_rst_int; @@ -525,6 +537,8 @@ wire qsfpdda_mac_2_rx_axis_tlast_int; wire [AXIS_ETH_RX_USER_WIDTH-1:0] qsfpdda_mac_2_rx_axis_tuser_int; wire qsfpdda_mac_2_rx_status_int; +wire qsfpdda_mac_2_rx_lfc_req_int; +wire [7:0] qsfpdda_mac_2_rx_pfc_req_int; wire qsfpdda_mac_3_tx_clk_int; wire qsfpdda_mac_3_tx_rst_int; @@ -544,6 +558,10 @@ wire qsfpdda_mac_3_tx_axis_tready_int; wire qsfpdda_mac_3_tx_axis_tlast_int; wire [AXIS_ETH_TX_USER_WIDTH-1:0] qsfpdda_mac_3_tx_axis_tuser_int; +wire qsfpdda_mac_3_tx_status_int; +wire qsfpdda_mac_3_tx_lfc_req_int; +wire [7:0] qsfpdda_mac_3_tx_pfc_req_int; + wire qsfpdda_mac_3_rx_clk_int; wire qsfpdda_mac_3_rx_rst_int; @@ -558,6 +576,8 @@ wire qsfpdda_mac_3_rx_axis_tlast_int; wire [AXIS_ETH_RX_USER_WIDTH-1:0] qsfpdda_mac_3_rx_axis_tuser_int; wire qsfpdda_mac_3_rx_status_int; +wire qsfpdda_mac_3_rx_lfc_req_int; +wire [7:0] qsfpdda_mac_3_rx_pfc_req_int; wire qsfpdda_mac_4_tx_clk_int; wire qsfpdda_mac_4_tx_rst_int; @@ -577,6 +597,10 @@ wire qsfpdda_mac_4_tx_axis_tready_int; wire qsfpdda_mac_4_tx_axis_tlast_int; wire [AXIS_ETH_TX_USER_WIDTH-1:0] qsfpdda_mac_4_tx_axis_tuser_int; +wire qsfpdda_mac_4_tx_status_int; +wire qsfpdda_mac_4_tx_lfc_req_int; +wire [7:0] qsfpdda_mac_4_tx_pfc_req_int; + wire qsfpdda_mac_4_rx_clk_int; wire qsfpdda_mac_4_rx_rst_int; @@ -591,6 +615,8 @@ wire qsfpdda_mac_4_rx_axis_tlast_int; wire [AXIS_ETH_RX_USER_WIDTH-1:0] qsfpdda_mac_4_rx_axis_tuser_int; wire qsfpdda_mac_4_rx_status_int; +wire qsfpdda_mac_4_rx_lfc_req_int; +wire [7:0] qsfpdda_mac_4_rx_pfc_req_int; wire qsfpdda_mac_5_tx_clk_int; wire qsfpdda_mac_5_tx_rst_int; @@ -610,6 +636,10 @@ wire qsfpdda_mac_5_tx_axis_tready_int; wire qsfpdda_mac_5_tx_axis_tlast_int; wire [AXIS_ETH_TX_USER_WIDTH-1:0] qsfpdda_mac_5_tx_axis_tuser_int; +wire qsfpdda_mac_5_tx_status_int; +wire qsfpdda_mac_5_tx_lfc_req_int; +wire [7:0] qsfpdda_mac_5_tx_pfc_req_int; + wire qsfpdda_mac_5_rx_clk_int; wire qsfpdda_mac_5_rx_rst_int; @@ -624,6 +654,8 @@ wire qsfpdda_mac_5_rx_axis_tlast_int; wire [AXIS_ETH_RX_USER_WIDTH-1:0] qsfpdda_mac_5_rx_axis_tuser_int; wire qsfpdda_mac_5_rx_status_int; +wire qsfpdda_mac_5_rx_lfc_req_int; +wire [7:0] qsfpdda_mac_5_rx_pfc_req_int; wire qsfpdda_mac_6_tx_clk_int; wire qsfpdda_mac_6_tx_rst_int; @@ -643,6 +675,10 @@ wire qsfpdda_mac_6_tx_axis_tready_int; wire qsfpdda_mac_6_tx_axis_tlast_int; wire [AXIS_ETH_TX_USER_WIDTH-1:0] qsfpdda_mac_6_tx_axis_tuser_int; +wire qsfpdda_mac_6_tx_status_int; +wire qsfpdda_mac_6_tx_lfc_req_int; +wire [7:0] qsfpdda_mac_6_tx_pfc_req_int; + wire qsfpdda_mac_6_rx_clk_int; wire qsfpdda_mac_6_rx_rst_int; @@ -657,6 +693,8 @@ wire qsfpdda_mac_6_rx_axis_tlast_int; wire [AXIS_ETH_RX_USER_WIDTH-1:0] qsfpdda_mac_6_rx_axis_tuser_int; wire qsfpdda_mac_6_rx_status_int; +wire qsfpdda_mac_6_rx_lfc_req_int; +wire [7:0] qsfpdda_mac_6_rx_pfc_req_int; wire qsfpdda_mac_7_tx_clk_int; wire qsfpdda_mac_7_tx_rst_int; @@ -676,6 +714,10 @@ wire qsfpdda_mac_7_tx_axis_tready_int; wire qsfpdda_mac_7_tx_axis_tlast_int; wire [AXIS_ETH_TX_USER_WIDTH-1:0] qsfpdda_mac_7_tx_axis_tuser_int; +wire qsfpdda_mac_7_tx_status_int; +wire qsfpdda_mac_7_tx_lfc_req_int; +wire [7:0] qsfpdda_mac_7_tx_pfc_req_int; + wire qsfpdda_mac_7_rx_clk_int; wire qsfpdda_mac_7_rx_rst_int; @@ -690,6 +732,8 @@ wire qsfpdda_mac_7_rx_axis_tlast_int; wire [AXIS_ETH_RX_USER_WIDTH-1:0] qsfpdda_mac_7_rx_axis_tuser_int; wire qsfpdda_mac_7_rx_status_int; +wire qsfpdda_mac_7_rx_lfc_req_int; +wire [7:0] qsfpdda_mac_7_rx_pfc_req_int; wire qsfpdda_mac_8_tx_clk_int; wire qsfpdda_mac_8_tx_rst_int; @@ -709,6 +753,10 @@ wire qsfpdda_mac_8_tx_axis_tready_int; wire qsfpdda_mac_8_tx_axis_tlast_int; wire [AXIS_ETH_TX_USER_WIDTH-1:0] qsfpdda_mac_8_tx_axis_tuser_int; +wire qsfpdda_mac_8_tx_status_int; +wire qsfpdda_mac_8_tx_lfc_req_int; +wire [7:0] qsfpdda_mac_8_tx_pfc_req_int; + wire qsfpdda_mac_8_rx_clk_int; wire qsfpdda_mac_8_rx_rst_int; @@ -723,6 +771,8 @@ wire qsfpdda_mac_8_rx_axis_tlast_int; wire [AXIS_ETH_RX_USER_WIDTH-1:0] qsfpdda_mac_8_rx_axis_tuser_int; wire qsfpdda_mac_8_rx_status_int; +wire qsfpdda_mac_8_rx_lfc_req_int; +wire [7:0] qsfpdda_mac_8_rx_pfc_req_int; eth_mac_dual_quad_wrapper #( .PTP_TS_WIDTH(PTP_TS_WIDTH), @@ -762,6 +812,10 @@ qsfpdda_mac_inst ( .mac_1_tx_axis_tlast(qsfpdda_mac_1_tx_axis_tlast_int), .mac_1_tx_axis_tuser(qsfpdda_mac_1_tx_axis_tuser_int), + .mac_1_tx_status(qsfpdda_mac_1_tx_status_int), + .mac_1_tx_lfc_req(qsfpdda_mac_1_tx_lfc_req_int), + .mac_1_tx_pfc_req(qsfpdda_mac_1_tx_pfc_req_int), + .mac_1_rx_clk(qsfpdda_mac_1_rx_clk_int), .mac_1_rx_rst(qsfpdda_mac_1_rx_rst_int), @@ -776,6 +830,8 @@ qsfpdda_mac_inst ( .mac_1_rx_axis_tuser(qsfpdda_mac_1_rx_axis_tuser_int), .mac_1_rx_status(qsfpdda_mac_1_rx_status_int), + .mac_1_rx_lfc_req(qsfpdda_mac_1_rx_lfc_req_int), + .mac_1_rx_pfc_req(qsfpdda_mac_1_rx_pfc_req_int), .mac_2_tx_clk(qsfpdda_mac_3_tx_clk_int), .mac_2_tx_rst(qsfpdda_mac_3_tx_rst_int), @@ -795,6 +851,10 @@ qsfpdda_mac_inst ( .mac_2_tx_axis_tlast(qsfpdda_mac_3_tx_axis_tlast_int), .mac_2_tx_axis_tuser(qsfpdda_mac_3_tx_axis_tuser_int), + .mac_2_tx_status(qsfpdda_mac_3_tx_status_int), + .mac_2_tx_lfc_req(qsfpdda_mac_3_tx_lfc_req_int), + .mac_2_tx_pfc_req(qsfpdda_mac_3_tx_pfc_req_int), + .mac_2_rx_clk(qsfpdda_mac_3_rx_clk_int), .mac_2_rx_rst(qsfpdda_mac_3_rx_rst_int), @@ -809,6 +869,8 @@ qsfpdda_mac_inst ( .mac_2_rx_axis_tuser(qsfpdda_mac_3_rx_axis_tuser_int), .mac_2_rx_status(qsfpdda_mac_3_rx_status_int), + .mac_2_rx_lfc_req(qsfpdda_mac_3_rx_lfc_req_int), + .mac_2_rx_pfc_req(qsfpdda_mac_3_rx_pfc_req_int), .mac_3_tx_clk(qsfpdda_mac_2_tx_clk_int), .mac_3_tx_rst(qsfpdda_mac_2_tx_rst_int), @@ -828,6 +890,10 @@ qsfpdda_mac_inst ( .mac_3_tx_axis_tlast(qsfpdda_mac_2_tx_axis_tlast_int), .mac_3_tx_axis_tuser(qsfpdda_mac_2_tx_axis_tuser_int), + .mac_3_tx_status(qsfpdda_mac_2_tx_status_int), + .mac_3_tx_lfc_req(qsfpdda_mac_2_tx_lfc_req_int), + .mac_3_tx_pfc_req(qsfpdda_mac_2_tx_pfc_req_int), + .mac_3_rx_clk(qsfpdda_mac_2_rx_clk_int), .mac_3_rx_rst(qsfpdda_mac_2_rx_rst_int), @@ -842,6 +908,8 @@ qsfpdda_mac_inst ( .mac_3_rx_axis_tuser(qsfpdda_mac_2_rx_axis_tuser_int), .mac_3_rx_status(qsfpdda_mac_2_rx_status_int), + .mac_3_rx_lfc_req(qsfpdda_mac_2_rx_lfc_req_int), + .mac_3_rx_pfc_req(qsfpdda_mac_2_rx_pfc_req_int), .mac_4_tx_clk(qsfpdda_mac_4_tx_clk_int), .mac_4_tx_rst(qsfpdda_mac_4_tx_rst_int), @@ -861,6 +929,10 @@ qsfpdda_mac_inst ( .mac_4_tx_axis_tlast(qsfpdda_mac_4_tx_axis_tlast_int), .mac_4_tx_axis_tuser(qsfpdda_mac_4_tx_axis_tuser_int), + .mac_4_tx_status(qsfpdda_mac_4_tx_status_int), + .mac_4_tx_lfc_req(qsfpdda_mac_4_tx_lfc_req_int), + .mac_4_tx_pfc_req(qsfpdda_mac_4_tx_pfc_req_int), + .mac_4_rx_clk(qsfpdda_mac_4_rx_clk_int), .mac_4_rx_rst(qsfpdda_mac_4_rx_rst_int), @@ -875,6 +947,8 @@ qsfpdda_mac_inst ( .mac_4_rx_axis_tuser(qsfpdda_mac_4_rx_axis_tuser_int), .mac_4_rx_status(qsfpdda_mac_4_rx_status_int), + .mac_4_rx_lfc_req(qsfpdda_mac_4_rx_lfc_req_int), + .mac_4_rx_pfc_req(qsfpdda_mac_4_rx_pfc_req_int), .mac_5_tx_clk(qsfpdda_mac_5_tx_clk_int), .mac_5_tx_rst(qsfpdda_mac_5_tx_rst_int), @@ -894,6 +968,10 @@ qsfpdda_mac_inst ( .mac_5_tx_axis_tlast(qsfpdda_mac_5_tx_axis_tlast_int), .mac_5_tx_axis_tuser(qsfpdda_mac_5_tx_axis_tuser_int), + .mac_5_tx_status(qsfpdda_mac_5_tx_status_int), + .mac_5_tx_lfc_req(qsfpdda_mac_5_tx_lfc_req_int), + .mac_5_tx_pfc_req(qsfpdda_mac_5_tx_pfc_req_int), + .mac_5_rx_clk(qsfpdda_mac_5_rx_clk_int), .mac_5_rx_rst(qsfpdda_mac_5_rx_rst_int), @@ -908,6 +986,8 @@ qsfpdda_mac_inst ( .mac_5_rx_axis_tuser(qsfpdda_mac_5_rx_axis_tuser_int), .mac_5_rx_status(qsfpdda_mac_5_rx_status_int), + .mac_5_rx_lfc_req(qsfpdda_mac_5_rx_lfc_req_int), + .mac_5_rx_pfc_req(qsfpdda_mac_5_rx_pfc_req_int), .mac_6_tx_clk(qsfpdda_mac_7_tx_clk_int), .mac_6_tx_rst(qsfpdda_mac_7_tx_rst_int), @@ -927,6 +1007,10 @@ qsfpdda_mac_inst ( .mac_6_tx_axis_tlast(qsfpdda_mac_7_tx_axis_tlast_int), .mac_6_tx_axis_tuser(qsfpdda_mac_7_tx_axis_tuser_int), + .mac_6_tx_status(qsfpdda_mac_7_tx_status_int), + .mac_6_tx_lfc_req(qsfpdda_mac_7_tx_lfc_req_int), + .mac_6_tx_pfc_req(qsfpdda_mac_7_tx_pfc_req_int), + .mac_6_rx_clk(qsfpdda_mac_7_rx_clk_int), .mac_6_rx_rst(qsfpdda_mac_7_rx_rst_int), @@ -941,6 +1025,8 @@ qsfpdda_mac_inst ( .mac_6_rx_axis_tuser(qsfpdda_mac_7_rx_axis_tuser_int), .mac_6_rx_status(qsfpdda_mac_7_rx_status_int), + .mac_6_rx_lfc_req(qsfpdda_mac_7_rx_lfc_req_int), + .mac_6_rx_pfc_req(qsfpdda_mac_7_rx_pfc_req_int), .mac_7_tx_clk(qsfpdda_mac_6_tx_clk_int), .mac_7_tx_rst(qsfpdda_mac_6_tx_rst_int), @@ -960,6 +1046,10 @@ qsfpdda_mac_inst ( .mac_7_tx_axis_tlast(qsfpdda_mac_6_tx_axis_tlast_int), .mac_7_tx_axis_tuser(qsfpdda_mac_6_tx_axis_tuser_int), + .mac_7_tx_status(qsfpdda_mac_6_tx_status_int), + .mac_7_tx_lfc_req(qsfpdda_mac_6_tx_lfc_req_int), + .mac_7_tx_pfc_req(qsfpdda_mac_6_tx_pfc_req_int), + .mac_7_rx_clk(qsfpdda_mac_6_rx_clk_int), .mac_7_rx_rst(qsfpdda_mac_6_rx_rst_int), @@ -974,6 +1064,8 @@ qsfpdda_mac_inst ( .mac_7_rx_axis_tuser(qsfpdda_mac_6_rx_axis_tuser_int), .mac_7_rx_status(qsfpdda_mac_6_rx_status_int), + .mac_7_rx_lfc_req(qsfpdda_mac_6_rx_lfc_req_int), + .mac_7_rx_pfc_req(qsfpdda_mac_6_rx_pfc_req_int), .mac_8_tx_clk(qsfpdda_mac_8_tx_clk_int), .mac_8_tx_rst(qsfpdda_mac_8_tx_rst_int), @@ -993,6 +1085,10 @@ qsfpdda_mac_inst ( .mac_8_tx_axis_tlast(qsfpdda_mac_8_tx_axis_tlast_int), .mac_8_tx_axis_tuser(qsfpdda_mac_8_tx_axis_tuser_int), + .mac_8_tx_status(qsfpdda_mac_8_tx_status_int), + .mac_8_tx_lfc_req(qsfpdda_mac_8_tx_lfc_req_int), + .mac_8_tx_pfc_req(qsfpdda_mac_8_tx_pfc_req_int), + .mac_8_rx_clk(qsfpdda_mac_8_rx_clk_int), .mac_8_rx_rst(qsfpdda_mac_8_rx_rst_int), @@ -1006,7 +1102,9 @@ qsfpdda_mac_inst ( .mac_8_rx_axis_tlast(qsfpdda_mac_8_rx_axis_tlast_int), .mac_8_rx_axis_tuser(qsfpdda_mac_8_rx_axis_tuser_int), - .mac_8_rx_status(qsfpdda_mac_8_rx_status_int) + .mac_8_rx_status(qsfpdda_mac_8_rx_status_int), + .mac_8_rx_lfc_req(qsfpdda_mac_8_rx_lfc_req_int), + .mac_8_rx_pfc_req(qsfpdda_mac_8_rx_pfc_req_int) ); // QSFP-DD B @@ -1028,6 +1126,10 @@ wire qsfpddb_mac_1_tx_axis_tready_int; wire qsfpddb_mac_1_tx_axis_tlast_int; wire [AXIS_ETH_TX_USER_WIDTH-1:0] qsfpddb_mac_1_tx_axis_tuser_int; +wire qsfpddb_mac_1_tx_status_int; +wire qsfpddb_mac_1_tx_lfc_req_int; +wire [7:0] qsfpddb_mac_1_tx_pfc_req_int; + wire qsfpddb_mac_1_rx_clk_int; wire qsfpddb_mac_1_rx_rst_int; @@ -1042,6 +1144,8 @@ wire qsfpddb_mac_1_rx_axis_tlast_int; wire [AXIS_ETH_RX_USER_WIDTH-1:0] qsfpddb_mac_1_rx_axis_tuser_int; wire qsfpddb_mac_1_rx_status_int; +wire qsfpddb_mac_1_rx_lfc_req_int; +wire [7:0] qsfpddb_mac_1_rx_pfc_req_int; wire qsfpddb_mac_2_tx_clk_int; wire qsfpddb_mac_2_tx_rst_int; @@ -1061,6 +1165,10 @@ wire qsfpddb_mac_2_tx_axis_tready_int; wire qsfpddb_mac_2_tx_axis_tlast_int; wire [AXIS_ETH_TX_USER_WIDTH-1:0] qsfpddb_mac_2_tx_axis_tuser_int; +wire qsfpddb_mac_2_tx_status_int; +wire qsfpddb_mac_2_tx_lfc_req_int; +wire [7:0] qsfpddb_mac_2_tx_pfc_req_int; + wire qsfpddb_mac_2_rx_clk_int; wire qsfpddb_mac_2_rx_rst_int; @@ -1075,6 +1183,8 @@ wire qsfpddb_mac_2_rx_axis_tlast_int; wire [AXIS_ETH_RX_USER_WIDTH-1:0] qsfpddb_mac_2_rx_axis_tuser_int; wire qsfpddb_mac_2_rx_status_int; +wire qsfpddb_mac_2_rx_lfc_req_int; +wire [7:0] qsfpddb_mac_2_rx_pfc_req_int; wire qsfpddb_mac_3_tx_clk_int; wire qsfpddb_mac_3_tx_rst_int; @@ -1094,6 +1204,10 @@ wire qsfpddb_mac_3_tx_axis_tready_int; wire qsfpddb_mac_3_tx_axis_tlast_int; wire [AXIS_ETH_TX_USER_WIDTH-1:0] qsfpddb_mac_3_tx_axis_tuser_int; +wire qsfpddb_mac_3_tx_status_int; +wire qsfpddb_mac_3_tx_lfc_req_int; +wire [7:0] qsfpddb_mac_3_tx_pfc_req_int; + wire qsfpddb_mac_3_rx_clk_int; wire qsfpddb_mac_3_rx_rst_int; @@ -1108,6 +1222,8 @@ wire qsfpddb_mac_3_rx_axis_tlast_int; wire [AXIS_ETH_RX_USER_WIDTH-1:0] qsfpddb_mac_3_rx_axis_tuser_int; wire qsfpddb_mac_3_rx_status_int; +wire qsfpddb_mac_3_rx_lfc_req_int; +wire [7:0] qsfpddb_mac_3_rx_pfc_req_int; wire qsfpddb_mac_4_tx_clk_int; wire qsfpddb_mac_4_tx_rst_int; @@ -1127,6 +1243,10 @@ wire qsfpddb_mac_4_tx_axis_tready_int; wire qsfpddb_mac_4_tx_axis_tlast_int; wire [AXIS_ETH_TX_USER_WIDTH-1:0] qsfpddb_mac_4_tx_axis_tuser_int; +wire qsfpddb_mac_4_tx_status_int; +wire qsfpddb_mac_4_tx_lfc_req_int; +wire [7:0] qsfpddb_mac_4_tx_pfc_req_int; + wire qsfpddb_mac_4_rx_clk_int; wire qsfpddb_mac_4_rx_rst_int; @@ -1141,6 +1261,8 @@ wire qsfpddb_mac_4_rx_axis_tlast_int; wire [AXIS_ETH_RX_USER_WIDTH-1:0] qsfpddb_mac_4_rx_axis_tuser_int; wire qsfpddb_mac_4_rx_status_int; +wire qsfpddb_mac_4_rx_lfc_req_int; +wire [7:0] qsfpddb_mac_4_rx_pfc_req_int; wire qsfpddb_mac_5_tx_clk_int; wire qsfpddb_mac_5_tx_rst_int; @@ -1160,6 +1282,10 @@ wire qsfpddb_mac_5_tx_axis_tready_int; wire qsfpddb_mac_5_tx_axis_tlast_int; wire [AXIS_ETH_TX_USER_WIDTH-1:0] qsfpddb_mac_5_tx_axis_tuser_int; +wire qsfpddb_mac_5_tx_status_int; +wire qsfpddb_mac_5_tx_lfc_req_int; +wire [7:0] qsfpddb_mac_5_tx_pfc_req_int; + wire qsfpddb_mac_5_rx_clk_int; wire qsfpddb_mac_5_rx_rst_int; @@ -1174,6 +1300,8 @@ wire qsfpddb_mac_5_rx_axis_tlast_int; wire [AXIS_ETH_RX_USER_WIDTH-1:0] qsfpddb_mac_5_rx_axis_tuser_int; wire qsfpddb_mac_5_rx_status_int; +wire qsfpddb_mac_5_rx_lfc_req_int; +wire [7:0] qsfpddb_mac_5_rx_pfc_req_int; wire qsfpddb_mac_6_tx_clk_int; wire qsfpddb_mac_6_tx_rst_int; @@ -1193,6 +1321,10 @@ wire qsfpddb_mac_6_tx_axis_tready_int; wire qsfpddb_mac_6_tx_axis_tlast_int; wire [AXIS_ETH_TX_USER_WIDTH-1:0] qsfpddb_mac_6_tx_axis_tuser_int; +wire qsfpddb_mac_6_tx_status_int; +wire qsfpddb_mac_6_tx_lfc_req_int; +wire [7:0] qsfpddb_mac_6_tx_pfc_req_int; + wire qsfpddb_mac_6_rx_clk_int; wire qsfpddb_mac_6_rx_rst_int; @@ -1207,6 +1339,8 @@ wire qsfpddb_mac_6_rx_axis_tlast_int; wire [AXIS_ETH_RX_USER_WIDTH-1:0] qsfpddb_mac_6_rx_axis_tuser_int; wire qsfpddb_mac_6_rx_status_int; +wire qsfpddb_mac_6_rx_lfc_req_int; +wire [7:0] qsfpddb_mac_6_rx_pfc_req_int; wire qsfpddb_mac_7_tx_clk_int; wire qsfpddb_mac_7_tx_rst_int; @@ -1226,6 +1360,10 @@ wire qsfpddb_mac_7_tx_axis_tready_int; wire qsfpddb_mac_7_tx_axis_tlast_int; wire [AXIS_ETH_TX_USER_WIDTH-1:0] qsfpddb_mac_7_tx_axis_tuser_int; +wire qsfpddb_mac_7_tx_status_int; +wire qsfpddb_mac_7_tx_lfc_req_int; +wire [7:0] qsfpddb_mac_7_tx_pfc_req_int; + wire qsfpddb_mac_7_rx_clk_int; wire qsfpddb_mac_7_rx_rst_int; @@ -1240,6 +1378,8 @@ wire qsfpddb_mac_7_rx_axis_tlast_int; wire [AXIS_ETH_RX_USER_WIDTH-1:0] qsfpddb_mac_7_rx_axis_tuser_int; wire qsfpddb_mac_7_rx_status_int; +wire qsfpddb_mac_7_rx_lfc_req_int; +wire [7:0] qsfpddb_mac_7_rx_pfc_req_int; wire qsfpddb_mac_8_tx_clk_int; wire qsfpddb_mac_8_tx_rst_int; @@ -1259,6 +1399,10 @@ wire qsfpddb_mac_8_tx_axis_tready_int; wire qsfpddb_mac_8_tx_axis_tlast_int; wire [AXIS_ETH_TX_USER_WIDTH-1:0] qsfpddb_mac_8_tx_axis_tuser_int; +wire qsfpddb_mac_8_tx_status_int; +wire qsfpddb_mac_8_tx_lfc_req_int; +wire [7:0] qsfpddb_mac_8_tx_pfc_req_int; + wire qsfpddb_mac_8_rx_clk_int; wire qsfpddb_mac_8_rx_rst_int; @@ -1273,6 +1417,8 @@ wire qsfpddb_mac_8_rx_axis_tlast_int; wire [AXIS_ETH_RX_USER_WIDTH-1:0] qsfpddb_mac_8_rx_axis_tuser_int; wire qsfpddb_mac_8_rx_status_int; +wire qsfpddb_mac_8_rx_lfc_req_int; +wire [7:0] qsfpddb_mac_8_rx_pfc_req_int; eth_mac_dual_quad_wrapper #( .PTP_TS_WIDTH(PTP_TS_WIDTH), @@ -1312,6 +1458,10 @@ qsfpddb_mac_inst ( .mac_1_tx_axis_tlast(qsfpddb_mac_1_tx_axis_tlast_int), .mac_1_tx_axis_tuser(qsfpddb_mac_1_tx_axis_tuser_int), + .mac_1_tx_status(qsfpddb_mac_1_tx_status_int), + .mac_1_tx_lfc_req(qsfpddb_mac_1_tx_lfc_req_int), + .mac_1_tx_pfc_req(qsfpddb_mac_1_tx_pfc_req_int), + .mac_1_rx_clk(qsfpddb_mac_1_rx_clk_int), .mac_1_rx_rst(qsfpddb_mac_1_rx_rst_int), @@ -1326,6 +1476,8 @@ qsfpddb_mac_inst ( .mac_1_rx_axis_tuser(qsfpddb_mac_1_rx_axis_tuser_int), .mac_1_rx_status(qsfpddb_mac_1_rx_status_int), + .mac_1_rx_lfc_req(qsfpddb_mac_1_rx_lfc_req_int), + .mac_1_rx_pfc_req(qsfpddb_mac_1_rx_pfc_req_int), .mac_2_tx_clk(qsfpddb_mac_3_tx_clk_int), .mac_2_tx_rst(qsfpddb_mac_3_tx_rst_int), @@ -1345,6 +1497,10 @@ qsfpddb_mac_inst ( .mac_2_tx_axis_tlast(qsfpddb_mac_3_tx_axis_tlast_int), .mac_2_tx_axis_tuser(qsfpddb_mac_3_tx_axis_tuser_int), + .mac_2_tx_status(qsfpddb_mac_3_tx_status_int), + .mac_2_tx_lfc_req(qsfpddb_mac_3_tx_lfc_req_int), + .mac_2_tx_pfc_req(qsfpddb_mac_3_tx_pfc_req_int), + .mac_2_rx_clk(qsfpddb_mac_3_rx_clk_int), .mac_2_rx_rst(qsfpddb_mac_3_rx_rst_int), @@ -1359,6 +1515,8 @@ qsfpddb_mac_inst ( .mac_2_rx_axis_tuser(qsfpddb_mac_3_rx_axis_tuser_int), .mac_2_rx_status(qsfpddb_mac_3_rx_status_int), + .mac_2_rx_lfc_req(qsfpddb_mac_3_rx_lfc_req_int), + .mac_2_rx_pfc_req(qsfpddb_mac_3_rx_pfc_req_int), .mac_3_tx_clk(qsfpddb_mac_2_tx_clk_int), .mac_3_tx_rst(qsfpddb_mac_2_tx_rst_int), @@ -1378,6 +1536,10 @@ qsfpddb_mac_inst ( .mac_3_tx_axis_tlast(qsfpddb_mac_2_tx_axis_tlast_int), .mac_3_tx_axis_tuser(qsfpddb_mac_2_tx_axis_tuser_int), + .mac_3_tx_status(qsfpddb_mac_2_tx_status_int), + .mac_3_tx_lfc_req(qsfpddb_mac_2_tx_lfc_req_int), + .mac_3_tx_pfc_req(qsfpddb_mac_2_tx_pfc_req_int), + .mac_3_rx_clk(qsfpddb_mac_2_rx_clk_int), .mac_3_rx_rst(qsfpddb_mac_2_rx_rst_int), @@ -1392,6 +1554,8 @@ qsfpddb_mac_inst ( .mac_3_rx_axis_tuser(qsfpddb_mac_2_rx_axis_tuser_int), .mac_3_rx_status(qsfpddb_mac_2_rx_status_int), + .mac_3_rx_lfc_req(qsfpddb_mac_2_rx_lfc_req_int), + .mac_3_rx_pfc_req(qsfpddb_mac_2_rx_pfc_req_int), .mac_4_tx_clk(qsfpddb_mac_4_tx_clk_int), .mac_4_tx_rst(qsfpddb_mac_4_tx_rst_int), @@ -1411,6 +1575,10 @@ qsfpddb_mac_inst ( .mac_4_tx_axis_tlast(qsfpddb_mac_4_tx_axis_tlast_int), .mac_4_tx_axis_tuser(qsfpddb_mac_4_tx_axis_tuser_int), + .mac_4_tx_status(qsfpddb_mac_4_tx_status_int), + .mac_4_tx_lfc_req(qsfpddb_mac_4_tx_lfc_req_int), + .mac_4_tx_pfc_req(qsfpddb_mac_4_tx_pfc_req_int), + .mac_4_rx_clk(qsfpddb_mac_4_rx_clk_int), .mac_4_rx_rst(qsfpddb_mac_4_rx_rst_int), @@ -1425,6 +1593,8 @@ qsfpddb_mac_inst ( .mac_4_rx_axis_tuser(qsfpddb_mac_4_rx_axis_tuser_int), .mac_4_rx_status(qsfpddb_mac_4_rx_status_int), + .mac_4_rx_lfc_req(qsfpddb_mac_4_rx_lfc_req_int), + .mac_4_rx_pfc_req(qsfpddb_mac_4_rx_pfc_req_int), .mac_5_tx_clk(qsfpddb_mac_5_tx_clk_int), .mac_5_tx_rst(qsfpddb_mac_5_tx_rst_int), @@ -1444,6 +1614,10 @@ qsfpddb_mac_inst ( .mac_5_tx_axis_tlast(qsfpddb_mac_5_tx_axis_tlast_int), .mac_5_tx_axis_tuser(qsfpddb_mac_5_tx_axis_tuser_int), + .mac_5_tx_status(qsfpddb_mac_5_tx_status_int), + .mac_5_tx_lfc_req(qsfpddb_mac_5_tx_lfc_req_int), + .mac_5_tx_pfc_req(qsfpddb_mac_5_tx_pfc_req_int), + .mac_5_rx_clk(qsfpddb_mac_5_rx_clk_int), .mac_5_rx_rst(qsfpddb_mac_5_rx_rst_int), @@ -1458,6 +1632,8 @@ qsfpddb_mac_inst ( .mac_5_rx_axis_tuser(qsfpddb_mac_5_rx_axis_tuser_int), .mac_5_rx_status(qsfpddb_mac_5_rx_status_int), + .mac_5_rx_lfc_req(qsfpddb_mac_5_rx_lfc_req_int), + .mac_5_rx_pfc_req(qsfpddb_mac_5_rx_pfc_req_int), .mac_6_tx_clk(qsfpddb_mac_7_tx_clk_int), .mac_6_tx_rst(qsfpddb_mac_7_tx_rst_int), @@ -1477,6 +1653,10 @@ qsfpddb_mac_inst ( .mac_6_tx_axis_tlast(qsfpddb_mac_7_tx_axis_tlast_int), .mac_6_tx_axis_tuser(qsfpddb_mac_7_tx_axis_tuser_int), + .mac_6_tx_status(qsfpddb_mac_7_tx_status_int), + .mac_6_tx_lfc_req(qsfpddb_mac_7_tx_lfc_req_int), + .mac_6_tx_pfc_req(qsfpddb_mac_7_tx_pfc_req_int), + .mac_6_rx_clk(qsfpddb_mac_7_rx_clk_int), .mac_6_rx_rst(qsfpddb_mac_7_rx_rst_int), @@ -1491,6 +1671,8 @@ qsfpddb_mac_inst ( .mac_6_rx_axis_tuser(qsfpddb_mac_7_rx_axis_tuser_int), .mac_6_rx_status(qsfpddb_mac_7_rx_status_int), + .mac_6_rx_lfc_req(qsfpddb_mac_7_rx_lfc_req_int), + .mac_6_rx_pfc_req(qsfpddb_mac_7_rx_pfc_req_int), .mac_7_tx_clk(qsfpddb_mac_6_tx_clk_int), .mac_7_tx_rst(qsfpddb_mac_6_tx_rst_int), @@ -1510,6 +1692,10 @@ qsfpddb_mac_inst ( .mac_7_tx_axis_tlast(qsfpddb_mac_6_tx_axis_tlast_int), .mac_7_tx_axis_tuser(qsfpddb_mac_6_tx_axis_tuser_int), + .mac_7_tx_status(qsfpddb_mac_6_tx_status_int), + .mac_7_tx_lfc_req(qsfpddb_mac_6_tx_lfc_req_int), + .mac_7_tx_pfc_req(qsfpddb_mac_6_tx_pfc_req_int), + .mac_7_rx_clk(qsfpddb_mac_6_rx_clk_int), .mac_7_rx_rst(qsfpddb_mac_6_rx_rst_int), @@ -1524,6 +1710,8 @@ qsfpddb_mac_inst ( .mac_7_rx_axis_tuser(qsfpddb_mac_6_rx_axis_tuser_int), .mac_7_rx_status(qsfpddb_mac_6_rx_status_int), + .mac_7_rx_lfc_req(qsfpddb_mac_6_rx_lfc_req_int), + .mac_7_rx_pfc_req(qsfpddb_mac_6_rx_pfc_req_int), .mac_8_tx_clk(qsfpddb_mac_8_tx_clk_int), .mac_8_tx_rst(qsfpddb_mac_8_tx_rst_int), @@ -1543,6 +1731,10 @@ qsfpddb_mac_inst ( .mac_8_tx_axis_tlast(qsfpddb_mac_8_tx_axis_tlast_int), .mac_8_tx_axis_tuser(qsfpddb_mac_8_tx_axis_tuser_int), + .mac_8_tx_status(qsfpddb_mac_8_tx_status_int), + .mac_8_tx_lfc_req(qsfpddb_mac_8_tx_lfc_req_int), + .mac_8_tx_pfc_req(qsfpddb_mac_8_tx_pfc_req_int), + .mac_8_rx_clk(qsfpddb_mac_8_rx_clk_int), .mac_8_rx_rst(qsfpddb_mac_8_rx_rst_int), @@ -1556,7 +1748,9 @@ qsfpddb_mac_inst ( .mac_8_rx_axis_tlast(qsfpddb_mac_8_rx_axis_tlast_int), .mac_8_rx_axis_tuser(qsfpddb_mac_8_rx_axis_tuser_int), - .mac_8_rx_status(qsfpddb_mac_8_rx_status_int) + .mac_8_rx_status(qsfpddb_mac_8_rx_status_int), + .mac_8_rx_lfc_req(qsfpddb_mac_8_rx_lfc_req_int), + .mac_8_rx_pfc_req(qsfpddb_mac_8_rx_pfc_req_int) ); wire ptp_clk; @@ -1649,6 +1843,8 @@ fpga_core #( .TX_CHECKSUM_ENABLE(TX_CHECKSUM_ENABLE), .RX_HASH_ENABLE(RX_HASH_ENABLE), .RX_CHECKSUM_ENABLE(RX_CHECKSUM_ENABLE), + .PFC_ENABLE(PFC_ENABLE), + .LFC_ENABLE(LFC_ENABLE), .TX_FIFO_DEPTH(TX_FIFO_DEPTH), .RX_FIFO_DEPTH(RX_FIFO_DEPTH), .MAX_TX_SIZE(MAX_TX_SIZE), @@ -1795,6 +1991,10 @@ core_inst ( .qsfpdda_mac_1_tx_axis_tlast(qsfpdda_mac_1_tx_axis_tlast_int), .qsfpdda_mac_1_tx_axis_tuser(qsfpdda_mac_1_tx_axis_tuser_int), + .qsfpdda_mac_1_tx_status(qsfpdda_mac_1_tx_status_int), + .qsfpdda_mac_1_tx_lfc_req(qsfpdda_mac_1_tx_lfc_req_int), + .qsfpdda_mac_1_tx_pfc_req(qsfpdda_mac_1_tx_pfc_req_int), + .qsfpdda_mac_1_rx_clk(qsfpdda_mac_1_rx_clk_int), .qsfpdda_mac_1_rx_rst(qsfpdda_mac_1_rx_rst_int), @@ -1809,6 +2009,8 @@ core_inst ( .qsfpdda_mac_1_rx_axis_tuser(qsfpdda_mac_1_rx_axis_tuser_int), .qsfpdda_mac_1_rx_status(qsfpdda_mac_1_rx_status_int), + .qsfpdda_mac_1_rx_lfc_req(qsfpdda_mac_1_rx_lfc_req_int), + .qsfpdda_mac_1_rx_pfc_req(qsfpdda_mac_1_rx_pfc_req_int), .qsfpdda_mac_2_tx_clk(qsfpdda_mac_2_tx_clk_int), .qsfpdda_mac_2_tx_rst(qsfpdda_mac_2_tx_rst_int), @@ -1828,6 +2030,10 @@ core_inst ( .qsfpdda_mac_2_tx_axis_tlast(qsfpdda_mac_2_tx_axis_tlast_int), .qsfpdda_mac_2_tx_axis_tuser(qsfpdda_mac_2_tx_axis_tuser_int), + .qsfpdda_mac_2_tx_status(qsfpdda_mac_2_tx_status_int), + .qsfpdda_mac_2_tx_lfc_req(qsfpdda_mac_2_tx_lfc_req_int), + .qsfpdda_mac_2_tx_pfc_req(qsfpdda_mac_2_tx_pfc_req_int), + .qsfpdda_mac_2_rx_clk(qsfpdda_mac_2_rx_clk_int), .qsfpdda_mac_2_rx_rst(qsfpdda_mac_2_rx_rst_int), @@ -1842,6 +2048,8 @@ core_inst ( .qsfpdda_mac_2_rx_axis_tuser(qsfpdda_mac_2_rx_axis_tuser_int), .qsfpdda_mac_2_rx_status(qsfpdda_mac_2_rx_status_int), + .qsfpdda_mac_2_rx_lfc_req(qsfpdda_mac_2_rx_lfc_req_int), + .qsfpdda_mac_2_rx_pfc_req(qsfpdda_mac_2_rx_pfc_req_int), .qsfpdda_mac_3_tx_clk(qsfpdda_mac_3_tx_clk_int), .qsfpdda_mac_3_tx_rst(qsfpdda_mac_3_tx_rst_int), @@ -1861,6 +2069,10 @@ core_inst ( .qsfpdda_mac_3_tx_axis_tlast(qsfpdda_mac_3_tx_axis_tlast_int), .qsfpdda_mac_3_tx_axis_tuser(qsfpdda_mac_3_tx_axis_tuser_int), + .qsfpdda_mac_3_tx_status(qsfpdda_mac_3_tx_status_int), + .qsfpdda_mac_3_tx_lfc_req(qsfpdda_mac_3_tx_lfc_req_int), + .qsfpdda_mac_3_tx_pfc_req(qsfpdda_mac_3_tx_pfc_req_int), + .qsfpdda_mac_3_rx_clk(qsfpdda_mac_3_rx_clk_int), .qsfpdda_mac_3_rx_rst(qsfpdda_mac_3_rx_rst_int), @@ -1875,6 +2087,8 @@ core_inst ( .qsfpdda_mac_3_rx_axis_tuser(qsfpdda_mac_3_rx_axis_tuser_int), .qsfpdda_mac_3_rx_status(qsfpdda_mac_3_rx_status_int), + .qsfpdda_mac_3_rx_lfc_req(qsfpdda_mac_3_rx_lfc_req_int), + .qsfpdda_mac_3_rx_pfc_req(qsfpdda_mac_3_rx_pfc_req_int), .qsfpdda_mac_4_tx_clk(qsfpdda_mac_4_tx_clk_int), .qsfpdda_mac_4_tx_rst(qsfpdda_mac_4_tx_rst_int), @@ -1894,6 +2108,10 @@ core_inst ( .qsfpdda_mac_4_tx_axis_tlast(qsfpdda_mac_4_tx_axis_tlast_int), .qsfpdda_mac_4_tx_axis_tuser(qsfpdda_mac_4_tx_axis_tuser_int), + .qsfpdda_mac_4_tx_status(qsfpdda_mac_4_tx_status_int), + .qsfpdda_mac_4_tx_lfc_req(qsfpdda_mac_4_tx_lfc_req_int), + .qsfpdda_mac_4_tx_pfc_req(qsfpdda_mac_4_tx_pfc_req_int), + .qsfpdda_mac_4_rx_clk(qsfpdda_mac_4_rx_clk_int), .qsfpdda_mac_4_rx_rst(qsfpdda_mac_4_rx_rst_int), @@ -1908,6 +2126,8 @@ core_inst ( .qsfpdda_mac_4_rx_axis_tuser(qsfpdda_mac_4_rx_axis_tuser_int), .qsfpdda_mac_4_rx_status(qsfpdda_mac_4_rx_status_int), + .qsfpdda_mac_4_rx_lfc_req(qsfpdda_mac_4_rx_lfc_req_int), + .qsfpdda_mac_4_rx_pfc_req(qsfpdda_mac_4_rx_pfc_req_int), .qsfpdda_mac_5_tx_clk(qsfpdda_mac_5_tx_clk_int), .qsfpdda_mac_5_tx_rst(qsfpdda_mac_5_tx_rst_int), @@ -1927,6 +2147,10 @@ core_inst ( .qsfpdda_mac_5_tx_axis_tlast(qsfpdda_mac_5_tx_axis_tlast_int), .qsfpdda_mac_5_tx_axis_tuser(qsfpdda_mac_5_tx_axis_tuser_int), + .qsfpdda_mac_5_tx_status(qsfpdda_mac_5_tx_status_int), + .qsfpdda_mac_5_tx_lfc_req(qsfpdda_mac_5_tx_lfc_req_int), + .qsfpdda_mac_5_tx_pfc_req(qsfpdda_mac_5_tx_pfc_req_int), + .qsfpdda_mac_5_rx_clk(qsfpdda_mac_5_rx_clk_int), .qsfpdda_mac_5_rx_rst(qsfpdda_mac_5_rx_rst_int), @@ -1941,6 +2165,8 @@ core_inst ( .qsfpdda_mac_5_rx_axis_tuser(qsfpdda_mac_5_rx_axis_tuser_int), .qsfpdda_mac_5_rx_status(qsfpdda_mac_5_rx_status_int), + .qsfpdda_mac_5_rx_lfc_req(qsfpdda_mac_5_rx_lfc_req_int), + .qsfpdda_mac_5_rx_pfc_req(qsfpdda_mac_5_rx_pfc_req_int), .qsfpdda_mac_6_tx_clk(qsfpdda_mac_6_tx_clk_int), .qsfpdda_mac_6_tx_rst(qsfpdda_mac_6_tx_rst_int), @@ -1960,6 +2186,10 @@ core_inst ( .qsfpdda_mac_6_tx_axis_tlast(qsfpdda_mac_6_tx_axis_tlast_int), .qsfpdda_mac_6_tx_axis_tuser(qsfpdda_mac_6_tx_axis_tuser_int), + .qsfpdda_mac_6_tx_status(qsfpdda_mac_6_tx_status_int), + .qsfpdda_mac_6_tx_lfc_req(qsfpdda_mac_6_tx_lfc_req_int), + .qsfpdda_mac_6_tx_pfc_req(qsfpdda_mac_6_tx_pfc_req_int), + .qsfpdda_mac_6_rx_clk(qsfpdda_mac_6_rx_clk_int), .qsfpdda_mac_6_rx_rst(qsfpdda_mac_6_rx_rst_int), @@ -1974,6 +2204,8 @@ core_inst ( .qsfpdda_mac_6_rx_axis_tuser(qsfpdda_mac_6_rx_axis_tuser_int), .qsfpdda_mac_6_rx_status(qsfpdda_mac_6_rx_status_int), + .qsfpdda_mac_6_rx_lfc_req(qsfpdda_mac_6_rx_lfc_req_int), + .qsfpdda_mac_6_rx_pfc_req(qsfpdda_mac_6_rx_pfc_req_int), .qsfpdda_mac_7_tx_clk(qsfpdda_mac_7_tx_clk_int), .qsfpdda_mac_7_tx_rst(qsfpdda_mac_7_tx_rst_int), @@ -1993,6 +2225,10 @@ core_inst ( .qsfpdda_mac_7_tx_axis_tlast(qsfpdda_mac_7_tx_axis_tlast_int), .qsfpdda_mac_7_tx_axis_tuser(qsfpdda_mac_7_tx_axis_tuser_int), + .qsfpdda_mac_7_tx_status(qsfpdda_mac_7_tx_status_int), + .qsfpdda_mac_7_tx_lfc_req(qsfpdda_mac_7_tx_lfc_req_int), + .qsfpdda_mac_7_tx_pfc_req(qsfpdda_mac_7_tx_pfc_req_int), + .qsfpdda_mac_7_rx_clk(qsfpdda_mac_7_rx_clk_int), .qsfpdda_mac_7_rx_rst(qsfpdda_mac_7_rx_rst_int), @@ -2007,6 +2243,8 @@ core_inst ( .qsfpdda_mac_7_rx_axis_tuser(qsfpdda_mac_7_rx_axis_tuser_int), .qsfpdda_mac_7_rx_status(qsfpdda_mac_7_rx_status_int), + .qsfpdda_mac_7_rx_lfc_req(qsfpdda_mac_7_rx_lfc_req_int), + .qsfpdda_mac_7_rx_pfc_req(qsfpdda_mac_7_rx_pfc_req_int), .qsfpdda_mac_8_tx_clk(qsfpdda_mac_8_tx_clk_int), .qsfpdda_mac_8_tx_rst(qsfpdda_mac_8_tx_rst_int), @@ -2026,6 +2264,10 @@ core_inst ( .qsfpdda_mac_8_tx_axis_tlast(qsfpdda_mac_8_tx_axis_tlast_int), .qsfpdda_mac_8_tx_axis_tuser(qsfpdda_mac_8_tx_axis_tuser_int), + .qsfpdda_mac_8_tx_status(qsfpdda_mac_8_tx_status_int), + .qsfpdda_mac_8_tx_lfc_req(qsfpdda_mac_8_tx_lfc_req_int), + .qsfpdda_mac_8_tx_pfc_req(qsfpdda_mac_8_tx_pfc_req_int), + .qsfpdda_mac_8_rx_clk(qsfpdda_mac_8_rx_clk_int), .qsfpdda_mac_8_rx_rst(qsfpdda_mac_8_rx_rst_int), @@ -2040,6 +2282,8 @@ core_inst ( .qsfpdda_mac_8_rx_axis_tuser(qsfpdda_mac_8_rx_axis_tuser_int), .qsfpdda_mac_8_rx_status(qsfpdda_mac_8_rx_status_int), + .qsfpdda_mac_8_rx_lfc_req(qsfpdda_mac_8_rx_lfc_req_int), + .qsfpdda_mac_8_rx_pfc_req(qsfpdda_mac_8_rx_pfc_req_int), .qsfpdda_initmode(qsfpdda_initmode), .qsfpdda_interrupt_n(qsfpdda_interrupt_n_int), @@ -2071,6 +2315,10 @@ core_inst ( .qsfpddb_mac_1_tx_axis_tlast(qsfpddb_mac_1_tx_axis_tlast_int), .qsfpddb_mac_1_tx_axis_tuser(qsfpddb_mac_1_tx_axis_tuser_int), + .qsfpddb_mac_1_tx_status(qsfpddb_mac_1_tx_status_int), + .qsfpddb_mac_1_tx_lfc_req(qsfpddb_mac_1_tx_lfc_req_int), + .qsfpddb_mac_1_tx_pfc_req(qsfpddb_mac_1_tx_pfc_req_int), + .qsfpddb_mac_1_rx_clk(qsfpddb_mac_1_rx_clk_int), .qsfpddb_mac_1_rx_rst(qsfpddb_mac_1_rx_rst_int), @@ -2085,6 +2333,8 @@ core_inst ( .qsfpddb_mac_1_rx_axis_tuser(qsfpddb_mac_1_rx_axis_tuser_int), .qsfpddb_mac_1_rx_status(qsfpddb_mac_1_rx_status_int), + .qsfpddb_mac_1_rx_lfc_req(qsfpddb_mac_1_rx_lfc_req_int), + .qsfpddb_mac_1_rx_pfc_req(qsfpddb_mac_1_rx_pfc_req_int), .qsfpddb_mac_2_tx_clk(qsfpddb_mac_2_tx_clk_int), .qsfpddb_mac_2_tx_rst(qsfpddb_mac_2_tx_rst_int), @@ -2104,6 +2354,10 @@ core_inst ( .qsfpddb_mac_2_tx_axis_tlast(qsfpddb_mac_2_tx_axis_tlast_int), .qsfpddb_mac_2_tx_axis_tuser(qsfpddb_mac_2_tx_axis_tuser_int), + .qsfpddb_mac_2_tx_status(qsfpddb_mac_2_tx_status_int), + .qsfpddb_mac_2_tx_lfc_req(qsfpddb_mac_2_tx_lfc_req_int), + .qsfpddb_mac_2_tx_pfc_req(qsfpddb_mac_2_tx_pfc_req_int), + .qsfpddb_mac_2_rx_clk(qsfpddb_mac_2_rx_clk_int), .qsfpddb_mac_2_rx_rst(qsfpddb_mac_2_rx_rst_int), @@ -2118,6 +2372,8 @@ core_inst ( .qsfpddb_mac_2_rx_axis_tuser(qsfpddb_mac_2_rx_axis_tuser_int), .qsfpddb_mac_2_rx_status(qsfpddb_mac_2_rx_status_int), + .qsfpddb_mac_2_rx_lfc_req(qsfpddb_mac_2_rx_lfc_req_int), + .qsfpddb_mac_2_rx_pfc_req(qsfpddb_mac_2_rx_pfc_req_int), .qsfpddb_mac_3_tx_clk(qsfpddb_mac_3_tx_clk_int), .qsfpddb_mac_3_tx_rst(qsfpddb_mac_3_tx_rst_int), @@ -2137,6 +2393,10 @@ core_inst ( .qsfpddb_mac_3_tx_axis_tlast(qsfpddb_mac_3_tx_axis_tlast_int), .qsfpddb_mac_3_tx_axis_tuser(qsfpddb_mac_3_tx_axis_tuser_int), + .qsfpddb_mac_3_tx_status(qsfpddb_mac_3_tx_status_int), + .qsfpddb_mac_3_tx_lfc_req(qsfpddb_mac_3_tx_lfc_req_int), + .qsfpddb_mac_3_tx_pfc_req(qsfpddb_mac_3_tx_pfc_req_int), + .qsfpddb_mac_3_rx_clk(qsfpddb_mac_3_rx_clk_int), .qsfpddb_mac_3_rx_rst(qsfpddb_mac_3_rx_rst_int), @@ -2151,6 +2411,8 @@ core_inst ( .qsfpddb_mac_3_rx_axis_tuser(qsfpddb_mac_3_rx_axis_tuser_int), .qsfpddb_mac_3_rx_status(qsfpddb_mac_3_rx_status_int), + .qsfpddb_mac_3_rx_lfc_req(qsfpddb_mac_3_rx_lfc_req_int), + .qsfpddb_mac_3_rx_pfc_req(qsfpddb_mac_3_rx_pfc_req_int), .qsfpddb_mac_4_tx_clk(qsfpddb_mac_4_tx_clk_int), .qsfpddb_mac_4_tx_rst(qsfpddb_mac_4_tx_rst_int), @@ -2170,6 +2432,10 @@ core_inst ( .qsfpddb_mac_4_tx_axis_tlast(qsfpddb_mac_4_tx_axis_tlast_int), .qsfpddb_mac_4_tx_axis_tuser(qsfpddb_mac_4_tx_axis_tuser_int), + .qsfpddb_mac_4_tx_status(qsfpddb_mac_4_tx_status_int), + .qsfpddb_mac_4_tx_lfc_req(qsfpddb_mac_4_tx_lfc_req_int), + .qsfpddb_mac_4_tx_pfc_req(qsfpddb_mac_4_tx_pfc_req_int), + .qsfpddb_mac_4_rx_clk(qsfpddb_mac_4_rx_clk_int), .qsfpddb_mac_4_rx_rst(qsfpddb_mac_4_rx_rst_int), @@ -2184,6 +2450,8 @@ core_inst ( .qsfpddb_mac_4_rx_axis_tuser(qsfpddb_mac_4_rx_axis_tuser_int), .qsfpddb_mac_4_rx_status(qsfpddb_mac_4_rx_status_int), + .qsfpddb_mac_4_rx_lfc_req(qsfpddb_mac_4_rx_lfc_req_int), + .qsfpddb_mac_4_rx_pfc_req(qsfpddb_mac_4_rx_pfc_req_int), .qsfpddb_mac_5_tx_clk(qsfpddb_mac_5_tx_clk_int), .qsfpddb_mac_5_tx_rst(qsfpddb_mac_5_tx_rst_int), @@ -2203,6 +2471,10 @@ core_inst ( .qsfpddb_mac_5_tx_axis_tlast(qsfpddb_mac_5_tx_axis_tlast_int), .qsfpddb_mac_5_tx_axis_tuser(qsfpddb_mac_5_tx_axis_tuser_int), + .qsfpddb_mac_5_tx_status(qsfpddb_mac_5_tx_status_int), + .qsfpddb_mac_5_tx_lfc_req(qsfpddb_mac_5_tx_lfc_req_int), + .qsfpddb_mac_5_tx_pfc_req(qsfpddb_mac_5_tx_pfc_req_int), + .qsfpddb_mac_5_rx_clk(qsfpddb_mac_5_rx_clk_int), .qsfpddb_mac_5_rx_rst(qsfpddb_mac_5_rx_rst_int), @@ -2217,6 +2489,8 @@ core_inst ( .qsfpddb_mac_5_rx_axis_tuser(qsfpddb_mac_5_rx_axis_tuser_int), .qsfpddb_mac_5_rx_status(qsfpddb_mac_5_rx_status_int), + .qsfpddb_mac_5_rx_lfc_req(qsfpddb_mac_5_rx_lfc_req_int), + .qsfpddb_mac_5_rx_pfc_req(qsfpddb_mac_5_rx_pfc_req_int), .qsfpddb_mac_6_tx_clk(qsfpddb_mac_6_tx_clk_int), .qsfpddb_mac_6_tx_rst(qsfpddb_mac_6_tx_rst_int), @@ -2236,6 +2510,10 @@ core_inst ( .qsfpddb_mac_6_tx_axis_tlast(qsfpddb_mac_6_tx_axis_tlast_int), .qsfpddb_mac_6_tx_axis_tuser(qsfpddb_mac_6_tx_axis_tuser_int), + .qsfpddb_mac_6_tx_status(qsfpddb_mac_6_tx_status_int), + .qsfpddb_mac_6_tx_lfc_req(qsfpddb_mac_6_tx_lfc_req_int), + .qsfpddb_mac_6_tx_pfc_req(qsfpddb_mac_6_tx_pfc_req_int), + .qsfpddb_mac_6_rx_clk(qsfpddb_mac_6_rx_clk_int), .qsfpddb_mac_6_rx_rst(qsfpddb_mac_6_rx_rst_int), @@ -2250,6 +2528,8 @@ core_inst ( .qsfpddb_mac_6_rx_axis_tuser(qsfpddb_mac_6_rx_axis_tuser_int), .qsfpddb_mac_6_rx_status(qsfpddb_mac_6_rx_status_int), + .qsfpddb_mac_6_rx_lfc_req(qsfpddb_mac_6_rx_lfc_req_int), + .qsfpddb_mac_6_rx_pfc_req(qsfpddb_mac_6_rx_pfc_req_int), .qsfpddb_mac_7_tx_clk(qsfpddb_mac_7_tx_clk_int), .qsfpddb_mac_7_tx_rst(qsfpddb_mac_7_tx_rst_int), @@ -2269,6 +2549,10 @@ core_inst ( .qsfpddb_mac_7_tx_axis_tlast(qsfpddb_mac_7_tx_axis_tlast_int), .qsfpddb_mac_7_tx_axis_tuser(qsfpddb_mac_7_tx_axis_tuser_int), + .qsfpddb_mac_7_tx_status(qsfpddb_mac_7_tx_status_int), + .qsfpddb_mac_7_tx_lfc_req(qsfpddb_mac_7_tx_lfc_req_int), + .qsfpddb_mac_7_tx_pfc_req(qsfpddb_mac_7_tx_pfc_req_int), + .qsfpddb_mac_7_rx_clk(qsfpddb_mac_7_rx_clk_int), .qsfpddb_mac_7_rx_rst(qsfpddb_mac_7_rx_rst_int), @@ -2283,6 +2567,8 @@ core_inst ( .qsfpddb_mac_7_rx_axis_tuser(qsfpddb_mac_7_rx_axis_tuser_int), .qsfpddb_mac_7_rx_status(qsfpddb_mac_7_rx_status_int), + .qsfpddb_mac_7_rx_lfc_req(qsfpddb_mac_7_rx_lfc_req_int), + .qsfpddb_mac_7_rx_pfc_req(qsfpddb_mac_7_rx_pfc_req_int), .qsfpddb_mac_8_tx_clk(qsfpddb_mac_8_tx_clk_int), .qsfpddb_mac_8_tx_rst(qsfpddb_mac_8_tx_rst_int), @@ -2302,6 +2588,10 @@ core_inst ( .qsfpddb_mac_8_tx_axis_tlast(qsfpddb_mac_8_tx_axis_tlast_int), .qsfpddb_mac_8_tx_axis_tuser(qsfpddb_mac_8_tx_axis_tuser_int), + .qsfpddb_mac_8_tx_status(qsfpddb_mac_8_tx_status_int), + .qsfpddb_mac_8_tx_lfc_req(qsfpddb_mac_8_tx_lfc_req_int), + .qsfpddb_mac_8_tx_pfc_req(qsfpddb_mac_8_tx_pfc_req_int), + .qsfpddb_mac_8_rx_clk(qsfpddb_mac_8_rx_clk_int), .qsfpddb_mac_8_rx_rst(qsfpddb_mac_8_rx_rst_int), @@ -2316,6 +2606,8 @@ core_inst ( .qsfpddb_mac_8_rx_axis_tuser(qsfpddb_mac_8_rx_axis_tuser_int), .qsfpddb_mac_8_rx_status(qsfpddb_mac_8_rx_status_int), + .qsfpddb_mac_8_rx_lfc_req(qsfpddb_mac_8_rx_lfc_req_int), + .qsfpddb_mac_8_rx_pfc_req(qsfpddb_mac_8_rx_pfc_req_int), .qsfpddb_initmode(qsfpddb_initmode), .qsfpddb_interrupt_n(qsfpddb_interrupt_n_int), diff --git a/fpga/mqnic/DE10_Agilex/fpga_25g/rtl/fpga_core.v b/fpga/mqnic/DE10_Agilex/fpga_25g/rtl/fpga_core.v index ad9364f34..d94e90e54 100644 --- a/fpga/mqnic/DE10_Agilex/fpga_25g/rtl/fpga_core.v +++ b/fpga/mqnic/DE10_Agilex/fpga_25g/rtl/fpga_core.v @@ -78,9 +78,8 @@ module fpga_core # parameter TX_CHECKSUM_ENABLE = 1, parameter RX_HASH_ENABLE = 1, parameter RX_CHECKSUM_ENABLE = 1, - parameter ENABLE_PADDING = 1, - parameter ENABLE_DIC = 1, - parameter MIN_FRAME_LENGTH = 64, + parameter PFC_ENABLE = 1, + parameter LFC_ENABLE = PFC_ENABLE, parameter TX_FIFO_DEPTH = 32768, parameter RX_FIFO_DEPTH = 32768, parameter MAX_TX_SIZE = 9214, @@ -227,6 +226,10 @@ module fpga_core # output wire qsfpdda_mac_1_tx_axis_tlast, output wire [AXIS_ETH_TX_USER_WIDTH-1:0] qsfpdda_mac_1_tx_axis_tuser, + input wire qsfpdda_mac_1_tx_status, + output wire qsfpdda_mac_1_tx_lfc_req, + output wire [7:0] qsfpdda_mac_1_tx_pfc_req, + input wire qsfpdda_mac_1_rx_clk, input wire qsfpdda_mac_1_rx_rst, @@ -241,6 +244,8 @@ module fpga_core # input wire [AXIS_ETH_RX_USER_WIDTH-1:0] qsfpdda_mac_1_rx_axis_tuser, input wire qsfpdda_mac_1_rx_status, + input wire qsfpdda_mac_1_rx_lfc_req, + input wire [7:0] qsfpdda_mac_1_rx_pfc_req, input wire qsfpdda_mac_2_tx_clk, input wire qsfpdda_mac_2_tx_rst, @@ -260,6 +265,10 @@ module fpga_core # output wire qsfpdda_mac_2_tx_axis_tlast, output wire [AXIS_ETH_TX_USER_WIDTH-1:0] qsfpdda_mac_2_tx_axis_tuser, + input wire qsfpdda_mac_2_tx_status, + output wire qsfpdda_mac_2_tx_lfc_req, + output wire [7:0] qsfpdda_mac_2_tx_pfc_req, + input wire qsfpdda_mac_2_rx_clk, input wire qsfpdda_mac_2_rx_rst, @@ -274,6 +283,8 @@ module fpga_core # input wire [AXIS_ETH_RX_USER_WIDTH-1:0] qsfpdda_mac_2_rx_axis_tuser, input wire qsfpdda_mac_2_rx_status, + input wire qsfpdda_mac_2_rx_lfc_req, + input wire [7:0] qsfpdda_mac_2_rx_pfc_req, input wire qsfpdda_mac_3_tx_clk, input wire qsfpdda_mac_3_tx_rst, @@ -293,6 +304,10 @@ module fpga_core # output wire qsfpdda_mac_3_tx_axis_tlast, output wire [AXIS_ETH_TX_USER_WIDTH-1:0] qsfpdda_mac_3_tx_axis_tuser, + input wire qsfpdda_mac_3_tx_status, + output wire qsfpdda_mac_3_tx_lfc_req, + output wire [7:0] qsfpdda_mac_3_tx_pfc_req, + input wire qsfpdda_mac_3_rx_clk, input wire qsfpdda_mac_3_rx_rst, @@ -307,6 +322,8 @@ module fpga_core # input wire [AXIS_ETH_RX_USER_WIDTH-1:0] qsfpdda_mac_3_rx_axis_tuser, input wire qsfpdda_mac_3_rx_status, + input wire qsfpdda_mac_3_rx_lfc_req, + input wire [7:0] qsfpdda_mac_3_rx_pfc_req, input wire qsfpdda_mac_4_tx_clk, input wire qsfpdda_mac_4_tx_rst, @@ -326,6 +343,10 @@ module fpga_core # output wire qsfpdda_mac_4_tx_axis_tlast, output wire [AXIS_ETH_TX_USER_WIDTH-1:0] qsfpdda_mac_4_tx_axis_tuser, + input wire qsfpdda_mac_4_tx_status, + output wire qsfpdda_mac_4_tx_lfc_req, + output wire [7:0] qsfpdda_mac_4_tx_pfc_req, + input wire qsfpdda_mac_4_rx_clk, input wire qsfpdda_mac_4_rx_rst, @@ -340,6 +361,8 @@ module fpga_core # input wire [AXIS_ETH_RX_USER_WIDTH-1:0] qsfpdda_mac_4_rx_axis_tuser, input wire qsfpdda_mac_4_rx_status, + input wire qsfpdda_mac_4_rx_lfc_req, + input wire [7:0] qsfpdda_mac_4_rx_pfc_req, input wire qsfpdda_mac_5_tx_clk, input wire qsfpdda_mac_5_tx_rst, @@ -359,6 +382,10 @@ module fpga_core # output wire qsfpdda_mac_5_tx_axis_tlast, output wire [AXIS_ETH_TX_USER_WIDTH-1:0] qsfpdda_mac_5_tx_axis_tuser, + input wire qsfpdda_mac_5_tx_status, + output wire qsfpdda_mac_5_tx_lfc_req, + output wire [7:0] qsfpdda_mac_5_tx_pfc_req, + input wire qsfpdda_mac_5_rx_clk, input wire qsfpdda_mac_5_rx_rst, @@ -373,6 +400,8 @@ module fpga_core # input wire [AXIS_ETH_RX_USER_WIDTH-1:0] qsfpdda_mac_5_rx_axis_tuser, input wire qsfpdda_mac_5_rx_status, + input wire qsfpdda_mac_5_rx_lfc_req, + input wire [7:0] qsfpdda_mac_5_rx_pfc_req, input wire qsfpdda_mac_6_tx_clk, input wire qsfpdda_mac_6_tx_rst, @@ -392,6 +421,10 @@ module fpga_core # output wire qsfpdda_mac_6_tx_axis_tlast, output wire [AXIS_ETH_TX_USER_WIDTH-1:0] qsfpdda_mac_6_tx_axis_tuser, + input wire qsfpdda_mac_6_tx_status, + output wire qsfpdda_mac_6_tx_lfc_req, + output wire [7:0] qsfpdda_mac_6_tx_pfc_req, + input wire qsfpdda_mac_6_rx_clk, input wire qsfpdda_mac_6_rx_rst, @@ -406,6 +439,8 @@ module fpga_core # input wire [AXIS_ETH_RX_USER_WIDTH-1:0] qsfpdda_mac_6_rx_axis_tuser, input wire qsfpdda_mac_6_rx_status, + input wire qsfpdda_mac_6_rx_lfc_req, + input wire [7:0] qsfpdda_mac_6_rx_pfc_req, input wire qsfpdda_mac_7_tx_clk, input wire qsfpdda_mac_7_tx_rst, @@ -425,6 +460,10 @@ module fpga_core # output wire qsfpdda_mac_7_tx_axis_tlast, output wire [AXIS_ETH_TX_USER_WIDTH-1:0] qsfpdda_mac_7_tx_axis_tuser, + input wire qsfpdda_mac_7_tx_status, + output wire qsfpdda_mac_7_tx_lfc_req, + output wire [7:0] qsfpdda_mac_7_tx_pfc_req, + input wire qsfpdda_mac_7_rx_clk, input wire qsfpdda_mac_7_rx_rst, @@ -439,6 +478,8 @@ module fpga_core # input wire [AXIS_ETH_RX_USER_WIDTH-1:0] qsfpdda_mac_7_rx_axis_tuser, input wire qsfpdda_mac_7_rx_status, + input wire qsfpdda_mac_7_rx_lfc_req, + input wire [7:0] qsfpdda_mac_7_rx_pfc_req, input wire qsfpdda_mac_8_tx_clk, input wire qsfpdda_mac_8_tx_rst, @@ -458,6 +499,10 @@ module fpga_core # output wire qsfpdda_mac_8_tx_axis_tlast, output wire [AXIS_ETH_TX_USER_WIDTH-1:0] qsfpdda_mac_8_tx_axis_tuser, + input wire qsfpdda_mac_8_tx_status, + output wire qsfpdda_mac_8_tx_lfc_req, + output wire [7:0] qsfpdda_mac_8_tx_pfc_req, + input wire qsfpdda_mac_8_rx_clk, input wire qsfpdda_mac_8_rx_rst, @@ -472,6 +517,8 @@ module fpga_core # input wire [AXIS_ETH_RX_USER_WIDTH-1:0] qsfpdda_mac_8_rx_axis_tuser, input wire qsfpdda_mac_8_rx_status, + input wire qsfpdda_mac_8_rx_lfc_req, + input wire [7:0] qsfpdda_mac_8_rx_pfc_req, output wire qsfpdda_initmode, input wire qsfpdda_interrupt_n, @@ -503,6 +550,10 @@ module fpga_core # output wire qsfpddb_mac_1_tx_axis_tlast, output wire [AXIS_ETH_TX_USER_WIDTH-1:0] qsfpddb_mac_1_tx_axis_tuser, + input wire qsfpddb_mac_1_tx_status, + output wire qsfpddb_mac_1_tx_lfc_req, + output wire [7:0] qsfpddb_mac_1_tx_pfc_req, + input wire qsfpddb_mac_1_rx_clk, input wire qsfpddb_mac_1_rx_rst, @@ -517,6 +568,8 @@ module fpga_core # input wire [AXIS_ETH_RX_USER_WIDTH-1:0] qsfpddb_mac_1_rx_axis_tuser, input wire qsfpddb_mac_1_rx_status, + input wire qsfpddb_mac_1_rx_lfc_req, + input wire [7:0] qsfpddb_mac_1_rx_pfc_req, input wire qsfpddb_mac_2_tx_clk, input wire qsfpddb_mac_2_tx_rst, @@ -536,6 +589,10 @@ module fpga_core # output wire qsfpddb_mac_2_tx_axis_tlast, output wire [AXIS_ETH_TX_USER_WIDTH-1:0] qsfpddb_mac_2_tx_axis_tuser, + input wire qsfpddb_mac_2_tx_status, + output wire qsfpddb_mac_2_tx_lfc_req, + output wire [7:0] qsfpddb_mac_2_tx_pfc_req, + input wire qsfpddb_mac_2_rx_clk, input wire qsfpddb_mac_2_rx_rst, @@ -550,6 +607,8 @@ module fpga_core # input wire [AXIS_ETH_RX_USER_WIDTH-1:0] qsfpddb_mac_2_rx_axis_tuser, input wire qsfpddb_mac_2_rx_status, + input wire qsfpddb_mac_2_rx_lfc_req, + input wire [7:0] qsfpddb_mac_2_rx_pfc_req, input wire qsfpddb_mac_3_tx_clk, input wire qsfpddb_mac_3_tx_rst, @@ -569,6 +628,10 @@ module fpga_core # output wire qsfpddb_mac_3_tx_axis_tlast, output wire [AXIS_ETH_TX_USER_WIDTH-1:0] qsfpddb_mac_3_tx_axis_tuser, + input wire qsfpddb_mac_3_tx_status, + output wire qsfpddb_mac_3_tx_lfc_req, + output wire [7:0] qsfpddb_mac_3_tx_pfc_req, + input wire qsfpddb_mac_3_rx_clk, input wire qsfpddb_mac_3_rx_rst, @@ -583,6 +646,8 @@ module fpga_core # input wire [AXIS_ETH_RX_USER_WIDTH-1:0] qsfpddb_mac_3_rx_axis_tuser, input wire qsfpddb_mac_3_rx_status, + input wire qsfpddb_mac_3_rx_lfc_req, + input wire [7:0] qsfpddb_mac_3_rx_pfc_req, input wire qsfpddb_mac_4_tx_clk, input wire qsfpddb_mac_4_tx_rst, @@ -602,6 +667,10 @@ module fpga_core # output wire qsfpddb_mac_4_tx_axis_tlast, output wire [AXIS_ETH_TX_USER_WIDTH-1:0] qsfpddb_mac_4_tx_axis_tuser, + input wire qsfpddb_mac_4_tx_status, + output wire qsfpddb_mac_4_tx_lfc_req, + output wire [7:0] qsfpddb_mac_4_tx_pfc_req, + input wire qsfpddb_mac_4_rx_clk, input wire qsfpddb_mac_4_rx_rst, @@ -616,6 +685,8 @@ module fpga_core # input wire [AXIS_ETH_RX_USER_WIDTH-1:0] qsfpddb_mac_4_rx_axis_tuser, input wire qsfpddb_mac_4_rx_status, + input wire qsfpddb_mac_4_rx_lfc_req, + input wire [7:0] qsfpddb_mac_4_rx_pfc_req, input wire qsfpddb_mac_5_tx_clk, input wire qsfpddb_mac_5_tx_rst, @@ -635,6 +706,10 @@ module fpga_core # output wire qsfpddb_mac_5_tx_axis_tlast, output wire [AXIS_ETH_TX_USER_WIDTH-1:0] qsfpddb_mac_5_tx_axis_tuser, + input wire qsfpddb_mac_5_tx_status, + output wire qsfpddb_mac_5_tx_lfc_req, + output wire [7:0] qsfpddb_mac_5_tx_pfc_req, + input wire qsfpddb_mac_5_rx_clk, input wire qsfpddb_mac_5_rx_rst, @@ -649,6 +724,8 @@ module fpga_core # input wire [AXIS_ETH_RX_USER_WIDTH-1:0] qsfpddb_mac_5_rx_axis_tuser, input wire qsfpddb_mac_5_rx_status, + input wire qsfpddb_mac_5_rx_lfc_req, + input wire [7:0] qsfpddb_mac_5_rx_pfc_req, input wire qsfpddb_mac_6_tx_clk, input wire qsfpddb_mac_6_tx_rst, @@ -668,6 +745,10 @@ module fpga_core # output wire qsfpddb_mac_6_tx_axis_tlast, output wire [AXIS_ETH_TX_USER_WIDTH-1:0] qsfpddb_mac_6_tx_axis_tuser, + input wire qsfpddb_mac_6_tx_status, + output wire qsfpddb_mac_6_tx_lfc_req, + output wire [7:0] qsfpddb_mac_6_tx_pfc_req, + input wire qsfpddb_mac_6_rx_clk, input wire qsfpddb_mac_6_rx_rst, @@ -682,6 +763,8 @@ module fpga_core # input wire [AXIS_ETH_RX_USER_WIDTH-1:0] qsfpddb_mac_6_rx_axis_tuser, input wire qsfpddb_mac_6_rx_status, + input wire qsfpddb_mac_6_rx_lfc_req, + input wire [7:0] qsfpddb_mac_6_rx_pfc_req, input wire qsfpddb_mac_7_tx_clk, input wire qsfpddb_mac_7_tx_rst, @@ -701,6 +784,10 @@ module fpga_core # output wire qsfpddb_mac_7_tx_axis_tlast, output wire [AXIS_ETH_TX_USER_WIDTH-1:0] qsfpddb_mac_7_tx_axis_tuser, + input wire qsfpddb_mac_7_tx_status, + output wire qsfpddb_mac_7_tx_lfc_req, + output wire [7:0] qsfpddb_mac_7_tx_pfc_req, + input wire qsfpddb_mac_7_rx_clk, input wire qsfpddb_mac_7_rx_rst, @@ -715,6 +802,8 @@ module fpga_core # input wire [AXIS_ETH_RX_USER_WIDTH-1:0] qsfpddb_mac_7_rx_axis_tuser, input wire qsfpddb_mac_7_rx_status, + input wire qsfpddb_mac_7_rx_lfc_req, + input wire [7:0] qsfpddb_mac_7_rx_pfc_req, input wire qsfpddb_mac_8_tx_clk, input wire qsfpddb_mac_8_tx_rst, @@ -734,6 +823,10 @@ module fpga_core # output wire qsfpddb_mac_8_tx_axis_tlast, output wire [AXIS_ETH_TX_USER_WIDTH-1:0] qsfpddb_mac_8_tx_axis_tuser, + input wire qsfpddb_mac_8_tx_status, + output wire qsfpddb_mac_8_tx_lfc_req, + output wire [7:0] qsfpddb_mac_8_tx_pfc_req, + input wire qsfpddb_mac_8_rx_clk, input wire qsfpddb_mac_8_rx_rst, @@ -748,6 +841,8 @@ module fpga_core # input wire [AXIS_ETH_RX_USER_WIDTH-1:0] qsfpddb_mac_8_rx_axis_tuser, input wire qsfpddb_mac_8_rx_status, + input wire qsfpddb_mac_8_rx_lfc_req, + input wire [7:0] qsfpddb_mac_8_rx_pfc_req, output wire qsfpddb_initmode, input wire qsfpddb_interrupt_n, @@ -1016,7 +1111,12 @@ wire [PORT_COUNT*TX_TAG_WIDTH-1:0] axis_eth_tx_ptp_ts_tag; wire [PORT_COUNT-1:0] axis_eth_tx_ptp_ts_valid; wire [PORT_COUNT-1:0] axis_eth_tx_ptp_ts_ready; +wire [PORT_COUNT-1:0] eth_tx_enable; wire [PORT_COUNT-1:0] eth_tx_status; +wire [PORT_COUNT-1:0] eth_tx_lfc_en; +wire [PORT_COUNT-1:0] eth_tx_lfc_req; +wire [PORT_COUNT*8-1:0] eth_tx_pfc_en; +wire [PORT_COUNT*8-1:0] eth_tx_pfc_req; wire [PORT_COUNT-1:0] eth_rx_clk; wire [PORT_COUNT-1:0] eth_rx_rst; @@ -1033,7 +1133,14 @@ wire [PORT_COUNT-1:0] axis_eth_rx_tready; wire [PORT_COUNT-1:0] axis_eth_rx_tlast; wire [PORT_COUNT*AXIS_ETH_RX_USER_WIDTH-1:0] axis_eth_rx_tuser; +wire [PORT_COUNT-1:0] eth_rx_enable; wire [PORT_COUNT-1:0] eth_rx_status; +wire [PORT_COUNT-1:0] eth_rx_lfc_en; +wire [PORT_COUNT-1:0] eth_rx_lfc_req; +wire [PORT_COUNT-1:0] eth_rx_lfc_ack; +wire [PORT_COUNT*8-1:0] eth_rx_pfc_en; +wire [PORT_COUNT*8-1:0] eth_rx_pfc_req; +wire [PORT_COUNT*8-1:0] eth_rx_pfc_ack; mqnic_port_map_mac_axis #( .MAC_COUNT(16), @@ -1074,7 +1181,12 @@ mqnic_port_map_mac_axis_inst ( .s_axis_mac_tx_ptp_ts_valid({qsfpddb_mac_8_tx_ptp_ts_valid, qsfpddb_mac_7_tx_ptp_ts_valid, qsfpddb_mac_6_tx_ptp_ts_valid, qsfpddb_mac_5_tx_ptp_ts_valid, qsfpddb_mac_4_tx_ptp_ts_valid, qsfpddb_mac_3_tx_ptp_ts_valid, qsfpddb_mac_2_tx_ptp_ts_valid, qsfpddb_mac_1_tx_ptp_ts_valid, qsfpdda_mac_8_tx_ptp_ts_valid, qsfpdda_mac_7_tx_ptp_ts_valid, qsfpdda_mac_6_tx_ptp_ts_valid, qsfpdda_mac_5_tx_ptp_ts_valid, qsfpdda_mac_4_tx_ptp_ts_valid, qsfpdda_mac_3_tx_ptp_ts_valid, qsfpdda_mac_2_tx_ptp_ts_valid, qsfpdda_mac_1_tx_ptp_ts_valid}), .s_axis_mac_tx_ptp_ts_ready(), - .mac_tx_status(16'hffff), + .mac_tx_enable(), + .mac_tx_status({qsfpddb_mac_8_tx_status, qsfpddb_mac_7_tx_status, qsfpddb_mac_6_tx_status, qsfpddb_mac_5_tx_status, qsfpddb_mac_4_tx_status, qsfpddb_mac_3_tx_status, qsfpddb_mac_2_tx_status, qsfpddb_mac_1_tx_status, qsfpdda_mac_8_tx_status, qsfpdda_mac_7_tx_status, qsfpdda_mac_6_tx_status, qsfpdda_mac_5_tx_status, qsfpdda_mac_4_tx_status, qsfpdda_mac_3_tx_status, qsfpdda_mac_2_tx_status, qsfpdda_mac_1_tx_status}), + .mac_tx_lfc_en(), + .mac_tx_lfc_req({qsfpddb_mac_8_tx_lfc_req, qsfpddb_mac_7_tx_lfc_req, qsfpddb_mac_6_tx_lfc_req, qsfpddb_mac_5_tx_lfc_req, qsfpddb_mac_4_tx_lfc_req, qsfpddb_mac_3_tx_lfc_req, qsfpddb_mac_2_tx_lfc_req, qsfpddb_mac_1_tx_lfc_req, qsfpdda_mac_8_tx_lfc_req, qsfpdda_mac_7_tx_lfc_req, qsfpdda_mac_6_tx_lfc_req, qsfpdda_mac_5_tx_lfc_req, qsfpdda_mac_4_tx_lfc_req, qsfpdda_mac_3_tx_lfc_req, qsfpdda_mac_2_tx_lfc_req, qsfpdda_mac_1_tx_lfc_req}), + .mac_tx_pfc_en(), + .mac_tx_pfc_req({qsfpddb_mac_8_tx_pfc_req, qsfpddb_mac_7_tx_pfc_req, qsfpddb_mac_6_tx_pfc_req, qsfpddb_mac_5_tx_pfc_req, qsfpddb_mac_4_tx_pfc_req, qsfpddb_mac_3_tx_pfc_req, qsfpddb_mac_2_tx_pfc_req, qsfpddb_mac_1_tx_pfc_req, qsfpdda_mac_8_tx_pfc_req, qsfpdda_mac_7_tx_pfc_req, qsfpdda_mac_6_tx_pfc_req, qsfpdda_mac_5_tx_pfc_req, qsfpdda_mac_4_tx_pfc_req, qsfpdda_mac_3_tx_pfc_req, qsfpdda_mac_2_tx_pfc_req, qsfpdda_mac_1_tx_pfc_req}), .mac_rx_clk({qsfpddb_mac_8_rx_clk, qsfpddb_mac_7_rx_clk, qsfpddb_mac_6_rx_clk, qsfpddb_mac_5_rx_clk, qsfpddb_mac_4_rx_clk, qsfpddb_mac_3_rx_clk, qsfpddb_mac_2_rx_clk, qsfpddb_mac_1_rx_clk, qsfpdda_mac_8_rx_clk, qsfpdda_mac_7_rx_clk, qsfpdda_mac_6_rx_clk, qsfpdda_mac_5_rx_clk, qsfpdda_mac_4_rx_clk, qsfpdda_mac_3_rx_clk, qsfpdda_mac_2_rx_clk, qsfpdda_mac_1_rx_clk}), .mac_rx_rst({qsfpddb_mac_8_rx_rst, qsfpddb_mac_7_rx_rst, qsfpddb_mac_6_rx_rst, qsfpddb_mac_5_rx_rst, qsfpddb_mac_4_rx_rst, qsfpddb_mac_3_rx_rst, qsfpddb_mac_2_rx_rst, qsfpddb_mac_1_rx_rst, qsfpdda_mac_8_rx_rst, qsfpdda_mac_7_rx_rst, qsfpdda_mac_6_rx_rst, qsfpdda_mac_5_rx_rst, qsfpdda_mac_4_rx_rst, qsfpdda_mac_3_rx_rst, qsfpdda_mac_2_rx_rst, qsfpdda_mac_1_rx_rst}), @@ -1091,7 +1203,14 @@ mqnic_port_map_mac_axis_inst ( .s_axis_mac_rx_tlast({qsfpddb_mac_8_rx_axis_tlast, qsfpddb_mac_7_rx_axis_tlast, qsfpddb_mac_6_rx_axis_tlast, qsfpddb_mac_5_rx_axis_tlast, qsfpddb_mac_4_rx_axis_tlast, qsfpddb_mac_3_rx_axis_tlast, qsfpddb_mac_2_rx_axis_tlast, qsfpddb_mac_1_rx_axis_tlast, qsfpdda_mac_8_rx_axis_tlast, qsfpdda_mac_7_rx_axis_tlast, qsfpdda_mac_6_rx_axis_tlast, qsfpdda_mac_5_rx_axis_tlast, qsfpdda_mac_4_rx_axis_tlast, qsfpdda_mac_3_rx_axis_tlast, qsfpdda_mac_2_rx_axis_tlast, qsfpdda_mac_1_rx_axis_tlast}), .s_axis_mac_rx_tuser({qsfpddb_mac_8_rx_axis_tuser, qsfpddb_mac_7_rx_axis_tuser, qsfpddb_mac_6_rx_axis_tuser, qsfpddb_mac_5_rx_axis_tuser, qsfpddb_mac_4_rx_axis_tuser, qsfpddb_mac_3_rx_axis_tuser, qsfpddb_mac_2_rx_axis_tuser, qsfpddb_mac_1_rx_axis_tuser, qsfpdda_mac_8_rx_axis_tuser, qsfpdda_mac_7_rx_axis_tuser, qsfpdda_mac_6_rx_axis_tuser, qsfpdda_mac_5_rx_axis_tuser, qsfpdda_mac_4_rx_axis_tuser, qsfpdda_mac_3_rx_axis_tuser, qsfpdda_mac_2_rx_axis_tuser, qsfpdda_mac_1_rx_axis_tuser}), + .mac_rx_enable(), .mac_rx_status({qsfpddb_mac_8_rx_status, qsfpddb_mac_7_rx_status, qsfpddb_mac_6_rx_status, qsfpddb_mac_5_rx_status, qsfpddb_mac_4_rx_status, qsfpddb_mac_3_rx_status, qsfpddb_mac_2_rx_status, qsfpddb_mac_1_rx_status, qsfpdda_mac_8_rx_status, qsfpdda_mac_7_rx_status, qsfpdda_mac_6_rx_status, qsfpdda_mac_5_rx_status, qsfpdda_mac_4_rx_status, qsfpdda_mac_3_rx_status, qsfpdda_mac_2_rx_status, qsfpdda_mac_1_rx_status}), + .mac_rx_lfc_en(), + .mac_rx_lfc_req({qsfpddb_mac_8_rx_lfc_req, qsfpddb_mac_7_rx_lfc_req, qsfpddb_mac_6_rx_lfc_req, qsfpddb_mac_5_rx_lfc_req, qsfpddb_mac_4_rx_lfc_req, qsfpddb_mac_3_rx_lfc_req, qsfpddb_mac_2_rx_lfc_req, qsfpddb_mac_1_rx_lfc_req, qsfpdda_mac_8_rx_lfc_req, qsfpdda_mac_7_rx_lfc_req, qsfpdda_mac_6_rx_lfc_req, qsfpdda_mac_5_rx_lfc_req, qsfpdda_mac_4_rx_lfc_req, qsfpdda_mac_3_rx_lfc_req, qsfpdda_mac_2_rx_lfc_req, qsfpdda_mac_1_rx_lfc_req}), + .mac_rx_lfc_ack(), + .mac_rx_pfc_en(), + .mac_rx_pfc_req({qsfpddb_mac_8_rx_pfc_req, qsfpddb_mac_7_rx_pfc_req, qsfpddb_mac_6_rx_pfc_req, qsfpddb_mac_5_rx_pfc_req, qsfpddb_mac_4_rx_pfc_req, qsfpddb_mac_3_rx_pfc_req, qsfpddb_mac_2_rx_pfc_req, qsfpddb_mac_1_rx_pfc_req, qsfpdda_mac_8_rx_pfc_req, qsfpdda_mac_7_rx_pfc_req, qsfpdda_mac_6_rx_pfc_req, qsfpdda_mac_5_rx_pfc_req, qsfpdda_mac_4_rx_pfc_req, qsfpdda_mac_3_rx_pfc_req, qsfpdda_mac_2_rx_pfc_req, qsfpdda_mac_1_rx_pfc_req}), + .mac_rx_pfc_ack(), // towards datapath .tx_clk(eth_tx_clk), @@ -1114,7 +1233,12 @@ mqnic_port_map_mac_axis_inst ( .m_axis_tx_ptp_ts_valid(axis_eth_tx_ptp_ts_valid), .m_axis_tx_ptp_ts_ready(axis_eth_tx_ptp_ts_ready), + .tx_enable(eth_tx_enable), .tx_status(eth_tx_status), + .tx_lfc_en(eth_tx_lfc_en), + .tx_lfc_req(eth_tx_lfc_req), + .tx_pfc_en(eth_tx_pfc_en), + .tx_pfc_req(eth_tx_pfc_req), .rx_clk(eth_rx_clk), .rx_rst(eth_rx_rst), @@ -1131,7 +1255,14 @@ mqnic_port_map_mac_axis_inst ( .m_axis_rx_tlast(axis_eth_rx_tlast), .m_axis_rx_tuser(axis_eth_rx_tuser), - .rx_status(eth_rx_status) + .rx_enable(eth_rx_enable), + .rx_status(eth_rx_status), + .rx_lfc_en(eth_rx_lfc_en), + .rx_lfc_req(eth_rx_lfc_req), + .rx_lfc_ack(eth_rx_lfc_ack), + .rx_pfc_en(eth_rx_pfc_en), + .rx_pfc_req(eth_rx_pfc_req), + .rx_pfc_ack(eth_rx_pfc_ack) ); mqnic_core_pcie_ptile #( @@ -1201,6 +1332,9 @@ mqnic_core_pcie_ptile #( .TX_CHECKSUM_ENABLE(TX_CHECKSUM_ENABLE), .RX_HASH_ENABLE(RX_HASH_ENABLE), .RX_CHECKSUM_ENABLE(RX_CHECKSUM_ENABLE), + .PFC_ENABLE(PFC_ENABLE), + .LFC_ENABLE(LFC_ENABLE), + .MAC_CTRL_ENABLE(0), .TX_FIFO_DEPTH(TX_FIFO_DEPTH), .RX_FIFO_DEPTH(RX_FIFO_DEPTH), .MAX_TX_SIZE(MAX_TX_SIZE), @@ -1410,7 +1544,13 @@ core_inst ( .s_axis_eth_tx_cpl_valid(axis_eth_tx_ptp_ts_valid), .s_axis_eth_tx_cpl_ready(axis_eth_tx_ptp_ts_ready), + .eth_tx_enable(eth_tx_enable), .eth_tx_status(eth_tx_status), + .eth_tx_lfc_en(eth_tx_lfc_en), + .eth_tx_lfc_req(eth_tx_lfc_req), + .eth_tx_pfc_en(eth_tx_pfc_en), + .eth_tx_pfc_req(eth_tx_pfc_req), + .eth_tx_fc_quanta_clk_en(0), .eth_rx_clk(eth_rx_clk), .eth_rx_rst(eth_rx_rst), @@ -1427,7 +1567,15 @@ core_inst ( .s_axis_eth_rx_tlast(axis_eth_rx_tlast), .s_axis_eth_rx_tuser(axis_eth_rx_tuser), + .eth_rx_enable(eth_rx_enable), .eth_rx_status(eth_rx_status), + .eth_rx_lfc_en(eth_rx_lfc_en), + .eth_rx_lfc_req(eth_rx_lfc_req), + .eth_rx_lfc_ack(eth_rx_lfc_ack), + .eth_rx_pfc_en(eth_rx_pfc_en), + .eth_rx_pfc_req(eth_rx_pfc_req), + .eth_rx_pfc_ack(eth_rx_pfc_ack), + .eth_rx_fc_quanta_clk_en(0), /* * DDR diff --git a/fpga/mqnic/DE10_Agilex/fpga_25g/tb/fpga_core/Makefile b/fpga/mqnic/DE10_Agilex/fpga_25g/tb/fpga_core/Makefile index 38c3fe9bd..e97f4f6f8 100644 --- a/fpga/mqnic/DE10_Agilex/fpga_25g/tb/fpga_core/Makefile +++ b/fpga/mqnic/DE10_Agilex/fpga_25g/tb/fpga_core/Makefile @@ -168,6 +168,8 @@ export PARAM_TX_CPL_FIFO_DEPTH := 32 export PARAM_TX_CHECKSUM_ENABLE := 1 export PARAM_RX_HASH_ENABLE := 1 export PARAM_RX_CHECKSUM_ENABLE := 1 +export PARAM_LFC_ENABLE := 1 +export PARAM_PFC_ENABLE := $(PARAM_LFC_ENABLE) export PARAM_TX_FIFO_DEPTH := 32768 export PARAM_RX_FIFO_DEPTH := 32768 export PARAM_MAX_TX_SIZE := 9214 diff --git a/fpga/mqnic/DE10_Agilex/fpga_25g/tb/fpga_core/test_fpga_core.py b/fpga/mqnic/DE10_Agilex/fpga_25g/tb/fpga_core/test_fpga_core.py index 1f18d50a8..92c9418cc 100644 --- a/fpga/mqnic/DE10_Agilex/fpga_25g/tb/fpga_core/test_fpga_core.py +++ b/fpga/mqnic/DE10_Agilex/fpga_25g/tb/fpga_core/test_fpga_core.py @@ -280,6 +280,8 @@ class TB(object): macs.append(mac) getattr(dut, f"qsfpdd{x}_mac_{y}_rx_status").setimmediatevalue(1) + getattr(dut, f"qsfpdd{x}_mac_{y}_rx_lfc_req").setimmediatevalue(0) + getattr(dut, f"qsfpdd{x}_mac_{y}_rx_pfc_req").setimmediatevalue(0) self.qsfpdd_mac.append(macs) @@ -689,6 +691,8 @@ def test_fpga_core(request): parameters['TX_CHECKSUM_ENABLE'] = 1 parameters['RX_HASH_ENABLE'] = 1 parameters['RX_CHECKSUM_ENABLE'] = 1 + parameters['LFC_ENABLE'] = 1 + parameters['PFC_ENABLE'] = parameters['LFC_ENABLE'] parameters['TX_FIFO_DEPTH'] = 32768 parameters['RX_FIFO_DEPTH'] = 32768 parameters['MAX_TX_SIZE'] = 9214 diff --git a/fpga/mqnic/DK_DEV_1SDX_P_A/fpga_100g/fpga/config.tcl b/fpga/mqnic/DK_DEV_1SDX_P_A/fpga_100g/fpga/config.tcl index 401bd90a7..060dc1b65 100644 --- a/fpga/mqnic/DK_DEV_1SDX_P_A/fpga_100g/fpga/config.tcl +++ b/fpga/mqnic/DK_DEV_1SDX_P_A/fpga_100g/fpga/config.tcl @@ -100,6 +100,8 @@ dict set params TX_CPL_FIFO_DEPTH "32" dict set params TX_CHECKSUM_ENABLE "1" dict set params RX_HASH_ENABLE "1" dict set params RX_CHECKSUM_ENABLE "1" +dict set params PFC_ENABLE "1" +dict set params LFC_ENABLE [dict get $params PFC_ENABLE] dict set params TX_FIFO_DEPTH "32768" dict set params RX_FIFO_DEPTH "131072" dict set params MAX_TX_SIZE "9214" diff --git a/fpga/mqnic/DK_DEV_1SDX_P_A/fpga_100g/fpga_app_dma_bench/config.tcl b/fpga/mqnic/DK_DEV_1SDX_P_A/fpga_100g/fpga_app_dma_bench/config.tcl index 3ce5388e6..bfcbc61f8 100644 --- a/fpga/mqnic/DK_DEV_1SDX_P_A/fpga_100g/fpga_app_dma_bench/config.tcl +++ b/fpga/mqnic/DK_DEV_1SDX_P_A/fpga_100g/fpga_app_dma_bench/config.tcl @@ -100,6 +100,8 @@ dict set params TX_CPL_FIFO_DEPTH "32" dict set params TX_CHECKSUM_ENABLE "1" dict set params RX_HASH_ENABLE "1" dict set params RX_CHECKSUM_ENABLE "1" +dict set params PFC_ENABLE "1" +dict set params LFC_ENABLE [dict get $params PFC_ENABLE] dict set params TX_FIFO_DEPTH "32768" dict set params RX_FIFO_DEPTH "131072" dict set params MAX_TX_SIZE "9214" diff --git a/fpga/mqnic/DK_DEV_1SDX_P_A/fpga_100g/rtl/eth_mac_wrapper.v b/fpga/mqnic/DK_DEV_1SDX_P_A/fpga_100g/rtl/eth_mac_wrapper.v index 543cbe071..d4c5bb46d 100644 --- a/fpga/mqnic/DK_DEV_1SDX_P_A/fpga_100g/rtl/eth_mac_wrapper.v +++ b/fpga/mqnic/DK_DEV_1SDX_P_A/fpga_100g/rtl/eth_mac_wrapper.v @@ -66,13 +66,19 @@ module eth_mac_wrapper # input wire mac_tx_axis_tlast, input wire [TX_USER_WIDTH-1:0] mac_tx_axis_tuser, + output wire mac_tx_status, + input wire mac_tx_lfc_req, + input wire [7:0] mac_tx_pfc_req, + output wire [DATA_WIDTH-1:0] mac_rx_axis_tdata, output wire [KEEP_WIDTH-1:0] mac_rx_axis_tkeep, output wire mac_rx_axis_tvalid, output wire mac_rx_axis_tlast, output wire [RX_USER_WIDTH-1:0] mac_rx_axis_tuser, - output wire mac_rx_status + output wire mac_rx_status, + output wire mac_rx_lfc_req, + output wire [7:0] mac_rx_pfc_req ); parameter XCVR_CH = 4; @@ -234,14 +240,16 @@ mac mac_inst ( .o_rx_error (mac_rx_error), .o_rxstatus_data (), .o_rxstatus_valid (), - .i_tx_pfc (8'd0), - .o_rx_pfc (), - .i_tx_pause (1'b0), - .o_rx_pause () + .i_tx_pfc (mac_tx_pfc_req), + .o_rx_pfc (mac_rx_pfc_req), + .i_tx_pause (mac_tx_lfc_req), + .o_rx_pause (mac_rx_lfc_req) ); assign mac_clk = mac_pll_clk_d64[4]; +assign mac_tx_status = mac_tx_lanes_stable; + assign mac_rx_status = mac_rx_pcs_ready; sync_reset #( diff --git a/fpga/mqnic/DK_DEV_1SDX_P_A/fpga_100g/rtl/fpga.v b/fpga/mqnic/DK_DEV_1SDX_P_A/fpga_100g/rtl/fpga.v index 1cd9c2391..fea7e216b 100644 --- a/fpga/mqnic/DK_DEV_1SDX_P_A/fpga_100g/rtl/fpga.v +++ b/fpga/mqnic/DK_DEV_1SDX_P_A/fpga_100g/rtl/fpga.v @@ -71,6 +71,8 @@ module fpga # parameter TX_CHECKSUM_ENABLE = 1, parameter RX_HASH_ENABLE = 1, parameter RX_CHECKSUM_ENABLE = 1, + parameter PFC_ENABLE = 1, + parameter LFC_ENABLE = PFC_ENABLE, parameter TX_FIFO_DEPTH = 32768, parameter RX_FIFO_DEPTH = 131072, parameter MAX_TX_SIZE = 9214, @@ -420,6 +422,10 @@ wire qsfp1_mac_tx_axis_tready_int; wire qsfp1_mac_tx_axis_tlast_int; wire [AXIS_ETH_TX_USER_WIDTH-1:0] qsfp1_mac_tx_axis_tuser_int; +wire qsfp1_mac_tx_status_int; +wire qsfp1_mac_tx_lfc_req_int; +wire [7:0] qsfp1_mac_tx_pfc_req_int; + wire [AXIS_ETH_DATA_WIDTH-1:0] qsfp1_mac_rx_axis_tdata_int; wire [AXIS_ETH_KEEP_WIDTH-1:0] qsfp1_mac_rx_axis_tkeep_int; wire qsfp1_mac_rx_axis_tvalid_int; @@ -427,6 +433,8 @@ wire qsfp1_mac_rx_axis_tlast_int; wire [AXIS_ETH_RX_USER_WIDTH-1:0] qsfp1_mac_rx_axis_tuser_int; wire qsfp1_mac_rx_status_int; +wire qsfp1_mac_rx_lfc_req_int; +wire [7:0] qsfp1_mac_rx_pfc_req_int; eth_mac_wrapper #( .PTP_TS_WIDTH(PTP_TS_WIDTH), @@ -462,13 +470,19 @@ qsfp1_mac_inst ( .mac_tx_axis_tlast(qsfp1_mac_tx_axis_tlast_int), .mac_tx_axis_tuser(qsfp1_mac_tx_axis_tuser_int), + .mac_tx_status(qsfp1_mac_tx_status_int), + .mac_tx_lfc_req(qsfp1_mac_tx_lfc_req_int), + .mac_tx_pfc_req(qsfp1_mac_tx_pfc_req_int), + .mac_rx_axis_tdata(qsfp1_mac_rx_axis_tdata_int), .mac_rx_axis_tkeep(qsfp1_mac_rx_axis_tkeep_int), .mac_rx_axis_tvalid(qsfp1_mac_rx_axis_tvalid_int), .mac_rx_axis_tlast(qsfp1_mac_rx_axis_tlast_int), .mac_rx_axis_tuser(qsfp1_mac_rx_axis_tuser_int), - .mac_rx_status(qsfp1_mac_rx_status_int) + .mac_rx_status(qsfp1_mac_rx_status_int), + .mac_rx_lfc_req(qsfp1_mac_rx_lfc_req_int), + .mac_rx_pfc_req(qsfp1_mac_rx_pfc_req_int) ); // QSFP2 @@ -488,6 +502,10 @@ wire qsfp2_mac_tx_axis_tready_int; wire qsfp2_mac_tx_axis_tlast_int; wire [AXIS_ETH_TX_USER_WIDTH-1:0] qsfp2_mac_tx_axis_tuser_int; +wire qsfp2_mac_tx_status_int; +wire qsfp2_mac_tx_lfc_req_int; +wire [7:0] qsfp2_mac_tx_pfc_req_int; + wire [AXIS_ETH_DATA_WIDTH-1:0] qsfp2_mac_rx_axis_tdata_int; wire [AXIS_ETH_KEEP_WIDTH-1:0] qsfp2_mac_rx_axis_tkeep_int; wire qsfp2_mac_rx_axis_tvalid_int; @@ -495,6 +513,8 @@ wire qsfp2_mac_rx_axis_tlast_int; wire [AXIS_ETH_RX_USER_WIDTH-1:0] qsfp2_mac_rx_axis_tuser_int; wire qsfp2_mac_rx_status_int; +wire qsfp2_mac_rx_lfc_req_int; +wire [7:0] qsfp2_mac_rx_pfc_req_int; eth_mac_wrapper #( .PTP_TS_WIDTH(PTP_TS_WIDTH), @@ -530,13 +550,19 @@ qsfp2_mac_inst ( .mac_tx_axis_tlast(qsfp2_mac_tx_axis_tlast_int), .mac_tx_axis_tuser(qsfp2_mac_tx_axis_tuser_int), + .mac_tx_status(qsfp2_mac_tx_status_int), + .mac_tx_lfc_req(qsfp2_mac_tx_lfc_req_int), + .mac_tx_pfc_req(qsfp2_mac_tx_pfc_req_int), + .mac_rx_axis_tdata(qsfp2_mac_rx_axis_tdata_int), .mac_rx_axis_tkeep(qsfp2_mac_rx_axis_tkeep_int), .mac_rx_axis_tvalid(qsfp2_mac_rx_axis_tvalid_int), .mac_rx_axis_tlast(qsfp2_mac_rx_axis_tlast_int), .mac_rx_axis_tuser(qsfp2_mac_rx_axis_tuser_int), - .mac_rx_status(qsfp2_mac_rx_status_int) + .mac_rx_status(qsfp2_mac_rx_status_int), + .mac_rx_lfc_req(qsfp2_mac_rx_lfc_req_int), + .mac_rx_pfc_req(qsfp2_mac_rx_pfc_req_int) ); wire ptp_clk; @@ -624,6 +650,8 @@ fpga_core #( .TX_CHECKSUM_ENABLE(TX_CHECKSUM_ENABLE), .RX_HASH_ENABLE(RX_HASH_ENABLE), .RX_CHECKSUM_ENABLE(RX_CHECKSUM_ENABLE), + .PFC_ENABLE(PFC_ENABLE), + .LFC_ENABLE(LFC_ENABLE), .TX_FIFO_DEPTH(TX_FIFO_DEPTH), .RX_FIFO_DEPTH(RX_FIFO_DEPTH), .MAX_TX_SIZE(MAX_TX_SIZE), @@ -775,6 +803,10 @@ core_inst ( .qsfp1_mac_tx_axis_tlast(qsfp1_mac_tx_axis_tlast_int), .qsfp1_mac_tx_axis_tuser(qsfp1_mac_tx_axis_tuser_int), + .qsfp1_mac_tx_status(qsfp1_mac_tx_status_int), + .qsfp1_mac_tx_lfc_req(qsfp1_mac_tx_lfc_req_int), + .qsfp1_mac_tx_pfc_req(qsfp1_mac_tx_pfc_req_int), + .qsfp1_mac_rx_axis_tdata(qsfp1_mac_rx_axis_tdata_int), .qsfp1_mac_rx_axis_tkeep(qsfp1_mac_rx_axis_tkeep_int), .qsfp1_mac_rx_axis_tvalid(qsfp1_mac_rx_axis_tvalid_int), @@ -782,6 +814,8 @@ core_inst ( .qsfp1_mac_rx_axis_tuser(qsfp1_mac_rx_axis_tuser_int), .qsfp1_mac_rx_status(qsfp1_mac_rx_status_int), + .qsfp1_mac_rx_lfc_req(qsfp1_mac_rx_lfc_req_int), + .qsfp1_mac_rx_pfc_req(qsfp1_mac_rx_pfc_req_int), .qsfp2_mac_clk(qsfp2_mac_clk_int), .qsfp2_mac_rst(qsfp2_mac_rst_int), @@ -799,13 +833,19 @@ core_inst ( .qsfp2_mac_tx_axis_tlast(qsfp2_mac_tx_axis_tlast_int), .qsfp2_mac_tx_axis_tuser(qsfp2_mac_tx_axis_tuser_int), + .qsfp2_mac_tx_status(qsfp2_mac_tx_status_int), + .qsfp2_mac_tx_lfc_req(qsfp2_mac_tx_lfc_req_int), + .qsfp2_mac_tx_pfc_req(qsfp2_mac_tx_pfc_req_int), + .qsfp2_mac_rx_axis_tdata(qsfp2_mac_rx_axis_tdata_int), .qsfp2_mac_rx_axis_tkeep(qsfp2_mac_rx_axis_tkeep_int), .qsfp2_mac_rx_axis_tvalid(qsfp2_mac_rx_axis_tvalid_int), .qsfp2_mac_rx_axis_tlast(qsfp2_mac_rx_axis_tlast_int), .qsfp2_mac_rx_axis_tuser(qsfp2_mac_rx_axis_tuser_int), - .qsfp2_mac_rx_status(qsfp2_mac_rx_status_int) + .qsfp2_mac_rx_status(qsfp2_mac_rx_status_int), + .qsfp2_mac_rx_lfc_req(qsfp2_mac_rx_lfc_req_int), + .qsfp2_mac_rx_pfc_req(qsfp2_mac_rx_pfc_req_int) ); endmodule diff --git a/fpga/mqnic/DK_DEV_1SDX_P_A/fpga_100g/rtl/fpga_core.v b/fpga/mqnic/DK_DEV_1SDX_P_A/fpga_100g/rtl/fpga_core.v index a1e3debf6..17d3fddf2 100644 --- a/fpga/mqnic/DK_DEV_1SDX_P_A/fpga_100g/rtl/fpga_core.v +++ b/fpga/mqnic/DK_DEV_1SDX_P_A/fpga_100g/rtl/fpga_core.v @@ -76,9 +76,8 @@ module fpga_core # parameter TX_CHECKSUM_ENABLE = 1, parameter RX_HASH_ENABLE = 1, parameter RX_CHECKSUM_ENABLE = 1, - parameter ENABLE_PADDING = 1, - parameter ENABLE_DIC = 1, - parameter MIN_FRAME_LENGTH = 64, + parameter PFC_ENABLE = 1, + parameter LFC_ENABLE = PFC_ENABLE, parameter TX_FIFO_DEPTH = 32768, parameter RX_FIFO_DEPTH = 131072, parameter MAX_TX_SIZE = 9214, @@ -232,6 +231,10 @@ module fpga_core # output wire qsfp1_mac_tx_axis_tlast, output wire [AXIS_ETH_TX_USER_WIDTH-1:0] qsfp1_mac_tx_axis_tuser, + input wire qsfp1_mac_tx_status, + output wire qsfp1_mac_tx_lfc_req, + output wire [7:0] qsfp1_mac_tx_pfc_req, + input wire [AXIS_ETH_DATA_WIDTH-1:0] qsfp1_mac_rx_axis_tdata, input wire [AXIS_ETH_KEEP_WIDTH-1:0] qsfp1_mac_rx_axis_tkeep, input wire qsfp1_mac_rx_axis_tvalid, @@ -239,6 +242,8 @@ module fpga_core # input wire [AXIS_ETH_RX_USER_WIDTH-1:0] qsfp1_mac_rx_axis_tuser, input wire qsfp1_mac_rx_status, + input wire qsfp1_mac_rx_lfc_req, + input wire [7:0] qsfp1_mac_rx_pfc_req, input wire qsfp2_mac_clk, input wire qsfp2_mac_rst, @@ -256,13 +261,19 @@ module fpga_core # output wire qsfp2_mac_tx_axis_tlast, output wire [AXIS_ETH_TX_USER_WIDTH-1:0] qsfp2_mac_tx_axis_tuser, + input wire qsfp2_mac_tx_status, + output wire qsfp2_mac_tx_lfc_req, + output wire [7:0] qsfp2_mac_tx_pfc_req, + input wire [AXIS_ETH_DATA_WIDTH-1:0] qsfp2_mac_rx_axis_tdata, input wire [AXIS_ETH_KEEP_WIDTH-1:0] qsfp2_mac_rx_axis_tkeep, input wire qsfp2_mac_rx_axis_tvalid, input wire qsfp2_mac_rx_axis_tlast, input wire [AXIS_ETH_RX_USER_WIDTH-1:0] qsfp2_mac_rx_axis_tuser, - input wire qsfp2_mac_rx_status + input wire qsfp2_mac_rx_status, + input wire qsfp2_mac_rx_lfc_req, + input wire [7:0] qsfp2_mac_rx_pfc_req ); parameter PORT_COUNT = IF_COUNT*PORTS_PER_IF; @@ -425,7 +436,12 @@ wire [PORT_COUNT*TX_TAG_WIDTH-1:0] axis_eth_tx_ptp_ts_tag; wire [PORT_COUNT-1:0] axis_eth_tx_ptp_ts_valid; wire [PORT_COUNT-1:0] axis_eth_tx_ptp_ts_ready; +wire [PORT_COUNT-1:0] eth_tx_enable; wire [PORT_COUNT-1:0] eth_tx_status; +wire [PORT_COUNT-1:0] eth_tx_lfc_en; +wire [PORT_COUNT-1:0] eth_tx_lfc_req; +wire [PORT_COUNT*8-1:0] eth_tx_pfc_en; +wire [PORT_COUNT*8-1:0] eth_tx_pfc_req; wire [PORT_COUNT-1:0] eth_rx_clk; wire [PORT_COUNT-1:0] eth_rx_rst; @@ -442,7 +458,14 @@ wire [PORT_COUNT-1:0] axis_eth_rx_tready; wire [PORT_COUNT-1:0] axis_eth_rx_tlast; wire [PORT_COUNT*AXIS_ETH_RX_USER_WIDTH-1:0] axis_eth_rx_tuser; +wire [PORT_COUNT-1:0] eth_rx_enable; wire [PORT_COUNT-1:0] eth_rx_status; +wire [PORT_COUNT-1:0] eth_rx_lfc_en; +wire [PORT_COUNT-1:0] eth_rx_lfc_req; +wire [PORT_COUNT-1:0] eth_rx_lfc_ack; +wire [PORT_COUNT*8-1:0] eth_rx_pfc_en; +wire [PORT_COUNT*8-1:0] eth_rx_pfc_req; +wire [PORT_COUNT*8-1:0] eth_rx_pfc_ack; mqnic_port_map_mac_axis #( .MAC_COUNT(2), @@ -483,7 +506,12 @@ mqnic_port_map_mac_axis_inst ( .s_axis_mac_tx_ptp_ts_valid({qsfp2_mac_tx_ptp_ts_valid, qsfp1_mac_tx_ptp_ts_valid}), .s_axis_mac_tx_ptp_ts_ready(), - .mac_tx_status(2'b11), + .mac_tx_enable(), + .mac_tx_status({qsfp2_mac_tx_status, qsfp1_mac_tx_status}), + .mac_tx_lfc_en(), + .mac_tx_lfc_req({qsfp2_mac_tx_lfc_req, qsfp1_mac_tx_lfc_req}), + .mac_tx_pfc_en(), + .mac_tx_pfc_req({qsfp2_mac_tx_pfc_req, qsfp1_mac_tx_pfc_req}), .mac_rx_clk({qsfp2_mac_clk, qsfp1_mac_clk}), .mac_rx_rst({qsfp2_mac_rst, qsfp1_mac_rst}), @@ -500,7 +528,14 @@ mqnic_port_map_mac_axis_inst ( .s_axis_mac_rx_tlast({qsfp2_mac_rx_axis_tlast, qsfp1_mac_rx_axis_tlast}), .s_axis_mac_rx_tuser({qsfp2_mac_rx_axis_tuser, qsfp1_mac_rx_axis_tuser}), + .mac_rx_enable(), .mac_rx_status({qsfp2_mac_rx_status, qsfp1_mac_rx_status}), + .mac_rx_lfc_en(), + .mac_rx_lfc_req({qsfp2_mac_rx_lfc_req, qsfp1_mac_rx_lfc_req}), + .mac_rx_lfc_ack(), + .mac_rx_pfc_en(), + .mac_rx_pfc_req({qsfp2_mac_rx_pfc_req, qsfp1_mac_rx_pfc_req}), + .mac_rx_pfc_ack(), // towards datapath .tx_clk(eth_tx_clk), @@ -523,7 +558,12 @@ mqnic_port_map_mac_axis_inst ( .m_axis_tx_ptp_ts_valid(axis_eth_tx_ptp_ts_valid), .m_axis_tx_ptp_ts_ready(axis_eth_tx_ptp_ts_ready), + .tx_enable(eth_tx_enable), .tx_status(eth_tx_status), + .tx_lfc_en(eth_tx_lfc_en), + .tx_lfc_req(eth_tx_lfc_req), + .tx_pfc_en(eth_tx_pfc_en), + .tx_pfc_req(eth_tx_pfc_req), .rx_clk(eth_rx_clk), .rx_rst(eth_rx_rst), @@ -540,7 +580,14 @@ mqnic_port_map_mac_axis_inst ( .m_axis_rx_tlast(axis_eth_rx_tlast), .m_axis_rx_tuser(axis_eth_rx_tuser), - .rx_status(eth_rx_status) + .rx_enable(eth_rx_enable), + .rx_status(eth_rx_status), + .rx_lfc_en(eth_rx_lfc_en), + .rx_lfc_req(eth_rx_lfc_req), + .rx_lfc_ack(eth_rx_lfc_ack), + .rx_pfc_en(eth_rx_pfc_en), + .rx_pfc_req(eth_rx_pfc_req), + .rx_pfc_ack(eth_rx_pfc_ack) ); mqnic_core_pcie_ptile #( @@ -610,6 +657,9 @@ mqnic_core_pcie_ptile #( .TX_CHECKSUM_ENABLE(TX_CHECKSUM_ENABLE), .RX_HASH_ENABLE(RX_HASH_ENABLE), .RX_CHECKSUM_ENABLE(RX_CHECKSUM_ENABLE), + .PFC_ENABLE(PFC_ENABLE), + .LFC_ENABLE(LFC_ENABLE), + .MAC_CTRL_ENABLE(0), .TX_FIFO_DEPTH(TX_FIFO_DEPTH), .RX_FIFO_DEPTH(RX_FIFO_DEPTH), .MAX_TX_SIZE(MAX_TX_SIZE), @@ -813,7 +863,13 @@ core_inst ( .s_axis_eth_tx_cpl_valid(axis_eth_tx_ptp_ts_valid), .s_axis_eth_tx_cpl_ready(axis_eth_tx_ptp_ts_ready), + .eth_tx_enable(eth_tx_enable), .eth_tx_status(eth_tx_status), + .eth_tx_lfc_en(eth_tx_lfc_en), + .eth_tx_lfc_req(eth_tx_lfc_req), + .eth_tx_pfc_en(eth_tx_pfc_en), + .eth_tx_pfc_req(eth_tx_pfc_req), + .eth_tx_fc_quanta_clk_en(0), .eth_rx_clk(eth_rx_clk), .eth_rx_rst(eth_rx_rst), @@ -830,7 +886,15 @@ core_inst ( .s_axis_eth_rx_tlast(axis_eth_rx_tlast), .s_axis_eth_rx_tuser(axis_eth_rx_tuser), + .eth_rx_enable(eth_rx_enable), .eth_rx_status(eth_rx_status), + .eth_rx_lfc_en(eth_rx_lfc_en), + .eth_rx_lfc_req(eth_rx_lfc_req), + .eth_rx_lfc_ack(eth_rx_lfc_ack), + .eth_rx_pfc_en(eth_rx_pfc_en), + .eth_rx_pfc_req(eth_rx_pfc_req), + .eth_rx_pfc_ack(eth_rx_pfc_ack), + .eth_rx_fc_quanta_clk_en(0), /* * Statistics input diff --git a/fpga/mqnic/DK_DEV_1SDX_P_A/fpga_100g/tb/fpga_core/Makefile b/fpga/mqnic/DK_DEV_1SDX_P_A/fpga_100g/tb/fpga_core/Makefile index d4e1c655e..0514e94eb 100644 --- a/fpga/mqnic/DK_DEV_1SDX_P_A/fpga_100g/tb/fpga_core/Makefile +++ b/fpga/mqnic/DK_DEV_1SDX_P_A/fpga_100g/tb/fpga_core/Makefile @@ -163,6 +163,8 @@ export PARAM_TX_CPL_FIFO_DEPTH := 32 export PARAM_TX_CHECKSUM_ENABLE := 1 export PARAM_RX_HASH_ENABLE := 1 export PARAM_RX_CHECKSUM_ENABLE := 1 +export PARAM_LFC_ENABLE := 1 +export PARAM_PFC_ENABLE := $(PARAM_LFC_ENABLE) export PARAM_TX_FIFO_DEPTH := 32768 export PARAM_RX_FIFO_DEPTH := 131072 export PARAM_MAX_TX_SIZE := 9214 diff --git a/fpga/mqnic/DK_DEV_1SDX_P_A/fpga_100g/tb/fpga_core/test_fpga_core.py b/fpga/mqnic/DK_DEV_1SDX_P_A/fpga_100g/tb/fpga_core/test_fpga_core.py index 3c19700f8..229b2d1ab 100644 --- a/fpga/mqnic/DK_DEV_1SDX_P_A/fpga_100g/tb/fpga_core/test_fpga_core.py +++ b/fpga/mqnic/DK_DEV_1SDX_P_A/fpga_100g/tb/fpga_core/test_fpga_core.py @@ -277,6 +277,8 @@ class TB(object): self.qsfp_mac.append(mac) getattr(dut, f"qsfp{k}_mac_rx_status").setimmediatevalue(1) + getattr(dut, f"qsfp{k}_mac_rx_lfc_req").setimmediatevalue(0) + getattr(dut, f"qsfp{k}_mac_rx_pfc_req").setimmediatevalue(0) dut.user_pb.setimmediatevalue(0) @@ -687,6 +689,8 @@ def test_fpga_core(request): parameters['TX_CHECKSUM_ENABLE'] = 1 parameters['RX_HASH_ENABLE'] = 1 parameters['RX_CHECKSUM_ENABLE'] = 1 + parameters['LFC_ENABLE'] = 1 + parameters['PFC_ENABLE'] = parameters['LFC_ENABLE'] parameters['TX_FIFO_DEPTH'] = 32768 parameters['RX_FIFO_DEPTH'] = 131072 parameters['MAX_TX_SIZE'] = 9214 diff --git a/fpga/mqnic/DK_DEV_1SDX_P_A/fpga_25g/fpga/config.tcl b/fpga/mqnic/DK_DEV_1SDX_P_A/fpga_25g/fpga/config.tcl index b55e710ac..4592d2b27 100644 --- a/fpga/mqnic/DK_DEV_1SDX_P_A/fpga_25g/fpga/config.tcl +++ b/fpga/mqnic/DK_DEV_1SDX_P_A/fpga_25g/fpga/config.tcl @@ -100,6 +100,8 @@ dict set params TX_CPL_FIFO_DEPTH "32" dict set params TX_CHECKSUM_ENABLE "1" dict set params RX_HASH_ENABLE "1" dict set params RX_CHECKSUM_ENABLE "1" +dict set params PFC_ENABLE "1" +dict set params LFC_ENABLE [dict get $params PFC_ENABLE] dict set params TX_FIFO_DEPTH "32768" dict set params RX_FIFO_DEPTH "32768" dict set params MAX_TX_SIZE "9214" diff --git a/fpga/mqnic/DK_DEV_1SDX_P_A/fpga_25g/fpga_10g/config.tcl b/fpga/mqnic/DK_DEV_1SDX_P_A/fpga_25g/fpga_10g/config.tcl index aeaa8041b..1f95358c4 100644 --- a/fpga/mqnic/DK_DEV_1SDX_P_A/fpga_25g/fpga_10g/config.tcl +++ b/fpga/mqnic/DK_DEV_1SDX_P_A/fpga_25g/fpga_10g/config.tcl @@ -100,6 +100,8 @@ dict set params TX_CPL_FIFO_DEPTH "32" dict set params TX_CHECKSUM_ENABLE "1" dict set params RX_HASH_ENABLE "1" dict set params RX_CHECKSUM_ENABLE "1" +dict set params PFC_ENABLE "1" +dict set params LFC_ENABLE [dict get $params PFC_ENABLE] dict set params TX_FIFO_DEPTH "32768" dict set params RX_FIFO_DEPTH "32768" dict set params MAX_TX_SIZE "9214" diff --git a/fpga/mqnic/DK_DEV_1SDX_P_A/fpga_25g/rtl/eth_mac_quad_wrapper.v b/fpga/mqnic/DK_DEV_1SDX_P_A/fpga_25g/rtl/eth_mac_quad_wrapper.v index e9bdbdd8d..bde677cb8 100644 --- a/fpga/mqnic/DK_DEV_1SDX_P_A/fpga_25g/rtl/eth_mac_quad_wrapper.v +++ b/fpga/mqnic/DK_DEV_1SDX_P_A/fpga_25g/rtl/eth_mac_quad_wrapper.v @@ -70,6 +70,10 @@ module eth_mac_quad_wrapper # input wire mac_1_tx_axis_tlast, input wire [TX_USER_WIDTH-1:0] mac_1_tx_axis_tuser, + output wire mac_1_tx_status, + input wire mac_1_tx_lfc_req, + input wire [7:0] mac_1_tx_pfc_req, + output wire mac_1_rx_clk, output wire mac_1_rx_rst, @@ -84,6 +88,8 @@ module eth_mac_quad_wrapper # output wire [RX_USER_WIDTH-1:0] mac_1_rx_axis_tuser, output wire mac_1_rx_status, + output wire mac_1_rx_lfc_req, + output wire [7:0] mac_1_rx_pfc_req, output wire mac_2_tx_clk, output wire mac_2_tx_rst, @@ -103,6 +109,10 @@ module eth_mac_quad_wrapper # input wire mac_2_tx_axis_tlast, input wire [TX_USER_WIDTH-1:0] mac_2_tx_axis_tuser, + output wire mac_2_tx_status, + input wire mac_2_tx_lfc_req, + input wire [7:0] mac_2_tx_pfc_req, + output wire mac_2_rx_clk, output wire mac_2_rx_rst, @@ -117,6 +127,8 @@ module eth_mac_quad_wrapper # output wire [RX_USER_WIDTH-1:0] mac_2_rx_axis_tuser, output wire mac_2_rx_status, + output wire mac_2_rx_lfc_req, + output wire [7:0] mac_2_rx_pfc_req, output wire mac_3_tx_clk, output wire mac_3_tx_rst, @@ -136,6 +148,10 @@ module eth_mac_quad_wrapper # input wire mac_3_tx_axis_tlast, input wire [TX_USER_WIDTH-1:0] mac_3_tx_axis_tuser, + output wire mac_3_tx_status, + input wire mac_3_tx_lfc_req, + input wire [7:0] mac_3_tx_pfc_req, + output wire mac_3_rx_clk, output wire mac_3_rx_rst, @@ -150,6 +166,8 @@ module eth_mac_quad_wrapper # output wire [RX_USER_WIDTH-1:0] mac_3_rx_axis_tuser, output wire mac_3_rx_status, + output wire mac_3_rx_lfc_req, + output wire [7:0] mac_3_rx_pfc_req, output wire mac_4_tx_clk, output wire mac_4_tx_rst, @@ -169,6 +187,10 @@ module eth_mac_quad_wrapper # input wire mac_4_tx_axis_tlast, input wire [TX_USER_WIDTH-1:0] mac_4_tx_axis_tuser, + output wire mac_4_tx_status, + input wire mac_4_tx_lfc_req, + input wire [7:0] mac_4_tx_pfc_req, + output wire mac_4_rx_clk, output wire mac_4_rx_rst, @@ -182,7 +204,9 @@ module eth_mac_quad_wrapper # output wire mac_4_rx_axis_tlast, output wire [RX_USER_WIDTH-1:0] mac_4_rx_axis_tuser, - output wire mac_4_rx_status + output wire mac_4_rx_status, + output wire mac_4_rx_lfc_req, + output wire [7:0] mac_4_rx_pfc_req ); parameter N_CH = 4; @@ -238,6 +262,11 @@ wire [N_CH-1:0] mac_rx_endofpacket; wire [N_CH*3-1:0] mac_rx_empty; wire [N_CH*6-1:0] mac_rx_error; +wire [N_CH*8-1:0] mac_tx_pfc; +wire [N_CH*8-1:0] mac_rx_pfc; +wire [N_CH-1:0] mac_tx_pause; +wire [N_CH-1:0] mac_rx_pause; + generate if (MAC_RSFEC) begin @@ -324,10 +353,10 @@ if (MAC_RSFEC) begin .o_sl_rx_error (mac_rx_error), .o_sl_rxstatus_data (), .o_sl_rxstatus_valid (), - .i_sl_tx_pfc ({4{8'd0}}), - .o_sl_rx_pfc (), - .i_sl_tx_pause ({4{1'b0}}), - .o_sl_rx_pause (), + .i_sl_tx_pfc (mac_tx_pfc), + .o_sl_rx_pfc (mac_rx_pfc), + .i_sl_tx_pause (mac_tx_pause), + .o_sl_rx_pause (mac_rx_pause), .i_sl_ptp_tx_tod (mac_ptp_tx_tod), .i_sl_ptp_rx_tod (mac_ptp_rx_tod), .i_sl_ptp_ts_req ({4{1'b1}}), @@ -429,10 +458,10 @@ end else begin .o_sl_rx_error (mac_rx_error), .o_sl_rxstatus_data (), .o_sl_rxstatus_valid (), - .i_sl_tx_pfc ({4{8'd0}}), - .o_sl_rx_pfc (), - .i_sl_tx_pause ({4{1'b0}}), - .o_sl_rx_pause (), + .i_sl_tx_pfc (mac_tx_pfc), + .o_sl_rx_pfc (mac_rx_pfc), + .i_sl_tx_pause (mac_tx_pause), + .o_sl_rx_pause (mac_rx_pause), .i_sl_ptp_tx_tod (mac_ptp_tx_tod), .i_sl_ptp_rx_tod (mac_ptp_rx_tod), .i_sl_ptp_ts_req ({4{1'b1}}), @@ -497,6 +526,10 @@ assign mac_1_tx_axis_tready = mac_tx_axis_tready[0]; assign mac_tx_axis_tlast[0] = mac_1_tx_axis_tlast; assign mac_tx_axis_tuser[0*TX_USER_WIDTH +: TX_USER_WIDTH] = mac_1_tx_axis_tuser; +assign mac_1_tx_status = mac_tx_lanes_stable[0*1 +: 1]; +assign mac_tx_pause[0*1 +: 1] = mac_1_tx_lfc_req; +assign mac_tx_pfc[0*8 +: 8] = mac_1_tx_pfc_req; + assign mac_1_rx_clk = mac_rx_clk[0]; assign mac_1_rx_rst = mac_rx_rst[0]; @@ -510,7 +543,9 @@ assign mac_1_rx_axis_tvalid = mac_rx_axis_tvalid[0]; assign mac_1_rx_axis_tlast = mac_rx_axis_tlast[0]; assign mac_1_rx_axis_tuser = mac_rx_axis_tuser[0*RX_USER_WIDTH +: RX_USER_WIDTH]; -assign mac_1_rx_status = mac_rx_pcs_ready[0]; +assign mac_1_rx_status = mac_rx_pcs_ready[0*1 +: 1]; +assign mac_1_rx_lfc_req = mac_rx_pause[0*1 +: 1]; +assign mac_1_rx_pfc_req = mac_rx_pfc[0*8 +: 8]; assign mac_2_tx_clk = mac_tx_clk[1]; assign mac_2_tx_rst = mac_tx_rst[1]; @@ -530,6 +565,10 @@ assign mac_2_tx_axis_tready = mac_tx_axis_tready[1]; assign mac_tx_axis_tlast[1] = mac_2_tx_axis_tlast; assign mac_tx_axis_tuser[1*TX_USER_WIDTH +: TX_USER_WIDTH] = mac_2_tx_axis_tuser; +assign mac_2_tx_status = mac_tx_lanes_stable[1*1 +: 1]; +assign mac_tx_pause[1*1 +: 1] = mac_2_tx_lfc_req; +assign mac_tx_pfc[1*8 +: 8] = mac_2_tx_pfc_req; + assign mac_2_rx_clk = mac_rx_clk[1]; assign mac_2_rx_rst = mac_rx_rst[1]; @@ -543,7 +582,9 @@ assign mac_2_rx_axis_tvalid = mac_rx_axis_tvalid[1]; assign mac_2_rx_axis_tlast = mac_rx_axis_tlast[1]; assign mac_2_rx_axis_tuser = mac_rx_axis_tuser[1*RX_USER_WIDTH +: RX_USER_WIDTH]; -assign mac_2_rx_status = mac_rx_pcs_ready[1]; +assign mac_2_rx_status = mac_rx_pcs_ready[1*1 +: 1]; +assign mac_2_rx_lfc_req = mac_rx_pause[1*1 +: 1]; +assign mac_2_rx_pfc_req = mac_rx_pfc[1*8 +: 8]; assign mac_3_tx_clk = mac_tx_clk[2]; assign mac_3_tx_rst = mac_tx_rst[2]; @@ -563,6 +604,10 @@ assign mac_3_tx_axis_tready = mac_tx_axis_tready[2]; assign mac_tx_axis_tlast[2] = mac_3_tx_axis_tlast; assign mac_tx_axis_tuser[2*TX_USER_WIDTH +: TX_USER_WIDTH] = mac_3_tx_axis_tuser; +assign mac_3_tx_status = mac_tx_lanes_stable[2*1 +: 1]; +assign mac_tx_pause[2*1 +: 1] = mac_3_tx_lfc_req; +assign mac_tx_pfc[2*8 +: 8] = mac_3_tx_pfc_req; + assign mac_3_rx_clk = mac_rx_clk[2]; assign mac_3_rx_rst = mac_rx_rst[2]; @@ -576,7 +621,9 @@ assign mac_3_rx_axis_tvalid = mac_rx_axis_tvalid[2]; assign mac_3_rx_axis_tlast = mac_rx_axis_tlast[2]; assign mac_3_rx_axis_tuser = mac_rx_axis_tuser[2*RX_USER_WIDTH +: RX_USER_WIDTH]; -assign mac_3_rx_status = mac_rx_pcs_ready[2]; +assign mac_3_rx_status = mac_rx_pcs_ready[2*1 +: 1]; +assign mac_3_rx_lfc_req = mac_rx_pause[2*1 +: 1]; +assign mac_3_rx_pfc_req = mac_rx_pfc[2*8 +: 8]; assign mac_4_tx_clk = mac_tx_clk[3]; assign mac_4_tx_rst = mac_tx_rst[3]; @@ -596,6 +643,10 @@ assign mac_4_tx_axis_tready = mac_tx_axis_tready[3]; assign mac_tx_axis_tlast[3] = mac_4_tx_axis_tlast; assign mac_tx_axis_tuser[3*TX_USER_WIDTH +: TX_USER_WIDTH] = mac_4_tx_axis_tuser; +assign mac_4_tx_status = mac_tx_lanes_stable[3*1 +: 1]; +assign mac_tx_pause[3*1 +: 1] = mac_4_tx_lfc_req; +assign mac_tx_pfc[3*8 +: 8] = mac_4_tx_pfc_req; + assign mac_4_rx_clk = mac_rx_clk[3]; assign mac_4_rx_rst = mac_rx_rst[3]; @@ -609,7 +660,9 @@ assign mac_4_rx_axis_tvalid = mac_rx_axis_tvalid[3]; assign mac_4_rx_axis_tlast = mac_rx_axis_tlast[3]; assign mac_4_rx_axis_tuser = mac_rx_axis_tuser[3*RX_USER_WIDTH +: RX_USER_WIDTH]; -assign mac_4_rx_status = mac_rx_pcs_ready[3]; +assign mac_4_rx_status = mac_rx_pcs_ready[3*1 +: 1]; +assign mac_4_rx_lfc_req = mac_rx_pause[3*1 +: 1]; +assign mac_4_rx_pfc_req = mac_rx_pfc[3*8 +: 8]; generate diff --git a/fpga/mqnic/DK_DEV_1SDX_P_A/fpga_25g/rtl/fpga.v b/fpga/mqnic/DK_DEV_1SDX_P_A/fpga_25g/rtl/fpga.v index 57d742bf4..062fa3fbf 100644 --- a/fpga/mqnic/DK_DEV_1SDX_P_A/fpga_25g/rtl/fpga.v +++ b/fpga/mqnic/DK_DEV_1SDX_P_A/fpga_25g/rtl/fpga.v @@ -71,6 +71,8 @@ module fpga # parameter TX_CHECKSUM_ENABLE = 1, parameter RX_HASH_ENABLE = 1, parameter RX_CHECKSUM_ENABLE = 1, + parameter PFC_ENABLE = 1, + parameter LFC_ENABLE = PFC_ENABLE, parameter TX_FIFO_DEPTH = 32768, parameter RX_FIFO_DEPTH = 32768, parameter MAX_TX_SIZE = 9214, @@ -434,6 +436,10 @@ wire qsfp1_mac_1_tx_axis_tready_int; wire qsfp1_mac_1_tx_axis_tlast_int; wire [AXIS_ETH_TX_USER_WIDTH-1:0] qsfp1_mac_1_tx_axis_tuser_int; +wire qsfp1_mac_1_tx_status_int; +wire qsfp1_mac_1_tx_lfc_req_int; +wire [7:0] qsfp1_mac_1_tx_pfc_req_int; + wire qsfp1_mac_1_rx_clk_int; wire qsfp1_mac_1_rx_rst_int; @@ -448,6 +454,8 @@ wire qsfp1_mac_1_rx_axis_tlast_int; wire [AXIS_ETH_RX_USER_WIDTH-1:0] qsfp1_mac_1_rx_axis_tuser_int; wire qsfp1_mac_1_rx_status_int; +wire qsfp1_mac_1_rx_lfc_req_int; +wire [7:0] qsfp1_mac_1_rx_pfc_req_int; wire qsfp1_mac_2_tx_clk_int; wire qsfp1_mac_2_tx_rst_int; @@ -467,6 +475,10 @@ wire qsfp1_mac_2_tx_axis_tready_int; wire qsfp1_mac_2_tx_axis_tlast_int; wire [AXIS_ETH_TX_USER_WIDTH-1:0] qsfp1_mac_2_tx_axis_tuser_int; +wire qsfp1_mac_2_tx_status_int; +wire qsfp1_mac_2_tx_lfc_req_int; +wire [7:0] qsfp1_mac_2_tx_pfc_req_int; + wire qsfp1_mac_2_rx_clk_int; wire qsfp1_mac_2_rx_rst_int; @@ -481,6 +493,8 @@ wire qsfp1_mac_2_rx_axis_tlast_int; wire [AXIS_ETH_RX_USER_WIDTH-1:0] qsfp1_mac_2_rx_axis_tuser_int; wire qsfp1_mac_2_rx_status_int; +wire qsfp1_mac_2_rx_lfc_req_int; +wire [7:0] qsfp1_mac_2_rx_pfc_req_int; wire qsfp1_mac_3_tx_clk_int; wire qsfp1_mac_3_tx_rst_int; @@ -500,6 +514,10 @@ wire qsfp1_mac_3_tx_axis_tready_int; wire qsfp1_mac_3_tx_axis_tlast_int; wire [AXIS_ETH_TX_USER_WIDTH-1:0] qsfp1_mac_3_tx_axis_tuser_int; +wire qsfp1_mac_3_tx_status_int; +wire qsfp1_mac_3_tx_lfc_req_int; +wire [7:0] qsfp1_mac_3_tx_pfc_req_int; + wire qsfp1_mac_3_rx_clk_int; wire qsfp1_mac_3_rx_rst_int; @@ -514,6 +532,8 @@ wire qsfp1_mac_3_rx_axis_tlast_int; wire [AXIS_ETH_RX_USER_WIDTH-1:0] qsfp1_mac_3_rx_axis_tuser_int; wire qsfp1_mac_3_rx_status_int; +wire qsfp1_mac_3_rx_lfc_req_int; +wire [7:0] qsfp1_mac_3_rx_pfc_req_int; wire qsfp1_mac_4_tx_clk_int; wire qsfp1_mac_4_tx_rst_int; @@ -533,6 +553,10 @@ wire qsfp1_mac_4_tx_axis_tready_int; wire qsfp1_mac_4_tx_axis_tlast_int; wire [AXIS_ETH_TX_USER_WIDTH-1:0] qsfp1_mac_4_tx_axis_tuser_int; +wire qsfp1_mac_4_tx_status_int; +wire qsfp1_mac_4_tx_lfc_req_int; +wire [7:0] qsfp1_mac_4_tx_pfc_req_int; + wire qsfp1_mac_4_rx_clk_int; wire qsfp1_mac_4_rx_rst_int; @@ -547,6 +571,8 @@ wire qsfp1_mac_4_rx_axis_tlast_int; wire [AXIS_ETH_RX_USER_WIDTH-1:0] qsfp1_mac_4_rx_axis_tuser_int; wire qsfp1_mac_4_rx_status_int; +wire qsfp1_mac_4_rx_lfc_req_int; +wire [7:0] qsfp1_mac_4_rx_pfc_req_int; eth_mac_quad_wrapper #( .PTP_TS_WIDTH(PTP_TS_WIDTH), @@ -586,6 +612,10 @@ qsfp1_mac_inst ( .mac_1_tx_axis_tlast(qsfp1_mac_1_tx_axis_tlast_int), .mac_1_tx_axis_tuser(qsfp1_mac_1_tx_axis_tuser_int), + .mac_1_tx_status(qsfp1_mac_1_tx_status_int), + .mac_1_tx_lfc_req(qsfp1_mac_1_tx_lfc_req_int), + .mac_1_tx_pfc_req(qsfp1_mac_1_tx_pfc_req_int), + .mac_1_rx_clk(qsfp1_mac_1_rx_clk_int), .mac_1_rx_rst(qsfp1_mac_1_rx_rst_int), @@ -600,6 +630,8 @@ qsfp1_mac_inst ( .mac_1_rx_axis_tuser(qsfp1_mac_1_rx_axis_tuser_int), .mac_1_rx_status(qsfp1_mac_1_rx_status_int), + .mac_1_rx_lfc_req(qsfp1_mac_1_rx_lfc_req_int), + .mac_1_rx_pfc_req(qsfp1_mac_1_rx_pfc_req_int), .mac_2_tx_clk(qsfp1_mac_3_tx_clk_int), .mac_2_tx_rst(qsfp1_mac_3_tx_rst_int), @@ -619,6 +651,10 @@ qsfp1_mac_inst ( .mac_2_tx_axis_tlast(qsfp1_mac_3_tx_axis_tlast_int), .mac_2_tx_axis_tuser(qsfp1_mac_3_tx_axis_tuser_int), + .mac_2_tx_status(qsfp1_mac_3_tx_status_int), + .mac_2_tx_lfc_req(qsfp1_mac_3_tx_lfc_req_int), + .mac_2_tx_pfc_req(qsfp1_mac_3_tx_pfc_req_int), + .mac_2_rx_clk(qsfp1_mac_3_rx_clk_int), .mac_2_rx_rst(qsfp1_mac_3_rx_rst_int), @@ -633,6 +669,8 @@ qsfp1_mac_inst ( .mac_2_rx_axis_tuser(qsfp1_mac_3_rx_axis_tuser_int), .mac_2_rx_status(qsfp1_mac_3_rx_status_int), + .mac_2_rx_lfc_req(qsfp1_mac_3_rx_lfc_req_int), + .mac_2_rx_pfc_req(qsfp1_mac_3_rx_pfc_req_int), .mac_3_tx_clk(qsfp1_mac_2_tx_clk_int), .mac_3_tx_rst(qsfp1_mac_2_tx_rst_int), @@ -652,6 +690,10 @@ qsfp1_mac_inst ( .mac_3_tx_axis_tlast(qsfp1_mac_2_tx_axis_tlast_int), .mac_3_tx_axis_tuser(qsfp1_mac_2_tx_axis_tuser_int), + .mac_3_tx_status(qsfp1_mac_2_tx_status_int), + .mac_3_tx_lfc_req(qsfp1_mac_2_tx_lfc_req_int), + .mac_3_tx_pfc_req(qsfp1_mac_2_tx_pfc_req_int), + .mac_3_rx_clk(qsfp1_mac_2_rx_clk_int), .mac_3_rx_rst(qsfp1_mac_2_rx_rst_int), @@ -666,6 +708,8 @@ qsfp1_mac_inst ( .mac_3_rx_axis_tuser(qsfp1_mac_2_rx_axis_tuser_int), .mac_3_rx_status(qsfp1_mac_2_rx_status_int), + .mac_3_rx_lfc_req(qsfp1_mac_2_rx_lfc_req_int), + .mac_3_rx_pfc_req(qsfp1_mac_2_rx_pfc_req_int), .mac_4_tx_clk(qsfp1_mac_4_tx_clk_int), .mac_4_tx_rst(qsfp1_mac_4_tx_rst_int), @@ -685,6 +729,10 @@ qsfp1_mac_inst ( .mac_4_tx_axis_tlast(qsfp1_mac_4_tx_axis_tlast_int), .mac_4_tx_axis_tuser(qsfp1_mac_4_tx_axis_tuser_int), + .mac_4_tx_status(qsfp1_mac_4_tx_status_int), + .mac_4_tx_lfc_req(qsfp1_mac_4_tx_lfc_req_int), + .mac_4_tx_pfc_req(qsfp1_mac_4_tx_pfc_req_int), + .mac_4_rx_clk(qsfp1_mac_4_rx_clk_int), .mac_4_rx_rst(qsfp1_mac_4_rx_rst_int), @@ -698,7 +746,9 @@ qsfp1_mac_inst ( .mac_4_rx_axis_tlast(qsfp1_mac_4_rx_axis_tlast_int), .mac_4_rx_axis_tuser(qsfp1_mac_4_rx_axis_tuser_int), - .mac_4_rx_status(qsfp1_mac_4_rx_status_int) + .mac_4_rx_status(qsfp1_mac_4_rx_status_int), + .mac_4_rx_lfc_req(qsfp1_mac_4_rx_lfc_req_int), + .mac_4_rx_pfc_req(qsfp1_mac_4_rx_pfc_req_int) ); // QSFP2 @@ -720,6 +770,10 @@ wire qsfp2_mac_1_tx_axis_tready_int; wire qsfp2_mac_1_tx_axis_tlast_int; wire [AXIS_ETH_TX_USER_WIDTH-1:0] qsfp2_mac_1_tx_axis_tuser_int; +wire qsfp2_mac_1_tx_status_int; +wire qsfp2_mac_1_tx_lfc_req_int; +wire [7:0] qsfp2_mac_1_tx_pfc_req_int; + wire qsfp2_mac_1_rx_clk_int; wire qsfp2_mac_1_rx_rst_int; @@ -734,6 +788,8 @@ wire qsfp2_mac_1_rx_axis_tlast_int; wire [AXIS_ETH_RX_USER_WIDTH-1:0] qsfp2_mac_1_rx_axis_tuser_int; wire qsfp2_mac_1_rx_status_int; +wire qsfp2_mac_1_rx_lfc_req_int; +wire [7:0] qsfp2_mac_1_rx_pfc_req_int; wire qsfp2_mac_2_tx_clk_int; wire qsfp2_mac_2_tx_rst_int; @@ -753,6 +809,10 @@ wire qsfp2_mac_2_tx_axis_tready_int; wire qsfp2_mac_2_tx_axis_tlast_int; wire [AXIS_ETH_TX_USER_WIDTH-1:0] qsfp2_mac_2_tx_axis_tuser_int; +wire qsfp2_mac_2_tx_status_int; +wire qsfp2_mac_2_tx_lfc_req_int; +wire [7:0] qsfp2_mac_2_tx_pfc_req_int; + wire qsfp2_mac_2_rx_clk_int; wire qsfp2_mac_2_rx_rst_int; @@ -767,6 +827,8 @@ wire qsfp2_mac_2_rx_axis_tlast_int; wire [AXIS_ETH_RX_USER_WIDTH-1:0] qsfp2_mac_2_rx_axis_tuser_int; wire qsfp2_mac_2_rx_status_int; +wire qsfp2_mac_2_rx_lfc_req_int; +wire [7:0] qsfp2_mac_2_rx_pfc_req_int; wire qsfp2_mac_3_tx_clk_int; wire qsfp2_mac_3_tx_rst_int; @@ -786,6 +848,10 @@ wire qsfp2_mac_3_tx_axis_tready_int; wire qsfp2_mac_3_tx_axis_tlast_int; wire [AXIS_ETH_TX_USER_WIDTH-1:0] qsfp2_mac_3_tx_axis_tuser_int; +wire qsfp2_mac_3_tx_status_int; +wire qsfp2_mac_3_tx_lfc_req_int; +wire [7:0] qsfp2_mac_3_tx_pfc_req_int; + wire qsfp2_mac_3_rx_clk_int; wire qsfp2_mac_3_rx_rst_int; @@ -800,6 +866,8 @@ wire qsfp2_mac_3_rx_axis_tlast_int; wire [AXIS_ETH_RX_USER_WIDTH-1:0] qsfp2_mac_3_rx_axis_tuser_int; wire qsfp2_mac_3_rx_status_int; +wire qsfp2_mac_3_rx_lfc_req_int; +wire [7:0] qsfp2_mac_3_rx_pfc_req_int; wire qsfp2_mac_4_tx_clk_int; wire qsfp2_mac_4_tx_rst_int; @@ -819,6 +887,10 @@ wire qsfp2_mac_4_tx_axis_tready_int; wire qsfp2_mac_4_tx_axis_tlast_int; wire [AXIS_ETH_TX_USER_WIDTH-1:0] qsfp2_mac_4_tx_axis_tuser_int; +wire qsfp2_mac_4_tx_status_int; +wire qsfp2_mac_4_tx_lfc_req_int; +wire [7:0] qsfp2_mac_4_tx_pfc_req_int; + wire qsfp2_mac_4_rx_clk_int; wire qsfp2_mac_4_rx_rst_int; @@ -833,6 +905,8 @@ wire qsfp2_mac_4_rx_axis_tlast_int; wire [AXIS_ETH_RX_USER_WIDTH-1:0] qsfp2_mac_4_rx_axis_tuser_int; wire qsfp2_mac_4_rx_status_int; +wire qsfp2_mac_4_rx_lfc_req_int; +wire [7:0] qsfp2_mac_4_rx_pfc_req_int; eth_mac_quad_wrapper #( .PTP_TS_WIDTH(PTP_TS_WIDTH), @@ -872,6 +946,10 @@ qsfp2_mac_inst ( .mac_1_tx_axis_tlast(qsfp2_mac_1_tx_axis_tlast_int), .mac_1_tx_axis_tuser(qsfp2_mac_1_tx_axis_tuser_int), + .mac_1_tx_status(qsfp2_mac_1_tx_status_int), + .mac_1_tx_lfc_req(qsfp2_mac_1_tx_lfc_req_int), + .mac_1_tx_pfc_req(qsfp2_mac_1_tx_pfc_req_int), + .mac_1_rx_clk(qsfp2_mac_1_rx_clk_int), .mac_1_rx_rst(qsfp2_mac_1_rx_rst_int), @@ -886,6 +964,8 @@ qsfp2_mac_inst ( .mac_1_rx_axis_tuser(qsfp2_mac_1_rx_axis_tuser_int), .mac_1_rx_status(qsfp2_mac_1_rx_status_int), + .mac_1_rx_lfc_req(qsfp2_mac_1_rx_lfc_req_int), + .mac_1_rx_pfc_req(qsfp2_mac_1_rx_pfc_req_int), .mac_2_tx_clk(qsfp2_mac_3_tx_clk_int), .mac_2_tx_rst(qsfp2_mac_3_tx_rst_int), @@ -905,6 +985,10 @@ qsfp2_mac_inst ( .mac_2_tx_axis_tlast(qsfp2_mac_3_tx_axis_tlast_int), .mac_2_tx_axis_tuser(qsfp2_mac_3_tx_axis_tuser_int), + .mac_2_tx_status(qsfp2_mac_3_tx_status_int), + .mac_2_tx_lfc_req(qsfp2_mac_3_tx_lfc_req_int), + .mac_2_tx_pfc_req(qsfp2_mac_3_tx_pfc_req_int), + .mac_2_rx_clk(qsfp2_mac_3_rx_clk_int), .mac_2_rx_rst(qsfp2_mac_3_rx_rst_int), @@ -919,6 +1003,8 @@ qsfp2_mac_inst ( .mac_2_rx_axis_tuser(qsfp2_mac_3_rx_axis_tuser_int), .mac_2_rx_status(qsfp2_mac_3_rx_status_int), + .mac_2_rx_lfc_req(qsfp2_mac_3_rx_lfc_req_int), + .mac_2_rx_pfc_req(qsfp2_mac_3_rx_pfc_req_int), .mac_3_tx_clk(qsfp2_mac_2_tx_clk_int), .mac_3_tx_rst(qsfp2_mac_2_tx_rst_int), @@ -938,6 +1024,10 @@ qsfp2_mac_inst ( .mac_3_tx_axis_tlast(qsfp2_mac_2_tx_axis_tlast_int), .mac_3_tx_axis_tuser(qsfp2_mac_2_tx_axis_tuser_int), + .mac_3_tx_status(qsfp2_mac_2_tx_status_int), + .mac_3_tx_lfc_req(qsfp2_mac_2_tx_lfc_req_int), + .mac_3_tx_pfc_req(qsfp2_mac_2_tx_pfc_req_int), + .mac_3_rx_clk(qsfp2_mac_2_rx_clk_int), .mac_3_rx_rst(qsfp2_mac_2_rx_rst_int), @@ -952,6 +1042,8 @@ qsfp2_mac_inst ( .mac_3_rx_axis_tuser(qsfp2_mac_2_rx_axis_tuser_int), .mac_3_rx_status(qsfp2_mac_2_rx_status_int), + .mac_3_rx_lfc_req(qsfp2_mac_2_rx_lfc_req_int), + .mac_3_rx_pfc_req(qsfp2_mac_2_rx_pfc_req_int), .mac_4_tx_clk(qsfp2_mac_4_tx_clk_int), .mac_4_tx_rst(qsfp2_mac_4_tx_rst_int), @@ -971,6 +1063,10 @@ qsfp2_mac_inst ( .mac_4_tx_axis_tlast(qsfp2_mac_4_tx_axis_tlast_int), .mac_4_tx_axis_tuser(qsfp2_mac_4_tx_axis_tuser_int), + .mac_4_tx_status(qsfp2_mac_4_tx_status_int), + .mac_4_tx_lfc_req(qsfp2_mac_4_tx_lfc_req_int), + .mac_4_tx_pfc_req(qsfp2_mac_4_tx_pfc_req_int), + .mac_4_rx_clk(qsfp2_mac_4_rx_clk_int), .mac_4_rx_rst(qsfp2_mac_4_rx_rst_int), @@ -984,7 +1080,9 @@ qsfp2_mac_inst ( .mac_4_rx_axis_tlast(qsfp2_mac_4_rx_axis_tlast_int), .mac_4_rx_axis_tuser(qsfp2_mac_4_rx_axis_tuser_int), - .mac_4_rx_status(qsfp2_mac_4_rx_status_int) + .mac_4_rx_status(qsfp2_mac_4_rx_status_int), + .mac_4_rx_lfc_req(qsfp2_mac_4_rx_lfc_req_int), + .mac_4_rx_pfc_req(qsfp2_mac_4_rx_pfc_req_int) ); wire ptp_clk; @@ -1074,6 +1172,8 @@ fpga_core #( .TX_CHECKSUM_ENABLE(TX_CHECKSUM_ENABLE), .RX_HASH_ENABLE(RX_HASH_ENABLE), .RX_CHECKSUM_ENABLE(RX_CHECKSUM_ENABLE), + .PFC_ENABLE(PFC_ENABLE), + .LFC_ENABLE(LFC_ENABLE), .TX_FIFO_DEPTH(TX_FIFO_DEPTH), .RX_FIFO_DEPTH(RX_FIFO_DEPTH), .MAX_TX_SIZE(MAX_TX_SIZE), @@ -1227,6 +1327,10 @@ core_inst ( .qsfp1_mac_1_tx_axis_tlast(qsfp1_mac_1_tx_axis_tlast_int), .qsfp1_mac_1_tx_axis_tuser(qsfp1_mac_1_tx_axis_tuser_int), + .qsfp1_mac_1_tx_status(qsfp1_mac_1_tx_status_int), + .qsfp1_mac_1_tx_lfc_req(qsfp1_mac_1_tx_lfc_req_int), + .qsfp1_mac_1_tx_pfc_req(qsfp1_mac_1_tx_pfc_req_int), + .qsfp1_mac_1_rx_clk(qsfp1_mac_1_rx_clk_int), .qsfp1_mac_1_rx_rst(qsfp1_mac_1_rx_rst_int), @@ -1241,6 +1345,8 @@ core_inst ( .qsfp1_mac_1_rx_axis_tuser(qsfp1_mac_1_rx_axis_tuser_int), .qsfp1_mac_1_rx_status(qsfp1_mac_1_rx_status_int), + .qsfp1_mac_1_rx_lfc_req(qsfp1_mac_1_rx_lfc_req_int), + .qsfp1_mac_1_rx_pfc_req(qsfp1_mac_1_rx_pfc_req_int), .qsfp1_mac_2_tx_clk(qsfp1_mac_2_tx_clk_int), .qsfp1_mac_2_tx_rst(qsfp1_mac_2_tx_rst_int), @@ -1260,6 +1366,10 @@ core_inst ( .qsfp1_mac_2_tx_axis_tlast(qsfp1_mac_2_tx_axis_tlast_int), .qsfp1_mac_2_tx_axis_tuser(qsfp1_mac_2_tx_axis_tuser_int), + .qsfp1_mac_2_tx_status(qsfp1_mac_2_tx_status_int), + .qsfp1_mac_2_tx_lfc_req(qsfp1_mac_2_tx_lfc_req_int), + .qsfp1_mac_2_tx_pfc_req(qsfp1_mac_2_tx_pfc_req_int), + .qsfp1_mac_2_rx_clk(qsfp1_mac_2_rx_clk_int), .qsfp1_mac_2_rx_rst(qsfp1_mac_2_rx_rst_int), @@ -1274,6 +1384,8 @@ core_inst ( .qsfp1_mac_2_rx_axis_tuser(qsfp1_mac_2_rx_axis_tuser_int), .qsfp1_mac_2_rx_status(qsfp1_mac_2_rx_status_int), + .qsfp1_mac_2_rx_lfc_req(qsfp1_mac_2_rx_lfc_req_int), + .qsfp1_mac_2_rx_pfc_req(qsfp1_mac_2_rx_pfc_req_int), .qsfp1_mac_3_tx_clk(qsfp1_mac_3_tx_clk_int), .qsfp1_mac_3_tx_rst(qsfp1_mac_3_tx_rst_int), @@ -1293,6 +1405,10 @@ core_inst ( .qsfp1_mac_3_tx_axis_tlast(qsfp1_mac_3_tx_axis_tlast_int), .qsfp1_mac_3_tx_axis_tuser(qsfp1_mac_3_tx_axis_tuser_int), + .qsfp1_mac_3_tx_status(qsfp1_mac_3_tx_status_int), + .qsfp1_mac_3_tx_lfc_req(qsfp1_mac_3_tx_lfc_req_int), + .qsfp1_mac_3_tx_pfc_req(qsfp1_mac_3_tx_pfc_req_int), + .qsfp1_mac_3_rx_clk(qsfp1_mac_3_rx_clk_int), .qsfp1_mac_3_rx_rst(qsfp1_mac_3_rx_rst_int), @@ -1307,6 +1423,8 @@ core_inst ( .qsfp1_mac_3_rx_axis_tuser(qsfp1_mac_3_rx_axis_tuser_int), .qsfp1_mac_3_rx_status(qsfp1_mac_3_rx_status_int), + .qsfp1_mac_3_rx_lfc_req(qsfp1_mac_3_rx_lfc_req_int), + .qsfp1_mac_3_rx_pfc_req(qsfp1_mac_3_rx_pfc_req_int), .qsfp1_mac_4_tx_clk(qsfp1_mac_4_tx_clk_int), .qsfp1_mac_4_tx_rst(qsfp1_mac_4_tx_rst_int), @@ -1326,6 +1444,10 @@ core_inst ( .qsfp1_mac_4_tx_axis_tlast(qsfp1_mac_4_tx_axis_tlast_int), .qsfp1_mac_4_tx_axis_tuser(qsfp1_mac_4_tx_axis_tuser_int), + .qsfp1_mac_4_tx_status(qsfp1_mac_4_tx_status_int), + .qsfp1_mac_4_tx_lfc_req(qsfp1_mac_4_tx_lfc_req_int), + .qsfp1_mac_4_tx_pfc_req(qsfp1_mac_4_tx_pfc_req_int), + .qsfp1_mac_4_rx_clk(qsfp1_mac_4_rx_clk_int), .qsfp1_mac_4_rx_rst(qsfp1_mac_4_rx_rst_int), @@ -1340,6 +1462,8 @@ core_inst ( .qsfp1_mac_4_rx_axis_tuser(qsfp1_mac_4_rx_axis_tuser_int), .qsfp1_mac_4_rx_status(qsfp1_mac_4_rx_status_int), + .qsfp1_mac_4_rx_lfc_req(qsfp1_mac_4_rx_lfc_req_int), + .qsfp1_mac_4_rx_pfc_req(qsfp1_mac_4_rx_pfc_req_int), .qsfp2_mac_1_tx_clk(qsfp2_mac_1_tx_clk_int), .qsfp2_mac_1_tx_rst(qsfp2_mac_1_tx_rst_int), @@ -1359,6 +1483,10 @@ core_inst ( .qsfp2_mac_1_tx_axis_tlast(qsfp2_mac_1_tx_axis_tlast_int), .qsfp2_mac_1_tx_axis_tuser(qsfp2_mac_1_tx_axis_tuser_int), + .qsfp2_mac_1_tx_status(qsfp2_mac_1_tx_status_int), + .qsfp2_mac_1_tx_lfc_req(qsfp2_mac_1_tx_lfc_req_int), + .qsfp2_mac_1_tx_pfc_req(qsfp2_mac_1_tx_pfc_req_int), + .qsfp2_mac_1_rx_clk(qsfp2_mac_1_rx_clk_int), .qsfp2_mac_1_rx_rst(qsfp2_mac_1_rx_rst_int), @@ -1373,6 +1501,8 @@ core_inst ( .qsfp2_mac_1_rx_axis_tuser(qsfp2_mac_1_rx_axis_tuser_int), .qsfp2_mac_1_rx_status(qsfp2_mac_1_rx_status_int), + .qsfp2_mac_1_rx_lfc_req(qsfp2_mac_1_rx_lfc_req_int), + .qsfp2_mac_1_rx_pfc_req(qsfp2_mac_1_rx_pfc_req_int), .qsfp2_mac_2_tx_clk(qsfp2_mac_2_tx_clk_int), .qsfp2_mac_2_tx_rst(qsfp2_mac_2_tx_rst_int), @@ -1392,6 +1522,10 @@ core_inst ( .qsfp2_mac_2_tx_axis_tlast(qsfp2_mac_2_tx_axis_tlast_int), .qsfp2_mac_2_tx_axis_tuser(qsfp2_mac_2_tx_axis_tuser_int), + .qsfp2_mac_2_tx_status(qsfp2_mac_2_tx_status_int), + .qsfp2_mac_2_tx_lfc_req(qsfp2_mac_2_tx_lfc_req_int), + .qsfp2_mac_2_tx_pfc_req(qsfp2_mac_2_tx_pfc_req_int), + .qsfp2_mac_2_rx_clk(qsfp2_mac_2_rx_clk_int), .qsfp2_mac_2_rx_rst(qsfp2_mac_2_rx_rst_int), @@ -1406,6 +1540,8 @@ core_inst ( .qsfp2_mac_2_rx_axis_tuser(qsfp2_mac_2_rx_axis_tuser_int), .qsfp2_mac_2_rx_status(qsfp2_mac_2_rx_status_int), + .qsfp2_mac_2_rx_lfc_req(qsfp2_mac_2_rx_lfc_req_int), + .qsfp2_mac_2_rx_pfc_req(qsfp2_mac_2_rx_pfc_req_int), .qsfp2_mac_3_tx_clk(qsfp2_mac_3_tx_clk_int), .qsfp2_mac_3_tx_rst(qsfp2_mac_3_tx_rst_int), @@ -1425,6 +1561,10 @@ core_inst ( .qsfp2_mac_3_tx_axis_tlast(qsfp2_mac_3_tx_axis_tlast_int), .qsfp2_mac_3_tx_axis_tuser(qsfp2_mac_3_tx_axis_tuser_int), + .qsfp2_mac_3_tx_status(qsfp2_mac_3_tx_status_int), + .qsfp2_mac_3_tx_lfc_req(qsfp2_mac_3_tx_lfc_req_int), + .qsfp2_mac_3_tx_pfc_req(qsfp2_mac_3_tx_pfc_req_int), + .qsfp2_mac_3_rx_clk(qsfp2_mac_3_rx_clk_int), .qsfp2_mac_3_rx_rst(qsfp2_mac_3_rx_rst_int), @@ -1439,6 +1579,8 @@ core_inst ( .qsfp2_mac_3_rx_axis_tuser(qsfp2_mac_3_rx_axis_tuser_int), .qsfp2_mac_3_rx_status(qsfp2_mac_3_rx_status_int), + .qsfp2_mac_3_rx_lfc_req(qsfp2_mac_3_rx_lfc_req_int), + .qsfp2_mac_3_rx_pfc_req(qsfp2_mac_3_rx_pfc_req_int), .qsfp2_mac_4_tx_clk(qsfp2_mac_4_tx_clk_int), .qsfp2_mac_4_tx_rst(qsfp2_mac_4_tx_rst_int), @@ -1458,6 +1600,10 @@ core_inst ( .qsfp2_mac_4_tx_axis_tlast(qsfp2_mac_4_tx_axis_tlast_int), .qsfp2_mac_4_tx_axis_tuser(qsfp2_mac_4_tx_axis_tuser_int), + .qsfp2_mac_4_tx_status(qsfp2_mac_4_tx_status_int), + .qsfp2_mac_4_tx_lfc_req(qsfp2_mac_4_tx_lfc_req_int), + .qsfp2_mac_4_tx_pfc_req(qsfp2_mac_4_tx_pfc_req_int), + .qsfp2_mac_4_rx_clk(qsfp2_mac_4_rx_clk_int), .qsfp2_mac_4_rx_rst(qsfp2_mac_4_rx_rst_int), @@ -1469,7 +1615,11 @@ core_inst ( .qsfp2_mac_4_rx_axis_tkeep(qsfp2_mac_4_rx_axis_tkeep_int), .qsfp2_mac_4_rx_axis_tvalid(qsfp2_mac_4_rx_axis_tvalid_int), .qsfp2_mac_4_rx_axis_tlast(qsfp2_mac_4_rx_axis_tlast_int), - .qsfp2_mac_4_rx_axis_tuser(qsfp2_mac_4_rx_axis_tuser_int) + .qsfp2_mac_4_rx_axis_tuser(qsfp2_mac_4_rx_axis_tuser_int), + + .qsfp2_mac_4_rx_status(qsfp2_mac_4_rx_status_int), + .qsfp2_mac_4_rx_lfc_req(qsfp2_mac_4_rx_lfc_req_int), + .qsfp2_mac_4_rx_pfc_req(qsfp2_mac_4_rx_pfc_req_int) ); endmodule diff --git a/fpga/mqnic/DK_DEV_1SDX_P_A/fpga_25g/rtl/fpga_core.v b/fpga/mqnic/DK_DEV_1SDX_P_A/fpga_25g/rtl/fpga_core.v index 638232e0a..5a9136ecc 100644 --- a/fpga/mqnic/DK_DEV_1SDX_P_A/fpga_25g/rtl/fpga_core.v +++ b/fpga/mqnic/DK_DEV_1SDX_P_A/fpga_25g/rtl/fpga_core.v @@ -78,9 +78,8 @@ module fpga_core # parameter TX_CHECKSUM_ENABLE = 1, parameter RX_HASH_ENABLE = 1, parameter RX_CHECKSUM_ENABLE = 1, - parameter ENABLE_PADDING = 1, - parameter ENABLE_DIC = 1, - parameter MIN_FRAME_LENGTH = 64, + parameter PFC_ENABLE = 1, + parameter LFC_ENABLE = PFC_ENABLE, parameter TX_FIFO_DEPTH = 32768, parameter RX_FIFO_DEPTH = 32768, parameter MAX_TX_SIZE = 9214, @@ -236,6 +235,10 @@ module fpga_core # output wire qsfp1_mac_1_tx_axis_tlast, output wire [AXIS_ETH_TX_USER_WIDTH-1:0] qsfp1_mac_1_tx_axis_tuser, + input wire qsfp1_mac_1_tx_status, + output wire qsfp1_mac_1_tx_lfc_req, + output wire [7:0] qsfp1_mac_1_tx_pfc_req, + input wire qsfp1_mac_1_rx_clk, input wire qsfp1_mac_1_rx_rst, @@ -250,6 +253,8 @@ module fpga_core # input wire [AXIS_ETH_RX_USER_WIDTH-1:0] qsfp1_mac_1_rx_axis_tuser, input wire qsfp1_mac_1_rx_status, + input wire qsfp1_mac_1_rx_lfc_req, + input wire [7:0] qsfp1_mac_1_rx_pfc_req, input wire qsfp1_mac_2_tx_clk, input wire qsfp1_mac_2_tx_rst, @@ -269,6 +274,10 @@ module fpga_core # output wire qsfp1_mac_2_tx_axis_tlast, output wire [AXIS_ETH_TX_USER_WIDTH-1:0] qsfp1_mac_2_tx_axis_tuser, + input wire qsfp1_mac_2_tx_status, + output wire qsfp1_mac_2_tx_lfc_req, + output wire [7:0] qsfp1_mac_2_tx_pfc_req, + input wire qsfp1_mac_2_rx_clk, input wire qsfp1_mac_2_rx_rst, @@ -283,6 +292,8 @@ module fpga_core # input wire [AXIS_ETH_RX_USER_WIDTH-1:0] qsfp1_mac_2_rx_axis_tuser, input wire qsfp1_mac_2_rx_status, + input wire qsfp1_mac_2_rx_lfc_req, + input wire [7:0] qsfp1_mac_2_rx_pfc_req, input wire qsfp1_mac_3_tx_clk, input wire qsfp1_mac_3_tx_rst, @@ -302,6 +313,10 @@ module fpga_core # output wire qsfp1_mac_3_tx_axis_tlast, output wire [AXIS_ETH_TX_USER_WIDTH-1:0] qsfp1_mac_3_tx_axis_tuser, + input wire qsfp1_mac_3_tx_status, + output wire qsfp1_mac_3_tx_lfc_req, + output wire [7:0] qsfp1_mac_3_tx_pfc_req, + input wire qsfp1_mac_3_rx_clk, input wire qsfp1_mac_3_rx_rst, @@ -316,6 +331,8 @@ module fpga_core # input wire [AXIS_ETH_RX_USER_WIDTH-1:0] qsfp1_mac_3_rx_axis_tuser, input wire qsfp1_mac_3_rx_status, + input wire qsfp1_mac_3_rx_lfc_req, + input wire [7:0] qsfp1_mac_3_rx_pfc_req, input wire qsfp1_mac_4_tx_clk, input wire qsfp1_mac_4_tx_rst, @@ -335,6 +352,10 @@ module fpga_core # output wire qsfp1_mac_4_tx_axis_tlast, output wire [AXIS_ETH_TX_USER_WIDTH-1:0] qsfp1_mac_4_tx_axis_tuser, + input wire qsfp1_mac_4_tx_status, + output wire qsfp1_mac_4_tx_lfc_req, + output wire [7:0] qsfp1_mac_4_tx_pfc_req, + input wire qsfp1_mac_4_rx_clk, input wire qsfp1_mac_4_rx_rst, @@ -349,6 +370,8 @@ module fpga_core # input wire [AXIS_ETH_RX_USER_WIDTH-1:0] qsfp1_mac_4_rx_axis_tuser, input wire qsfp1_mac_4_rx_status, + input wire qsfp1_mac_4_rx_lfc_req, + input wire [7:0] qsfp1_mac_4_rx_pfc_req, input wire qsfp2_mac_1_tx_clk, input wire qsfp2_mac_1_tx_rst, @@ -368,6 +391,10 @@ module fpga_core # output wire qsfp2_mac_1_tx_axis_tlast, output wire [AXIS_ETH_TX_USER_WIDTH-1:0] qsfp2_mac_1_tx_axis_tuser, + input wire qsfp2_mac_1_tx_status, + output wire qsfp2_mac_1_tx_lfc_req, + output wire [7:0] qsfp2_mac_1_tx_pfc_req, + input wire qsfp2_mac_1_rx_clk, input wire qsfp2_mac_1_rx_rst, @@ -382,6 +409,8 @@ module fpga_core # input wire [AXIS_ETH_RX_USER_WIDTH-1:0] qsfp2_mac_1_rx_axis_tuser, input wire qsfp2_mac_1_rx_status, + input wire qsfp2_mac_1_rx_lfc_req, + input wire [7:0] qsfp2_mac_1_rx_pfc_req, input wire qsfp2_mac_2_tx_clk, input wire qsfp2_mac_2_tx_rst, @@ -401,6 +430,10 @@ module fpga_core # output wire qsfp2_mac_2_tx_axis_tlast, output wire [AXIS_ETH_TX_USER_WIDTH-1:0] qsfp2_mac_2_tx_axis_tuser, + input wire qsfp2_mac_2_tx_status, + output wire qsfp2_mac_2_tx_lfc_req, + output wire [7:0] qsfp2_mac_2_tx_pfc_req, + input wire qsfp2_mac_2_rx_clk, input wire qsfp2_mac_2_rx_rst, @@ -415,6 +448,8 @@ module fpga_core # input wire [AXIS_ETH_RX_USER_WIDTH-1:0] qsfp2_mac_2_rx_axis_tuser, input wire qsfp2_mac_2_rx_status, + input wire qsfp2_mac_2_rx_lfc_req, + input wire [7:0] qsfp2_mac_2_rx_pfc_req, input wire qsfp2_mac_3_tx_clk, input wire qsfp2_mac_3_tx_rst, @@ -434,6 +469,10 @@ module fpga_core # output wire qsfp2_mac_3_tx_axis_tlast, output wire [AXIS_ETH_TX_USER_WIDTH-1:0] qsfp2_mac_3_tx_axis_tuser, + input wire qsfp2_mac_3_tx_status, + output wire qsfp2_mac_3_tx_lfc_req, + output wire [7:0] qsfp2_mac_3_tx_pfc_req, + input wire qsfp2_mac_3_rx_clk, input wire qsfp2_mac_3_rx_rst, @@ -448,6 +487,8 @@ module fpga_core # input wire [AXIS_ETH_RX_USER_WIDTH-1:0] qsfp2_mac_3_rx_axis_tuser, input wire qsfp2_mac_3_rx_status, + input wire qsfp2_mac_3_rx_lfc_req, + input wire [7:0] qsfp2_mac_3_rx_pfc_req, input wire qsfp2_mac_4_tx_clk, input wire qsfp2_mac_4_tx_rst, @@ -467,6 +508,10 @@ module fpga_core # output wire qsfp2_mac_4_tx_axis_tlast, output wire [AXIS_ETH_TX_USER_WIDTH-1:0] qsfp2_mac_4_tx_axis_tuser, + input wire qsfp2_mac_4_tx_status, + output wire qsfp2_mac_4_tx_lfc_req, + output wire [7:0] qsfp2_mac_4_tx_pfc_req, + input wire qsfp2_mac_4_rx_clk, input wire qsfp2_mac_4_rx_rst, @@ -480,7 +525,9 @@ module fpga_core # input wire qsfp2_mac_4_rx_axis_tlast, input wire [AXIS_ETH_RX_USER_WIDTH-1:0] qsfp2_mac_4_rx_axis_tuser, - input wire qsfp2_mac_4_rx_status + input wire qsfp2_mac_4_rx_status, + input wire qsfp2_mac_4_rx_lfc_req, + input wire [7:0] qsfp2_mac_4_rx_pfc_req ); parameter PORT_COUNT = IF_COUNT*PORTS_PER_IF; @@ -643,7 +690,12 @@ wire [PORT_COUNT*TX_TAG_WIDTH-1:0] axis_eth_tx_ptp_ts_tag; wire [PORT_COUNT-1:0] axis_eth_tx_ptp_ts_valid; wire [PORT_COUNT-1:0] axis_eth_tx_ptp_ts_ready; +wire [PORT_COUNT-1:0] eth_tx_enable; wire [PORT_COUNT-1:0] eth_tx_status; +wire [PORT_COUNT-1:0] eth_tx_lfc_en; +wire [PORT_COUNT-1:0] eth_tx_lfc_req; +wire [PORT_COUNT*8-1:0] eth_tx_pfc_en; +wire [PORT_COUNT*8-1:0] eth_tx_pfc_req; wire [PORT_COUNT-1:0] eth_rx_clk; wire [PORT_COUNT-1:0] eth_rx_rst; @@ -660,7 +712,14 @@ wire [PORT_COUNT-1:0] axis_eth_rx_tready; wire [PORT_COUNT-1:0] axis_eth_rx_tlast; wire [PORT_COUNT*AXIS_ETH_RX_USER_WIDTH-1:0] axis_eth_rx_tuser; +wire [PORT_COUNT-1:0] eth_rx_enable; wire [PORT_COUNT-1:0] eth_rx_status; +wire [PORT_COUNT-1:0] eth_rx_lfc_en; +wire [PORT_COUNT-1:0] eth_rx_lfc_req; +wire [PORT_COUNT-1:0] eth_rx_lfc_ack; +wire [PORT_COUNT*8-1:0] eth_rx_pfc_en; +wire [PORT_COUNT*8-1:0] eth_rx_pfc_req; +wire [PORT_COUNT*8-1:0] eth_rx_pfc_ack; mqnic_port_map_mac_axis #( .MAC_COUNT(8), @@ -701,7 +760,12 @@ mqnic_port_map_mac_axis_inst ( .s_axis_mac_tx_ptp_ts_valid({qsfp2_mac_4_tx_ptp_ts_valid, qsfp2_mac_3_tx_ptp_ts_valid, qsfp2_mac_2_tx_ptp_ts_valid, qsfp2_mac_1_tx_ptp_ts_valid, qsfp1_mac_4_tx_ptp_ts_valid, qsfp1_mac_3_tx_ptp_ts_valid, qsfp1_mac_2_tx_ptp_ts_valid, qsfp1_mac_1_tx_ptp_ts_valid}), .s_axis_mac_tx_ptp_ts_ready(), - .mac_tx_status(8'hff), + .mac_tx_enable(), + .mac_tx_status({qsfp2_mac_4_tx_status, qsfp2_mac_3_tx_status, qsfp2_mac_2_tx_status, qsfp2_mac_1_tx_status, qsfp1_mac_4_tx_status, qsfp1_mac_3_tx_status, qsfp1_mac_2_tx_status, qsfp1_mac_1_tx_status}), + .mac_tx_lfc_en(), + .mac_tx_lfc_req({qsfp2_mac_4_tx_lfc_req, qsfp2_mac_3_tx_lfc_req, qsfp2_mac_2_tx_lfc_req, qsfp2_mac_1_tx_lfc_req, qsfp1_mac_4_tx_lfc_req, qsfp1_mac_3_tx_lfc_req, qsfp1_mac_2_tx_lfc_req, qsfp1_mac_1_tx_lfc_req}), + .mac_tx_pfc_en(), + .mac_tx_pfc_req({qsfp2_mac_4_tx_pfc_req, qsfp2_mac_3_tx_pfc_req, qsfp2_mac_2_tx_pfc_req, qsfp2_mac_1_tx_pfc_req, qsfp1_mac_4_tx_pfc_req, qsfp1_mac_3_tx_pfc_req, qsfp1_mac_2_tx_pfc_req, qsfp1_mac_1_tx_pfc_req}), .mac_rx_clk({qsfp2_mac_4_rx_clk, qsfp2_mac_3_rx_clk, qsfp2_mac_2_rx_clk, qsfp2_mac_1_rx_clk, qsfp1_mac_4_rx_clk, qsfp1_mac_3_rx_clk, qsfp1_mac_2_rx_clk, qsfp1_mac_1_rx_clk}), .mac_rx_rst({qsfp2_mac_4_rx_rst, qsfp2_mac_3_rx_rst, qsfp2_mac_2_rx_rst, qsfp2_mac_1_rx_rst, qsfp1_mac_4_rx_rst, qsfp1_mac_3_rx_rst, qsfp1_mac_2_rx_rst, qsfp1_mac_1_rx_rst}), @@ -718,7 +782,14 @@ mqnic_port_map_mac_axis_inst ( .s_axis_mac_rx_tlast({qsfp2_mac_4_rx_axis_tlast, qsfp2_mac_3_rx_axis_tlast, qsfp2_mac_2_rx_axis_tlast, qsfp2_mac_1_rx_axis_tlast, qsfp1_mac_4_rx_axis_tlast, qsfp1_mac_3_rx_axis_tlast, qsfp1_mac_2_rx_axis_tlast, qsfp1_mac_1_rx_axis_tlast}), .s_axis_mac_rx_tuser({qsfp2_mac_4_rx_axis_tuser, qsfp2_mac_3_rx_axis_tuser, qsfp2_mac_2_rx_axis_tuser, qsfp2_mac_1_rx_axis_tuser, qsfp1_mac_4_rx_axis_tuser, qsfp1_mac_3_rx_axis_tuser, qsfp1_mac_2_rx_axis_tuser, qsfp1_mac_1_rx_axis_tuser}), + .mac_rx_enable(), .mac_rx_status({qsfp2_mac_4_rx_status, qsfp2_mac_3_rx_status, qsfp2_mac_2_rx_status, qsfp2_mac_1_rx_status, qsfp1_mac_4_rx_status, qsfp1_mac_3_rx_status, qsfp1_mac_2_rx_status, qsfp1_mac_1_rx_status}), + .mac_rx_lfc_en(), + .mac_rx_lfc_req({qsfp2_mac_4_rx_lfc_req, qsfp2_mac_3_rx_lfc_req, qsfp2_mac_2_rx_lfc_req, qsfp2_mac_1_rx_lfc_req, qsfp1_mac_4_rx_lfc_req, qsfp1_mac_3_rx_lfc_req, qsfp1_mac_2_rx_lfc_req, qsfp1_mac_1_rx_lfc_req}), + .mac_rx_lfc_ack(), + .mac_rx_pfc_en(), + .mac_rx_pfc_req({qsfp2_mac_4_rx_pfc_req, qsfp2_mac_3_rx_pfc_req, qsfp2_mac_2_rx_pfc_req, qsfp2_mac_1_rx_pfc_req, qsfp1_mac_4_rx_pfc_req, qsfp1_mac_3_rx_pfc_req, qsfp1_mac_2_rx_pfc_req, qsfp1_mac_1_rx_pfc_req}), + .mac_rx_pfc_ack(), // towards datapath .tx_clk(eth_tx_clk), @@ -741,7 +812,12 @@ mqnic_port_map_mac_axis_inst ( .m_axis_tx_ptp_ts_valid(axis_eth_tx_ptp_ts_valid), .m_axis_tx_ptp_ts_ready(axis_eth_tx_ptp_ts_ready), + .tx_enable(eth_tx_enable), .tx_status(eth_tx_status), + .tx_lfc_en(eth_tx_lfc_en), + .tx_lfc_req(eth_tx_lfc_req), + .tx_pfc_en(eth_tx_pfc_en), + .tx_pfc_req(eth_tx_pfc_req), .rx_clk(eth_rx_clk), .rx_rst(eth_rx_rst), @@ -758,7 +834,14 @@ mqnic_port_map_mac_axis_inst ( .m_axis_rx_tlast(axis_eth_rx_tlast), .m_axis_rx_tuser(axis_eth_rx_tuser), - .rx_status(eth_rx_status) + .rx_enable(eth_rx_enable), + .rx_status(eth_rx_status), + .rx_lfc_en(eth_rx_lfc_en), + .rx_lfc_req(eth_rx_lfc_req), + .rx_lfc_ack(eth_rx_lfc_ack), + .rx_pfc_en(eth_rx_pfc_en), + .rx_pfc_req(eth_rx_pfc_req), + .rx_pfc_ack(eth_rx_pfc_ack) ); mqnic_core_pcie_ptile #( @@ -828,6 +911,9 @@ mqnic_core_pcie_ptile #( .TX_CHECKSUM_ENABLE(TX_CHECKSUM_ENABLE), .RX_HASH_ENABLE(RX_HASH_ENABLE), .RX_CHECKSUM_ENABLE(RX_CHECKSUM_ENABLE), + .PFC_ENABLE(PFC_ENABLE), + .LFC_ENABLE(LFC_ENABLE), + .MAC_CTRL_ENABLE(0), .TX_FIFO_DEPTH(TX_FIFO_DEPTH), .RX_FIFO_DEPTH(RX_FIFO_DEPTH), .MAX_TX_SIZE(MAX_TX_SIZE), @@ -1035,7 +1121,13 @@ core_inst ( .s_axis_eth_tx_cpl_valid(axis_eth_tx_ptp_ts_valid), .s_axis_eth_tx_cpl_ready(axis_eth_tx_ptp_ts_ready), + .eth_tx_enable(eth_tx_enable), .eth_tx_status(eth_tx_status), + .eth_tx_lfc_en(eth_tx_lfc_en), + .eth_tx_lfc_req(eth_tx_lfc_req), + .eth_tx_pfc_en(eth_tx_pfc_en), + .eth_tx_pfc_req(eth_tx_pfc_req), + .eth_tx_fc_quanta_clk_en(0), .eth_rx_clk(eth_rx_clk), .eth_rx_rst(eth_rx_rst), @@ -1052,7 +1144,15 @@ core_inst ( .s_axis_eth_rx_tlast(axis_eth_rx_tlast), .s_axis_eth_rx_tuser(axis_eth_rx_tuser), + .eth_rx_enable(eth_rx_enable), .eth_rx_status(eth_rx_status), + .eth_rx_lfc_en(eth_rx_lfc_en), + .eth_rx_lfc_req(eth_rx_lfc_req), + .eth_rx_lfc_ack(eth_rx_lfc_ack), + .eth_rx_pfc_en(eth_rx_pfc_en), + .eth_rx_pfc_req(eth_rx_pfc_req), + .eth_rx_pfc_ack(eth_rx_pfc_ack), + .eth_rx_fc_quanta_clk_en(0), /* * DDR diff --git a/fpga/mqnic/DK_DEV_1SDX_P_A/fpga_25g/tb/fpga_core/Makefile b/fpga/mqnic/DK_DEV_1SDX_P_A/fpga_25g/tb/fpga_core/Makefile index 5e5cc21ff..e238a8428 100644 --- a/fpga/mqnic/DK_DEV_1SDX_P_A/fpga_25g/tb/fpga_core/Makefile +++ b/fpga/mqnic/DK_DEV_1SDX_P_A/fpga_25g/tb/fpga_core/Makefile @@ -165,6 +165,8 @@ export PARAM_TX_CPL_FIFO_DEPTH := 32 export PARAM_TX_CHECKSUM_ENABLE := 1 export PARAM_RX_HASH_ENABLE := 1 export PARAM_RX_CHECKSUM_ENABLE := 1 +export PARAM_LFC_ENABLE := 1 +export PARAM_PFC_ENABLE := $(PARAM_LFC_ENABLE) export PARAM_TX_FIFO_DEPTH := 32768 export PARAM_RX_FIFO_DEPTH := 32768 export PARAM_MAX_TX_SIZE := 9214 diff --git a/fpga/mqnic/DK_DEV_1SDX_P_A/fpga_25g/tb/fpga_core/test_fpga_core.py b/fpga/mqnic/DK_DEV_1SDX_P_A/fpga_25g/tb/fpga_core/test_fpga_core.py index de76dcf03..22da5624c 100644 --- a/fpga/mqnic/DK_DEV_1SDX_P_A/fpga_25g/tb/fpga_core/test_fpga_core.py +++ b/fpga/mqnic/DK_DEV_1SDX_P_A/fpga_25g/tb/fpga_core/test_fpga_core.py @@ -280,6 +280,8 @@ class TB(object): macs.append(mac) getattr(dut, f"qsfp{x}_mac_{y}_rx_status").setimmediatevalue(1) + getattr(dut, f"qsfp{x}_mac_{y}_rx_lfc_req").setimmediatevalue(0) + getattr(dut, f"qsfp{x}_mac_{y}_rx_pfc_req").setimmediatevalue(0) self.qsfp_mac.append(macs) @@ -681,6 +683,8 @@ def test_fpga_core(request): parameters['TX_CHECKSUM_ENABLE'] = 1 parameters['RX_HASH_ENABLE'] = 1 parameters['RX_CHECKSUM_ENABLE'] = 1 + parameters['LFC_ENABLE'] = 1 + parameters['PFC_ENABLE'] = parameters['LFC_ENABLE'] parameters['TX_FIFO_DEPTH'] = 32768 parameters['RX_FIFO_DEPTH'] = 32768 parameters['MAX_TX_SIZE'] = 9214 diff --git a/fpga/mqnic/DK_DEV_1SMX_H_A/fpga_25g/fpga_10g_1sm21b/Makefile b/fpga/mqnic/DK_DEV_1SMX_H_A/fpga_25g/fpga_10g_1sm21b/Makefile index eb4bcbd98..bd0055029 100644 --- a/fpga/mqnic/DK_DEV_1SMX_H_A/fpga_25g/fpga_10g_1sm21b/Makefile +++ b/fpga/mqnic/DK_DEV_1SMX_H_A/fpga_25g/fpga_10g_1sm21b/Makefile @@ -60,6 +60,10 @@ SYN_FILES += rtl/common/i2c_single_reg.v SYN_FILES += lib/eth/rtl/eth_mac_10g.v SYN_FILES += lib/eth/rtl/axis_xgmii_rx_64.v SYN_FILES += lib/eth/rtl/axis_xgmii_tx_64.v +SYN_FILES += lib/eth/rtl/mac_ctrl_rx.v +SYN_FILES += lib/eth/rtl/mac_ctrl_tx.v +SYN_FILES += lib/eth/rtl/mac_pause_ctrl_rx.v +SYN_FILES += lib/eth/rtl/mac_pause_ctrl_tx.v SYN_FILES += lib/eth/rtl/eth_phy_10g.v SYN_FILES += lib/eth/rtl/eth_phy_10g_rx.v SYN_FILES += lib/eth/rtl/eth_phy_10g_rx_if.v diff --git a/fpga/mqnic/DK_DEV_1SMX_H_A/fpga_25g/fpga_10g_1sm21b/config.tcl b/fpga/mqnic/DK_DEV_1SMX_H_A/fpga_25g/fpga_10g_1sm21b/config.tcl index 1e5bd1549..1c3824396 100644 --- a/fpga/mqnic/DK_DEV_1SMX_H_A/fpga_25g/fpga_10g_1sm21b/config.tcl +++ b/fpga/mqnic/DK_DEV_1SMX_H_A/fpga_25g/fpga_10g_1sm21b/config.tcl @@ -104,6 +104,8 @@ dict set params TX_CPL_FIFO_DEPTH "32" dict set params TX_CHECKSUM_ENABLE "1" dict set params RX_HASH_ENABLE "1" dict set params RX_CHECKSUM_ENABLE "1" +dict set params PFC_ENABLE "1" +dict set params LFC_ENABLE [dict get $params PFC_ENABLE] dict set params ENABLE_PADDING "1" dict set params ENABLE_DIC "1" dict set params MIN_FRAME_LENGTH "64" diff --git a/fpga/mqnic/DK_DEV_1SMX_H_A/fpga_25g/fpga_10g_1sm21c/Makefile b/fpga/mqnic/DK_DEV_1SMX_H_A/fpga_25g/fpga_10g_1sm21c/Makefile index 023d0082d..2016af126 100644 --- a/fpga/mqnic/DK_DEV_1SMX_H_A/fpga_25g/fpga_10g_1sm21c/Makefile +++ b/fpga/mqnic/DK_DEV_1SMX_H_A/fpga_25g/fpga_10g_1sm21c/Makefile @@ -60,6 +60,10 @@ SYN_FILES += rtl/common/i2c_single_reg.v SYN_FILES += lib/eth/rtl/eth_mac_10g.v SYN_FILES += lib/eth/rtl/axis_xgmii_rx_64.v SYN_FILES += lib/eth/rtl/axis_xgmii_tx_64.v +SYN_FILES += lib/eth/rtl/mac_ctrl_rx.v +SYN_FILES += lib/eth/rtl/mac_ctrl_tx.v +SYN_FILES += lib/eth/rtl/mac_pause_ctrl_rx.v +SYN_FILES += lib/eth/rtl/mac_pause_ctrl_tx.v SYN_FILES += lib/eth/rtl/eth_phy_10g.v SYN_FILES += lib/eth/rtl/eth_phy_10g_rx.v SYN_FILES += lib/eth/rtl/eth_phy_10g_rx_if.v diff --git a/fpga/mqnic/DK_DEV_1SMX_H_A/fpga_25g/fpga_10g_1sm21c/config.tcl b/fpga/mqnic/DK_DEV_1SMX_H_A/fpga_25g/fpga_10g_1sm21c/config.tcl index 891cf57b9..c420d485a 100644 --- a/fpga/mqnic/DK_DEV_1SMX_H_A/fpga_25g/fpga_10g_1sm21c/config.tcl +++ b/fpga/mqnic/DK_DEV_1SMX_H_A/fpga_25g/fpga_10g_1sm21c/config.tcl @@ -104,6 +104,8 @@ dict set params TX_CPL_FIFO_DEPTH "32" dict set params TX_CHECKSUM_ENABLE "1" dict set params RX_HASH_ENABLE "1" dict set params RX_CHECKSUM_ENABLE "1" +dict set params PFC_ENABLE "1" +dict set params LFC_ENABLE [dict get $params PFC_ENABLE] dict set params ENABLE_PADDING "1" dict set params ENABLE_DIC "1" dict set params MIN_FRAME_LENGTH "64" diff --git a/fpga/mqnic/DK_DEV_1SMX_H_A/fpga_25g/fpga_1sm21b/Makefile b/fpga/mqnic/DK_DEV_1SMX_H_A/fpga_25g/fpga_1sm21b/Makefile index d234975ca..7bedb94b0 100644 --- a/fpga/mqnic/DK_DEV_1SMX_H_A/fpga_25g/fpga_1sm21b/Makefile +++ b/fpga/mqnic/DK_DEV_1SMX_H_A/fpga_25g/fpga_1sm21b/Makefile @@ -60,6 +60,10 @@ SYN_FILES += rtl/common/i2c_single_reg.v SYN_FILES += lib/eth/rtl/eth_mac_10g.v SYN_FILES += lib/eth/rtl/axis_xgmii_rx_64.v SYN_FILES += lib/eth/rtl/axis_xgmii_tx_64.v +SYN_FILES += lib/eth/rtl/mac_ctrl_rx.v +SYN_FILES += lib/eth/rtl/mac_ctrl_tx.v +SYN_FILES += lib/eth/rtl/mac_pause_ctrl_rx.v +SYN_FILES += lib/eth/rtl/mac_pause_ctrl_tx.v SYN_FILES += lib/eth/rtl/eth_phy_10g.v SYN_FILES += lib/eth/rtl/eth_phy_10g_rx.v SYN_FILES += lib/eth/rtl/eth_phy_10g_rx_if.v diff --git a/fpga/mqnic/DK_DEV_1SMX_H_A/fpga_25g/fpga_1sm21b/config.tcl b/fpga/mqnic/DK_DEV_1SMX_H_A/fpga_25g/fpga_1sm21b/config.tcl index 74751ea7f..2ea6e9dba 100644 --- a/fpga/mqnic/DK_DEV_1SMX_H_A/fpga_25g/fpga_1sm21b/config.tcl +++ b/fpga/mqnic/DK_DEV_1SMX_H_A/fpga_25g/fpga_1sm21b/config.tcl @@ -104,6 +104,8 @@ dict set params TX_CPL_FIFO_DEPTH "32" dict set params TX_CHECKSUM_ENABLE "1" dict set params RX_HASH_ENABLE "1" dict set params RX_CHECKSUM_ENABLE "1" +dict set params PFC_ENABLE "1" +dict set params LFC_ENABLE [dict get $params PFC_ENABLE] dict set params ENABLE_PADDING "1" dict set params ENABLE_DIC "1" dict set params MIN_FRAME_LENGTH "64" diff --git a/fpga/mqnic/DK_DEV_1SMX_H_A/fpga_25g/fpga_1sm21c/Makefile b/fpga/mqnic/DK_DEV_1SMX_H_A/fpga_25g/fpga_1sm21c/Makefile index 2445a445b..bddf86ff1 100644 --- a/fpga/mqnic/DK_DEV_1SMX_H_A/fpga_25g/fpga_1sm21c/Makefile +++ b/fpga/mqnic/DK_DEV_1SMX_H_A/fpga_25g/fpga_1sm21c/Makefile @@ -60,6 +60,10 @@ SYN_FILES += rtl/common/i2c_single_reg.v SYN_FILES += lib/eth/rtl/eth_mac_10g.v SYN_FILES += lib/eth/rtl/axis_xgmii_rx_64.v SYN_FILES += lib/eth/rtl/axis_xgmii_tx_64.v +SYN_FILES += lib/eth/rtl/mac_ctrl_rx.v +SYN_FILES += lib/eth/rtl/mac_ctrl_tx.v +SYN_FILES += lib/eth/rtl/mac_pause_ctrl_rx.v +SYN_FILES += lib/eth/rtl/mac_pause_ctrl_tx.v SYN_FILES += lib/eth/rtl/eth_phy_10g.v SYN_FILES += lib/eth/rtl/eth_phy_10g_rx.v SYN_FILES += lib/eth/rtl/eth_phy_10g_rx_if.v diff --git a/fpga/mqnic/DK_DEV_1SMX_H_A/fpga_25g/fpga_1sm21c/config.tcl b/fpga/mqnic/DK_DEV_1SMX_H_A/fpga_25g/fpga_1sm21c/config.tcl index d3420b33e..9f5b19b13 100644 --- a/fpga/mqnic/DK_DEV_1SMX_H_A/fpga_25g/fpga_1sm21c/config.tcl +++ b/fpga/mqnic/DK_DEV_1SMX_H_A/fpga_25g/fpga_1sm21c/config.tcl @@ -104,6 +104,8 @@ dict set params TX_CPL_FIFO_DEPTH "32" dict set params TX_CHECKSUM_ENABLE "1" dict set params RX_HASH_ENABLE "1" dict set params RX_CHECKSUM_ENABLE "1" +dict set params PFC_ENABLE "1" +dict set params LFC_ENABLE [dict get $params PFC_ENABLE] dict set params ENABLE_PADDING "1" dict set params ENABLE_DIC "1" dict set params MIN_FRAME_LENGTH "64" diff --git a/fpga/mqnic/DK_DEV_1SMX_H_A/fpga_25g/rtl/fpga.v b/fpga/mqnic/DK_DEV_1SMX_H_A/fpga_25g/rtl/fpga.v index 224cda30f..40e8948e2 100644 --- a/fpga/mqnic/DK_DEV_1SMX_H_A/fpga_25g/rtl/fpga.v +++ b/fpga/mqnic/DK_DEV_1SMX_H_A/fpga_25g/rtl/fpga.v @@ -74,6 +74,8 @@ module fpga # parameter TX_CHECKSUM_ENABLE = 1, parameter RX_HASH_ENABLE = 1, parameter RX_CHECKSUM_ENABLE = 1, + parameter PFC_ENABLE = 1, + parameter LFC_ENABLE = PFC_ENABLE, parameter ENABLE_PADDING = 1, parameter ENABLE_DIC = 1, parameter MIN_FRAME_LENGTH = 64, @@ -1018,6 +1020,8 @@ fpga_core #( .TX_CHECKSUM_ENABLE(TX_CHECKSUM_ENABLE), .RX_HASH_ENABLE(RX_HASH_ENABLE), .RX_CHECKSUM_ENABLE(RX_CHECKSUM_ENABLE), + .PFC_ENABLE(PFC_ENABLE), + .LFC_ENABLE(LFC_ENABLE), .ENABLE_PADDING(ENABLE_PADDING), .ENABLE_DIC(ENABLE_DIC), .MIN_FRAME_LENGTH(MIN_FRAME_LENGTH), diff --git a/fpga/mqnic/DK_DEV_1SMX_H_A/fpga_25g/rtl/fpga_core.v b/fpga/mqnic/DK_DEV_1SMX_H_A/fpga_25g/rtl/fpga_core.v index 00a705c15..d632a1117 100644 --- a/fpga/mqnic/DK_DEV_1SMX_H_A/fpga_25g/rtl/fpga_core.v +++ b/fpga/mqnic/DK_DEV_1SMX_H_A/fpga_25g/rtl/fpga_core.v @@ -81,6 +81,8 @@ module fpga_core # parameter TX_CHECKSUM_ENABLE = 1, parameter RX_HASH_ENABLE = 1, parameter RX_CHECKSUM_ENABLE = 1, + parameter PFC_ENABLE = 1, + parameter LFC_ENABLE = PFC_ENABLE, parameter ENABLE_PADDING = 1, parameter ENABLE_DIC = 1, parameter MIN_FRAME_LENGTH = 64, @@ -642,7 +644,12 @@ wire [PORT_COUNT*TX_TAG_WIDTH-1:0] axis_eth_tx_ptp_ts_tag; wire [PORT_COUNT-1:0] axis_eth_tx_ptp_ts_valid; wire [PORT_COUNT-1:0] axis_eth_tx_ptp_ts_ready; +wire [PORT_COUNT-1:0] eth_tx_enable; wire [PORT_COUNT-1:0] eth_tx_status; +wire [PORT_COUNT-1:0] eth_tx_lfc_en; +wire [PORT_COUNT-1:0] eth_tx_lfc_req; +wire [PORT_COUNT*8-1:0] eth_tx_pfc_en; +wire [PORT_COUNT*8-1:0] eth_tx_pfc_req; wire [PORT_COUNT-1:0] eth_rx_clk; wire [PORT_COUNT-1:0] eth_rx_rst; @@ -657,7 +664,14 @@ wire [PORT_COUNT-1:0] axis_eth_rx_tready; wire [PORT_COUNT-1:0] axis_eth_rx_tlast; wire [PORT_COUNT*AXIS_ETH_RX_USER_WIDTH-1:0] axis_eth_rx_tuser; +wire [PORT_COUNT-1:0] eth_rx_enable; wire [PORT_COUNT-1:0] eth_rx_status; +wire [PORT_COUNT-1:0] eth_rx_lfc_en; +wire [PORT_COUNT-1:0] eth_rx_lfc_req; +wire [PORT_COUNT-1:0] eth_rx_lfc_ack; +wire [PORT_COUNT*8-1:0] eth_rx_pfc_en; +wire [PORT_COUNT*8-1:0] eth_rx_pfc_req; +wire [PORT_COUNT*8-1:0] eth_rx_pfc_ack; wire [PORT_COUNT-1:0] port_xgmii_tx_clk; wire [PORT_COUNT-1:0] port_xgmii_tx_rst; @@ -730,12 +744,15 @@ generate .PTP_PERIOD_FNS(IF_PTP_PERIOD_FNS), .TX_PTP_TS_ENABLE(PTP_TS_ENABLE), .TX_PTP_TS_WIDTH(PTP_TS_WIDTH), + .TX_PTP_TS_CTRL_IN_TUSER(0), .TX_PTP_TAG_ENABLE(PTP_TS_ENABLE), .TX_PTP_TAG_WIDTH(TX_TAG_WIDTH), .RX_PTP_TS_ENABLE(PTP_TS_ENABLE), .RX_PTP_TS_WIDTH(PTP_TS_WIDTH), .TX_USER_WIDTH(AXIS_ETH_TX_USER_WIDTH), - .RX_USER_WIDTH(AXIS_ETH_RX_USER_WIDTH) + .RX_USER_WIDTH(AXIS_ETH_RX_USER_WIDTH), + .PFC_ENABLE(PFC_ENABLE), + .PAUSE_ENABLE(LFC_ENABLE) ) eth_mac_inst ( .tx_clk(port_xgmii_tx_clk[n]), @@ -743,6 +760,9 @@ generate .rx_clk(port_xgmii_rx_clk[n]), .rx_rst(port_xgmii_rx_rst[n]), + /* + * AXI input + */ .tx_axis_tdata(axis_eth_tx_tdata[n*AXIS_ETH_DATA_WIDTH +: AXIS_ETH_DATA_WIDTH]), .tx_axis_tkeep(axis_eth_tx_tkeep[n*AXIS_ETH_KEEP_WIDTH +: AXIS_ETH_KEEP_WIDTH]), .tx_axis_tvalid(axis_eth_tx_tvalid[n +: 1]), @@ -750,30 +770,121 @@ generate .tx_axis_tlast(axis_eth_tx_tlast[n +: 1]), .tx_axis_tuser(axis_eth_tx_tuser[n*AXIS_ETH_TX_USER_WIDTH +: AXIS_ETH_TX_USER_WIDTH]), + /* + * AXI output + */ .rx_axis_tdata(axis_eth_rx_tdata[n*AXIS_ETH_DATA_WIDTH +: AXIS_ETH_DATA_WIDTH]), .rx_axis_tkeep(axis_eth_rx_tkeep[n*AXIS_ETH_KEEP_WIDTH +: AXIS_ETH_KEEP_WIDTH]), .rx_axis_tvalid(axis_eth_rx_tvalid[n +: 1]), .rx_axis_tlast(axis_eth_rx_tlast[n +: 1]), .rx_axis_tuser(axis_eth_rx_tuser[n*AXIS_ETH_RX_USER_WIDTH +: AXIS_ETH_RX_USER_WIDTH]), + /* + * XGMII interface + */ .xgmii_rxd(port_xgmii_rxd[n*XGMII_DATA_WIDTH +: XGMII_DATA_WIDTH]), .xgmii_rxc(port_xgmii_rxc[n*XGMII_CTRL_WIDTH +: XGMII_CTRL_WIDTH]), .xgmii_txd(port_xgmii_txd[n*XGMII_DATA_WIDTH +: XGMII_DATA_WIDTH]), .xgmii_txc(port_xgmii_txc[n*XGMII_CTRL_WIDTH +: XGMII_CTRL_WIDTH]), + /* + * PTP + */ .tx_ptp_ts(eth_tx_ptp_ts_96[n*PTP_TS_WIDTH +: PTP_TS_WIDTH]), .rx_ptp_ts(eth_rx_ptp_ts_96[n*PTP_TS_WIDTH +: PTP_TS_WIDTH]), .tx_axis_ptp_ts(axis_eth_tx_ptp_ts[n*PTP_TS_WIDTH +: PTP_TS_WIDTH]), .tx_axis_ptp_ts_tag(axis_eth_tx_ptp_ts_tag[n*TX_TAG_WIDTH +: TX_TAG_WIDTH]), .tx_axis_ptp_ts_valid(axis_eth_tx_ptp_ts_valid[n +: 1]), + /* + * Link-level Flow Control (LFC) (IEEE 802.3 annex 31B PAUSE) + */ + .tx_lfc_req(eth_tx_lfc_req[n +: 1]), + .tx_lfc_resend(1'b0), + .rx_lfc_en(eth_rx_lfc_en[n +: 1]), + .rx_lfc_req(eth_rx_lfc_req[n +: 1]), + .rx_lfc_ack(eth_rx_lfc_ack[n +: 1]), + + /* + * Priority Flow Control (PFC) (IEEE 802.3 annex 31D PFC) + */ + .tx_pfc_req(eth_tx_pfc_req[n*8 +: 8]), + .tx_pfc_resend(1'b0), + .rx_pfc_en(eth_rx_pfc_en[n*8 +: 8]), + .rx_pfc_req(eth_rx_pfc_req[n*8 +: 8]), + .rx_pfc_ack(eth_rx_pfc_ack[n*8 +: 8]), + + /* + * Pause interface + */ + .tx_lfc_pause_en(1'b1), + .tx_pause_req(1'b0), + .tx_pause_ack(), + + /* + * Status + */ + .tx_start_packet(), .tx_error_underflow(), + .rx_start_packet(), .rx_error_bad_frame(), .rx_error_bad_fcs(), + .stat_tx_mcf(), + .stat_rx_mcf(), + .stat_tx_lfc_pkt(), + .stat_tx_lfc_xon(), + .stat_tx_lfc_xoff(), + .stat_tx_lfc_paused(), + .stat_tx_pfc_pkt(), + .stat_tx_pfc_xon(), + .stat_tx_pfc_xoff(), + .stat_tx_pfc_paused(), + .stat_rx_lfc_pkt(), + .stat_rx_lfc_xon(), + .stat_rx_lfc_xoff(), + .stat_rx_lfc_paused(), + .stat_rx_pfc_pkt(), + .stat_rx_pfc_xon(), + .stat_rx_pfc_xoff(), + .stat_rx_pfc_paused(), + /* + * Configuration + */ .cfg_ifg(8'd12), - .cfg_tx_enable(1'b1), - .cfg_rx_enable(1'b1) + .cfg_tx_enable(eth_tx_enable[n +: 1]), + .cfg_rx_enable(eth_rx_enable[n +: 1]), + .cfg_mcf_rx_eth_dst_mcast(48'h01_80_C2_00_00_01), + .cfg_mcf_rx_check_eth_dst_mcast(1'b1), + .cfg_mcf_rx_eth_dst_ucast(48'd0), + .cfg_mcf_rx_check_eth_dst_ucast(1'b0), + .cfg_mcf_rx_eth_src(48'd0), + .cfg_mcf_rx_check_eth_src(1'b0), + .cfg_mcf_rx_eth_type(16'h8808), + .cfg_mcf_rx_opcode_lfc(16'h0001), + .cfg_mcf_rx_check_opcode_lfc(eth_rx_lfc_en[n +: 1]), + .cfg_mcf_rx_opcode_pfc(16'h0101), + .cfg_mcf_rx_check_opcode_pfc(eth_rx_pfc_en[n*8 +: 8] != 0), + .cfg_mcf_rx_forward(1'b0), + .cfg_mcf_rx_enable(eth_rx_lfc_en[n +: 1] || eth_rx_pfc_en[n*8 +: 8]), + .cfg_tx_lfc_eth_dst(48'h01_80_C2_00_00_01), + .cfg_tx_lfc_eth_src(48'h80_23_31_43_54_4C), + .cfg_tx_lfc_eth_type(16'h8808), + .cfg_tx_lfc_opcode(16'h0001), + .cfg_tx_lfc_en(eth_tx_lfc_en[n +: 1]), + .cfg_tx_lfc_quanta(16'hffff), + .cfg_tx_lfc_refresh(16'h7fff), + .cfg_tx_pfc_eth_dst(48'h01_80_C2_00_00_01), + .cfg_tx_pfc_eth_src(48'h80_23_31_43_54_4C), + .cfg_tx_pfc_eth_type(16'h8808), + .cfg_tx_pfc_opcode(16'h0101), + .cfg_tx_pfc_en(eth_tx_pfc_en[n*8 +: 8] != 0), + .cfg_tx_pfc_quanta({8{16'hffff}}), + .cfg_tx_pfc_refresh({8{16'h7fff}}), + .cfg_rx_lfc_opcode(16'h0001), + .cfg_rx_lfc_en(eth_rx_lfc_en[n +: 1]), + .cfg_rx_pfc_opcode(16'h0101), + .cfg_rx_pfc_en(eth_rx_pfc_en[n*8 +: 8] != 0) ); end @@ -847,6 +958,9 @@ mqnic_core_pcie_s10 #( .TX_CHECKSUM_ENABLE(TX_CHECKSUM_ENABLE), .RX_HASH_ENABLE(RX_HASH_ENABLE), .RX_CHECKSUM_ENABLE(RX_CHECKSUM_ENABLE), + .PFC_ENABLE(PFC_ENABLE), + .LFC_ENABLE(LFC_ENABLE), + .MAC_CTRL_ENABLE(0), .TX_FIFO_DEPTH(TX_FIFO_DEPTH), .RX_FIFO_DEPTH(RX_FIFO_DEPTH), .MAX_TX_SIZE(MAX_TX_SIZE), @@ -1053,7 +1167,13 @@ core_inst ( .s_axis_eth_tx_cpl_valid(axis_eth_tx_ptp_ts_valid), .s_axis_eth_tx_cpl_ready(axis_eth_tx_ptp_ts_ready), + .eth_tx_enable(eth_tx_enable), .eth_tx_status(eth_tx_status), + .eth_tx_lfc_en(eth_tx_lfc_en), + .eth_tx_lfc_req(eth_tx_lfc_req), + .eth_tx_pfc_en(eth_tx_pfc_en), + .eth_tx_pfc_req(eth_tx_pfc_req), + .eth_tx_fc_quanta_clk_en(0), .eth_rx_clk(eth_rx_clk), .eth_rx_rst(eth_rx_rst), @@ -1070,7 +1190,15 @@ core_inst ( .s_axis_eth_rx_tlast(axis_eth_rx_tlast), .s_axis_eth_rx_tuser(axis_eth_rx_tuser), + .eth_rx_enable(eth_rx_enable), .eth_rx_status(eth_rx_status), + .eth_rx_lfc_en(eth_rx_lfc_en), + .eth_rx_lfc_req(eth_rx_lfc_req), + .eth_rx_lfc_ack(eth_rx_lfc_ack), + .eth_rx_pfc_en(eth_rx_pfc_en), + .eth_rx_pfc_req(eth_rx_pfc_req), + .eth_rx_pfc_ack(eth_rx_pfc_ack), + .eth_rx_fc_quanta_clk_en(0), /* * DDR diff --git a/fpga/mqnic/DK_DEV_1SMX_H_A/fpga_25g/tb/fpga_core/Makefile b/fpga/mqnic/DK_DEV_1SMX_H_A/fpga_25g/tb/fpga_core/Makefile index fe48ca242..f7e55b764 100644 --- a/fpga/mqnic/DK_DEV_1SMX_H_A/fpga_25g/tb/fpga_core/Makefile +++ b/fpga/mqnic/DK_DEV_1SMX_H_A/fpga_25g/tb/fpga_core/Makefile @@ -61,6 +61,10 @@ VERILOG_SOURCES += ../../rtl/common/i2c_single_reg.v VERILOG_SOURCES += ../../lib/eth/rtl/eth_mac_10g.v VERILOG_SOURCES += ../../lib/eth/rtl/axis_xgmii_rx_64.v VERILOG_SOURCES += ../../lib/eth/rtl/axis_xgmii_tx_64.v +VERILOG_SOURCES += ../../lib/eth/rtl/mac_ctrl_rx.v +VERILOG_SOURCES += ../../lib/eth/rtl/mac_ctrl_tx.v +VERILOG_SOURCES += ../../lib/eth/rtl/mac_pause_ctrl_rx.v +VERILOG_SOURCES += ../../lib/eth/rtl/mac_pause_ctrl_tx.v VERILOG_SOURCES += ../../lib/eth/rtl/lfsr.v VERILOG_SOURCES += ../../lib/eth/rtl/ptp_clock.v VERILOG_SOURCES += ../../lib/eth/rtl/ptp_clock_cdc.v @@ -166,6 +170,8 @@ export PARAM_TX_CPL_FIFO_DEPTH := 32 export PARAM_TX_CHECKSUM_ENABLE := 1 export PARAM_RX_HASH_ENABLE := 1 export PARAM_RX_CHECKSUM_ENABLE := 1 +export PARAM_LFC_ENABLE := 1 +export PARAM_PFC_ENABLE := $(PARAM_LFC_ENABLE) export PARAM_TX_FIFO_DEPTH := 32768 export PARAM_RX_FIFO_DEPTH := 32768 export PARAM_MAX_TX_SIZE := 9214 diff --git a/fpga/mqnic/DK_DEV_1SMX_H_A/fpga_25g/tb/fpga_core/test_fpga_core.py b/fpga/mqnic/DK_DEV_1SMX_H_A/fpga_25g/tb/fpga_core/test_fpga_core.py index 084ff8986..710cc61f5 100644 --- a/fpga/mqnic/DK_DEV_1SMX_H_A/fpga_25g/tb/fpga_core/test_fpga_core.py +++ b/fpga/mqnic/DK_DEV_1SMX_H_A/fpga_25g/tb/fpga_core/test_fpga_core.py @@ -3,6 +3,7 @@ import logging import os +import struct import sys import scapy.utils @@ -16,7 +17,7 @@ from cocotb.log import SimLog from cocotb.clock import Clock from cocotb.triggers import RisingEdge, FallingEdge, Timer -from cocotbext.eth import XgmiiSource, XgmiiSink +from cocotbext.eth import XgmiiSource, XgmiiSink, XgmiiFrame from cocotbext.pcie.core import RootComplex from cocotbext.pcie.intel.s10 import S10PcieDevice, S10RxBus, S10TxBus @@ -440,6 +441,35 @@ async def run_test_nic(dut): tb.loopback_enable = False + if tb.driver.interfaces[0].if_feature_lfc: + tb.log.info("Test LFC pause frame RX") + + await tb.driver.interfaces[0].ports[0].set_lfc_ctrl(mqnic.MQNIC_PORT_LFC_CTRL_TX_LFC_EN | mqnic.MQNIC_PORT_LFC_CTRL_RX_LFC_EN) + await tb.driver.hw_regs.read_dword(0) + + lfc_xoff = Ether(src='DA:D1:D2:D3:D4:D5', dst='01:80:C2:00:00:01', type=0x8808) / struct.pack('!HH', 0x0001, 2000) + + await tb.qsfp_source[0][0].send(XgmiiFrame.from_payload(bytes(lfc_xoff))) + + count = 16 + + pkts = [bytearray([(x+k) % 256 for x in range(1514)]) for k in range(count)] + + tb.loopback_enable = True + + for p in pkts: + await tb.driver.interfaces[0].start_xmit(p, 0) + + for k in range(count): + pkt = await tb.driver.interfaces[0].recv() + + tb.log.info("Packet: %s", pkt) + assert pkt.data == pkts[k] + if tb.driver.interfaces[0].if_feature_rx_csum: + assert pkt.rx_checksum == ~scapy.utils.checksum(bytes(pkt.data[14:])) & 0xffff + + tb.loopback_enable = False + await RisingEdge(dut.clk_250mhz) await RisingEdge(dut.clk_250mhz) @@ -511,6 +541,10 @@ def test_fpga_core(request): os.path.join(eth_rtl_dir, "eth_mac_10g.v"), os.path.join(eth_rtl_dir, "axis_xgmii_rx_64.v"), os.path.join(eth_rtl_dir, "axis_xgmii_tx_64.v"), + os.path.join(eth_rtl_dir, "mac_ctrl_rx.v"), + os.path.join(eth_rtl_dir, "mac_ctrl_tx.v"), + os.path.join(eth_rtl_dir, "mac_pause_ctrl_rx.v"), + os.path.join(eth_rtl_dir, "mac_pause_ctrl_tx.v"), os.path.join(eth_rtl_dir, "lfsr.v"), os.path.join(eth_rtl_dir, "ptp_clock.v"), os.path.join(eth_rtl_dir, "ptp_clock_cdc.v"), @@ -617,6 +651,8 @@ def test_fpga_core(request): parameters['TX_CHECKSUM_ENABLE'] = 1 parameters['RX_HASH_ENABLE'] = 1 parameters['RX_CHECKSUM_ENABLE'] = 1 + parameters['LFC_ENABLE'] = 1 + parameters['PFC_ENABLE'] = parameters['LFC_ENABLE'] parameters['TX_FIFO_DEPTH'] = 32768 parameters['RX_FIFO_DEPTH'] = 32768 parameters['MAX_TX_SIZE'] = 9214 diff --git a/fpga/mqnic/DK_DEV_AGF014EA/fpga_100g/fpga/config.tcl b/fpga/mqnic/DK_DEV_AGF014EA/fpga_100g/fpga/config.tcl index c12010d61..8a4dc71c7 100644 --- a/fpga/mqnic/DK_DEV_AGF014EA/fpga_100g/fpga/config.tcl +++ b/fpga/mqnic/DK_DEV_AGF014EA/fpga_100g/fpga/config.tcl @@ -100,6 +100,8 @@ dict set params TX_CPL_FIFO_DEPTH "32" dict set params TX_CHECKSUM_ENABLE "1" dict set params RX_HASH_ENABLE "1" dict set params RX_CHECKSUM_ENABLE "1" +dict set params PFC_ENABLE "1" +dict set params LFC_ENABLE [dict get $params PFC_ENABLE] dict set params TX_FIFO_DEPTH "32768" dict set params RX_FIFO_DEPTH "131072" dict set params MAX_TX_SIZE "9214" diff --git a/fpga/mqnic/DK_DEV_AGF014EA/fpga_100g/fpga_24AR0/config.tcl b/fpga/mqnic/DK_DEV_AGF014EA/fpga_100g/fpga_24AR0/config.tcl index b2d660077..7cc09c217 100644 --- a/fpga/mqnic/DK_DEV_AGF014EA/fpga_100g/fpga_24AR0/config.tcl +++ b/fpga/mqnic/DK_DEV_AGF014EA/fpga_100g/fpga_24AR0/config.tcl @@ -100,6 +100,8 @@ dict set params TX_CPL_FIFO_DEPTH "32" dict set params TX_CHECKSUM_ENABLE "1" dict set params RX_HASH_ENABLE "1" dict set params RX_CHECKSUM_ENABLE "1" +dict set params PFC_ENABLE "1" +dict set params LFC_ENABLE [dict get $params PFC_ENABLE] dict set params TX_FIFO_DEPTH "32768" dict set params RX_FIFO_DEPTH "131072" dict set params MAX_TX_SIZE "9214" diff --git a/fpga/mqnic/DK_DEV_AGF014EA/fpga_100g/fpga_app_dma_bench/config.tcl b/fpga/mqnic/DK_DEV_AGF014EA/fpga_100g/fpga_app_dma_bench/config.tcl index 492e8975c..2b8ebc5a0 100644 --- a/fpga/mqnic/DK_DEV_AGF014EA/fpga_100g/fpga_app_dma_bench/config.tcl +++ b/fpga/mqnic/DK_DEV_AGF014EA/fpga_100g/fpga_app_dma_bench/config.tcl @@ -100,6 +100,8 @@ dict set params TX_CPL_FIFO_DEPTH "32" dict set params TX_CHECKSUM_ENABLE "1" dict set params RX_HASH_ENABLE "1" dict set params RX_CHECKSUM_ENABLE "1" +dict set params PFC_ENABLE "1" +dict set params LFC_ENABLE [dict get $params PFC_ENABLE] dict set params TX_FIFO_DEPTH "32768" dict set params RX_FIFO_DEPTH "131072" dict set params MAX_TX_SIZE "9214" diff --git a/fpga/mqnic/DK_DEV_AGF014EA/fpga_100g/fpga_app_dma_bench_24AR0/config.tcl b/fpga/mqnic/DK_DEV_AGF014EA/fpga_100g/fpga_app_dma_bench_24AR0/config.tcl index 505281a7a..7c50bbd15 100644 --- a/fpga/mqnic/DK_DEV_AGF014EA/fpga_100g/fpga_app_dma_bench_24AR0/config.tcl +++ b/fpga/mqnic/DK_DEV_AGF014EA/fpga_100g/fpga_app_dma_bench_24AR0/config.tcl @@ -100,6 +100,8 @@ dict set params TX_CPL_FIFO_DEPTH "32" dict set params TX_CHECKSUM_ENABLE "1" dict set params RX_HASH_ENABLE "1" dict set params RX_CHECKSUM_ENABLE "1" +dict set params PFC_ENABLE "1" +dict set params LFC_ENABLE [dict get $params PFC_ENABLE] dict set params TX_FIFO_DEPTH "32768" dict set params RX_FIFO_DEPTH "131072" dict set params MAX_TX_SIZE "9214" diff --git a/fpga/mqnic/DK_DEV_AGF014EA/fpga_100g/rtl/eth_mac_dual_wrapper.v b/fpga/mqnic/DK_DEV_AGF014EA/fpga_100g/rtl/eth_mac_dual_wrapper.v index 326b3aa75..63978d10a 100644 --- a/fpga/mqnic/DK_DEV_AGF014EA/fpga_100g/rtl/eth_mac_dual_wrapper.v +++ b/fpga/mqnic/DK_DEV_AGF014EA/fpga_100g/rtl/eth_mac_dual_wrapper.v @@ -66,6 +66,10 @@ module eth_mac_dual_wrapper # input wire mac_1_tx_axis_tlast, input wire [TX_USER_WIDTH-1:0] mac_1_tx_axis_tuser, + output wire mac_1_tx_status, + input wire mac_1_tx_lfc_req, + input wire [7:0] mac_1_tx_pfc_req, + output wire [DATA_WIDTH-1:0] mac_1_rx_axis_tdata, output wire [KEEP_WIDTH-1:0] mac_1_rx_axis_tkeep, output wire mac_1_rx_axis_tvalid, @@ -73,6 +77,8 @@ module eth_mac_dual_wrapper # output wire [RX_USER_WIDTH-1:0] mac_1_rx_axis_tuser, output wire mac_1_rx_status, + output wire mac_1_rx_lfc_req, + output wire [7:0] mac_1_rx_pfc_req, output wire mac_2_clk, output wire mac_2_rst, @@ -90,13 +96,19 @@ module eth_mac_dual_wrapper # input wire mac_2_tx_axis_tlast, input wire [TX_USER_WIDTH-1:0] mac_2_tx_axis_tuser, + output wire mac_2_tx_status, + input wire mac_2_tx_lfc_req, + input wire [7:0] mac_2_tx_pfc_req, + output wire [DATA_WIDTH-1:0] mac_2_rx_axis_tdata, output wire [KEEP_WIDTH-1:0] mac_2_rx_axis_tkeep, output wire mac_2_rx_axis_tvalid, output wire mac_2_rx_axis_tlast, output wire [RX_USER_WIDTH-1:0] mac_2_rx_axis_tuser, - output wire mac_2_rx_status + output wire mac_2_rx_status, + output wire mac_2_rx_lfc_req, + output wire [7:0] mac_2_rx_pfc_req ); parameter N_CH = 2; @@ -146,6 +158,11 @@ wire [N_CH-1:0] mac_rx_endofpacket; wire [N_CH*6-1:0] mac_rx_empty; wire [N_CH*6-1:0] mac_rx_error; +wire [N_CH*8-1:0] mac_tx_pfc; +wire [N_CH*8-1:0] mac_rx_pfc; +wire [N_CH-1:0] mac_tx_pause; +wire [N_CH-1:0] mac_rx_pause; + mac_02 mac_02_inst ( .i_stats_snapshot (1'b0), .o_cdr_lock (), @@ -234,10 +251,10 @@ mac_02 mac_02_inst ( .o_rx_error (mac_rx_error[0*6 +: 6]), .o_rxstatus_data (), .o_rxstatus_valid (), - .i_tx_pfc (8'd0), - .o_rx_pfc (), - .i_tx_pause (1'b0), - .o_rx_pause () + .i_tx_pfc (mac_tx_pfc[0*8 +: 8]), + .o_rx_pfc (mac_rx_pfc[0*8 +: 8]), + .i_tx_pause (mac_tx_pause[0*1 +: 1]), + .o_rx_pause (mac_rx_pause[0*1 +: 1]) ); mac_13 mac_13_inst ( @@ -328,10 +345,10 @@ mac_13 mac_13_inst ( .o_rx_error (mac_rx_error[1*6 +: 6]), .o_rxstatus_data (), .o_rxstatus_valid (), - .i_tx_pfc (8'd0), - .o_rx_pfc (), - .i_tx_pause (1'b0), - .o_rx_pause () + .i_tx_pfc (mac_tx_pfc[1*8 +: 8]), + .o_rx_pfc (mac_rx_pfc[1*8 +: 8]), + .i_tx_pause (mac_tx_pause[1*1 +: 1]), + .o_rx_pause (mac_rx_pause[1*1 +: 1]) ); wire [N_CH*DATA_WIDTH-1:0] mac_rx_axis_tdata; @@ -366,13 +383,19 @@ assign mac_1_tx_axis_tready = mac_tx_axis_tready[0]; assign mac_tx_axis_tlast[0] = mac_1_tx_axis_tlast; assign mac_tx_axis_tuser[0*TX_USER_WIDTH +: TX_USER_WIDTH] = mac_1_tx_axis_tuser; +assign mac_1_tx_status = mac_tx_lanes_stable[0*1 +: 1]; +assign mac_tx_pause[0*1 +: 1] = mac_1_tx_lfc_req; +assign mac_tx_pfc[0*8 +: 8] = mac_1_tx_pfc_req; + assign mac_1_rx_axis_tdata = mac_rx_axis_tdata[0*DATA_WIDTH +: DATA_WIDTH]; assign mac_1_rx_axis_tkeep = mac_rx_axis_tkeep[0*KEEP_WIDTH +: KEEP_WIDTH]; assign mac_1_rx_axis_tvalid = mac_rx_axis_tvalid[0]; assign mac_1_rx_axis_tlast = mac_rx_axis_tlast[0]; assign mac_1_rx_axis_tuser = mac_rx_axis_tuser[0*RX_USER_WIDTH +: RX_USER_WIDTH]; -assign mac_1_rx_status = mac_rx_pcs_ready[0]; +assign mac_1_rx_status = mac_rx_pcs_ready[0*1 +: 1]; +assign mac_1_rx_lfc_req = mac_rx_pause[0*1 +: 1]; +assign mac_1_rx_pfc_req = mac_rx_pfc[0*8 +: 8]; assign mac_2_clk = mac_clk[1]; assign mac_2_rst = mac_rst[1]; @@ -390,13 +413,19 @@ assign mac_2_tx_axis_tready = mac_tx_axis_tready[1]; assign mac_tx_axis_tlast[1] = mac_2_tx_axis_tlast; assign mac_tx_axis_tuser[1*TX_USER_WIDTH +: TX_USER_WIDTH] = mac_2_tx_axis_tuser; +assign mac_2_tx_status = mac_tx_lanes_stable[1*1 +: 1]; +assign mac_tx_pause[1*1 +: 1] = mac_2_tx_lfc_req; +assign mac_tx_pfc[1*8 +: 8] = mac_2_tx_pfc_req; + assign mac_2_rx_axis_tdata = mac_rx_axis_tdata[1*DATA_WIDTH +: DATA_WIDTH]; assign mac_2_rx_axis_tkeep = mac_rx_axis_tkeep[1*KEEP_WIDTH +: KEEP_WIDTH]; assign mac_2_rx_axis_tvalid = mac_rx_axis_tvalid[1]; assign mac_2_rx_axis_tlast = mac_rx_axis_tlast[1]; assign mac_2_rx_axis_tuser = mac_rx_axis_tuser[1*RX_USER_WIDTH +: RX_USER_WIDTH]; -assign mac_2_rx_status = mac_rx_pcs_ready[1]; +assign mac_2_rx_status = mac_rx_pcs_ready[1*1 +: 1]; +assign mac_2_rx_lfc_req = mac_rx_pause[1*1 +: 1]; +assign mac_2_rx_pfc_req = mac_rx_pfc[1*8 +: 8]; generate diff --git a/fpga/mqnic/DK_DEV_AGF014EA/fpga_100g/rtl/fpga.v b/fpga/mqnic/DK_DEV_AGF014EA/fpga_100g/rtl/fpga.v index 42f943a32..f9d76a06a 100644 --- a/fpga/mqnic/DK_DEV_AGF014EA/fpga_100g/rtl/fpga.v +++ b/fpga/mqnic/DK_DEV_AGF014EA/fpga_100g/rtl/fpga.v @@ -71,6 +71,8 @@ module fpga # parameter TX_CHECKSUM_ENABLE = 1, parameter RX_HASH_ENABLE = 1, parameter RX_CHECKSUM_ENABLE = 1, + parameter PFC_ENABLE = 1, + parameter LFC_ENABLE = PFC_ENABLE, parameter TX_FIFO_DEPTH = 32768, parameter RX_FIFO_DEPTH = 131072, parameter MAX_TX_SIZE = 9214, @@ -444,7 +446,7 @@ pcie pcie_hip_inst ( // QSFP28 interfaces -// QSFP-DD A +// QSFP-DD 0 wire qsfpdd0_mac_1_clk_int; wire qsfpdd0_mac_1_rst_int; @@ -461,6 +463,10 @@ wire qsfpdd0_mac_1_tx_axis_tready_int; wire qsfpdd0_mac_1_tx_axis_tlast_int; wire [AXIS_ETH_TX_USER_WIDTH-1:0] qsfpdd0_mac_1_tx_axis_tuser_int; +wire qsfpdd0_mac_1_tx_status_int; +wire qsfpdd0_mac_1_tx_lfc_req_int; +wire [7:0] qsfpdd0_mac_1_tx_pfc_req_int; + wire [AXIS_ETH_DATA_WIDTH-1:0] qsfpdd0_mac_1_rx_axis_tdata_int; wire [AXIS_ETH_KEEP_WIDTH-1:0] qsfpdd0_mac_1_rx_axis_tkeep_int; wire qsfpdd0_mac_1_rx_axis_tvalid_int; @@ -468,6 +474,8 @@ wire qsfpdd0_mac_1_rx_axis_tlast_int; wire [AXIS_ETH_RX_USER_WIDTH-1:0] qsfpdd0_mac_1_rx_axis_tuser_int; wire qsfpdd0_mac_1_rx_status_int; +wire qsfpdd0_mac_1_rx_lfc_req_int; +wire [7:0] qsfpdd0_mac_1_rx_pfc_req_int; wire qsfpdd0_mac_2_clk_int; wire qsfpdd0_mac_2_rst_int; @@ -485,6 +493,10 @@ wire qsfpdd0_mac_2_tx_axis_tready_int; wire qsfpdd0_mac_2_tx_axis_tlast_int; wire [AXIS_ETH_TX_USER_WIDTH-1:0] qsfpdd0_mac_2_tx_axis_tuser_int; +wire qsfpdd0_mac_2_tx_status_int; +wire qsfpdd0_mac_2_tx_lfc_req_int; +wire [7:0] qsfpdd0_mac_2_tx_pfc_req_int; + wire [AXIS_ETH_DATA_WIDTH-1:0] qsfpdd0_mac_2_rx_axis_tdata_int; wire [AXIS_ETH_KEEP_WIDTH-1:0] qsfpdd0_mac_2_rx_axis_tkeep_int; wire qsfpdd0_mac_2_rx_axis_tvalid_int; @@ -492,6 +504,8 @@ wire qsfpdd0_mac_2_rx_axis_tlast_int; wire [AXIS_ETH_RX_USER_WIDTH-1:0] qsfpdd0_mac_2_rx_axis_tuser_int; wire qsfpdd0_mac_2_rx_status_int; +wire qsfpdd0_mac_2_rx_lfc_req_int; +wire [7:0] qsfpdd0_mac_2_rx_pfc_req_int; eth_mac_dual_wrapper #( .PTP_TS_WIDTH(PTP_TS_WIDTH), @@ -527,6 +541,10 @@ qsfpdd0_mac_inst ( .mac_1_tx_axis_tlast(qsfpdd0_mac_1_tx_axis_tlast_int), .mac_1_tx_axis_tuser(qsfpdd0_mac_1_tx_axis_tuser_int), + .mac_1_tx_status(qsfpdd0_mac_1_tx_status_int), + .mac_1_tx_lfc_req(qsfpdd0_mac_1_tx_lfc_req_int), + .mac_1_tx_pfc_req(qsfpdd0_mac_1_tx_pfc_req_int), + .mac_1_rx_axis_tdata(qsfpdd0_mac_1_rx_axis_tdata_int), .mac_1_rx_axis_tkeep(qsfpdd0_mac_1_rx_axis_tkeep_int), .mac_1_rx_axis_tvalid(qsfpdd0_mac_1_rx_axis_tvalid_int), @@ -534,6 +552,8 @@ qsfpdd0_mac_inst ( .mac_1_rx_axis_tuser(qsfpdd0_mac_1_rx_axis_tuser_int), .mac_1_rx_status(qsfpdd0_mac_1_rx_status_int), + .mac_1_rx_lfc_req(qsfpdd0_mac_1_rx_lfc_req_int), + .mac_1_rx_pfc_req(qsfpdd0_mac_1_rx_pfc_req_int), .mac_2_clk(qsfpdd0_mac_2_clk_int), .mac_2_rst(qsfpdd0_mac_2_rst_int), @@ -551,16 +571,22 @@ qsfpdd0_mac_inst ( .mac_2_tx_axis_tlast(qsfpdd0_mac_2_tx_axis_tlast_int), .mac_2_tx_axis_tuser(qsfpdd0_mac_2_tx_axis_tuser_int), + .mac_2_tx_status(qsfpdd0_mac_2_tx_status_int), + .mac_2_tx_lfc_req(qsfpdd0_mac_2_tx_lfc_req_int), + .mac_2_tx_pfc_req(qsfpdd0_mac_2_tx_pfc_req_int), + .mac_2_rx_axis_tdata(qsfpdd0_mac_2_rx_axis_tdata_int), .mac_2_rx_axis_tkeep(qsfpdd0_mac_2_rx_axis_tkeep_int), .mac_2_rx_axis_tvalid(qsfpdd0_mac_2_rx_axis_tvalid_int), .mac_2_rx_axis_tlast(qsfpdd0_mac_2_rx_axis_tlast_int), .mac_2_rx_axis_tuser(qsfpdd0_mac_2_rx_axis_tuser_int), - .mac_2_rx_status(qsfpdd0_mac_2_rx_status_int) + .mac_2_rx_status(qsfpdd0_mac_2_rx_status_int), + .mac_2_rx_lfc_req(qsfpdd0_mac_2_rx_lfc_req_int), + .mac_2_rx_pfc_req(qsfpdd0_mac_2_rx_pfc_req_int) ); -// QSFP-DD B +// QSFP-DD 1 wire qsfpdd1_mac_1_clk_int; wire qsfpdd1_mac_1_rst_int; @@ -577,6 +603,10 @@ wire qsfpdd1_mac_1_tx_axis_tready_int; wire qsfpdd1_mac_1_tx_axis_tlast_int; wire [AXIS_ETH_TX_USER_WIDTH-1:0] qsfpdd1_mac_1_tx_axis_tuser_int; +wire qsfpdd1_mac_1_tx_status_int; +wire qsfpdd1_mac_1_tx_lfc_req_int; +wire [7:0] qsfpdd1_mac_1_tx_pfc_req_int; + wire [AXIS_ETH_DATA_WIDTH-1:0] qsfpdd1_mac_1_rx_axis_tdata_int; wire [AXIS_ETH_KEEP_WIDTH-1:0] qsfpdd1_mac_1_rx_axis_tkeep_int; wire qsfpdd1_mac_1_rx_axis_tvalid_int; @@ -584,6 +614,8 @@ wire qsfpdd1_mac_1_rx_axis_tlast_int; wire [AXIS_ETH_RX_USER_WIDTH-1:0] qsfpdd1_mac_1_rx_axis_tuser_int; wire qsfpdd1_mac_1_rx_status_int; +wire qsfpdd1_mac_1_rx_lfc_req_int; +wire [7:0] qsfpdd1_mac_1_rx_pfc_req_int; wire qsfpdd1_mac_2_clk_int; wire qsfpdd1_mac_2_rst_int; @@ -601,6 +633,10 @@ wire qsfpdd1_mac_2_tx_axis_tready_int; wire qsfpdd1_mac_2_tx_axis_tlast_int; wire [AXIS_ETH_TX_USER_WIDTH-1:0] qsfpdd1_mac_2_tx_axis_tuser_int; +wire qsfpdd1_mac_2_tx_status_int; +wire qsfpdd1_mac_2_tx_lfc_req_int; +wire [7:0] qsfpdd1_mac_2_tx_pfc_req_int; + wire [AXIS_ETH_DATA_WIDTH-1:0] qsfpdd1_mac_2_rx_axis_tdata_int; wire [AXIS_ETH_KEEP_WIDTH-1:0] qsfpdd1_mac_2_rx_axis_tkeep_int; wire qsfpdd1_mac_2_rx_axis_tvalid_int; @@ -608,6 +644,8 @@ wire qsfpdd1_mac_2_rx_axis_tlast_int; wire [AXIS_ETH_RX_USER_WIDTH-1:0] qsfpdd1_mac_2_rx_axis_tuser_int; wire qsfpdd1_mac_2_rx_status_int; +wire qsfpdd1_mac_2_rx_lfc_req_int; +wire [7:0] qsfpdd1_mac_2_rx_pfc_req_int; eth_mac_dual_wrapper #( .PTP_TS_WIDTH(PTP_TS_WIDTH), @@ -643,6 +681,10 @@ qsfpdd1_mac_inst ( .mac_1_tx_axis_tlast(qsfpdd1_mac_1_tx_axis_tlast_int), .mac_1_tx_axis_tuser(qsfpdd1_mac_1_tx_axis_tuser_int), + .mac_1_tx_status(qsfpdd1_mac_1_tx_status_int), + .mac_1_tx_lfc_req(qsfpdd1_mac_1_tx_lfc_req_int), + .mac_1_tx_pfc_req(qsfpdd1_mac_1_tx_pfc_req_int), + .mac_1_rx_axis_tdata(qsfpdd1_mac_1_rx_axis_tdata_int), .mac_1_rx_axis_tkeep(qsfpdd1_mac_1_rx_axis_tkeep_int), .mac_1_rx_axis_tvalid(qsfpdd1_mac_1_rx_axis_tvalid_int), @@ -650,6 +692,8 @@ qsfpdd1_mac_inst ( .mac_1_rx_axis_tuser(qsfpdd1_mac_1_rx_axis_tuser_int), .mac_1_rx_status(qsfpdd1_mac_1_rx_status_int), + .mac_1_rx_lfc_req(qsfpdd1_mac_1_rx_lfc_req_int), + .mac_1_rx_pfc_req(qsfpdd1_mac_1_rx_pfc_req_int), .mac_2_clk(qsfpdd1_mac_2_clk_int), .mac_2_rst(qsfpdd1_mac_2_rst_int), @@ -667,13 +711,19 @@ qsfpdd1_mac_inst ( .mac_2_tx_axis_tlast(qsfpdd1_mac_2_tx_axis_tlast_int), .mac_2_tx_axis_tuser(qsfpdd1_mac_2_tx_axis_tuser_int), + .mac_2_tx_status(qsfpdd1_mac_2_tx_status_int), + .mac_2_tx_lfc_req(qsfpdd1_mac_2_tx_lfc_req_int), + .mac_2_tx_pfc_req(qsfpdd1_mac_2_tx_pfc_req_int), + .mac_2_rx_axis_tdata(qsfpdd1_mac_2_rx_axis_tdata_int), .mac_2_rx_axis_tkeep(qsfpdd1_mac_2_rx_axis_tkeep_int), .mac_2_rx_axis_tvalid(qsfpdd1_mac_2_rx_axis_tvalid_int), .mac_2_rx_axis_tlast(qsfpdd1_mac_2_rx_axis_tlast_int), .mac_2_rx_axis_tuser(qsfpdd1_mac_2_rx_axis_tuser_int), - .mac_2_rx_status(qsfpdd1_mac_2_rx_status_int) + .mac_2_rx_status(qsfpdd1_mac_2_rx_status_int), + .mac_2_rx_lfc_req(qsfpdd1_mac_2_rx_lfc_req_int), + .mac_2_rx_pfc_req(qsfpdd1_mac_2_rx_pfc_req_int) ); wire ptp_clk; @@ -748,6 +798,8 @@ fpga_core #( .TX_CHECKSUM_ENABLE(TX_CHECKSUM_ENABLE), .RX_HASH_ENABLE(RX_HASH_ENABLE), .RX_CHECKSUM_ENABLE(RX_CHECKSUM_ENABLE), + .PFC_ENABLE(PFC_ENABLE), + .LFC_ENABLE(LFC_ENABLE), .TX_FIFO_DEPTH(TX_FIFO_DEPTH), .RX_FIFO_DEPTH(RX_FIFO_DEPTH), .MAX_TX_SIZE(MAX_TX_SIZE), @@ -905,6 +957,10 @@ core_inst ( .qsfpdd0_mac_1_tx_axis_tlast(qsfpdd0_mac_1_tx_axis_tlast_int), .qsfpdd0_mac_1_tx_axis_tuser(qsfpdd0_mac_1_tx_axis_tuser_int), + .qsfpdd0_mac_1_tx_status(qsfpdd0_mac_1_tx_status_int), + .qsfpdd0_mac_1_tx_lfc_req(qsfpdd0_mac_1_tx_lfc_req_int), + .qsfpdd0_mac_1_tx_pfc_req(qsfpdd0_mac_1_tx_pfc_req_int), + .qsfpdd0_mac_1_rx_axis_tdata(qsfpdd0_mac_1_rx_axis_tdata_int), .qsfpdd0_mac_1_rx_axis_tkeep(qsfpdd0_mac_1_rx_axis_tkeep_int), .qsfpdd0_mac_1_rx_axis_tvalid(qsfpdd0_mac_1_rx_axis_tvalid_int), @@ -912,6 +968,8 @@ core_inst ( .qsfpdd0_mac_1_rx_axis_tuser(qsfpdd0_mac_1_rx_axis_tuser_int), .qsfpdd0_mac_1_rx_status(qsfpdd0_mac_1_rx_status_int), + .qsfpdd0_mac_1_rx_lfc_req(qsfpdd0_mac_1_rx_lfc_req_int), + .qsfpdd0_mac_1_rx_pfc_req(qsfpdd0_mac_1_rx_pfc_req_int), .qsfpdd0_mac_2_clk(qsfpdd0_mac_2_clk_int), .qsfpdd0_mac_2_rst(qsfpdd0_mac_2_rst_int), @@ -929,6 +987,10 @@ core_inst ( .qsfpdd0_mac_2_tx_axis_tlast(qsfpdd0_mac_2_tx_axis_tlast_int), .qsfpdd0_mac_2_tx_axis_tuser(qsfpdd0_mac_2_tx_axis_tuser_int), + .qsfpdd0_mac_2_tx_status(qsfpdd0_mac_2_tx_status_int), + .qsfpdd0_mac_2_tx_lfc_req(qsfpdd0_mac_2_tx_lfc_req_int), + .qsfpdd0_mac_2_tx_pfc_req(qsfpdd0_mac_2_tx_pfc_req_int), + .qsfpdd0_mac_2_rx_axis_tdata(qsfpdd0_mac_2_rx_axis_tdata_int), .qsfpdd0_mac_2_rx_axis_tkeep(qsfpdd0_mac_2_rx_axis_tkeep_int), .qsfpdd0_mac_2_rx_axis_tvalid(qsfpdd0_mac_2_rx_axis_tvalid_int), @@ -936,6 +998,8 @@ core_inst ( .qsfpdd0_mac_2_rx_axis_tuser(qsfpdd0_mac_2_rx_axis_tuser_int), .qsfpdd0_mac_2_rx_status(qsfpdd0_mac_2_rx_status_int), + .qsfpdd0_mac_2_rx_lfc_req(qsfpdd0_mac_2_rx_lfc_req_int), + .qsfpdd0_mac_2_rx_pfc_req(qsfpdd0_mac_2_rx_pfc_req_int), .qsfpdd1_mac_1_clk(qsfpdd1_mac_1_clk_int), .qsfpdd1_mac_1_rst(qsfpdd1_mac_1_rst_int), @@ -953,6 +1017,10 @@ core_inst ( .qsfpdd1_mac_1_tx_axis_tlast(qsfpdd1_mac_1_tx_axis_tlast_int), .qsfpdd1_mac_1_tx_axis_tuser(qsfpdd1_mac_1_tx_axis_tuser_int), + .qsfpdd1_mac_1_tx_status(qsfpdd1_mac_1_tx_status_int), + .qsfpdd1_mac_1_tx_lfc_req(qsfpdd1_mac_1_tx_lfc_req_int), + .qsfpdd1_mac_1_tx_pfc_req(qsfpdd1_mac_1_tx_pfc_req_int), + .qsfpdd1_mac_1_rx_axis_tdata(qsfpdd1_mac_1_rx_axis_tdata_int), .qsfpdd1_mac_1_rx_axis_tkeep(qsfpdd1_mac_1_rx_axis_tkeep_int), .qsfpdd1_mac_1_rx_axis_tvalid(qsfpdd1_mac_1_rx_axis_tvalid_int), @@ -960,6 +1028,8 @@ core_inst ( .qsfpdd1_mac_1_rx_axis_tuser(qsfpdd1_mac_1_rx_axis_tuser_int), .qsfpdd1_mac_1_rx_status(qsfpdd1_mac_1_rx_status_int), + .qsfpdd1_mac_1_rx_lfc_req(qsfpdd1_mac_1_rx_lfc_req_int), + .qsfpdd1_mac_1_rx_pfc_req(qsfpdd1_mac_1_rx_pfc_req_int), .qsfpdd1_mac_2_clk(qsfpdd1_mac_2_clk_int), .qsfpdd1_mac_2_rst(qsfpdd1_mac_2_rst_int), @@ -977,6 +1047,10 @@ core_inst ( .qsfpdd1_mac_2_tx_axis_tlast(qsfpdd1_mac_2_tx_axis_tlast_int), .qsfpdd1_mac_2_tx_axis_tuser(qsfpdd1_mac_2_tx_axis_tuser_int), + .qsfpdd1_mac_2_tx_status(qsfpdd1_mac_2_tx_status_int), + .qsfpdd1_mac_2_tx_lfc_req(qsfpdd1_mac_2_tx_lfc_req_int), + .qsfpdd1_mac_2_tx_pfc_req(qsfpdd1_mac_2_tx_pfc_req_int), + .qsfpdd1_mac_2_rx_axis_tdata(qsfpdd1_mac_2_rx_axis_tdata_int), .qsfpdd1_mac_2_rx_axis_tkeep(qsfpdd1_mac_2_rx_axis_tkeep_int), .qsfpdd1_mac_2_rx_axis_tvalid(qsfpdd1_mac_2_rx_axis_tvalid_int), @@ -984,6 +1058,8 @@ core_inst ( .qsfpdd1_mac_2_rx_axis_tuser(qsfpdd1_mac_2_rx_axis_tuser_int), .qsfpdd1_mac_2_rx_status(qsfpdd1_mac_2_rx_status_int), + .qsfpdd1_mac_2_rx_lfc_req(qsfpdd1_mac_2_rx_lfc_req_int), + .qsfpdd1_mac_2_rx_pfc_req(qsfpdd1_mac_2_rx_pfc_req_int), .qsfpdd0_modsel_l(qsfpdd0_modsel_l), .qsfpdd0_reset_l(qsfpdd0_reset_l), diff --git a/fpga/mqnic/DK_DEV_AGF014EA/fpga_100g/rtl/fpga_core.v b/fpga/mqnic/DK_DEV_AGF014EA/fpga_100g/rtl/fpga_core.v index 324e2eb68..5bc1b2640 100644 --- a/fpga/mqnic/DK_DEV_AGF014EA/fpga_100g/rtl/fpga_core.v +++ b/fpga/mqnic/DK_DEV_AGF014EA/fpga_100g/rtl/fpga_core.v @@ -76,9 +76,8 @@ module fpga_core # parameter TX_CHECKSUM_ENABLE = 1, parameter RX_HASH_ENABLE = 1, parameter RX_CHECKSUM_ENABLE = 1, - parameter ENABLE_PADDING = 1, - parameter ENABLE_DIC = 1, - parameter MIN_FRAME_LENGTH = 64, + parameter PFC_ENABLE = 1, + parameter LFC_ENABLE = PFC_ENABLE, parameter TX_FIFO_DEPTH = 32768, parameter RX_FIFO_DEPTH = 131072, parameter MAX_TX_SIZE = 9214, @@ -236,6 +235,10 @@ module fpga_core # output wire qsfpdd0_mac_1_tx_axis_tlast, output wire [AXIS_ETH_TX_USER_WIDTH-1:0] qsfpdd0_mac_1_tx_axis_tuser, + input wire qsfpdd0_mac_1_tx_status, + output wire qsfpdd0_mac_1_tx_lfc_req, + output wire [7:0] qsfpdd0_mac_1_tx_pfc_req, + input wire [AXIS_ETH_DATA_WIDTH-1:0] qsfpdd0_mac_1_rx_axis_tdata, input wire [AXIS_ETH_KEEP_WIDTH-1:0] qsfpdd0_mac_1_rx_axis_tkeep, input wire qsfpdd0_mac_1_rx_axis_tvalid, @@ -243,6 +246,8 @@ module fpga_core # input wire [AXIS_ETH_RX_USER_WIDTH-1:0] qsfpdd0_mac_1_rx_axis_tuser, input wire qsfpdd0_mac_1_rx_status, + input wire qsfpdd0_mac_1_rx_lfc_req, + input wire [7:0] qsfpdd0_mac_1_rx_pfc_req, input wire qsfpdd0_mac_2_clk, input wire qsfpdd0_mac_2_rst, @@ -260,6 +265,10 @@ module fpga_core # output wire qsfpdd0_mac_2_tx_axis_tlast, output wire [AXIS_ETH_TX_USER_WIDTH-1:0] qsfpdd0_mac_2_tx_axis_tuser, + input wire qsfpdd0_mac_2_tx_status, + output wire qsfpdd0_mac_2_tx_lfc_req, + output wire [7:0] qsfpdd0_mac_2_tx_pfc_req, + input wire [AXIS_ETH_DATA_WIDTH-1:0] qsfpdd0_mac_2_rx_axis_tdata, input wire [AXIS_ETH_KEEP_WIDTH-1:0] qsfpdd0_mac_2_rx_axis_tkeep, input wire qsfpdd0_mac_2_rx_axis_tvalid, @@ -267,6 +276,8 @@ module fpga_core # input wire [AXIS_ETH_RX_USER_WIDTH-1:0] qsfpdd0_mac_2_rx_axis_tuser, input wire qsfpdd0_mac_2_rx_status, + input wire qsfpdd0_mac_2_rx_lfc_req, + input wire [7:0] qsfpdd0_mac_2_rx_pfc_req, input wire qsfpdd1_mac_1_clk, input wire qsfpdd1_mac_1_rst, @@ -284,6 +295,10 @@ module fpga_core # output wire qsfpdd1_mac_1_tx_axis_tlast, output wire [AXIS_ETH_TX_USER_WIDTH-1:0] qsfpdd1_mac_1_tx_axis_tuser, + input wire qsfpdd1_mac_1_tx_status, + output wire qsfpdd1_mac_1_tx_lfc_req, + output wire [7:0] qsfpdd1_mac_1_tx_pfc_req, + input wire [AXIS_ETH_DATA_WIDTH-1:0] qsfpdd1_mac_1_rx_axis_tdata, input wire [AXIS_ETH_KEEP_WIDTH-1:0] qsfpdd1_mac_1_rx_axis_tkeep, input wire qsfpdd1_mac_1_rx_axis_tvalid, @@ -291,6 +306,8 @@ module fpga_core # input wire [AXIS_ETH_RX_USER_WIDTH-1:0] qsfpdd1_mac_1_rx_axis_tuser, input wire qsfpdd1_mac_1_rx_status, + input wire qsfpdd1_mac_1_rx_lfc_req, + input wire [7:0] qsfpdd1_mac_1_rx_pfc_req, input wire qsfpdd1_mac_2_clk, input wire qsfpdd1_mac_2_rst, @@ -308,6 +325,10 @@ module fpga_core # output wire qsfpdd1_mac_2_tx_axis_tlast, output wire [AXIS_ETH_TX_USER_WIDTH-1:0] qsfpdd1_mac_2_tx_axis_tuser, + input wire qsfpdd1_mac_2_tx_status, + output wire qsfpdd1_mac_2_tx_lfc_req, + output wire [7:0] qsfpdd1_mac_2_tx_pfc_req, + input wire [AXIS_ETH_DATA_WIDTH-1:0] qsfpdd1_mac_2_rx_axis_tdata, input wire [AXIS_ETH_KEEP_WIDTH-1:0] qsfpdd1_mac_2_rx_axis_tkeep, input wire qsfpdd1_mac_2_rx_axis_tvalid, @@ -315,6 +336,8 @@ module fpga_core # input wire [AXIS_ETH_RX_USER_WIDTH-1:0] qsfpdd1_mac_2_rx_axis_tuser, input wire qsfpdd1_mac_2_rx_status, + input wire qsfpdd1_mac_2_rx_lfc_req, + input wire [7:0] qsfpdd1_mac_2_rx_pfc_req, output wire qsfpdd0_modsel_l, output wire qsfpdd0_reset_l, @@ -613,7 +636,12 @@ wire [PORT_COUNT*TX_TAG_WIDTH-1:0] axis_eth_tx_ptp_ts_tag; wire [PORT_COUNT-1:0] axis_eth_tx_ptp_ts_valid; wire [PORT_COUNT-1:0] axis_eth_tx_ptp_ts_ready; +wire [PORT_COUNT-1:0] eth_tx_enable; wire [PORT_COUNT-1:0] eth_tx_status; +wire [PORT_COUNT-1:0] eth_tx_lfc_en; +wire [PORT_COUNT-1:0] eth_tx_lfc_req; +wire [PORT_COUNT*8-1:0] eth_tx_pfc_en; +wire [PORT_COUNT*8-1:0] eth_tx_pfc_req; wire [PORT_COUNT-1:0] eth_rx_clk; wire [PORT_COUNT-1:0] eth_rx_rst; @@ -630,7 +658,14 @@ wire [PORT_COUNT-1:0] axis_eth_rx_tready; wire [PORT_COUNT-1:0] axis_eth_rx_tlast; wire [PORT_COUNT*AXIS_ETH_RX_USER_WIDTH-1:0] axis_eth_rx_tuser; +wire [PORT_COUNT-1:0] eth_rx_enable; wire [PORT_COUNT-1:0] eth_rx_status; +wire [PORT_COUNT-1:0] eth_rx_lfc_en; +wire [PORT_COUNT-1:0] eth_rx_lfc_req; +wire [PORT_COUNT-1:0] eth_rx_lfc_ack; +wire [PORT_COUNT*8-1:0] eth_rx_pfc_en; +wire [PORT_COUNT*8-1:0] eth_rx_pfc_req; +wire [PORT_COUNT*8-1:0] eth_rx_pfc_ack; mqnic_port_map_mac_axis #( .MAC_COUNT(4), @@ -671,7 +706,12 @@ mqnic_port_map_mac_axis_inst ( .s_axis_mac_tx_ptp_ts_valid({qsfpdd1_mac_2_tx_ptp_ts_valid, qsfpdd1_mac_1_tx_ptp_ts_valid, qsfpdd0_mac_2_tx_ptp_ts_valid, qsfpdd0_mac_1_tx_ptp_ts_valid}), .s_axis_mac_tx_ptp_ts_ready(), - .mac_tx_status(4'hf), + .mac_tx_enable(), + .mac_tx_status({qsfpdd1_mac_2_tx_status, qsfpdd1_mac_1_tx_status, qsfpdd0_mac_2_tx_status, qsfpdd0_mac_1_tx_status}), + .mac_tx_lfc_en(), + .mac_tx_lfc_req({qsfpdd1_mac_2_tx_lfc_req, qsfpdd1_mac_1_tx_lfc_req, qsfpdd0_mac_2_tx_lfc_req, qsfpdd0_mac_1_tx_lfc_req}), + .mac_tx_pfc_en(), + .mac_tx_pfc_req({qsfpdd1_mac_2_tx_pfc_req, qsfpdd1_mac_1_tx_pfc_req, qsfpdd0_mac_2_tx_pfc_req, qsfpdd0_mac_1_tx_pfc_req}), .mac_rx_clk({qsfpdd1_mac_2_clk, qsfpdd1_mac_1_clk, qsfpdd0_mac_2_clk, qsfpdd0_mac_1_clk}), .mac_rx_rst({qsfpdd1_mac_2_rst, qsfpdd1_mac_1_rst, qsfpdd0_mac_2_rst, qsfpdd0_mac_1_rst}), @@ -688,7 +728,14 @@ mqnic_port_map_mac_axis_inst ( .s_axis_mac_rx_tlast({qsfpdd1_mac_2_rx_axis_tlast, qsfpdd1_mac_1_rx_axis_tlast, qsfpdd0_mac_2_rx_axis_tlast, qsfpdd0_mac_1_rx_axis_tlast}), .s_axis_mac_rx_tuser({qsfpdd1_mac_2_rx_axis_tuser, qsfpdd1_mac_1_rx_axis_tuser, qsfpdd0_mac_2_rx_axis_tuser, qsfpdd0_mac_1_rx_axis_tuser}), + .mac_rx_enable(), .mac_rx_status({qsfpdd1_mac_2_rx_status, qsfpdd1_mac_1_rx_status, qsfpdd0_mac_2_rx_status, qsfpdd0_mac_1_rx_status}), + .mac_rx_lfc_en(), + .mac_rx_lfc_req({qsfpdd1_mac_2_rx_lfc_req, qsfpdd1_mac_1_rx_lfc_req, qsfpdd0_mac_2_rx_lfc_req, qsfpdd0_mac_1_rx_lfc_req}), + .mac_rx_lfc_ack(), + .mac_rx_pfc_en(), + .mac_rx_pfc_req({qsfpdd1_mac_2_rx_pfc_req, qsfpdd1_mac_1_rx_pfc_req, qsfpdd0_mac_2_rx_pfc_req, qsfpdd0_mac_1_rx_pfc_req}), + .mac_rx_pfc_ack(), // towards datapath .tx_clk(eth_tx_clk), @@ -711,7 +758,12 @@ mqnic_port_map_mac_axis_inst ( .m_axis_tx_ptp_ts_valid(axis_eth_tx_ptp_ts_valid), .m_axis_tx_ptp_ts_ready(axis_eth_tx_ptp_ts_ready), + .tx_enable(eth_tx_enable), .tx_status(eth_tx_status), + .tx_lfc_en(eth_tx_lfc_en), + .tx_lfc_req(eth_tx_lfc_req), + .tx_pfc_en(eth_tx_pfc_en), + .tx_pfc_req(eth_tx_pfc_req), .rx_clk(eth_rx_clk), .rx_rst(eth_rx_rst), @@ -728,7 +780,14 @@ mqnic_port_map_mac_axis_inst ( .m_axis_rx_tlast(axis_eth_rx_tlast), .m_axis_rx_tuser(axis_eth_rx_tuser), - .rx_status(eth_rx_status) + .rx_enable(eth_rx_enable), + .rx_status(eth_rx_status), + .rx_lfc_en(eth_rx_lfc_en), + .rx_lfc_req(eth_rx_lfc_req), + .rx_lfc_ack(eth_rx_lfc_ack), + .rx_pfc_en(eth_rx_pfc_en), + .rx_pfc_req(eth_rx_pfc_req), + .rx_pfc_ack(eth_rx_pfc_ack) ); mqnic_core_pcie_ptile #( @@ -798,6 +857,9 @@ mqnic_core_pcie_ptile #( .TX_CHECKSUM_ENABLE(TX_CHECKSUM_ENABLE), .RX_HASH_ENABLE(RX_HASH_ENABLE), .RX_CHECKSUM_ENABLE(RX_CHECKSUM_ENABLE), + .PFC_ENABLE(PFC_ENABLE), + .LFC_ENABLE(LFC_ENABLE), + .MAC_CTRL_ENABLE(0), .TX_FIFO_DEPTH(TX_FIFO_DEPTH), .RX_FIFO_DEPTH(RX_FIFO_DEPTH), .MAX_TX_SIZE(MAX_TX_SIZE), @@ -1007,7 +1069,13 @@ core_inst ( .s_axis_eth_tx_cpl_valid(axis_eth_tx_ptp_ts_valid), .s_axis_eth_tx_cpl_ready(axis_eth_tx_ptp_ts_ready), + .eth_tx_enable(eth_tx_enable), .eth_tx_status(eth_tx_status), + .eth_tx_lfc_en(eth_tx_lfc_en), + .eth_tx_lfc_req(eth_tx_lfc_req), + .eth_tx_pfc_en(eth_tx_pfc_en), + .eth_tx_pfc_req(eth_tx_pfc_req), + .eth_tx_fc_quanta_clk_en(0), .eth_rx_clk(eth_rx_clk), .eth_rx_rst(eth_rx_rst), @@ -1024,7 +1092,15 @@ core_inst ( .s_axis_eth_rx_tlast(axis_eth_rx_tlast), .s_axis_eth_rx_tuser(axis_eth_rx_tuser), + .eth_rx_enable(eth_rx_enable), .eth_rx_status(eth_rx_status), + .eth_rx_lfc_en(eth_rx_lfc_en), + .eth_rx_lfc_req(eth_rx_lfc_req), + .eth_rx_lfc_ack(eth_rx_lfc_ack), + .eth_rx_pfc_en(eth_rx_pfc_en), + .eth_rx_pfc_req(eth_rx_pfc_req), + .eth_rx_pfc_ack(eth_rx_pfc_ack), + .eth_rx_fc_quanta_clk_en(0), /* * DDR diff --git a/fpga/mqnic/DK_DEV_AGF014EA/fpga_100g/tb/fpga_core/Makefile b/fpga/mqnic/DK_DEV_AGF014EA/fpga_100g/tb/fpga_core/Makefile index 6ac8b7ad4..1423ef2ca 100644 --- a/fpga/mqnic/DK_DEV_AGF014EA/fpga_100g/tb/fpga_core/Makefile +++ b/fpga/mqnic/DK_DEV_AGF014EA/fpga_100g/tb/fpga_core/Makefile @@ -167,6 +167,8 @@ export PARAM_TX_CPL_FIFO_DEPTH := 32 export PARAM_TX_CHECKSUM_ENABLE := 1 export PARAM_RX_HASH_ENABLE := 1 export PARAM_RX_CHECKSUM_ENABLE := 1 +export PARAM_LFC_ENABLE := 1 +export PARAM_PFC_ENABLE := $(PARAM_LFC_ENABLE) export PARAM_TX_FIFO_DEPTH := 32768 export PARAM_RX_FIFO_DEPTH := 131072 export PARAM_MAX_TX_SIZE := 9214 diff --git a/fpga/mqnic/DK_DEV_AGF014EA/fpga_100g/tb/fpga_core/test_fpga_core.py b/fpga/mqnic/DK_DEV_AGF014EA/fpga_100g/tb/fpga_core/test_fpga_core.py index db38ce2ae..1cb6af34b 100644 --- a/fpga/mqnic/DK_DEV_AGF014EA/fpga_100g/tb/fpga_core/test_fpga_core.py +++ b/fpga/mqnic/DK_DEV_AGF014EA/fpga_100g/tb/fpga_core/test_fpga_core.py @@ -279,6 +279,8 @@ class TB(object): macs.append(mac) getattr(dut, f"qsfpdd{x}_mac_{y}_rx_status").setimmediatevalue(1) + getattr(dut, f"qsfpdd{x}_mac_{y}_rx_lfc_req").setimmediatevalue(0) + getattr(dut, f"qsfpdd{x}_mac_{y}_rx_pfc_req").setimmediatevalue(0) self.qsfpdd_mac.append(macs) @@ -703,6 +705,8 @@ def test_fpga_core(request): parameters['TX_CHECKSUM_ENABLE'] = 1 parameters['RX_HASH_ENABLE'] = 1 parameters['RX_CHECKSUM_ENABLE'] = 1 + parameters['LFC_ENABLE'] = 1 + parameters['PFC_ENABLE'] = parameters['LFC_ENABLE'] parameters['TX_FIFO_DEPTH'] = 32768 parameters['RX_FIFO_DEPTH'] = 131072 parameters['MAX_TX_SIZE'] = 9214 diff --git a/fpga/mqnic/DK_DEV_AGF014EA/fpga_25g/fpga/config.tcl b/fpga/mqnic/DK_DEV_AGF014EA/fpga_25g/fpga/config.tcl index ecd594799..0e1b8350f 100644 --- a/fpga/mqnic/DK_DEV_AGF014EA/fpga_25g/fpga/config.tcl +++ b/fpga/mqnic/DK_DEV_AGF014EA/fpga_25g/fpga/config.tcl @@ -100,6 +100,8 @@ dict set params TX_CPL_FIFO_DEPTH "32" dict set params TX_CHECKSUM_ENABLE "1" dict set params RX_HASH_ENABLE "1" dict set params RX_CHECKSUM_ENABLE "1" +dict set params PFC_ENABLE "1" +dict set params LFC_ENABLE [dict get $params PFC_ENABLE] dict set params TX_FIFO_DEPTH "32768" dict set params RX_FIFO_DEPTH "32768" dict set params MAX_TX_SIZE "9214" diff --git a/fpga/mqnic/DK_DEV_AGF014EA/fpga_25g/fpga_10g/config.tcl b/fpga/mqnic/DK_DEV_AGF014EA/fpga_25g/fpga_10g/config.tcl index f2fc545d5..bf7018385 100644 --- a/fpga/mqnic/DK_DEV_AGF014EA/fpga_25g/fpga_10g/config.tcl +++ b/fpga/mqnic/DK_DEV_AGF014EA/fpga_25g/fpga_10g/config.tcl @@ -100,6 +100,8 @@ dict set params TX_CPL_FIFO_DEPTH "32" dict set params TX_CHECKSUM_ENABLE "1" dict set params RX_HASH_ENABLE "1" dict set params RX_CHECKSUM_ENABLE "1" +dict set params PFC_ENABLE "1" +dict set params LFC_ENABLE [dict get $params PFC_ENABLE] dict set params TX_FIFO_DEPTH "32768" dict set params RX_FIFO_DEPTH "32768" dict set params MAX_TX_SIZE "9214" diff --git a/fpga/mqnic/DK_DEV_AGF014EA/fpga_25g/fpga_10g_24AR0/config.tcl b/fpga/mqnic/DK_DEV_AGF014EA/fpga_25g/fpga_10g_24AR0/config.tcl index c709eb5f5..d92687d58 100644 --- a/fpga/mqnic/DK_DEV_AGF014EA/fpga_25g/fpga_10g_24AR0/config.tcl +++ b/fpga/mqnic/DK_DEV_AGF014EA/fpga_25g/fpga_10g_24AR0/config.tcl @@ -100,6 +100,8 @@ dict set params TX_CPL_FIFO_DEPTH "32" dict set params TX_CHECKSUM_ENABLE "1" dict set params RX_HASH_ENABLE "1" dict set params RX_CHECKSUM_ENABLE "1" +dict set params PFC_ENABLE "1" +dict set params LFC_ENABLE [dict get $params PFC_ENABLE] dict set params TX_FIFO_DEPTH "32768" dict set params RX_FIFO_DEPTH "32768" dict set params MAX_TX_SIZE "9214" diff --git a/fpga/mqnic/DK_DEV_AGF014EA/fpga_25g/fpga_24AR0/config.tcl b/fpga/mqnic/DK_DEV_AGF014EA/fpga_25g/fpga_24AR0/config.tcl index ac71809b9..f4e08b31c 100644 --- a/fpga/mqnic/DK_DEV_AGF014EA/fpga_25g/fpga_24AR0/config.tcl +++ b/fpga/mqnic/DK_DEV_AGF014EA/fpga_25g/fpga_24AR0/config.tcl @@ -100,6 +100,8 @@ dict set params TX_CPL_FIFO_DEPTH "32" dict set params TX_CHECKSUM_ENABLE "1" dict set params RX_HASH_ENABLE "1" dict set params RX_CHECKSUM_ENABLE "1" +dict set params PFC_ENABLE "1" +dict set params LFC_ENABLE [dict get $params PFC_ENABLE] dict set params TX_FIFO_DEPTH "32768" dict set params RX_FIFO_DEPTH "32768" dict set params MAX_TX_SIZE "9214" diff --git a/fpga/mqnic/DK_DEV_AGF014EA/fpga_25g/rtl/eth_mac_dual_quad_wrapper.v b/fpga/mqnic/DK_DEV_AGF014EA/fpga_25g/rtl/eth_mac_dual_quad_wrapper.v index d7f29c044..ce159801a 100644 --- a/fpga/mqnic/DK_DEV_AGF014EA/fpga_25g/rtl/eth_mac_dual_quad_wrapper.v +++ b/fpga/mqnic/DK_DEV_AGF014EA/fpga_25g/rtl/eth_mac_dual_quad_wrapper.v @@ -70,6 +70,10 @@ module eth_mac_dual_quad_wrapper # input wire mac_1_tx_axis_tlast, input wire [TX_USER_WIDTH-1:0] mac_1_tx_axis_tuser, + output wire mac_1_tx_status, + input wire mac_1_tx_lfc_req, + input wire [7:0] mac_1_tx_pfc_req, + output wire mac_1_rx_clk, output wire mac_1_rx_rst, @@ -84,6 +88,8 @@ module eth_mac_dual_quad_wrapper # output wire [RX_USER_WIDTH-1:0] mac_1_rx_axis_tuser, output wire mac_1_rx_status, + output wire mac_1_rx_lfc_req, + output wire [7:0] mac_1_rx_pfc_req, output wire mac_2_tx_clk, output wire mac_2_tx_rst, @@ -103,6 +109,10 @@ module eth_mac_dual_quad_wrapper # input wire mac_2_tx_axis_tlast, input wire [TX_USER_WIDTH-1:0] mac_2_tx_axis_tuser, + output wire mac_2_tx_status, + input wire mac_2_tx_lfc_req, + input wire [7:0] mac_2_tx_pfc_req, + output wire mac_2_rx_clk, output wire mac_2_rx_rst, @@ -117,6 +127,8 @@ module eth_mac_dual_quad_wrapper # output wire [RX_USER_WIDTH-1:0] mac_2_rx_axis_tuser, output wire mac_2_rx_status, + output wire mac_2_rx_lfc_req, + output wire [7:0] mac_2_rx_pfc_req, output wire mac_3_tx_clk, output wire mac_3_tx_rst, @@ -136,6 +148,10 @@ module eth_mac_dual_quad_wrapper # input wire mac_3_tx_axis_tlast, input wire [TX_USER_WIDTH-1:0] mac_3_tx_axis_tuser, + output wire mac_3_tx_status, + input wire mac_3_tx_lfc_req, + input wire [7:0] mac_3_tx_pfc_req, + output wire mac_3_rx_clk, output wire mac_3_rx_rst, @@ -150,6 +166,8 @@ module eth_mac_dual_quad_wrapper # output wire [RX_USER_WIDTH-1:0] mac_3_rx_axis_tuser, output wire mac_3_rx_status, + output wire mac_3_rx_lfc_req, + output wire [7:0] mac_3_rx_pfc_req, output wire mac_4_tx_clk, output wire mac_4_tx_rst, @@ -169,12 +187,16 @@ module eth_mac_dual_quad_wrapper # input wire mac_4_tx_axis_tlast, input wire [TX_USER_WIDTH-1:0] mac_4_tx_axis_tuser, + output wire mac_4_tx_status, + input wire mac_4_tx_lfc_req, + input wire [7:0] mac_4_tx_pfc_req, + output wire mac_4_rx_clk, output wire mac_4_rx_rst, output wire mac_4_rx_ptp_clk, output wire mac_4_rx_ptp_rst, - output wire [PTP_TS_WIDTH-1:0] mac_4_rx_ptp_time, + input wire [PTP_TS_WIDTH-1:0] mac_4_rx_ptp_time, output wire [DATA_WIDTH-1:0] mac_4_rx_axis_tdata, output wire [KEEP_WIDTH-1:0] mac_4_rx_axis_tkeep, @@ -183,6 +205,8 @@ module eth_mac_dual_quad_wrapper # output wire [RX_USER_WIDTH-1:0] mac_4_rx_axis_tuser, output wire mac_4_rx_status, + output wire mac_4_rx_lfc_req, + output wire [7:0] mac_4_rx_pfc_req, output wire mac_5_tx_clk, output wire mac_5_tx_rst, @@ -202,6 +226,10 @@ module eth_mac_dual_quad_wrapper # input wire mac_5_tx_axis_tlast, input wire [TX_USER_WIDTH-1:0] mac_5_tx_axis_tuser, + output wire mac_5_tx_status, + input wire mac_5_tx_lfc_req, + input wire [7:0] mac_5_tx_pfc_req, + output wire mac_5_rx_clk, output wire mac_5_rx_rst, @@ -216,6 +244,8 @@ module eth_mac_dual_quad_wrapper # output wire [RX_USER_WIDTH-1:0] mac_5_rx_axis_tuser, output wire mac_5_rx_status, + output wire mac_5_rx_lfc_req, + output wire [7:0] mac_5_rx_pfc_req, output wire mac_6_tx_clk, output wire mac_6_tx_rst, @@ -235,6 +265,10 @@ module eth_mac_dual_quad_wrapper # input wire mac_6_tx_axis_tlast, input wire [TX_USER_WIDTH-1:0] mac_6_tx_axis_tuser, + output wire mac_6_tx_status, + input wire mac_6_tx_lfc_req, + input wire [7:0] mac_6_tx_pfc_req, + output wire mac_6_rx_clk, output wire mac_6_rx_rst, @@ -249,6 +283,8 @@ module eth_mac_dual_quad_wrapper # output wire [RX_USER_WIDTH-1:0] mac_6_rx_axis_tuser, output wire mac_6_rx_status, + output wire mac_6_rx_lfc_req, + output wire [7:0] mac_6_rx_pfc_req, output wire mac_7_tx_clk, output wire mac_7_tx_rst, @@ -268,6 +304,10 @@ module eth_mac_dual_quad_wrapper # input wire mac_7_tx_axis_tlast, input wire [TX_USER_WIDTH-1:0] mac_7_tx_axis_tuser, + output wire mac_7_tx_status, + input wire mac_7_tx_lfc_req, + input wire [7:0] mac_7_tx_pfc_req, + output wire mac_7_rx_clk, output wire mac_7_rx_rst, @@ -282,6 +322,8 @@ module eth_mac_dual_quad_wrapper # output wire [RX_USER_WIDTH-1:0] mac_7_rx_axis_tuser, output wire mac_7_rx_status, + output wire mac_7_rx_lfc_req, + output wire [7:0] mac_7_rx_pfc_req, output wire mac_8_tx_clk, output wire mac_8_tx_rst, @@ -301,12 +343,16 @@ module eth_mac_dual_quad_wrapper # input wire mac_8_tx_axis_tlast, input wire [TX_USER_WIDTH-1:0] mac_8_tx_axis_tuser, + output wire mac_8_tx_status, + input wire mac_8_tx_lfc_req, + input wire [7:0] mac_8_tx_pfc_req, + output wire mac_8_rx_clk, output wire mac_8_rx_rst, output wire mac_8_rx_ptp_clk, output wire mac_8_rx_ptp_rst, - output wire [PTP_TS_WIDTH-1:0] mac_8_rx_ptp_time, + input wire [PTP_TS_WIDTH-1:0] mac_8_rx_ptp_time, output wire [DATA_WIDTH-1:0] mac_8_rx_axis_tdata, output wire [KEEP_WIDTH-1:0] mac_8_rx_axis_tkeep, @@ -314,7 +360,9 @@ module eth_mac_dual_quad_wrapper # output wire mac_8_rx_axis_tlast, output wire [RX_USER_WIDTH-1:0] mac_8_rx_axis_tuser, - output wire mac_8_rx_status + output wire mac_8_rx_status, + output wire mac_8_rx_lfc_req, + output wire [7:0] mac_8_rx_pfc_req ); parameter N_CH = 8; @@ -370,6 +418,11 @@ wire [N_CH-1:0] mac_rx_endofpacket; wire [N_CH*3-1:0] mac_rx_empty; wire [N_CH*6-1:0] mac_rx_error; +wire [N_CH*8-1:0] mac_tx_pfc; +wire [N_CH*8-1:0] mac_rx_pfc; +wire [N_CH-1:0] mac_tx_pause; +wire [N_CH-1:0] mac_rx_pause; + generate if (MAC_RSFEC) begin @@ -456,10 +509,10 @@ if (MAC_RSFEC) begin .o_sl_rx_error (mac_rx_error[0*4*6 +: 4*6]), .o_sl_rxstatus_data (), .o_sl_rxstatus_valid (), - .i_sl_tx_pfc ({4{8'd0}}), - .o_sl_rx_pfc (), - .i_sl_tx_pause ({4{1'b0}}), - .o_sl_rx_pause (), + .i_sl_tx_pfc (mac_tx_pfc[0*4*8 +: 4*8]), + .o_sl_rx_pfc (mac_rx_pfc[0*4*8 +: 4*8]), + .i_sl_tx_pause (mac_tx_pause[0*4*1 +: 4*1]), + .o_sl_rx_pause (mac_rx_pause[0*4*1 +: 4*1]), .i_sl_ptp_tx_tod (mac_ptp_tx_tod[0*4*PTP_TS_WIDTH +: 4*PTP_TS_WIDTH]), .i_sl_ptp_rx_tod (mac_ptp_rx_tod[0*4*PTP_TS_WIDTH +: 4*PTP_TS_WIDTH]), .i_sl_ptp_ts_req ({4{1'b1}}), @@ -565,10 +618,10 @@ if (MAC_RSFEC) begin .o_sl_rx_error (mac_rx_error[1*4*6 +: 4*6]), .o_sl_rxstatus_data (), .o_sl_rxstatus_valid (), - .i_sl_tx_pfc ({4{8'd0}}), - .o_sl_rx_pfc (), - .i_sl_tx_pause ({4{1'b0}}), - .o_sl_rx_pause (), + .i_sl_tx_pfc (mac_tx_pfc[1*4*8 +: 4*8]), + .o_sl_rx_pfc (mac_rx_pfc[1*4*8 +: 4*8]), + .i_sl_tx_pause (mac_tx_pause[1*4*1 +: 4*1]), + .o_sl_rx_pause (mac_rx_pause[1*4*1 +: 4*1]), .i_sl_ptp_tx_tod (mac_ptp_tx_tod[1*4*PTP_TS_WIDTH +: 4*PTP_TS_WIDTH]), .i_sl_ptp_rx_tod (mac_ptp_rx_tod[1*4*PTP_TS_WIDTH +: 4*PTP_TS_WIDTH]), .i_sl_ptp_ts_req ({4{1'b1}}), @@ -670,10 +723,10 @@ end else begin .o_sl_rx_error (mac_rx_error[0*4*6 +: 4*6]), .o_sl_rxstatus_data (), .o_sl_rxstatus_valid (), - .i_sl_tx_pfc ({4{8'd0}}), - .o_sl_rx_pfc (), - .i_sl_tx_pause ({4{1'b0}}), - .o_sl_rx_pause (), + .i_sl_tx_pfc (mac_tx_pfc[0*4*8 +: 4*8]), + .o_sl_rx_pfc (mac_rx_pfc[0*4*8 +: 4*8]), + .i_sl_tx_pause (mac_tx_pause[0*4*1 +: 4*1]), + .o_sl_rx_pause (mac_rx_pause[0*4*1 +: 4*1]), .i_sl_ptp_tx_tod (mac_ptp_tx_tod[0*4*PTP_TS_WIDTH +: 4*PTP_TS_WIDTH]), .i_sl_ptp_rx_tod (mac_ptp_rx_tod[0*4*PTP_TS_WIDTH +: 4*PTP_TS_WIDTH]), .i_sl_ptp_ts_req ({4{1'b1}}), @@ -773,10 +826,10 @@ end else begin .o_sl_rx_error (mac_rx_error[1*4*6 +: 4*6]), .o_sl_rxstatus_data (), .o_sl_rxstatus_valid (), - .i_sl_tx_pfc ({4{8'd0}}), - .o_sl_rx_pfc (), - .i_sl_tx_pause ({4{1'b0}}), - .o_sl_rx_pause (), + .i_sl_tx_pfc (mac_tx_pfc[1*4*8 +: 4*8]), + .o_sl_rx_pfc (mac_rx_pfc[1*4*8 +: 4*8]), + .i_sl_tx_pause (mac_tx_pause[1*4*1 +: 4*1]), + .o_sl_rx_pause (mac_rx_pause[1*4*1 +: 4*1]), .i_sl_ptp_tx_tod (mac_ptp_tx_tod[1*4*PTP_TS_WIDTH +: 4*PTP_TS_WIDTH]), .i_sl_ptp_rx_tod (mac_ptp_rx_tod[1*4*PTP_TS_WIDTH +: 4*PTP_TS_WIDTH]), .i_sl_ptp_ts_req ({4{1'b1}}), @@ -847,6 +900,10 @@ assign mac_1_tx_axis_tready = mac_tx_axis_tready[0]; assign mac_tx_axis_tlast[0] = mac_1_tx_axis_tlast; assign mac_tx_axis_tuser[0*TX_USER_WIDTH +: TX_USER_WIDTH] = mac_1_tx_axis_tuser; +assign mac_1_tx_status = mac_tx_lanes_stable[0*1 +: 1]; +assign mac_tx_pause[0*1 +: 1] = mac_1_tx_lfc_req; +assign mac_tx_pfc[0*8 +: 8] = mac_1_tx_pfc_req; + assign mac_1_rx_clk = mac_rx_clk[0]; assign mac_1_rx_rst = mac_rx_rst[0]; @@ -860,7 +917,9 @@ assign mac_1_rx_axis_tvalid = mac_rx_axis_tvalid[0]; assign mac_1_rx_axis_tlast = mac_rx_axis_tlast[0]; assign mac_1_rx_axis_tuser = mac_rx_axis_tuser[0*RX_USER_WIDTH +: RX_USER_WIDTH]; -assign mac_1_rx_status = mac_rx_pcs_ready[0]; +assign mac_1_rx_status = mac_rx_pcs_ready[0*1 +: 1]; +assign mac_1_rx_lfc_req = mac_rx_pause[0*1 +: 1]; +assign mac_1_rx_pfc_req = mac_rx_pfc[0*8 +: 8]; assign mac_2_tx_clk = mac_tx_clk[1]; assign mac_2_tx_rst = mac_tx_rst[1]; @@ -880,6 +939,10 @@ assign mac_2_tx_axis_tready = mac_tx_axis_tready[1]; assign mac_tx_axis_tlast[1] = mac_2_tx_axis_tlast; assign mac_tx_axis_tuser[1*TX_USER_WIDTH +: TX_USER_WIDTH] = mac_2_tx_axis_tuser; +assign mac_2_tx_status = mac_tx_lanes_stable[1*1 +: 1]; +assign mac_tx_pause[1*1 +: 1] = mac_2_tx_lfc_req; +assign mac_tx_pfc[1*8 +: 8] = mac_2_tx_pfc_req; + assign mac_2_rx_clk = mac_rx_clk[1]; assign mac_2_rx_rst = mac_rx_rst[1]; @@ -893,7 +956,9 @@ assign mac_2_rx_axis_tvalid = mac_rx_axis_tvalid[1]; assign mac_2_rx_axis_tlast = mac_rx_axis_tlast[1]; assign mac_2_rx_axis_tuser = mac_rx_axis_tuser[1*RX_USER_WIDTH +: RX_USER_WIDTH]; -assign mac_2_rx_status = mac_rx_pcs_ready[1]; +assign mac_2_rx_status = mac_rx_pcs_ready[1*1 +: 1]; +assign mac_2_rx_lfc_req = mac_rx_pause[1*1 +: 1]; +assign mac_2_rx_pfc_req = mac_rx_pfc[1*8 +: 8]; assign mac_3_tx_clk = mac_tx_clk[2]; assign mac_3_tx_rst = mac_tx_rst[2]; @@ -913,6 +978,10 @@ assign mac_3_tx_axis_tready = mac_tx_axis_tready[2]; assign mac_tx_axis_tlast[2] = mac_3_tx_axis_tlast; assign mac_tx_axis_tuser[2*TX_USER_WIDTH +: TX_USER_WIDTH] = mac_3_tx_axis_tuser; +assign mac_3_tx_status = mac_tx_lanes_stable[2*1 +: 1]; +assign mac_tx_pause[2*1 +: 1] = mac_3_tx_lfc_req; +assign mac_tx_pfc[2*8 +: 8] = mac_3_tx_pfc_req; + assign mac_3_rx_clk = mac_rx_clk[2]; assign mac_3_rx_rst = mac_rx_rst[2]; @@ -926,7 +995,9 @@ assign mac_3_rx_axis_tvalid = mac_rx_axis_tvalid[2]; assign mac_3_rx_axis_tlast = mac_rx_axis_tlast[2]; assign mac_3_rx_axis_tuser = mac_rx_axis_tuser[2*RX_USER_WIDTH +: RX_USER_WIDTH]; -assign mac_3_rx_status = mac_rx_pcs_ready[2]; +assign mac_3_rx_status = mac_rx_pcs_ready[2*1 +: 1]; +assign mac_3_rx_lfc_req = mac_rx_pause[2*1 +: 1]; +assign mac_3_rx_pfc_req = mac_rx_pfc[2*8 +: 8]; assign mac_4_tx_clk = mac_tx_clk[3]; assign mac_4_tx_rst = mac_tx_rst[3]; @@ -946,6 +1017,10 @@ assign mac_4_tx_axis_tready = mac_tx_axis_tready[3]; assign mac_tx_axis_tlast[3] = mac_4_tx_axis_tlast; assign mac_tx_axis_tuser[3*TX_USER_WIDTH +: TX_USER_WIDTH] = mac_4_tx_axis_tuser; +assign mac_4_tx_status = mac_tx_lanes_stable[3*1 +: 1]; +assign mac_tx_pause[3*1 +: 1] = mac_4_tx_lfc_req; +assign mac_tx_pfc[3*8 +: 8] = mac_4_tx_pfc_req; + assign mac_4_rx_clk = mac_rx_clk[3]; assign mac_4_rx_rst = mac_rx_rst[3]; @@ -959,7 +1034,9 @@ assign mac_4_rx_axis_tvalid = mac_rx_axis_tvalid[3]; assign mac_4_rx_axis_tlast = mac_rx_axis_tlast[3]; assign mac_4_rx_axis_tuser = mac_rx_axis_tuser[3*RX_USER_WIDTH +: RX_USER_WIDTH]; -assign mac_4_rx_status = mac_rx_pcs_ready[3]; +assign mac_4_rx_status = mac_rx_pcs_ready[3*1 +: 1]; +assign mac_4_rx_lfc_req = mac_rx_pause[3*1 +: 1]; +assign mac_4_rx_pfc_req = mac_rx_pfc[3*8 +: 8]; assign mac_5_tx_clk = mac_tx_clk[4]; assign mac_5_tx_rst = mac_tx_rst[4]; @@ -979,6 +1056,10 @@ assign mac_5_tx_axis_tready = mac_tx_axis_tready[4]; assign mac_tx_axis_tlast[4] = mac_5_tx_axis_tlast; assign mac_tx_axis_tuser[4*TX_USER_WIDTH +: TX_USER_WIDTH] = mac_5_tx_axis_tuser; +assign mac_5_tx_status = mac_tx_lanes_stable[4*1 +: 1]; +assign mac_tx_pause[4*1 +: 1] = mac_5_tx_lfc_req; +assign mac_tx_pfc[4*8 +: 8] = mac_5_tx_pfc_req; + assign mac_5_rx_clk = mac_rx_clk[4]; assign mac_5_rx_rst = mac_rx_rst[4]; @@ -992,7 +1073,9 @@ assign mac_5_rx_axis_tvalid = mac_rx_axis_tvalid[4]; assign mac_5_rx_axis_tlast = mac_rx_axis_tlast[4]; assign mac_5_rx_axis_tuser = mac_rx_axis_tuser[4*RX_USER_WIDTH +: RX_USER_WIDTH]; -assign mac_5_rx_status = mac_rx_pcs_ready[4]; +assign mac_5_rx_status = mac_rx_pcs_ready[4*1 +: 1]; +assign mac_5_rx_lfc_req = mac_rx_pause[4*1 +: 1]; +assign mac_5_rx_pfc_req = mac_rx_pfc[4*8 +: 8]; assign mac_6_tx_clk = mac_tx_clk[5]; assign mac_6_tx_rst = mac_tx_rst[5]; @@ -1012,6 +1095,10 @@ assign mac_6_tx_axis_tready = mac_tx_axis_tready[5]; assign mac_tx_axis_tlast[5] = mac_6_tx_axis_tlast; assign mac_tx_axis_tuser[5*TX_USER_WIDTH +: TX_USER_WIDTH] = mac_6_tx_axis_tuser; +assign mac_6_tx_status = mac_tx_lanes_stable[5*1 +: 1]; +assign mac_tx_pause[5*1 +: 1] = mac_6_tx_lfc_req; +assign mac_tx_pfc[5*8 +: 8] = mac_6_tx_pfc_req; + assign mac_6_rx_clk = mac_rx_clk[5]; assign mac_6_rx_rst = mac_rx_rst[5]; @@ -1025,7 +1112,9 @@ assign mac_6_rx_axis_tvalid = mac_rx_axis_tvalid[5]; assign mac_6_rx_axis_tlast = mac_rx_axis_tlast[5]; assign mac_6_rx_axis_tuser = mac_rx_axis_tuser[5*RX_USER_WIDTH +: RX_USER_WIDTH]; -assign mac_6_rx_status = mac_rx_pcs_ready[5]; +assign mac_6_rx_status = mac_rx_pcs_ready[5*1 +: 1]; +assign mac_6_rx_lfc_req = mac_rx_pause[5*1 +: 1]; +assign mac_6_rx_pfc_req = mac_rx_pfc[5*8 +: 8]; assign mac_7_tx_clk = mac_tx_clk[6]; assign mac_7_tx_rst = mac_tx_rst[6]; @@ -1045,6 +1134,10 @@ assign mac_7_tx_axis_tready = mac_tx_axis_tready[6]; assign mac_tx_axis_tlast[6] = mac_7_tx_axis_tlast; assign mac_tx_axis_tuser[6*TX_USER_WIDTH +: TX_USER_WIDTH] = mac_7_tx_axis_tuser; +assign mac_7_tx_status = mac_tx_lanes_stable[6*1 +: 1]; +assign mac_tx_pause[6*1 +: 1] = mac_7_tx_lfc_req; +assign mac_tx_pfc[6*8 +: 8] = mac_7_tx_pfc_req; + assign mac_7_rx_clk = mac_rx_clk[6]; assign mac_7_rx_rst = mac_rx_rst[6]; @@ -1058,7 +1151,9 @@ assign mac_7_rx_axis_tvalid = mac_rx_axis_tvalid[6]; assign mac_7_rx_axis_tlast = mac_rx_axis_tlast[6]; assign mac_7_rx_axis_tuser = mac_rx_axis_tuser[6*RX_USER_WIDTH +: RX_USER_WIDTH]; -assign mac_7_rx_status = mac_rx_pcs_ready[6]; +assign mac_7_rx_status = mac_rx_pcs_ready[6*1 +: 1]; +assign mac_7_rx_lfc_req = mac_rx_pause[6*1 +: 1]; +assign mac_7_rx_pfc_req = mac_rx_pfc[6*8 +: 8]; assign mac_8_tx_clk = mac_tx_clk[7]; assign mac_8_tx_rst = mac_tx_rst[7]; @@ -1078,6 +1173,10 @@ assign mac_8_tx_axis_tready = mac_tx_axis_tready[7]; assign mac_tx_axis_tlast[7] = mac_8_tx_axis_tlast; assign mac_tx_axis_tuser[7*TX_USER_WIDTH +: TX_USER_WIDTH] = mac_8_tx_axis_tuser; +assign mac_8_tx_status = mac_tx_lanes_stable[7*1 +: 1]; +assign mac_tx_pause[7*1 +: 1] = mac_8_tx_lfc_req; +assign mac_tx_pfc[7*8 +: 8] = mac_8_tx_pfc_req; + assign mac_8_rx_clk = mac_rx_clk[7]; assign mac_8_rx_rst = mac_rx_rst[7]; @@ -1091,7 +1190,9 @@ assign mac_8_rx_axis_tvalid = mac_rx_axis_tvalid[7]; assign mac_8_rx_axis_tlast = mac_rx_axis_tlast[7]; assign mac_8_rx_axis_tuser = mac_rx_axis_tuser[7*RX_USER_WIDTH +: RX_USER_WIDTH]; -assign mac_8_rx_status = mac_rx_pcs_ready[7]; +assign mac_8_rx_status = mac_rx_pcs_ready[7*1 +: 1]; +assign mac_8_rx_lfc_req = mac_rx_pause[7*1 +: 1]; +assign mac_8_rx_pfc_req = mac_rx_pfc[7*8 +: 8]; generate diff --git a/fpga/mqnic/DK_DEV_AGF014EA/fpga_25g/rtl/fpga.v b/fpga/mqnic/DK_DEV_AGF014EA/fpga_25g/rtl/fpga.v index 2795ea6a2..8a1a2ad0d 100644 --- a/fpga/mqnic/DK_DEV_AGF014EA/fpga_25g/rtl/fpga.v +++ b/fpga/mqnic/DK_DEV_AGF014EA/fpga_25g/rtl/fpga.v @@ -71,6 +71,8 @@ module fpga # parameter TX_CHECKSUM_ENABLE = 1, parameter RX_HASH_ENABLE = 1, parameter RX_CHECKSUM_ENABLE = 1, + parameter PFC_ENABLE = 1, + parameter LFC_ENABLE = PFC_ENABLE, parameter TX_FIFO_DEPTH = 32768, parameter RX_FIFO_DEPTH = 32768, parameter MAX_TX_SIZE = 9214, @@ -456,7 +458,7 @@ iopll_etile_ptp iopll_etile_ptp_inst ( .outclk_0 (etile_ptp_sample_clk) ); -// QSFP-DD A +// QSFP-DD 0 wire qsfpdd0_mac_1_tx_clk_int; wire qsfpdd0_mac_1_tx_rst_int; @@ -475,6 +477,10 @@ wire qsfpdd0_mac_1_tx_axis_tready_int; wire qsfpdd0_mac_1_tx_axis_tlast_int; wire [AXIS_ETH_TX_USER_WIDTH-1:0] qsfpdd0_mac_1_tx_axis_tuser_int; +wire qsfpdd0_mac_1_tx_status_int; +wire qsfpdd0_mac_1_tx_lfc_req_int; +wire [7:0] qsfpdd0_mac_1_tx_pfc_req_int; + wire qsfpdd0_mac_1_rx_clk_int; wire qsfpdd0_mac_1_rx_rst_int; @@ -489,6 +495,8 @@ wire qsfpdd0_mac_1_rx_axis_tlast_int; wire [AXIS_ETH_RX_USER_WIDTH-1:0] qsfpdd0_mac_1_rx_axis_tuser_int; wire qsfpdd0_mac_1_rx_status_int; +wire qsfpdd0_mac_1_rx_lfc_req_int; +wire [7:0] qsfpdd0_mac_1_rx_pfc_req_int; wire qsfpdd0_mac_2_tx_clk_int; wire qsfpdd0_mac_2_tx_rst_int; @@ -508,6 +516,10 @@ wire qsfpdd0_mac_2_tx_axis_tready_int; wire qsfpdd0_mac_2_tx_axis_tlast_int; wire [AXIS_ETH_TX_USER_WIDTH-1:0] qsfpdd0_mac_2_tx_axis_tuser_int; +wire qsfpdd0_mac_2_tx_status_int; +wire qsfpdd0_mac_2_tx_lfc_req_int; +wire [7:0] qsfpdd0_mac_2_tx_pfc_req_int; + wire qsfpdd0_mac_2_rx_clk_int; wire qsfpdd0_mac_2_rx_rst_int; @@ -522,6 +534,8 @@ wire qsfpdd0_mac_2_rx_axis_tlast_int; wire [AXIS_ETH_RX_USER_WIDTH-1:0] qsfpdd0_mac_2_rx_axis_tuser_int; wire qsfpdd0_mac_2_rx_status_int; +wire qsfpdd0_mac_2_rx_lfc_req_int; +wire [7:0] qsfpdd0_mac_2_rx_pfc_req_int; wire qsfpdd0_mac_3_tx_clk_int; wire qsfpdd0_mac_3_tx_rst_int; @@ -541,6 +555,10 @@ wire qsfpdd0_mac_3_tx_axis_tready_int; wire qsfpdd0_mac_3_tx_axis_tlast_int; wire [AXIS_ETH_TX_USER_WIDTH-1:0] qsfpdd0_mac_3_tx_axis_tuser_int; +wire qsfpdd0_mac_3_tx_status_int; +wire qsfpdd0_mac_3_tx_lfc_req_int; +wire [7:0] qsfpdd0_mac_3_tx_pfc_req_int; + wire qsfpdd0_mac_3_rx_clk_int; wire qsfpdd0_mac_3_rx_rst_int; @@ -555,6 +573,8 @@ wire qsfpdd0_mac_3_rx_axis_tlast_int; wire [AXIS_ETH_RX_USER_WIDTH-1:0] qsfpdd0_mac_3_rx_axis_tuser_int; wire qsfpdd0_mac_3_rx_status_int; +wire qsfpdd0_mac_3_rx_lfc_req_int; +wire [7:0] qsfpdd0_mac_3_rx_pfc_req_int; wire qsfpdd0_mac_4_tx_clk_int; wire qsfpdd0_mac_4_tx_rst_int; @@ -574,6 +594,10 @@ wire qsfpdd0_mac_4_tx_axis_tready_int; wire qsfpdd0_mac_4_tx_axis_tlast_int; wire [AXIS_ETH_TX_USER_WIDTH-1:0] qsfpdd0_mac_4_tx_axis_tuser_int; +wire qsfpdd0_mac_4_tx_status_int; +wire qsfpdd0_mac_4_tx_lfc_req_int; +wire [7:0] qsfpdd0_mac_4_tx_pfc_req_int; + wire qsfpdd0_mac_4_rx_clk_int; wire qsfpdd0_mac_4_rx_rst_int; @@ -588,6 +612,8 @@ wire qsfpdd0_mac_4_rx_axis_tlast_int; wire [AXIS_ETH_RX_USER_WIDTH-1:0] qsfpdd0_mac_4_rx_axis_tuser_int; wire qsfpdd0_mac_4_rx_status_int; +wire qsfpdd0_mac_4_rx_lfc_req_int; +wire [7:0] qsfpdd0_mac_4_rx_pfc_req_int; wire qsfpdd0_mac_5_tx_clk_int; wire qsfpdd0_mac_5_tx_rst_int; @@ -607,6 +633,10 @@ wire qsfpdd0_mac_5_tx_axis_tready_int; wire qsfpdd0_mac_5_tx_axis_tlast_int; wire [AXIS_ETH_TX_USER_WIDTH-1:0] qsfpdd0_mac_5_tx_axis_tuser_int; +wire qsfpdd0_mac_5_tx_status_int; +wire qsfpdd0_mac_5_tx_lfc_req_int; +wire [7:0] qsfpdd0_mac_5_tx_pfc_req_int; + wire qsfpdd0_mac_5_rx_clk_int; wire qsfpdd0_mac_5_rx_rst_int; @@ -621,6 +651,8 @@ wire qsfpdd0_mac_5_rx_axis_tlast_int; wire [AXIS_ETH_RX_USER_WIDTH-1:0] qsfpdd0_mac_5_rx_axis_tuser_int; wire qsfpdd0_mac_5_rx_status_int; +wire qsfpdd0_mac_5_rx_lfc_req_int; +wire [7:0] qsfpdd0_mac_5_rx_pfc_req_int; wire qsfpdd0_mac_6_tx_clk_int; wire qsfpdd0_mac_6_tx_rst_int; @@ -640,6 +672,10 @@ wire qsfpdd0_mac_6_tx_axis_tready_int; wire qsfpdd0_mac_6_tx_axis_tlast_int; wire [AXIS_ETH_TX_USER_WIDTH-1:0] qsfpdd0_mac_6_tx_axis_tuser_int; +wire qsfpdd0_mac_6_tx_status_int; +wire qsfpdd0_mac_6_tx_lfc_req_int; +wire [7:0] qsfpdd0_mac_6_tx_pfc_req_int; + wire qsfpdd0_mac_6_rx_clk_int; wire qsfpdd0_mac_6_rx_rst_int; @@ -654,6 +690,8 @@ wire qsfpdd0_mac_6_rx_axis_tlast_int; wire [AXIS_ETH_RX_USER_WIDTH-1:0] qsfpdd0_mac_6_rx_axis_tuser_int; wire qsfpdd0_mac_6_rx_status_int; +wire qsfpdd0_mac_6_rx_lfc_req_int; +wire [7:0] qsfpdd0_mac_6_rx_pfc_req_int; wire qsfpdd0_mac_7_tx_clk_int; wire qsfpdd0_mac_7_tx_rst_int; @@ -673,6 +711,10 @@ wire qsfpdd0_mac_7_tx_axis_tready_int; wire qsfpdd0_mac_7_tx_axis_tlast_int; wire [AXIS_ETH_TX_USER_WIDTH-1:0] qsfpdd0_mac_7_tx_axis_tuser_int; +wire qsfpdd0_mac_7_tx_status_int; +wire qsfpdd0_mac_7_tx_lfc_req_int; +wire [7:0] qsfpdd0_mac_7_tx_pfc_req_int; + wire qsfpdd0_mac_7_rx_clk_int; wire qsfpdd0_mac_7_rx_rst_int; @@ -687,6 +729,8 @@ wire qsfpdd0_mac_7_rx_axis_tlast_int; wire [AXIS_ETH_RX_USER_WIDTH-1:0] qsfpdd0_mac_7_rx_axis_tuser_int; wire qsfpdd0_mac_7_rx_status_int; +wire qsfpdd0_mac_7_rx_lfc_req_int; +wire [7:0] qsfpdd0_mac_7_rx_pfc_req_int; wire qsfpdd0_mac_8_tx_clk_int; wire qsfpdd0_mac_8_tx_rst_int; @@ -706,6 +750,10 @@ wire qsfpdd0_mac_8_tx_axis_tready_int; wire qsfpdd0_mac_8_tx_axis_tlast_int; wire [AXIS_ETH_TX_USER_WIDTH-1:0] qsfpdd0_mac_8_tx_axis_tuser_int; +wire qsfpdd0_mac_8_tx_status_int; +wire qsfpdd0_mac_8_tx_lfc_req_int; +wire [7:0] qsfpdd0_mac_8_tx_pfc_req_int; + wire qsfpdd0_mac_8_rx_clk_int; wire qsfpdd0_mac_8_rx_rst_int; @@ -720,6 +768,8 @@ wire qsfpdd0_mac_8_rx_axis_tlast_int; wire [AXIS_ETH_RX_USER_WIDTH-1:0] qsfpdd0_mac_8_rx_axis_tuser_int; wire qsfpdd0_mac_8_rx_status_int; +wire qsfpdd0_mac_8_rx_lfc_req_int; +wire [7:0] qsfpdd0_mac_8_rx_pfc_req_int; eth_mac_dual_quad_wrapper #( .PTP_TS_WIDTH(PTP_TS_WIDTH), @@ -759,6 +809,10 @@ qsfpdd0_mac_inst ( .mac_1_tx_axis_tlast(qsfpdd0_mac_1_tx_axis_tlast_int), .mac_1_tx_axis_tuser(qsfpdd0_mac_1_tx_axis_tuser_int), + .mac_1_tx_status(qsfpdd0_mac_1_tx_status_int), + .mac_1_tx_lfc_req(qsfpdd0_mac_1_tx_lfc_req_int), + .mac_1_tx_pfc_req(qsfpdd0_mac_1_tx_pfc_req_int), + .mac_1_rx_clk(qsfpdd0_mac_1_rx_clk_int), .mac_1_rx_rst(qsfpdd0_mac_1_rx_rst_int), @@ -773,6 +827,8 @@ qsfpdd0_mac_inst ( .mac_1_rx_axis_tuser(qsfpdd0_mac_1_rx_axis_tuser_int), .mac_1_rx_status(qsfpdd0_mac_1_rx_status_int), + .mac_1_rx_lfc_req(qsfpdd0_mac_1_rx_lfc_req_int), + .mac_1_rx_pfc_req(qsfpdd0_mac_1_rx_pfc_req_int), .mac_2_tx_clk(qsfpdd0_mac_3_tx_clk_int), .mac_2_tx_rst(qsfpdd0_mac_3_tx_rst_int), @@ -792,6 +848,10 @@ qsfpdd0_mac_inst ( .mac_2_tx_axis_tlast(qsfpdd0_mac_3_tx_axis_tlast_int), .mac_2_tx_axis_tuser(qsfpdd0_mac_3_tx_axis_tuser_int), + .mac_2_tx_status(qsfpdd0_mac_3_tx_status_int), + .mac_2_tx_lfc_req(qsfpdd0_mac_3_tx_lfc_req_int), + .mac_2_tx_pfc_req(qsfpdd0_mac_3_tx_pfc_req_int), + .mac_2_rx_clk(qsfpdd0_mac_3_rx_clk_int), .mac_2_rx_rst(qsfpdd0_mac_3_rx_rst_int), @@ -806,6 +866,8 @@ qsfpdd0_mac_inst ( .mac_2_rx_axis_tuser(qsfpdd0_mac_3_rx_axis_tuser_int), .mac_2_rx_status(qsfpdd0_mac_3_rx_status_int), + .mac_2_rx_lfc_req(qsfpdd0_mac_3_rx_lfc_req_int), + .mac_2_rx_pfc_req(qsfpdd0_mac_3_rx_pfc_req_int), .mac_3_tx_clk(qsfpdd0_mac_2_tx_clk_int), .mac_3_tx_rst(qsfpdd0_mac_2_tx_rst_int), @@ -825,6 +887,10 @@ qsfpdd0_mac_inst ( .mac_3_tx_axis_tlast(qsfpdd0_mac_2_tx_axis_tlast_int), .mac_3_tx_axis_tuser(qsfpdd0_mac_2_tx_axis_tuser_int), + .mac_3_tx_status(qsfpdd0_mac_2_tx_status_int), + .mac_3_tx_lfc_req(qsfpdd0_mac_2_tx_lfc_req_int), + .mac_3_tx_pfc_req(qsfpdd0_mac_2_tx_pfc_req_int), + .mac_3_rx_clk(qsfpdd0_mac_2_rx_clk_int), .mac_3_rx_rst(qsfpdd0_mac_2_rx_rst_int), @@ -839,6 +905,8 @@ qsfpdd0_mac_inst ( .mac_3_rx_axis_tuser(qsfpdd0_mac_2_rx_axis_tuser_int), .mac_3_rx_status(qsfpdd0_mac_2_rx_status_int), + .mac_3_rx_lfc_req(qsfpdd0_mac_2_rx_lfc_req_int), + .mac_3_rx_pfc_req(qsfpdd0_mac_2_rx_pfc_req_int), .mac_4_tx_clk(qsfpdd0_mac_4_tx_clk_int), .mac_4_tx_rst(qsfpdd0_mac_4_tx_rst_int), @@ -858,6 +926,10 @@ qsfpdd0_mac_inst ( .mac_4_tx_axis_tlast(qsfpdd0_mac_4_tx_axis_tlast_int), .mac_4_tx_axis_tuser(qsfpdd0_mac_4_tx_axis_tuser_int), + .mac_4_tx_status(qsfpdd0_mac_4_tx_status_int), + .mac_4_tx_lfc_req(qsfpdd0_mac_4_tx_lfc_req_int), + .mac_4_tx_pfc_req(qsfpdd0_mac_4_tx_pfc_req_int), + .mac_4_rx_clk(qsfpdd0_mac_4_rx_clk_int), .mac_4_rx_rst(qsfpdd0_mac_4_rx_rst_int), @@ -872,6 +944,8 @@ qsfpdd0_mac_inst ( .mac_4_rx_axis_tuser(qsfpdd0_mac_4_rx_axis_tuser_int), .mac_4_rx_status(qsfpdd0_mac_4_rx_status_int), + .mac_4_rx_lfc_req(qsfpdd0_mac_4_rx_lfc_req_int), + .mac_4_rx_pfc_req(qsfpdd0_mac_4_rx_pfc_req_int), .mac_5_tx_clk(qsfpdd0_mac_5_tx_clk_int), .mac_5_tx_rst(qsfpdd0_mac_5_tx_rst_int), @@ -891,6 +965,10 @@ qsfpdd0_mac_inst ( .mac_5_tx_axis_tlast(qsfpdd0_mac_5_tx_axis_tlast_int), .mac_5_tx_axis_tuser(qsfpdd0_mac_5_tx_axis_tuser_int), + .mac_5_tx_status(qsfpdd0_mac_5_tx_status_int), + .mac_5_tx_lfc_req(qsfpdd0_mac_5_tx_lfc_req_int), + .mac_5_tx_pfc_req(qsfpdd0_mac_5_tx_pfc_req_int), + .mac_5_rx_clk(qsfpdd0_mac_5_rx_clk_int), .mac_5_rx_rst(qsfpdd0_mac_5_rx_rst_int), @@ -905,6 +983,8 @@ qsfpdd0_mac_inst ( .mac_5_rx_axis_tuser(qsfpdd0_mac_5_rx_axis_tuser_int), .mac_5_rx_status(qsfpdd0_mac_5_rx_status_int), + .mac_5_rx_lfc_req(qsfpdd0_mac_5_rx_lfc_req_int), + .mac_5_rx_pfc_req(qsfpdd0_mac_5_rx_pfc_req_int), .mac_6_tx_clk(qsfpdd0_mac_7_tx_clk_int), .mac_6_tx_rst(qsfpdd0_mac_7_tx_rst_int), @@ -924,6 +1004,10 @@ qsfpdd0_mac_inst ( .mac_6_tx_axis_tlast(qsfpdd0_mac_7_tx_axis_tlast_int), .mac_6_tx_axis_tuser(qsfpdd0_mac_7_tx_axis_tuser_int), + .mac_6_tx_status(qsfpdd0_mac_7_tx_status_int), + .mac_6_tx_lfc_req(qsfpdd0_mac_7_tx_lfc_req_int), + .mac_6_tx_pfc_req(qsfpdd0_mac_7_tx_pfc_req_int), + .mac_6_rx_clk(qsfpdd0_mac_7_rx_clk_int), .mac_6_rx_rst(qsfpdd0_mac_7_rx_rst_int), @@ -938,6 +1022,8 @@ qsfpdd0_mac_inst ( .mac_6_rx_axis_tuser(qsfpdd0_mac_7_rx_axis_tuser_int), .mac_6_rx_status(qsfpdd0_mac_7_rx_status_int), + .mac_6_rx_lfc_req(qsfpdd0_mac_7_rx_lfc_req_int), + .mac_6_rx_pfc_req(qsfpdd0_mac_7_rx_pfc_req_int), .mac_7_tx_clk(qsfpdd0_mac_6_tx_clk_int), .mac_7_tx_rst(qsfpdd0_mac_6_tx_rst_int), @@ -957,6 +1043,10 @@ qsfpdd0_mac_inst ( .mac_7_tx_axis_tlast(qsfpdd0_mac_6_tx_axis_tlast_int), .mac_7_tx_axis_tuser(qsfpdd0_mac_6_tx_axis_tuser_int), + .mac_7_tx_status(qsfpdd0_mac_6_tx_status_int), + .mac_7_tx_lfc_req(qsfpdd0_mac_6_tx_lfc_req_int), + .mac_7_tx_pfc_req(qsfpdd0_mac_6_tx_pfc_req_int), + .mac_7_rx_clk(qsfpdd0_mac_6_rx_clk_int), .mac_7_rx_rst(qsfpdd0_mac_6_rx_rst_int), @@ -971,6 +1061,8 @@ qsfpdd0_mac_inst ( .mac_7_rx_axis_tuser(qsfpdd0_mac_6_rx_axis_tuser_int), .mac_7_rx_status(qsfpdd0_mac_6_rx_status_int), + .mac_7_rx_lfc_req(qsfpdd0_mac_6_rx_lfc_req_int), + .mac_7_rx_pfc_req(qsfpdd0_mac_6_rx_pfc_req_int), .mac_8_tx_clk(qsfpdd0_mac_8_tx_clk_int), .mac_8_tx_rst(qsfpdd0_mac_8_tx_rst_int), @@ -990,6 +1082,10 @@ qsfpdd0_mac_inst ( .mac_8_tx_axis_tlast(qsfpdd0_mac_8_tx_axis_tlast_int), .mac_8_tx_axis_tuser(qsfpdd0_mac_8_tx_axis_tuser_int), + .mac_8_tx_status(qsfpdd0_mac_8_tx_status_int), + .mac_8_tx_lfc_req(qsfpdd0_mac_8_tx_lfc_req_int), + .mac_8_tx_pfc_req(qsfpdd0_mac_8_tx_pfc_req_int), + .mac_8_rx_clk(qsfpdd0_mac_8_rx_clk_int), .mac_8_rx_rst(qsfpdd0_mac_8_rx_rst_int), @@ -1003,10 +1099,12 @@ qsfpdd0_mac_inst ( .mac_8_rx_axis_tlast(qsfpdd0_mac_8_rx_axis_tlast_int), .mac_8_rx_axis_tuser(qsfpdd0_mac_8_rx_axis_tuser_int), - .mac_8_rx_status(qsfpdd0_mac_8_rx_status_int) + .mac_8_rx_status(qsfpdd0_mac_8_rx_status_int), + .mac_8_rx_lfc_req(qsfpdd0_mac_8_rx_lfc_req_int), + .mac_8_rx_pfc_req(qsfpdd0_mac_8_rx_pfc_req_int) ); -// QSFP-DD B +// QSFP-DD 1 wire qsfpdd1_mac_1_tx_clk_int; wire qsfpdd1_mac_1_tx_rst_int; @@ -1025,6 +1123,10 @@ wire qsfpdd1_mac_1_tx_axis_tready_int; wire qsfpdd1_mac_1_tx_axis_tlast_int; wire [AXIS_ETH_TX_USER_WIDTH-1:0] qsfpdd1_mac_1_tx_axis_tuser_int; +wire qsfpdd1_mac_1_tx_status_int; +wire qsfpdd1_mac_1_tx_lfc_req_int; +wire [7:0] qsfpdd1_mac_1_tx_pfc_req_int; + wire qsfpdd1_mac_1_rx_clk_int; wire qsfpdd1_mac_1_rx_rst_int; @@ -1039,6 +1141,8 @@ wire qsfpdd1_mac_1_rx_axis_tlast_int; wire [AXIS_ETH_RX_USER_WIDTH-1:0] qsfpdd1_mac_1_rx_axis_tuser_int; wire qsfpdd1_mac_1_rx_status_int; +wire qsfpdd1_mac_1_rx_lfc_req_int; +wire [7:0] qsfpdd1_mac_1_rx_pfc_req_int; wire qsfpdd1_mac_2_tx_clk_int; wire qsfpdd1_mac_2_tx_rst_int; @@ -1058,6 +1162,10 @@ wire qsfpdd1_mac_2_tx_axis_tready_int; wire qsfpdd1_mac_2_tx_axis_tlast_int; wire [AXIS_ETH_TX_USER_WIDTH-1:0] qsfpdd1_mac_2_tx_axis_tuser_int; +wire qsfpdd1_mac_2_tx_status_int; +wire qsfpdd1_mac_2_tx_lfc_req_int; +wire [7:0] qsfpdd1_mac_2_tx_pfc_req_int; + wire qsfpdd1_mac_2_rx_clk_int; wire qsfpdd1_mac_2_rx_rst_int; @@ -1072,6 +1180,8 @@ wire qsfpdd1_mac_2_rx_axis_tlast_int; wire [AXIS_ETH_RX_USER_WIDTH-1:0] qsfpdd1_mac_2_rx_axis_tuser_int; wire qsfpdd1_mac_2_rx_status_int; +wire qsfpdd1_mac_2_rx_lfc_req_int; +wire [7:0] qsfpdd1_mac_2_rx_pfc_req_int; wire qsfpdd1_mac_3_tx_clk_int; wire qsfpdd1_mac_3_tx_rst_int; @@ -1091,6 +1201,10 @@ wire qsfpdd1_mac_3_tx_axis_tready_int; wire qsfpdd1_mac_3_tx_axis_tlast_int; wire [AXIS_ETH_TX_USER_WIDTH-1:0] qsfpdd1_mac_3_tx_axis_tuser_int; +wire qsfpdd1_mac_3_tx_status_int; +wire qsfpdd1_mac_3_tx_lfc_req_int; +wire [7:0] qsfpdd1_mac_3_tx_pfc_req_int; + wire qsfpdd1_mac_3_rx_clk_int; wire qsfpdd1_mac_3_rx_rst_int; @@ -1105,6 +1219,8 @@ wire qsfpdd1_mac_3_rx_axis_tlast_int; wire [AXIS_ETH_RX_USER_WIDTH-1:0] qsfpdd1_mac_3_rx_axis_tuser_int; wire qsfpdd1_mac_3_rx_status_int; +wire qsfpdd1_mac_3_rx_lfc_req_int; +wire [7:0] qsfpdd1_mac_3_rx_pfc_req_int; wire qsfpdd1_mac_4_tx_clk_int; wire qsfpdd1_mac_4_tx_rst_int; @@ -1124,6 +1240,10 @@ wire qsfpdd1_mac_4_tx_axis_tready_int; wire qsfpdd1_mac_4_tx_axis_tlast_int; wire [AXIS_ETH_TX_USER_WIDTH-1:0] qsfpdd1_mac_4_tx_axis_tuser_int; +wire qsfpdd1_mac_4_tx_status_int; +wire qsfpdd1_mac_4_tx_lfc_req_int; +wire [7:0] qsfpdd1_mac_4_tx_pfc_req_int; + wire qsfpdd1_mac_4_rx_clk_int; wire qsfpdd1_mac_4_rx_rst_int; @@ -1138,6 +1258,8 @@ wire qsfpdd1_mac_4_rx_axis_tlast_int; wire [AXIS_ETH_RX_USER_WIDTH-1:0] qsfpdd1_mac_4_rx_axis_tuser_int; wire qsfpdd1_mac_4_rx_status_int; +wire qsfpdd1_mac_4_rx_lfc_req_int; +wire [7:0] qsfpdd1_mac_4_rx_pfc_req_int; wire qsfpdd1_mac_5_tx_clk_int; wire qsfpdd1_mac_5_tx_rst_int; @@ -1157,6 +1279,10 @@ wire qsfpdd1_mac_5_tx_axis_tready_int; wire qsfpdd1_mac_5_tx_axis_tlast_int; wire [AXIS_ETH_TX_USER_WIDTH-1:0] qsfpdd1_mac_5_tx_axis_tuser_int; +wire qsfpdd1_mac_5_tx_status_int; +wire qsfpdd1_mac_5_tx_lfc_req_int; +wire [7:0] qsfpdd1_mac_5_tx_pfc_req_int; + wire qsfpdd1_mac_5_rx_clk_int; wire qsfpdd1_mac_5_rx_rst_int; @@ -1171,6 +1297,8 @@ wire qsfpdd1_mac_5_rx_axis_tlast_int; wire [AXIS_ETH_RX_USER_WIDTH-1:0] qsfpdd1_mac_5_rx_axis_tuser_int; wire qsfpdd1_mac_5_rx_status_int; +wire qsfpdd1_mac_5_rx_lfc_req_int; +wire [7:0] qsfpdd1_mac_5_rx_pfc_req_int; wire qsfpdd1_mac_6_tx_clk_int; wire qsfpdd1_mac_6_tx_rst_int; @@ -1190,6 +1318,10 @@ wire qsfpdd1_mac_6_tx_axis_tready_int; wire qsfpdd1_mac_6_tx_axis_tlast_int; wire [AXIS_ETH_TX_USER_WIDTH-1:0] qsfpdd1_mac_6_tx_axis_tuser_int; +wire qsfpdd1_mac_6_tx_status_int; +wire qsfpdd1_mac_6_tx_lfc_req_int; +wire [7:0] qsfpdd1_mac_6_tx_pfc_req_int; + wire qsfpdd1_mac_6_rx_clk_int; wire qsfpdd1_mac_6_rx_rst_int; @@ -1204,6 +1336,8 @@ wire qsfpdd1_mac_6_rx_axis_tlast_int; wire [AXIS_ETH_RX_USER_WIDTH-1:0] qsfpdd1_mac_6_rx_axis_tuser_int; wire qsfpdd1_mac_6_rx_status_int; +wire qsfpdd1_mac_6_rx_lfc_req_int; +wire [7:0] qsfpdd1_mac_6_rx_pfc_req_int; wire qsfpdd1_mac_7_tx_clk_int; wire qsfpdd1_mac_7_tx_rst_int; @@ -1223,6 +1357,10 @@ wire qsfpdd1_mac_7_tx_axis_tready_int; wire qsfpdd1_mac_7_tx_axis_tlast_int; wire [AXIS_ETH_TX_USER_WIDTH-1:0] qsfpdd1_mac_7_tx_axis_tuser_int; +wire qsfpdd1_mac_7_tx_status_int; +wire qsfpdd1_mac_7_tx_lfc_req_int; +wire [7:0] qsfpdd1_mac_7_tx_pfc_req_int; + wire qsfpdd1_mac_7_rx_clk_int; wire qsfpdd1_mac_7_rx_rst_int; @@ -1237,6 +1375,8 @@ wire qsfpdd1_mac_7_rx_axis_tlast_int; wire [AXIS_ETH_RX_USER_WIDTH-1:0] qsfpdd1_mac_7_rx_axis_tuser_int; wire qsfpdd1_mac_7_rx_status_int; +wire qsfpdd1_mac_7_rx_lfc_req_int; +wire [7:0] qsfpdd1_mac_7_rx_pfc_req_int; wire qsfpdd1_mac_8_tx_clk_int; wire qsfpdd1_mac_8_tx_rst_int; @@ -1256,6 +1396,10 @@ wire qsfpdd1_mac_8_tx_axis_tready_int; wire qsfpdd1_mac_8_tx_axis_tlast_int; wire [AXIS_ETH_TX_USER_WIDTH-1:0] qsfpdd1_mac_8_tx_axis_tuser_int; +wire qsfpdd1_mac_8_tx_status_int; +wire qsfpdd1_mac_8_tx_lfc_req_int; +wire [7:0] qsfpdd1_mac_8_tx_pfc_req_int; + wire qsfpdd1_mac_8_rx_clk_int; wire qsfpdd1_mac_8_rx_rst_int; @@ -1270,6 +1414,8 @@ wire qsfpdd1_mac_8_rx_axis_tlast_int; wire [AXIS_ETH_RX_USER_WIDTH-1:0] qsfpdd1_mac_8_rx_axis_tuser_int; wire qsfpdd1_mac_8_rx_status_int; +wire qsfpdd1_mac_8_rx_lfc_req_int; +wire [7:0] qsfpdd1_mac_8_rx_pfc_req_int; eth_mac_dual_quad_wrapper #( .PTP_TS_WIDTH(PTP_TS_WIDTH), @@ -1309,6 +1455,10 @@ qsfpdd1_mac_inst ( .mac_1_tx_axis_tlast(qsfpdd1_mac_1_tx_axis_tlast_int), .mac_1_tx_axis_tuser(qsfpdd1_mac_1_tx_axis_tuser_int), + .mac_1_tx_status(qsfpdd1_mac_1_tx_status_int), + .mac_1_tx_lfc_req(qsfpdd1_mac_1_tx_lfc_req_int), + .mac_1_tx_pfc_req(qsfpdd1_mac_1_tx_pfc_req_int), + .mac_1_rx_clk(qsfpdd1_mac_1_rx_clk_int), .mac_1_rx_rst(qsfpdd1_mac_1_rx_rst_int), @@ -1323,6 +1473,8 @@ qsfpdd1_mac_inst ( .mac_1_rx_axis_tuser(qsfpdd1_mac_1_rx_axis_tuser_int), .mac_1_rx_status(qsfpdd1_mac_1_rx_status_int), + .mac_1_rx_lfc_req(qsfpdd1_mac_1_rx_lfc_req_int), + .mac_1_rx_pfc_req(qsfpdd1_mac_1_rx_pfc_req_int), .mac_2_tx_clk(qsfpdd1_mac_3_tx_clk_int), .mac_2_tx_rst(qsfpdd1_mac_3_tx_rst_int), @@ -1342,6 +1494,10 @@ qsfpdd1_mac_inst ( .mac_2_tx_axis_tlast(qsfpdd1_mac_3_tx_axis_tlast_int), .mac_2_tx_axis_tuser(qsfpdd1_mac_3_tx_axis_tuser_int), + .mac_2_tx_status(qsfpdd1_mac_3_tx_status_int), + .mac_2_tx_lfc_req(qsfpdd1_mac_3_tx_lfc_req_int), + .mac_2_tx_pfc_req(qsfpdd1_mac_3_tx_pfc_req_int), + .mac_2_rx_clk(qsfpdd1_mac_3_rx_clk_int), .mac_2_rx_rst(qsfpdd1_mac_3_rx_rst_int), @@ -1356,6 +1512,8 @@ qsfpdd1_mac_inst ( .mac_2_rx_axis_tuser(qsfpdd1_mac_3_rx_axis_tuser_int), .mac_2_rx_status(qsfpdd1_mac_3_rx_status_int), + .mac_2_rx_lfc_req(qsfpdd1_mac_3_rx_lfc_req_int), + .mac_2_rx_pfc_req(qsfpdd1_mac_3_rx_pfc_req_int), .mac_3_tx_clk(qsfpdd1_mac_2_tx_clk_int), .mac_3_tx_rst(qsfpdd1_mac_2_tx_rst_int), @@ -1375,6 +1533,10 @@ qsfpdd1_mac_inst ( .mac_3_tx_axis_tlast(qsfpdd1_mac_2_tx_axis_tlast_int), .mac_3_tx_axis_tuser(qsfpdd1_mac_2_tx_axis_tuser_int), + .mac_3_tx_status(qsfpdd1_mac_2_tx_status_int), + .mac_3_tx_lfc_req(qsfpdd1_mac_2_tx_lfc_req_int), + .mac_3_tx_pfc_req(qsfpdd1_mac_2_tx_pfc_req_int), + .mac_3_rx_clk(qsfpdd1_mac_2_rx_clk_int), .mac_3_rx_rst(qsfpdd1_mac_2_rx_rst_int), @@ -1389,6 +1551,8 @@ qsfpdd1_mac_inst ( .mac_3_rx_axis_tuser(qsfpdd1_mac_2_rx_axis_tuser_int), .mac_3_rx_status(qsfpdd1_mac_2_rx_status_int), + .mac_3_rx_lfc_req(qsfpdd1_mac_2_rx_lfc_req_int), + .mac_3_rx_pfc_req(qsfpdd1_mac_2_rx_pfc_req_int), .mac_4_tx_clk(qsfpdd1_mac_4_tx_clk_int), .mac_4_tx_rst(qsfpdd1_mac_4_tx_rst_int), @@ -1408,6 +1572,10 @@ qsfpdd1_mac_inst ( .mac_4_tx_axis_tlast(qsfpdd1_mac_4_tx_axis_tlast_int), .mac_4_tx_axis_tuser(qsfpdd1_mac_4_tx_axis_tuser_int), + .mac_4_tx_status(qsfpdd1_mac_4_tx_status_int), + .mac_4_tx_lfc_req(qsfpdd1_mac_4_tx_lfc_req_int), + .mac_4_tx_pfc_req(qsfpdd1_mac_4_tx_pfc_req_int), + .mac_4_rx_clk(qsfpdd1_mac_4_rx_clk_int), .mac_4_rx_rst(qsfpdd1_mac_4_rx_rst_int), @@ -1422,6 +1590,8 @@ qsfpdd1_mac_inst ( .mac_4_rx_axis_tuser(qsfpdd1_mac_4_rx_axis_tuser_int), .mac_4_rx_status(qsfpdd1_mac_4_rx_status_int), + .mac_4_rx_lfc_req(qsfpdd1_mac_4_rx_lfc_req_int), + .mac_4_rx_pfc_req(qsfpdd1_mac_4_rx_pfc_req_int), .mac_5_tx_clk(qsfpdd1_mac_5_tx_clk_int), .mac_5_tx_rst(qsfpdd1_mac_5_tx_rst_int), @@ -1441,6 +1611,10 @@ qsfpdd1_mac_inst ( .mac_5_tx_axis_tlast(qsfpdd1_mac_5_tx_axis_tlast_int), .mac_5_tx_axis_tuser(qsfpdd1_mac_5_tx_axis_tuser_int), + .mac_5_tx_status(qsfpdd1_mac_5_tx_status_int), + .mac_5_tx_lfc_req(qsfpdd1_mac_5_tx_lfc_req_int), + .mac_5_tx_pfc_req(qsfpdd1_mac_5_tx_pfc_req_int), + .mac_5_rx_clk(qsfpdd1_mac_5_rx_clk_int), .mac_5_rx_rst(qsfpdd1_mac_5_rx_rst_int), @@ -1455,6 +1629,8 @@ qsfpdd1_mac_inst ( .mac_5_rx_axis_tuser(qsfpdd1_mac_5_rx_axis_tuser_int), .mac_5_rx_status(qsfpdd1_mac_5_rx_status_int), + .mac_5_rx_lfc_req(qsfpdd1_mac_5_rx_lfc_req_int), + .mac_5_rx_pfc_req(qsfpdd1_mac_5_rx_pfc_req_int), .mac_6_tx_clk(qsfpdd1_mac_7_tx_clk_int), .mac_6_tx_rst(qsfpdd1_mac_7_tx_rst_int), @@ -1474,6 +1650,10 @@ qsfpdd1_mac_inst ( .mac_6_tx_axis_tlast(qsfpdd1_mac_7_tx_axis_tlast_int), .mac_6_tx_axis_tuser(qsfpdd1_mac_7_tx_axis_tuser_int), + .mac_6_tx_status(qsfpdd1_mac_7_tx_status_int), + .mac_6_tx_lfc_req(qsfpdd1_mac_7_tx_lfc_req_int), + .mac_6_tx_pfc_req(qsfpdd1_mac_7_tx_pfc_req_int), + .mac_6_rx_clk(qsfpdd1_mac_7_rx_clk_int), .mac_6_rx_rst(qsfpdd1_mac_7_rx_rst_int), @@ -1488,6 +1668,8 @@ qsfpdd1_mac_inst ( .mac_6_rx_axis_tuser(qsfpdd1_mac_7_rx_axis_tuser_int), .mac_6_rx_status(qsfpdd1_mac_7_rx_status_int), + .mac_6_rx_lfc_req(qsfpdd1_mac_7_rx_lfc_req_int), + .mac_6_rx_pfc_req(qsfpdd1_mac_7_rx_pfc_req_int), .mac_7_tx_clk(qsfpdd1_mac_6_tx_clk_int), .mac_7_tx_rst(qsfpdd1_mac_6_tx_rst_int), @@ -1507,6 +1689,10 @@ qsfpdd1_mac_inst ( .mac_7_tx_axis_tlast(qsfpdd1_mac_6_tx_axis_tlast_int), .mac_7_tx_axis_tuser(qsfpdd1_mac_6_tx_axis_tuser_int), + .mac_7_tx_status(qsfpdd1_mac_6_tx_status_int), + .mac_7_tx_lfc_req(qsfpdd1_mac_6_tx_lfc_req_int), + .mac_7_tx_pfc_req(qsfpdd1_mac_6_tx_pfc_req_int), + .mac_7_rx_clk(qsfpdd1_mac_6_rx_clk_int), .mac_7_rx_rst(qsfpdd1_mac_6_rx_rst_int), @@ -1521,6 +1707,8 @@ qsfpdd1_mac_inst ( .mac_7_rx_axis_tuser(qsfpdd1_mac_6_rx_axis_tuser_int), .mac_7_rx_status(qsfpdd1_mac_6_rx_status_int), + .mac_7_rx_lfc_req(qsfpdd1_mac_6_rx_lfc_req_int), + .mac_7_rx_pfc_req(qsfpdd1_mac_6_rx_pfc_req_int), .mac_8_tx_clk(qsfpdd1_mac_8_tx_clk_int), .mac_8_tx_rst(qsfpdd1_mac_8_tx_rst_int), @@ -1540,6 +1728,10 @@ qsfpdd1_mac_inst ( .mac_8_tx_axis_tlast(qsfpdd1_mac_8_tx_axis_tlast_int), .mac_8_tx_axis_tuser(qsfpdd1_mac_8_tx_axis_tuser_int), + .mac_8_tx_status(qsfpdd1_mac_8_tx_status_int), + .mac_8_tx_lfc_req(qsfpdd1_mac_8_tx_lfc_req_int), + .mac_8_tx_pfc_req(qsfpdd1_mac_8_tx_pfc_req_int), + .mac_8_rx_clk(qsfpdd1_mac_8_rx_clk_int), .mac_8_rx_rst(qsfpdd1_mac_8_rx_rst_int), @@ -1553,7 +1745,9 @@ qsfpdd1_mac_inst ( .mac_8_rx_axis_tlast(qsfpdd1_mac_8_rx_axis_tlast_int), .mac_8_rx_axis_tuser(qsfpdd1_mac_8_rx_axis_tuser_int), - .mac_8_rx_status(qsfpdd1_mac_8_rx_status_int) + .mac_8_rx_status(qsfpdd1_mac_8_rx_status_int), + .mac_8_rx_lfc_req(qsfpdd1_mac_8_rx_lfc_req_int), + .mac_8_rx_pfc_req(qsfpdd1_mac_8_rx_pfc_req_int) ); wire ptp_clk; @@ -1646,6 +1840,8 @@ fpga_core #( .TX_CHECKSUM_ENABLE(TX_CHECKSUM_ENABLE), .RX_HASH_ENABLE(RX_HASH_ENABLE), .RX_CHECKSUM_ENABLE(RX_CHECKSUM_ENABLE), + .PFC_ENABLE(PFC_ENABLE), + .LFC_ENABLE(LFC_ENABLE), .TX_FIFO_DEPTH(TX_FIFO_DEPTH), .RX_FIFO_DEPTH(RX_FIFO_DEPTH), .MAX_TX_SIZE(MAX_TX_SIZE), @@ -1805,6 +2001,10 @@ core_inst ( .qsfpdd0_mac_1_tx_axis_tlast(qsfpdd0_mac_1_tx_axis_tlast_int), .qsfpdd0_mac_1_tx_axis_tuser(qsfpdd0_mac_1_tx_axis_tuser_int), + .qsfpdd0_mac_1_tx_status(qsfpdd0_mac_1_tx_status_int), + .qsfpdd0_mac_1_tx_lfc_req(qsfpdd0_mac_1_tx_lfc_req_int), + .qsfpdd0_mac_1_tx_pfc_req(qsfpdd0_mac_1_tx_pfc_req_int), + .qsfpdd0_mac_1_rx_clk(qsfpdd0_mac_1_rx_clk_int), .qsfpdd0_mac_1_rx_rst(qsfpdd0_mac_1_rx_rst_int), @@ -1819,6 +2019,8 @@ core_inst ( .qsfpdd0_mac_1_rx_axis_tuser(qsfpdd0_mac_1_rx_axis_tuser_int), .qsfpdd0_mac_1_rx_status(qsfpdd0_mac_1_rx_status_int), + .qsfpdd0_mac_1_rx_lfc_req(qsfpdd0_mac_1_rx_lfc_req_int), + .qsfpdd0_mac_1_rx_pfc_req(qsfpdd0_mac_1_rx_pfc_req_int), .qsfpdd0_mac_2_tx_clk(qsfpdd0_mac_2_tx_clk_int), .qsfpdd0_mac_2_tx_rst(qsfpdd0_mac_2_tx_rst_int), @@ -1838,6 +2040,10 @@ core_inst ( .qsfpdd0_mac_2_tx_axis_tlast(qsfpdd0_mac_2_tx_axis_tlast_int), .qsfpdd0_mac_2_tx_axis_tuser(qsfpdd0_mac_2_tx_axis_tuser_int), + .qsfpdd0_mac_2_tx_status(qsfpdd0_mac_2_tx_status_int), + .qsfpdd0_mac_2_tx_lfc_req(qsfpdd0_mac_2_tx_lfc_req_int), + .qsfpdd0_mac_2_tx_pfc_req(qsfpdd0_mac_2_tx_pfc_req_int), + .qsfpdd0_mac_2_rx_clk(qsfpdd0_mac_2_rx_clk_int), .qsfpdd0_mac_2_rx_rst(qsfpdd0_mac_2_rx_rst_int), @@ -1852,6 +2058,8 @@ core_inst ( .qsfpdd0_mac_2_rx_axis_tuser(qsfpdd0_mac_2_rx_axis_tuser_int), .qsfpdd0_mac_2_rx_status(qsfpdd0_mac_2_rx_status_int), + .qsfpdd0_mac_2_rx_lfc_req(qsfpdd0_mac_2_rx_lfc_req_int), + .qsfpdd0_mac_2_rx_pfc_req(qsfpdd0_mac_2_rx_pfc_req_int), .qsfpdd0_mac_3_tx_clk(qsfpdd0_mac_3_tx_clk_int), .qsfpdd0_mac_3_tx_rst(qsfpdd0_mac_3_tx_rst_int), @@ -1871,6 +2079,10 @@ core_inst ( .qsfpdd0_mac_3_tx_axis_tlast(qsfpdd0_mac_3_tx_axis_tlast_int), .qsfpdd0_mac_3_tx_axis_tuser(qsfpdd0_mac_3_tx_axis_tuser_int), + .qsfpdd0_mac_3_tx_status(qsfpdd0_mac_3_tx_status_int), + .qsfpdd0_mac_3_tx_lfc_req(qsfpdd0_mac_3_tx_lfc_req_int), + .qsfpdd0_mac_3_tx_pfc_req(qsfpdd0_mac_3_tx_pfc_req_int), + .qsfpdd0_mac_3_rx_clk(qsfpdd0_mac_3_rx_clk_int), .qsfpdd0_mac_3_rx_rst(qsfpdd0_mac_3_rx_rst_int), @@ -1885,6 +2097,8 @@ core_inst ( .qsfpdd0_mac_3_rx_axis_tuser(qsfpdd0_mac_3_rx_axis_tuser_int), .qsfpdd0_mac_3_rx_status(qsfpdd0_mac_3_rx_status_int), + .qsfpdd0_mac_3_rx_lfc_req(qsfpdd0_mac_3_rx_lfc_req_int), + .qsfpdd0_mac_3_rx_pfc_req(qsfpdd0_mac_3_rx_pfc_req_int), .qsfpdd0_mac_4_tx_clk(qsfpdd0_mac_4_tx_clk_int), .qsfpdd0_mac_4_tx_rst(qsfpdd0_mac_4_tx_rst_int), @@ -1904,6 +2118,10 @@ core_inst ( .qsfpdd0_mac_4_tx_axis_tlast(qsfpdd0_mac_4_tx_axis_tlast_int), .qsfpdd0_mac_4_tx_axis_tuser(qsfpdd0_mac_4_tx_axis_tuser_int), + .qsfpdd0_mac_4_tx_status(qsfpdd0_mac_4_tx_status_int), + .qsfpdd0_mac_4_tx_lfc_req(qsfpdd0_mac_4_tx_lfc_req_int), + .qsfpdd0_mac_4_tx_pfc_req(qsfpdd0_mac_4_tx_pfc_req_int), + .qsfpdd0_mac_4_rx_clk(qsfpdd0_mac_4_rx_clk_int), .qsfpdd0_mac_4_rx_rst(qsfpdd0_mac_4_rx_rst_int), @@ -1918,6 +2136,8 @@ core_inst ( .qsfpdd0_mac_4_rx_axis_tuser(qsfpdd0_mac_4_rx_axis_tuser_int), .qsfpdd0_mac_4_rx_status(qsfpdd0_mac_4_rx_status_int), + .qsfpdd0_mac_4_rx_lfc_req(qsfpdd0_mac_4_rx_lfc_req_int), + .qsfpdd0_mac_4_rx_pfc_req(qsfpdd0_mac_4_rx_pfc_req_int), .qsfpdd0_mac_5_tx_clk(qsfpdd0_mac_5_tx_clk_int), .qsfpdd0_mac_5_tx_rst(qsfpdd0_mac_5_tx_rst_int), @@ -1937,6 +2157,10 @@ core_inst ( .qsfpdd0_mac_5_tx_axis_tlast(qsfpdd0_mac_5_tx_axis_tlast_int), .qsfpdd0_mac_5_tx_axis_tuser(qsfpdd0_mac_5_tx_axis_tuser_int), + .qsfpdd0_mac_5_tx_status(qsfpdd0_mac_5_tx_status_int), + .qsfpdd0_mac_5_tx_lfc_req(qsfpdd0_mac_5_tx_lfc_req_int), + .qsfpdd0_mac_5_tx_pfc_req(qsfpdd0_mac_5_tx_pfc_req_int), + .qsfpdd0_mac_5_rx_clk(qsfpdd0_mac_5_rx_clk_int), .qsfpdd0_mac_5_rx_rst(qsfpdd0_mac_5_rx_rst_int), @@ -1951,6 +2175,8 @@ core_inst ( .qsfpdd0_mac_5_rx_axis_tuser(qsfpdd0_mac_5_rx_axis_tuser_int), .qsfpdd0_mac_5_rx_status(qsfpdd0_mac_5_rx_status_int), + .qsfpdd0_mac_5_rx_lfc_req(qsfpdd0_mac_5_rx_lfc_req_int), + .qsfpdd0_mac_5_rx_pfc_req(qsfpdd0_mac_5_rx_pfc_req_int), .qsfpdd0_mac_6_tx_clk(qsfpdd0_mac_6_tx_clk_int), .qsfpdd0_mac_6_tx_rst(qsfpdd0_mac_6_tx_rst_int), @@ -1970,6 +2196,10 @@ core_inst ( .qsfpdd0_mac_6_tx_axis_tlast(qsfpdd0_mac_6_tx_axis_tlast_int), .qsfpdd0_mac_6_tx_axis_tuser(qsfpdd0_mac_6_tx_axis_tuser_int), + .qsfpdd0_mac_6_tx_status(qsfpdd0_mac_6_tx_status_int), + .qsfpdd0_mac_6_tx_lfc_req(qsfpdd0_mac_6_tx_lfc_req_int), + .qsfpdd0_mac_6_tx_pfc_req(qsfpdd0_mac_6_tx_pfc_req_int), + .qsfpdd0_mac_6_rx_clk(qsfpdd0_mac_6_rx_clk_int), .qsfpdd0_mac_6_rx_rst(qsfpdd0_mac_6_rx_rst_int), @@ -1984,6 +2214,8 @@ core_inst ( .qsfpdd0_mac_6_rx_axis_tuser(qsfpdd0_mac_6_rx_axis_tuser_int), .qsfpdd0_mac_6_rx_status(qsfpdd0_mac_6_rx_status_int), + .qsfpdd0_mac_6_rx_lfc_req(qsfpdd0_mac_6_rx_lfc_req_int), + .qsfpdd0_mac_6_rx_pfc_req(qsfpdd0_mac_6_rx_pfc_req_int), .qsfpdd0_mac_7_tx_clk(qsfpdd0_mac_7_tx_clk_int), .qsfpdd0_mac_7_tx_rst(qsfpdd0_mac_7_tx_rst_int), @@ -2003,6 +2235,10 @@ core_inst ( .qsfpdd0_mac_7_tx_axis_tlast(qsfpdd0_mac_7_tx_axis_tlast_int), .qsfpdd0_mac_7_tx_axis_tuser(qsfpdd0_mac_7_tx_axis_tuser_int), + .qsfpdd0_mac_7_tx_status(qsfpdd0_mac_7_tx_status_int), + .qsfpdd0_mac_7_tx_lfc_req(qsfpdd0_mac_7_tx_lfc_req_int), + .qsfpdd0_mac_7_tx_pfc_req(qsfpdd0_mac_7_tx_pfc_req_int), + .qsfpdd0_mac_7_rx_clk(qsfpdd0_mac_7_rx_clk_int), .qsfpdd0_mac_7_rx_rst(qsfpdd0_mac_7_rx_rst_int), @@ -2017,6 +2253,8 @@ core_inst ( .qsfpdd0_mac_7_rx_axis_tuser(qsfpdd0_mac_7_rx_axis_tuser_int), .qsfpdd0_mac_7_rx_status(qsfpdd0_mac_7_rx_status_int), + .qsfpdd0_mac_7_rx_lfc_req(qsfpdd0_mac_7_rx_lfc_req_int), + .qsfpdd0_mac_7_rx_pfc_req(qsfpdd0_mac_7_rx_pfc_req_int), .qsfpdd0_mac_8_tx_clk(qsfpdd0_mac_8_tx_clk_int), .qsfpdd0_mac_8_tx_rst(qsfpdd0_mac_8_tx_rst_int), @@ -2036,6 +2274,10 @@ core_inst ( .qsfpdd0_mac_8_tx_axis_tlast(qsfpdd0_mac_8_tx_axis_tlast_int), .qsfpdd0_mac_8_tx_axis_tuser(qsfpdd0_mac_8_tx_axis_tuser_int), + .qsfpdd0_mac_8_tx_status(qsfpdd0_mac_8_tx_status_int), + .qsfpdd0_mac_8_tx_lfc_req(qsfpdd0_mac_8_tx_lfc_req_int), + .qsfpdd0_mac_8_tx_pfc_req(qsfpdd0_mac_8_tx_pfc_req_int), + .qsfpdd0_mac_8_rx_clk(qsfpdd0_mac_8_rx_clk_int), .qsfpdd0_mac_8_rx_rst(qsfpdd0_mac_8_rx_rst_int), @@ -2050,6 +2292,8 @@ core_inst ( .qsfpdd0_mac_8_rx_axis_tuser(qsfpdd0_mac_8_rx_axis_tuser_int), .qsfpdd0_mac_8_rx_status(qsfpdd0_mac_8_rx_status_int), + .qsfpdd0_mac_8_rx_lfc_req(qsfpdd0_mac_8_rx_lfc_req_int), + .qsfpdd0_mac_8_rx_pfc_req(qsfpdd0_mac_8_rx_pfc_req_int), .qsfpdd1_mac_1_tx_clk(qsfpdd1_mac_1_tx_clk_int), .qsfpdd1_mac_1_tx_rst(qsfpdd1_mac_1_tx_rst_int), @@ -2069,6 +2313,10 @@ core_inst ( .qsfpdd1_mac_1_tx_axis_tlast(qsfpdd1_mac_1_tx_axis_tlast_int), .qsfpdd1_mac_1_tx_axis_tuser(qsfpdd1_mac_1_tx_axis_tuser_int), + .qsfpdd1_mac_1_tx_status(qsfpdd1_mac_1_tx_status_int), + .qsfpdd1_mac_1_tx_lfc_req(qsfpdd1_mac_1_tx_lfc_req_int), + .qsfpdd1_mac_1_tx_pfc_req(qsfpdd1_mac_1_tx_pfc_req_int), + .qsfpdd1_mac_1_rx_clk(qsfpdd1_mac_1_rx_clk_int), .qsfpdd1_mac_1_rx_rst(qsfpdd1_mac_1_rx_rst_int), @@ -2083,6 +2331,8 @@ core_inst ( .qsfpdd1_mac_1_rx_axis_tuser(qsfpdd1_mac_1_rx_axis_tuser_int), .qsfpdd1_mac_1_rx_status(qsfpdd1_mac_1_rx_status_int), + .qsfpdd1_mac_1_rx_lfc_req(qsfpdd1_mac_1_rx_lfc_req_int), + .qsfpdd1_mac_1_rx_pfc_req(qsfpdd1_mac_1_rx_pfc_req_int), .qsfpdd1_mac_2_tx_clk(qsfpdd1_mac_2_tx_clk_int), .qsfpdd1_mac_2_tx_rst(qsfpdd1_mac_2_tx_rst_int), @@ -2102,6 +2352,10 @@ core_inst ( .qsfpdd1_mac_2_tx_axis_tlast(qsfpdd1_mac_2_tx_axis_tlast_int), .qsfpdd1_mac_2_tx_axis_tuser(qsfpdd1_mac_2_tx_axis_tuser_int), + .qsfpdd1_mac_2_tx_status(qsfpdd1_mac_2_tx_status_int), + .qsfpdd1_mac_2_tx_lfc_req(qsfpdd1_mac_2_tx_lfc_req_int), + .qsfpdd1_mac_2_tx_pfc_req(qsfpdd1_mac_2_tx_pfc_req_int), + .qsfpdd1_mac_2_rx_clk(qsfpdd1_mac_2_rx_clk_int), .qsfpdd1_mac_2_rx_rst(qsfpdd1_mac_2_rx_rst_int), @@ -2116,6 +2370,8 @@ core_inst ( .qsfpdd1_mac_2_rx_axis_tuser(qsfpdd1_mac_2_rx_axis_tuser_int), .qsfpdd1_mac_2_rx_status(qsfpdd1_mac_2_rx_status_int), + .qsfpdd1_mac_2_rx_lfc_req(qsfpdd1_mac_2_rx_lfc_req_int), + .qsfpdd1_mac_2_rx_pfc_req(qsfpdd1_mac_2_rx_pfc_req_int), .qsfpdd1_mac_3_tx_clk(qsfpdd1_mac_3_tx_clk_int), .qsfpdd1_mac_3_tx_rst(qsfpdd1_mac_3_tx_rst_int), @@ -2135,6 +2391,10 @@ core_inst ( .qsfpdd1_mac_3_tx_axis_tlast(qsfpdd1_mac_3_tx_axis_tlast_int), .qsfpdd1_mac_3_tx_axis_tuser(qsfpdd1_mac_3_tx_axis_tuser_int), + .qsfpdd1_mac_3_tx_status(qsfpdd1_mac_3_tx_status_int), + .qsfpdd1_mac_3_tx_lfc_req(qsfpdd1_mac_3_tx_lfc_req_int), + .qsfpdd1_mac_3_tx_pfc_req(qsfpdd1_mac_3_tx_pfc_req_int), + .qsfpdd1_mac_3_rx_clk(qsfpdd1_mac_3_rx_clk_int), .qsfpdd1_mac_3_rx_rst(qsfpdd1_mac_3_rx_rst_int), @@ -2149,6 +2409,8 @@ core_inst ( .qsfpdd1_mac_3_rx_axis_tuser(qsfpdd1_mac_3_rx_axis_tuser_int), .qsfpdd1_mac_3_rx_status(qsfpdd1_mac_3_rx_status_int), + .qsfpdd1_mac_3_rx_lfc_req(qsfpdd1_mac_3_rx_lfc_req_int), + .qsfpdd1_mac_3_rx_pfc_req(qsfpdd1_mac_3_rx_pfc_req_int), .qsfpdd1_mac_4_tx_clk(qsfpdd1_mac_4_tx_clk_int), .qsfpdd1_mac_4_tx_rst(qsfpdd1_mac_4_tx_rst_int), @@ -2168,6 +2430,10 @@ core_inst ( .qsfpdd1_mac_4_tx_axis_tlast(qsfpdd1_mac_4_tx_axis_tlast_int), .qsfpdd1_mac_4_tx_axis_tuser(qsfpdd1_mac_4_tx_axis_tuser_int), + .qsfpdd1_mac_4_tx_status(qsfpdd1_mac_4_tx_status_int), + .qsfpdd1_mac_4_tx_lfc_req(qsfpdd1_mac_4_tx_lfc_req_int), + .qsfpdd1_mac_4_tx_pfc_req(qsfpdd1_mac_4_tx_pfc_req_int), + .qsfpdd1_mac_4_rx_clk(qsfpdd1_mac_4_rx_clk_int), .qsfpdd1_mac_4_rx_rst(qsfpdd1_mac_4_rx_rst_int), @@ -2182,6 +2448,8 @@ core_inst ( .qsfpdd1_mac_4_rx_axis_tuser(qsfpdd1_mac_4_rx_axis_tuser_int), .qsfpdd1_mac_4_rx_status(qsfpdd1_mac_4_rx_status_int), + .qsfpdd1_mac_4_rx_lfc_req(qsfpdd1_mac_4_rx_lfc_req_int), + .qsfpdd1_mac_4_rx_pfc_req(qsfpdd1_mac_4_rx_pfc_req_int), .qsfpdd1_mac_5_tx_clk(qsfpdd1_mac_5_tx_clk_int), .qsfpdd1_mac_5_tx_rst(qsfpdd1_mac_5_tx_rst_int), @@ -2201,6 +2469,10 @@ core_inst ( .qsfpdd1_mac_5_tx_axis_tlast(qsfpdd1_mac_5_tx_axis_tlast_int), .qsfpdd1_mac_5_tx_axis_tuser(qsfpdd1_mac_5_tx_axis_tuser_int), + .qsfpdd1_mac_5_tx_status(qsfpdd1_mac_5_tx_status_int), + .qsfpdd1_mac_5_tx_lfc_req(qsfpdd1_mac_5_tx_lfc_req_int), + .qsfpdd1_mac_5_tx_pfc_req(qsfpdd1_mac_5_tx_pfc_req_int), + .qsfpdd1_mac_5_rx_clk(qsfpdd1_mac_5_rx_clk_int), .qsfpdd1_mac_5_rx_rst(qsfpdd1_mac_5_rx_rst_int), @@ -2215,6 +2487,8 @@ core_inst ( .qsfpdd1_mac_5_rx_axis_tuser(qsfpdd1_mac_5_rx_axis_tuser_int), .qsfpdd1_mac_5_rx_status(qsfpdd1_mac_5_rx_status_int), + .qsfpdd1_mac_5_rx_lfc_req(qsfpdd1_mac_5_rx_lfc_req_int), + .qsfpdd1_mac_5_rx_pfc_req(qsfpdd1_mac_5_rx_pfc_req_int), .qsfpdd1_mac_6_tx_clk(qsfpdd1_mac_6_tx_clk_int), .qsfpdd1_mac_6_tx_rst(qsfpdd1_mac_6_tx_rst_int), @@ -2234,6 +2508,10 @@ core_inst ( .qsfpdd1_mac_6_tx_axis_tlast(qsfpdd1_mac_6_tx_axis_tlast_int), .qsfpdd1_mac_6_tx_axis_tuser(qsfpdd1_mac_6_tx_axis_tuser_int), + .qsfpdd1_mac_6_tx_status(qsfpdd1_mac_6_tx_status_int), + .qsfpdd1_mac_6_tx_lfc_req(qsfpdd1_mac_6_tx_lfc_req_int), + .qsfpdd1_mac_6_tx_pfc_req(qsfpdd1_mac_6_tx_pfc_req_int), + .qsfpdd1_mac_6_rx_clk(qsfpdd1_mac_6_rx_clk_int), .qsfpdd1_mac_6_rx_rst(qsfpdd1_mac_6_rx_rst_int), @@ -2248,6 +2526,8 @@ core_inst ( .qsfpdd1_mac_6_rx_axis_tuser(qsfpdd1_mac_6_rx_axis_tuser_int), .qsfpdd1_mac_6_rx_status(qsfpdd1_mac_6_rx_status_int), + .qsfpdd1_mac_6_rx_lfc_req(qsfpdd1_mac_6_rx_lfc_req_int), + .qsfpdd1_mac_6_rx_pfc_req(qsfpdd1_mac_6_rx_pfc_req_int), .qsfpdd1_mac_7_tx_clk(qsfpdd1_mac_7_tx_clk_int), .qsfpdd1_mac_7_tx_rst(qsfpdd1_mac_7_tx_rst_int), @@ -2267,6 +2547,10 @@ core_inst ( .qsfpdd1_mac_7_tx_axis_tlast(qsfpdd1_mac_7_tx_axis_tlast_int), .qsfpdd1_mac_7_tx_axis_tuser(qsfpdd1_mac_7_tx_axis_tuser_int), + .qsfpdd1_mac_7_tx_status(qsfpdd1_mac_7_tx_status_int), + .qsfpdd1_mac_7_tx_lfc_req(qsfpdd1_mac_7_tx_lfc_req_int), + .qsfpdd1_mac_7_tx_pfc_req(qsfpdd1_mac_7_tx_pfc_req_int), + .qsfpdd1_mac_7_rx_clk(qsfpdd1_mac_7_rx_clk_int), .qsfpdd1_mac_7_rx_rst(qsfpdd1_mac_7_rx_rst_int), @@ -2281,6 +2565,8 @@ core_inst ( .qsfpdd1_mac_7_rx_axis_tuser(qsfpdd1_mac_7_rx_axis_tuser_int), .qsfpdd1_mac_7_rx_status(qsfpdd1_mac_7_rx_status_int), + .qsfpdd1_mac_7_rx_lfc_req(qsfpdd1_mac_7_rx_lfc_req_int), + .qsfpdd1_mac_7_rx_pfc_req(qsfpdd1_mac_7_rx_pfc_req_int), .qsfpdd1_mac_8_tx_clk(qsfpdd1_mac_8_tx_clk_int), .qsfpdd1_mac_8_tx_rst(qsfpdd1_mac_8_tx_rst_int), @@ -2300,6 +2586,10 @@ core_inst ( .qsfpdd1_mac_8_tx_axis_tlast(qsfpdd1_mac_8_tx_axis_tlast_int), .qsfpdd1_mac_8_tx_axis_tuser(qsfpdd1_mac_8_tx_axis_tuser_int), + .qsfpdd1_mac_8_tx_status(qsfpdd1_mac_8_tx_status_int), + .qsfpdd1_mac_8_tx_lfc_req(qsfpdd1_mac_8_tx_lfc_req_int), + .qsfpdd1_mac_8_tx_pfc_req(qsfpdd1_mac_8_tx_pfc_req_int), + .qsfpdd1_mac_8_rx_clk(qsfpdd1_mac_8_rx_clk_int), .qsfpdd1_mac_8_rx_rst(qsfpdd1_mac_8_rx_rst_int), @@ -2314,6 +2604,8 @@ core_inst ( .qsfpdd1_mac_8_rx_axis_tuser(qsfpdd1_mac_8_rx_axis_tuser_int), .qsfpdd1_mac_8_rx_status(qsfpdd1_mac_8_rx_status_int), + .qsfpdd1_mac_8_rx_lfc_req(qsfpdd1_mac_8_rx_lfc_req_int), + .qsfpdd1_mac_8_rx_pfc_req(qsfpdd1_mac_8_rx_pfc_req_int), .qsfpdd0_modsel_l(qsfpdd0_modsel_l), .qsfpdd0_reset_l(qsfpdd0_reset_l), diff --git a/fpga/mqnic/DK_DEV_AGF014EA/fpga_25g/rtl/fpga_core.v b/fpga/mqnic/DK_DEV_AGF014EA/fpga_25g/rtl/fpga_core.v index 991d7ce37..2f5b8dc34 100644 --- a/fpga/mqnic/DK_DEV_AGF014EA/fpga_25g/rtl/fpga_core.v +++ b/fpga/mqnic/DK_DEV_AGF014EA/fpga_25g/rtl/fpga_core.v @@ -78,9 +78,8 @@ module fpga_core # parameter TX_CHECKSUM_ENABLE = 1, parameter RX_HASH_ENABLE = 1, parameter RX_CHECKSUM_ENABLE = 1, - parameter ENABLE_PADDING = 1, - parameter ENABLE_DIC = 1, - parameter MIN_FRAME_LENGTH = 64, + parameter PFC_ENABLE = 1, + parameter LFC_ENABLE = PFC_ENABLE, parameter TX_FIFO_DEPTH = 32768, parameter RX_FIFO_DEPTH = 32768, parameter MAX_TX_SIZE = 9214, @@ -240,6 +239,10 @@ module fpga_core # output wire qsfpdd0_mac_1_tx_axis_tlast, output wire [AXIS_ETH_TX_USER_WIDTH-1:0] qsfpdd0_mac_1_tx_axis_tuser, + input wire qsfpdd0_mac_1_tx_status, + output wire qsfpdd0_mac_1_tx_lfc_req, + output wire [7:0] qsfpdd0_mac_1_tx_pfc_req, + input wire qsfpdd0_mac_1_rx_clk, input wire qsfpdd0_mac_1_rx_rst, @@ -254,6 +257,8 @@ module fpga_core # input wire [AXIS_ETH_RX_USER_WIDTH-1:0] qsfpdd0_mac_1_rx_axis_tuser, input wire qsfpdd0_mac_1_rx_status, + input wire qsfpdd0_mac_1_rx_lfc_req, + input wire [7:0] qsfpdd0_mac_1_rx_pfc_req, input wire qsfpdd0_mac_2_tx_clk, input wire qsfpdd0_mac_2_tx_rst, @@ -273,6 +278,10 @@ module fpga_core # output wire qsfpdd0_mac_2_tx_axis_tlast, output wire [AXIS_ETH_TX_USER_WIDTH-1:0] qsfpdd0_mac_2_tx_axis_tuser, + input wire qsfpdd0_mac_2_tx_status, + output wire qsfpdd0_mac_2_tx_lfc_req, + output wire [7:0] qsfpdd0_mac_2_tx_pfc_req, + input wire qsfpdd0_mac_2_rx_clk, input wire qsfpdd0_mac_2_rx_rst, @@ -287,6 +296,8 @@ module fpga_core # input wire [AXIS_ETH_RX_USER_WIDTH-1:0] qsfpdd0_mac_2_rx_axis_tuser, input wire qsfpdd0_mac_2_rx_status, + input wire qsfpdd0_mac_2_rx_lfc_req, + input wire [7:0] qsfpdd0_mac_2_rx_pfc_req, input wire qsfpdd0_mac_3_tx_clk, input wire qsfpdd0_mac_3_tx_rst, @@ -306,6 +317,10 @@ module fpga_core # output wire qsfpdd0_mac_3_tx_axis_tlast, output wire [AXIS_ETH_TX_USER_WIDTH-1:0] qsfpdd0_mac_3_tx_axis_tuser, + input wire qsfpdd0_mac_3_tx_status, + output wire qsfpdd0_mac_3_tx_lfc_req, + output wire [7:0] qsfpdd0_mac_3_tx_pfc_req, + input wire qsfpdd0_mac_3_rx_clk, input wire qsfpdd0_mac_3_rx_rst, @@ -320,6 +335,8 @@ module fpga_core # input wire [AXIS_ETH_RX_USER_WIDTH-1:0] qsfpdd0_mac_3_rx_axis_tuser, input wire qsfpdd0_mac_3_rx_status, + input wire qsfpdd0_mac_3_rx_lfc_req, + input wire [7:0] qsfpdd0_mac_3_rx_pfc_req, input wire qsfpdd0_mac_4_tx_clk, input wire qsfpdd0_mac_4_tx_rst, @@ -339,6 +356,10 @@ module fpga_core # output wire qsfpdd0_mac_4_tx_axis_tlast, output wire [AXIS_ETH_TX_USER_WIDTH-1:0] qsfpdd0_mac_4_tx_axis_tuser, + input wire qsfpdd0_mac_4_tx_status, + output wire qsfpdd0_mac_4_tx_lfc_req, + output wire [7:0] qsfpdd0_mac_4_tx_pfc_req, + input wire qsfpdd0_mac_4_rx_clk, input wire qsfpdd0_mac_4_rx_rst, @@ -353,6 +374,8 @@ module fpga_core # input wire [AXIS_ETH_RX_USER_WIDTH-1:0] qsfpdd0_mac_4_rx_axis_tuser, input wire qsfpdd0_mac_4_rx_status, + input wire qsfpdd0_mac_4_rx_lfc_req, + input wire [7:0] qsfpdd0_mac_4_rx_pfc_req, input wire qsfpdd0_mac_5_tx_clk, input wire qsfpdd0_mac_5_tx_rst, @@ -372,6 +395,10 @@ module fpga_core # output wire qsfpdd0_mac_5_tx_axis_tlast, output wire [AXIS_ETH_TX_USER_WIDTH-1:0] qsfpdd0_mac_5_tx_axis_tuser, + input wire qsfpdd0_mac_5_tx_status, + output wire qsfpdd0_mac_5_tx_lfc_req, + output wire [7:0] qsfpdd0_mac_5_tx_pfc_req, + input wire qsfpdd0_mac_5_rx_clk, input wire qsfpdd0_mac_5_rx_rst, @@ -386,6 +413,8 @@ module fpga_core # input wire [AXIS_ETH_RX_USER_WIDTH-1:0] qsfpdd0_mac_5_rx_axis_tuser, input wire qsfpdd0_mac_5_rx_status, + input wire qsfpdd0_mac_5_rx_lfc_req, + input wire [7:0] qsfpdd0_mac_5_rx_pfc_req, input wire qsfpdd0_mac_6_tx_clk, input wire qsfpdd0_mac_6_tx_rst, @@ -405,6 +434,10 @@ module fpga_core # output wire qsfpdd0_mac_6_tx_axis_tlast, output wire [AXIS_ETH_TX_USER_WIDTH-1:0] qsfpdd0_mac_6_tx_axis_tuser, + input wire qsfpdd0_mac_6_tx_status, + output wire qsfpdd0_mac_6_tx_lfc_req, + output wire [7:0] qsfpdd0_mac_6_tx_pfc_req, + input wire qsfpdd0_mac_6_rx_clk, input wire qsfpdd0_mac_6_rx_rst, @@ -419,6 +452,8 @@ module fpga_core # input wire [AXIS_ETH_RX_USER_WIDTH-1:0] qsfpdd0_mac_6_rx_axis_tuser, input wire qsfpdd0_mac_6_rx_status, + input wire qsfpdd0_mac_6_rx_lfc_req, + input wire [7:0] qsfpdd0_mac_6_rx_pfc_req, input wire qsfpdd0_mac_7_tx_clk, input wire qsfpdd0_mac_7_tx_rst, @@ -438,6 +473,10 @@ module fpga_core # output wire qsfpdd0_mac_7_tx_axis_tlast, output wire [AXIS_ETH_TX_USER_WIDTH-1:0] qsfpdd0_mac_7_tx_axis_tuser, + input wire qsfpdd0_mac_7_tx_status, + output wire qsfpdd0_mac_7_tx_lfc_req, + output wire [7:0] qsfpdd0_mac_7_tx_pfc_req, + input wire qsfpdd0_mac_7_rx_clk, input wire qsfpdd0_mac_7_rx_rst, @@ -452,6 +491,8 @@ module fpga_core # input wire [AXIS_ETH_RX_USER_WIDTH-1:0] qsfpdd0_mac_7_rx_axis_tuser, input wire qsfpdd0_mac_7_rx_status, + input wire qsfpdd0_mac_7_rx_lfc_req, + input wire [7:0] qsfpdd0_mac_7_rx_pfc_req, input wire qsfpdd0_mac_8_tx_clk, input wire qsfpdd0_mac_8_tx_rst, @@ -471,6 +512,10 @@ module fpga_core # output wire qsfpdd0_mac_8_tx_axis_tlast, output wire [AXIS_ETH_TX_USER_WIDTH-1:0] qsfpdd0_mac_8_tx_axis_tuser, + input wire qsfpdd0_mac_8_tx_status, + output wire qsfpdd0_mac_8_tx_lfc_req, + output wire [7:0] qsfpdd0_mac_8_tx_pfc_req, + input wire qsfpdd0_mac_8_rx_clk, input wire qsfpdd0_mac_8_rx_rst, @@ -485,6 +530,8 @@ module fpga_core # input wire [AXIS_ETH_RX_USER_WIDTH-1:0] qsfpdd0_mac_8_rx_axis_tuser, input wire qsfpdd0_mac_8_rx_status, + input wire qsfpdd0_mac_8_rx_lfc_req, + input wire [7:0] qsfpdd0_mac_8_rx_pfc_req, input wire qsfpdd1_mac_1_tx_clk, input wire qsfpdd1_mac_1_tx_rst, @@ -504,6 +551,10 @@ module fpga_core # output wire qsfpdd1_mac_1_tx_axis_tlast, output wire [AXIS_ETH_TX_USER_WIDTH-1:0] qsfpdd1_mac_1_tx_axis_tuser, + input wire qsfpdd1_mac_1_tx_status, + output wire qsfpdd1_mac_1_tx_lfc_req, + output wire [7:0] qsfpdd1_mac_1_tx_pfc_req, + input wire qsfpdd1_mac_1_rx_clk, input wire qsfpdd1_mac_1_rx_rst, @@ -518,6 +569,8 @@ module fpga_core # input wire [AXIS_ETH_RX_USER_WIDTH-1:0] qsfpdd1_mac_1_rx_axis_tuser, input wire qsfpdd1_mac_1_rx_status, + input wire qsfpdd1_mac_1_rx_lfc_req, + input wire [7:0] qsfpdd1_mac_1_rx_pfc_req, input wire qsfpdd1_mac_2_tx_clk, input wire qsfpdd1_mac_2_tx_rst, @@ -537,6 +590,10 @@ module fpga_core # output wire qsfpdd1_mac_2_tx_axis_tlast, output wire [AXIS_ETH_TX_USER_WIDTH-1:0] qsfpdd1_mac_2_tx_axis_tuser, + input wire qsfpdd1_mac_2_tx_status, + output wire qsfpdd1_mac_2_tx_lfc_req, + output wire [7:0] qsfpdd1_mac_2_tx_pfc_req, + input wire qsfpdd1_mac_2_rx_clk, input wire qsfpdd1_mac_2_rx_rst, @@ -551,6 +608,8 @@ module fpga_core # input wire [AXIS_ETH_RX_USER_WIDTH-1:0] qsfpdd1_mac_2_rx_axis_tuser, input wire qsfpdd1_mac_2_rx_status, + input wire qsfpdd1_mac_2_rx_lfc_req, + input wire [7:0] qsfpdd1_mac_2_rx_pfc_req, input wire qsfpdd1_mac_3_tx_clk, input wire qsfpdd1_mac_3_tx_rst, @@ -570,6 +629,10 @@ module fpga_core # output wire qsfpdd1_mac_3_tx_axis_tlast, output wire [AXIS_ETH_TX_USER_WIDTH-1:0] qsfpdd1_mac_3_tx_axis_tuser, + input wire qsfpdd1_mac_3_tx_status, + output wire qsfpdd1_mac_3_tx_lfc_req, + output wire [7:0] qsfpdd1_mac_3_tx_pfc_req, + input wire qsfpdd1_mac_3_rx_clk, input wire qsfpdd1_mac_3_rx_rst, @@ -584,6 +647,8 @@ module fpga_core # input wire [AXIS_ETH_RX_USER_WIDTH-1:0] qsfpdd1_mac_3_rx_axis_tuser, input wire qsfpdd1_mac_3_rx_status, + input wire qsfpdd1_mac_3_rx_lfc_req, + input wire [7:0] qsfpdd1_mac_3_rx_pfc_req, input wire qsfpdd1_mac_4_tx_clk, input wire qsfpdd1_mac_4_tx_rst, @@ -603,6 +668,10 @@ module fpga_core # output wire qsfpdd1_mac_4_tx_axis_tlast, output wire [AXIS_ETH_TX_USER_WIDTH-1:0] qsfpdd1_mac_4_tx_axis_tuser, + input wire qsfpdd1_mac_4_tx_status, + output wire qsfpdd1_mac_4_tx_lfc_req, + output wire [7:0] qsfpdd1_mac_4_tx_pfc_req, + input wire qsfpdd1_mac_4_rx_clk, input wire qsfpdd1_mac_4_rx_rst, @@ -617,6 +686,8 @@ module fpga_core # input wire [AXIS_ETH_RX_USER_WIDTH-1:0] qsfpdd1_mac_4_rx_axis_tuser, input wire qsfpdd1_mac_4_rx_status, + input wire qsfpdd1_mac_4_rx_lfc_req, + input wire [7:0] qsfpdd1_mac_4_rx_pfc_req, input wire qsfpdd1_mac_5_tx_clk, input wire qsfpdd1_mac_5_tx_rst, @@ -636,6 +707,10 @@ module fpga_core # output wire qsfpdd1_mac_5_tx_axis_tlast, output wire [AXIS_ETH_TX_USER_WIDTH-1:0] qsfpdd1_mac_5_tx_axis_tuser, + input wire qsfpdd1_mac_5_tx_status, + output wire qsfpdd1_mac_5_tx_lfc_req, + output wire [7:0] qsfpdd1_mac_5_tx_pfc_req, + input wire qsfpdd1_mac_5_rx_clk, input wire qsfpdd1_mac_5_rx_rst, @@ -650,6 +725,8 @@ module fpga_core # input wire [AXIS_ETH_RX_USER_WIDTH-1:0] qsfpdd1_mac_5_rx_axis_tuser, input wire qsfpdd1_mac_5_rx_status, + input wire qsfpdd1_mac_5_rx_lfc_req, + input wire [7:0] qsfpdd1_mac_5_rx_pfc_req, input wire qsfpdd1_mac_6_tx_clk, input wire qsfpdd1_mac_6_tx_rst, @@ -669,6 +746,10 @@ module fpga_core # output wire qsfpdd1_mac_6_tx_axis_tlast, output wire [AXIS_ETH_TX_USER_WIDTH-1:0] qsfpdd1_mac_6_tx_axis_tuser, + input wire qsfpdd1_mac_6_tx_status, + output wire qsfpdd1_mac_6_tx_lfc_req, + output wire [7:0] qsfpdd1_mac_6_tx_pfc_req, + input wire qsfpdd1_mac_6_rx_clk, input wire qsfpdd1_mac_6_rx_rst, @@ -683,6 +764,8 @@ module fpga_core # input wire [AXIS_ETH_RX_USER_WIDTH-1:0] qsfpdd1_mac_6_rx_axis_tuser, input wire qsfpdd1_mac_6_rx_status, + input wire qsfpdd1_mac_6_rx_lfc_req, + input wire [7:0] qsfpdd1_mac_6_rx_pfc_req, input wire qsfpdd1_mac_7_tx_clk, input wire qsfpdd1_mac_7_tx_rst, @@ -702,6 +785,10 @@ module fpga_core # output wire qsfpdd1_mac_7_tx_axis_tlast, output wire [AXIS_ETH_TX_USER_WIDTH-1:0] qsfpdd1_mac_7_tx_axis_tuser, + input wire qsfpdd1_mac_7_tx_status, + output wire qsfpdd1_mac_7_tx_lfc_req, + output wire [7:0] qsfpdd1_mac_7_tx_pfc_req, + input wire qsfpdd1_mac_7_rx_clk, input wire qsfpdd1_mac_7_rx_rst, @@ -716,6 +803,8 @@ module fpga_core # input wire [AXIS_ETH_RX_USER_WIDTH-1:0] qsfpdd1_mac_7_rx_axis_tuser, input wire qsfpdd1_mac_7_rx_status, + input wire qsfpdd1_mac_7_rx_lfc_req, + input wire [7:0] qsfpdd1_mac_7_rx_pfc_req, input wire qsfpdd1_mac_8_tx_clk, input wire qsfpdd1_mac_8_tx_rst, @@ -735,6 +824,10 @@ module fpga_core # output wire qsfpdd1_mac_8_tx_axis_tlast, output wire [AXIS_ETH_TX_USER_WIDTH-1:0] qsfpdd1_mac_8_tx_axis_tuser, + input wire qsfpdd1_mac_8_tx_status, + output wire qsfpdd1_mac_8_tx_lfc_req, + output wire [7:0] qsfpdd1_mac_8_tx_pfc_req, + input wire qsfpdd1_mac_8_rx_clk, input wire qsfpdd1_mac_8_rx_rst, @@ -749,6 +842,8 @@ module fpga_core # input wire [AXIS_ETH_RX_USER_WIDTH-1:0] qsfpdd1_mac_8_rx_axis_tuser, input wire qsfpdd1_mac_8_rx_status, + input wire qsfpdd1_mac_8_rx_lfc_req, + input wire [7:0] qsfpdd1_mac_8_rx_pfc_req, output wire qsfpdd0_modsel_l, output wire qsfpdd0_reset_l, @@ -1047,7 +1142,12 @@ wire [PORT_COUNT*TX_TAG_WIDTH-1:0] axis_eth_tx_ptp_ts_tag; wire [PORT_COUNT-1:0] axis_eth_tx_ptp_ts_valid; wire [PORT_COUNT-1:0] axis_eth_tx_ptp_ts_ready; +wire [PORT_COUNT-1:0] eth_tx_enable; wire [PORT_COUNT-1:0] eth_tx_status; +wire [PORT_COUNT-1:0] eth_tx_lfc_en; +wire [PORT_COUNT-1:0] eth_tx_lfc_req; +wire [PORT_COUNT*8-1:0] eth_tx_pfc_en; +wire [PORT_COUNT*8-1:0] eth_tx_pfc_req; wire [PORT_COUNT-1:0] eth_rx_clk; wire [PORT_COUNT-1:0] eth_rx_rst; @@ -1064,7 +1164,14 @@ wire [PORT_COUNT-1:0] axis_eth_rx_tready; wire [PORT_COUNT-1:0] axis_eth_rx_tlast; wire [PORT_COUNT*AXIS_ETH_RX_USER_WIDTH-1:0] axis_eth_rx_tuser; +wire [PORT_COUNT-1:0] eth_rx_enable; wire [PORT_COUNT-1:0] eth_rx_status; +wire [PORT_COUNT-1:0] eth_rx_lfc_en; +wire [PORT_COUNT-1:0] eth_rx_lfc_req; +wire [PORT_COUNT-1:0] eth_rx_lfc_ack; +wire [PORT_COUNT*8-1:0] eth_rx_pfc_en; +wire [PORT_COUNT*8-1:0] eth_rx_pfc_req; +wire [PORT_COUNT*8-1:0] eth_rx_pfc_ack; mqnic_port_map_mac_axis #( .MAC_COUNT(16), @@ -1105,7 +1212,12 @@ mqnic_port_map_mac_axis_inst ( .s_axis_mac_tx_ptp_ts_valid({qsfpdd1_mac_8_tx_ptp_ts_valid, qsfpdd1_mac_7_tx_ptp_ts_valid, qsfpdd1_mac_6_tx_ptp_ts_valid, qsfpdd1_mac_5_tx_ptp_ts_valid, qsfpdd1_mac_4_tx_ptp_ts_valid, qsfpdd1_mac_3_tx_ptp_ts_valid, qsfpdd1_mac_2_tx_ptp_ts_valid, qsfpdd1_mac_1_tx_ptp_ts_valid, qsfpdd0_mac_8_tx_ptp_ts_valid, qsfpdd0_mac_7_tx_ptp_ts_valid, qsfpdd0_mac_6_tx_ptp_ts_valid, qsfpdd0_mac_5_tx_ptp_ts_valid, qsfpdd0_mac_4_tx_ptp_ts_valid, qsfpdd0_mac_3_tx_ptp_ts_valid, qsfpdd0_mac_2_tx_ptp_ts_valid, qsfpdd0_mac_1_tx_ptp_ts_valid}), .s_axis_mac_tx_ptp_ts_ready(), - .mac_tx_status(16'hffff), + .mac_tx_enable(), + .mac_tx_status({qsfpdd1_mac_8_tx_status, qsfpdd1_mac_7_tx_status, qsfpdd1_mac_6_tx_status, qsfpdd1_mac_5_tx_status, qsfpdd1_mac_4_tx_status, qsfpdd1_mac_3_tx_status, qsfpdd1_mac_2_tx_status, qsfpdd1_mac_1_tx_status, qsfpdd0_mac_8_tx_status, qsfpdd0_mac_7_tx_status, qsfpdd0_mac_6_tx_status, qsfpdd0_mac_5_tx_status, qsfpdd0_mac_4_tx_status, qsfpdd0_mac_3_tx_status, qsfpdd0_mac_2_tx_status, qsfpdd0_mac_1_tx_status}), + .mac_tx_lfc_en(), + .mac_tx_lfc_req({qsfpdd1_mac_8_tx_lfc_req, qsfpdd1_mac_7_tx_lfc_req, qsfpdd1_mac_6_tx_lfc_req, qsfpdd1_mac_5_tx_lfc_req, qsfpdd1_mac_4_tx_lfc_req, qsfpdd1_mac_3_tx_lfc_req, qsfpdd1_mac_2_tx_lfc_req, qsfpdd1_mac_1_tx_lfc_req, qsfpdd0_mac_8_tx_lfc_req, qsfpdd0_mac_7_tx_lfc_req, qsfpdd0_mac_6_tx_lfc_req, qsfpdd0_mac_5_tx_lfc_req, qsfpdd0_mac_4_tx_lfc_req, qsfpdd0_mac_3_tx_lfc_req, qsfpdd0_mac_2_tx_lfc_req, qsfpdd0_mac_1_tx_lfc_req}), + .mac_tx_pfc_en(), + .mac_tx_pfc_req({qsfpdd1_mac_8_tx_pfc_req, qsfpdd1_mac_7_tx_pfc_req, qsfpdd1_mac_6_tx_pfc_req, qsfpdd1_mac_5_tx_pfc_req, qsfpdd1_mac_4_tx_pfc_req, qsfpdd1_mac_3_tx_pfc_req, qsfpdd1_mac_2_tx_pfc_req, qsfpdd1_mac_1_tx_pfc_req, qsfpdd0_mac_8_tx_pfc_req, qsfpdd0_mac_7_tx_pfc_req, qsfpdd0_mac_6_tx_pfc_req, qsfpdd0_mac_5_tx_pfc_req, qsfpdd0_mac_4_tx_pfc_req, qsfpdd0_mac_3_tx_pfc_req, qsfpdd0_mac_2_tx_pfc_req, qsfpdd0_mac_1_tx_pfc_req}), .mac_rx_clk({qsfpdd1_mac_8_rx_clk, qsfpdd1_mac_7_rx_clk, qsfpdd1_mac_6_rx_clk, qsfpdd1_mac_5_rx_clk, qsfpdd1_mac_4_rx_clk, qsfpdd1_mac_3_rx_clk, qsfpdd1_mac_2_rx_clk, qsfpdd1_mac_1_rx_clk, qsfpdd0_mac_8_rx_clk, qsfpdd0_mac_7_rx_clk, qsfpdd0_mac_6_rx_clk, qsfpdd0_mac_5_rx_clk, qsfpdd0_mac_4_rx_clk, qsfpdd0_mac_3_rx_clk, qsfpdd0_mac_2_rx_clk, qsfpdd0_mac_1_rx_clk}), .mac_rx_rst({qsfpdd1_mac_8_rx_rst, qsfpdd1_mac_7_rx_rst, qsfpdd1_mac_6_rx_rst, qsfpdd1_mac_5_rx_rst, qsfpdd1_mac_4_rx_rst, qsfpdd1_mac_3_rx_rst, qsfpdd1_mac_2_rx_rst, qsfpdd1_mac_1_rx_rst, qsfpdd0_mac_8_rx_rst, qsfpdd0_mac_7_rx_rst, qsfpdd0_mac_6_rx_rst, qsfpdd0_mac_5_rx_rst, qsfpdd0_mac_4_rx_rst, qsfpdd0_mac_3_rx_rst, qsfpdd0_mac_2_rx_rst, qsfpdd0_mac_1_rx_rst}), @@ -1122,7 +1234,14 @@ mqnic_port_map_mac_axis_inst ( .s_axis_mac_rx_tlast({qsfpdd1_mac_8_rx_axis_tlast, qsfpdd1_mac_7_rx_axis_tlast, qsfpdd1_mac_6_rx_axis_tlast, qsfpdd1_mac_5_rx_axis_tlast, qsfpdd1_mac_4_rx_axis_tlast, qsfpdd1_mac_3_rx_axis_tlast, qsfpdd1_mac_2_rx_axis_tlast, qsfpdd1_mac_1_rx_axis_tlast, qsfpdd0_mac_8_rx_axis_tlast, qsfpdd0_mac_7_rx_axis_tlast, qsfpdd0_mac_6_rx_axis_tlast, qsfpdd0_mac_5_rx_axis_tlast, qsfpdd0_mac_4_rx_axis_tlast, qsfpdd0_mac_3_rx_axis_tlast, qsfpdd0_mac_2_rx_axis_tlast, qsfpdd0_mac_1_rx_axis_tlast}), .s_axis_mac_rx_tuser({qsfpdd1_mac_8_rx_axis_tuser, qsfpdd1_mac_7_rx_axis_tuser, qsfpdd1_mac_6_rx_axis_tuser, qsfpdd1_mac_5_rx_axis_tuser, qsfpdd1_mac_4_rx_axis_tuser, qsfpdd1_mac_3_rx_axis_tuser, qsfpdd1_mac_2_rx_axis_tuser, qsfpdd1_mac_1_rx_axis_tuser, qsfpdd0_mac_8_rx_axis_tuser, qsfpdd0_mac_7_rx_axis_tuser, qsfpdd0_mac_6_rx_axis_tuser, qsfpdd0_mac_5_rx_axis_tuser, qsfpdd0_mac_4_rx_axis_tuser, qsfpdd0_mac_3_rx_axis_tuser, qsfpdd0_mac_2_rx_axis_tuser, qsfpdd0_mac_1_rx_axis_tuser}), + .mac_rx_enable(), .mac_rx_status({qsfpdd1_mac_8_rx_status, qsfpdd1_mac_7_rx_status, qsfpdd1_mac_6_rx_status, qsfpdd1_mac_5_rx_status, qsfpdd1_mac_4_rx_status, qsfpdd1_mac_3_rx_status, qsfpdd1_mac_2_rx_status, qsfpdd1_mac_1_rx_status, qsfpdd0_mac_8_rx_status, qsfpdd0_mac_7_rx_status, qsfpdd0_mac_6_rx_status, qsfpdd0_mac_5_rx_status, qsfpdd0_mac_4_rx_status, qsfpdd0_mac_3_rx_status, qsfpdd0_mac_2_rx_status, qsfpdd0_mac_1_rx_status}), + .mac_rx_lfc_en(), + .mac_rx_lfc_req({qsfpdd1_mac_8_rx_lfc_req, qsfpdd1_mac_7_rx_lfc_req, qsfpdd1_mac_6_rx_lfc_req, qsfpdd1_mac_5_rx_lfc_req, qsfpdd1_mac_4_rx_lfc_req, qsfpdd1_mac_3_rx_lfc_req, qsfpdd1_mac_2_rx_lfc_req, qsfpdd1_mac_1_rx_lfc_req, qsfpdd0_mac_8_rx_lfc_req, qsfpdd0_mac_7_rx_lfc_req, qsfpdd0_mac_6_rx_lfc_req, qsfpdd0_mac_5_rx_lfc_req, qsfpdd0_mac_4_rx_lfc_req, qsfpdd0_mac_3_rx_lfc_req, qsfpdd0_mac_2_rx_lfc_req, qsfpdd0_mac_1_rx_lfc_req}), + .mac_rx_lfc_ack(), + .mac_rx_pfc_en(), + .mac_rx_pfc_req({qsfpdd1_mac_8_rx_pfc_req, qsfpdd1_mac_7_rx_pfc_req, qsfpdd1_mac_6_rx_pfc_req, qsfpdd1_mac_5_rx_pfc_req, qsfpdd1_mac_4_rx_pfc_req, qsfpdd1_mac_3_rx_pfc_req, qsfpdd1_mac_2_rx_pfc_req, qsfpdd1_mac_1_rx_pfc_req, qsfpdd0_mac_8_rx_pfc_req, qsfpdd0_mac_7_rx_pfc_req, qsfpdd0_mac_6_rx_pfc_req, qsfpdd0_mac_5_rx_pfc_req, qsfpdd0_mac_4_rx_pfc_req, qsfpdd0_mac_3_rx_pfc_req, qsfpdd0_mac_2_rx_pfc_req, qsfpdd0_mac_1_rx_pfc_req}), + .mac_rx_pfc_ack(), // towards datapath .tx_clk(eth_tx_clk), @@ -1145,7 +1264,12 @@ mqnic_port_map_mac_axis_inst ( .m_axis_tx_ptp_ts_valid(axis_eth_tx_ptp_ts_valid), .m_axis_tx_ptp_ts_ready(axis_eth_tx_ptp_ts_ready), + .tx_enable(eth_tx_enable), .tx_status(eth_tx_status), + .tx_lfc_en(eth_tx_lfc_en), + .tx_lfc_req(eth_tx_lfc_req), + .tx_pfc_en(eth_tx_pfc_en), + .tx_pfc_req(eth_tx_pfc_req), .rx_clk(eth_rx_clk), .rx_rst(eth_rx_rst), @@ -1162,7 +1286,14 @@ mqnic_port_map_mac_axis_inst ( .m_axis_rx_tlast(axis_eth_rx_tlast), .m_axis_rx_tuser(axis_eth_rx_tuser), - .rx_status(eth_rx_status) + .rx_enable(eth_rx_enable), + .rx_status(eth_rx_status), + .rx_lfc_en(eth_rx_lfc_en), + .rx_lfc_req(eth_rx_lfc_req), + .rx_lfc_ack(eth_rx_lfc_ack), + .rx_pfc_en(eth_rx_pfc_en), + .rx_pfc_req(eth_rx_pfc_req), + .rx_pfc_ack(eth_rx_pfc_ack) ); mqnic_core_pcie_ptile #( @@ -1232,6 +1363,9 @@ mqnic_core_pcie_ptile #( .TX_CHECKSUM_ENABLE(TX_CHECKSUM_ENABLE), .RX_HASH_ENABLE(RX_HASH_ENABLE), .RX_CHECKSUM_ENABLE(RX_CHECKSUM_ENABLE), + .PFC_ENABLE(PFC_ENABLE), + .LFC_ENABLE(LFC_ENABLE), + .MAC_CTRL_ENABLE(0), .TX_FIFO_DEPTH(TX_FIFO_DEPTH), .RX_FIFO_DEPTH(RX_FIFO_DEPTH), .MAX_TX_SIZE(MAX_TX_SIZE), @@ -1441,7 +1575,13 @@ core_inst ( .s_axis_eth_tx_cpl_valid(axis_eth_tx_ptp_ts_valid), .s_axis_eth_tx_cpl_ready(axis_eth_tx_ptp_ts_ready), + .eth_tx_enable(eth_tx_enable), .eth_tx_status(eth_tx_status), + .eth_tx_lfc_en(eth_tx_lfc_en), + .eth_tx_lfc_req(eth_tx_lfc_req), + .eth_tx_pfc_en(eth_tx_pfc_en), + .eth_tx_pfc_req(eth_tx_pfc_req), + .eth_tx_fc_quanta_clk_en(0), .eth_rx_clk(eth_rx_clk), .eth_rx_rst(eth_rx_rst), @@ -1458,7 +1598,15 @@ core_inst ( .s_axis_eth_rx_tlast(axis_eth_rx_tlast), .s_axis_eth_rx_tuser(axis_eth_rx_tuser), + .eth_rx_enable(eth_rx_enable), .eth_rx_status(eth_rx_status), + .eth_rx_lfc_en(eth_rx_lfc_en), + .eth_rx_lfc_req(eth_rx_lfc_req), + .eth_rx_lfc_ack(eth_rx_lfc_ack), + .eth_rx_pfc_en(eth_rx_pfc_en), + .eth_rx_pfc_req(eth_rx_pfc_req), + .eth_rx_pfc_ack(eth_rx_pfc_ack), + .eth_rx_fc_quanta_clk_en(0), /* * DDR diff --git a/fpga/mqnic/DK_DEV_AGF014EA/fpga_25g/tb/fpga_core/Makefile b/fpga/mqnic/DK_DEV_AGF014EA/fpga_25g/tb/fpga_core/Makefile index 1fa7138d9..2665007c9 100644 --- a/fpga/mqnic/DK_DEV_AGF014EA/fpga_25g/tb/fpga_core/Makefile +++ b/fpga/mqnic/DK_DEV_AGF014EA/fpga_25g/tb/fpga_core/Makefile @@ -169,6 +169,8 @@ export PARAM_TX_CPL_FIFO_DEPTH := 32 export PARAM_TX_CHECKSUM_ENABLE := 1 export PARAM_RX_HASH_ENABLE := 1 export PARAM_RX_CHECKSUM_ENABLE := 1 +export PARAM_LFC_ENABLE := 1 +export PARAM_PFC_ENABLE := $(PARAM_LFC_ENABLE) export PARAM_TX_FIFO_DEPTH := 32768 export PARAM_RX_FIFO_DEPTH := 32768 export PARAM_MAX_TX_SIZE := 9214 diff --git a/fpga/mqnic/DK_DEV_AGF014EA/fpga_25g/tb/fpga_core/test_fpga_core.py b/fpga/mqnic/DK_DEV_AGF014EA/fpga_25g/tb/fpga_core/test_fpga_core.py index 8417d4600..2d96ec42f 100644 --- a/fpga/mqnic/DK_DEV_AGF014EA/fpga_25g/tb/fpga_core/test_fpga_core.py +++ b/fpga/mqnic/DK_DEV_AGF014EA/fpga_25g/tb/fpga_core/test_fpga_core.py @@ -280,6 +280,8 @@ class TB(object): macs.append(mac) getattr(dut, f"qsfpdd{x}_mac_{y}_rx_status").setimmediatevalue(1) + getattr(dut, f"qsfpdd{x}_mac_{y}_rx_lfc_req").setimmediatevalue(0) + getattr(dut, f"qsfpdd{x}_mac_{y}_rx_pfc_req").setimmediatevalue(0) self.qsfpdd_mac.append(macs) @@ -689,6 +691,8 @@ def test_fpga_core(request): parameters['TX_CHECKSUM_ENABLE'] = 1 parameters['RX_HASH_ENABLE'] = 1 parameters['RX_CHECKSUM_ENABLE'] = 1 + parameters['LFC_ENABLE'] = 1 + parameters['PFC_ENABLE'] = parameters['LFC_ENABLE'] parameters['TX_FIFO_DEPTH'] = 32768 parameters['RX_FIFO_DEPTH'] = 32768 parameters['MAX_TX_SIZE'] = 9214 diff --git a/fpga/mqnic/DNPCIe_40G_KU_LL_2QSFP/fpga/fpga_app_dma_bench_ku040/Makefile b/fpga/mqnic/DNPCIe_40G_KU_LL_2QSFP/fpga/fpga_app_dma_bench_ku040/Makefile index 2ed0c9bbf..1ce6d0bc4 100644 --- a/fpga/mqnic/DNPCIe_40G_KU_LL_2QSFP/fpga/fpga_app_dma_bench_ku040/Makefile +++ b/fpga/mqnic/DNPCIe_40G_KU_LL_2QSFP/fpga/fpga_app_dma_bench_ku040/Makefile @@ -64,6 +64,10 @@ SYN_FILES += app/dma_bench/rtl/dram_test_ch.v SYN_FILES += lib/eth/rtl/eth_mac_10g.v SYN_FILES += lib/eth/rtl/axis_xgmii_rx_64.v SYN_FILES += lib/eth/rtl/axis_xgmii_tx_64.v +SYN_FILES += lib/eth/rtl/mac_ctrl_rx.v +SYN_FILES += lib/eth/rtl/mac_ctrl_tx.v +SYN_FILES += lib/eth/rtl/mac_pause_ctrl_rx.v +SYN_FILES += lib/eth/rtl/mac_pause_ctrl_tx.v SYN_FILES += lib/eth/rtl/eth_phy_10g.v SYN_FILES += lib/eth/rtl/eth_phy_10g_rx.v SYN_FILES += lib/eth/rtl/eth_phy_10g_rx_if.v diff --git a/fpga/mqnic/DNPCIe_40G_KU_LL_2QSFP/fpga/fpga_app_dma_bench_ku040/config.tcl b/fpga/mqnic/DNPCIe_40G_KU_LL_2QSFP/fpga/fpga_app_dma_bench_ku040/config.tcl index 761eb81a8..bbd7982e3 100644 --- a/fpga/mqnic/DNPCIe_40G_KU_LL_2QSFP/fpga/fpga_app_dma_bench_ku040/config.tcl +++ b/fpga/mqnic/DNPCIe_40G_KU_LL_2QSFP/fpga/fpga_app_dma_bench_ku040/config.tcl @@ -104,6 +104,8 @@ dict set params TX_CPL_FIFO_DEPTH "32" dict set params TX_CHECKSUM_ENABLE "1" dict set params RX_HASH_ENABLE "1" dict set params RX_CHECKSUM_ENABLE "1" +dict set params PFC_ENABLE "1" +dict set params LFC_ENABLE [dict get $params PFC_ENABLE] dict set params ENABLE_PADDING "1" dict set params ENABLE_DIC "1" dict set params MIN_FRAME_LENGTH "64" diff --git a/fpga/mqnic/DNPCIe_40G_KU_LL_2QSFP/fpga/fpga_app_dma_bench_ku060/Makefile b/fpga/mqnic/DNPCIe_40G_KU_LL_2QSFP/fpga/fpga_app_dma_bench_ku060/Makefile index 60c149165..c99f209cd 100644 --- a/fpga/mqnic/DNPCIe_40G_KU_LL_2QSFP/fpga/fpga_app_dma_bench_ku060/Makefile +++ b/fpga/mqnic/DNPCIe_40G_KU_LL_2QSFP/fpga/fpga_app_dma_bench_ku060/Makefile @@ -64,6 +64,10 @@ SYN_FILES += app/dma_bench/rtl/dram_test_ch.v SYN_FILES += lib/eth/rtl/eth_mac_10g.v SYN_FILES += lib/eth/rtl/axis_xgmii_rx_64.v SYN_FILES += lib/eth/rtl/axis_xgmii_tx_64.v +SYN_FILES += lib/eth/rtl/mac_ctrl_rx.v +SYN_FILES += lib/eth/rtl/mac_ctrl_tx.v +SYN_FILES += lib/eth/rtl/mac_pause_ctrl_rx.v +SYN_FILES += lib/eth/rtl/mac_pause_ctrl_tx.v SYN_FILES += lib/eth/rtl/eth_phy_10g.v SYN_FILES += lib/eth/rtl/eth_phy_10g_rx.v SYN_FILES += lib/eth/rtl/eth_phy_10g_rx_if.v diff --git a/fpga/mqnic/DNPCIe_40G_KU_LL_2QSFP/fpga/fpga_app_dma_bench_ku060/config.tcl b/fpga/mqnic/DNPCIe_40G_KU_LL_2QSFP/fpga/fpga_app_dma_bench_ku060/config.tcl index a7a3c7337..7b3f27d76 100644 --- a/fpga/mqnic/DNPCIe_40G_KU_LL_2QSFP/fpga/fpga_app_dma_bench_ku060/config.tcl +++ b/fpga/mqnic/DNPCIe_40G_KU_LL_2QSFP/fpga/fpga_app_dma_bench_ku060/config.tcl @@ -104,6 +104,8 @@ dict set params TX_CPL_FIFO_DEPTH "32" dict set params TX_CHECKSUM_ENABLE "1" dict set params RX_HASH_ENABLE "1" dict set params RX_CHECKSUM_ENABLE "1" +dict set params PFC_ENABLE "1" +dict set params LFC_ENABLE [dict get $params PFC_ENABLE] dict set params ENABLE_PADDING "1" dict set params ENABLE_DIC "1" dict set params MIN_FRAME_LENGTH "64" diff --git a/fpga/mqnic/DNPCIe_40G_KU_LL_2QSFP/fpga/fpga_ku040/Makefile b/fpga/mqnic/DNPCIe_40G_KU_LL_2QSFP/fpga/fpga_ku040/Makefile index 72311645d..4e90ae131 100644 --- a/fpga/mqnic/DNPCIe_40G_KU_LL_2QSFP/fpga/fpga_ku040/Makefile +++ b/fpga/mqnic/DNPCIe_40G_KU_LL_2QSFP/fpga/fpga_ku040/Makefile @@ -61,6 +61,10 @@ SYN_FILES += rtl/common/tdma_ber_ch.v SYN_FILES += lib/eth/rtl/eth_mac_10g.v SYN_FILES += lib/eth/rtl/axis_xgmii_rx_64.v SYN_FILES += lib/eth/rtl/axis_xgmii_tx_64.v +SYN_FILES += lib/eth/rtl/mac_ctrl_rx.v +SYN_FILES += lib/eth/rtl/mac_ctrl_tx.v +SYN_FILES += lib/eth/rtl/mac_pause_ctrl_rx.v +SYN_FILES += lib/eth/rtl/mac_pause_ctrl_tx.v SYN_FILES += lib/eth/rtl/eth_phy_10g.v SYN_FILES += lib/eth/rtl/eth_phy_10g_rx.v SYN_FILES += lib/eth/rtl/eth_phy_10g_rx_if.v diff --git a/fpga/mqnic/DNPCIe_40G_KU_LL_2QSFP/fpga/fpga_ku040/config.tcl b/fpga/mqnic/DNPCIe_40G_KU_LL_2QSFP/fpga/fpga_ku040/config.tcl index 18f1f4d03..cf6107c5a 100644 --- a/fpga/mqnic/DNPCIe_40G_KU_LL_2QSFP/fpga/fpga_ku040/config.tcl +++ b/fpga/mqnic/DNPCIe_40G_KU_LL_2QSFP/fpga/fpga_ku040/config.tcl @@ -104,6 +104,8 @@ dict set params TX_CPL_FIFO_DEPTH "32" dict set params TX_CHECKSUM_ENABLE "1" dict set params RX_HASH_ENABLE "1" dict set params RX_CHECKSUM_ENABLE "1" +dict set params PFC_ENABLE "1" +dict set params LFC_ENABLE [dict get $params PFC_ENABLE] dict set params ENABLE_PADDING "1" dict set params ENABLE_DIC "1" dict set params MIN_FRAME_LENGTH "64" diff --git a/fpga/mqnic/DNPCIe_40G_KU_LL_2QSFP/fpga/fpga_ku060/Makefile b/fpga/mqnic/DNPCIe_40G_KU_LL_2QSFP/fpga/fpga_ku060/Makefile index f283b4c5f..5eafd72d2 100644 --- a/fpga/mqnic/DNPCIe_40G_KU_LL_2QSFP/fpga/fpga_ku060/Makefile +++ b/fpga/mqnic/DNPCIe_40G_KU_LL_2QSFP/fpga/fpga_ku060/Makefile @@ -61,6 +61,10 @@ SYN_FILES += rtl/common/tdma_ber_ch.v SYN_FILES += lib/eth/rtl/eth_mac_10g.v SYN_FILES += lib/eth/rtl/axis_xgmii_rx_64.v SYN_FILES += lib/eth/rtl/axis_xgmii_tx_64.v +SYN_FILES += lib/eth/rtl/mac_ctrl_rx.v +SYN_FILES += lib/eth/rtl/mac_ctrl_tx.v +SYN_FILES += lib/eth/rtl/mac_pause_ctrl_rx.v +SYN_FILES += lib/eth/rtl/mac_pause_ctrl_tx.v SYN_FILES += lib/eth/rtl/eth_phy_10g.v SYN_FILES += lib/eth/rtl/eth_phy_10g_rx.v SYN_FILES += lib/eth/rtl/eth_phy_10g_rx_if.v diff --git a/fpga/mqnic/DNPCIe_40G_KU_LL_2QSFP/fpga/fpga_ku060/config.tcl b/fpga/mqnic/DNPCIe_40G_KU_LL_2QSFP/fpga/fpga_ku060/config.tcl index 4f53af53b..8ab48248f 100644 --- a/fpga/mqnic/DNPCIe_40G_KU_LL_2QSFP/fpga/fpga_ku060/config.tcl +++ b/fpga/mqnic/DNPCIe_40G_KU_LL_2QSFP/fpga/fpga_ku060/config.tcl @@ -104,6 +104,8 @@ dict set params TX_CPL_FIFO_DEPTH "32" dict set params TX_CHECKSUM_ENABLE "1" dict set params RX_HASH_ENABLE "1" dict set params RX_CHECKSUM_ENABLE "1" +dict set params PFC_ENABLE "1" +dict set params LFC_ENABLE [dict get $params PFC_ENABLE] dict set params ENABLE_PADDING "1" dict set params ENABLE_DIC "1" dict set params MIN_FRAME_LENGTH "64" diff --git a/fpga/mqnic/DNPCIe_40G_KU_LL_2QSFP/fpga/rtl/fpga.v b/fpga/mqnic/DNPCIe_40G_KU_LL_2QSFP/fpga/rtl/fpga.v index ffbda4999..e07106ec1 100644 --- a/fpga/mqnic/DNPCIe_40G_KU_LL_2QSFP/fpga/rtl/fpga.v +++ b/fpga/mqnic/DNPCIe_40G_KU_LL_2QSFP/fpga/rtl/fpga.v @@ -74,6 +74,8 @@ module fpga # parameter TX_CHECKSUM_ENABLE = 1, parameter RX_HASH_ENABLE = 1, parameter RX_CHECKSUM_ENABLE = 1, + parameter LFC_ENABLE = PFC_ENABLE, + parameter PFC_ENABLE = 1, parameter ENABLE_PADDING = 1, parameter ENABLE_DIC = 1, parameter MIN_FRAME_LENGTH = 64, @@ -1582,6 +1584,8 @@ fpga_core #( .TX_CHECKSUM_ENABLE(TX_CHECKSUM_ENABLE), .RX_HASH_ENABLE(RX_HASH_ENABLE), .RX_CHECKSUM_ENABLE(RX_CHECKSUM_ENABLE), + .PFC_ENABLE(PFC_ENABLE), + .LFC_ENABLE(LFC_ENABLE), .ENABLE_PADDING(ENABLE_PADDING), .ENABLE_DIC(ENABLE_DIC), .MIN_FRAME_LENGTH(MIN_FRAME_LENGTH), diff --git a/fpga/mqnic/DNPCIe_40G_KU_LL_2QSFP/fpga/rtl/fpga_core.v b/fpga/mqnic/DNPCIe_40G_KU_LL_2QSFP/fpga/rtl/fpga_core.v index 59a80ee34..d44cb1566 100644 --- a/fpga/mqnic/DNPCIe_40G_KU_LL_2QSFP/fpga/rtl/fpga_core.v +++ b/fpga/mqnic/DNPCIe_40G_KU_LL_2QSFP/fpga/rtl/fpga_core.v @@ -81,6 +81,8 @@ module fpga_core # parameter TX_CHECKSUM_ENABLE = 1, parameter RX_HASH_ENABLE = 1, parameter RX_CHECKSUM_ENABLE = 1, + parameter PFC_ENABLE = 1, + parameter LFC_ENABLE = PFC_ENABLE, parameter ENABLE_PADDING = 1, parameter ENABLE_DIC = 1, parameter MIN_FRAME_LENGTH = 64, @@ -998,7 +1000,12 @@ wire [PORT_COUNT*TX_TAG_WIDTH-1:0] axis_eth_tx_ptp_ts_tag; wire [PORT_COUNT-1:0] axis_eth_tx_ptp_ts_valid; wire [PORT_COUNT-1:0] axis_eth_tx_ptp_ts_ready; +wire [PORT_COUNT-1:0] eth_tx_enable; wire [PORT_COUNT-1:0] eth_tx_status; +wire [PORT_COUNT-1:0] eth_tx_lfc_en; +wire [PORT_COUNT-1:0] eth_tx_lfc_req; +wire [PORT_COUNT*8-1:0] eth_tx_pfc_en; +wire [PORT_COUNT*8-1:0] eth_tx_pfc_req; wire [PORT_COUNT-1:0] eth_rx_clk; wire [PORT_COUNT-1:0] eth_rx_rst; @@ -1013,7 +1020,14 @@ wire [PORT_COUNT-1:0] axis_eth_rx_tready; wire [PORT_COUNT-1:0] axis_eth_rx_tlast; wire [PORT_COUNT*AXIS_ETH_RX_USER_WIDTH-1:0] axis_eth_rx_tuser; +wire [PORT_COUNT-1:0] eth_rx_enable; wire [PORT_COUNT-1:0] eth_rx_status; +wire [PORT_COUNT-1:0] eth_rx_lfc_en; +wire [PORT_COUNT-1:0] eth_rx_lfc_req; +wire [PORT_COUNT-1:0] eth_rx_lfc_ack; +wire [PORT_COUNT*8-1:0] eth_rx_pfc_en; +wire [PORT_COUNT*8-1:0] eth_rx_pfc_req; +wire [PORT_COUNT*8-1:0] eth_rx_pfc_ack; wire [PORT_COUNT-1:0] port_xgmii_tx_clk; wire [PORT_COUNT-1:0] port_xgmii_tx_rst; @@ -1086,12 +1100,15 @@ generate .PTP_PERIOD_FNS(IF_PTP_PERIOD_FNS), .TX_PTP_TS_ENABLE(PTP_TS_ENABLE), .TX_PTP_TS_WIDTH(PTP_TS_WIDTH), + .TX_PTP_TS_CTRL_IN_TUSER(0), .TX_PTP_TAG_ENABLE(PTP_TS_ENABLE), .TX_PTP_TAG_WIDTH(TX_TAG_WIDTH), .RX_PTP_TS_ENABLE(PTP_TS_ENABLE), .RX_PTP_TS_WIDTH(PTP_TS_WIDTH), .TX_USER_WIDTH(AXIS_ETH_TX_USER_WIDTH), - .RX_USER_WIDTH(AXIS_ETH_RX_USER_WIDTH) + .RX_USER_WIDTH(AXIS_ETH_RX_USER_WIDTH), + .PFC_ENABLE(PFC_ENABLE), + .PAUSE_ENABLE(LFC_ENABLE) ) eth_mac_inst ( .tx_clk(port_xgmii_tx_clk[n]), @@ -1099,6 +1116,9 @@ generate .rx_clk(port_xgmii_rx_clk[n]), .rx_rst(port_xgmii_rx_rst[n]), + /* + * AXI input + */ .tx_axis_tdata(axis_eth_tx_tdata[n*AXIS_ETH_DATA_WIDTH +: AXIS_ETH_DATA_WIDTH]), .tx_axis_tkeep(axis_eth_tx_tkeep[n*AXIS_ETH_KEEP_WIDTH +: AXIS_ETH_KEEP_WIDTH]), .tx_axis_tvalid(axis_eth_tx_tvalid[n +: 1]), @@ -1106,30 +1126,121 @@ generate .tx_axis_tlast(axis_eth_tx_tlast[n +: 1]), .tx_axis_tuser(axis_eth_tx_tuser[n*AXIS_ETH_TX_USER_WIDTH +: AXIS_ETH_TX_USER_WIDTH]), + /* + * AXI output + */ .rx_axis_tdata(axis_eth_rx_tdata[n*AXIS_ETH_DATA_WIDTH +: AXIS_ETH_DATA_WIDTH]), .rx_axis_tkeep(axis_eth_rx_tkeep[n*AXIS_ETH_KEEP_WIDTH +: AXIS_ETH_KEEP_WIDTH]), .rx_axis_tvalid(axis_eth_rx_tvalid[n +: 1]), .rx_axis_tlast(axis_eth_rx_tlast[n +: 1]), .rx_axis_tuser(axis_eth_rx_tuser[n*AXIS_ETH_RX_USER_WIDTH +: AXIS_ETH_RX_USER_WIDTH]), + /* + * XGMII interface + */ .xgmii_rxd(port_xgmii_rxd[n*XGMII_DATA_WIDTH +: XGMII_DATA_WIDTH]), .xgmii_rxc(port_xgmii_rxc[n*XGMII_CTRL_WIDTH +: XGMII_CTRL_WIDTH]), .xgmii_txd(port_xgmii_txd[n*XGMII_DATA_WIDTH +: XGMII_DATA_WIDTH]), .xgmii_txc(port_xgmii_txc[n*XGMII_CTRL_WIDTH +: XGMII_CTRL_WIDTH]), + /* + * PTP + */ .tx_ptp_ts(eth_tx_ptp_ts_96[n*PTP_TS_WIDTH +: PTP_TS_WIDTH]), .rx_ptp_ts(eth_rx_ptp_ts_96[n*PTP_TS_WIDTH +: PTP_TS_WIDTH]), .tx_axis_ptp_ts(axis_eth_tx_ptp_ts[n*PTP_TS_WIDTH +: PTP_TS_WIDTH]), .tx_axis_ptp_ts_tag(axis_eth_tx_ptp_ts_tag[n*TX_TAG_WIDTH +: TX_TAG_WIDTH]), .tx_axis_ptp_ts_valid(axis_eth_tx_ptp_ts_valid[n +: 1]), + /* + * Link-level Flow Control (LFC) (IEEE 802.3 annex 31B PAUSE) + */ + .tx_lfc_req(eth_tx_lfc_req[n +: 1]), + .tx_lfc_resend(1'b0), + .rx_lfc_en(eth_rx_lfc_en[n +: 1]), + .rx_lfc_req(eth_rx_lfc_req[n +: 1]), + .rx_lfc_ack(eth_rx_lfc_ack[n +: 1]), + + /* + * Priority Flow Control (PFC) (IEEE 802.3 annex 31D PFC) + */ + .tx_pfc_req(eth_tx_pfc_req[n*8 +: 8]), + .tx_pfc_resend(1'b0), + .rx_pfc_en(eth_rx_pfc_en[n*8 +: 8]), + .rx_pfc_req(eth_rx_pfc_req[n*8 +: 8]), + .rx_pfc_ack(eth_rx_pfc_ack[n*8 +: 8]), + + /* + * Pause interface + */ + .tx_lfc_pause_en(1'b1), + .tx_pause_req(1'b0), + .tx_pause_ack(), + + /* + * Status + */ + .tx_start_packet(), .tx_error_underflow(), + .rx_start_packet(), .rx_error_bad_frame(), .rx_error_bad_fcs(), + .stat_tx_mcf(), + .stat_rx_mcf(), + .stat_tx_lfc_pkt(), + .stat_tx_lfc_xon(), + .stat_tx_lfc_xoff(), + .stat_tx_lfc_paused(), + .stat_tx_pfc_pkt(), + .stat_tx_pfc_xon(), + .stat_tx_pfc_xoff(), + .stat_tx_pfc_paused(), + .stat_rx_lfc_pkt(), + .stat_rx_lfc_xon(), + .stat_rx_lfc_xoff(), + .stat_rx_lfc_paused(), + .stat_rx_pfc_pkt(), + .stat_rx_pfc_xon(), + .stat_rx_pfc_xoff(), + .stat_rx_pfc_paused(), + /* + * Configuration + */ .cfg_ifg(8'd12), - .cfg_tx_enable(1'b1), - .cfg_rx_enable(1'b1) + .cfg_tx_enable(eth_tx_enable[n +: 1]), + .cfg_rx_enable(eth_rx_enable[n +: 1]), + .cfg_mcf_rx_eth_dst_mcast(48'h01_80_C2_00_00_01), + .cfg_mcf_rx_check_eth_dst_mcast(1'b1), + .cfg_mcf_rx_eth_dst_ucast(48'd0), + .cfg_mcf_rx_check_eth_dst_ucast(1'b0), + .cfg_mcf_rx_eth_src(48'd0), + .cfg_mcf_rx_check_eth_src(1'b0), + .cfg_mcf_rx_eth_type(16'h8808), + .cfg_mcf_rx_opcode_lfc(16'h0001), + .cfg_mcf_rx_check_opcode_lfc(eth_rx_lfc_en[n +: 1]), + .cfg_mcf_rx_opcode_pfc(16'h0101), + .cfg_mcf_rx_check_opcode_pfc(eth_rx_pfc_en[n*8 +: 8] != 0), + .cfg_mcf_rx_forward(1'b0), + .cfg_mcf_rx_enable(eth_rx_lfc_en[n +: 1] || eth_rx_pfc_en[n*8 +: 8]), + .cfg_tx_lfc_eth_dst(48'h01_80_C2_00_00_01), + .cfg_tx_lfc_eth_src(48'h80_23_31_43_54_4C), + .cfg_tx_lfc_eth_type(16'h8808), + .cfg_tx_lfc_opcode(16'h0001), + .cfg_tx_lfc_en(eth_tx_lfc_en[n +: 1]), + .cfg_tx_lfc_quanta(16'hffff), + .cfg_tx_lfc_refresh(16'h7fff), + .cfg_tx_pfc_eth_dst(48'h01_80_C2_00_00_01), + .cfg_tx_pfc_eth_src(48'h80_23_31_43_54_4C), + .cfg_tx_pfc_eth_type(16'h8808), + .cfg_tx_pfc_opcode(16'h0101), + .cfg_tx_pfc_en(eth_tx_pfc_en[n*8 +: 8] != 0), + .cfg_tx_pfc_quanta({8{16'hffff}}), + .cfg_tx_pfc_refresh({8{16'h7fff}}), + .cfg_rx_lfc_opcode(16'h0001), + .cfg_rx_lfc_en(eth_rx_lfc_en[n +: 1]), + .cfg_rx_pfc_opcode(16'h0101), + .cfg_rx_pfc_en(eth_rx_pfc_en[n*8 +: 8] != 0) ); end @@ -1203,6 +1314,9 @@ mqnic_core_pcie_us #( .TX_CHECKSUM_ENABLE(TX_CHECKSUM_ENABLE), .RX_HASH_ENABLE(RX_HASH_ENABLE), .RX_CHECKSUM_ENABLE(RX_CHECKSUM_ENABLE), + .PFC_ENABLE(PFC_ENABLE), + .LFC_ENABLE(LFC_ENABLE), + .MAC_CTRL_ENABLE(0), .TX_FIFO_DEPTH(TX_FIFO_DEPTH), .RX_FIFO_DEPTH(RX_FIFO_DEPTH), .MAX_TX_SIZE(MAX_TX_SIZE), @@ -1484,7 +1598,13 @@ core_inst ( .s_axis_eth_tx_cpl_valid(axis_eth_tx_ptp_ts_valid), .s_axis_eth_tx_cpl_ready(axis_eth_tx_ptp_ts_ready), + .eth_tx_enable(eth_tx_enable), .eth_tx_status(eth_tx_status), + .eth_tx_lfc_en(eth_tx_lfc_en), + .eth_tx_lfc_req(eth_tx_lfc_req), + .eth_tx_pfc_en(eth_tx_pfc_en), + .eth_tx_pfc_req(eth_tx_pfc_req), + .eth_tx_fc_quanta_clk_en(0), .eth_rx_clk(eth_rx_clk), .eth_rx_rst(eth_rx_rst), @@ -1501,7 +1621,15 @@ core_inst ( .s_axis_eth_rx_tlast(axis_eth_rx_tlast), .s_axis_eth_rx_tuser(axis_eth_rx_tuser), + .eth_rx_enable(eth_rx_enable), .eth_rx_status(eth_rx_status), + .eth_rx_lfc_en(eth_rx_lfc_en), + .eth_rx_lfc_req(eth_rx_lfc_req), + .eth_rx_lfc_ack(eth_rx_lfc_ack), + .eth_rx_pfc_en(eth_rx_pfc_en), + .eth_rx_pfc_req(eth_rx_pfc_req), + .eth_rx_pfc_ack(eth_rx_pfc_ack), + .eth_rx_fc_quanta_clk_en(0), /* * DDR diff --git a/fpga/mqnic/DNPCIe_40G_KU_LL_2QSFP/fpga/tb/fpga_core/Makefile b/fpga/mqnic/DNPCIe_40G_KU_LL_2QSFP/fpga/tb/fpga_core/Makefile index f1f4d999d..127984b05 100644 --- a/fpga/mqnic/DNPCIe_40G_KU_LL_2QSFP/fpga/tb/fpga_core/Makefile +++ b/fpga/mqnic/DNPCIe_40G_KU_LL_2QSFP/fpga/tb/fpga_core/Makefile @@ -62,6 +62,10 @@ VERILOG_SOURCES += ../../rtl/common/tdma_ber_ch.v VERILOG_SOURCES += ../../lib/eth/rtl/eth_mac_10g.v VERILOG_SOURCES += ../../lib/eth/rtl/axis_xgmii_rx_64.v VERILOG_SOURCES += ../../lib/eth/rtl/axis_xgmii_tx_64.v +VERILOG_SOURCES += ../../lib/eth/rtl/mac_ctrl_rx.v +VERILOG_SOURCES += ../../lib/eth/rtl/mac_ctrl_tx.v +VERILOG_SOURCES += ../../lib/eth/rtl/mac_pause_ctrl_rx.v +VERILOG_SOURCES += ../../lib/eth/rtl/mac_pause_ctrl_tx.v VERILOG_SOURCES += ../../lib/eth/rtl/lfsr.v VERILOG_SOURCES += ../../lib/eth/rtl/ptp_clock.v VERILOG_SOURCES += ../../lib/eth/rtl/ptp_clock_cdc.v @@ -167,6 +171,8 @@ export PARAM_TX_CPL_FIFO_DEPTH := 32 export PARAM_TX_CHECKSUM_ENABLE := 1 export PARAM_RX_HASH_ENABLE := 1 export PARAM_RX_CHECKSUM_ENABLE := 1 +export PARAM_LFC_ENABLE := 1 +export PARAM_PFC_ENABLE := $(PARAM_LFC_ENABLE) export PARAM_TX_FIFO_DEPTH := 32768 export PARAM_RX_FIFO_DEPTH := 32768 export PARAM_MAX_TX_SIZE := 9214 diff --git a/fpga/mqnic/DNPCIe_40G_KU_LL_2QSFP/fpga/tb/fpga_core/test_fpga_core.py b/fpga/mqnic/DNPCIe_40G_KU_LL_2QSFP/fpga/tb/fpga_core/test_fpga_core.py index 7835473e2..6134aa680 100644 --- a/fpga/mqnic/DNPCIe_40G_KU_LL_2QSFP/fpga/tb/fpga_core/test_fpga_core.py +++ b/fpga/mqnic/DNPCIe_40G_KU_LL_2QSFP/fpga/tb/fpga_core/test_fpga_core.py @@ -3,6 +3,7 @@ import logging import os +import struct import sys import scapy.utils @@ -17,7 +18,7 @@ from cocotb.clock import Clock from cocotb.triggers import RisingEdge, FallingEdge, Timer from cocotbext.axi import AxiStreamBus -from cocotbext.eth import XgmiiSource, XgmiiSink +from cocotbext.eth import XgmiiSource, XgmiiSink, XgmiiFrame from cocotbext.pcie.core import RootComplex from cocotbext.pcie.xilinx.us import UltraScalePcieDevice @@ -488,6 +489,35 @@ async def run_test_nic(dut): tb.loopback_enable = False + if tb.driver.interfaces[0].if_feature_lfc: + tb.log.info("Test LFC pause frame RX") + + await tb.driver.interfaces[0].ports[0].set_lfc_ctrl(mqnic.MQNIC_PORT_LFC_CTRL_TX_LFC_EN | mqnic.MQNIC_PORT_LFC_CTRL_RX_LFC_EN) + await tb.driver.hw_regs.read_dword(0) + + lfc_xoff = Ether(src='DA:D1:D2:D3:D4:D5', dst='01:80:C2:00:00:01', type=0x8808) / struct.pack('!HH', 0x0001, 2000) + + await tb.qsfp_source[0][0].send(XgmiiFrame.from_payload(bytes(lfc_xoff))) + + count = 16 + + pkts = [bytearray([(x+k) % 256 for x in range(1514)]) for k in range(count)] + + tb.loopback_enable = True + + for p in pkts: + await tb.driver.interfaces[0].start_xmit(p, 0) + + for k in range(count): + pkt = await tb.driver.interfaces[0].recv() + + tb.log.info("Packet: %s", pkt) + assert pkt.data == pkts[k] + if tb.driver.interfaces[0].if_feature_rx_csum: + assert pkt.rx_checksum == ~scapy.utils.checksum(bytes(pkt.data[14:])) & 0xffff + + tb.loopback_enable = False + await RisingEdge(dut.clk_250mhz) await RisingEdge(dut.clk_250mhz) @@ -560,6 +590,10 @@ def test_fpga_core(request): os.path.join(eth_rtl_dir, "eth_mac_10g.v"), os.path.join(eth_rtl_dir, "axis_xgmii_rx_64.v"), os.path.join(eth_rtl_dir, "axis_xgmii_tx_64.v"), + os.path.join(eth_rtl_dir, "mac_ctrl_rx.v"), + os.path.join(eth_rtl_dir, "mac_ctrl_tx.v"), + os.path.join(eth_rtl_dir, "mac_pause_ctrl_rx.v"), + os.path.join(eth_rtl_dir, "mac_pause_ctrl_tx.v"), os.path.join(eth_rtl_dir, "lfsr.v"), os.path.join(eth_rtl_dir, "ptp_clock.v"), os.path.join(eth_rtl_dir, "ptp_clock_cdc.v"), @@ -666,6 +700,8 @@ def test_fpga_core(request): parameters['TX_CHECKSUM_ENABLE'] = 1 parameters['RX_HASH_ENABLE'] = 1 parameters['RX_CHECKSUM_ENABLE'] = 1 + parameters['LFC_ENABLE'] = 1 + parameters['PFC_ENABLE'] = parameters['LFC_ENABLE'] parameters['TX_FIFO_DEPTH'] = 32768 parameters['RX_FIFO_DEPTH'] = 32768 parameters['MAX_TX_SIZE'] = 9214 diff --git a/fpga/mqnic/KR260/fpga/fpga/Makefile b/fpga/mqnic/KR260/fpga/fpga/Makefile index 1b8496132..9d3e5f72d 100644 --- a/fpga/mqnic/KR260/fpga/fpga/Makefile +++ b/fpga/mqnic/KR260/fpga/fpga/Makefile @@ -58,6 +58,10 @@ SYN_FILES += rtl/common/tdma_ber_ch.v SYN_FILES += lib/eth/rtl/eth_mac_10g.v SYN_FILES += lib/eth/rtl/axis_xgmii_rx_64.v SYN_FILES += lib/eth/rtl/axis_xgmii_tx_64.v +SYN_FILES += lib/eth/rtl/mac_ctrl_rx.v +SYN_FILES += lib/eth/rtl/mac_ctrl_tx.v +SYN_FILES += lib/eth/rtl/mac_pause_ctrl_rx.v +SYN_FILES += lib/eth/rtl/mac_pause_ctrl_tx.v SYN_FILES += lib/eth/rtl/eth_phy_10g.v SYN_FILES += lib/eth/rtl/eth_phy_10g_rx.v SYN_FILES += lib/eth/rtl/eth_phy_10g_rx_if.v diff --git a/fpga/mqnic/KR260/fpga/fpga/config.tcl b/fpga/mqnic/KR260/fpga/fpga/config.tcl index 39876117f..13e6a85a7 100644 --- a/fpga/mqnic/KR260/fpga/fpga/config.tcl +++ b/fpga/mqnic/KR260/fpga/fpga/config.tcl @@ -96,6 +96,8 @@ dict set params TX_CPL_FIFO_DEPTH "32" dict set params TX_CHECKSUM_ENABLE "1" dict set params RX_HASH_ENABLE "1" dict set params RX_CHECKSUM_ENABLE "1" +dict set params PFC_ENABLE "1" +dict set params LFC_ENABLE [dict get $params PFC_ENABLE] dict set params ENABLE_PADDING "1" dict set params ENABLE_DIC "1" dict set params MIN_FRAME_LENGTH "64" diff --git a/fpga/mqnic/KR260/fpga/fpga_app_dma_bench/Makefile b/fpga/mqnic/KR260/fpga/fpga_app_dma_bench/Makefile index b3933ca3d..7fdf57888 100644 --- a/fpga/mqnic/KR260/fpga/fpga_app_dma_bench/Makefile +++ b/fpga/mqnic/KR260/fpga/fpga_app_dma_bench/Makefile @@ -61,6 +61,10 @@ SYN_FILES += app/dma_bench/rtl/dram_test_ch.v SYN_FILES += lib/eth/rtl/eth_mac_10g.v SYN_FILES += lib/eth/rtl/axis_xgmii_rx_64.v SYN_FILES += lib/eth/rtl/axis_xgmii_tx_64.v +SYN_FILES += lib/eth/rtl/mac_ctrl_rx.v +SYN_FILES += lib/eth/rtl/mac_ctrl_tx.v +SYN_FILES += lib/eth/rtl/mac_pause_ctrl_rx.v +SYN_FILES += lib/eth/rtl/mac_pause_ctrl_tx.v SYN_FILES += lib/eth/rtl/eth_phy_10g.v SYN_FILES += lib/eth/rtl/eth_phy_10g_rx.v SYN_FILES += lib/eth/rtl/eth_phy_10g_rx_if.v diff --git a/fpga/mqnic/KR260/fpga/fpga_app_dma_bench/config.tcl b/fpga/mqnic/KR260/fpga/fpga_app_dma_bench/config.tcl index bab627d69..9d22be6d7 100644 --- a/fpga/mqnic/KR260/fpga/fpga_app_dma_bench/config.tcl +++ b/fpga/mqnic/KR260/fpga/fpga_app_dma_bench/config.tcl @@ -96,6 +96,8 @@ dict set params TX_CPL_FIFO_DEPTH "32" dict set params TX_CHECKSUM_ENABLE "1" dict set params RX_HASH_ENABLE "1" dict set params RX_CHECKSUM_ENABLE "1" +dict set params PFC_ENABLE "1" +dict set params LFC_ENABLE [dict get $params PFC_ENABLE] dict set params ENABLE_PADDING "1" dict set params ENABLE_DIC "1" dict set params MIN_FRAME_LENGTH "64" diff --git a/fpga/mqnic/KR260/fpga/rtl/fpga.v b/fpga/mqnic/KR260/fpga/rtl/fpga.v index fa8bb673f..6dfe63eb3 100644 --- a/fpga/mqnic/KR260/fpga/rtl/fpga.v +++ b/fpga/mqnic/KR260/fpga/rtl/fpga.v @@ -74,6 +74,8 @@ module fpga # parameter TX_CHECKSUM_ENABLE = 1, parameter RX_HASH_ENABLE = 1, parameter RX_CHECKSUM_ENABLE = 1, + parameter PFC_ENABLE = 1, + parameter LFC_ENABLE = PFC_ENABLE, parameter ENABLE_PADDING = 1, parameter ENABLE_DIC = 1, parameter MIN_FRAME_LENGTH = 64, @@ -696,6 +698,8 @@ fpga_core #( .TX_CHECKSUM_ENABLE(TX_CHECKSUM_ENABLE), .RX_HASH_ENABLE(RX_HASH_ENABLE), .RX_CHECKSUM_ENABLE(RX_CHECKSUM_ENABLE), + .PFC_ENABLE(PFC_ENABLE), + .LFC_ENABLE(LFC_ENABLE), .ENABLE_PADDING(ENABLE_PADDING), .ENABLE_DIC(ENABLE_DIC), .MIN_FRAME_LENGTH(MIN_FRAME_LENGTH), diff --git a/fpga/mqnic/KR260/fpga/rtl/fpga_core.v b/fpga/mqnic/KR260/fpga/rtl/fpga_core.v index fcee7ceb6..1564e0e94 100644 --- a/fpga/mqnic/KR260/fpga/rtl/fpga_core.v +++ b/fpga/mqnic/KR260/fpga/rtl/fpga_core.v @@ -81,6 +81,8 @@ module fpga_core # parameter TX_CHECKSUM_ENABLE = 1, parameter RX_HASH_ENABLE = 1, parameter RX_CHECKSUM_ENABLE = 1, + parameter PFC_ENABLE = 1, + parameter LFC_ENABLE = PFC_ENABLE, parameter ENABLE_PADDING = 1, parameter ENABLE_DIC = 1, parameter MIN_FRAME_LENGTH = 64, @@ -587,7 +589,12 @@ wire [PORT_COUNT*TX_TAG_WIDTH-1:0] axis_eth_tx_ptp_ts_tag; wire [PORT_COUNT-1:0] axis_eth_tx_ptp_ts_valid; wire [PORT_COUNT-1:0] axis_eth_tx_ptp_ts_ready; +wire [PORT_COUNT-1:0] eth_tx_enable; wire [PORT_COUNT-1:0] eth_tx_status; +wire [PORT_COUNT-1:0] eth_tx_lfc_en; +wire [PORT_COUNT-1:0] eth_tx_lfc_req; +wire [PORT_COUNT*8-1:0] eth_tx_pfc_en; +wire [PORT_COUNT*8-1:0] eth_tx_pfc_req; wire [PORT_COUNT-1:0] eth_rx_clk; wire [PORT_COUNT-1:0] eth_rx_rst; @@ -602,7 +609,14 @@ wire [PORT_COUNT-1:0] axis_eth_rx_tready; wire [PORT_COUNT-1:0] axis_eth_rx_tlast; wire [PORT_COUNT*AXIS_ETH_RX_USER_WIDTH-1:0] axis_eth_rx_tuser; +wire [PORT_COUNT-1:0] eth_rx_enable; wire [PORT_COUNT-1:0] eth_rx_status; +wire [PORT_COUNT-1:0] eth_rx_lfc_en; +wire [PORT_COUNT-1:0] eth_rx_lfc_req; +wire [PORT_COUNT-1:0] eth_rx_lfc_ack; +wire [PORT_COUNT*8-1:0] eth_rx_pfc_en; +wire [PORT_COUNT*8-1:0] eth_rx_pfc_req; +wire [PORT_COUNT*8-1:0] eth_rx_pfc_ack; wire [PORT_COUNT-1:0] port_xgmii_tx_clk; wire [PORT_COUNT-1:0] port_xgmii_tx_rst; @@ -675,12 +689,15 @@ generate .PTP_PERIOD_FNS(IF_PTP_PERIOD_FNS), .TX_PTP_TS_ENABLE(PTP_TS_ENABLE), .TX_PTP_TS_WIDTH(PTP_TS_WIDTH), + .TX_PTP_TS_CTRL_IN_TUSER(0), .TX_PTP_TAG_ENABLE(PTP_TS_ENABLE), .TX_PTP_TAG_WIDTH(TX_TAG_WIDTH), .RX_PTP_TS_ENABLE(PTP_TS_ENABLE), .RX_PTP_TS_WIDTH(PTP_TS_WIDTH), .TX_USER_WIDTH(AXIS_ETH_TX_USER_WIDTH), - .RX_USER_WIDTH(AXIS_ETH_RX_USER_WIDTH) + .RX_USER_WIDTH(AXIS_ETH_RX_USER_WIDTH), + .PFC_ENABLE(PFC_ENABLE), + .PAUSE_ENABLE(LFC_ENABLE) ) eth_mac_inst ( .tx_clk(port_xgmii_tx_clk[n]), @@ -688,6 +705,9 @@ generate .rx_clk(port_xgmii_rx_clk[n]), .rx_rst(port_xgmii_rx_rst[n]), + /* + * AXI input + */ .tx_axis_tdata(axis_eth_tx_tdata[n*AXIS_ETH_DATA_WIDTH +: AXIS_ETH_DATA_WIDTH]), .tx_axis_tkeep(axis_eth_tx_tkeep[n*AXIS_ETH_KEEP_WIDTH +: AXIS_ETH_KEEP_WIDTH]), .tx_axis_tvalid(axis_eth_tx_tvalid[n +: 1]), @@ -695,30 +715,121 @@ generate .tx_axis_tlast(axis_eth_tx_tlast[n +: 1]), .tx_axis_tuser(axis_eth_tx_tuser[n*AXIS_ETH_TX_USER_WIDTH +: AXIS_ETH_TX_USER_WIDTH]), + /* + * AXI output + */ .rx_axis_tdata(axis_eth_rx_tdata[n*AXIS_ETH_DATA_WIDTH +: AXIS_ETH_DATA_WIDTH]), .rx_axis_tkeep(axis_eth_rx_tkeep[n*AXIS_ETH_KEEP_WIDTH +: AXIS_ETH_KEEP_WIDTH]), .rx_axis_tvalid(axis_eth_rx_tvalid[n +: 1]), .rx_axis_tlast(axis_eth_rx_tlast[n +: 1]), .rx_axis_tuser(axis_eth_rx_tuser[n*AXIS_ETH_RX_USER_WIDTH +: AXIS_ETH_RX_USER_WIDTH]), + /* + * XGMII interface + */ .xgmii_rxd(port_xgmii_rxd[n*XGMII_DATA_WIDTH +: XGMII_DATA_WIDTH]), .xgmii_rxc(port_xgmii_rxc[n*XGMII_CTRL_WIDTH +: XGMII_CTRL_WIDTH]), .xgmii_txd(port_xgmii_txd[n*XGMII_DATA_WIDTH +: XGMII_DATA_WIDTH]), .xgmii_txc(port_xgmii_txc[n*XGMII_CTRL_WIDTH +: XGMII_CTRL_WIDTH]), + /* + * PTP + */ .tx_ptp_ts(eth_tx_ptp_ts_96[n*PTP_TS_WIDTH +: PTP_TS_WIDTH]), .rx_ptp_ts(eth_rx_ptp_ts_96[n*PTP_TS_WIDTH +: PTP_TS_WIDTH]), .tx_axis_ptp_ts(axis_eth_tx_ptp_ts[n*PTP_TS_WIDTH +: PTP_TS_WIDTH]), .tx_axis_ptp_ts_tag(axis_eth_tx_ptp_ts_tag[n*TX_TAG_WIDTH +: TX_TAG_WIDTH]), .tx_axis_ptp_ts_valid(axis_eth_tx_ptp_ts_valid[n +: 1]), + /* + * Link-level Flow Control (LFC) (IEEE 802.3 annex 31B PAUSE) + */ + .tx_lfc_req(eth_tx_lfc_req[n +: 1]), + .tx_lfc_resend(1'b0), + .rx_lfc_en(eth_rx_lfc_en[n +: 1]), + .rx_lfc_req(eth_rx_lfc_req[n +: 1]), + .rx_lfc_ack(eth_rx_lfc_ack[n +: 1]), + + /* + * Priority Flow Control (PFC) (IEEE 802.3 annex 31D PFC) + */ + .tx_pfc_req(eth_tx_pfc_req[n*8 +: 8]), + .tx_pfc_resend(1'b0), + .rx_pfc_en(eth_rx_pfc_en[n*8 +: 8]), + .rx_pfc_req(eth_rx_pfc_req[n*8 +: 8]), + .rx_pfc_ack(eth_rx_pfc_ack[n*8 +: 8]), + + /* + * Pause interface + */ + .tx_lfc_pause_en(1'b1), + .tx_pause_req(1'b0), + .tx_pause_ack(), + + /* + * Status + */ + .tx_start_packet(), .tx_error_underflow(), + .rx_start_packet(), .rx_error_bad_frame(), .rx_error_bad_fcs(), + .stat_tx_mcf(), + .stat_rx_mcf(), + .stat_tx_lfc_pkt(), + .stat_tx_lfc_xon(), + .stat_tx_lfc_xoff(), + .stat_tx_lfc_paused(), + .stat_tx_pfc_pkt(), + .stat_tx_pfc_xon(), + .stat_tx_pfc_xoff(), + .stat_tx_pfc_paused(), + .stat_rx_lfc_pkt(), + .stat_rx_lfc_xon(), + .stat_rx_lfc_xoff(), + .stat_rx_lfc_paused(), + .stat_rx_pfc_pkt(), + .stat_rx_pfc_xon(), + .stat_rx_pfc_xoff(), + .stat_rx_pfc_paused(), + /* + * Configuration + */ .cfg_ifg(8'd12), - .cfg_tx_enable(1'b1), - .cfg_rx_enable(1'b1) + .cfg_tx_enable(eth_tx_enable[n +: 1]), + .cfg_rx_enable(eth_rx_enable[n +: 1]), + .cfg_mcf_rx_eth_dst_mcast(48'h01_80_C2_00_00_01), + .cfg_mcf_rx_check_eth_dst_mcast(1'b1), + .cfg_mcf_rx_eth_dst_ucast(48'd0), + .cfg_mcf_rx_check_eth_dst_ucast(1'b0), + .cfg_mcf_rx_eth_src(48'd0), + .cfg_mcf_rx_check_eth_src(1'b0), + .cfg_mcf_rx_eth_type(16'h8808), + .cfg_mcf_rx_opcode_lfc(16'h0001), + .cfg_mcf_rx_check_opcode_lfc(eth_rx_lfc_en[n +: 1]), + .cfg_mcf_rx_opcode_pfc(16'h0101), + .cfg_mcf_rx_check_opcode_pfc(eth_rx_pfc_en[n*8 +: 8] != 0), + .cfg_mcf_rx_forward(1'b0), + .cfg_mcf_rx_enable(eth_rx_lfc_en[n +: 1] || eth_rx_pfc_en[n*8 +: 8]), + .cfg_tx_lfc_eth_dst(48'h01_80_C2_00_00_01), + .cfg_tx_lfc_eth_src(48'h80_23_31_43_54_4C), + .cfg_tx_lfc_eth_type(16'h8808), + .cfg_tx_lfc_opcode(16'h0001), + .cfg_tx_lfc_en(eth_tx_lfc_en[n +: 1]), + .cfg_tx_lfc_quanta(16'hffff), + .cfg_tx_lfc_refresh(16'h7fff), + .cfg_tx_pfc_eth_dst(48'h01_80_C2_00_00_01), + .cfg_tx_pfc_eth_src(48'h80_23_31_43_54_4C), + .cfg_tx_pfc_eth_type(16'h8808), + .cfg_tx_pfc_opcode(16'h0101), + .cfg_tx_pfc_en(eth_tx_pfc_en[n*8 +: 8] != 0), + .cfg_tx_pfc_quanta({8{16'hffff}}), + .cfg_tx_pfc_refresh({8{16'h7fff}}), + .cfg_rx_lfc_opcode(16'h0001), + .cfg_rx_lfc_en(eth_rx_lfc_en[n +: 1]), + .cfg_rx_pfc_opcode(16'h0101), + .cfg_rx_pfc_en(eth_rx_pfc_en[n*8 +: 8] != 0) ); end @@ -792,6 +903,9 @@ mqnic_core_axi #( .TX_CHECKSUM_ENABLE(TX_CHECKSUM_ENABLE), .RX_HASH_ENABLE(RX_HASH_ENABLE), .RX_CHECKSUM_ENABLE(RX_CHECKSUM_ENABLE), + .PFC_ENABLE(PFC_ENABLE), + .LFC_ENABLE(LFC_ENABLE), + .MAC_CTRL_ENABLE(0), .TX_FIFO_DEPTH(TX_FIFO_DEPTH), .RX_FIFO_DEPTH(RX_FIFO_DEPTH), .MAX_TX_SIZE(MAX_TX_SIZE), @@ -1038,7 +1152,13 @@ core_inst ( .s_axis_tx_cpl_valid(axis_eth_tx_ptp_ts_valid), .s_axis_tx_cpl_ready(axis_eth_tx_ptp_ts_ready), + .tx_enable(eth_tx_enable), .tx_status(eth_tx_status), + .tx_lfc_en(eth_tx_lfc_en), + .tx_lfc_req(eth_tx_lfc_req), + .tx_pfc_en(eth_tx_pfc_en), + .tx_pfc_req(eth_tx_pfc_req), + .tx_fc_quanta_clk_en(0), .rx_clk(eth_rx_clk), .rx_rst(eth_rx_rst), @@ -1055,7 +1175,15 @@ core_inst ( .s_axis_rx_tlast(axis_eth_rx_tlast), .s_axis_rx_tuser(axis_eth_rx_tuser), + .rx_enable(eth_rx_enable), .rx_status(eth_rx_status), + .rx_lfc_en(eth_rx_lfc_en), + .rx_lfc_req(eth_rx_lfc_req), + .rx_lfc_ack(eth_rx_lfc_ack), + .rx_pfc_en(eth_rx_pfc_en), + .rx_pfc_req(eth_rx_pfc_req), + .rx_pfc_ack(eth_rx_pfc_ack), + .rx_fc_quanta_clk_en(0), /* * DDR diff --git a/fpga/mqnic/KR260/fpga/tb/fpga_core/Makefile b/fpga/mqnic/KR260/fpga/tb/fpga_core/Makefile index 926b2def7..962a2f758 100644 --- a/fpga/mqnic/KR260/fpga/tb/fpga_core/Makefile +++ b/fpga/mqnic/KR260/fpga/tb/fpga_core/Makefile @@ -1,7 +1,6 @@ # SPDX-License-Identifier: BSD-2-Clause-Views # Copyright (c) 2020-2023 The Regents of the University of California - TOPLEVEL_LANG = verilog SIM ?= icarus @@ -60,6 +59,10 @@ VERILOG_SOURCES += ../../rtl/common/tdma_ber_ch.v VERILOG_SOURCES += ../../lib/eth/rtl/eth_mac_10g.v VERILOG_SOURCES += ../../lib/eth/rtl/axis_xgmii_rx_64.v VERILOG_SOURCES += ../../lib/eth/rtl/axis_xgmii_tx_64.v +VERILOG_SOURCES += ../../lib/eth/rtl/mac_ctrl_rx.v +VERILOG_SOURCES += ../../lib/eth/rtl/mac_ctrl_tx.v +VERILOG_SOURCES += ../../lib/eth/rtl/mac_pause_ctrl_rx.v +VERILOG_SOURCES += ../../lib/eth/rtl/mac_pause_ctrl_tx.v VERILOG_SOURCES += ../../lib/eth/rtl/lfsr.v VERILOG_SOURCES += ../../lib/eth/rtl/ptp_clock.v VERILOG_SOURCES += ../../lib/eth/rtl/ptp_clock_cdc.v @@ -152,6 +155,8 @@ export PARAM_TX_CPL_FIFO_DEPTH := 32 export PARAM_TX_CHECKSUM_ENABLE := 1 export PARAM_RX_HASH_ENABLE := 1 export PARAM_RX_CHECKSUM_ENABLE := 1 +export PARAM_LFC_ENABLE := 1 +export PARAM_PFC_ENABLE := $(PARAM_LFC_ENABLE) export PARAM_TX_FIFO_DEPTH := 32768 export PARAM_RX_FIFO_DEPTH := 32768 export PARAM_MAX_TX_SIZE := 9214 @@ -197,7 +202,7 @@ export PARAM_AXIS_ETH_TX_FIFO_PIPELINE := 2 export PARAM_AXIS_ETH_TX_TS_PIPELINE := 0 export PARAM_AXIS_ETH_RX_PIPELINE := 0 export PARAM_AXIS_ETH_RX_FIFO_PIPELINE := 2 - + # Statistics counter subsystem export PARAM_STAT_ENABLE := 1 export PARAM_STAT_DMA_ENABLE := 1 diff --git a/fpga/mqnic/KR260/fpga/tb/fpga_core/test_fpga_core.py b/fpga/mqnic/KR260/fpga/tb/fpga_core/test_fpga_core.py index 00033b1cc..e9f39181c 100644 --- a/fpga/mqnic/KR260/fpga/tb/fpga_core/test_fpga_core.py +++ b/fpga/mqnic/KR260/fpga/tb/fpga_core/test_fpga_core.py @@ -3,6 +3,7 @@ import logging import os +import struct import sys import scapy.utils @@ -19,7 +20,7 @@ from cocotb.triggers import RisingEdge from cocotbext.axi import AddressSpace from cocotbext.axi import AxiLiteMaster, AxiLiteBus from cocotbext.axi import AxiSlave, AxiBus -from cocotbext.eth import XgmiiSource, XgmiiSink +from cocotbext.eth import XgmiiSource, XgmiiSink, XgmiiFrame try: import mqnic @@ -272,6 +273,35 @@ async def run_test_nic(dut): tb.loopback_enable = False + if tb.driver.interfaces[0].if_feature_lfc: + tb.log.info("Test LFC pause frame RX") + + await tb.driver.interfaces[0].ports[0].set_lfc_ctrl(mqnic.MQNIC_PORT_LFC_CTRL_TX_LFC_EN | mqnic.MQNIC_PORT_LFC_CTRL_RX_LFC_EN) + await tb.driver.hw_regs.read_dword(0) + + lfc_xoff = Ether(src='DA:D1:D2:D3:D4:D5', dst='01:80:C2:00:00:01', type=0x8808) / struct.pack('!HH', 0x0001, 2000) + + await tb.sfp_source.send(XgmiiFrame.from_payload(bytes(lfc_xoff))) + + count = 16 + + pkts = [bytearray([(x+k) % 256 for x in range(1514)]) for k in range(count)] + + tb.loopback_enable = True + + for p in pkts: + await tb.driver.interfaces[0].start_xmit(p, 0) + + for k in range(count): + pkt = await tb.driver.interfaces[0].recv() + + tb.log.info("Packet: %s", pkt) + assert pkt.data == pkts[k] + if tb.driver.interfaces[0].if_feature_rx_csum: + assert pkt.rx_checksum == ~scapy.utils.checksum(bytes(pkt.data[14:])) & 0xffff + + tb.loopback_enable = False + await RisingEdge(dut.clk_250mhz) await RisingEdge(dut.clk_250mhz) @@ -341,6 +371,10 @@ def test_fpga_core(request): os.path.join(eth_rtl_dir, "eth_mac_10g.v"), os.path.join(eth_rtl_dir, "axis_xgmii_rx_64.v"), os.path.join(eth_rtl_dir, "axis_xgmii_tx_64.v"), + os.path.join(eth_rtl_dir, "mac_ctrl_rx.v"), + os.path.join(eth_rtl_dir, "mac_ctrl_tx.v"), + os.path.join(eth_rtl_dir, "mac_pause_ctrl_rx.v"), + os.path.join(eth_rtl_dir, "mac_pause_ctrl_tx.v"), os.path.join(eth_rtl_dir, "lfsr.v"), os.path.join(eth_rtl_dir, "ptp_clock.v"), os.path.join(eth_rtl_dir, "ptp_clock_cdc.v"), @@ -434,6 +468,8 @@ def test_fpga_core(request): parameters['TX_CHECKSUM_ENABLE'] = 1 parameters['RX_HASH_ENABLE'] = 1 parameters['RX_CHECKSUM_ENABLE'] = 1 + parameters['LFC_ENABLE'] = 1 + parameters['PFC_ENABLE'] = parameters['LFC_ENABLE'] parameters['TX_FIFO_DEPTH'] = 32768 parameters['RX_FIFO_DEPTH'] = 32768 parameters['MAX_TX_SIZE'] = 9214 diff --git a/fpga/mqnic/NetFPGA_SUME/fpga/fpga/Makefile b/fpga/mqnic/NetFPGA_SUME/fpga/fpga/Makefile index a144a72af..4532cb5cc 100644 --- a/fpga/mqnic/NetFPGA_SUME/fpga/fpga/Makefile +++ b/fpga/mqnic/NetFPGA_SUME/fpga/fpga/Makefile @@ -60,6 +60,10 @@ SYN_FILES += rtl/common/tdma_ber_ch.v SYN_FILES += lib/eth/rtl/eth_mac_10g.v SYN_FILES += lib/eth/rtl/axis_xgmii_rx_64.v SYN_FILES += lib/eth/rtl/axis_xgmii_tx_64.v +SYN_FILES += lib/eth/rtl/mac_ctrl_rx.v +SYN_FILES += lib/eth/rtl/mac_ctrl_tx.v +SYN_FILES += lib/eth/rtl/mac_pause_ctrl_rx.v +SYN_FILES += lib/eth/rtl/mac_pause_ctrl_tx.v SYN_FILES += lib/eth/rtl/eth_phy_10g.v SYN_FILES += lib/eth/rtl/eth_phy_10g_rx.v SYN_FILES += lib/eth/rtl/eth_phy_10g_rx_if.v diff --git a/fpga/mqnic/NetFPGA_SUME/fpga/fpga/config.tcl b/fpga/mqnic/NetFPGA_SUME/fpga/fpga/config.tcl index 20746e6a2..c2cba15f4 100644 --- a/fpga/mqnic/NetFPGA_SUME/fpga/fpga/config.tcl +++ b/fpga/mqnic/NetFPGA_SUME/fpga/fpga/config.tcl @@ -101,6 +101,8 @@ dict set params TX_CPL_FIFO_DEPTH "32" dict set params TX_CHECKSUM_ENABLE "1" dict set params RX_HASH_ENABLE "1" dict set params RX_CHECKSUM_ENABLE "1" +dict set params PFC_ENABLE "1" +dict set params LFC_ENABLE [dict get $params PFC_ENABLE] dict set params ENABLE_PADDING "1" dict set params ENABLE_DIC "1" dict set params MIN_FRAME_LENGTH "64" diff --git a/fpga/mqnic/NetFPGA_SUME/fpga/fpga_app_dma_bench/Makefile b/fpga/mqnic/NetFPGA_SUME/fpga/fpga_app_dma_bench/Makefile index 69b18673e..bae621a35 100644 --- a/fpga/mqnic/NetFPGA_SUME/fpga/fpga_app_dma_bench/Makefile +++ b/fpga/mqnic/NetFPGA_SUME/fpga/fpga_app_dma_bench/Makefile @@ -62,6 +62,10 @@ SYN_FILES += app/dma_bench/rtl/dma_bench.v SYN_FILES += lib/eth/rtl/eth_mac_10g.v SYN_FILES += lib/eth/rtl/axis_xgmii_rx_64.v SYN_FILES += lib/eth/rtl/axis_xgmii_tx_64.v +SYN_FILES += lib/eth/rtl/mac_ctrl_rx.v +SYN_FILES += lib/eth/rtl/mac_ctrl_tx.v +SYN_FILES += lib/eth/rtl/mac_pause_ctrl_rx.v +SYN_FILES += lib/eth/rtl/mac_pause_ctrl_tx.v SYN_FILES += lib/eth/rtl/eth_phy_10g.v SYN_FILES += lib/eth/rtl/eth_phy_10g_rx.v SYN_FILES += lib/eth/rtl/eth_phy_10g_rx_if.v diff --git a/fpga/mqnic/NetFPGA_SUME/fpga/fpga_app_dma_bench/config.tcl b/fpga/mqnic/NetFPGA_SUME/fpga/fpga_app_dma_bench/config.tcl index 0e482d503..5812ea96a 100644 --- a/fpga/mqnic/NetFPGA_SUME/fpga/fpga_app_dma_bench/config.tcl +++ b/fpga/mqnic/NetFPGA_SUME/fpga/fpga_app_dma_bench/config.tcl @@ -101,6 +101,8 @@ dict set params TX_CPL_FIFO_DEPTH "32" dict set params TX_CHECKSUM_ENABLE "1" dict set params RX_HASH_ENABLE "1" dict set params RX_CHECKSUM_ENABLE "1" +dict set params PFC_ENABLE "1" +dict set params LFC_ENABLE [dict get $params PFC_ENABLE] dict set params ENABLE_PADDING "1" dict set params ENABLE_DIC "1" dict set params MIN_FRAME_LENGTH "64" diff --git a/fpga/mqnic/NetFPGA_SUME/fpga/rtl/fpga.v b/fpga/mqnic/NetFPGA_SUME/fpga/rtl/fpga.v index a6528e856..2e5233107 100644 --- a/fpga/mqnic/NetFPGA_SUME/fpga/rtl/fpga.v +++ b/fpga/mqnic/NetFPGA_SUME/fpga/rtl/fpga.v @@ -71,6 +71,8 @@ module fpga # parameter TX_CHECKSUM_ENABLE = 1, parameter RX_HASH_ENABLE = 1, parameter RX_CHECKSUM_ENABLE = 1, + parameter LFC_ENABLE = PFC_ENABLE, + parameter PFC_ENABLE = 1, parameter ENABLE_PADDING = 1, parameter ENABLE_DIC = 1, parameter MIN_FRAME_LENGTH = 64, @@ -1332,6 +1334,8 @@ fpga_core #( .TX_CHECKSUM_ENABLE(TX_CHECKSUM_ENABLE), .RX_HASH_ENABLE(RX_HASH_ENABLE), .RX_CHECKSUM_ENABLE(RX_CHECKSUM_ENABLE), + .PFC_ENABLE(PFC_ENABLE), + .LFC_ENABLE(LFC_ENABLE), .ENABLE_PADDING(ENABLE_PADDING), .ENABLE_DIC(ENABLE_DIC), .MIN_FRAME_LENGTH(MIN_FRAME_LENGTH), diff --git a/fpga/mqnic/NetFPGA_SUME/fpga/rtl/fpga_core.v b/fpga/mqnic/NetFPGA_SUME/fpga/rtl/fpga_core.v index 7fa1fccb0..bd491dac4 100644 --- a/fpga/mqnic/NetFPGA_SUME/fpga/rtl/fpga_core.v +++ b/fpga/mqnic/NetFPGA_SUME/fpga/rtl/fpga_core.v @@ -78,6 +78,8 @@ module fpga_core # parameter TX_CHECKSUM_ENABLE = 1, parameter RX_HASH_ENABLE = 1, parameter RX_CHECKSUM_ENABLE = 1, + parameter PFC_ENABLE = 1, + parameter LFC_ENABLE = PFC_ENABLE, parameter ENABLE_PADDING = 1, parameter ENABLE_DIC = 1, parameter MIN_FRAME_LENGTH = 64, @@ -544,7 +546,12 @@ wire [PORT_COUNT*TX_TAG_WIDTH-1:0] axis_eth_tx_ptp_ts_tag; wire [PORT_COUNT-1:0] axis_eth_tx_ptp_ts_valid; wire [PORT_COUNT-1:0] axis_eth_tx_ptp_ts_ready; +wire [PORT_COUNT-1:0] eth_tx_enable; wire [PORT_COUNT-1:0] eth_tx_status; +wire [PORT_COUNT-1:0] eth_tx_lfc_en; +wire [PORT_COUNT-1:0] eth_tx_lfc_req; +wire [PORT_COUNT*8-1:0] eth_tx_pfc_en; +wire [PORT_COUNT*8-1:0] eth_tx_pfc_req; wire [PORT_COUNT-1:0] eth_rx_clk; wire [PORT_COUNT-1:0] eth_rx_rst; @@ -559,7 +566,14 @@ wire [PORT_COUNT-1:0] axis_eth_rx_tready; wire [PORT_COUNT-1:0] axis_eth_rx_tlast; wire [PORT_COUNT*AXIS_ETH_RX_USER_WIDTH-1:0] axis_eth_rx_tuser; +wire [PORT_COUNT-1:0] eth_rx_enable; wire [PORT_COUNT-1:0] eth_rx_status; +wire [PORT_COUNT-1:0] eth_rx_lfc_en; +wire [PORT_COUNT-1:0] eth_rx_lfc_req; +wire [PORT_COUNT-1:0] eth_rx_lfc_ack; +wire [PORT_COUNT*8-1:0] eth_rx_pfc_en; +wire [PORT_COUNT*8-1:0] eth_rx_pfc_req; +wire [PORT_COUNT*8-1:0] eth_rx_pfc_ack; wire [PORT_COUNT-1:0] port_xgmii_tx_clk; wire [PORT_COUNT-1:0] port_xgmii_tx_rst; @@ -632,12 +646,15 @@ generate .PTP_PERIOD_FNS(IF_PTP_PERIOD_FNS), .TX_PTP_TS_ENABLE(PTP_TS_ENABLE), .TX_PTP_TS_WIDTH(PTP_TS_WIDTH), + .TX_PTP_TS_CTRL_IN_TUSER(0), .TX_PTP_TAG_ENABLE(PTP_TS_ENABLE), .TX_PTP_TAG_WIDTH(TX_TAG_WIDTH), .RX_PTP_TS_ENABLE(PTP_TS_ENABLE), .RX_PTP_TS_WIDTH(PTP_TS_WIDTH), .TX_USER_WIDTH(AXIS_ETH_TX_USER_WIDTH), - .RX_USER_WIDTH(AXIS_ETH_RX_USER_WIDTH) + .RX_USER_WIDTH(AXIS_ETH_RX_USER_WIDTH), + .PFC_ENABLE(PFC_ENABLE), + .PAUSE_ENABLE(LFC_ENABLE) ) eth_mac_inst ( .tx_clk(port_xgmii_tx_clk[n]), @@ -645,6 +662,9 @@ generate .rx_clk(port_xgmii_rx_clk[n]), .rx_rst(port_xgmii_rx_rst[n]), + /* + * AXI input + */ .tx_axis_tdata(axis_eth_tx_tdata[n*AXIS_ETH_DATA_WIDTH +: AXIS_ETH_DATA_WIDTH]), .tx_axis_tkeep(axis_eth_tx_tkeep[n*AXIS_ETH_KEEP_WIDTH +: AXIS_ETH_KEEP_WIDTH]), .tx_axis_tvalid(axis_eth_tx_tvalid[n +: 1]), @@ -652,30 +672,121 @@ generate .tx_axis_tlast(axis_eth_tx_tlast[n +: 1]), .tx_axis_tuser(axis_eth_tx_tuser[n*AXIS_ETH_TX_USER_WIDTH +: AXIS_ETH_TX_USER_WIDTH]), + /* + * AXI output + */ .rx_axis_tdata(axis_eth_rx_tdata[n*AXIS_ETH_DATA_WIDTH +: AXIS_ETH_DATA_WIDTH]), .rx_axis_tkeep(axis_eth_rx_tkeep[n*AXIS_ETH_KEEP_WIDTH +: AXIS_ETH_KEEP_WIDTH]), .rx_axis_tvalid(axis_eth_rx_tvalid[n +: 1]), .rx_axis_tlast(axis_eth_rx_tlast[n +: 1]), .rx_axis_tuser(axis_eth_rx_tuser[n*AXIS_ETH_RX_USER_WIDTH +: AXIS_ETH_RX_USER_WIDTH]), + /* + * XGMII interface + */ .xgmii_rxd(port_xgmii_rxd[n*XGMII_DATA_WIDTH +: XGMII_DATA_WIDTH]), .xgmii_rxc(port_xgmii_rxc[n*XGMII_CTRL_WIDTH +: XGMII_CTRL_WIDTH]), .xgmii_txd(port_xgmii_txd[n*XGMII_DATA_WIDTH +: XGMII_DATA_WIDTH]), .xgmii_txc(port_xgmii_txc[n*XGMII_CTRL_WIDTH +: XGMII_CTRL_WIDTH]), + /* + * PTP + */ .tx_ptp_ts(eth_tx_ptp_ts_96[n*PTP_TS_WIDTH +: PTP_TS_WIDTH]), .rx_ptp_ts(eth_rx_ptp_ts_96[n*PTP_TS_WIDTH +: PTP_TS_WIDTH]), .tx_axis_ptp_ts(axis_eth_tx_ptp_ts[n*PTP_TS_WIDTH +: PTP_TS_WIDTH]), .tx_axis_ptp_ts_tag(axis_eth_tx_ptp_ts_tag[n*TX_TAG_WIDTH +: TX_TAG_WIDTH]), .tx_axis_ptp_ts_valid(axis_eth_tx_ptp_ts_valid[n +: 1]), + /* + * Link-level Flow Control (LFC) (IEEE 802.3 annex 31B PAUSE) + */ + .tx_lfc_req(eth_tx_lfc_req[n +: 1]), + .tx_lfc_resend(1'b0), + .rx_lfc_en(eth_rx_lfc_en[n +: 1]), + .rx_lfc_req(eth_rx_lfc_req[n +: 1]), + .rx_lfc_ack(eth_rx_lfc_ack[n +: 1]), + + /* + * Priority Flow Control (PFC) (IEEE 802.3 annex 31D PFC) + */ + .tx_pfc_req(eth_tx_pfc_req[n*8 +: 8]), + .tx_pfc_resend(1'b0), + .rx_pfc_en(eth_rx_pfc_en[n*8 +: 8]), + .rx_pfc_req(eth_rx_pfc_req[n*8 +: 8]), + .rx_pfc_ack(eth_rx_pfc_ack[n*8 +: 8]), + + /* + * Pause interface + */ + .tx_lfc_pause_en(1'b1), + .tx_pause_req(1'b0), + .tx_pause_ack(), + + /* + * Status + */ + .tx_start_packet(), .tx_error_underflow(), + .rx_start_packet(), .rx_error_bad_frame(), .rx_error_bad_fcs(), + .stat_tx_mcf(), + .stat_rx_mcf(), + .stat_tx_lfc_pkt(), + .stat_tx_lfc_xon(), + .stat_tx_lfc_xoff(), + .stat_tx_lfc_paused(), + .stat_tx_pfc_pkt(), + .stat_tx_pfc_xon(), + .stat_tx_pfc_xoff(), + .stat_tx_pfc_paused(), + .stat_rx_lfc_pkt(), + .stat_rx_lfc_xon(), + .stat_rx_lfc_xoff(), + .stat_rx_lfc_paused(), + .stat_rx_pfc_pkt(), + .stat_rx_pfc_xon(), + .stat_rx_pfc_xoff(), + .stat_rx_pfc_paused(), + /* + * Configuration + */ .cfg_ifg(8'd12), - .cfg_tx_enable(1'b1), - .cfg_rx_enable(1'b1) + .cfg_tx_enable(eth_tx_enable[n +: 1]), + .cfg_rx_enable(eth_rx_enable[n +: 1]), + .cfg_mcf_rx_eth_dst_mcast(48'h01_80_C2_00_00_01), + .cfg_mcf_rx_check_eth_dst_mcast(1'b1), + .cfg_mcf_rx_eth_dst_ucast(48'd0), + .cfg_mcf_rx_check_eth_dst_ucast(1'b0), + .cfg_mcf_rx_eth_src(48'd0), + .cfg_mcf_rx_check_eth_src(1'b0), + .cfg_mcf_rx_eth_type(16'h8808), + .cfg_mcf_rx_opcode_lfc(16'h0001), + .cfg_mcf_rx_check_opcode_lfc(eth_rx_lfc_en[n +: 1]), + .cfg_mcf_rx_opcode_pfc(16'h0101), + .cfg_mcf_rx_check_opcode_pfc(eth_rx_pfc_en[n*8 +: 8] != 0), + .cfg_mcf_rx_forward(1'b0), + .cfg_mcf_rx_enable(eth_rx_lfc_en[n +: 1] || eth_rx_pfc_en[n*8 +: 8]), + .cfg_tx_lfc_eth_dst(48'h01_80_C2_00_00_01), + .cfg_tx_lfc_eth_src(48'h80_23_31_43_54_4C), + .cfg_tx_lfc_eth_type(16'h8808), + .cfg_tx_lfc_opcode(16'h0001), + .cfg_tx_lfc_en(eth_tx_lfc_en[n +: 1]), + .cfg_tx_lfc_quanta(16'hffff), + .cfg_tx_lfc_refresh(16'h7fff), + .cfg_tx_pfc_eth_dst(48'h01_80_C2_00_00_01), + .cfg_tx_pfc_eth_src(48'h80_23_31_43_54_4C), + .cfg_tx_pfc_eth_type(16'h8808), + .cfg_tx_pfc_opcode(16'h0101), + .cfg_tx_pfc_en(eth_tx_pfc_en[n*8 +: 8] != 0), + .cfg_tx_pfc_quanta({8{16'hffff}}), + .cfg_tx_pfc_refresh({8{16'h7fff}}), + .cfg_rx_lfc_opcode(16'h0001), + .cfg_rx_lfc_en(eth_rx_lfc_en[n +: 1]), + .cfg_rx_pfc_opcode(16'h0101), + .cfg_rx_pfc_en(eth_rx_pfc_en[n*8 +: 8] != 0) ); end @@ -749,6 +860,9 @@ mqnic_core_pcie_us #( .TX_CHECKSUM_ENABLE(TX_CHECKSUM_ENABLE), .RX_HASH_ENABLE(RX_HASH_ENABLE), .RX_CHECKSUM_ENABLE(RX_CHECKSUM_ENABLE), + .PFC_ENABLE(PFC_ENABLE), + .LFC_ENABLE(LFC_ENABLE), + .MAC_CTRL_ENABLE(0), .TX_FIFO_DEPTH(TX_FIFO_DEPTH), .RX_FIFO_DEPTH(RX_FIFO_DEPTH), .MAX_TX_SIZE(MAX_TX_SIZE), @@ -1015,7 +1129,13 @@ core_inst ( .s_axis_eth_tx_cpl_valid(axis_eth_tx_ptp_ts_valid), .s_axis_eth_tx_cpl_ready(axis_eth_tx_ptp_ts_ready), + .eth_tx_enable(eth_tx_enable), .eth_tx_status(eth_tx_status), + .eth_tx_lfc_en(eth_tx_lfc_en), + .eth_tx_lfc_req(eth_tx_lfc_req), + .eth_tx_pfc_en(eth_tx_pfc_en), + .eth_tx_pfc_req(eth_tx_pfc_req), + .eth_tx_fc_quanta_clk_en(0), .eth_rx_clk(eth_rx_clk), .eth_rx_rst(eth_rx_rst), @@ -1032,7 +1152,15 @@ core_inst ( .s_axis_eth_rx_tlast(axis_eth_rx_tlast), .s_axis_eth_rx_tuser(axis_eth_rx_tuser), + .eth_rx_enable(eth_rx_enable), .eth_rx_status(eth_rx_status), + .eth_rx_lfc_en(eth_rx_lfc_en), + .eth_rx_lfc_req(eth_rx_lfc_req), + .eth_rx_lfc_ack(eth_rx_lfc_ack), + .eth_rx_pfc_en(eth_rx_pfc_en), + .eth_rx_pfc_req(eth_rx_pfc_req), + .eth_rx_pfc_ack(eth_rx_pfc_ack), + .eth_rx_fc_quanta_clk_en(0), /* * DDR diff --git a/fpga/mqnic/NetFPGA_SUME/fpga/tb/fpga_core/Makefile b/fpga/mqnic/NetFPGA_SUME/fpga/tb/fpga_core/Makefile index 37103f784..4661932b0 100644 --- a/fpga/mqnic/NetFPGA_SUME/fpga/tb/fpga_core/Makefile +++ b/fpga/mqnic/NetFPGA_SUME/fpga/tb/fpga_core/Makefile @@ -60,6 +60,10 @@ VERILOG_SOURCES += ../../rtl/common/tdma_ber_ch.v VERILOG_SOURCES += ../../lib/eth/rtl/eth_mac_10g.v VERILOG_SOURCES += ../../lib/eth/rtl/axis_xgmii_rx_64.v VERILOG_SOURCES += ../../lib/eth/rtl/axis_xgmii_tx_64.v +VERILOG_SOURCES += ../../lib/eth/rtl/mac_ctrl_rx.v +VERILOG_SOURCES += ../../lib/eth/rtl/mac_ctrl_tx.v +VERILOG_SOURCES += ../../lib/eth/rtl/mac_pause_ctrl_rx.v +VERILOG_SOURCES += ../../lib/eth/rtl/mac_pause_ctrl_tx.v VERILOG_SOURCES += ../../lib/eth/rtl/lfsr.v VERILOG_SOURCES += ../../lib/eth/rtl/ptp_clock.v VERILOG_SOURCES += ../../lib/eth/rtl/ptp_clock_cdc.v @@ -165,6 +169,8 @@ export PARAM_TX_CPL_FIFO_DEPTH := 32 export PARAM_TX_CHECKSUM_ENABLE := 1 export PARAM_RX_HASH_ENABLE := 1 export PARAM_RX_CHECKSUM_ENABLE := 1 +export PARAM_LFC_ENABLE := 1 +export PARAM_PFC_ENABLE := $(PARAM_LFC_ENABLE) export PARAM_TX_FIFO_DEPTH := 32768 export PARAM_RX_FIFO_DEPTH := 32768 export PARAM_MAX_TX_SIZE := 9214 diff --git a/fpga/mqnic/NetFPGA_SUME/fpga/tb/fpga_core/test_fpga_core.py b/fpga/mqnic/NetFPGA_SUME/fpga/tb/fpga_core/test_fpga_core.py index 7659eac21..f7d1bb550 100644 --- a/fpga/mqnic/NetFPGA_SUME/fpga/tb/fpga_core/test_fpga_core.py +++ b/fpga/mqnic/NetFPGA_SUME/fpga/tb/fpga_core/test_fpga_core.py @@ -3,6 +3,7 @@ import logging import os +import struct import sys import scapy.utils @@ -17,7 +18,7 @@ from cocotb.clock import Clock from cocotb.triggers import RisingEdge, FallingEdge, Timer from cocotbext.axi import AxiStreamBus -from cocotbext.eth import XgmiiSource, XgmiiSink +from cocotbext.eth import XgmiiSource, XgmiiSink, XgmiiFrame from cocotbext.pcie.core import RootComplex from cocotbext.pcie.xilinx.us import UltraScalePcieDevice @@ -480,6 +481,35 @@ async def run_test_nic(dut): tb.loopback_enable = False + if tb.driver.interfaces[0].if_feature_lfc: + tb.log.info("Test LFC pause frame RX") + + await tb.driver.interfaces[0].ports[0].set_lfc_ctrl(mqnic.MQNIC_PORT_LFC_CTRL_TX_LFC_EN | mqnic.MQNIC_PORT_LFC_CTRL_RX_LFC_EN) + await tb.driver.hw_regs.read_dword(0) + + lfc_xoff = Ether(src='DA:D1:D2:D3:D4:D5', dst='01:80:C2:00:00:01', type=0x8808) / struct.pack('!HH', 0x0001, 2000) + + await tb.sfp_source[0].send(XgmiiFrame.from_payload(bytes(lfc_xoff))) + + count = 16 + + pkts = [bytearray([(x+k) % 256 for x in range(1514)]) for k in range(count)] + + tb.loopback_enable = True + + for p in pkts: + await tb.driver.interfaces[0].start_xmit(p, 0) + + for k in range(count): + pkt = await tb.driver.interfaces[0].recv() + + tb.log.info("Packet: %s", pkt) + assert pkt.data == pkts[k] + if tb.driver.interfaces[0].if_feature_rx_csum: + assert pkt.rx_checksum == ~scapy.utils.checksum(bytes(pkt.data[14:])) & 0xffff + + tb.loopback_enable = False + await RisingEdge(dut.clk_250mhz) await RisingEdge(dut.clk_250mhz) @@ -550,6 +580,10 @@ def test_fpga_core(request): os.path.join(eth_rtl_dir, "eth_mac_10g.v"), os.path.join(eth_rtl_dir, "axis_xgmii_rx_64.v"), os.path.join(eth_rtl_dir, "axis_xgmii_tx_64.v"), + os.path.join(eth_rtl_dir, "mac_ctrl_rx.v"), + os.path.join(eth_rtl_dir, "mac_ctrl_tx.v"), + os.path.join(eth_rtl_dir, "mac_pause_ctrl_rx.v"), + os.path.join(eth_rtl_dir, "mac_pause_ctrl_tx.v"), os.path.join(eth_rtl_dir, "lfsr.v"), os.path.join(eth_rtl_dir, "ptp_clock.v"), os.path.join(eth_rtl_dir, "ptp_clock_cdc.v"), @@ -656,6 +690,8 @@ def test_fpga_core(request): parameters['TX_CHECKSUM_ENABLE'] = 1 parameters['RX_HASH_ENABLE'] = 1 parameters['RX_CHECKSUM_ENABLE'] = 1 + parameters['LFC_ENABLE'] = 1 + parameters['PFC_ENABLE'] = parameters['LFC_ENABLE'] parameters['TX_FIFO_DEPTH'] = 32768 parameters['RX_FIFO_DEPTH'] = 32768 parameters['MAX_TX_SIZE'] = 9214 diff --git a/fpga/mqnic/Nexus_K35_S/fpga/fpga/Makefile b/fpga/mqnic/Nexus_K35_S/fpga/fpga/Makefile index 27166f87b..b2b1a9151 100644 --- a/fpga/mqnic/Nexus_K35_S/fpga/fpga/Makefile +++ b/fpga/mqnic/Nexus_K35_S/fpga/fpga/Makefile @@ -61,6 +61,10 @@ SYN_FILES += rtl/common/i2c_single_reg.v SYN_FILES += lib/eth/rtl/eth_mac_10g.v SYN_FILES += lib/eth/rtl/axis_xgmii_rx_64.v SYN_FILES += lib/eth/rtl/axis_xgmii_tx_64.v +SYN_FILES += lib/eth/rtl/mac_ctrl_rx.v +SYN_FILES += lib/eth/rtl/mac_ctrl_tx.v +SYN_FILES += lib/eth/rtl/mac_pause_ctrl_rx.v +SYN_FILES += lib/eth/rtl/mac_pause_ctrl_tx.v SYN_FILES += lib/eth/rtl/eth_phy_10g.v SYN_FILES += lib/eth/rtl/eth_phy_10g_rx.v SYN_FILES += lib/eth/rtl/eth_phy_10g_rx_if.v diff --git a/fpga/mqnic/Nexus_K35_S/fpga/fpga/config.tcl b/fpga/mqnic/Nexus_K35_S/fpga/fpga/config.tcl index e9f0a42d7..e88d5621d 100644 --- a/fpga/mqnic/Nexus_K35_S/fpga/fpga/config.tcl +++ b/fpga/mqnic/Nexus_K35_S/fpga/fpga/config.tcl @@ -101,6 +101,8 @@ dict set params TX_CPL_FIFO_DEPTH "32" dict set params TX_CHECKSUM_ENABLE "1" dict set params RX_HASH_ENABLE "1" dict set params RX_CHECKSUM_ENABLE "1" +dict set params PFC_ENABLE "1" +dict set params LFC_ENABLE [dict get $params PFC_ENABLE] dict set params ENABLE_PADDING "1" dict set params ENABLE_DIC "1" dict set params MIN_FRAME_LENGTH "64" diff --git a/fpga/mqnic/Nexus_K35_S/fpga/fpga_app_dma_bench/Makefile b/fpga/mqnic/Nexus_K35_S/fpga/fpga_app_dma_bench/Makefile index 21ad2fc80..828250a71 100644 --- a/fpga/mqnic/Nexus_K35_S/fpga/fpga_app_dma_bench/Makefile +++ b/fpga/mqnic/Nexus_K35_S/fpga/fpga_app_dma_bench/Makefile @@ -63,6 +63,10 @@ SYN_FILES += app/dma_bench/rtl/dma_bench.v SYN_FILES += lib/eth/rtl/eth_mac_10g.v SYN_FILES += lib/eth/rtl/axis_xgmii_rx_64.v SYN_FILES += lib/eth/rtl/axis_xgmii_tx_64.v +SYN_FILES += lib/eth/rtl/mac_ctrl_rx.v +SYN_FILES += lib/eth/rtl/mac_ctrl_tx.v +SYN_FILES += lib/eth/rtl/mac_pause_ctrl_rx.v +SYN_FILES += lib/eth/rtl/mac_pause_ctrl_tx.v SYN_FILES += lib/eth/rtl/eth_phy_10g.v SYN_FILES += lib/eth/rtl/eth_phy_10g_rx.v SYN_FILES += lib/eth/rtl/eth_phy_10g_rx_if.v diff --git a/fpga/mqnic/Nexus_K35_S/fpga/fpga_app_dma_bench/config.tcl b/fpga/mqnic/Nexus_K35_S/fpga/fpga_app_dma_bench/config.tcl index a27007a73..2abd0335f 100644 --- a/fpga/mqnic/Nexus_K35_S/fpga/fpga_app_dma_bench/config.tcl +++ b/fpga/mqnic/Nexus_K35_S/fpga/fpga_app_dma_bench/config.tcl @@ -101,6 +101,8 @@ dict set params TX_CPL_FIFO_DEPTH "32" dict set params TX_CHECKSUM_ENABLE "1" dict set params RX_HASH_ENABLE "1" dict set params RX_CHECKSUM_ENABLE "1" +dict set params PFC_ENABLE "1" +dict set params LFC_ENABLE [dict get $params PFC_ENABLE] dict set params ENABLE_PADDING "1" dict set params ENABLE_DIC "1" dict set params MIN_FRAME_LENGTH "64" diff --git a/fpga/mqnic/Nexus_K35_S/fpga/rtl/fpga.v b/fpga/mqnic/Nexus_K35_S/fpga/rtl/fpga.v index 24ca1200a..c011c33ae 100644 --- a/fpga/mqnic/Nexus_K35_S/fpga/rtl/fpga.v +++ b/fpga/mqnic/Nexus_K35_S/fpga/rtl/fpga.v @@ -71,6 +71,8 @@ module fpga # parameter TX_CHECKSUM_ENABLE = 1, parameter RX_HASH_ENABLE = 1, parameter RX_CHECKSUM_ENABLE = 1, + parameter PFC_ENABLE = 1, + parameter LFC_ENABLE = PFC_ENABLE, parameter ENABLE_PADDING = 1, parameter ENABLE_DIC = 1, parameter MIN_FRAME_LENGTH = 64, @@ -1047,6 +1049,8 @@ fpga_core #( .TX_CHECKSUM_ENABLE(TX_CHECKSUM_ENABLE), .RX_HASH_ENABLE(RX_HASH_ENABLE), .RX_CHECKSUM_ENABLE(RX_CHECKSUM_ENABLE), + .PFC_ENABLE(PFC_ENABLE), + .LFC_ENABLE(LFC_ENABLE), .ENABLE_PADDING(ENABLE_PADDING), .ENABLE_DIC(ENABLE_DIC), .MIN_FRAME_LENGTH(MIN_FRAME_LENGTH), diff --git a/fpga/mqnic/Nexus_K35_S/fpga/rtl/fpga_core.v b/fpga/mqnic/Nexus_K35_S/fpga/rtl/fpga_core.v index a96def108..10ede33ed 100644 --- a/fpga/mqnic/Nexus_K35_S/fpga/rtl/fpga_core.v +++ b/fpga/mqnic/Nexus_K35_S/fpga/rtl/fpga_core.v @@ -78,6 +78,8 @@ module fpga_core # parameter TX_CHECKSUM_ENABLE = 1, parameter RX_HASH_ENABLE = 1, parameter RX_CHECKSUM_ENABLE = 1, + parameter PFC_ENABLE = 1, + parameter LFC_ENABLE = PFC_ENABLE, parameter ENABLE_PADDING = 1, parameter ENABLE_DIC = 1, parameter MIN_FRAME_LENGTH = 64, @@ -719,7 +721,12 @@ wire [PORT_COUNT*TX_TAG_WIDTH-1:0] axis_eth_tx_ptp_ts_tag; wire [PORT_COUNT-1:0] axis_eth_tx_ptp_ts_valid; wire [PORT_COUNT-1:0] axis_eth_tx_ptp_ts_ready; +wire [PORT_COUNT-1:0] eth_tx_enable; wire [PORT_COUNT-1:0] eth_tx_status; +wire [PORT_COUNT-1:0] eth_tx_lfc_en; +wire [PORT_COUNT-1:0] eth_tx_lfc_req; +wire [PORT_COUNT*8-1:0] eth_tx_pfc_en; +wire [PORT_COUNT*8-1:0] eth_tx_pfc_req; wire [PORT_COUNT-1:0] eth_rx_clk; wire [PORT_COUNT-1:0] eth_rx_rst; @@ -734,7 +741,14 @@ wire [PORT_COUNT-1:0] axis_eth_rx_tready; wire [PORT_COUNT-1:0] axis_eth_rx_tlast; wire [PORT_COUNT*AXIS_ETH_RX_USER_WIDTH-1:0] axis_eth_rx_tuser; +wire [PORT_COUNT-1:0] eth_rx_enable; wire [PORT_COUNT-1:0] eth_rx_status; +wire [PORT_COUNT-1:0] eth_rx_lfc_en; +wire [PORT_COUNT-1:0] eth_rx_lfc_req; +wire [PORT_COUNT-1:0] eth_rx_lfc_ack; +wire [PORT_COUNT*8-1:0] eth_rx_pfc_en; +wire [PORT_COUNT*8-1:0] eth_rx_pfc_req; +wire [PORT_COUNT*8-1:0] eth_rx_pfc_ack; wire [PORT_COUNT-1:0] port_xgmii_tx_clk; wire [PORT_COUNT-1:0] port_xgmii_tx_rst; @@ -807,12 +821,15 @@ generate .PTP_PERIOD_FNS(IF_PTP_PERIOD_FNS), .TX_PTP_TS_ENABLE(PTP_TS_ENABLE), .TX_PTP_TS_WIDTH(PTP_TS_WIDTH), + .TX_PTP_TS_CTRL_IN_TUSER(0), .TX_PTP_TAG_ENABLE(PTP_TS_ENABLE), .TX_PTP_TAG_WIDTH(TX_TAG_WIDTH), .RX_PTP_TS_ENABLE(PTP_TS_ENABLE), .RX_PTP_TS_WIDTH(PTP_TS_WIDTH), .TX_USER_WIDTH(AXIS_ETH_TX_USER_WIDTH), - .RX_USER_WIDTH(AXIS_ETH_RX_USER_WIDTH) + .RX_USER_WIDTH(AXIS_ETH_RX_USER_WIDTH), + .PFC_ENABLE(PFC_ENABLE), + .PAUSE_ENABLE(LFC_ENABLE) ) eth_mac_inst ( .tx_clk(port_xgmii_tx_clk[n]), @@ -820,6 +837,9 @@ generate .rx_clk(port_xgmii_rx_clk[n]), .rx_rst(port_xgmii_rx_rst[n]), + /* + * AXI input + */ .tx_axis_tdata(axis_eth_tx_tdata[n*AXIS_ETH_DATA_WIDTH +: AXIS_ETH_DATA_WIDTH]), .tx_axis_tkeep(axis_eth_tx_tkeep[n*AXIS_ETH_KEEP_WIDTH +: AXIS_ETH_KEEP_WIDTH]), .tx_axis_tvalid(axis_eth_tx_tvalid[n +: 1]), @@ -827,30 +847,121 @@ generate .tx_axis_tlast(axis_eth_tx_tlast[n +: 1]), .tx_axis_tuser(axis_eth_tx_tuser[n*AXIS_ETH_TX_USER_WIDTH +: AXIS_ETH_TX_USER_WIDTH]), + /* + * AXI output + */ .rx_axis_tdata(axis_eth_rx_tdata[n*AXIS_ETH_DATA_WIDTH +: AXIS_ETH_DATA_WIDTH]), .rx_axis_tkeep(axis_eth_rx_tkeep[n*AXIS_ETH_KEEP_WIDTH +: AXIS_ETH_KEEP_WIDTH]), .rx_axis_tvalid(axis_eth_rx_tvalid[n +: 1]), .rx_axis_tlast(axis_eth_rx_tlast[n +: 1]), .rx_axis_tuser(axis_eth_rx_tuser[n*AXIS_ETH_RX_USER_WIDTH +: AXIS_ETH_RX_USER_WIDTH]), + /* + * XGMII interface + */ .xgmii_rxd(port_xgmii_rxd[n*XGMII_DATA_WIDTH +: XGMII_DATA_WIDTH]), .xgmii_rxc(port_xgmii_rxc[n*XGMII_CTRL_WIDTH +: XGMII_CTRL_WIDTH]), .xgmii_txd(port_xgmii_txd[n*XGMII_DATA_WIDTH +: XGMII_DATA_WIDTH]), .xgmii_txc(port_xgmii_txc[n*XGMII_CTRL_WIDTH +: XGMII_CTRL_WIDTH]), + /* + * PTP + */ .tx_ptp_ts(eth_tx_ptp_ts_96[n*PTP_TS_WIDTH +: PTP_TS_WIDTH]), .rx_ptp_ts(eth_rx_ptp_ts_96[n*PTP_TS_WIDTH +: PTP_TS_WIDTH]), .tx_axis_ptp_ts(axis_eth_tx_ptp_ts[n*PTP_TS_WIDTH +: PTP_TS_WIDTH]), .tx_axis_ptp_ts_tag(axis_eth_tx_ptp_ts_tag[n*TX_TAG_WIDTH +: TX_TAG_WIDTH]), .tx_axis_ptp_ts_valid(axis_eth_tx_ptp_ts_valid[n +: 1]), + /* + * Link-level Flow Control (LFC) (IEEE 802.3 annex 31B PAUSE) + */ + .tx_lfc_req(eth_tx_lfc_req[n +: 1]), + .tx_lfc_resend(1'b0), + .rx_lfc_en(eth_rx_lfc_en[n +: 1]), + .rx_lfc_req(eth_rx_lfc_req[n +: 1]), + .rx_lfc_ack(eth_rx_lfc_ack[n +: 1]), + + /* + * Priority Flow Control (PFC) (IEEE 802.3 annex 31D PFC) + */ + .tx_pfc_req(eth_tx_pfc_req[n*8 +: 8]), + .tx_pfc_resend(1'b0), + .rx_pfc_en(eth_rx_pfc_en[n*8 +: 8]), + .rx_pfc_req(eth_rx_pfc_req[n*8 +: 8]), + .rx_pfc_ack(eth_rx_pfc_ack[n*8 +: 8]), + + /* + * Pause interface + */ + .tx_lfc_pause_en(1'b1), + .tx_pause_req(1'b0), + .tx_pause_ack(), + + /* + * Status + */ + .tx_start_packet(), .tx_error_underflow(), + .rx_start_packet(), .rx_error_bad_frame(), .rx_error_bad_fcs(), + .stat_tx_mcf(), + .stat_rx_mcf(), + .stat_tx_lfc_pkt(), + .stat_tx_lfc_xon(), + .stat_tx_lfc_xoff(), + .stat_tx_lfc_paused(), + .stat_tx_pfc_pkt(), + .stat_tx_pfc_xon(), + .stat_tx_pfc_xoff(), + .stat_tx_pfc_paused(), + .stat_rx_lfc_pkt(), + .stat_rx_lfc_xon(), + .stat_rx_lfc_xoff(), + .stat_rx_lfc_paused(), + .stat_rx_pfc_pkt(), + .stat_rx_pfc_xon(), + .stat_rx_pfc_xoff(), + .stat_rx_pfc_paused(), + /* + * Configuration + */ .cfg_ifg(8'd12), - .cfg_tx_enable(1'b1), - .cfg_rx_enable(1'b1) + .cfg_tx_enable(eth_tx_enable[n +: 1]), + .cfg_rx_enable(eth_rx_enable[n +: 1]), + .cfg_mcf_rx_eth_dst_mcast(48'h01_80_C2_00_00_01), + .cfg_mcf_rx_check_eth_dst_mcast(1'b1), + .cfg_mcf_rx_eth_dst_ucast(48'd0), + .cfg_mcf_rx_check_eth_dst_ucast(1'b0), + .cfg_mcf_rx_eth_src(48'd0), + .cfg_mcf_rx_check_eth_src(1'b0), + .cfg_mcf_rx_eth_type(16'h8808), + .cfg_mcf_rx_opcode_lfc(16'h0001), + .cfg_mcf_rx_check_opcode_lfc(eth_rx_lfc_en[n +: 1]), + .cfg_mcf_rx_opcode_pfc(16'h0101), + .cfg_mcf_rx_check_opcode_pfc(eth_rx_pfc_en[n*8 +: 8] != 0), + .cfg_mcf_rx_forward(1'b0), + .cfg_mcf_rx_enable(eth_rx_lfc_en[n +: 1] || eth_rx_pfc_en[n*8 +: 8]), + .cfg_tx_lfc_eth_dst(48'h01_80_C2_00_00_01), + .cfg_tx_lfc_eth_src(48'h80_23_31_43_54_4C), + .cfg_tx_lfc_eth_type(16'h8808), + .cfg_tx_lfc_opcode(16'h0001), + .cfg_tx_lfc_en(eth_tx_lfc_en[n +: 1]), + .cfg_tx_lfc_quanta(16'hffff), + .cfg_tx_lfc_refresh(16'h7fff), + .cfg_tx_pfc_eth_dst(48'h01_80_C2_00_00_01), + .cfg_tx_pfc_eth_src(48'h80_23_31_43_54_4C), + .cfg_tx_pfc_eth_type(16'h8808), + .cfg_tx_pfc_opcode(16'h0101), + .cfg_tx_pfc_en(eth_tx_pfc_en[n*8 +: 8] != 0), + .cfg_tx_pfc_quanta({8{16'hffff}}), + .cfg_tx_pfc_refresh({8{16'h7fff}}), + .cfg_rx_lfc_opcode(16'h0001), + .cfg_rx_lfc_en(eth_rx_lfc_en[n +: 1]), + .cfg_rx_pfc_opcode(16'h0101), + .cfg_rx_pfc_en(eth_rx_pfc_en[n*8 +: 8] != 0) ); end @@ -924,6 +1035,9 @@ mqnic_core_pcie_us #( .TX_CHECKSUM_ENABLE(TX_CHECKSUM_ENABLE), .RX_HASH_ENABLE(RX_HASH_ENABLE), .RX_CHECKSUM_ENABLE(RX_CHECKSUM_ENABLE), + .PFC_ENABLE(PFC_ENABLE), + .LFC_ENABLE(LFC_ENABLE), + .MAC_CTRL_ENABLE(0), .TX_FIFO_DEPTH(TX_FIFO_DEPTH), .RX_FIFO_DEPTH(RX_FIFO_DEPTH), .MAX_TX_SIZE(MAX_TX_SIZE), @@ -1190,7 +1304,13 @@ core_inst ( .s_axis_eth_tx_cpl_valid(axis_eth_tx_ptp_ts_valid), .s_axis_eth_tx_cpl_ready(axis_eth_tx_ptp_ts_ready), + .eth_tx_enable(eth_tx_enable), .eth_tx_status(eth_tx_status), + .eth_tx_lfc_en(eth_tx_lfc_en), + .eth_tx_lfc_req(eth_tx_lfc_req), + .eth_tx_pfc_en(eth_tx_pfc_en), + .eth_tx_pfc_req(eth_tx_pfc_req), + .eth_tx_fc_quanta_clk_en(0), .eth_rx_clk(eth_rx_clk), .eth_rx_rst(eth_rx_rst), @@ -1207,7 +1327,15 @@ core_inst ( .s_axis_eth_rx_tlast(axis_eth_rx_tlast), .s_axis_eth_rx_tuser(axis_eth_rx_tuser), + .eth_rx_enable(eth_rx_enable), .eth_rx_status(eth_rx_status), + .eth_rx_lfc_en(eth_rx_lfc_en), + .eth_rx_lfc_req(eth_rx_lfc_req), + .eth_rx_lfc_ack(eth_rx_lfc_ack), + .eth_rx_pfc_en(eth_rx_pfc_en), + .eth_rx_pfc_req(eth_rx_pfc_req), + .eth_rx_pfc_ack(eth_rx_pfc_ack), + .eth_rx_fc_quanta_clk_en(0), /* * DDR diff --git a/fpga/mqnic/Nexus_K35_S/fpga/tb/fpga_core/Makefile b/fpga/mqnic/Nexus_K35_S/fpga/tb/fpga_core/Makefile index 264ffbe23..2d6b6da10 100644 --- a/fpga/mqnic/Nexus_K35_S/fpga/tb/fpga_core/Makefile +++ b/fpga/mqnic/Nexus_K35_S/fpga/tb/fpga_core/Makefile @@ -62,6 +62,10 @@ VERILOG_SOURCES += ../../rtl/common/i2c_single_reg.v VERILOG_SOURCES += ../../lib/eth/rtl/eth_mac_10g.v VERILOG_SOURCES += ../../lib/eth/rtl/axis_xgmii_rx_64.v VERILOG_SOURCES += ../../lib/eth/rtl/axis_xgmii_tx_64.v +VERILOG_SOURCES += ../../lib/eth/rtl/mac_ctrl_rx.v +VERILOG_SOURCES += ../../lib/eth/rtl/mac_ctrl_tx.v +VERILOG_SOURCES += ../../lib/eth/rtl/mac_pause_ctrl_rx.v +VERILOG_SOURCES += ../../lib/eth/rtl/mac_pause_ctrl_tx.v VERILOG_SOURCES += ../../lib/eth/rtl/lfsr.v VERILOG_SOURCES += ../../lib/eth/rtl/ptp_clock.v VERILOG_SOURCES += ../../lib/eth/rtl/ptp_clock_cdc.v @@ -167,6 +171,8 @@ export PARAM_TX_CPL_FIFO_DEPTH := 32 export PARAM_TX_CHECKSUM_ENABLE := 1 export PARAM_RX_HASH_ENABLE := 1 export PARAM_RX_CHECKSUM_ENABLE := 1 +export PARAM_LFC_ENABLE := 1 +export PARAM_PFC_ENABLE := $(PARAM_LFC_ENABLE) export PARAM_TX_FIFO_DEPTH := 32768 export PARAM_RX_FIFO_DEPTH := 32768 export PARAM_MAX_TX_SIZE := 9214 diff --git a/fpga/mqnic/Nexus_K35_S/fpga/tb/fpga_core/test_fpga_core.py b/fpga/mqnic/Nexus_K35_S/fpga/tb/fpga_core/test_fpga_core.py index 4699d2e5e..7bbacdf3b 100644 --- a/fpga/mqnic/Nexus_K35_S/fpga/tb/fpga_core/test_fpga_core.py +++ b/fpga/mqnic/Nexus_K35_S/fpga/tb/fpga_core/test_fpga_core.py @@ -3,6 +3,7 @@ import logging import os +import struct import sys import scapy.utils @@ -17,7 +18,7 @@ from cocotb.clock import Clock from cocotb.triggers import RisingEdge, FallingEdge, Timer from cocotbext.axi import AxiStreamBus -from cocotbext.eth import XgmiiSource, XgmiiSink +from cocotbext.eth import XgmiiSource, XgmiiSink, XgmiiFrame from cocotbext.pcie.core import RootComplex from cocotbext.pcie.xilinx.us import UltraScalePcieDevice @@ -261,7 +262,7 @@ class TB(object): sink = XgmiiSink(getattr(dut, f"sfp_{k}_txd"), getattr(dut, f"sfp_{k}_txc"), getattr(dut, f"sfp_{k}_tx_clk"), getattr(dut, f"sfp_{k}_tx_rst")) self.sfp_sink.append(sink) getattr(dut, f"sfp_{k}_rx_status").setimmediatevalue(1) - getattr(dut, f"sfp_{k}_npres").setimmediatevalue(1) + getattr(dut, f"sfp_{k}_npres").setimmediatevalue(0) getattr(dut, f"sfp_{k}_los").setimmediatevalue(1) cocotb.start_soon(Clock(dut.sfp_drp_clk, 8, units="ns").start()) @@ -493,6 +494,35 @@ async def run_test_nic(dut): tb.loopback_enable = False + if tb.driver.interfaces[0].if_feature_lfc: + tb.log.info("Test LFC pause frame RX") + + await tb.driver.interfaces[0].ports[0].set_lfc_ctrl(mqnic.MQNIC_PORT_LFC_CTRL_TX_LFC_EN | mqnic.MQNIC_PORT_LFC_CTRL_RX_LFC_EN) + await tb.driver.hw_regs.read_dword(0) + + lfc_xoff = Ether(src='DA:D1:D2:D3:D4:D5', dst='01:80:C2:00:00:01', type=0x8808) / struct.pack('!HH', 0x0001, 2000) + + await tb.sfp_source[0].send(XgmiiFrame.from_payload(bytes(lfc_xoff))) + + count = 16 + + pkts = [bytearray([(x+k) % 256 for x in range(1514)]) for k in range(count)] + + tb.loopback_enable = True + + for p in pkts: + await tb.driver.interfaces[0].start_xmit(p, 0) + + for k in range(count): + pkt = await tb.driver.interfaces[0].recv() + + tb.log.info("Packet: %s", pkt) + assert pkt.data == pkts[k] + if tb.driver.interfaces[0].if_feature_rx_csum: + assert pkt.rx_checksum == ~scapy.utils.checksum(bytes(pkt.data[14:])) & 0xffff + + tb.loopback_enable = False + await RisingEdge(dut.clk_250mhz) await RisingEdge(dut.clk_250mhz) @@ -565,6 +595,10 @@ def test_fpga_core(request): os.path.join(eth_rtl_dir, "eth_mac_10g.v"), os.path.join(eth_rtl_dir, "axis_xgmii_rx_64.v"), os.path.join(eth_rtl_dir, "axis_xgmii_tx_64.v"), + os.path.join(eth_rtl_dir, "mac_ctrl_rx.v"), + os.path.join(eth_rtl_dir, "mac_ctrl_tx.v"), + os.path.join(eth_rtl_dir, "mac_pause_ctrl_rx.v"), + os.path.join(eth_rtl_dir, "mac_pause_ctrl_tx.v"), os.path.join(eth_rtl_dir, "lfsr.v"), os.path.join(eth_rtl_dir, "ptp_clock.v"), os.path.join(eth_rtl_dir, "ptp_clock_cdc.v"), @@ -671,6 +705,8 @@ def test_fpga_core(request): parameters['TX_CHECKSUM_ENABLE'] = 1 parameters['RX_HASH_ENABLE'] = 1 parameters['RX_CHECKSUM_ENABLE'] = 1 + parameters['LFC_ENABLE'] = 1 + parameters['PFC_ENABLE'] = parameters['LFC_ENABLE'] parameters['TX_FIFO_DEPTH'] = 32768 parameters['RX_FIFO_DEPTH'] = 32768 parameters['MAX_TX_SIZE'] = 9214 diff --git a/fpga/mqnic/Nexus_K3P_Q/fpga_25g/fpga/Makefile b/fpga/mqnic/Nexus_K3P_Q/fpga_25g/fpga/Makefile index 551b76cb3..031011057 100644 --- a/fpga/mqnic/Nexus_K3P_Q/fpga_25g/fpga/Makefile +++ b/fpga/mqnic/Nexus_K3P_Q/fpga_25g/fpga/Makefile @@ -61,6 +61,10 @@ SYN_FILES += rtl/common/tdma_ber_ch.v SYN_FILES += lib/eth/rtl/eth_mac_10g.v SYN_FILES += lib/eth/rtl/axis_xgmii_rx_64.v SYN_FILES += lib/eth/rtl/axis_xgmii_tx_64.v +SYN_FILES += lib/eth/rtl/mac_ctrl_rx.v +SYN_FILES += lib/eth/rtl/mac_ctrl_tx.v +SYN_FILES += lib/eth/rtl/mac_pause_ctrl_rx.v +SYN_FILES += lib/eth/rtl/mac_pause_ctrl_tx.v SYN_FILES += lib/eth/rtl/eth_phy_10g.v SYN_FILES += lib/eth/rtl/eth_phy_10g_rx.v SYN_FILES += lib/eth/rtl/eth_phy_10g_rx_if.v diff --git a/fpga/mqnic/Nexus_K3P_Q/fpga_25g/fpga/config.tcl b/fpga/mqnic/Nexus_K3P_Q/fpga_25g/fpga/config.tcl index 17a69ea0c..24a5c9312 100644 --- a/fpga/mqnic/Nexus_K3P_Q/fpga_25g/fpga/config.tcl +++ b/fpga/mqnic/Nexus_K3P_Q/fpga_25g/fpga/config.tcl @@ -113,6 +113,8 @@ dict set params TX_CPL_FIFO_DEPTH "32" dict set params TX_CHECKSUM_ENABLE "1" dict set params RX_HASH_ENABLE "1" dict set params RX_CHECKSUM_ENABLE "1" +dict set params PFC_ENABLE "1" +dict set params LFC_ENABLE [dict get $params PFC_ENABLE] dict set params ENABLE_PADDING "1" dict set params ENABLE_DIC "1" dict set params MIN_FRAME_LENGTH "64" diff --git a/fpga/mqnic/Nexus_K3P_Q/fpga_25g/fpga_10g/Makefile b/fpga/mqnic/Nexus_K3P_Q/fpga_25g/fpga_10g/Makefile index 551b76cb3..031011057 100644 --- a/fpga/mqnic/Nexus_K3P_Q/fpga_25g/fpga_10g/Makefile +++ b/fpga/mqnic/Nexus_K3P_Q/fpga_25g/fpga_10g/Makefile @@ -61,6 +61,10 @@ SYN_FILES += rtl/common/tdma_ber_ch.v SYN_FILES += lib/eth/rtl/eth_mac_10g.v SYN_FILES += lib/eth/rtl/axis_xgmii_rx_64.v SYN_FILES += lib/eth/rtl/axis_xgmii_tx_64.v +SYN_FILES += lib/eth/rtl/mac_ctrl_rx.v +SYN_FILES += lib/eth/rtl/mac_ctrl_tx.v +SYN_FILES += lib/eth/rtl/mac_pause_ctrl_rx.v +SYN_FILES += lib/eth/rtl/mac_pause_ctrl_tx.v SYN_FILES += lib/eth/rtl/eth_phy_10g.v SYN_FILES += lib/eth/rtl/eth_phy_10g_rx.v SYN_FILES += lib/eth/rtl/eth_phy_10g_rx_if.v diff --git a/fpga/mqnic/Nexus_K3P_Q/fpga_25g/fpga_10g/config.tcl b/fpga/mqnic/Nexus_K3P_Q/fpga_25g/fpga_10g/config.tcl index a02419034..83441f116 100644 --- a/fpga/mqnic/Nexus_K3P_Q/fpga_25g/fpga_10g/config.tcl +++ b/fpga/mqnic/Nexus_K3P_Q/fpga_25g/fpga_10g/config.tcl @@ -113,6 +113,8 @@ dict set params TX_CPL_FIFO_DEPTH "32" dict set params TX_CHECKSUM_ENABLE "1" dict set params RX_HASH_ENABLE "1" dict set params RX_CHECKSUM_ENABLE "1" +dict set params PFC_ENABLE "1" +dict set params LFC_ENABLE [dict get $params PFC_ENABLE] dict set params ENABLE_PADDING "1" dict set params ENABLE_DIC "1" dict set params MIN_FRAME_LENGTH "64" diff --git a/fpga/mqnic/Nexus_K3P_Q/fpga_25g/fpga_app_dma_bench/Makefile b/fpga/mqnic/Nexus_K3P_Q/fpga_25g/fpga_app_dma_bench/Makefile index bff08a901..ff04ea793 100644 --- a/fpga/mqnic/Nexus_K3P_Q/fpga_25g/fpga_app_dma_bench/Makefile +++ b/fpga/mqnic/Nexus_K3P_Q/fpga_25g/fpga_app_dma_bench/Makefile @@ -64,6 +64,10 @@ SYN_FILES += app/dma_bench/rtl/dram_test_ch.v SYN_FILES += lib/eth/rtl/eth_mac_10g.v SYN_FILES += lib/eth/rtl/axis_xgmii_rx_64.v SYN_FILES += lib/eth/rtl/axis_xgmii_tx_64.v +SYN_FILES += lib/eth/rtl/mac_ctrl_rx.v +SYN_FILES += lib/eth/rtl/mac_ctrl_tx.v +SYN_FILES += lib/eth/rtl/mac_pause_ctrl_rx.v +SYN_FILES += lib/eth/rtl/mac_pause_ctrl_tx.v SYN_FILES += lib/eth/rtl/eth_phy_10g.v SYN_FILES += lib/eth/rtl/eth_phy_10g_rx.v SYN_FILES += lib/eth/rtl/eth_phy_10g_rx_if.v diff --git a/fpga/mqnic/Nexus_K3P_Q/fpga_25g/fpga_app_dma_bench/config.tcl b/fpga/mqnic/Nexus_K3P_Q/fpga_25g/fpga_app_dma_bench/config.tcl index 33f7716ed..da093654a 100644 --- a/fpga/mqnic/Nexus_K3P_Q/fpga_25g/fpga_app_dma_bench/config.tcl +++ b/fpga/mqnic/Nexus_K3P_Q/fpga_25g/fpga_app_dma_bench/config.tcl @@ -113,6 +113,8 @@ dict set params TX_CPL_FIFO_DEPTH "32" dict set params TX_CHECKSUM_ENABLE "1" dict set params RX_HASH_ENABLE "1" dict set params RX_CHECKSUM_ENABLE "1" +dict set params PFC_ENABLE "1" +dict set params LFC_ENABLE [dict get $params PFC_ENABLE] dict set params ENABLE_PADDING "1" dict set params ENABLE_DIC "1" dict set params MIN_FRAME_LENGTH "64" diff --git a/fpga/mqnic/Nexus_K3P_Q/fpga_25g/rtl/fpga.v b/fpga/mqnic/Nexus_K3P_Q/fpga_25g/rtl/fpga.v index 4980471aa..e8b8b559b 100644 --- a/fpga/mqnic/Nexus_K3P_Q/fpga_25g/rtl/fpga.v +++ b/fpga/mqnic/Nexus_K3P_Q/fpga_25g/rtl/fpga.v @@ -74,6 +74,8 @@ module fpga # parameter TX_CHECKSUM_ENABLE = 1, parameter RX_HASH_ENABLE = 1, parameter RX_CHECKSUM_ENABLE = 1, + parameter PFC_ENABLE = 1, + parameter LFC_ENABLE = PFC_ENABLE, parameter ENABLE_PADDING = 1, parameter ENABLE_DIC = 1, parameter MIN_FRAME_LENGTH = 64, @@ -1599,6 +1601,8 @@ fpga_core #( .TX_CHECKSUM_ENABLE(TX_CHECKSUM_ENABLE), .RX_HASH_ENABLE(RX_HASH_ENABLE), .RX_CHECKSUM_ENABLE(RX_CHECKSUM_ENABLE), + .PFC_ENABLE(PFC_ENABLE), + .LFC_ENABLE(LFC_ENABLE), .ENABLE_PADDING(ENABLE_PADDING), .ENABLE_DIC(ENABLE_DIC), .MIN_FRAME_LENGTH(MIN_FRAME_LENGTH), diff --git a/fpga/mqnic/Nexus_K3P_Q/fpga_25g/rtl/fpga_core.v b/fpga/mqnic/Nexus_K3P_Q/fpga_25g/rtl/fpga_core.v index 22b0adc41..fc53b259d 100644 --- a/fpga/mqnic/Nexus_K3P_Q/fpga_25g/rtl/fpga_core.v +++ b/fpga/mqnic/Nexus_K3P_Q/fpga_25g/rtl/fpga_core.v @@ -81,6 +81,8 @@ module fpga_core # parameter TX_CHECKSUM_ENABLE = 1, parameter RX_HASH_ENABLE = 1, parameter RX_CHECKSUM_ENABLE = 1, + parameter PFC_ENABLE = 1, + parameter LFC_ENABLE = PFC_ENABLE, parameter ENABLE_PADDING = 1, parameter ENABLE_DIC = 1, parameter MIN_FRAME_LENGTH = 64, @@ -1033,7 +1035,12 @@ wire [PORT_COUNT*TX_TAG_WIDTH-1:0] axis_eth_tx_ptp_ts_tag; wire [PORT_COUNT-1:0] axis_eth_tx_ptp_ts_valid; wire [PORT_COUNT-1:0] axis_eth_tx_ptp_ts_ready; +wire [PORT_COUNT-1:0] eth_tx_enable; wire [PORT_COUNT-1:0] eth_tx_status; +wire [PORT_COUNT-1:0] eth_tx_lfc_en; +wire [PORT_COUNT-1:0] eth_tx_lfc_req; +wire [PORT_COUNT*8-1:0] eth_tx_pfc_en; +wire [PORT_COUNT*8-1:0] eth_tx_pfc_req; wire [PORT_COUNT-1:0] eth_rx_clk; wire [PORT_COUNT-1:0] eth_rx_rst; @@ -1048,7 +1055,14 @@ wire [PORT_COUNT-1:0] axis_eth_rx_tready; wire [PORT_COUNT-1:0] axis_eth_rx_tlast; wire [PORT_COUNT*AXIS_ETH_RX_USER_WIDTH-1:0] axis_eth_rx_tuser; +wire [PORT_COUNT-1:0] eth_rx_enable; wire [PORT_COUNT-1:0] eth_rx_status; +wire [PORT_COUNT-1:0] eth_rx_lfc_en; +wire [PORT_COUNT-1:0] eth_rx_lfc_req; +wire [PORT_COUNT-1:0] eth_rx_lfc_ack; +wire [PORT_COUNT*8-1:0] eth_rx_pfc_en; +wire [PORT_COUNT*8-1:0] eth_rx_pfc_req; +wire [PORT_COUNT*8-1:0] eth_rx_pfc_ack; wire [PORT_COUNT-1:0] port_xgmii_tx_clk; wire [PORT_COUNT-1:0] port_xgmii_tx_rst; @@ -1121,12 +1135,15 @@ generate .PTP_PERIOD_FNS(IF_PTP_PERIOD_FNS), .TX_PTP_TS_ENABLE(PTP_TS_ENABLE), .TX_PTP_TS_WIDTH(PTP_TS_WIDTH), + .TX_PTP_TS_CTRL_IN_TUSER(0), .TX_PTP_TAG_ENABLE(PTP_TS_ENABLE), .TX_PTP_TAG_WIDTH(TX_TAG_WIDTH), .RX_PTP_TS_ENABLE(PTP_TS_ENABLE), .RX_PTP_TS_WIDTH(PTP_TS_WIDTH), .TX_USER_WIDTH(AXIS_ETH_TX_USER_WIDTH), - .RX_USER_WIDTH(AXIS_ETH_RX_USER_WIDTH) + .RX_USER_WIDTH(AXIS_ETH_RX_USER_WIDTH), + .PFC_ENABLE(PFC_ENABLE), + .PAUSE_ENABLE(LFC_ENABLE) ) eth_mac_inst ( .tx_clk(port_xgmii_tx_clk[n]), @@ -1134,6 +1151,9 @@ generate .rx_clk(port_xgmii_rx_clk[n]), .rx_rst(port_xgmii_rx_rst[n]), + /* + * AXI input + */ .tx_axis_tdata(axis_eth_tx_tdata[n*AXIS_ETH_DATA_WIDTH +: AXIS_ETH_DATA_WIDTH]), .tx_axis_tkeep(axis_eth_tx_tkeep[n*AXIS_ETH_KEEP_WIDTH +: AXIS_ETH_KEEP_WIDTH]), .tx_axis_tvalid(axis_eth_tx_tvalid[n +: 1]), @@ -1141,30 +1161,121 @@ generate .tx_axis_tlast(axis_eth_tx_tlast[n +: 1]), .tx_axis_tuser(axis_eth_tx_tuser[n*AXIS_ETH_TX_USER_WIDTH +: AXIS_ETH_TX_USER_WIDTH]), + /* + * AXI output + */ .rx_axis_tdata(axis_eth_rx_tdata[n*AXIS_ETH_DATA_WIDTH +: AXIS_ETH_DATA_WIDTH]), .rx_axis_tkeep(axis_eth_rx_tkeep[n*AXIS_ETH_KEEP_WIDTH +: AXIS_ETH_KEEP_WIDTH]), .rx_axis_tvalid(axis_eth_rx_tvalid[n +: 1]), .rx_axis_tlast(axis_eth_rx_tlast[n +: 1]), .rx_axis_tuser(axis_eth_rx_tuser[n*AXIS_ETH_RX_USER_WIDTH +: AXIS_ETH_RX_USER_WIDTH]), + /* + * XGMII interface + */ .xgmii_rxd(port_xgmii_rxd[n*XGMII_DATA_WIDTH +: XGMII_DATA_WIDTH]), .xgmii_rxc(port_xgmii_rxc[n*XGMII_CTRL_WIDTH +: XGMII_CTRL_WIDTH]), .xgmii_txd(port_xgmii_txd[n*XGMII_DATA_WIDTH +: XGMII_DATA_WIDTH]), .xgmii_txc(port_xgmii_txc[n*XGMII_CTRL_WIDTH +: XGMII_CTRL_WIDTH]), + /* + * PTP + */ .tx_ptp_ts(eth_tx_ptp_ts_96[n*PTP_TS_WIDTH +: PTP_TS_WIDTH]), .rx_ptp_ts(eth_rx_ptp_ts_96[n*PTP_TS_WIDTH +: PTP_TS_WIDTH]), .tx_axis_ptp_ts(axis_eth_tx_ptp_ts[n*PTP_TS_WIDTH +: PTP_TS_WIDTH]), .tx_axis_ptp_ts_tag(axis_eth_tx_ptp_ts_tag[n*TX_TAG_WIDTH +: TX_TAG_WIDTH]), .tx_axis_ptp_ts_valid(axis_eth_tx_ptp_ts_valid[n +: 1]), + /* + * Link-level Flow Control (LFC) (IEEE 802.3 annex 31B PAUSE) + */ + .tx_lfc_req(eth_tx_lfc_req[n +: 1]), + .tx_lfc_resend(1'b0), + .rx_lfc_en(eth_rx_lfc_en[n +: 1]), + .rx_lfc_req(eth_rx_lfc_req[n +: 1]), + .rx_lfc_ack(eth_rx_lfc_ack[n +: 1]), + + /* + * Priority Flow Control (PFC) (IEEE 802.3 annex 31D PFC) + */ + .tx_pfc_req(eth_tx_pfc_req[n*8 +: 8]), + .tx_pfc_resend(1'b0), + .rx_pfc_en(eth_rx_pfc_en[n*8 +: 8]), + .rx_pfc_req(eth_rx_pfc_req[n*8 +: 8]), + .rx_pfc_ack(eth_rx_pfc_ack[n*8 +: 8]), + + /* + * Pause interface + */ + .tx_lfc_pause_en(1'b1), + .tx_pause_req(1'b0), + .tx_pause_ack(), + + /* + * Status + */ + .tx_start_packet(), .tx_error_underflow(), + .rx_start_packet(), .rx_error_bad_frame(), .rx_error_bad_fcs(), + .stat_tx_mcf(), + .stat_rx_mcf(), + .stat_tx_lfc_pkt(), + .stat_tx_lfc_xon(), + .stat_tx_lfc_xoff(), + .stat_tx_lfc_paused(), + .stat_tx_pfc_pkt(), + .stat_tx_pfc_xon(), + .stat_tx_pfc_xoff(), + .stat_tx_pfc_paused(), + .stat_rx_lfc_pkt(), + .stat_rx_lfc_xon(), + .stat_rx_lfc_xoff(), + .stat_rx_lfc_paused(), + .stat_rx_pfc_pkt(), + .stat_rx_pfc_xon(), + .stat_rx_pfc_xoff(), + .stat_rx_pfc_paused(), + /* + * Configuration + */ .cfg_ifg(8'd12), - .cfg_tx_enable(1'b1), - .cfg_rx_enable(1'b1) + .cfg_tx_enable(eth_tx_enable[n +: 1]), + .cfg_rx_enable(eth_rx_enable[n +: 1]), + .cfg_mcf_rx_eth_dst_mcast(48'h01_80_C2_00_00_01), + .cfg_mcf_rx_check_eth_dst_mcast(1'b1), + .cfg_mcf_rx_eth_dst_ucast(48'd0), + .cfg_mcf_rx_check_eth_dst_ucast(1'b0), + .cfg_mcf_rx_eth_src(48'd0), + .cfg_mcf_rx_check_eth_src(1'b0), + .cfg_mcf_rx_eth_type(16'h8808), + .cfg_mcf_rx_opcode_lfc(16'h0001), + .cfg_mcf_rx_check_opcode_lfc(eth_rx_lfc_en[n +: 1]), + .cfg_mcf_rx_opcode_pfc(16'h0101), + .cfg_mcf_rx_check_opcode_pfc(eth_rx_pfc_en[n*8 +: 8] != 0), + .cfg_mcf_rx_forward(1'b0), + .cfg_mcf_rx_enable(eth_rx_lfc_en[n +: 1] || eth_rx_pfc_en[n*8 +: 8]), + .cfg_tx_lfc_eth_dst(48'h01_80_C2_00_00_01), + .cfg_tx_lfc_eth_src(48'h80_23_31_43_54_4C), + .cfg_tx_lfc_eth_type(16'h8808), + .cfg_tx_lfc_opcode(16'h0001), + .cfg_tx_lfc_en(eth_tx_lfc_en[n +: 1]), + .cfg_tx_lfc_quanta(16'hffff), + .cfg_tx_lfc_refresh(16'h7fff), + .cfg_tx_pfc_eth_dst(48'h01_80_C2_00_00_01), + .cfg_tx_pfc_eth_src(48'h80_23_31_43_54_4C), + .cfg_tx_pfc_eth_type(16'h8808), + .cfg_tx_pfc_opcode(16'h0101), + .cfg_tx_pfc_en(eth_tx_pfc_en[n*8 +: 8] != 0), + .cfg_tx_pfc_quanta({8{16'hffff}}), + .cfg_tx_pfc_refresh({8{16'h7fff}}), + .cfg_rx_lfc_opcode(16'h0001), + .cfg_rx_lfc_en(eth_rx_lfc_en[n +: 1]), + .cfg_rx_pfc_opcode(16'h0101), + .cfg_rx_pfc_en(eth_rx_pfc_en[n*8 +: 8] != 0) ); end @@ -1238,6 +1349,9 @@ mqnic_core_pcie_us #( .TX_CHECKSUM_ENABLE(TX_CHECKSUM_ENABLE), .RX_HASH_ENABLE(RX_HASH_ENABLE), .RX_CHECKSUM_ENABLE(RX_CHECKSUM_ENABLE), + .PFC_ENABLE(PFC_ENABLE), + .LFC_ENABLE(LFC_ENABLE), + .MAC_CTRL_ENABLE(0), .TX_FIFO_DEPTH(TX_FIFO_DEPTH), .RX_FIFO_DEPTH(RX_FIFO_DEPTH), .MAX_TX_SIZE(MAX_TX_SIZE), @@ -1519,7 +1633,13 @@ core_inst ( .s_axis_eth_tx_cpl_valid(axis_eth_tx_ptp_ts_valid), .s_axis_eth_tx_cpl_ready(axis_eth_tx_ptp_ts_ready), + .eth_tx_enable(eth_tx_enable), .eth_tx_status(eth_tx_status), + .eth_tx_lfc_en(eth_tx_lfc_en), + .eth_tx_lfc_req(eth_tx_lfc_req), + .eth_tx_pfc_en(eth_tx_pfc_en), + .eth_tx_pfc_req(eth_tx_pfc_req), + .eth_tx_fc_quanta_clk_en(0), .eth_rx_clk(eth_rx_clk), .eth_rx_rst(eth_rx_rst), @@ -1536,7 +1656,15 @@ core_inst ( .s_axis_eth_rx_tlast(axis_eth_rx_tlast), .s_axis_eth_rx_tuser(axis_eth_rx_tuser), + .eth_rx_enable(eth_rx_enable), .eth_rx_status(eth_rx_status), + .eth_rx_lfc_en(eth_rx_lfc_en), + .eth_rx_lfc_req(eth_rx_lfc_req), + .eth_rx_lfc_ack(eth_rx_lfc_ack), + .eth_rx_pfc_en(eth_rx_pfc_en), + .eth_rx_pfc_req(eth_rx_pfc_req), + .eth_rx_pfc_ack(eth_rx_pfc_ack), + .eth_rx_fc_quanta_clk_en(0), /* * DDR diff --git a/fpga/mqnic/Nexus_K3P_Q/fpga_25g/tb/fpga_core/Makefile b/fpga/mqnic/Nexus_K3P_Q/fpga_25g/tb/fpga_core/Makefile index db060a8f8..ad0525a2f 100644 --- a/fpga/mqnic/Nexus_K3P_Q/fpga_25g/tb/fpga_core/Makefile +++ b/fpga/mqnic/Nexus_K3P_Q/fpga_25g/tb/fpga_core/Makefile @@ -62,6 +62,10 @@ VERILOG_SOURCES += ../../rtl/common/tdma_ber_ch.v VERILOG_SOURCES += ../../lib/eth/rtl/eth_mac_10g.v VERILOG_SOURCES += ../../lib/eth/rtl/axis_xgmii_rx_64.v VERILOG_SOURCES += ../../lib/eth/rtl/axis_xgmii_tx_64.v +VERILOG_SOURCES += ../../lib/eth/rtl/mac_ctrl_rx.v +VERILOG_SOURCES += ../../lib/eth/rtl/mac_ctrl_tx.v +VERILOG_SOURCES += ../../lib/eth/rtl/mac_pause_ctrl_rx.v +VERILOG_SOURCES += ../../lib/eth/rtl/mac_pause_ctrl_tx.v VERILOG_SOURCES += ../../lib/eth/rtl/lfsr.v VERILOG_SOURCES += ../../lib/eth/rtl/ptp_clock.v VERILOG_SOURCES += ../../lib/eth/rtl/ptp_clock_cdc.v @@ -167,6 +171,8 @@ export PARAM_TX_CPL_FIFO_DEPTH := 32 export PARAM_TX_CHECKSUM_ENABLE := 1 export PARAM_RX_HASH_ENABLE := 1 export PARAM_RX_CHECKSUM_ENABLE := 1 +export PARAM_LFC_ENABLE := 1 +export PARAM_PFC_ENABLE := $(PARAM_LFC_ENABLE) export PARAM_TX_FIFO_DEPTH := 32768 export PARAM_RX_FIFO_DEPTH := 32768 export PARAM_MAX_TX_SIZE := 9214 diff --git a/fpga/mqnic/Nexus_K3P_Q/fpga_25g/tb/fpga_core/test_fpga_core.py b/fpga/mqnic/Nexus_K3P_Q/fpga_25g/tb/fpga_core/test_fpga_core.py index 08e6f89c3..6fbf52859 100644 --- a/fpga/mqnic/Nexus_K3P_Q/fpga_25g/tb/fpga_core/test_fpga_core.py +++ b/fpga/mqnic/Nexus_K3P_Q/fpga_25g/tb/fpga_core/test_fpga_core.py @@ -3,6 +3,7 @@ import logging import os +import struct import sys import scapy.utils @@ -17,7 +18,7 @@ from cocotb.clock import Clock from cocotb.triggers import RisingEdge, FallingEdge, Timer from cocotbext.axi import AxiStreamBus -from cocotbext.eth import XgmiiSource, XgmiiSink +from cocotbext.eth import XgmiiSource, XgmiiSink, XgmiiFrame from cocotbext.pcie.core import RootComplex from cocotbext.pcie.xilinx.us import UltraScalePlusPcieDevice @@ -528,6 +529,35 @@ async def run_test_nic(dut): tb.loopback_enable = False + if tb.driver.interfaces[0].if_feature_lfc: + tb.log.info("Test LFC pause frame RX") + + await tb.driver.interfaces[0].ports[0].set_lfc_ctrl(mqnic.MQNIC_PORT_LFC_CTRL_TX_LFC_EN | mqnic.MQNIC_PORT_LFC_CTRL_RX_LFC_EN) + await tb.driver.hw_regs.read_dword(0) + + lfc_xoff = Ether(src='DA:D1:D2:D3:D4:D5', dst='01:80:C2:00:00:01', type=0x8808) / struct.pack('!HH', 0x0001, 2000) + + await tb.qsfp_source[0][0].send(XgmiiFrame.from_payload(bytes(lfc_xoff))) + + count = 16 + + pkts = [bytearray([(x+k) % 256 for x in range(1514)]) for k in range(count)] + + tb.loopback_enable = True + + for p in pkts: + await tb.driver.interfaces[0].start_xmit(p, 0) + + for k in range(count): + pkt = await tb.driver.interfaces[0].recv() + + tb.log.info("Packet: %s", pkt) + assert pkt.data == pkts[k] + if tb.driver.interfaces[0].if_feature_rx_csum: + assert pkt.rx_checksum == ~scapy.utils.checksum(bytes(pkt.data[14:])) & 0xffff + + tb.loopback_enable = False + await RisingEdge(dut.clk_250mhz) await RisingEdge(dut.clk_250mhz) @@ -600,6 +630,10 @@ def test_fpga_core(request): os.path.join(eth_rtl_dir, "eth_mac_10g.v"), os.path.join(eth_rtl_dir, "axis_xgmii_rx_64.v"), os.path.join(eth_rtl_dir, "axis_xgmii_tx_64.v"), + os.path.join(eth_rtl_dir, "mac_ctrl_rx.v"), + os.path.join(eth_rtl_dir, "mac_ctrl_tx.v"), + os.path.join(eth_rtl_dir, "mac_pause_ctrl_rx.v"), + os.path.join(eth_rtl_dir, "mac_pause_ctrl_tx.v"), os.path.join(eth_rtl_dir, "lfsr.v"), os.path.join(eth_rtl_dir, "ptp_clock.v"), os.path.join(eth_rtl_dir, "ptp_clock_cdc.v"), @@ -706,6 +740,8 @@ def test_fpga_core(request): parameters['TX_CHECKSUM_ENABLE'] = 1 parameters['RX_HASH_ENABLE'] = 1 parameters['RX_CHECKSUM_ENABLE'] = 1 + parameters['LFC_ENABLE'] = 1 + parameters['PFC_ENABLE'] = parameters['LFC_ENABLE'] parameters['TX_FIFO_DEPTH'] = 32768 parameters['RX_FIFO_DEPTH'] = 32768 parameters['MAX_TX_SIZE'] = 9214 diff --git a/fpga/mqnic/Nexus_K3P_S/fpga_25g/fpga/Makefile b/fpga/mqnic/Nexus_K3P_S/fpga_25g/fpga/Makefile index 9c10fb70f..8c64e22e1 100644 --- a/fpga/mqnic/Nexus_K3P_S/fpga_25g/fpga/Makefile +++ b/fpga/mqnic/Nexus_K3P_S/fpga_25g/fpga/Makefile @@ -62,6 +62,10 @@ SYN_FILES += rtl/common/i2c_single_reg.v SYN_FILES += lib/eth/rtl/eth_mac_10g.v SYN_FILES += lib/eth/rtl/axis_xgmii_rx_64.v SYN_FILES += lib/eth/rtl/axis_xgmii_tx_64.v +SYN_FILES += lib/eth/rtl/mac_ctrl_rx.v +SYN_FILES += lib/eth/rtl/mac_ctrl_tx.v +SYN_FILES += lib/eth/rtl/mac_pause_ctrl_rx.v +SYN_FILES += lib/eth/rtl/mac_pause_ctrl_tx.v SYN_FILES += lib/eth/rtl/eth_phy_10g.v SYN_FILES += lib/eth/rtl/eth_phy_10g_rx.v SYN_FILES += lib/eth/rtl/eth_phy_10g_rx_if.v diff --git a/fpga/mqnic/Nexus_K3P_S/fpga_25g/fpga/config.tcl b/fpga/mqnic/Nexus_K3P_S/fpga_25g/fpga/config.tcl index 163107b54..1afa024fd 100644 --- a/fpga/mqnic/Nexus_K3P_S/fpga_25g/fpga/config.tcl +++ b/fpga/mqnic/Nexus_K3P_S/fpga_25g/fpga/config.tcl @@ -113,6 +113,8 @@ dict set params TX_CPL_FIFO_DEPTH "32" dict set params TX_CHECKSUM_ENABLE "1" dict set params RX_HASH_ENABLE "1" dict set params RX_CHECKSUM_ENABLE "1" +dict set params PFC_ENABLE "1" +dict set params LFC_ENABLE [dict get $params PFC_ENABLE] dict set params ENABLE_PADDING "1" dict set params ENABLE_DIC "1" dict set params MIN_FRAME_LENGTH "64" diff --git a/fpga/mqnic/Nexus_K3P_S/fpga_25g/fpga_10g/Makefile b/fpga/mqnic/Nexus_K3P_S/fpga_25g/fpga_10g/Makefile index 9c10fb70f..8c64e22e1 100644 --- a/fpga/mqnic/Nexus_K3P_S/fpga_25g/fpga_10g/Makefile +++ b/fpga/mqnic/Nexus_K3P_S/fpga_25g/fpga_10g/Makefile @@ -62,6 +62,10 @@ SYN_FILES += rtl/common/i2c_single_reg.v SYN_FILES += lib/eth/rtl/eth_mac_10g.v SYN_FILES += lib/eth/rtl/axis_xgmii_rx_64.v SYN_FILES += lib/eth/rtl/axis_xgmii_tx_64.v +SYN_FILES += lib/eth/rtl/mac_ctrl_rx.v +SYN_FILES += lib/eth/rtl/mac_ctrl_tx.v +SYN_FILES += lib/eth/rtl/mac_pause_ctrl_rx.v +SYN_FILES += lib/eth/rtl/mac_pause_ctrl_tx.v SYN_FILES += lib/eth/rtl/eth_phy_10g.v SYN_FILES += lib/eth/rtl/eth_phy_10g_rx.v SYN_FILES += lib/eth/rtl/eth_phy_10g_rx_if.v diff --git a/fpga/mqnic/Nexus_K3P_S/fpga_25g/fpga_10g/config.tcl b/fpga/mqnic/Nexus_K3P_S/fpga_25g/fpga_10g/config.tcl index 716fc242d..c26a1d0a4 100644 --- a/fpga/mqnic/Nexus_K3P_S/fpga_25g/fpga_10g/config.tcl +++ b/fpga/mqnic/Nexus_K3P_S/fpga_25g/fpga_10g/config.tcl @@ -113,6 +113,8 @@ dict set params TX_CPL_FIFO_DEPTH "32" dict set params TX_CHECKSUM_ENABLE "1" dict set params RX_HASH_ENABLE "1" dict set params RX_CHECKSUM_ENABLE "1" +dict set params PFC_ENABLE "1" +dict set params LFC_ENABLE [dict get $params PFC_ENABLE] dict set params ENABLE_PADDING "1" dict set params ENABLE_DIC "1" dict set params MIN_FRAME_LENGTH "64" diff --git a/fpga/mqnic/Nexus_K3P_S/fpga_25g/fpga_app_dma_bench/Makefile b/fpga/mqnic/Nexus_K3P_S/fpga_25g/fpga_app_dma_bench/Makefile index 4b983be68..5f14795cb 100644 --- a/fpga/mqnic/Nexus_K3P_S/fpga_25g/fpga_app_dma_bench/Makefile +++ b/fpga/mqnic/Nexus_K3P_S/fpga_25g/fpga_app_dma_bench/Makefile @@ -64,6 +64,10 @@ SYN_FILES += app/dma_bench/rtl/dma_bench.v SYN_FILES += lib/eth/rtl/eth_mac_10g.v SYN_FILES += lib/eth/rtl/axis_xgmii_rx_64.v SYN_FILES += lib/eth/rtl/axis_xgmii_tx_64.v +SYN_FILES += lib/eth/rtl/mac_ctrl_rx.v +SYN_FILES += lib/eth/rtl/mac_ctrl_tx.v +SYN_FILES += lib/eth/rtl/mac_pause_ctrl_rx.v +SYN_FILES += lib/eth/rtl/mac_pause_ctrl_tx.v SYN_FILES += lib/eth/rtl/eth_phy_10g.v SYN_FILES += lib/eth/rtl/eth_phy_10g_rx.v SYN_FILES += lib/eth/rtl/eth_phy_10g_rx_if.v diff --git a/fpga/mqnic/Nexus_K3P_S/fpga_25g/fpga_app_dma_bench/config.tcl b/fpga/mqnic/Nexus_K3P_S/fpga_25g/fpga_app_dma_bench/config.tcl index 7aa572f91..cde8e02a5 100644 --- a/fpga/mqnic/Nexus_K3P_S/fpga_25g/fpga_app_dma_bench/config.tcl +++ b/fpga/mqnic/Nexus_K3P_S/fpga_25g/fpga_app_dma_bench/config.tcl @@ -113,6 +113,8 @@ dict set params TX_CPL_FIFO_DEPTH "32" dict set params TX_CHECKSUM_ENABLE "1" dict set params RX_HASH_ENABLE "1" dict set params RX_CHECKSUM_ENABLE "1" +dict set params PFC_ENABLE "1" +dict set params LFC_ENABLE [dict get $params PFC_ENABLE] dict set params ENABLE_PADDING "1" dict set params ENABLE_DIC "1" dict set params MIN_FRAME_LENGTH "64" diff --git a/fpga/mqnic/Nexus_K3P_S/fpga_25g/rtl/fpga.v b/fpga/mqnic/Nexus_K3P_S/fpga_25g/rtl/fpga.v index 9cc4ea6ad..3b4dc12cd 100644 --- a/fpga/mqnic/Nexus_K3P_S/fpga_25g/rtl/fpga.v +++ b/fpga/mqnic/Nexus_K3P_S/fpga_25g/rtl/fpga.v @@ -74,6 +74,8 @@ module fpga # parameter TX_CHECKSUM_ENABLE = 1, parameter RX_HASH_ENABLE = 1, parameter RX_CHECKSUM_ENABLE = 1, + parameter PFC_ENABLE = 1, + parameter LFC_ENABLE = PFC_ENABLE, parameter ENABLE_PADDING = 1, parameter ENABLE_DIC = 1, parameter MIN_FRAME_LENGTH = 64, @@ -1175,6 +1177,8 @@ fpga_core #( .TX_CHECKSUM_ENABLE(TX_CHECKSUM_ENABLE), .RX_HASH_ENABLE(RX_HASH_ENABLE), .RX_CHECKSUM_ENABLE(RX_CHECKSUM_ENABLE), + .PFC_ENABLE(PFC_ENABLE), + .LFC_ENABLE(LFC_ENABLE), .ENABLE_PADDING(ENABLE_PADDING), .ENABLE_DIC(ENABLE_DIC), .MIN_FRAME_LENGTH(MIN_FRAME_LENGTH), diff --git a/fpga/mqnic/Nexus_K3P_S/fpga_25g/rtl/fpga_core.v b/fpga/mqnic/Nexus_K3P_S/fpga_25g/rtl/fpga_core.v index ef43cd06f..be1d09fd9 100644 --- a/fpga/mqnic/Nexus_K3P_S/fpga_25g/rtl/fpga_core.v +++ b/fpga/mqnic/Nexus_K3P_S/fpga_25g/rtl/fpga_core.v @@ -81,6 +81,8 @@ module fpga_core # parameter TX_CHECKSUM_ENABLE = 1, parameter RX_HASH_ENABLE = 1, parameter RX_CHECKSUM_ENABLE = 1, + parameter PFC_ENABLE = 1, + parameter LFC_ENABLE = PFC_ENABLE, parameter ENABLE_PADDING = 1, parameter ENABLE_DIC = 1, parameter MIN_FRAME_LENGTH = 64, @@ -817,7 +819,12 @@ wire [PORT_COUNT*TX_TAG_WIDTH-1:0] axis_eth_tx_ptp_ts_tag; wire [PORT_COUNT-1:0] axis_eth_tx_ptp_ts_valid; wire [PORT_COUNT-1:0] axis_eth_tx_ptp_ts_ready; +wire [PORT_COUNT-1:0] eth_tx_enable; wire [PORT_COUNT-1:0] eth_tx_status; +wire [PORT_COUNT-1:0] eth_tx_lfc_en; +wire [PORT_COUNT-1:0] eth_tx_lfc_req; +wire [PORT_COUNT*8-1:0] eth_tx_pfc_en; +wire [PORT_COUNT*8-1:0] eth_tx_pfc_req; wire [PORT_COUNT-1:0] eth_rx_clk; wire [PORT_COUNT-1:0] eth_rx_rst; @@ -832,7 +839,14 @@ wire [PORT_COUNT-1:0] axis_eth_rx_tready; wire [PORT_COUNT-1:0] axis_eth_rx_tlast; wire [PORT_COUNT*AXIS_ETH_RX_USER_WIDTH-1:0] axis_eth_rx_tuser; +wire [PORT_COUNT-1:0] eth_rx_enable; wire [PORT_COUNT-1:0] eth_rx_status; +wire [PORT_COUNT-1:0] eth_rx_lfc_en; +wire [PORT_COUNT-1:0] eth_rx_lfc_req; +wire [PORT_COUNT-1:0] eth_rx_lfc_ack; +wire [PORT_COUNT*8-1:0] eth_rx_pfc_en; +wire [PORT_COUNT*8-1:0] eth_rx_pfc_req; +wire [PORT_COUNT*8-1:0] eth_rx_pfc_ack; wire [PORT_COUNT-1:0] port_xgmii_tx_clk; wire [PORT_COUNT-1:0] port_xgmii_tx_rst; @@ -905,12 +919,15 @@ generate .PTP_PERIOD_FNS(IF_PTP_PERIOD_FNS), .TX_PTP_TS_ENABLE(PTP_TS_ENABLE), .TX_PTP_TS_WIDTH(PTP_TS_WIDTH), + .TX_PTP_TS_CTRL_IN_TUSER(0), .TX_PTP_TAG_ENABLE(PTP_TS_ENABLE), .TX_PTP_TAG_WIDTH(TX_TAG_WIDTH), .RX_PTP_TS_ENABLE(PTP_TS_ENABLE), .RX_PTP_TS_WIDTH(PTP_TS_WIDTH), .TX_USER_WIDTH(AXIS_ETH_TX_USER_WIDTH), - .RX_USER_WIDTH(AXIS_ETH_RX_USER_WIDTH) + .RX_USER_WIDTH(AXIS_ETH_RX_USER_WIDTH), + .PFC_ENABLE(PFC_ENABLE), + .PAUSE_ENABLE(LFC_ENABLE) ) eth_mac_inst ( .tx_clk(port_xgmii_tx_clk[n]), @@ -918,6 +935,9 @@ generate .rx_clk(port_xgmii_rx_clk[n]), .rx_rst(port_xgmii_rx_rst[n]), + /* + * AXI input + */ .tx_axis_tdata(axis_eth_tx_tdata[n*AXIS_ETH_DATA_WIDTH +: AXIS_ETH_DATA_WIDTH]), .tx_axis_tkeep(axis_eth_tx_tkeep[n*AXIS_ETH_KEEP_WIDTH +: AXIS_ETH_KEEP_WIDTH]), .tx_axis_tvalid(axis_eth_tx_tvalid[n +: 1]), @@ -925,30 +945,121 @@ generate .tx_axis_tlast(axis_eth_tx_tlast[n +: 1]), .tx_axis_tuser(axis_eth_tx_tuser[n*AXIS_ETH_TX_USER_WIDTH +: AXIS_ETH_TX_USER_WIDTH]), + /* + * AXI output + */ .rx_axis_tdata(axis_eth_rx_tdata[n*AXIS_ETH_DATA_WIDTH +: AXIS_ETH_DATA_WIDTH]), .rx_axis_tkeep(axis_eth_rx_tkeep[n*AXIS_ETH_KEEP_WIDTH +: AXIS_ETH_KEEP_WIDTH]), .rx_axis_tvalid(axis_eth_rx_tvalid[n +: 1]), .rx_axis_tlast(axis_eth_rx_tlast[n +: 1]), .rx_axis_tuser(axis_eth_rx_tuser[n*AXIS_ETH_RX_USER_WIDTH +: AXIS_ETH_RX_USER_WIDTH]), + /* + * XGMII interface + */ .xgmii_rxd(port_xgmii_rxd[n*XGMII_DATA_WIDTH +: XGMII_DATA_WIDTH]), .xgmii_rxc(port_xgmii_rxc[n*XGMII_CTRL_WIDTH +: XGMII_CTRL_WIDTH]), .xgmii_txd(port_xgmii_txd[n*XGMII_DATA_WIDTH +: XGMII_DATA_WIDTH]), .xgmii_txc(port_xgmii_txc[n*XGMII_CTRL_WIDTH +: XGMII_CTRL_WIDTH]), + /* + * PTP + */ .tx_ptp_ts(eth_tx_ptp_ts_96[n*PTP_TS_WIDTH +: PTP_TS_WIDTH]), .rx_ptp_ts(eth_rx_ptp_ts_96[n*PTP_TS_WIDTH +: PTP_TS_WIDTH]), .tx_axis_ptp_ts(axis_eth_tx_ptp_ts[n*PTP_TS_WIDTH +: PTP_TS_WIDTH]), .tx_axis_ptp_ts_tag(axis_eth_tx_ptp_ts_tag[n*TX_TAG_WIDTH +: TX_TAG_WIDTH]), .tx_axis_ptp_ts_valid(axis_eth_tx_ptp_ts_valid[n +: 1]), + /* + * Link-level Flow Control (LFC) (IEEE 802.3 annex 31B PAUSE) + */ + .tx_lfc_req(eth_tx_lfc_req[n +: 1]), + .tx_lfc_resend(1'b0), + .rx_lfc_en(eth_rx_lfc_en[n +: 1]), + .rx_lfc_req(eth_rx_lfc_req[n +: 1]), + .rx_lfc_ack(eth_rx_lfc_ack[n +: 1]), + + /* + * Priority Flow Control (PFC) (IEEE 802.3 annex 31D PFC) + */ + .tx_pfc_req(eth_tx_pfc_req[n*8 +: 8]), + .tx_pfc_resend(1'b0), + .rx_pfc_en(eth_rx_pfc_en[n*8 +: 8]), + .rx_pfc_req(eth_rx_pfc_req[n*8 +: 8]), + .rx_pfc_ack(eth_rx_pfc_ack[n*8 +: 8]), + + /* + * Pause interface + */ + .tx_lfc_pause_en(1'b1), + .tx_pause_req(1'b0), + .tx_pause_ack(), + + /* + * Status + */ + .tx_start_packet(), .tx_error_underflow(), + .rx_start_packet(), .rx_error_bad_frame(), .rx_error_bad_fcs(), + .stat_tx_mcf(), + .stat_rx_mcf(), + .stat_tx_lfc_pkt(), + .stat_tx_lfc_xon(), + .stat_tx_lfc_xoff(), + .stat_tx_lfc_paused(), + .stat_tx_pfc_pkt(), + .stat_tx_pfc_xon(), + .stat_tx_pfc_xoff(), + .stat_tx_pfc_paused(), + .stat_rx_lfc_pkt(), + .stat_rx_lfc_xon(), + .stat_rx_lfc_xoff(), + .stat_rx_lfc_paused(), + .stat_rx_pfc_pkt(), + .stat_rx_pfc_xon(), + .stat_rx_pfc_xoff(), + .stat_rx_pfc_paused(), + /* + * Configuration + */ .cfg_ifg(8'd12), - .cfg_tx_enable(1'b1), - .cfg_rx_enable(1'b1) + .cfg_tx_enable(eth_tx_enable[n +: 1]), + .cfg_rx_enable(eth_rx_enable[n +: 1]), + .cfg_mcf_rx_eth_dst_mcast(48'h01_80_C2_00_00_01), + .cfg_mcf_rx_check_eth_dst_mcast(1'b1), + .cfg_mcf_rx_eth_dst_ucast(48'd0), + .cfg_mcf_rx_check_eth_dst_ucast(1'b0), + .cfg_mcf_rx_eth_src(48'd0), + .cfg_mcf_rx_check_eth_src(1'b0), + .cfg_mcf_rx_eth_type(16'h8808), + .cfg_mcf_rx_opcode_lfc(16'h0001), + .cfg_mcf_rx_check_opcode_lfc(eth_rx_lfc_en[n +: 1]), + .cfg_mcf_rx_opcode_pfc(16'h0101), + .cfg_mcf_rx_check_opcode_pfc(eth_rx_pfc_en[n*8 +: 8] != 0), + .cfg_mcf_rx_forward(1'b0), + .cfg_mcf_rx_enable(eth_rx_lfc_en[n +: 1] || eth_rx_pfc_en[n*8 +: 8]), + .cfg_tx_lfc_eth_dst(48'h01_80_C2_00_00_01), + .cfg_tx_lfc_eth_src(48'h80_23_31_43_54_4C), + .cfg_tx_lfc_eth_type(16'h8808), + .cfg_tx_lfc_opcode(16'h0001), + .cfg_tx_lfc_en(eth_tx_lfc_en[n +: 1]), + .cfg_tx_lfc_quanta(16'hffff), + .cfg_tx_lfc_refresh(16'h7fff), + .cfg_tx_pfc_eth_dst(48'h01_80_C2_00_00_01), + .cfg_tx_pfc_eth_src(48'h80_23_31_43_54_4C), + .cfg_tx_pfc_eth_type(16'h8808), + .cfg_tx_pfc_opcode(16'h0101), + .cfg_tx_pfc_en(eth_tx_pfc_en[n*8 +: 8] != 0), + .cfg_tx_pfc_quanta({8{16'hffff}}), + .cfg_tx_pfc_refresh({8{16'h7fff}}), + .cfg_rx_lfc_opcode(16'h0001), + .cfg_rx_lfc_en(eth_rx_lfc_en[n +: 1]), + .cfg_rx_pfc_opcode(16'h0101), + .cfg_rx_pfc_en(eth_rx_pfc_en[n*8 +: 8] != 0) ); end @@ -1022,6 +1133,9 @@ mqnic_core_pcie_us #( .TX_CHECKSUM_ENABLE(TX_CHECKSUM_ENABLE), .RX_HASH_ENABLE(RX_HASH_ENABLE), .RX_CHECKSUM_ENABLE(RX_CHECKSUM_ENABLE), + .PFC_ENABLE(PFC_ENABLE), + .LFC_ENABLE(LFC_ENABLE), + .MAC_CTRL_ENABLE(0), .TX_FIFO_DEPTH(TX_FIFO_DEPTH), .RX_FIFO_DEPTH(RX_FIFO_DEPTH), .MAX_TX_SIZE(MAX_TX_SIZE), @@ -1288,7 +1402,13 @@ core_inst ( .s_axis_eth_tx_cpl_valid(axis_eth_tx_ptp_ts_valid), .s_axis_eth_tx_cpl_ready(axis_eth_tx_ptp_ts_ready), + .eth_tx_enable(eth_tx_enable), .eth_tx_status(eth_tx_status), + .eth_tx_lfc_en(eth_tx_lfc_en), + .eth_tx_lfc_req(eth_tx_lfc_req), + .eth_tx_pfc_en(eth_tx_pfc_en), + .eth_tx_pfc_req(eth_tx_pfc_req), + .eth_tx_fc_quanta_clk_en(0), .eth_rx_clk(eth_rx_clk), .eth_rx_rst(eth_rx_rst), @@ -1305,7 +1425,15 @@ core_inst ( .s_axis_eth_rx_tlast(axis_eth_rx_tlast), .s_axis_eth_rx_tuser(axis_eth_rx_tuser), + .eth_rx_enable(eth_rx_enable), .eth_rx_status(eth_rx_status), + .eth_rx_lfc_en(eth_rx_lfc_en), + .eth_rx_lfc_req(eth_rx_lfc_req), + .eth_rx_lfc_ack(eth_rx_lfc_ack), + .eth_rx_pfc_en(eth_rx_pfc_en), + .eth_rx_pfc_req(eth_rx_pfc_req), + .eth_rx_pfc_ack(eth_rx_pfc_ack), + .eth_rx_fc_quanta_clk_en(0), /* * DDR diff --git a/fpga/mqnic/Nexus_K3P_S/fpga_25g/tb/fpga_core/Makefile b/fpga/mqnic/Nexus_K3P_S/fpga_25g/tb/fpga_core/Makefile index 19471b677..ae24adcbe 100644 --- a/fpga/mqnic/Nexus_K3P_S/fpga_25g/tb/fpga_core/Makefile +++ b/fpga/mqnic/Nexus_K3P_S/fpga_25g/tb/fpga_core/Makefile @@ -63,6 +63,10 @@ VERILOG_SOURCES += ../../rtl/common/i2c_single_reg.v VERILOG_SOURCES += ../../lib/eth/rtl/eth_mac_10g.v VERILOG_SOURCES += ../../lib/eth/rtl/axis_xgmii_rx_64.v VERILOG_SOURCES += ../../lib/eth/rtl/axis_xgmii_tx_64.v +VERILOG_SOURCES += ../../lib/eth/rtl/mac_ctrl_rx.v +VERILOG_SOURCES += ../../lib/eth/rtl/mac_ctrl_tx.v +VERILOG_SOURCES += ../../lib/eth/rtl/mac_pause_ctrl_rx.v +VERILOG_SOURCES += ../../lib/eth/rtl/mac_pause_ctrl_tx.v VERILOG_SOURCES += ../../lib/eth/rtl/lfsr.v VERILOG_SOURCES += ../../lib/eth/rtl/ptp_clock.v VERILOG_SOURCES += ../../lib/eth/rtl/ptp_clock_cdc.v @@ -168,6 +172,8 @@ export PARAM_TX_CPL_FIFO_DEPTH := 32 export PARAM_TX_CHECKSUM_ENABLE := 1 export PARAM_RX_HASH_ENABLE := 1 export PARAM_RX_CHECKSUM_ENABLE := 1 +export PARAM_LFC_ENABLE := 1 +export PARAM_PFC_ENABLE := $(PARAM_LFC_ENABLE) export PARAM_TX_FIFO_DEPTH := 32768 export PARAM_RX_FIFO_DEPTH := 32768 export PARAM_MAX_TX_SIZE := 9214 diff --git a/fpga/mqnic/Nexus_K3P_S/fpga_25g/tb/fpga_core/test_fpga_core.py b/fpga/mqnic/Nexus_K3P_S/fpga_25g/tb/fpga_core/test_fpga_core.py index 570cc16d4..8aa8ca4c3 100644 --- a/fpga/mqnic/Nexus_K3P_S/fpga_25g/tb/fpga_core/test_fpga_core.py +++ b/fpga/mqnic/Nexus_K3P_S/fpga_25g/tb/fpga_core/test_fpga_core.py @@ -3,6 +3,7 @@ import logging import os +import struct import sys import scapy.utils @@ -17,7 +18,7 @@ from cocotb.clock import Clock from cocotb.triggers import RisingEdge, FallingEdge, Timer from cocotbext.axi import AxiStreamBus -from cocotbext.eth import XgmiiSource, XgmiiSink +from cocotbext.eth import XgmiiSource, XgmiiSink, XgmiiFrame from cocotbext.pcie.core import RootComplex from cocotbext.pcie.xilinx.us import UltraScalePlusPcieDevice @@ -520,6 +521,35 @@ async def run_test_nic(dut): tb.loopback_enable = False + if tb.driver.interfaces[0].if_feature_lfc: + tb.log.info("Test LFC pause frame RX") + + await tb.driver.interfaces[0].ports[0].set_lfc_ctrl(mqnic.MQNIC_PORT_LFC_CTRL_TX_LFC_EN | mqnic.MQNIC_PORT_LFC_CTRL_RX_LFC_EN) + await tb.driver.hw_regs.read_dword(0) + + lfc_xoff = Ether(src='DA:D1:D2:D3:D4:D5', dst='01:80:C2:00:00:01', type=0x8808) / struct.pack('!HH', 0x0001, 2000) + + await tb.sfp_source[0].send(XgmiiFrame.from_payload(bytes(lfc_xoff))) + + count = 16 + + pkts = [bytearray([(x+k) % 256 for x in range(1514)]) for k in range(count)] + + tb.loopback_enable = True + + for p in pkts: + await tb.driver.interfaces[0].start_xmit(p, 0) + + for k in range(count): + pkt = await tb.driver.interfaces[0].recv() + + tb.log.info("Packet: %s", pkt) + assert pkt.data == pkts[k] + if tb.driver.interfaces[0].if_feature_rx_csum: + assert pkt.rx_checksum == ~scapy.utils.checksum(bytes(pkt.data[14:])) & 0xffff + + tb.loopback_enable = False + await RisingEdge(dut.clk_250mhz) await RisingEdge(dut.clk_250mhz) @@ -593,6 +623,10 @@ def test_fpga_core(request): os.path.join(eth_rtl_dir, "eth_mac_10g.v"), os.path.join(eth_rtl_dir, "axis_xgmii_rx_64.v"), os.path.join(eth_rtl_dir, "axis_xgmii_tx_64.v"), + os.path.join(eth_rtl_dir, "mac_ctrl_rx.v"), + os.path.join(eth_rtl_dir, "mac_ctrl_tx.v"), + os.path.join(eth_rtl_dir, "mac_pause_ctrl_rx.v"), + os.path.join(eth_rtl_dir, "mac_pause_ctrl_tx.v"), os.path.join(eth_rtl_dir, "lfsr.v"), os.path.join(eth_rtl_dir, "ptp_clock.v"), os.path.join(eth_rtl_dir, "ptp_clock_cdc.v"), @@ -699,6 +733,8 @@ def test_fpga_core(request): parameters['TX_CHECKSUM_ENABLE'] = 1 parameters['RX_HASH_ENABLE'] = 1 parameters['RX_CHECKSUM_ENABLE'] = 1 + parameters['LFC_ENABLE'] = 1 + parameters['PFC_ENABLE'] = parameters['LFC_ENABLE'] parameters['TX_FIFO_DEPTH'] = 32768 parameters['RX_FIFO_DEPTH'] = 32768 parameters['MAX_TX_SIZE'] = 9214 diff --git a/fpga/mqnic/VCU108/fpga_25g/fpga/Makefile b/fpga/mqnic/VCU108/fpga_25g/fpga/Makefile index 8811a47af..a0c586685 100644 --- a/fpga/mqnic/VCU108/fpga_25g/fpga/Makefile +++ b/fpga/mqnic/VCU108/fpga_25g/fpga/Makefile @@ -62,6 +62,10 @@ SYN_FILES += rtl/common/tdma_ber_ch.v SYN_FILES += lib/eth/rtl/eth_mac_10g.v SYN_FILES += lib/eth/rtl/axis_xgmii_rx_64.v SYN_FILES += lib/eth/rtl/axis_xgmii_tx_64.v +SYN_FILES += lib/eth/rtl/mac_ctrl_rx.v +SYN_FILES += lib/eth/rtl/mac_ctrl_tx.v +SYN_FILES += lib/eth/rtl/mac_pause_ctrl_rx.v +SYN_FILES += lib/eth/rtl/mac_pause_ctrl_tx.v SYN_FILES += lib/eth/rtl/eth_phy_10g.v SYN_FILES += lib/eth/rtl/eth_phy_10g_rx.v SYN_FILES += lib/eth/rtl/eth_phy_10g_rx_if.v diff --git a/fpga/mqnic/VCU108/fpga_25g/fpga/config.tcl b/fpga/mqnic/VCU108/fpga_25g/fpga/config.tcl index bccffb161..e3ce5ff43 100644 --- a/fpga/mqnic/VCU108/fpga_25g/fpga/config.tcl +++ b/fpga/mqnic/VCU108/fpga_25g/fpga/config.tcl @@ -113,6 +113,8 @@ dict set params TX_CPL_FIFO_DEPTH "32" dict set params TX_CHECKSUM_ENABLE "1" dict set params RX_HASH_ENABLE "1" dict set params RX_CHECKSUM_ENABLE "1" +dict set params PFC_ENABLE "1" +dict set params LFC_ENABLE [dict get $params PFC_ENABLE] dict set params ENABLE_PADDING "1" dict set params ENABLE_DIC "1" dict set params MIN_FRAME_LENGTH "64" diff --git a/fpga/mqnic/VCU108/fpga_25g/fpga_10g/Makefile b/fpga/mqnic/VCU108/fpga_25g/fpga_10g/Makefile index 8811a47af..a0c586685 100644 --- a/fpga/mqnic/VCU108/fpga_25g/fpga_10g/Makefile +++ b/fpga/mqnic/VCU108/fpga_25g/fpga_10g/Makefile @@ -62,6 +62,10 @@ SYN_FILES += rtl/common/tdma_ber_ch.v SYN_FILES += lib/eth/rtl/eth_mac_10g.v SYN_FILES += lib/eth/rtl/axis_xgmii_rx_64.v SYN_FILES += lib/eth/rtl/axis_xgmii_tx_64.v +SYN_FILES += lib/eth/rtl/mac_ctrl_rx.v +SYN_FILES += lib/eth/rtl/mac_ctrl_tx.v +SYN_FILES += lib/eth/rtl/mac_pause_ctrl_rx.v +SYN_FILES += lib/eth/rtl/mac_pause_ctrl_tx.v SYN_FILES += lib/eth/rtl/eth_phy_10g.v SYN_FILES += lib/eth/rtl/eth_phy_10g_rx.v SYN_FILES += lib/eth/rtl/eth_phy_10g_rx_if.v diff --git a/fpga/mqnic/VCU108/fpga_25g/fpga_10g/config.tcl b/fpga/mqnic/VCU108/fpga_25g/fpga_10g/config.tcl index 90e872c76..ce5272675 100644 --- a/fpga/mqnic/VCU108/fpga_25g/fpga_10g/config.tcl +++ b/fpga/mqnic/VCU108/fpga_25g/fpga_10g/config.tcl @@ -113,6 +113,8 @@ dict set params TX_CPL_FIFO_DEPTH "32" dict set params TX_CHECKSUM_ENABLE "1" dict set params RX_HASH_ENABLE "1" dict set params RX_CHECKSUM_ENABLE "1" +dict set params PFC_ENABLE "1" +dict set params LFC_ENABLE [dict get $params PFC_ENABLE] dict set params ENABLE_PADDING "1" dict set params ENABLE_DIC "1" dict set params MIN_FRAME_LENGTH "64" diff --git a/fpga/mqnic/VCU108/fpga_25g/fpga_app_dma_bench/Makefile b/fpga/mqnic/VCU108/fpga_25g/fpga_app_dma_bench/Makefile index 89899ec92..e2953b626 100644 --- a/fpga/mqnic/VCU108/fpga_25g/fpga_app_dma_bench/Makefile +++ b/fpga/mqnic/VCU108/fpga_25g/fpga_app_dma_bench/Makefile @@ -65,6 +65,10 @@ SYN_FILES += app/dma_bench/rtl/dram_test_ch.v SYN_FILES += lib/eth/rtl/eth_mac_10g.v SYN_FILES += lib/eth/rtl/axis_xgmii_rx_64.v SYN_FILES += lib/eth/rtl/axis_xgmii_tx_64.v +SYN_FILES += lib/eth/rtl/mac_ctrl_rx.v +SYN_FILES += lib/eth/rtl/mac_ctrl_tx.v +SYN_FILES += lib/eth/rtl/mac_pause_ctrl_rx.v +SYN_FILES += lib/eth/rtl/mac_pause_ctrl_tx.v SYN_FILES += lib/eth/rtl/eth_phy_10g.v SYN_FILES += lib/eth/rtl/eth_phy_10g_rx.v SYN_FILES += lib/eth/rtl/eth_phy_10g_rx_if.v diff --git a/fpga/mqnic/VCU108/fpga_25g/fpga_app_dma_bench/config.tcl b/fpga/mqnic/VCU108/fpga_25g/fpga_app_dma_bench/config.tcl index 7520c962b..42f780547 100644 --- a/fpga/mqnic/VCU108/fpga_25g/fpga_app_dma_bench/config.tcl +++ b/fpga/mqnic/VCU108/fpga_25g/fpga_app_dma_bench/config.tcl @@ -113,6 +113,8 @@ dict set params TX_CPL_FIFO_DEPTH "32" dict set params TX_CHECKSUM_ENABLE "1" dict set params RX_HASH_ENABLE "1" dict set params RX_CHECKSUM_ENABLE "1" +dict set params PFC_ENABLE "1" +dict set params LFC_ENABLE [dict get $params PFC_ENABLE] dict set params ENABLE_PADDING "1" dict set params ENABLE_DIC "1" dict set params MIN_FRAME_LENGTH "64" diff --git a/fpga/mqnic/VCU108/fpga_25g/rtl/fpga.v b/fpga/mqnic/VCU108/fpga_25g/rtl/fpga.v index 19b022a09..2c95fcae3 100644 --- a/fpga/mqnic/VCU108/fpga_25g/rtl/fpga.v +++ b/fpga/mqnic/VCU108/fpga_25g/rtl/fpga.v @@ -74,6 +74,8 @@ module fpga # parameter TX_CHECKSUM_ENABLE = 1, parameter RX_HASH_ENABLE = 1, parameter RX_CHECKSUM_ENABLE = 1, + parameter LFC_ENABLE = PFC_ENABLE, + parameter PFC_ENABLE = 1, parameter ENABLE_PADDING = 1, parameter ENABLE_DIC = 1, parameter MIN_FRAME_LENGTH = 64, @@ -1522,6 +1524,8 @@ fpga_core #( .TX_CHECKSUM_ENABLE(TX_CHECKSUM_ENABLE), .RX_HASH_ENABLE(RX_HASH_ENABLE), .RX_CHECKSUM_ENABLE(RX_CHECKSUM_ENABLE), + .PFC_ENABLE(PFC_ENABLE), + .LFC_ENABLE(LFC_ENABLE), .ENABLE_PADDING(ENABLE_PADDING), .ENABLE_DIC(ENABLE_DIC), .MIN_FRAME_LENGTH(MIN_FRAME_LENGTH), diff --git a/fpga/mqnic/VCU108/fpga_25g/rtl/fpga_core.v b/fpga/mqnic/VCU108/fpga_25g/rtl/fpga_core.v index 7f50fffd6..5b244fe5b 100644 --- a/fpga/mqnic/VCU108/fpga_25g/rtl/fpga_core.v +++ b/fpga/mqnic/VCU108/fpga_25g/rtl/fpga_core.v @@ -81,6 +81,8 @@ module fpga_core # parameter TX_CHECKSUM_ENABLE = 1, parameter RX_HASH_ENABLE = 1, parameter RX_CHECKSUM_ENABLE = 1, + parameter PFC_ENABLE = 1, + parameter LFC_ENABLE = PFC_ENABLE, parameter ENABLE_PADDING = 1, parameter ENABLE_DIC = 1, parameter MIN_FRAME_LENGTH = 64, @@ -804,7 +806,12 @@ wire [PORT_COUNT*TX_TAG_WIDTH-1:0] axis_eth_tx_ptp_ts_tag; wire [PORT_COUNT-1:0] axis_eth_tx_ptp_ts_valid; wire [PORT_COUNT-1:0] axis_eth_tx_ptp_ts_ready; +wire [PORT_COUNT-1:0] eth_tx_enable; wire [PORT_COUNT-1:0] eth_tx_status; +wire [PORT_COUNT-1:0] eth_tx_lfc_en; +wire [PORT_COUNT-1:0] eth_tx_lfc_req; +wire [PORT_COUNT*8-1:0] eth_tx_pfc_en; +wire [PORT_COUNT*8-1:0] eth_tx_pfc_req; wire [PORT_COUNT-1:0] eth_rx_clk; wire [PORT_COUNT-1:0] eth_rx_rst; @@ -819,7 +826,14 @@ wire [PORT_COUNT-1:0] axis_eth_rx_tready; wire [PORT_COUNT-1:0] axis_eth_rx_tlast; wire [PORT_COUNT*AXIS_ETH_RX_USER_WIDTH-1:0] axis_eth_rx_tuser; +wire [PORT_COUNT-1:0] eth_rx_enable; wire [PORT_COUNT-1:0] eth_rx_status; +wire [PORT_COUNT-1:0] eth_rx_lfc_en; +wire [PORT_COUNT-1:0] eth_rx_lfc_req; +wire [PORT_COUNT-1:0] eth_rx_lfc_ack; +wire [PORT_COUNT*8-1:0] eth_rx_pfc_en; +wire [PORT_COUNT*8-1:0] eth_rx_pfc_req; +wire [PORT_COUNT*8-1:0] eth_rx_pfc_ack; wire [PORT_COUNT-1:0] port_xgmii_tx_clk; wire [PORT_COUNT-1:0] port_xgmii_tx_rst; @@ -892,12 +906,15 @@ generate .PTP_PERIOD_FNS(IF_PTP_PERIOD_FNS), .TX_PTP_TS_ENABLE(PTP_TS_ENABLE), .TX_PTP_TS_WIDTH(PTP_TS_WIDTH), + .TX_PTP_TS_CTRL_IN_TUSER(0), .TX_PTP_TAG_ENABLE(PTP_TS_ENABLE), .TX_PTP_TAG_WIDTH(TX_TAG_WIDTH), .RX_PTP_TS_ENABLE(PTP_TS_ENABLE), .RX_PTP_TS_WIDTH(PTP_TS_WIDTH), .TX_USER_WIDTH(AXIS_ETH_TX_USER_WIDTH), - .RX_USER_WIDTH(AXIS_ETH_RX_USER_WIDTH) + .RX_USER_WIDTH(AXIS_ETH_RX_USER_WIDTH), + .PFC_ENABLE(PFC_ENABLE), + .PAUSE_ENABLE(LFC_ENABLE) ) eth_mac_inst ( .tx_clk(port_xgmii_tx_clk[n]), @@ -905,6 +922,9 @@ generate .rx_clk(port_xgmii_rx_clk[n]), .rx_rst(port_xgmii_rx_rst[n]), + /* + * AXI input + */ .tx_axis_tdata(axis_eth_tx_tdata[n*AXIS_ETH_DATA_WIDTH +: AXIS_ETH_DATA_WIDTH]), .tx_axis_tkeep(axis_eth_tx_tkeep[n*AXIS_ETH_KEEP_WIDTH +: AXIS_ETH_KEEP_WIDTH]), .tx_axis_tvalid(axis_eth_tx_tvalid[n +: 1]), @@ -912,30 +932,121 @@ generate .tx_axis_tlast(axis_eth_tx_tlast[n +: 1]), .tx_axis_tuser(axis_eth_tx_tuser[n*AXIS_ETH_TX_USER_WIDTH +: AXIS_ETH_TX_USER_WIDTH]), + /* + * AXI output + */ .rx_axis_tdata(axis_eth_rx_tdata[n*AXIS_ETH_DATA_WIDTH +: AXIS_ETH_DATA_WIDTH]), .rx_axis_tkeep(axis_eth_rx_tkeep[n*AXIS_ETH_KEEP_WIDTH +: AXIS_ETH_KEEP_WIDTH]), .rx_axis_tvalid(axis_eth_rx_tvalid[n +: 1]), .rx_axis_tlast(axis_eth_rx_tlast[n +: 1]), .rx_axis_tuser(axis_eth_rx_tuser[n*AXIS_ETH_RX_USER_WIDTH +: AXIS_ETH_RX_USER_WIDTH]), + /* + * XGMII interface + */ .xgmii_rxd(port_xgmii_rxd[n*XGMII_DATA_WIDTH +: XGMII_DATA_WIDTH]), .xgmii_rxc(port_xgmii_rxc[n*XGMII_CTRL_WIDTH +: XGMII_CTRL_WIDTH]), .xgmii_txd(port_xgmii_txd[n*XGMII_DATA_WIDTH +: XGMII_DATA_WIDTH]), .xgmii_txc(port_xgmii_txc[n*XGMII_CTRL_WIDTH +: XGMII_CTRL_WIDTH]), + /* + * PTP + */ .tx_ptp_ts(eth_tx_ptp_ts_96[n*PTP_TS_WIDTH +: PTP_TS_WIDTH]), .rx_ptp_ts(eth_rx_ptp_ts_96[n*PTP_TS_WIDTH +: PTP_TS_WIDTH]), .tx_axis_ptp_ts(axis_eth_tx_ptp_ts[n*PTP_TS_WIDTH +: PTP_TS_WIDTH]), .tx_axis_ptp_ts_tag(axis_eth_tx_ptp_ts_tag[n*TX_TAG_WIDTH +: TX_TAG_WIDTH]), .tx_axis_ptp_ts_valid(axis_eth_tx_ptp_ts_valid[n +: 1]), + /* + * Link-level Flow Control (LFC) (IEEE 802.3 annex 31B PAUSE) + */ + .tx_lfc_req(eth_tx_lfc_req[n +: 1]), + .tx_lfc_resend(1'b0), + .rx_lfc_en(eth_rx_lfc_en[n +: 1]), + .rx_lfc_req(eth_rx_lfc_req[n +: 1]), + .rx_lfc_ack(eth_rx_lfc_ack[n +: 1]), + + /* + * Priority Flow Control (PFC) (IEEE 802.3 annex 31D PFC) + */ + .tx_pfc_req(eth_tx_pfc_req[n*8 +: 8]), + .tx_pfc_resend(1'b0), + .rx_pfc_en(eth_rx_pfc_en[n*8 +: 8]), + .rx_pfc_req(eth_rx_pfc_req[n*8 +: 8]), + .rx_pfc_ack(eth_rx_pfc_ack[n*8 +: 8]), + + /* + * Pause interface + */ + .tx_lfc_pause_en(1'b1), + .tx_pause_req(1'b0), + .tx_pause_ack(), + + /* + * Status + */ + .tx_start_packet(), .tx_error_underflow(), + .rx_start_packet(), .rx_error_bad_frame(), .rx_error_bad_fcs(), + .stat_tx_mcf(), + .stat_rx_mcf(), + .stat_tx_lfc_pkt(), + .stat_tx_lfc_xon(), + .stat_tx_lfc_xoff(), + .stat_tx_lfc_paused(), + .stat_tx_pfc_pkt(), + .stat_tx_pfc_xon(), + .stat_tx_pfc_xoff(), + .stat_tx_pfc_paused(), + .stat_rx_lfc_pkt(), + .stat_rx_lfc_xon(), + .stat_rx_lfc_xoff(), + .stat_rx_lfc_paused(), + .stat_rx_pfc_pkt(), + .stat_rx_pfc_xon(), + .stat_rx_pfc_xoff(), + .stat_rx_pfc_paused(), + /* + * Configuration + */ .cfg_ifg(8'd12), - .cfg_tx_enable(1'b1), - .cfg_rx_enable(1'b1) + .cfg_tx_enable(eth_tx_enable[n +: 1]), + .cfg_rx_enable(eth_rx_enable[n +: 1]), + .cfg_mcf_rx_eth_dst_mcast(48'h01_80_C2_00_00_01), + .cfg_mcf_rx_check_eth_dst_mcast(1'b1), + .cfg_mcf_rx_eth_dst_ucast(48'd0), + .cfg_mcf_rx_check_eth_dst_ucast(1'b0), + .cfg_mcf_rx_eth_src(48'd0), + .cfg_mcf_rx_check_eth_src(1'b0), + .cfg_mcf_rx_eth_type(16'h8808), + .cfg_mcf_rx_opcode_lfc(16'h0001), + .cfg_mcf_rx_check_opcode_lfc(eth_rx_lfc_en[n +: 1]), + .cfg_mcf_rx_opcode_pfc(16'h0101), + .cfg_mcf_rx_check_opcode_pfc(eth_rx_pfc_en[n*8 +: 8] != 0), + .cfg_mcf_rx_forward(1'b0), + .cfg_mcf_rx_enable(eth_rx_lfc_en[n +: 1] || eth_rx_pfc_en[n*8 +: 8]), + .cfg_tx_lfc_eth_dst(48'h01_80_C2_00_00_01), + .cfg_tx_lfc_eth_src(48'h80_23_31_43_54_4C), + .cfg_tx_lfc_eth_type(16'h8808), + .cfg_tx_lfc_opcode(16'h0001), + .cfg_tx_lfc_en(eth_tx_lfc_en[n +: 1]), + .cfg_tx_lfc_quanta(16'hffff), + .cfg_tx_lfc_refresh(16'h7fff), + .cfg_tx_pfc_eth_dst(48'h01_80_C2_00_00_01), + .cfg_tx_pfc_eth_src(48'h80_23_31_43_54_4C), + .cfg_tx_pfc_eth_type(16'h8808), + .cfg_tx_pfc_opcode(16'h0101), + .cfg_tx_pfc_en(eth_tx_pfc_en[n*8 +: 8] != 0), + .cfg_tx_pfc_quanta({8{16'hffff}}), + .cfg_tx_pfc_refresh({8{16'h7fff}}), + .cfg_rx_lfc_opcode(16'h0001), + .cfg_rx_lfc_en(eth_rx_lfc_en[n +: 1]), + .cfg_rx_pfc_opcode(16'h0101), + .cfg_rx_pfc_en(eth_rx_pfc_en[n*8 +: 8] != 0) ); end @@ -1009,6 +1120,9 @@ mqnic_core_pcie_us #( .TX_CHECKSUM_ENABLE(TX_CHECKSUM_ENABLE), .RX_HASH_ENABLE(RX_HASH_ENABLE), .RX_CHECKSUM_ENABLE(RX_CHECKSUM_ENABLE), + .PFC_ENABLE(PFC_ENABLE), + .LFC_ENABLE(LFC_ENABLE), + .MAC_CTRL_ENABLE(0), .TX_FIFO_DEPTH(TX_FIFO_DEPTH), .RX_FIFO_DEPTH(RX_FIFO_DEPTH), .MAX_TX_SIZE(MAX_TX_SIZE), @@ -1290,7 +1404,13 @@ core_inst ( .s_axis_eth_tx_cpl_valid(axis_eth_tx_ptp_ts_valid), .s_axis_eth_tx_cpl_ready(axis_eth_tx_ptp_ts_ready), + .eth_tx_enable(eth_tx_enable), .eth_tx_status(eth_tx_status), + .eth_tx_lfc_en(eth_tx_lfc_en), + .eth_tx_lfc_req(eth_tx_lfc_req), + .eth_tx_pfc_en(eth_tx_pfc_en), + .eth_tx_pfc_req(eth_tx_pfc_req), + .eth_tx_fc_quanta_clk_en(0), .eth_rx_clk(eth_rx_clk), .eth_rx_rst(eth_rx_rst), @@ -1307,7 +1427,15 @@ core_inst ( .s_axis_eth_rx_tlast(axis_eth_rx_tlast), .s_axis_eth_rx_tuser(axis_eth_rx_tuser), + .eth_rx_enable(eth_rx_enable), .eth_rx_status(eth_rx_status), + .eth_rx_lfc_en(eth_rx_lfc_en), + .eth_rx_lfc_req(eth_rx_lfc_req), + .eth_rx_lfc_ack(eth_rx_lfc_ack), + .eth_rx_pfc_en(eth_rx_pfc_en), + .eth_rx_pfc_req(eth_rx_pfc_req), + .eth_rx_pfc_ack(eth_rx_pfc_ack), + .eth_rx_fc_quanta_clk_en(0), /* * DDR diff --git a/fpga/mqnic/VCU108/fpga_25g/tb/fpga_core/Makefile b/fpga/mqnic/VCU108/fpga_25g/tb/fpga_core/Makefile index 6a4f8efa4..cee5e0dfc 100644 --- a/fpga/mqnic/VCU108/fpga_25g/tb/fpga_core/Makefile +++ b/fpga/mqnic/VCU108/fpga_25g/tb/fpga_core/Makefile @@ -62,6 +62,10 @@ VERILOG_SOURCES += ../../rtl/common/tdma_ber_ch.v VERILOG_SOURCES += ../../lib/eth/rtl/eth_mac_10g.v VERILOG_SOURCES += ../../lib/eth/rtl/axis_xgmii_rx_64.v VERILOG_SOURCES += ../../lib/eth/rtl/axis_xgmii_tx_64.v +VERILOG_SOURCES += ../../lib/eth/rtl/mac_ctrl_rx.v +VERILOG_SOURCES += ../../lib/eth/rtl/mac_ctrl_tx.v +VERILOG_SOURCES += ../../lib/eth/rtl/mac_pause_ctrl_rx.v +VERILOG_SOURCES += ../../lib/eth/rtl/mac_pause_ctrl_tx.v VERILOG_SOURCES += ../../lib/eth/rtl/lfsr.v VERILOG_SOURCES += ../../lib/eth/rtl/ptp_clock.v VERILOG_SOURCES += ../../lib/eth/rtl/ptp_clock_cdc.v @@ -167,6 +171,8 @@ export PARAM_TX_CPL_FIFO_DEPTH := 32 export PARAM_TX_CHECKSUM_ENABLE := 1 export PARAM_RX_HASH_ENABLE := 1 export PARAM_RX_CHECKSUM_ENABLE := 1 +export PARAM_LFC_ENABLE := 1 +export PARAM_PFC_ENABLE := $(PARAM_LFC_ENABLE) export PARAM_TX_FIFO_DEPTH := 32768 export PARAM_RX_FIFO_DEPTH := 32768 export PARAM_MAX_TX_SIZE := 9214 diff --git a/fpga/mqnic/VCU108/fpga_25g/tb/fpga_core/test_fpga_core.py b/fpga/mqnic/VCU108/fpga_25g/tb/fpga_core/test_fpga_core.py index 720c63d4f..a1729a28b 100644 --- a/fpga/mqnic/VCU108/fpga_25g/tb/fpga_core/test_fpga_core.py +++ b/fpga/mqnic/VCU108/fpga_25g/tb/fpga_core/test_fpga_core.py @@ -3,6 +3,7 @@ import logging import os +import struct import sys import scapy.utils @@ -17,7 +18,7 @@ from cocotb.clock import Clock from cocotb.triggers import RisingEdge, FallingEdge, Timer from cocotbext.axi import AxiStreamBus -from cocotbext.eth import XgmiiSource, XgmiiSink +from cocotbext.eth import XgmiiSource, XgmiiSink, XgmiiFrame from cocotbext.pcie.core import RootComplex from cocotbext.pcie.xilinx.us import UltraScalePcieDevice @@ -276,7 +277,7 @@ class TB(object): dut.qsfp_drp_rdy.setimmediatevalue(0) dut.qsfp_modprsl.setimmediatevalue(0) - dut.qsfp_intl.setimmediatevalue(0) + dut.qsfp_intl.setimmediatevalue(1) dut.sw.setimmediatevalue(0) @@ -322,8 +323,8 @@ class TB(object): if self.loopback_enable: for x in range(len(self.qsfp_sink)): - if not self.qsfp_sink[x].empty(): - await self.qsfp_source[x].send(await self.qsfp_sink[x].recv()) + if not self.qsfp_sink[x].empty(): + await self.qsfp_source[x].send(await self.qsfp_sink[x].recv()) @cocotb.test() @@ -485,6 +486,35 @@ async def run_test_nic(dut): tb.loopback_enable = False + if tb.driver.interfaces[0].if_feature_lfc: + tb.log.info("Test LFC pause frame RX") + + await tb.driver.interfaces[0].ports[0].set_lfc_ctrl(mqnic.MQNIC_PORT_LFC_CTRL_TX_LFC_EN | mqnic.MQNIC_PORT_LFC_CTRL_RX_LFC_EN) + await tb.driver.hw_regs.read_dword(0) + + lfc_xoff = Ether(src='DA:D1:D2:D3:D4:D5', dst='01:80:C2:00:00:01', type=0x8808) / struct.pack('!HH', 0x0001, 2000) + + await tb.qsfp_source[0].send(XgmiiFrame.from_payload(bytes(lfc_xoff))) + + count = 16 + + pkts = [bytearray([(x+k) % 256 for x in range(1514)]) for k in range(count)] + + tb.loopback_enable = True + + for p in pkts: + await tb.driver.interfaces[0].start_xmit(p, 0) + + for k in range(count): + pkt = await tb.driver.interfaces[0].recv() + + tb.log.info("Packet: %s", pkt) + assert pkt.data == pkts[k] + if tb.driver.interfaces[0].if_feature_rx_csum: + assert pkt.rx_checksum == ~scapy.utils.checksum(bytes(pkt.data[14:])) & 0xffff + + tb.loopback_enable = False + await RisingEdge(dut.clk_250mhz) await RisingEdge(dut.clk_250mhz) @@ -557,6 +587,10 @@ def test_fpga_core(request): os.path.join(eth_rtl_dir, "eth_mac_10g.v"), os.path.join(eth_rtl_dir, "axis_xgmii_rx_64.v"), os.path.join(eth_rtl_dir, "axis_xgmii_tx_64.v"), + os.path.join(eth_rtl_dir, "mac_ctrl_rx.v"), + os.path.join(eth_rtl_dir, "mac_ctrl_tx.v"), + os.path.join(eth_rtl_dir, "mac_pause_ctrl_rx.v"), + os.path.join(eth_rtl_dir, "mac_pause_ctrl_tx.v"), os.path.join(eth_rtl_dir, "lfsr.v"), os.path.join(eth_rtl_dir, "ptp_clock.v"), os.path.join(eth_rtl_dir, "ptp_clock_cdc.v"), @@ -663,6 +697,8 @@ def test_fpga_core(request): parameters['TX_CHECKSUM_ENABLE'] = 1 parameters['RX_HASH_ENABLE'] = 1 parameters['RX_CHECKSUM_ENABLE'] = 1 + parameters['LFC_ENABLE'] = 1 + parameters['PFC_ENABLE'] = parameters['LFC_ENABLE'] parameters['TX_FIFO_DEPTH'] = 32768 parameters['RX_FIFO_DEPTH'] = 32768 parameters['MAX_TX_SIZE'] = 9214 diff --git a/fpga/mqnic/VCU118/fpga_100g/fpga/config.tcl b/fpga/mqnic/VCU118/fpga_100g/fpga/config.tcl index 5bd8d3174..211a69f3a 100644 --- a/fpga/mqnic/VCU118/fpga_100g/fpga/config.tcl +++ b/fpga/mqnic/VCU118/fpga_100g/fpga/config.tcl @@ -101,6 +101,8 @@ dict set params TX_CPL_FIFO_DEPTH "32" dict set params TX_CHECKSUM_ENABLE "1" dict set params RX_HASH_ENABLE "1" dict set params RX_CHECKSUM_ENABLE "1" +dict set params PFC_ENABLE "1" +dict set params LFC_ENABLE [dict get $params PFC_ENABLE] dict set params TX_FIFO_DEPTH "32768" dict set params RX_FIFO_DEPTH "131072" dict set params MAX_TX_SIZE "9214" diff --git a/fpga/mqnic/VCU118/fpga_100g/fpga_app_dma_bench/config.tcl b/fpga/mqnic/VCU118/fpga_100g/fpga_app_dma_bench/config.tcl index 010f4ddab..a2662da4f 100644 --- a/fpga/mqnic/VCU118/fpga_100g/fpga_app_dma_bench/config.tcl +++ b/fpga/mqnic/VCU118/fpga_100g/fpga_app_dma_bench/config.tcl @@ -101,6 +101,8 @@ dict set params TX_CPL_FIFO_DEPTH "32" dict set params TX_CHECKSUM_ENABLE "1" dict set params RX_HASH_ENABLE "1" dict set params RX_CHECKSUM_ENABLE "1" +dict set params PFC_ENABLE "1" +dict set params LFC_ENABLE [dict get $params PFC_ENABLE] dict set params TX_FIFO_DEPTH "32768" dict set params RX_FIFO_DEPTH "131072" dict set params MAX_TX_SIZE "9214" diff --git a/fpga/mqnic/VCU118/fpga_100g/ip/cmac_usplus.tcl b/fpga/mqnic/VCU118/fpga_100g/ip/cmac_usplus.tcl index b86d4ea5e..af9cc8265 100644 --- a/fpga/mqnic/VCU118/fpga_100g/ip/cmac_usplus.tcl +++ b/fpga/mqnic/VCU118/fpga_100g/ip/cmac_usplus.tcl @@ -7,8 +7,10 @@ set_property -dict [list \ CONFIG.USER_INTERFACE {AXIS} \ CONFIG.GT_DRP_CLK {125} \ CONFIG.GT_LOCATION {0} \ - CONFIG.TX_FLOW_CONTROL {0} \ - CONFIG.RX_FLOW_CONTROL {0} \ + CONFIG.TX_FLOW_CONTROL {1} \ + CONFIG.RX_FLOW_CONTROL {1} \ + CONFIG.RX_FORWARD_CONTROL_FRAMES {0} \ + CONFIG.RX_CHECK_ACK {1} \ CONFIG.INCLUDE_RS_FEC {1} \ CONFIG.ENABLE_TIME_STAMPING {1} ] [get_ips cmac_usplus] diff --git a/fpga/mqnic/VCU118/fpga_100g/rtl/fpga.v b/fpga/mqnic/VCU118/fpga_100g/rtl/fpga.v index b699de235..c9b15561d 100644 --- a/fpga/mqnic/VCU118/fpga_100g/rtl/fpga.v +++ b/fpga/mqnic/VCU118/fpga_100g/rtl/fpga.v @@ -71,6 +71,8 @@ module fpga # parameter TX_CHECKSUM_ENABLE = 1, parameter RX_HASH_ENABLE = 1, parameter RX_CHECKSUM_ENABLE = 1, + parameter PFC_ENABLE = 1, + parameter LFC_ENABLE = PFC_ENABLE, parameter TX_FIFO_DEPTH = 32768, parameter RX_FIFO_DEPTH = 131072, parameter MAX_TX_SIZE = 9214, @@ -942,7 +944,20 @@ wire qsfp1_drp_we; wire [15:0] qsfp1_drp_do; wire qsfp1_drp_rdy; -wire qsfp1_rx_status; +wire qsfp1_tx_enable; +wire qsfp1_tx_lfc_en; +wire qsfp1_tx_lfc_req; +wire [7:0] qsfp1_tx_pfc_en; +wire [7:0] qsfp1_tx_pfc_req; + +wire qsfp1_rx_enable; +wire qsfp1_rx_status; +wire qsfp1_rx_lfc_en; +wire qsfp1_rx_lfc_req; +wire qsfp1_rx_lfc_ack; +wire [7:0] qsfp1_rx_pfc_en; +wire [7:0] qsfp1_rx_pfc_req; +wire [7:0] qsfp1_rx_pfc_ack; wire qsfp1_gtpowergood; @@ -1035,6 +1050,12 @@ qsfp1_cmac_inst ( .tx_ptp_ts_tag(qsfp1_tx_ptp_ts_tag_int), .tx_ptp_ts_valid(qsfp1_tx_ptp_ts_valid_int), + .tx_enable(qsfp1_tx_enable), + .tx_lfc_en(qsfp1_tx_lfc_en), + .tx_lfc_req(qsfp1_tx_lfc_req), + .tx_pfc_en(qsfp1_tx_pfc_en), + .tx_pfc_req(qsfp1_tx_pfc_req), + .rx_clk(qsfp1_rx_clk_int), .rx_rst(qsfp1_rx_rst_int), @@ -1048,7 +1069,14 @@ qsfp1_cmac_inst ( .rx_ptp_rst(qsfp1_rx_ptp_rst_int), .rx_ptp_time(qsfp1_rx_ptp_time_int), - .rx_status(qsfp1_rx_status) + .rx_enable(qsfp1_rx_enable), + .rx_status(qsfp1_rx_status), + .rx_lfc_en(qsfp1_rx_lfc_en), + .rx_lfc_req(qsfp1_rx_lfc_req), + .rx_lfc_ack(qsfp1_rx_lfc_ack), + .rx_pfc_en(qsfp1_rx_pfc_en), + .rx_pfc_req(qsfp1_rx_pfc_req), + .rx_pfc_ack(qsfp1_rx_pfc_ack) ); // QSFP2 CMAC @@ -1089,7 +1117,20 @@ wire qsfp2_drp_we; wire [15:0] qsfp2_drp_do; wire qsfp2_drp_rdy; -wire qsfp2_rx_status; +wire qsfp2_tx_enable; +wire qsfp2_tx_lfc_en; +wire qsfp2_tx_lfc_req; +wire [7:0] qsfp2_tx_pfc_en; +wire [7:0] qsfp2_tx_pfc_req; + +wire qsfp2_rx_enable; +wire qsfp2_rx_status; +wire qsfp2_rx_lfc_en; +wire qsfp2_rx_lfc_req; +wire qsfp2_rx_lfc_ack; +wire [7:0] qsfp2_rx_pfc_en; +wire [7:0] qsfp2_rx_pfc_req; +wire [7:0] qsfp2_rx_pfc_ack; cmac_gty_wrapper #( .DRP_CLK_FREQ_HZ(125000000), @@ -1147,6 +1188,12 @@ qsfp2_cmac_inst ( .tx_ptp_ts_tag(qsfp2_tx_ptp_ts_tag_int), .tx_ptp_ts_valid(qsfp2_tx_ptp_ts_valid_int), + .tx_enable(qsfp2_tx_enable), + .tx_lfc_en(qsfp2_tx_lfc_en), + .tx_lfc_req(qsfp2_tx_lfc_req), + .tx_pfc_en(qsfp2_tx_pfc_en), + .tx_pfc_req(qsfp2_tx_pfc_req), + .rx_clk(qsfp2_rx_clk_int), .rx_rst(qsfp2_rx_rst_int), @@ -1160,7 +1207,14 @@ qsfp2_cmac_inst ( .rx_ptp_rst(qsfp2_rx_ptp_rst_int), .rx_ptp_time(qsfp2_rx_ptp_time_int), - .rx_status(qsfp2_rx_status) + .rx_enable(qsfp2_rx_enable), + .rx_status(qsfp2_rx_status), + .rx_lfc_en(qsfp2_rx_lfc_en), + .rx_lfc_req(qsfp2_rx_lfc_req), + .rx_lfc_ack(qsfp2_rx_lfc_ack), + .rx_pfc_en(qsfp2_rx_pfc_en), + .rx_pfc_req(qsfp2_rx_pfc_req), + .rx_pfc_ack(qsfp2_rx_pfc_ack) ); wire ptp_clk; @@ -1556,6 +1610,8 @@ fpga_core #( .TX_CHECKSUM_ENABLE(TX_CHECKSUM_ENABLE), .RX_HASH_ENABLE(RX_HASH_ENABLE), .RX_CHECKSUM_ENABLE(RX_CHECKSUM_ENABLE), + .PFC_ENABLE(PFC_ENABLE), + .LFC_ENABLE(LFC_ENABLE), .TX_FIFO_DEPTH(TX_FIFO_DEPTH), .RX_FIFO_DEPTH(RX_FIFO_DEPTH), .MAX_TX_SIZE(MAX_TX_SIZE), @@ -1767,6 +1823,12 @@ core_inst ( .qsfp1_tx_ptp_ts_tag(qsfp1_tx_ptp_ts_tag_int), .qsfp1_tx_ptp_ts_valid(qsfp1_tx_ptp_ts_valid_int), + .qsfp1_tx_enable(qsfp1_tx_enable), + .qsfp1_tx_lfc_en(qsfp1_tx_lfc_en), + .qsfp1_tx_lfc_req(qsfp1_tx_lfc_req), + .qsfp1_tx_pfc_en(qsfp1_tx_pfc_en), + .qsfp1_tx_pfc_req(qsfp1_tx_pfc_req), + .qsfp1_rx_clk(qsfp1_rx_clk_int), .qsfp1_rx_rst(qsfp1_rx_rst_int), .qsfp1_rx_axis_tdata(qsfp1_rx_axis_tdata_int), @@ -1778,7 +1840,14 @@ core_inst ( .qsfp1_rx_ptp_rst(qsfp1_rx_ptp_rst_int), .qsfp1_rx_ptp_time(qsfp1_rx_ptp_time_int), + .qsfp1_rx_enable(qsfp1_rx_enable), .qsfp1_rx_status(qsfp1_rx_status), + .qsfp1_rx_lfc_en(qsfp1_rx_lfc_en), + .qsfp1_rx_lfc_req(qsfp1_rx_lfc_req), + .qsfp1_rx_lfc_ack(qsfp1_rx_lfc_ack), + .qsfp1_rx_pfc_en(qsfp1_rx_pfc_en), + .qsfp1_rx_pfc_req(qsfp1_rx_pfc_req), + .qsfp1_rx_pfc_ack(qsfp1_rx_pfc_ack), .qsfp1_drp_clk(qsfp1_drp_clk), .qsfp1_drp_rst(qsfp1_drp_rst), @@ -1808,6 +1877,12 @@ core_inst ( .qsfp2_tx_ptp_ts_tag(qsfp2_tx_ptp_ts_tag_int), .qsfp2_tx_ptp_ts_valid(qsfp2_tx_ptp_ts_valid_int), + .qsfp2_tx_enable(qsfp2_tx_enable), + .qsfp2_tx_lfc_en(qsfp2_tx_lfc_en), + .qsfp2_tx_lfc_req(qsfp2_tx_lfc_req), + .qsfp2_tx_pfc_en(qsfp2_tx_pfc_en), + .qsfp2_tx_pfc_req(qsfp2_tx_pfc_req), + .qsfp2_rx_clk(qsfp2_rx_clk_int), .qsfp2_rx_rst(qsfp2_rx_rst_int), .qsfp2_rx_axis_tdata(qsfp2_rx_axis_tdata_int), @@ -1819,7 +1894,14 @@ core_inst ( .qsfp2_rx_ptp_rst(qsfp2_rx_ptp_rst_int), .qsfp2_rx_ptp_time(qsfp2_rx_ptp_time_int), + .qsfp2_rx_enable(qsfp2_rx_enable), .qsfp2_rx_status(qsfp2_rx_status), + .qsfp2_rx_lfc_en(qsfp2_rx_lfc_en), + .qsfp2_rx_lfc_req(qsfp2_rx_lfc_req), + .qsfp2_rx_lfc_ack(qsfp2_rx_lfc_ack), + .qsfp2_rx_pfc_en(qsfp2_rx_pfc_en), + .qsfp2_rx_pfc_req(qsfp2_rx_pfc_req), + .qsfp2_rx_pfc_ack(qsfp2_rx_pfc_ack), .qsfp2_drp_clk(qsfp2_drp_clk), .qsfp2_drp_rst(qsfp2_drp_rst), diff --git a/fpga/mqnic/VCU118/fpga_100g/rtl/fpga_core.v b/fpga/mqnic/VCU118/fpga_100g/rtl/fpga_core.v index aed23f4cb..b19cb8eed 100644 --- a/fpga/mqnic/VCU118/fpga_100g/rtl/fpga_core.v +++ b/fpga/mqnic/VCU118/fpga_100g/rtl/fpga_core.v @@ -77,6 +77,8 @@ module fpga_core # parameter TX_CHECKSUM_ENABLE = 1, parameter RX_HASH_ENABLE = 1, parameter RX_CHECKSUM_ENABLE = 1, + parameter PFC_ENABLE = 1, + parameter LFC_ENABLE = PFC_ENABLE, parameter TX_FIFO_DEPTH = 32768, parameter RX_FIFO_DEPTH = 131072, parameter MAX_TX_SIZE = 9214, @@ -290,6 +292,12 @@ module fpga_core # input wire [15:0] qsfp1_tx_ptp_ts_tag, input wire qsfp1_tx_ptp_ts_valid, + output wire qsfp1_tx_enable, + output wire qsfp1_tx_lfc_en, + output wire qsfp1_tx_lfc_req, + output wire [7:0] qsfp1_tx_pfc_en, + output wire [7:0] qsfp1_tx_pfc_req, + input wire qsfp1_rx_clk, input wire qsfp1_rx_rst, @@ -303,7 +311,14 @@ module fpga_core # input wire qsfp1_rx_ptp_rst, output wire [79:0] qsfp1_rx_ptp_time, + output wire qsfp1_rx_enable, input wire qsfp1_rx_status, + output wire qsfp1_rx_lfc_en, + input wire qsfp1_rx_lfc_req, + output wire qsfp1_rx_lfc_ack, + output wire [7:0] qsfp1_rx_pfc_en, + input wire [7:0] qsfp1_rx_pfc_req, + output wire [7:0] qsfp1_rx_pfc_ack, input wire qsfp1_drp_clk, input wire qsfp1_drp_rst, @@ -335,6 +350,12 @@ module fpga_core # input wire [15:0] qsfp2_tx_ptp_ts_tag, input wire qsfp2_tx_ptp_ts_valid, + output wire qsfp2_tx_enable, + output wire qsfp2_tx_lfc_en, + output wire qsfp2_tx_lfc_req, + output wire [7:0] qsfp2_tx_pfc_en, + output wire [7:0] qsfp2_tx_pfc_req, + input wire qsfp2_rx_clk, input wire qsfp2_rx_rst, @@ -357,7 +378,14 @@ module fpga_core # input wire [15:0] qsfp2_drp_do, input wire qsfp2_drp_rdy, + output wire qsfp2_rx_enable, input wire qsfp2_rx_status, + output wire qsfp2_rx_lfc_en, + input wire qsfp2_rx_lfc_req, + output wire qsfp2_rx_lfc_ack, + output wire [7:0] qsfp2_rx_pfc_en, + input wire [7:0] qsfp2_rx_pfc_req, + output wire [7:0] qsfp2_rx_pfc_ack, output wire qsfp2_modsell, output wire qsfp2_resetl, @@ -805,7 +833,12 @@ wire [PORT_COUNT*TX_TAG_WIDTH-1:0] axis_eth_tx_ptp_ts_tag; wire [PORT_COUNT-1:0] axis_eth_tx_ptp_ts_valid; wire [PORT_COUNT-1:0] axis_eth_tx_ptp_ts_ready; +wire [PORT_COUNT-1:0] eth_tx_enable; wire [PORT_COUNT-1:0] eth_tx_status; +wire [PORT_COUNT-1:0] eth_tx_lfc_en; +wire [PORT_COUNT-1:0] eth_tx_lfc_req; +wire [PORT_COUNT*8-1:0] eth_tx_pfc_en; +wire [PORT_COUNT*8-1:0] eth_tx_pfc_req; wire [PORT_COUNT-1:0] eth_rx_clk; wire [PORT_COUNT-1:0] eth_rx_rst; @@ -822,7 +855,14 @@ wire [PORT_COUNT-1:0] axis_eth_rx_tready; wire [PORT_COUNT-1:0] axis_eth_rx_tlast; wire [PORT_COUNT*AXIS_ETH_RX_USER_WIDTH-1:0] axis_eth_rx_tuser; +wire [PORT_COUNT-1:0] eth_rx_enable; wire [PORT_COUNT-1:0] eth_rx_status; +wire [PORT_COUNT-1:0] eth_rx_lfc_en; +wire [PORT_COUNT-1:0] eth_rx_lfc_req; +wire [PORT_COUNT-1:0] eth_rx_lfc_ack; +wire [PORT_COUNT*8-1:0] eth_rx_pfc_en; +wire [PORT_COUNT*8-1:0] eth_rx_pfc_req; +wire [PORT_COUNT*8-1:0] eth_rx_pfc_ack; wire [PTP_TS_WIDTH-1:0] qsfp1_tx_ptp_time_int; wire [PTP_TS_WIDTH-1:0] qsfp2_tx_ptp_time_int; @@ -873,7 +913,12 @@ mqnic_port_map_mac_axis_inst ( .s_axis_mac_tx_ptp_ts_valid({qsfp2_tx_ptp_ts_valid, qsfp1_tx_ptp_ts_valid}), .s_axis_mac_tx_ptp_ts_ready(), + .mac_tx_enable({qsfp2_tx_enable, qsfp1_tx_enable}), .mac_tx_status(2'b11), + .mac_tx_lfc_en({qsfp2_tx_lfc_en, qsfp1_tx_lfc_en}), + .mac_tx_lfc_req({qsfp2_tx_lfc_req, qsfp1_tx_lfc_req}), + .mac_tx_pfc_en({qsfp2_tx_pfc_en, qsfp1_tx_pfc_en}), + .mac_tx_pfc_req({qsfp2_tx_pfc_req, qsfp1_tx_pfc_req}), .mac_rx_clk({qsfp2_rx_clk, qsfp1_rx_clk}), .mac_rx_rst({qsfp2_rx_rst, qsfp1_rx_rst}), @@ -890,7 +935,14 @@ mqnic_port_map_mac_axis_inst ( .s_axis_mac_rx_tlast({qsfp2_rx_axis_tlast, qsfp1_rx_axis_tlast}), .s_axis_mac_rx_tuser({{qsfp2_rx_axis_tuser[80:1], 16'd0, qsfp2_rx_axis_tuser[0]}, {qsfp1_rx_axis_tuser[80:1], 16'd0, qsfp1_rx_axis_tuser[0]}}), + .mac_rx_enable({qsfp2_rx_enable, qsfp1_rx_enable}), .mac_rx_status({qsfp2_rx_status, qsfp1_rx_status}), + .mac_rx_lfc_en({qsfp2_rx_lfc_en, qsfp1_rx_lfc_en}), + .mac_rx_lfc_req({qsfp2_rx_lfc_req, qsfp1_rx_lfc_req}), + .mac_rx_lfc_ack({qsfp2_rx_lfc_ack, qsfp1_rx_lfc_ack}), + .mac_rx_pfc_en({qsfp2_rx_pfc_en, qsfp1_rx_pfc_en}), + .mac_rx_pfc_req({qsfp2_rx_pfc_req, qsfp1_rx_pfc_req}), + .mac_rx_pfc_ack({qsfp2_rx_pfc_ack, qsfp1_rx_pfc_ack}), // towards datapath .tx_clk(eth_tx_clk), @@ -913,7 +965,12 @@ mqnic_port_map_mac_axis_inst ( .m_axis_tx_ptp_ts_valid(axis_eth_tx_ptp_ts_valid), .m_axis_tx_ptp_ts_ready(axis_eth_tx_ptp_ts_ready), + .tx_enable(eth_tx_enable), .tx_status(eth_tx_status), + .tx_lfc_en(eth_tx_lfc_en), + .tx_lfc_req(eth_tx_lfc_req), + .tx_pfc_en(eth_tx_pfc_en), + .tx_pfc_req(eth_tx_pfc_req), .rx_clk(eth_rx_clk), .rx_rst(eth_rx_rst), @@ -930,7 +987,14 @@ mqnic_port_map_mac_axis_inst ( .m_axis_rx_tlast(axis_eth_rx_tlast), .m_axis_rx_tuser(axis_eth_rx_tuser), - .rx_status(eth_rx_status) + .rx_enable(eth_rx_enable), + .rx_status(eth_rx_status), + .rx_lfc_en(eth_rx_lfc_en), + .rx_lfc_req(eth_rx_lfc_req), + .rx_lfc_ack(eth_rx_lfc_ack), + .rx_pfc_en(eth_rx_pfc_en), + .rx_pfc_req(eth_rx_pfc_req), + .rx_pfc_ack(eth_rx_pfc_ack) ); mqnic_core_pcie_us #( @@ -1000,6 +1064,9 @@ mqnic_core_pcie_us #( .TX_CHECKSUM_ENABLE(TX_CHECKSUM_ENABLE), .RX_HASH_ENABLE(RX_HASH_ENABLE), .RX_CHECKSUM_ENABLE(RX_CHECKSUM_ENABLE), + .PFC_ENABLE(PFC_ENABLE), + .LFC_ENABLE(LFC_ENABLE), + .MAC_CTRL_ENABLE(0), .TX_FIFO_DEPTH(TX_FIFO_DEPTH), .RX_FIFO_DEPTH(RX_FIFO_DEPTH), .MAX_TX_SIZE(MAX_TX_SIZE), @@ -1281,7 +1348,13 @@ core_inst ( .s_axis_eth_tx_cpl_valid(axis_eth_tx_ptp_ts_valid), .s_axis_eth_tx_cpl_ready(axis_eth_tx_ptp_ts_ready), + .eth_tx_enable(eth_tx_enable), .eth_tx_status(eth_tx_status), + .eth_tx_lfc_en(eth_tx_lfc_en), + .eth_tx_lfc_req(eth_tx_lfc_req), + .eth_tx_pfc_en(eth_tx_pfc_en), + .eth_tx_pfc_req(eth_tx_pfc_req), + .eth_tx_fc_quanta_clk_en(0), .eth_rx_clk(eth_rx_clk), .eth_rx_rst(eth_rx_rst), @@ -1298,7 +1371,15 @@ core_inst ( .s_axis_eth_rx_tlast(axis_eth_rx_tlast), .s_axis_eth_rx_tuser(axis_eth_rx_tuser), + .eth_rx_enable(eth_rx_enable), .eth_rx_status(eth_rx_status), + .eth_rx_lfc_en(eth_rx_lfc_en), + .eth_rx_lfc_req(eth_rx_lfc_req), + .eth_rx_lfc_ack(eth_rx_lfc_ack), + .eth_rx_pfc_en(eth_rx_pfc_en), + .eth_rx_pfc_req(eth_rx_pfc_req), + .eth_rx_pfc_ack(eth_rx_pfc_ack), + .eth_rx_fc_quanta_clk_en(0), /* * DDR diff --git a/fpga/mqnic/VCU118/fpga_100g/tb/fpga_core/Makefile b/fpga/mqnic/VCU118/fpga_100g/tb/fpga_core/Makefile index 1b819db55..c10056880 100644 --- a/fpga/mqnic/VCU118/fpga_100g/tb/fpga_core/Makefile +++ b/fpga/mqnic/VCU118/fpga_100g/tb/fpga_core/Makefile @@ -161,6 +161,8 @@ export PARAM_TX_CPL_FIFO_DEPTH := 32 export PARAM_TX_CHECKSUM_ENABLE := 1 export PARAM_RX_HASH_ENABLE := 1 export PARAM_RX_CHECKSUM_ENABLE := 1 +export PARAM_LFC_ENABLE := 1 +export PARAM_PFC_ENABLE := $(PARAM_LFC_ENABLE) export PARAM_TX_FIFO_DEPTH := 32768 export PARAM_RX_FIFO_DEPTH := 131072 export PARAM_MAX_TX_SIZE := 9214 diff --git a/fpga/mqnic/VCU118/fpga_100g/tb/fpga_core/test_fpga_core.py b/fpga/mqnic/VCU118/fpga_100g/tb/fpga_core/test_fpga_core.py index 22aa0184d..0b29b84bb 100644 --- a/fpga/mqnic/VCU118/fpga_100g/tb/fpga_core/test_fpga_core.py +++ b/fpga/mqnic/VCU118/fpga_100g/tb/fpga_core/test_fpga_core.py @@ -300,6 +300,8 @@ class TB(object): self.qsfp_mac.append(mac) getattr(dut, f"qsfp{k}_rx_status").setimmediatevalue(1) + getattr(dut, f"qsfp{k}_rx_lfc_req").setimmediatevalue(0) + getattr(dut, f"qsfp{k}_rx_pfc_req").setimmediatevalue(0) cocotb.start_soon(Clock(getattr(dut, f"qsfp{k}_drp_clk"), 8, units="ns").start()) getattr(dut, f"qsfp{k}_drp_rst").setimmediatevalue(0) @@ -727,6 +729,8 @@ def test_fpga_core(request): parameters['TX_CHECKSUM_ENABLE'] = 1 parameters['RX_HASH_ENABLE'] = 1 parameters['RX_CHECKSUM_ENABLE'] = 1 + parameters['LFC_ENABLE'] = 1 + parameters['PFC_ENABLE'] = parameters['LFC_ENABLE'] parameters['TX_FIFO_DEPTH'] = 32768 parameters['RX_FIFO_DEPTH'] = 131072 parameters['MAX_TX_SIZE'] = 9214 diff --git a/fpga/mqnic/VCU118/fpga_25g/fpga/Makefile b/fpga/mqnic/VCU118/fpga_25g/fpga/Makefile index 13fb47770..df9c38a71 100644 --- a/fpga/mqnic/VCU118/fpga_25g/fpga/Makefile +++ b/fpga/mqnic/VCU118/fpga_25g/fpga/Makefile @@ -62,6 +62,10 @@ SYN_FILES += rtl/common/tdma_ber_ch.v SYN_FILES += lib/eth/rtl/eth_mac_10g.v SYN_FILES += lib/eth/rtl/axis_xgmii_rx_64.v SYN_FILES += lib/eth/rtl/axis_xgmii_tx_64.v +SYN_FILES += lib/eth/rtl/mac_ctrl_rx.v +SYN_FILES += lib/eth/rtl/mac_ctrl_tx.v +SYN_FILES += lib/eth/rtl/mac_pause_ctrl_rx.v +SYN_FILES += lib/eth/rtl/mac_pause_ctrl_tx.v SYN_FILES += lib/eth/rtl/eth_phy_10g.v SYN_FILES += lib/eth/rtl/eth_phy_10g_rx.v SYN_FILES += lib/eth/rtl/eth_phy_10g_rx_if.v diff --git a/fpga/mqnic/VCU118/fpga_25g/fpga/config.tcl b/fpga/mqnic/VCU118/fpga_25g/fpga/config.tcl index 22b1cbb21..6d28620df 100644 --- a/fpga/mqnic/VCU118/fpga_25g/fpga/config.tcl +++ b/fpga/mqnic/VCU118/fpga_25g/fpga/config.tcl @@ -113,6 +113,8 @@ dict set params TX_CPL_FIFO_DEPTH "32" dict set params TX_CHECKSUM_ENABLE "1" dict set params RX_HASH_ENABLE "1" dict set params RX_CHECKSUM_ENABLE "1" +dict set params PFC_ENABLE "1" +dict set params LFC_ENABLE [dict get $params PFC_ENABLE] dict set params ENABLE_PADDING "1" dict set params ENABLE_DIC "1" dict set params MIN_FRAME_LENGTH "64" diff --git a/fpga/mqnic/VCU118/fpga_25g/fpga_10g/Makefile b/fpga/mqnic/VCU118/fpga_25g/fpga_10g/Makefile index 13fb47770..df9c38a71 100644 --- a/fpga/mqnic/VCU118/fpga_25g/fpga_10g/Makefile +++ b/fpga/mqnic/VCU118/fpga_25g/fpga_10g/Makefile @@ -62,6 +62,10 @@ SYN_FILES += rtl/common/tdma_ber_ch.v SYN_FILES += lib/eth/rtl/eth_mac_10g.v SYN_FILES += lib/eth/rtl/axis_xgmii_rx_64.v SYN_FILES += lib/eth/rtl/axis_xgmii_tx_64.v +SYN_FILES += lib/eth/rtl/mac_ctrl_rx.v +SYN_FILES += lib/eth/rtl/mac_ctrl_tx.v +SYN_FILES += lib/eth/rtl/mac_pause_ctrl_rx.v +SYN_FILES += lib/eth/rtl/mac_pause_ctrl_tx.v SYN_FILES += lib/eth/rtl/eth_phy_10g.v SYN_FILES += lib/eth/rtl/eth_phy_10g_rx.v SYN_FILES += lib/eth/rtl/eth_phy_10g_rx_if.v diff --git a/fpga/mqnic/VCU118/fpga_25g/fpga_10g/config.tcl b/fpga/mqnic/VCU118/fpga_25g/fpga_10g/config.tcl index 01dc3067c..bc24256b3 100644 --- a/fpga/mqnic/VCU118/fpga_25g/fpga_10g/config.tcl +++ b/fpga/mqnic/VCU118/fpga_25g/fpga_10g/config.tcl @@ -113,6 +113,8 @@ dict set params TX_CPL_FIFO_DEPTH "32" dict set params TX_CHECKSUM_ENABLE "1" dict set params RX_HASH_ENABLE "1" dict set params RX_CHECKSUM_ENABLE "1" +dict set params PFC_ENABLE "1" +dict set params LFC_ENABLE [dict get $params PFC_ENABLE] dict set params ENABLE_PADDING "1" dict set params ENABLE_DIC "1" dict set params MIN_FRAME_LENGTH "64" diff --git a/fpga/mqnic/VCU118/fpga_25g/rtl/fpga.v b/fpga/mqnic/VCU118/fpga_25g/rtl/fpga.v index 9bb62ad38..0364b137f 100644 --- a/fpga/mqnic/VCU118/fpga_25g/rtl/fpga.v +++ b/fpga/mqnic/VCU118/fpga_25g/rtl/fpga.v @@ -74,6 +74,8 @@ module fpga # parameter TX_CHECKSUM_ENABLE = 1, parameter RX_HASH_ENABLE = 1, parameter RX_CHECKSUM_ENABLE = 1, + parameter PFC_ENABLE = 1, + parameter LFC_ENABLE = PFC_ENABLE, parameter ENABLE_PADDING = 1, parameter ENABLE_DIC = 1, parameter MIN_FRAME_LENGTH = 64, @@ -1691,6 +1693,8 @@ fpga_core #( .TX_CHECKSUM_ENABLE(TX_CHECKSUM_ENABLE), .RX_HASH_ENABLE(RX_HASH_ENABLE), .RX_CHECKSUM_ENABLE(RX_CHECKSUM_ENABLE), + .PFC_ENABLE(PFC_ENABLE), + .LFC_ENABLE(LFC_ENABLE), .ENABLE_PADDING(ENABLE_PADDING), .ENABLE_DIC(ENABLE_DIC), .MIN_FRAME_LENGTH(MIN_FRAME_LENGTH), diff --git a/fpga/mqnic/VCU118/fpga_25g/rtl/fpga_core.v b/fpga/mqnic/VCU118/fpga_25g/rtl/fpga_core.v index 7f027c842..5e9d47283 100644 --- a/fpga/mqnic/VCU118/fpga_25g/rtl/fpga_core.v +++ b/fpga/mqnic/VCU118/fpga_25g/rtl/fpga_core.v @@ -81,6 +81,8 @@ module fpga_core # parameter TX_CHECKSUM_ENABLE = 1, parameter RX_HASH_ENABLE = 1, parameter RX_CHECKSUM_ENABLE = 1, + parameter PFC_ENABLE = 1, + parameter LFC_ENABLE = PFC_ENABLE, parameter ENABLE_PADDING = 1, parameter ENABLE_DIC = 1, parameter MIN_FRAME_LENGTH = 64, @@ -947,7 +949,12 @@ wire [PORT_COUNT*TX_TAG_WIDTH-1:0] axis_eth_tx_ptp_ts_tag; wire [PORT_COUNT-1:0] axis_eth_tx_ptp_ts_valid; wire [PORT_COUNT-1:0] axis_eth_tx_ptp_ts_ready; +wire [PORT_COUNT-1:0] eth_tx_enable; wire [PORT_COUNT-1:0] eth_tx_status; +wire [PORT_COUNT-1:0] eth_tx_lfc_en; +wire [PORT_COUNT-1:0] eth_tx_lfc_req; +wire [PORT_COUNT*8-1:0] eth_tx_pfc_en; +wire [PORT_COUNT*8-1:0] eth_tx_pfc_req; wire [PORT_COUNT-1:0] eth_rx_clk; wire [PORT_COUNT-1:0] eth_rx_rst; @@ -962,7 +969,14 @@ wire [PORT_COUNT-1:0] axis_eth_rx_tready; wire [PORT_COUNT-1:0] axis_eth_rx_tlast; wire [PORT_COUNT*AXIS_ETH_RX_USER_WIDTH-1:0] axis_eth_rx_tuser; +wire [PORT_COUNT-1:0] eth_rx_enable; wire [PORT_COUNT-1:0] eth_rx_status; +wire [PORT_COUNT-1:0] eth_rx_lfc_en; +wire [PORT_COUNT-1:0] eth_rx_lfc_req; +wire [PORT_COUNT-1:0] eth_rx_lfc_ack; +wire [PORT_COUNT*8-1:0] eth_rx_pfc_en; +wire [PORT_COUNT*8-1:0] eth_rx_pfc_req; +wire [PORT_COUNT*8-1:0] eth_rx_pfc_ack; wire [PORT_COUNT-1:0] port_xgmii_tx_clk; wire [PORT_COUNT-1:0] port_xgmii_tx_rst; @@ -1035,12 +1049,15 @@ generate .PTP_PERIOD_FNS(IF_PTP_PERIOD_FNS), .TX_PTP_TS_ENABLE(PTP_TS_ENABLE), .TX_PTP_TS_WIDTH(PTP_TS_WIDTH), + .TX_PTP_TS_CTRL_IN_TUSER(0), .TX_PTP_TAG_ENABLE(PTP_TS_ENABLE), .TX_PTP_TAG_WIDTH(TX_TAG_WIDTH), .RX_PTP_TS_ENABLE(PTP_TS_ENABLE), .RX_PTP_TS_WIDTH(PTP_TS_WIDTH), .TX_USER_WIDTH(AXIS_ETH_TX_USER_WIDTH), - .RX_USER_WIDTH(AXIS_ETH_RX_USER_WIDTH) + .RX_USER_WIDTH(AXIS_ETH_RX_USER_WIDTH), + .PFC_ENABLE(PFC_ENABLE), + .PAUSE_ENABLE(LFC_ENABLE) ) eth_mac_inst ( .tx_clk(port_xgmii_tx_clk[n]), @@ -1048,6 +1065,9 @@ generate .rx_clk(port_xgmii_rx_clk[n]), .rx_rst(port_xgmii_rx_rst[n]), + /* + * AXI input + */ .tx_axis_tdata(axis_eth_tx_tdata[n*AXIS_ETH_DATA_WIDTH +: AXIS_ETH_DATA_WIDTH]), .tx_axis_tkeep(axis_eth_tx_tkeep[n*AXIS_ETH_KEEP_WIDTH +: AXIS_ETH_KEEP_WIDTH]), .tx_axis_tvalid(axis_eth_tx_tvalid[n +: 1]), @@ -1055,30 +1075,121 @@ generate .tx_axis_tlast(axis_eth_tx_tlast[n +: 1]), .tx_axis_tuser(axis_eth_tx_tuser[n*AXIS_ETH_TX_USER_WIDTH +: AXIS_ETH_TX_USER_WIDTH]), + /* + * AXI output + */ .rx_axis_tdata(axis_eth_rx_tdata[n*AXIS_ETH_DATA_WIDTH +: AXIS_ETH_DATA_WIDTH]), .rx_axis_tkeep(axis_eth_rx_tkeep[n*AXIS_ETH_KEEP_WIDTH +: AXIS_ETH_KEEP_WIDTH]), .rx_axis_tvalid(axis_eth_rx_tvalid[n +: 1]), .rx_axis_tlast(axis_eth_rx_tlast[n +: 1]), .rx_axis_tuser(axis_eth_rx_tuser[n*AXIS_ETH_RX_USER_WIDTH +: AXIS_ETH_RX_USER_WIDTH]), + /* + * XGMII interface + */ .xgmii_rxd(port_xgmii_rxd[n*XGMII_DATA_WIDTH +: XGMII_DATA_WIDTH]), .xgmii_rxc(port_xgmii_rxc[n*XGMII_CTRL_WIDTH +: XGMII_CTRL_WIDTH]), .xgmii_txd(port_xgmii_txd[n*XGMII_DATA_WIDTH +: XGMII_DATA_WIDTH]), .xgmii_txc(port_xgmii_txc[n*XGMII_CTRL_WIDTH +: XGMII_CTRL_WIDTH]), + /* + * PTP + */ .tx_ptp_ts(eth_tx_ptp_ts_96[n*PTP_TS_WIDTH +: PTP_TS_WIDTH]), .rx_ptp_ts(eth_rx_ptp_ts_96[n*PTP_TS_WIDTH +: PTP_TS_WIDTH]), .tx_axis_ptp_ts(axis_eth_tx_ptp_ts[n*PTP_TS_WIDTH +: PTP_TS_WIDTH]), .tx_axis_ptp_ts_tag(axis_eth_tx_ptp_ts_tag[n*TX_TAG_WIDTH +: TX_TAG_WIDTH]), .tx_axis_ptp_ts_valid(axis_eth_tx_ptp_ts_valid[n +: 1]), + /* + * Link-level Flow Control (LFC) (IEEE 802.3 annex 31B PAUSE) + */ + .tx_lfc_req(eth_tx_lfc_req[n +: 1]), + .tx_lfc_resend(1'b0), + .rx_lfc_en(eth_rx_lfc_en[n +: 1]), + .rx_lfc_req(eth_rx_lfc_req[n +: 1]), + .rx_lfc_ack(eth_rx_lfc_ack[n +: 1]), + + /* + * Priority Flow Control (PFC) (IEEE 802.3 annex 31D PFC) + */ + .tx_pfc_req(eth_tx_pfc_req[n*8 +: 8]), + .tx_pfc_resend(1'b0), + .rx_pfc_en(eth_rx_pfc_en[n*8 +: 8]), + .rx_pfc_req(eth_rx_pfc_req[n*8 +: 8]), + .rx_pfc_ack(eth_rx_pfc_ack[n*8 +: 8]), + + /* + * Pause interface + */ + .tx_lfc_pause_en(1'b1), + .tx_pause_req(1'b0), + .tx_pause_ack(), + + /* + * Status + */ + .tx_start_packet(), .tx_error_underflow(), + .rx_start_packet(), .rx_error_bad_frame(), .rx_error_bad_fcs(), + .stat_tx_mcf(), + .stat_rx_mcf(), + .stat_tx_lfc_pkt(), + .stat_tx_lfc_xon(), + .stat_tx_lfc_xoff(), + .stat_tx_lfc_paused(), + .stat_tx_pfc_pkt(), + .stat_tx_pfc_xon(), + .stat_tx_pfc_xoff(), + .stat_tx_pfc_paused(), + .stat_rx_lfc_pkt(), + .stat_rx_lfc_xon(), + .stat_rx_lfc_xoff(), + .stat_rx_lfc_paused(), + .stat_rx_pfc_pkt(), + .stat_rx_pfc_xon(), + .stat_rx_pfc_xoff(), + .stat_rx_pfc_paused(), + /* + * Configuration + */ .cfg_ifg(8'd12), - .cfg_tx_enable(1'b1), - .cfg_rx_enable(1'b1) + .cfg_tx_enable(eth_tx_enable[n +: 1]), + .cfg_rx_enable(eth_rx_enable[n +: 1]), + .cfg_mcf_rx_eth_dst_mcast(48'h01_80_C2_00_00_01), + .cfg_mcf_rx_check_eth_dst_mcast(1'b1), + .cfg_mcf_rx_eth_dst_ucast(48'd0), + .cfg_mcf_rx_check_eth_dst_ucast(1'b0), + .cfg_mcf_rx_eth_src(48'd0), + .cfg_mcf_rx_check_eth_src(1'b0), + .cfg_mcf_rx_eth_type(16'h8808), + .cfg_mcf_rx_opcode_lfc(16'h0001), + .cfg_mcf_rx_check_opcode_lfc(eth_rx_lfc_en[n +: 1]), + .cfg_mcf_rx_opcode_pfc(16'h0101), + .cfg_mcf_rx_check_opcode_pfc(eth_rx_pfc_en[n*8 +: 8] != 0), + .cfg_mcf_rx_forward(1'b0), + .cfg_mcf_rx_enable(eth_rx_lfc_en[n +: 1] || eth_rx_pfc_en[n*8 +: 8]), + .cfg_tx_lfc_eth_dst(48'h01_80_C2_00_00_01), + .cfg_tx_lfc_eth_src(48'h80_23_31_43_54_4C), + .cfg_tx_lfc_eth_type(16'h8808), + .cfg_tx_lfc_opcode(16'h0001), + .cfg_tx_lfc_en(eth_tx_lfc_en[n +: 1]), + .cfg_tx_lfc_quanta(16'hffff), + .cfg_tx_lfc_refresh(16'h7fff), + .cfg_tx_pfc_eth_dst(48'h01_80_C2_00_00_01), + .cfg_tx_pfc_eth_src(48'h80_23_31_43_54_4C), + .cfg_tx_pfc_eth_type(16'h8808), + .cfg_tx_pfc_opcode(16'h0101), + .cfg_tx_pfc_en(eth_tx_pfc_en[n*8 +: 8] != 0), + .cfg_tx_pfc_quanta({8{16'hffff}}), + .cfg_tx_pfc_refresh({8{16'h7fff}}), + .cfg_rx_lfc_opcode(16'h0001), + .cfg_rx_lfc_en(eth_rx_lfc_en[n +: 1]), + .cfg_rx_pfc_opcode(16'h0101), + .cfg_rx_pfc_en(eth_rx_pfc_en[n*8 +: 8] != 0) ); end @@ -1152,6 +1263,9 @@ mqnic_core_pcie_us #( .TX_CHECKSUM_ENABLE(TX_CHECKSUM_ENABLE), .RX_HASH_ENABLE(RX_HASH_ENABLE), .RX_CHECKSUM_ENABLE(RX_CHECKSUM_ENABLE), + .PFC_ENABLE(PFC_ENABLE), + .LFC_ENABLE(LFC_ENABLE), + .MAC_CTRL_ENABLE(0), .TX_FIFO_DEPTH(TX_FIFO_DEPTH), .RX_FIFO_DEPTH(RX_FIFO_DEPTH), .MAX_TX_SIZE(MAX_TX_SIZE), @@ -1433,7 +1547,13 @@ core_inst ( .s_axis_eth_tx_cpl_valid(axis_eth_tx_ptp_ts_valid), .s_axis_eth_tx_cpl_ready(axis_eth_tx_ptp_ts_ready), + .eth_tx_enable(eth_tx_enable), .eth_tx_status(eth_tx_status), + .eth_tx_lfc_en(eth_tx_lfc_en), + .eth_tx_lfc_req(eth_tx_lfc_req), + .eth_tx_pfc_en(eth_tx_pfc_en), + .eth_tx_pfc_req(eth_tx_pfc_req), + .eth_tx_fc_quanta_clk_en(0), .eth_rx_clk(eth_rx_clk), .eth_rx_rst(eth_rx_rst), @@ -1450,7 +1570,15 @@ core_inst ( .s_axis_eth_rx_tlast(axis_eth_rx_tlast), .s_axis_eth_rx_tuser(axis_eth_rx_tuser), + .eth_rx_enable(eth_rx_enable), .eth_rx_status(eth_rx_status), + .eth_rx_lfc_en(eth_rx_lfc_en), + .eth_rx_lfc_req(eth_rx_lfc_req), + .eth_rx_lfc_ack(eth_rx_lfc_ack), + .eth_rx_pfc_en(eth_rx_pfc_en), + .eth_rx_pfc_req(eth_rx_pfc_req), + .eth_rx_pfc_ack(eth_rx_pfc_ack), + .eth_rx_fc_quanta_clk_en(0), /* * DDR diff --git a/fpga/mqnic/VCU118/fpga_25g/tb/fpga_core/Makefile b/fpga/mqnic/VCU118/fpga_25g/tb/fpga_core/Makefile index 631c0f284..33b3c8ee4 100644 --- a/fpga/mqnic/VCU118/fpga_25g/tb/fpga_core/Makefile +++ b/fpga/mqnic/VCU118/fpga_25g/tb/fpga_core/Makefile @@ -62,6 +62,10 @@ VERILOG_SOURCES += ../../rtl/common/tdma_ber_ch.v VERILOG_SOURCES += ../../lib/eth/rtl/eth_mac_10g.v VERILOG_SOURCES += ../../lib/eth/rtl/axis_xgmii_rx_64.v VERILOG_SOURCES += ../../lib/eth/rtl/axis_xgmii_tx_64.v +VERILOG_SOURCES += ../../lib/eth/rtl/mac_ctrl_rx.v +VERILOG_SOURCES += ../../lib/eth/rtl/mac_ctrl_tx.v +VERILOG_SOURCES += ../../lib/eth/rtl/mac_pause_ctrl_rx.v +VERILOG_SOURCES += ../../lib/eth/rtl/mac_pause_ctrl_tx.v VERILOG_SOURCES += ../../lib/eth/rtl/lfsr.v VERILOG_SOURCES += ../../lib/eth/rtl/ptp_clock.v VERILOG_SOURCES += ../../lib/eth/rtl/ptp_clock_cdc.v @@ -167,6 +171,8 @@ export PARAM_TX_CPL_FIFO_DEPTH := 32 export PARAM_TX_CHECKSUM_ENABLE := 1 export PARAM_RX_HASH_ENABLE := 1 export PARAM_RX_CHECKSUM_ENABLE := 1 +export PARAM_LFC_ENABLE := 1 +export PARAM_PFC_ENABLE := $(PARAM_LFC_ENABLE) export PARAM_TX_FIFO_DEPTH := 32768 export PARAM_RX_FIFO_DEPTH := 32768 export PARAM_MAX_TX_SIZE := 9214 diff --git a/fpga/mqnic/VCU118/fpga_25g/tb/fpga_core/test_fpga_core.py b/fpga/mqnic/VCU118/fpga_25g/tb/fpga_core/test_fpga_core.py index d2738104f..6b80fb2bc 100644 --- a/fpga/mqnic/VCU118/fpga_25g/tb/fpga_core/test_fpga_core.py +++ b/fpga/mqnic/VCU118/fpga_25g/tb/fpga_core/test_fpga_core.py @@ -3,6 +3,7 @@ import logging import os +import struct import sys import scapy.utils @@ -17,7 +18,7 @@ from cocotb.clock import Clock from cocotb.triggers import RisingEdge, FallingEdge, Timer from cocotbext.axi import AxiStreamBus -from cocotbext.eth import XgmiiSource, XgmiiSink +from cocotbext.eth import XgmiiSource, XgmiiSink, XgmiiFrame from cocotbext.pcie.core import RootComplex from cocotbext.pcie.xilinx.us import UltraScalePlusPcieDevice @@ -532,6 +533,35 @@ async def run_test_nic(dut): tb.loopback_enable = False + if tb.driver.interfaces[0].if_feature_lfc: + tb.log.info("Test LFC pause frame RX") + + await tb.driver.interfaces[0].ports[0].set_lfc_ctrl(mqnic.MQNIC_PORT_LFC_CTRL_TX_LFC_EN | mqnic.MQNIC_PORT_LFC_CTRL_RX_LFC_EN) + await tb.driver.hw_regs.read_dword(0) + + lfc_xoff = Ether(src='DA:D1:D2:D3:D4:D5', dst='01:80:C2:00:00:01', type=0x8808) / struct.pack('!HH', 0x0001, 2000) + + await tb.qsfp_source[0][0].send(XgmiiFrame.from_payload(bytes(lfc_xoff))) + + count = 16 + + pkts = [bytearray([(x+k) % 256 for x in range(1514)]) for k in range(count)] + + tb.loopback_enable = True + + for p in pkts: + await tb.driver.interfaces[0].start_xmit(p, 0) + + for k in range(count): + pkt = await tb.driver.interfaces[0].recv() + + tb.log.info("Packet: %s", pkt) + assert pkt.data == pkts[k] + if tb.driver.interfaces[0].if_feature_rx_csum: + assert pkt.rx_checksum == ~scapy.utils.checksum(bytes(pkt.data[14:])) & 0xffff + + tb.loopback_enable = False + await RisingEdge(dut.clk_250mhz) await RisingEdge(dut.clk_250mhz) @@ -604,6 +634,10 @@ def test_fpga_core(request): os.path.join(eth_rtl_dir, "eth_mac_10g.v"), os.path.join(eth_rtl_dir, "axis_xgmii_rx_64.v"), os.path.join(eth_rtl_dir, "axis_xgmii_tx_64.v"), + os.path.join(eth_rtl_dir, "mac_ctrl_rx.v"), + os.path.join(eth_rtl_dir, "mac_ctrl_tx.v"), + os.path.join(eth_rtl_dir, "mac_pause_ctrl_rx.v"), + os.path.join(eth_rtl_dir, "mac_pause_ctrl_tx.v"), os.path.join(eth_rtl_dir, "lfsr.v"), os.path.join(eth_rtl_dir, "ptp_clock.v"), os.path.join(eth_rtl_dir, "ptp_clock_cdc.v"), @@ -710,6 +744,8 @@ def test_fpga_core(request): parameters['TX_CHECKSUM_ENABLE'] = 1 parameters['RX_HASH_ENABLE'] = 1 parameters['RX_CHECKSUM_ENABLE'] = 1 + parameters['LFC_ENABLE'] = 1 + parameters['PFC_ENABLE'] = parameters['LFC_ENABLE'] parameters['TX_FIFO_DEPTH'] = 32768 parameters['RX_FIFO_DEPTH'] = 32768 parameters['MAX_TX_SIZE'] = 9214 diff --git a/fpga/mqnic/VCU1525/fpga_100g/fpga/config.tcl b/fpga/mqnic/VCU1525/fpga_100g/fpga/config.tcl index 49619499e..740c0574e 100644 --- a/fpga/mqnic/VCU1525/fpga_100g/fpga/config.tcl +++ b/fpga/mqnic/VCU1525/fpga_100g/fpga/config.tcl @@ -101,6 +101,8 @@ dict set params TX_CPL_FIFO_DEPTH "32" dict set params TX_CHECKSUM_ENABLE "1" dict set params RX_HASH_ENABLE "1" dict set params RX_CHECKSUM_ENABLE "1" +dict set params PFC_ENABLE "1" +dict set params LFC_ENABLE [dict get $params PFC_ENABLE] dict set params TX_FIFO_DEPTH "32768" dict set params RX_FIFO_DEPTH "131072" dict set params MAX_TX_SIZE "9214" diff --git a/fpga/mqnic/VCU1525/fpga_100g/fpga_app_dma_bench/config.tcl b/fpga/mqnic/VCU1525/fpga_100g/fpga_app_dma_bench/config.tcl index 00a354fe7..bac18153f 100644 --- a/fpga/mqnic/VCU1525/fpga_100g/fpga_app_dma_bench/config.tcl +++ b/fpga/mqnic/VCU1525/fpga_100g/fpga_app_dma_bench/config.tcl @@ -101,6 +101,8 @@ dict set params TX_CPL_FIFO_DEPTH "32" dict set params TX_CHECKSUM_ENABLE "1" dict set params RX_HASH_ENABLE "1" dict set params RX_CHECKSUM_ENABLE "1" +dict set params PFC_ENABLE "1" +dict set params LFC_ENABLE [dict get $params PFC_ENABLE] dict set params TX_FIFO_DEPTH "32768" dict set params RX_FIFO_DEPTH "131072" dict set params MAX_TX_SIZE "9214" diff --git a/fpga/mqnic/VCU1525/fpga_100g/ip/cmac_usplus.tcl b/fpga/mqnic/VCU1525/fpga_100g/ip/cmac_usplus.tcl index b86d4ea5e..af9cc8265 100644 --- a/fpga/mqnic/VCU1525/fpga_100g/ip/cmac_usplus.tcl +++ b/fpga/mqnic/VCU1525/fpga_100g/ip/cmac_usplus.tcl @@ -7,8 +7,10 @@ set_property -dict [list \ CONFIG.USER_INTERFACE {AXIS} \ CONFIG.GT_DRP_CLK {125} \ CONFIG.GT_LOCATION {0} \ - CONFIG.TX_FLOW_CONTROL {0} \ - CONFIG.RX_FLOW_CONTROL {0} \ + CONFIG.TX_FLOW_CONTROL {1} \ + CONFIG.RX_FLOW_CONTROL {1} \ + CONFIG.RX_FORWARD_CONTROL_FRAMES {0} \ + CONFIG.RX_CHECK_ACK {1} \ CONFIG.INCLUDE_RS_FEC {1} \ CONFIG.ENABLE_TIME_STAMPING {1} ] [get_ips cmac_usplus] diff --git a/fpga/mqnic/VCU1525/fpga_100g/rtl/fpga.v b/fpga/mqnic/VCU1525/fpga_100g/rtl/fpga.v index 7bb542e19..e66d6a163 100644 --- a/fpga/mqnic/VCU1525/fpga_100g/rtl/fpga.v +++ b/fpga/mqnic/VCU1525/fpga_100g/rtl/fpga.v @@ -71,6 +71,8 @@ module fpga # parameter TX_CHECKSUM_ENABLE = 1, parameter RX_HASH_ENABLE = 1, parameter RX_CHECKSUM_ENABLE = 1, + parameter PFC_ENABLE = 1, + parameter LFC_ENABLE = PFC_ENABLE, parameter TX_FIFO_DEPTH = 32768, parameter RX_FIFO_DEPTH = 131072, parameter MAX_TX_SIZE = 9214, @@ -954,7 +956,20 @@ wire qsfp0_drp_we; wire [15:0] qsfp0_drp_do; wire qsfp0_drp_rdy; -wire qsfp0_rx_status; +wire qsfp0_tx_enable; +wire qsfp0_tx_lfc_en; +wire qsfp0_tx_lfc_req; +wire [7:0] qsfp0_tx_pfc_en; +wire [7:0] qsfp0_tx_pfc_req; + +wire qsfp0_rx_enable; +wire qsfp0_rx_status; +wire qsfp0_rx_lfc_en; +wire qsfp0_rx_lfc_req; +wire qsfp0_rx_lfc_ack; +wire [7:0] qsfp0_rx_pfc_en; +wire [7:0] qsfp0_rx_pfc_req; +wire [7:0] qsfp0_rx_pfc_ack; wire qsfp0_gtpowergood; @@ -1049,6 +1064,12 @@ qsfp0_cmac_inst ( .tx_ptp_ts_tag(qsfp0_tx_ptp_ts_tag_int), .tx_ptp_ts_valid(qsfp0_tx_ptp_ts_valid_int), + .tx_enable(qsfp0_tx_enable), + .tx_lfc_en(qsfp0_tx_lfc_en), + .tx_lfc_req(qsfp0_tx_lfc_req), + .tx_pfc_en(qsfp0_tx_pfc_en), + .tx_pfc_req(qsfp0_tx_pfc_req), + .rx_clk(qsfp0_rx_clk_int), .rx_rst(qsfp0_rx_rst_int), @@ -1062,7 +1083,14 @@ qsfp0_cmac_inst ( .rx_ptp_rst(qsfp0_rx_ptp_rst_int), .rx_ptp_time(qsfp0_rx_ptp_time_int), - .rx_status(qsfp0_rx_status) + .rx_enable(qsfp0_rx_enable), + .rx_status(qsfp0_rx_status), + .rx_lfc_en(qsfp0_rx_lfc_en), + .rx_lfc_req(qsfp0_rx_lfc_req), + .rx_lfc_ack(qsfp0_rx_lfc_ack), + .rx_pfc_en(qsfp0_rx_pfc_en), + .rx_pfc_req(qsfp0_rx_pfc_req), + .rx_pfc_ack(qsfp0_rx_pfc_ack) ); // QSFP1 CMAC @@ -1106,7 +1134,20 @@ wire qsfp1_drp_we; wire [15:0] qsfp1_drp_do; wire qsfp1_drp_rdy; -wire qsfp1_rx_status; +wire qsfp1_tx_enable; +wire qsfp1_tx_lfc_en; +wire qsfp1_tx_lfc_req; +wire [7:0] qsfp1_tx_pfc_en; +wire [7:0] qsfp1_tx_pfc_req; + +wire qsfp1_rx_enable; +wire qsfp1_rx_status; +wire qsfp1_rx_lfc_en; +wire qsfp1_rx_lfc_req; +wire qsfp1_rx_lfc_ack; +wire [7:0] qsfp1_rx_pfc_en; +wire [7:0] qsfp1_rx_pfc_req; +wire [7:0] qsfp1_rx_pfc_ack; wire qsfp1_gtpowergood; @@ -1199,6 +1240,12 @@ qsfp1_cmac_inst ( .tx_ptp_ts_tag(qsfp1_tx_ptp_ts_tag_int), .tx_ptp_ts_valid(qsfp1_tx_ptp_ts_valid_int), + .tx_enable(qsfp1_tx_enable), + .tx_lfc_en(qsfp1_tx_lfc_en), + .tx_lfc_req(qsfp1_tx_lfc_req), + .tx_pfc_en(qsfp1_tx_pfc_en), + .tx_pfc_req(qsfp1_tx_pfc_req), + .rx_clk(qsfp1_rx_clk_int), .rx_rst(qsfp1_rx_rst_int), @@ -1212,7 +1259,14 @@ qsfp1_cmac_inst ( .rx_ptp_rst(qsfp1_rx_ptp_rst_int), .rx_ptp_time(qsfp1_rx_ptp_time_int), - .rx_status(qsfp1_rx_status) + .rx_enable(qsfp1_rx_enable), + .rx_status(qsfp1_rx_status), + .rx_lfc_en(qsfp1_rx_lfc_en), + .rx_lfc_req(qsfp1_rx_lfc_req), + .rx_lfc_ack(qsfp1_rx_lfc_ack), + .rx_pfc_en(qsfp1_rx_pfc_en), + .rx_pfc_req(qsfp1_rx_pfc_req), + .rx_pfc_ack(qsfp1_rx_pfc_ack) ); wire ptp_clk; @@ -1846,6 +1900,8 @@ fpga_core #( .TX_CHECKSUM_ENABLE(TX_CHECKSUM_ENABLE), .RX_HASH_ENABLE(RX_HASH_ENABLE), .RX_CHECKSUM_ENABLE(RX_CHECKSUM_ENABLE), + .PFC_ENABLE(PFC_ENABLE), + .LFC_ENABLE(LFC_ENABLE), .TX_FIFO_DEPTH(TX_FIFO_DEPTH), .RX_FIFO_DEPTH(RX_FIFO_DEPTH), .MAX_TX_SIZE(MAX_TX_SIZE), @@ -2050,6 +2106,12 @@ core_inst ( .qsfp0_tx_ptp_ts_tag(qsfp0_tx_ptp_ts_tag_int), .qsfp0_tx_ptp_ts_valid(qsfp0_tx_ptp_ts_valid_int), + .qsfp0_tx_enable(qsfp0_tx_enable), + .qsfp0_tx_lfc_en(qsfp0_tx_lfc_en), + .qsfp0_tx_lfc_req(qsfp0_tx_lfc_req), + .qsfp0_tx_pfc_en(qsfp0_tx_pfc_en), + .qsfp0_tx_pfc_req(qsfp0_tx_pfc_req), + .qsfp0_rx_clk(qsfp0_rx_clk_int), .qsfp0_rx_rst(qsfp0_rx_rst_int), .qsfp0_rx_axis_tdata(qsfp0_rx_axis_tdata_int), @@ -2061,7 +2123,14 @@ core_inst ( .qsfp0_rx_ptp_rst(qsfp0_rx_ptp_rst_int), .qsfp0_rx_ptp_time(qsfp0_rx_ptp_time_int), + .qsfp0_rx_enable(qsfp0_rx_enable), .qsfp0_rx_status(qsfp0_rx_status), + .qsfp0_rx_lfc_en(qsfp0_rx_lfc_en), + .qsfp0_rx_lfc_req(qsfp0_rx_lfc_req), + .qsfp0_rx_lfc_ack(qsfp0_rx_lfc_ack), + .qsfp0_rx_pfc_en(qsfp0_rx_pfc_en), + .qsfp0_rx_pfc_req(qsfp0_rx_pfc_req), + .qsfp0_rx_pfc_ack(qsfp0_rx_pfc_ack), .qsfp0_drp_clk(qsfp0_drp_clk), .qsfp0_drp_rst(qsfp0_drp_rst), @@ -2091,6 +2160,12 @@ core_inst ( .qsfp1_tx_ptp_ts_tag(qsfp1_tx_ptp_ts_tag_int), .qsfp1_tx_ptp_ts_valid(qsfp1_tx_ptp_ts_valid_int), + .qsfp1_tx_enable(qsfp1_tx_enable), + .qsfp1_tx_lfc_en(qsfp1_tx_lfc_en), + .qsfp1_tx_lfc_req(qsfp1_tx_lfc_req), + .qsfp1_tx_pfc_en(qsfp1_tx_pfc_en), + .qsfp1_tx_pfc_req(qsfp1_tx_pfc_req), + .qsfp1_rx_clk(qsfp1_rx_clk_int), .qsfp1_rx_rst(qsfp1_rx_rst_int), .qsfp1_rx_axis_tdata(qsfp1_rx_axis_tdata_int), @@ -2102,7 +2177,14 @@ core_inst ( .qsfp1_rx_ptp_rst(qsfp1_rx_ptp_rst_int), .qsfp1_rx_ptp_time(qsfp1_rx_ptp_time_int), + .qsfp1_rx_enable(qsfp1_rx_enable), .qsfp1_rx_status(qsfp1_rx_status), + .qsfp1_rx_lfc_en(qsfp1_rx_lfc_en), + .qsfp1_rx_lfc_req(qsfp1_rx_lfc_req), + .qsfp1_rx_lfc_ack(qsfp1_rx_lfc_ack), + .qsfp1_rx_pfc_en(qsfp1_rx_pfc_en), + .qsfp1_rx_pfc_req(qsfp1_rx_pfc_req), + .qsfp1_rx_pfc_ack(qsfp1_rx_pfc_ack), .qsfp1_drp_clk(qsfp1_drp_clk), .qsfp1_drp_rst(qsfp1_drp_rst), diff --git a/fpga/mqnic/VCU1525/fpga_100g/rtl/fpga_core.v b/fpga/mqnic/VCU1525/fpga_100g/rtl/fpga_core.v index 722b02e0c..8a282db11 100644 --- a/fpga/mqnic/VCU1525/fpga_100g/rtl/fpga_core.v +++ b/fpga/mqnic/VCU1525/fpga_100g/rtl/fpga_core.v @@ -77,6 +77,8 @@ module fpga_core # parameter TX_CHECKSUM_ENABLE = 1, parameter RX_HASH_ENABLE = 1, parameter RX_CHECKSUM_ENABLE = 1, + parameter PFC_ENABLE = 1, + parameter LFC_ENABLE = PFC_ENABLE, parameter TX_FIFO_DEPTH = 32768, parameter RX_FIFO_DEPTH = 131072, parameter MAX_TX_SIZE = 9214, @@ -283,6 +285,12 @@ module fpga_core # input wire [15:0] qsfp0_tx_ptp_ts_tag, input wire qsfp0_tx_ptp_ts_valid, + output wire qsfp0_tx_enable, + output wire qsfp0_tx_lfc_en, + output wire qsfp0_tx_lfc_req, + output wire [7:0] qsfp0_tx_pfc_en, + output wire [7:0] qsfp0_tx_pfc_req, + input wire qsfp0_rx_clk, input wire qsfp0_rx_rst, @@ -296,7 +304,14 @@ module fpga_core # input wire qsfp0_rx_ptp_rst, output wire [79:0] qsfp0_rx_ptp_time, + output wire qsfp0_rx_enable, input wire qsfp0_rx_status, + output wire qsfp0_rx_lfc_en, + input wire qsfp0_rx_lfc_req, + output wire qsfp0_rx_lfc_ack, + output wire [7:0] qsfp0_rx_pfc_en, + input wire [7:0] qsfp0_rx_pfc_req, + output wire [7:0] qsfp0_rx_pfc_ack, input wire qsfp0_drp_clk, input wire qsfp0_drp_rst, @@ -328,6 +343,12 @@ module fpga_core # input wire [15:0] qsfp1_tx_ptp_ts_tag, input wire qsfp1_tx_ptp_ts_valid, + output wire qsfp1_tx_enable, + output wire qsfp1_tx_lfc_en, + output wire qsfp1_tx_lfc_req, + output wire [7:0] qsfp1_tx_pfc_en, + output wire [7:0] qsfp1_tx_pfc_req, + input wire qsfp1_rx_clk, input wire qsfp1_rx_rst, @@ -341,7 +362,14 @@ module fpga_core # input wire qsfp1_rx_ptp_rst, output wire [79:0] qsfp1_rx_ptp_time, + output wire qsfp1_rx_enable, input wire qsfp1_rx_status, + output wire qsfp1_rx_lfc_en, + input wire qsfp1_rx_lfc_req, + output wire qsfp1_rx_lfc_ack, + output wire [7:0] qsfp1_rx_pfc_en, + input wire [7:0] qsfp1_rx_pfc_req, + output wire [7:0] qsfp1_rx_pfc_ack, input wire qsfp1_drp_clk, input wire qsfp1_drp_rst, @@ -760,7 +788,12 @@ wire [PORT_COUNT*TX_TAG_WIDTH-1:0] axis_eth_tx_ptp_ts_tag; wire [PORT_COUNT-1:0] axis_eth_tx_ptp_ts_valid; wire [PORT_COUNT-1:0] axis_eth_tx_ptp_ts_ready; +wire [PORT_COUNT-1:0] eth_tx_enable; wire [PORT_COUNT-1:0] eth_tx_status; +wire [PORT_COUNT-1:0] eth_tx_lfc_en; +wire [PORT_COUNT-1:0] eth_tx_lfc_req; +wire [PORT_COUNT*8-1:0] eth_tx_pfc_en; +wire [PORT_COUNT*8-1:0] eth_tx_pfc_req; wire [PORT_COUNT-1:0] eth_rx_clk; wire [PORT_COUNT-1:0] eth_rx_rst; @@ -777,7 +810,14 @@ wire [PORT_COUNT-1:0] axis_eth_rx_tready; wire [PORT_COUNT-1:0] axis_eth_rx_tlast; wire [PORT_COUNT*AXIS_ETH_RX_USER_WIDTH-1:0] axis_eth_rx_tuser; +wire [PORT_COUNT-1:0] eth_rx_enable; wire [PORT_COUNT-1:0] eth_rx_status; +wire [PORT_COUNT-1:0] eth_rx_lfc_en; +wire [PORT_COUNT-1:0] eth_rx_lfc_req; +wire [PORT_COUNT-1:0] eth_rx_lfc_ack; +wire [PORT_COUNT*8-1:0] eth_rx_pfc_en; +wire [PORT_COUNT*8-1:0] eth_rx_pfc_req; +wire [PORT_COUNT*8-1:0] eth_rx_pfc_ack; wire [PTP_TS_WIDTH-1:0] qsfp0_tx_ptp_time_int; wire [PTP_TS_WIDTH-1:0] qsfp1_tx_ptp_time_int; @@ -828,7 +868,12 @@ mqnic_port_map_mac_axis_inst ( .s_axis_mac_tx_ptp_ts_valid({qsfp1_tx_ptp_ts_valid, qsfp0_tx_ptp_ts_valid}), .s_axis_mac_tx_ptp_ts_ready(), + .mac_tx_enable({qsfp1_tx_enable, qsfp0_tx_enable}), .mac_tx_status(2'b11), + .mac_tx_lfc_en({qsfp1_tx_lfc_en, qsfp0_tx_lfc_en}), + .mac_tx_lfc_req({qsfp1_tx_lfc_req, qsfp0_tx_lfc_req}), + .mac_tx_pfc_en({qsfp1_tx_pfc_en, qsfp0_tx_pfc_en}), + .mac_tx_pfc_req({qsfp1_tx_pfc_req, qsfp0_tx_pfc_req}), .mac_rx_clk({qsfp1_rx_clk, qsfp0_rx_clk}), .mac_rx_rst({qsfp1_rx_rst, qsfp0_rx_rst}), @@ -845,7 +890,14 @@ mqnic_port_map_mac_axis_inst ( .s_axis_mac_rx_tlast({qsfp1_rx_axis_tlast, qsfp0_rx_axis_tlast}), .s_axis_mac_rx_tuser({{qsfp1_rx_axis_tuser[80:1], 16'd0, qsfp1_rx_axis_tuser[0]}, {qsfp0_rx_axis_tuser[80:1], 16'd0, qsfp0_rx_axis_tuser[0]}}), + .mac_rx_enable({qsfp1_rx_enable, qsfp0_rx_enable}), .mac_rx_status({qsfp1_rx_status, qsfp0_rx_status}), + .mac_rx_lfc_en({qsfp1_rx_lfc_en, qsfp0_rx_lfc_en}), + .mac_rx_lfc_req({qsfp1_rx_lfc_req, qsfp0_rx_lfc_req}), + .mac_rx_lfc_ack({qsfp1_rx_lfc_ack, qsfp0_rx_lfc_ack}), + .mac_rx_pfc_en({qsfp1_rx_pfc_en, qsfp0_rx_pfc_en}), + .mac_rx_pfc_req({qsfp1_rx_pfc_req, qsfp0_rx_pfc_req}), + .mac_rx_pfc_ack({qsfp1_rx_pfc_ack, qsfp0_rx_pfc_ack}), // towards datapath .tx_clk(eth_tx_clk), @@ -868,7 +920,12 @@ mqnic_port_map_mac_axis_inst ( .m_axis_tx_ptp_ts_valid(axis_eth_tx_ptp_ts_valid), .m_axis_tx_ptp_ts_ready(axis_eth_tx_ptp_ts_ready), + .tx_enable(eth_tx_enable), .tx_status(eth_tx_status), + .tx_lfc_en(eth_tx_lfc_en), + .tx_lfc_req(eth_tx_lfc_req), + .tx_pfc_en(eth_tx_pfc_en), + .tx_pfc_req(eth_tx_pfc_req), .rx_clk(eth_rx_clk), .rx_rst(eth_rx_rst), @@ -885,7 +942,14 @@ mqnic_port_map_mac_axis_inst ( .m_axis_rx_tlast(axis_eth_rx_tlast), .m_axis_rx_tuser(axis_eth_rx_tuser), - .rx_status(eth_rx_status) + .rx_enable(eth_rx_enable), + .rx_status(eth_rx_status), + .rx_lfc_en(eth_rx_lfc_en), + .rx_lfc_req(eth_rx_lfc_req), + .rx_lfc_ack(eth_rx_lfc_ack), + .rx_pfc_en(eth_rx_pfc_en), + .rx_pfc_req(eth_rx_pfc_req), + .rx_pfc_ack(eth_rx_pfc_ack) ); mqnic_core_pcie_us #( @@ -955,6 +1019,9 @@ mqnic_core_pcie_us #( .TX_CHECKSUM_ENABLE(TX_CHECKSUM_ENABLE), .RX_HASH_ENABLE(RX_HASH_ENABLE), .RX_CHECKSUM_ENABLE(RX_CHECKSUM_ENABLE), + .PFC_ENABLE(PFC_ENABLE), + .LFC_ENABLE(LFC_ENABLE), + .MAC_CTRL_ENABLE(0), .TX_FIFO_DEPTH(TX_FIFO_DEPTH), .RX_FIFO_DEPTH(RX_FIFO_DEPTH), .MAX_TX_SIZE(MAX_TX_SIZE), @@ -1236,7 +1303,13 @@ core_inst ( .s_axis_eth_tx_cpl_valid(axis_eth_tx_ptp_ts_valid), .s_axis_eth_tx_cpl_ready(axis_eth_tx_ptp_ts_ready), + .eth_tx_enable(eth_tx_enable), .eth_tx_status(eth_tx_status), + .eth_tx_lfc_en(eth_tx_lfc_en), + .eth_tx_lfc_req(eth_tx_lfc_req), + .eth_tx_pfc_en(eth_tx_pfc_en), + .eth_tx_pfc_req(eth_tx_pfc_req), + .eth_tx_fc_quanta_clk_en(0), .eth_rx_clk(eth_rx_clk), .eth_rx_rst(eth_rx_rst), @@ -1253,7 +1326,15 @@ core_inst ( .s_axis_eth_rx_tlast(axis_eth_rx_tlast), .s_axis_eth_rx_tuser(axis_eth_rx_tuser), + .eth_rx_enable(eth_rx_enable), .eth_rx_status(eth_rx_status), + .eth_rx_lfc_en(eth_rx_lfc_en), + .eth_rx_lfc_req(eth_rx_lfc_req), + .eth_rx_lfc_ack(eth_rx_lfc_ack), + .eth_rx_pfc_en(eth_rx_pfc_en), + .eth_rx_pfc_req(eth_rx_pfc_req), + .eth_rx_pfc_ack(eth_rx_pfc_ack), + .eth_rx_fc_quanta_clk_en(0), /* * DDR diff --git a/fpga/mqnic/VCU1525/fpga_100g/tb/fpga_core/Makefile b/fpga/mqnic/VCU1525/fpga_100g/tb/fpga_core/Makefile index 67d20a951..e8de2d7d3 100644 --- a/fpga/mqnic/VCU1525/fpga_100g/tb/fpga_core/Makefile +++ b/fpga/mqnic/VCU1525/fpga_100g/tb/fpga_core/Makefile @@ -161,6 +161,8 @@ export PARAM_TX_CPL_FIFO_DEPTH := 32 export PARAM_TX_CHECKSUM_ENABLE := 1 export PARAM_RX_HASH_ENABLE := 1 export PARAM_RX_CHECKSUM_ENABLE := 1 +export PARAM_LFC_ENABLE := 1 +export PARAM_PFC_ENABLE := $(PARAM_LFC_ENABLE) export PARAM_TX_FIFO_DEPTH := 32768 export PARAM_RX_FIFO_DEPTH := 131072 export PARAM_MAX_TX_SIZE := 9214 diff --git a/fpga/mqnic/VCU1525/fpga_100g/tb/fpga_core/test_fpga_core.py b/fpga/mqnic/VCU1525/fpga_100g/tb/fpga_core/test_fpga_core.py index 405ba18b9..f5574158f 100644 --- a/fpga/mqnic/VCU1525/fpga_100g/tb/fpga_core/test_fpga_core.py +++ b/fpga/mqnic/VCU1525/fpga_100g/tb/fpga_core/test_fpga_core.py @@ -300,6 +300,8 @@ class TB(object): self.qsfp_mac.append(mac) getattr(dut, f"qsfp{k}_rx_status").setimmediatevalue(1) + getattr(dut, f"qsfp{k}_rx_lfc_req").setimmediatevalue(0) + getattr(dut, f"qsfp{k}_rx_pfc_req").setimmediatevalue(0) cocotb.start_soon(Clock(getattr(dut, f"qsfp{k}_drp_clk"), 8, units="ns").start()) getattr(dut, f"qsfp{k}_drp_rst").setimmediatevalue(0) @@ -307,7 +309,7 @@ class TB(object): getattr(dut, f"qsfp{k}_drp_rdy").setimmediatevalue(0) getattr(dut, f"qsfp{k}_modprsl").setimmediatevalue(0) - getattr(dut, f"qsfp{k}_intl").setimmediatevalue(0) + getattr(dut, f"qsfp{k}_intl").setimmediatevalue(1) dut.sw.setimmediatevalue(0) @@ -721,6 +723,8 @@ def test_fpga_core(request): parameters['TX_CHECKSUM_ENABLE'] = 1 parameters['RX_HASH_ENABLE'] = 1 parameters['RX_CHECKSUM_ENABLE'] = 1 + parameters['LFC_ENABLE'] = 1 + parameters['PFC_ENABLE'] = parameters['LFC_ENABLE'] parameters['TX_FIFO_DEPTH'] = 32768 parameters['RX_FIFO_DEPTH'] = 131072 parameters['MAX_TX_SIZE'] = 9214 diff --git a/fpga/mqnic/VCU1525/fpga_25g/fpga/Makefile b/fpga/mqnic/VCU1525/fpga_25g/fpga/Makefile index 67f27cf6f..01aea6547 100644 --- a/fpga/mqnic/VCU1525/fpga_25g/fpga/Makefile +++ b/fpga/mqnic/VCU1525/fpga_25g/fpga/Makefile @@ -62,6 +62,10 @@ SYN_FILES += rtl/common/tdma_ber_ch.v SYN_FILES += lib/eth/rtl/eth_mac_10g.v SYN_FILES += lib/eth/rtl/axis_xgmii_rx_64.v SYN_FILES += lib/eth/rtl/axis_xgmii_tx_64.v +SYN_FILES += lib/eth/rtl/mac_ctrl_rx.v +SYN_FILES += lib/eth/rtl/mac_ctrl_tx.v +SYN_FILES += lib/eth/rtl/mac_pause_ctrl_rx.v +SYN_FILES += lib/eth/rtl/mac_pause_ctrl_tx.v SYN_FILES += lib/eth/rtl/eth_phy_10g.v SYN_FILES += lib/eth/rtl/eth_phy_10g_rx.v SYN_FILES += lib/eth/rtl/eth_phy_10g_rx_if.v diff --git a/fpga/mqnic/VCU1525/fpga_25g/fpga/config.tcl b/fpga/mqnic/VCU1525/fpga_25g/fpga/config.tcl index 625e812ac..f150b330c 100644 --- a/fpga/mqnic/VCU1525/fpga_25g/fpga/config.tcl +++ b/fpga/mqnic/VCU1525/fpga_25g/fpga/config.tcl @@ -113,6 +113,8 @@ dict set params TX_CPL_FIFO_DEPTH "32" dict set params TX_CHECKSUM_ENABLE "1" dict set params RX_HASH_ENABLE "1" dict set params RX_CHECKSUM_ENABLE "1" +dict set params PFC_ENABLE "1" +dict set params LFC_ENABLE [dict get $params PFC_ENABLE] dict set params ENABLE_PADDING "1" dict set params ENABLE_DIC "1" dict set params MIN_FRAME_LENGTH "64" diff --git a/fpga/mqnic/VCU1525/fpga_25g/fpga_10g/Makefile b/fpga/mqnic/VCU1525/fpga_25g/fpga_10g/Makefile index 67f27cf6f..01aea6547 100644 --- a/fpga/mqnic/VCU1525/fpga_25g/fpga_10g/Makefile +++ b/fpga/mqnic/VCU1525/fpga_25g/fpga_10g/Makefile @@ -62,6 +62,10 @@ SYN_FILES += rtl/common/tdma_ber_ch.v SYN_FILES += lib/eth/rtl/eth_mac_10g.v SYN_FILES += lib/eth/rtl/axis_xgmii_rx_64.v SYN_FILES += lib/eth/rtl/axis_xgmii_tx_64.v +SYN_FILES += lib/eth/rtl/mac_ctrl_rx.v +SYN_FILES += lib/eth/rtl/mac_ctrl_tx.v +SYN_FILES += lib/eth/rtl/mac_pause_ctrl_rx.v +SYN_FILES += lib/eth/rtl/mac_pause_ctrl_tx.v SYN_FILES += lib/eth/rtl/eth_phy_10g.v SYN_FILES += lib/eth/rtl/eth_phy_10g_rx.v SYN_FILES += lib/eth/rtl/eth_phy_10g_rx_if.v diff --git a/fpga/mqnic/VCU1525/fpga_25g/fpga_10g/config.tcl b/fpga/mqnic/VCU1525/fpga_25g/fpga_10g/config.tcl index f30b4170c..f6ad5044f 100644 --- a/fpga/mqnic/VCU1525/fpga_25g/fpga_10g/config.tcl +++ b/fpga/mqnic/VCU1525/fpga_25g/fpga_10g/config.tcl @@ -113,6 +113,8 @@ dict set params TX_CPL_FIFO_DEPTH "32" dict set params TX_CHECKSUM_ENABLE "1" dict set params RX_HASH_ENABLE "1" dict set params RX_CHECKSUM_ENABLE "1" +dict set params PFC_ENABLE "1" +dict set params LFC_ENABLE [dict get $params PFC_ENABLE] dict set params ENABLE_PADDING "1" dict set params ENABLE_DIC "1" dict set params MIN_FRAME_LENGTH "64" diff --git a/fpga/mqnic/VCU1525/fpga_25g/rtl/fpga.v b/fpga/mqnic/VCU1525/fpga_25g/rtl/fpga.v index fba5b741e..7c54b7b31 100644 --- a/fpga/mqnic/VCU1525/fpga_25g/rtl/fpga.v +++ b/fpga/mqnic/VCU1525/fpga_25g/rtl/fpga.v @@ -74,6 +74,8 @@ module fpga # parameter TX_CHECKSUM_ENABLE = 1, parameter RX_HASH_ENABLE = 1, parameter RX_CHECKSUM_ENABLE = 1, + parameter PFC_ENABLE = 1, + parameter LFC_ENABLE = PFC_ENABLE, parameter ENABLE_PADDING = 1, parameter ENABLE_DIC = 1, parameter MIN_FRAME_LENGTH = 64, @@ -1982,6 +1984,8 @@ fpga_core #( .TX_CHECKSUM_ENABLE(TX_CHECKSUM_ENABLE), .RX_HASH_ENABLE(RX_HASH_ENABLE), .RX_CHECKSUM_ENABLE(RX_CHECKSUM_ENABLE), + .PFC_ENABLE(PFC_ENABLE), + .LFC_ENABLE(LFC_ENABLE), .ENABLE_PADDING(ENABLE_PADDING), .ENABLE_DIC(ENABLE_DIC), .MIN_FRAME_LENGTH(MIN_FRAME_LENGTH), diff --git a/fpga/mqnic/VCU1525/fpga_25g/rtl/fpga_core.v b/fpga/mqnic/VCU1525/fpga_25g/rtl/fpga_core.v index 4a884f91e..83473995e 100644 --- a/fpga/mqnic/VCU1525/fpga_25g/rtl/fpga_core.v +++ b/fpga/mqnic/VCU1525/fpga_25g/rtl/fpga_core.v @@ -81,6 +81,8 @@ module fpga_core # parameter TX_CHECKSUM_ENABLE = 1, parameter RX_HASH_ENABLE = 1, parameter RX_CHECKSUM_ENABLE = 1, + parameter PFC_ENABLE = 1, + parameter LFC_ENABLE = PFC_ENABLE, parameter ENABLE_PADDING = 1, parameter ENABLE_DIC = 1, parameter MIN_FRAME_LENGTH = 64, @@ -902,7 +904,12 @@ wire [PORT_COUNT*TX_TAG_WIDTH-1:0] axis_eth_tx_ptp_ts_tag; wire [PORT_COUNT-1:0] axis_eth_tx_ptp_ts_valid; wire [PORT_COUNT-1:0] axis_eth_tx_ptp_ts_ready; +wire [PORT_COUNT-1:0] eth_tx_enable; wire [PORT_COUNT-1:0] eth_tx_status; +wire [PORT_COUNT-1:0] eth_tx_lfc_en; +wire [PORT_COUNT-1:0] eth_tx_lfc_req; +wire [PORT_COUNT*8-1:0] eth_tx_pfc_en; +wire [PORT_COUNT*8-1:0] eth_tx_pfc_req; wire [PORT_COUNT-1:0] eth_rx_clk; wire [PORT_COUNT-1:0] eth_rx_rst; @@ -917,7 +924,14 @@ wire [PORT_COUNT-1:0] axis_eth_rx_tready; wire [PORT_COUNT-1:0] axis_eth_rx_tlast; wire [PORT_COUNT*AXIS_ETH_RX_USER_WIDTH-1:0] axis_eth_rx_tuser; +wire [PORT_COUNT-1:0] eth_rx_enable; wire [PORT_COUNT-1:0] eth_rx_status; +wire [PORT_COUNT-1:0] eth_rx_lfc_en; +wire [PORT_COUNT-1:0] eth_rx_lfc_req; +wire [PORT_COUNT-1:0] eth_rx_lfc_ack; +wire [PORT_COUNT*8-1:0] eth_rx_pfc_en; +wire [PORT_COUNT*8-1:0] eth_rx_pfc_req; +wire [PORT_COUNT*8-1:0] eth_rx_pfc_ack; wire [PORT_COUNT-1:0] port_xgmii_tx_clk; wire [PORT_COUNT-1:0] port_xgmii_tx_rst; @@ -990,12 +1004,15 @@ generate .PTP_PERIOD_FNS(IF_PTP_PERIOD_FNS), .TX_PTP_TS_ENABLE(PTP_TS_ENABLE), .TX_PTP_TS_WIDTH(PTP_TS_WIDTH), + .TX_PTP_TS_CTRL_IN_TUSER(0), .TX_PTP_TAG_ENABLE(PTP_TS_ENABLE), .TX_PTP_TAG_WIDTH(TX_TAG_WIDTH), .RX_PTP_TS_ENABLE(PTP_TS_ENABLE), .RX_PTP_TS_WIDTH(PTP_TS_WIDTH), .TX_USER_WIDTH(AXIS_ETH_TX_USER_WIDTH), - .RX_USER_WIDTH(AXIS_ETH_RX_USER_WIDTH) + .RX_USER_WIDTH(AXIS_ETH_RX_USER_WIDTH), + .PFC_ENABLE(PFC_ENABLE), + .PAUSE_ENABLE(LFC_ENABLE) ) eth_mac_inst ( .tx_clk(port_xgmii_tx_clk[n]), @@ -1003,6 +1020,9 @@ generate .rx_clk(port_xgmii_rx_clk[n]), .rx_rst(port_xgmii_rx_rst[n]), + /* + * AXI input + */ .tx_axis_tdata(axis_eth_tx_tdata[n*AXIS_ETH_DATA_WIDTH +: AXIS_ETH_DATA_WIDTH]), .tx_axis_tkeep(axis_eth_tx_tkeep[n*AXIS_ETH_KEEP_WIDTH +: AXIS_ETH_KEEP_WIDTH]), .tx_axis_tvalid(axis_eth_tx_tvalid[n +: 1]), @@ -1010,30 +1030,121 @@ generate .tx_axis_tlast(axis_eth_tx_tlast[n +: 1]), .tx_axis_tuser(axis_eth_tx_tuser[n*AXIS_ETH_TX_USER_WIDTH +: AXIS_ETH_TX_USER_WIDTH]), + /* + * AXI output + */ .rx_axis_tdata(axis_eth_rx_tdata[n*AXIS_ETH_DATA_WIDTH +: AXIS_ETH_DATA_WIDTH]), .rx_axis_tkeep(axis_eth_rx_tkeep[n*AXIS_ETH_KEEP_WIDTH +: AXIS_ETH_KEEP_WIDTH]), .rx_axis_tvalid(axis_eth_rx_tvalid[n +: 1]), .rx_axis_tlast(axis_eth_rx_tlast[n +: 1]), .rx_axis_tuser(axis_eth_rx_tuser[n*AXIS_ETH_RX_USER_WIDTH +: AXIS_ETH_RX_USER_WIDTH]), + /* + * XGMII interface + */ .xgmii_rxd(port_xgmii_rxd[n*XGMII_DATA_WIDTH +: XGMII_DATA_WIDTH]), .xgmii_rxc(port_xgmii_rxc[n*XGMII_CTRL_WIDTH +: XGMII_CTRL_WIDTH]), .xgmii_txd(port_xgmii_txd[n*XGMII_DATA_WIDTH +: XGMII_DATA_WIDTH]), .xgmii_txc(port_xgmii_txc[n*XGMII_CTRL_WIDTH +: XGMII_CTRL_WIDTH]), + /* + * PTP + */ .tx_ptp_ts(eth_tx_ptp_ts_96[n*PTP_TS_WIDTH +: PTP_TS_WIDTH]), .rx_ptp_ts(eth_rx_ptp_ts_96[n*PTP_TS_WIDTH +: PTP_TS_WIDTH]), .tx_axis_ptp_ts(axis_eth_tx_ptp_ts[n*PTP_TS_WIDTH +: PTP_TS_WIDTH]), .tx_axis_ptp_ts_tag(axis_eth_tx_ptp_ts_tag[n*TX_TAG_WIDTH +: TX_TAG_WIDTH]), .tx_axis_ptp_ts_valid(axis_eth_tx_ptp_ts_valid[n +: 1]), + /* + * Link-level Flow Control (LFC) (IEEE 802.3 annex 31B PAUSE) + */ + .tx_lfc_req(eth_tx_lfc_req[n +: 1]), + .tx_lfc_resend(1'b0), + .rx_lfc_en(eth_rx_lfc_en[n +: 1]), + .rx_lfc_req(eth_rx_lfc_req[n +: 1]), + .rx_lfc_ack(eth_rx_lfc_ack[n +: 1]), + + /* + * Priority Flow Control (PFC) (IEEE 802.3 annex 31D PFC) + */ + .tx_pfc_req(eth_tx_pfc_req[n*8 +: 8]), + .tx_pfc_resend(1'b0), + .rx_pfc_en(eth_rx_pfc_en[n*8 +: 8]), + .rx_pfc_req(eth_rx_pfc_req[n*8 +: 8]), + .rx_pfc_ack(eth_rx_pfc_ack[n*8 +: 8]), + + /* + * Pause interface + */ + .tx_lfc_pause_en(1'b1), + .tx_pause_req(1'b0), + .tx_pause_ack(), + + /* + * Status + */ + .tx_start_packet(), .tx_error_underflow(), + .rx_start_packet(), .rx_error_bad_frame(), .rx_error_bad_fcs(), + .stat_tx_mcf(), + .stat_rx_mcf(), + .stat_tx_lfc_pkt(), + .stat_tx_lfc_xon(), + .stat_tx_lfc_xoff(), + .stat_tx_lfc_paused(), + .stat_tx_pfc_pkt(), + .stat_tx_pfc_xon(), + .stat_tx_pfc_xoff(), + .stat_tx_pfc_paused(), + .stat_rx_lfc_pkt(), + .stat_rx_lfc_xon(), + .stat_rx_lfc_xoff(), + .stat_rx_lfc_paused(), + .stat_rx_pfc_pkt(), + .stat_rx_pfc_xon(), + .stat_rx_pfc_xoff(), + .stat_rx_pfc_paused(), + /* + * Configuration + */ .cfg_ifg(8'd12), - .cfg_tx_enable(1'b1), - .cfg_rx_enable(1'b1) + .cfg_tx_enable(eth_tx_enable[n +: 1]), + .cfg_rx_enable(eth_rx_enable[n +: 1]), + .cfg_mcf_rx_eth_dst_mcast(48'h01_80_C2_00_00_01), + .cfg_mcf_rx_check_eth_dst_mcast(1'b1), + .cfg_mcf_rx_eth_dst_ucast(48'd0), + .cfg_mcf_rx_check_eth_dst_ucast(1'b0), + .cfg_mcf_rx_eth_src(48'd0), + .cfg_mcf_rx_check_eth_src(1'b0), + .cfg_mcf_rx_eth_type(16'h8808), + .cfg_mcf_rx_opcode_lfc(16'h0001), + .cfg_mcf_rx_check_opcode_lfc(eth_rx_lfc_en[n +: 1]), + .cfg_mcf_rx_opcode_pfc(16'h0101), + .cfg_mcf_rx_check_opcode_pfc(eth_rx_pfc_en[n*8 +: 8] != 0), + .cfg_mcf_rx_forward(1'b0), + .cfg_mcf_rx_enable(eth_rx_lfc_en[n +: 1] || eth_rx_pfc_en[n*8 +: 8]), + .cfg_tx_lfc_eth_dst(48'h01_80_C2_00_00_01), + .cfg_tx_lfc_eth_src(48'h80_23_31_43_54_4C), + .cfg_tx_lfc_eth_type(16'h8808), + .cfg_tx_lfc_opcode(16'h0001), + .cfg_tx_lfc_en(eth_tx_lfc_en[n +: 1]), + .cfg_tx_lfc_quanta(16'hffff), + .cfg_tx_lfc_refresh(16'h7fff), + .cfg_tx_pfc_eth_dst(48'h01_80_C2_00_00_01), + .cfg_tx_pfc_eth_src(48'h80_23_31_43_54_4C), + .cfg_tx_pfc_eth_type(16'h8808), + .cfg_tx_pfc_opcode(16'h0101), + .cfg_tx_pfc_en(eth_tx_pfc_en[n*8 +: 8] != 0), + .cfg_tx_pfc_quanta({8{16'hffff}}), + .cfg_tx_pfc_refresh({8{16'h7fff}}), + .cfg_rx_lfc_opcode(16'h0001), + .cfg_rx_lfc_en(eth_rx_lfc_en[n +: 1]), + .cfg_rx_pfc_opcode(16'h0101), + .cfg_rx_pfc_en(eth_rx_pfc_en[n*8 +: 8] != 0) ); end @@ -1107,6 +1218,9 @@ mqnic_core_pcie_us #( .TX_CHECKSUM_ENABLE(TX_CHECKSUM_ENABLE), .RX_HASH_ENABLE(RX_HASH_ENABLE), .RX_CHECKSUM_ENABLE(RX_CHECKSUM_ENABLE), + .PFC_ENABLE(PFC_ENABLE), + .LFC_ENABLE(LFC_ENABLE), + .MAC_CTRL_ENABLE(0), .TX_FIFO_DEPTH(TX_FIFO_DEPTH), .RX_FIFO_DEPTH(RX_FIFO_DEPTH), .MAX_TX_SIZE(MAX_TX_SIZE), @@ -1388,7 +1502,13 @@ core_inst ( .s_axis_eth_tx_cpl_valid(axis_eth_tx_ptp_ts_valid), .s_axis_eth_tx_cpl_ready(axis_eth_tx_ptp_ts_ready), + .eth_tx_enable(eth_tx_enable), .eth_tx_status(eth_tx_status), + .eth_tx_lfc_en(eth_tx_lfc_en), + .eth_tx_lfc_req(eth_tx_lfc_req), + .eth_tx_pfc_en(eth_tx_pfc_en), + .eth_tx_pfc_req(eth_tx_pfc_req), + .eth_tx_fc_quanta_clk_en(0), .eth_rx_clk(eth_rx_clk), .eth_rx_rst(eth_rx_rst), @@ -1405,7 +1525,15 @@ core_inst ( .s_axis_eth_rx_tlast(axis_eth_rx_tlast), .s_axis_eth_rx_tuser(axis_eth_rx_tuser), + .eth_rx_enable(eth_rx_enable), .eth_rx_status(eth_rx_status), + .eth_rx_lfc_en(eth_rx_lfc_en), + .eth_rx_lfc_req(eth_rx_lfc_req), + .eth_rx_lfc_ack(eth_rx_lfc_ack), + .eth_rx_pfc_en(eth_rx_pfc_en), + .eth_rx_pfc_req(eth_rx_pfc_req), + .eth_rx_pfc_ack(eth_rx_pfc_ack), + .eth_rx_fc_quanta_clk_en(0), /* * DDR diff --git a/fpga/mqnic/VCU1525/fpga_25g/tb/fpga_core/Makefile b/fpga/mqnic/VCU1525/fpga_25g/tb/fpga_core/Makefile index d9702a197..78a21e1ad 100644 --- a/fpga/mqnic/VCU1525/fpga_25g/tb/fpga_core/Makefile +++ b/fpga/mqnic/VCU1525/fpga_25g/tb/fpga_core/Makefile @@ -62,6 +62,10 @@ VERILOG_SOURCES += ../../rtl/common/tdma_ber_ch.v VERILOG_SOURCES += ../../lib/eth/rtl/eth_mac_10g.v VERILOG_SOURCES += ../../lib/eth/rtl/axis_xgmii_rx_64.v VERILOG_SOURCES += ../../lib/eth/rtl/axis_xgmii_tx_64.v +VERILOG_SOURCES += ../../lib/eth/rtl/mac_ctrl_rx.v +VERILOG_SOURCES += ../../lib/eth/rtl/mac_ctrl_tx.v +VERILOG_SOURCES += ../../lib/eth/rtl/mac_pause_ctrl_rx.v +VERILOG_SOURCES += ../../lib/eth/rtl/mac_pause_ctrl_tx.v VERILOG_SOURCES += ../../lib/eth/rtl/lfsr.v VERILOG_SOURCES += ../../lib/eth/rtl/ptp_clock.v VERILOG_SOURCES += ../../lib/eth/rtl/ptp_clock_cdc.v @@ -167,6 +171,8 @@ export PARAM_TX_CPL_FIFO_DEPTH := 32 export PARAM_TX_CHECKSUM_ENABLE := 1 export PARAM_RX_HASH_ENABLE := 1 export PARAM_RX_CHECKSUM_ENABLE := 1 +export PARAM_LFC_ENABLE := 1 +export PARAM_PFC_ENABLE := $(PARAM_LFC_ENABLE) export PARAM_TX_FIFO_DEPTH := 32768 export PARAM_RX_FIFO_DEPTH := 32768 export PARAM_MAX_TX_SIZE := 9214 diff --git a/fpga/mqnic/VCU1525/fpga_25g/tb/fpga_core/test_fpga_core.py b/fpga/mqnic/VCU1525/fpga_25g/tb/fpga_core/test_fpga_core.py index 0c699ae0a..3b69cf287 100644 --- a/fpga/mqnic/VCU1525/fpga_25g/tb/fpga_core/test_fpga_core.py +++ b/fpga/mqnic/VCU1525/fpga_25g/tb/fpga_core/test_fpga_core.py @@ -3,6 +3,7 @@ import logging import os +import struct import sys import scapy.utils @@ -17,7 +18,7 @@ from cocotb.clock import Clock from cocotb.triggers import RisingEdge, FallingEdge, Timer from cocotbext.axi import AxiStreamBus -from cocotbext.eth import XgmiiSource, XgmiiSink +from cocotbext.eth import XgmiiSource, XgmiiSink, XgmiiFrame from cocotbext.pcie.core import RootComplex from cocotbext.pcie.xilinx.us import UltraScalePlusPcieDevice @@ -526,6 +527,35 @@ async def run_test_nic(dut): tb.loopback_enable = False + if tb.driver.interfaces[0].if_feature_lfc: + tb.log.info("Test LFC pause frame RX") + + await tb.driver.interfaces[0].ports[0].set_lfc_ctrl(mqnic.MQNIC_PORT_LFC_CTRL_TX_LFC_EN | mqnic.MQNIC_PORT_LFC_CTRL_RX_LFC_EN) + await tb.driver.hw_regs.read_dword(0) + + lfc_xoff = Ether(src='DA:D1:D2:D3:D4:D5', dst='01:80:C2:00:00:01', type=0x8808) / struct.pack('!HH', 0x0001, 2000) + + await tb.qsfp_source[0][0].send(XgmiiFrame.from_payload(bytes(lfc_xoff))) + + count = 16 + + pkts = [bytearray([(x+k) % 256 for x in range(1514)]) for k in range(count)] + + tb.loopback_enable = True + + for p in pkts: + await tb.driver.interfaces[0].start_xmit(p, 0) + + for k in range(count): + pkt = await tb.driver.interfaces[0].recv() + + tb.log.info("Packet: %s", pkt) + assert pkt.data == pkts[k] + if tb.driver.interfaces[0].if_feature_rx_csum: + assert pkt.rx_checksum == ~scapy.utils.checksum(bytes(pkt.data[14:])) & 0xffff + + tb.loopback_enable = False + await RisingEdge(dut.clk_250mhz) await RisingEdge(dut.clk_250mhz) @@ -598,6 +628,10 @@ def test_fpga_core(request): os.path.join(eth_rtl_dir, "eth_mac_10g.v"), os.path.join(eth_rtl_dir, "axis_xgmii_rx_64.v"), os.path.join(eth_rtl_dir, "axis_xgmii_tx_64.v"), + os.path.join(eth_rtl_dir, "mac_ctrl_rx.v"), + os.path.join(eth_rtl_dir, "mac_ctrl_tx.v"), + os.path.join(eth_rtl_dir, "mac_pause_ctrl_rx.v"), + os.path.join(eth_rtl_dir, "mac_pause_ctrl_tx.v"), os.path.join(eth_rtl_dir, "lfsr.v"), os.path.join(eth_rtl_dir, "ptp_clock.v"), os.path.join(eth_rtl_dir, "ptp_clock_cdc.v"), @@ -704,6 +738,8 @@ def test_fpga_core(request): parameters['TX_CHECKSUM_ENABLE'] = 1 parameters['RX_HASH_ENABLE'] = 1 parameters['RX_CHECKSUM_ENABLE'] = 1 + parameters['LFC_ENABLE'] = 1 + parameters['PFC_ENABLE'] = parameters['LFC_ENABLE'] parameters['TX_FIFO_DEPTH'] = 32768 parameters['RX_FIFO_DEPTH'] = 32768 parameters['MAX_TX_SIZE'] = 9214 diff --git a/fpga/mqnic/XUPP3R/fpga_100g/fpga/config.tcl b/fpga/mqnic/XUPP3R/fpga_100g/fpga/config.tcl index 341eb1d12..447529ec1 100644 --- a/fpga/mqnic/XUPP3R/fpga_100g/fpga/config.tcl +++ b/fpga/mqnic/XUPP3R/fpga_100g/fpga/config.tcl @@ -101,6 +101,8 @@ dict set params TX_CPL_FIFO_DEPTH "32" dict set params TX_CHECKSUM_ENABLE "1" dict set params RX_HASH_ENABLE "1" dict set params RX_CHECKSUM_ENABLE "1" +dict set params PFC_ENABLE "1" +dict set params LFC_ENABLE [dict get $params PFC_ENABLE] dict set params TX_FIFO_DEPTH "32768" dict set params RX_FIFO_DEPTH "131072" dict set params MAX_TX_SIZE "9214" diff --git a/fpga/mqnic/XUPP3R/fpga_100g/fpga_app_dma_bench/config.tcl b/fpga/mqnic/XUPP3R/fpga_100g/fpga_app_dma_bench/config.tcl index a6c0a3ba9..f0a3fb8e3 100644 --- a/fpga/mqnic/XUPP3R/fpga_100g/fpga_app_dma_bench/config.tcl +++ b/fpga/mqnic/XUPP3R/fpga_100g/fpga_app_dma_bench/config.tcl @@ -101,6 +101,8 @@ dict set params TX_CPL_FIFO_DEPTH "32" dict set params TX_CHECKSUM_ENABLE "1" dict set params RX_HASH_ENABLE "1" dict set params RX_CHECKSUM_ENABLE "1" +dict set params PFC_ENABLE "1" +dict set params LFC_ENABLE [dict get $params PFC_ENABLE] dict set params TX_FIFO_DEPTH "32768" dict set params RX_FIFO_DEPTH "131072" dict set params MAX_TX_SIZE "9214" diff --git a/fpga/mqnic/XUPP3R/fpga_100g/ip/cmac_usplus.tcl b/fpga/mqnic/XUPP3R/fpga_100g/ip/cmac_usplus.tcl index b86d4ea5e..af9cc8265 100644 --- a/fpga/mqnic/XUPP3R/fpga_100g/ip/cmac_usplus.tcl +++ b/fpga/mqnic/XUPP3R/fpga_100g/ip/cmac_usplus.tcl @@ -7,8 +7,10 @@ set_property -dict [list \ CONFIG.USER_INTERFACE {AXIS} \ CONFIG.GT_DRP_CLK {125} \ CONFIG.GT_LOCATION {0} \ - CONFIG.TX_FLOW_CONTROL {0} \ - CONFIG.RX_FLOW_CONTROL {0} \ + CONFIG.TX_FLOW_CONTROL {1} \ + CONFIG.RX_FLOW_CONTROL {1} \ + CONFIG.RX_FORWARD_CONTROL_FRAMES {0} \ + CONFIG.RX_CHECK_ACK {1} \ CONFIG.INCLUDE_RS_FEC {1} \ CONFIG.ENABLE_TIME_STAMPING {1} ] [get_ips cmac_usplus] diff --git a/fpga/mqnic/XUPP3R/fpga_100g/rtl/fpga.v b/fpga/mqnic/XUPP3R/fpga_100g/rtl/fpga.v index 89f2b3ec2..a7537ddd5 100644 --- a/fpga/mqnic/XUPP3R/fpga_100g/rtl/fpga.v +++ b/fpga/mqnic/XUPP3R/fpga_100g/rtl/fpga.v @@ -71,6 +71,8 @@ module fpga # parameter TX_CHECKSUM_ENABLE = 1, parameter RX_HASH_ENABLE = 1, parameter RX_CHECKSUM_ENABLE = 1, + parameter PFC_ENABLE = 1, + parameter LFC_ENABLE = PFC_ENABLE, parameter TX_FIFO_DEPTH = 32768, parameter RX_FIFO_DEPTH = 131072, parameter MAX_TX_SIZE = 9214, @@ -1046,7 +1048,20 @@ wire qsfp0_drp_we; wire [15:0] qsfp0_drp_do; wire qsfp0_drp_rdy; -wire qsfp0_rx_status; +wire qsfp0_tx_enable; +wire qsfp0_tx_lfc_en; +wire qsfp0_tx_lfc_req; +wire [7:0] qsfp0_tx_pfc_en; +wire [7:0] qsfp0_tx_pfc_req; + +wire qsfp0_rx_enable; +wire qsfp0_rx_status; +wire qsfp0_rx_lfc_en; +wire qsfp0_rx_lfc_req; +wire qsfp0_rx_lfc_ack; +wire [7:0] qsfp0_rx_pfc_en; +wire [7:0] qsfp0_rx_pfc_req; +wire [7:0] qsfp0_rx_pfc_ack; wire qsfp0_gtpowergood; @@ -1139,6 +1154,12 @@ qsfp0_cmac_inst ( .tx_ptp_ts_tag(qsfp0_tx_ptp_ts_tag_int), .tx_ptp_ts_valid(qsfp0_tx_ptp_ts_valid_int), + .tx_enable(qsfp0_tx_enable), + .tx_lfc_en(qsfp0_tx_lfc_en), + .tx_lfc_req(qsfp0_tx_lfc_req), + .tx_pfc_en(qsfp0_tx_pfc_en), + .tx_pfc_req(qsfp0_tx_pfc_req), + .rx_clk(qsfp0_rx_clk_int), .rx_rst(qsfp0_rx_rst_int), @@ -1152,7 +1173,14 @@ qsfp0_cmac_inst ( .rx_ptp_rst(qsfp0_rx_ptp_rst_int), .rx_ptp_time(qsfp0_rx_ptp_time_int), - .rx_status(qsfp0_rx_status) + .rx_enable(qsfp0_rx_enable), + .rx_status(qsfp0_rx_status), + .rx_lfc_en(qsfp0_rx_lfc_en), + .rx_lfc_req(qsfp0_rx_lfc_req), + .rx_lfc_ack(qsfp0_rx_lfc_ack), + .rx_pfc_en(qsfp0_rx_pfc_en), + .rx_pfc_req(qsfp0_rx_pfc_req), + .rx_pfc_ack(qsfp0_rx_pfc_ack) ); // QSFP1 CMAC @@ -1193,7 +1221,20 @@ wire qsfp1_drp_we; wire [15:0] qsfp1_drp_do; wire qsfp1_drp_rdy; -wire qsfp1_rx_status; +wire qsfp1_tx_enable; +wire qsfp1_tx_lfc_en; +wire qsfp1_tx_lfc_req; +wire [7:0] qsfp1_tx_pfc_en; +wire [7:0] qsfp1_tx_pfc_req; + +wire qsfp1_rx_enable; +wire qsfp1_rx_status; +wire qsfp1_rx_lfc_en; +wire qsfp1_rx_lfc_req; +wire qsfp1_rx_lfc_ack; +wire [7:0] qsfp1_rx_pfc_en; +wire [7:0] qsfp1_rx_pfc_req; +wire [7:0] qsfp1_rx_pfc_ack; wire qsfp1_gtpowergood; @@ -1286,6 +1327,12 @@ qsfp1_cmac_inst ( .tx_ptp_ts_tag(qsfp1_tx_ptp_ts_tag_int), .tx_ptp_ts_valid(qsfp1_tx_ptp_ts_valid_int), + .tx_enable(qsfp1_tx_enable), + .tx_lfc_en(qsfp1_tx_lfc_en), + .tx_lfc_req(qsfp1_tx_lfc_req), + .tx_pfc_en(qsfp1_tx_pfc_en), + .tx_pfc_req(qsfp1_tx_pfc_req), + .rx_clk(qsfp1_rx_clk_int), .rx_rst(qsfp1_rx_rst_int), @@ -1299,7 +1346,14 @@ qsfp1_cmac_inst ( .rx_ptp_rst(qsfp1_rx_ptp_rst_int), .rx_ptp_time(qsfp1_rx_ptp_time_int), - .rx_status(qsfp1_rx_status) + .rx_enable(qsfp1_rx_enable), + .rx_status(qsfp1_rx_status), + .rx_lfc_en(qsfp1_rx_lfc_en), + .rx_lfc_req(qsfp1_rx_lfc_req), + .rx_lfc_ack(qsfp1_rx_lfc_ack), + .rx_pfc_en(qsfp1_rx_pfc_en), + .rx_pfc_req(qsfp1_rx_pfc_req), + .rx_pfc_ack(qsfp1_rx_pfc_ack) ); // QSFP2 CMAC @@ -1340,7 +1394,20 @@ wire qsfp2_drp_we; wire [15:0] qsfp2_drp_do; wire qsfp2_drp_rdy; -wire qsfp2_rx_status; +wire qsfp2_tx_enable; +wire qsfp2_tx_lfc_en; +wire qsfp2_tx_lfc_req; +wire [7:0] qsfp2_tx_pfc_en; +wire [7:0] qsfp2_tx_pfc_req; + +wire qsfp2_rx_enable; +wire qsfp2_rx_status; +wire qsfp2_rx_lfc_en; +wire qsfp2_rx_lfc_req; +wire qsfp2_rx_lfc_ack; +wire [7:0] qsfp2_rx_pfc_en; +wire [7:0] qsfp2_rx_pfc_req; +wire [7:0] qsfp2_rx_pfc_ack; wire qsfp2_gtpowergood; @@ -1433,6 +1500,12 @@ qsfp2_cmac_inst ( .tx_ptp_ts_tag(qsfp2_tx_ptp_ts_tag_int), .tx_ptp_ts_valid(qsfp2_tx_ptp_ts_valid_int), + .tx_enable(qsfp2_tx_enable), + .tx_lfc_en(qsfp2_tx_lfc_en), + .tx_lfc_req(qsfp2_tx_lfc_req), + .tx_pfc_en(qsfp2_tx_pfc_en), + .tx_pfc_req(qsfp2_tx_pfc_req), + .rx_clk(qsfp2_rx_clk_int), .rx_rst(qsfp2_rx_rst_int), @@ -1446,7 +1519,14 @@ qsfp2_cmac_inst ( .rx_ptp_rst(qsfp2_rx_ptp_rst_int), .rx_ptp_time(qsfp2_rx_ptp_time_int), - .rx_status(qsfp2_rx_status) + .rx_enable(qsfp2_rx_enable), + .rx_status(qsfp2_rx_status), + .rx_lfc_en(qsfp2_rx_lfc_en), + .rx_lfc_req(qsfp2_rx_lfc_req), + .rx_lfc_ack(qsfp2_rx_lfc_ack), + .rx_pfc_en(qsfp2_rx_pfc_en), + .rx_pfc_req(qsfp2_rx_pfc_req), + .rx_pfc_ack(qsfp2_rx_pfc_ack) ); // QSFP3 CMAC @@ -1487,7 +1567,20 @@ wire qsfp3_drp_we; wire [15:0] qsfp3_drp_do; wire qsfp3_drp_rdy; -wire qsfp3_rx_status; +wire qsfp3_tx_enable; +wire qsfp3_tx_lfc_en; +wire qsfp3_tx_lfc_req; +wire [7:0] qsfp3_tx_pfc_en; +wire [7:0] qsfp3_tx_pfc_req; + +wire qsfp3_rx_enable; +wire qsfp3_rx_status; +wire qsfp3_rx_lfc_en; +wire qsfp3_rx_lfc_req; +wire qsfp3_rx_lfc_ack; +wire [7:0] qsfp3_rx_pfc_en; +wire [7:0] qsfp3_rx_pfc_req; +wire [7:0] qsfp3_rx_pfc_ack; wire qsfp3_gtpowergood; @@ -1580,6 +1673,12 @@ qsfp3_cmac_inst ( .tx_ptp_ts_tag(qsfp3_tx_ptp_ts_tag_int), .tx_ptp_ts_valid(qsfp3_tx_ptp_ts_valid_int), + .tx_enable(qsfp3_tx_enable), + .tx_lfc_en(qsfp3_tx_lfc_en), + .tx_lfc_req(qsfp3_tx_lfc_req), + .tx_pfc_en(qsfp3_tx_pfc_en), + .tx_pfc_req(qsfp3_tx_pfc_req), + .rx_clk(qsfp3_rx_clk_int), .rx_rst(qsfp3_rx_rst_int), @@ -1593,7 +1692,14 @@ qsfp3_cmac_inst ( .rx_ptp_rst(qsfp3_rx_ptp_rst_int), .rx_ptp_time(qsfp3_rx_ptp_time_int), - .rx_status(qsfp3_rx_status) + .rx_enable(qsfp3_rx_enable), + .rx_status(qsfp3_rx_status), + .rx_lfc_en(qsfp3_rx_lfc_en), + .rx_lfc_req(qsfp3_rx_lfc_req), + .rx_lfc_ack(qsfp3_rx_lfc_ack), + .rx_pfc_en(qsfp3_rx_pfc_en), + .rx_pfc_req(qsfp3_rx_pfc_req), + .rx_pfc_ack(qsfp3_rx_pfc_ack) ); wire ptp_clk; @@ -2228,6 +2334,8 @@ fpga_core #( .TX_CHECKSUM_ENABLE(TX_CHECKSUM_ENABLE), .RX_HASH_ENABLE(RX_HASH_ENABLE), .RX_CHECKSUM_ENABLE(RX_CHECKSUM_ENABLE), + .PFC_ENABLE(PFC_ENABLE), + .LFC_ENABLE(LFC_ENABLE), .TX_FIFO_DEPTH(TX_FIFO_DEPTH), .RX_FIFO_DEPTH(RX_FIFO_DEPTH), .MAX_TX_SIZE(MAX_TX_SIZE), @@ -2433,6 +2541,12 @@ core_inst ( .qsfp0_tx_ptp_ts_tag(qsfp0_tx_ptp_ts_tag_int), .qsfp0_tx_ptp_ts_valid(qsfp0_tx_ptp_ts_valid_int), + .qsfp0_tx_enable(qsfp0_tx_enable), + .qsfp0_tx_lfc_en(qsfp0_tx_lfc_en), + .qsfp0_tx_lfc_req(qsfp0_tx_lfc_req), + .qsfp0_tx_pfc_en(qsfp0_tx_pfc_en), + .qsfp0_tx_pfc_req(qsfp0_tx_pfc_req), + .qsfp0_rx_clk(qsfp0_rx_clk_int), .qsfp0_rx_rst(qsfp0_rx_rst_int), .qsfp0_rx_axis_tdata(qsfp0_rx_axis_tdata_int), @@ -2444,7 +2558,14 @@ core_inst ( .qsfp0_rx_ptp_rst(qsfp0_rx_ptp_rst_int), .qsfp0_rx_ptp_time(qsfp0_rx_ptp_time_int), + .qsfp0_rx_enable(qsfp0_rx_enable), .qsfp0_rx_status(qsfp0_rx_status), + .qsfp0_rx_lfc_en(qsfp0_rx_lfc_en), + .qsfp0_rx_lfc_req(qsfp0_rx_lfc_req), + .qsfp0_rx_lfc_ack(qsfp0_rx_lfc_ack), + .qsfp0_rx_pfc_en(qsfp0_rx_pfc_en), + .qsfp0_rx_pfc_req(qsfp0_rx_pfc_req), + .qsfp0_rx_pfc_ack(qsfp0_rx_pfc_ack), .qsfp0_drp_clk(qsfp0_drp_clk), .qsfp0_drp_rst(qsfp0_drp_rst), @@ -2480,6 +2601,12 @@ core_inst ( .qsfp1_tx_ptp_ts_tag(qsfp1_tx_ptp_ts_tag_int), .qsfp1_tx_ptp_ts_valid(qsfp1_tx_ptp_ts_valid_int), + .qsfp1_tx_enable(qsfp1_tx_enable), + .qsfp1_tx_lfc_en(qsfp1_tx_lfc_en), + .qsfp1_tx_lfc_req(qsfp1_tx_lfc_req), + .qsfp1_tx_pfc_en(qsfp1_tx_pfc_en), + .qsfp1_tx_pfc_req(qsfp1_tx_pfc_req), + .qsfp1_rx_clk(qsfp1_rx_clk_int), .qsfp1_rx_rst(qsfp1_rx_rst_int), .qsfp1_rx_axis_tdata(qsfp1_rx_axis_tdata_int), @@ -2491,7 +2618,14 @@ core_inst ( .qsfp1_rx_ptp_rst(qsfp1_rx_ptp_rst_int), .qsfp1_rx_ptp_time(qsfp1_rx_ptp_time_int), + .qsfp1_rx_enable(qsfp1_rx_enable), .qsfp1_rx_status(qsfp1_rx_status), + .qsfp1_rx_lfc_en(qsfp1_rx_lfc_en), + .qsfp1_rx_lfc_req(qsfp1_rx_lfc_req), + .qsfp1_rx_lfc_ack(qsfp1_rx_lfc_ack), + .qsfp1_rx_pfc_en(qsfp1_rx_pfc_en), + .qsfp1_rx_pfc_req(qsfp1_rx_pfc_req), + .qsfp1_rx_pfc_ack(qsfp1_rx_pfc_ack), .qsfp1_drp_clk(qsfp1_drp_clk), .qsfp1_drp_rst(qsfp1_drp_rst), @@ -2527,6 +2661,12 @@ core_inst ( .qsfp2_tx_ptp_ts_tag(qsfp2_tx_ptp_ts_tag_int), .qsfp2_tx_ptp_ts_valid(qsfp2_tx_ptp_ts_valid_int), + .qsfp2_tx_enable(qsfp2_tx_enable), + .qsfp2_tx_lfc_en(qsfp2_tx_lfc_en), + .qsfp2_tx_lfc_req(qsfp2_tx_lfc_req), + .qsfp2_tx_pfc_en(qsfp2_tx_pfc_en), + .qsfp2_tx_pfc_req(qsfp2_tx_pfc_req), + .qsfp2_rx_clk(qsfp2_rx_clk_int), .qsfp2_rx_rst(qsfp2_rx_rst_int), .qsfp2_rx_axis_tdata(qsfp2_rx_axis_tdata_int), @@ -2538,7 +2678,14 @@ core_inst ( .qsfp2_rx_ptp_rst(qsfp2_rx_ptp_rst_int), .qsfp2_rx_ptp_time(qsfp2_rx_ptp_time_int), + .qsfp2_rx_enable(qsfp2_rx_enable), .qsfp2_rx_status(qsfp2_rx_status), + .qsfp2_rx_lfc_en(qsfp2_rx_lfc_en), + .qsfp2_rx_lfc_req(qsfp2_rx_lfc_req), + .qsfp2_rx_lfc_ack(qsfp2_rx_lfc_ack), + .qsfp2_rx_pfc_en(qsfp2_rx_pfc_en), + .qsfp2_rx_pfc_req(qsfp2_rx_pfc_req), + .qsfp2_rx_pfc_ack(qsfp2_rx_pfc_ack), .qsfp2_drp_clk(qsfp2_drp_clk), .qsfp2_drp_rst(qsfp2_drp_rst), @@ -2574,6 +2721,12 @@ core_inst ( .qsfp3_tx_ptp_ts_tag(qsfp3_tx_ptp_ts_tag_int), .qsfp3_tx_ptp_ts_valid(qsfp3_tx_ptp_ts_valid_int), + .qsfp3_tx_enable(qsfp3_tx_enable), + .qsfp3_tx_lfc_en(qsfp3_tx_lfc_en), + .qsfp3_tx_lfc_req(qsfp3_tx_lfc_req), + .qsfp3_tx_pfc_en(qsfp3_tx_pfc_en), + .qsfp3_tx_pfc_req(qsfp3_tx_pfc_req), + .qsfp3_rx_clk(qsfp3_rx_clk_int), .qsfp3_rx_rst(qsfp3_rx_rst_int), .qsfp3_rx_axis_tdata(qsfp3_rx_axis_tdata_int), @@ -2585,7 +2738,14 @@ core_inst ( .qsfp3_rx_ptp_rst(qsfp3_rx_ptp_rst_int), .qsfp3_rx_ptp_time(qsfp3_rx_ptp_time_int), + .qsfp3_rx_enable(qsfp3_rx_enable), .qsfp3_rx_status(qsfp3_rx_status), + .qsfp3_rx_lfc_en(qsfp3_rx_lfc_en), + .qsfp3_rx_lfc_req(qsfp3_rx_lfc_req), + .qsfp3_rx_lfc_ack(qsfp3_rx_lfc_ack), + .qsfp3_rx_pfc_en(qsfp3_rx_pfc_en), + .qsfp3_rx_pfc_req(qsfp3_rx_pfc_req), + .qsfp3_rx_pfc_ack(qsfp3_rx_pfc_ack), .qsfp3_drp_clk(qsfp3_drp_clk), .qsfp3_drp_rst(qsfp3_drp_rst), diff --git a/fpga/mqnic/XUPP3R/fpga_100g/rtl/fpga_core.v b/fpga/mqnic/XUPP3R/fpga_100g/rtl/fpga_core.v index b2e786d5b..cbe280aa7 100644 --- a/fpga/mqnic/XUPP3R/fpga_100g/rtl/fpga_core.v +++ b/fpga/mqnic/XUPP3R/fpga_100g/rtl/fpga_core.v @@ -77,6 +77,8 @@ module fpga_core # parameter TX_CHECKSUM_ENABLE = 1, parameter RX_HASH_ENABLE = 1, parameter RX_CHECKSUM_ENABLE = 1, + parameter PFC_ENABLE = 1, + parameter LFC_ENABLE = PFC_ENABLE, parameter TX_FIFO_DEPTH = 32768, parameter RX_FIFO_DEPTH = 131072, parameter MAX_TX_SIZE = 9214, @@ -284,6 +286,12 @@ module fpga_core # input wire [15:0] qsfp0_tx_ptp_ts_tag, input wire qsfp0_tx_ptp_ts_valid, + output wire qsfp0_tx_enable, + output wire qsfp0_tx_lfc_en, + output wire qsfp0_tx_lfc_req, + output wire [7:0] qsfp0_tx_pfc_en, + output wire [7:0] qsfp0_tx_pfc_req, + input wire qsfp0_rx_clk, input wire qsfp0_rx_rst, @@ -297,7 +305,14 @@ module fpga_core # input wire qsfp0_rx_ptp_rst, output wire [79:0] qsfp0_rx_ptp_time, + output wire qsfp0_rx_enable, input wire qsfp0_rx_status, + output wire qsfp0_rx_lfc_en, + input wire qsfp0_rx_lfc_req, + output wire qsfp0_rx_lfc_ack, + output wire [7:0] qsfp0_rx_pfc_en, + input wire [7:0] qsfp0_rx_pfc_req, + output wire [7:0] qsfp0_rx_pfc_ack, input wire qsfp0_drp_clk, input wire qsfp0_drp_rst, @@ -335,6 +350,12 @@ module fpga_core # input wire [15:0] qsfp1_tx_ptp_ts_tag, input wire qsfp1_tx_ptp_ts_valid, + output wire qsfp1_tx_enable, + output wire qsfp1_tx_lfc_en, + output wire qsfp1_tx_lfc_req, + output wire [7:0] qsfp1_tx_pfc_en, + output wire [7:0] qsfp1_tx_pfc_req, + input wire qsfp1_rx_clk, input wire qsfp1_rx_rst, @@ -348,7 +369,14 @@ module fpga_core # input wire qsfp1_rx_ptp_rst, output wire [79:0] qsfp1_rx_ptp_time, + output wire qsfp1_rx_enable, input wire qsfp1_rx_status, + output wire qsfp1_rx_lfc_en, + input wire qsfp1_rx_lfc_req, + output wire qsfp1_rx_lfc_ack, + output wire [7:0] qsfp1_rx_pfc_en, + input wire [7:0] qsfp1_rx_pfc_req, + output wire [7:0] qsfp1_rx_pfc_ack, input wire qsfp1_drp_clk, input wire qsfp1_drp_rst, @@ -386,6 +414,12 @@ module fpga_core # input wire [15:0] qsfp2_tx_ptp_ts_tag, input wire qsfp2_tx_ptp_ts_valid, + output wire qsfp2_tx_enable, + output wire qsfp2_tx_lfc_en, + output wire qsfp2_tx_lfc_req, + output wire [7:0] qsfp2_tx_pfc_en, + output wire [7:0] qsfp2_tx_pfc_req, + input wire qsfp2_rx_clk, input wire qsfp2_rx_rst, @@ -399,7 +433,14 @@ module fpga_core # input wire qsfp2_rx_ptp_rst, output wire [79:0] qsfp2_rx_ptp_time, + output wire qsfp2_rx_enable, input wire qsfp2_rx_status, + output wire qsfp2_rx_lfc_en, + input wire qsfp2_rx_lfc_req, + output wire qsfp2_rx_lfc_ack, + output wire [7:0] qsfp2_rx_pfc_en, + input wire [7:0] qsfp2_rx_pfc_req, + output wire [7:0] qsfp2_rx_pfc_ack, input wire qsfp2_drp_clk, input wire qsfp2_drp_rst, @@ -437,6 +478,12 @@ module fpga_core # input wire [15:0] qsfp3_tx_ptp_ts_tag, input wire qsfp3_tx_ptp_ts_valid, + output wire qsfp3_tx_enable, + output wire qsfp3_tx_lfc_en, + output wire qsfp3_tx_lfc_req, + output wire [7:0] qsfp3_tx_pfc_en, + output wire [7:0] qsfp3_tx_pfc_req, + input wire qsfp3_rx_clk, input wire qsfp3_rx_rst, @@ -450,7 +497,14 @@ module fpga_core # input wire qsfp3_rx_ptp_rst, output wire [79:0] qsfp3_rx_ptp_time, + output wire qsfp3_rx_enable, input wire qsfp3_rx_status, + output wire qsfp3_rx_lfc_en, + input wire qsfp3_rx_lfc_req, + output wire qsfp3_rx_lfc_ack, + output wire [7:0] qsfp3_rx_pfc_en, + input wire [7:0] qsfp3_rx_pfc_req, + output wire [7:0] qsfp3_rx_pfc_ack, input wire qsfp3_drp_clk, input wire qsfp3_drp_rst, @@ -1126,7 +1180,12 @@ wire [PORT_COUNT*TX_TAG_WIDTH-1:0] axis_eth_tx_ptp_ts_tag; wire [PORT_COUNT-1:0] axis_eth_tx_ptp_ts_valid; wire [PORT_COUNT-1:0] axis_eth_tx_ptp_ts_ready; +wire [PORT_COUNT-1:0] eth_tx_enable; wire [PORT_COUNT-1:0] eth_tx_status; +wire [PORT_COUNT-1:0] eth_tx_lfc_en; +wire [PORT_COUNT-1:0] eth_tx_lfc_req; +wire [PORT_COUNT*8-1:0] eth_tx_pfc_en; +wire [PORT_COUNT*8-1:0] eth_tx_pfc_req; wire [PORT_COUNT-1:0] eth_rx_clk; wire [PORT_COUNT-1:0] eth_rx_rst; @@ -1143,7 +1202,14 @@ wire [PORT_COUNT-1:0] axis_eth_rx_tready; wire [PORT_COUNT-1:0] axis_eth_rx_tlast; wire [PORT_COUNT*AXIS_ETH_RX_USER_WIDTH-1:0] axis_eth_rx_tuser; +wire [PORT_COUNT-1:0] eth_rx_enable; wire [PORT_COUNT-1:0] eth_rx_status; +wire [PORT_COUNT-1:0] eth_rx_lfc_en; +wire [PORT_COUNT-1:0] eth_rx_lfc_req; +wire [PORT_COUNT-1:0] eth_rx_lfc_ack; +wire [PORT_COUNT*8-1:0] eth_rx_pfc_en; +wire [PORT_COUNT*8-1:0] eth_rx_pfc_req; +wire [PORT_COUNT*8-1:0] eth_rx_pfc_ack; wire [PTP_TS_WIDTH-1:0] qsfp0_tx_ptp_time_int; wire [PTP_TS_WIDTH-1:0] qsfp1_tx_ptp_time_int; @@ -1202,7 +1268,12 @@ mqnic_port_map_mac_axis_inst ( .s_axis_mac_tx_ptp_ts_valid({qsfp3_tx_ptp_ts_valid, qsfp2_tx_ptp_ts_valid, qsfp1_tx_ptp_ts_valid, qsfp0_tx_ptp_ts_valid}), .s_axis_mac_tx_ptp_ts_ready(), + .mac_tx_enable({qsfp3_tx_enable, qsfp2_tx_enable, qsfp1_tx_enable, qsfp0_tx_enable}), .mac_tx_status(4'b1111), + .mac_tx_lfc_en({qsfp3_tx_lfc_en, qsfp2_tx_lfc_en, qsfp1_tx_lfc_en, qsfp0_tx_lfc_en}), + .mac_tx_lfc_req({qsfp3_tx_lfc_req, qsfp2_tx_lfc_req, qsfp1_tx_lfc_req, qsfp0_tx_lfc_req}), + .mac_tx_pfc_en({qsfp3_tx_pfc_en, qsfp2_tx_pfc_en, qsfp1_tx_pfc_en, qsfp0_tx_pfc_en}), + .mac_tx_pfc_req({qsfp3_tx_pfc_req, qsfp2_tx_pfc_req, qsfp1_tx_pfc_req, qsfp0_tx_pfc_req}), .mac_rx_clk({qsfp3_rx_clk, qsfp2_rx_clk, qsfp1_rx_clk, qsfp0_rx_clk}), .mac_rx_rst({qsfp3_rx_rst, qsfp2_rx_rst, qsfp1_rx_rst, qsfp0_rx_rst}), @@ -1219,7 +1290,14 @@ mqnic_port_map_mac_axis_inst ( .s_axis_mac_rx_tlast({qsfp3_rx_axis_tlast, qsfp2_rx_axis_tlast, qsfp1_rx_axis_tlast, qsfp0_rx_axis_tlast}), .s_axis_mac_rx_tuser({{qsfp3_rx_axis_tuser[80:1], 16'd0, qsfp3_rx_axis_tuser[0]}, {qsfp2_rx_axis_tuser[80:1], 16'd0, qsfp2_rx_axis_tuser[0]}, {qsfp1_rx_axis_tuser[80:1], 16'd0, qsfp1_rx_axis_tuser[0]}, {qsfp0_rx_axis_tuser[80:1], 16'd0, qsfp0_rx_axis_tuser[0]}}), + .mac_rx_enable({qsfp3_rx_enable, qsfp2_rx_enable, qsfp1_rx_enable, qsfp0_rx_enable}), .mac_rx_status({qsfp3_rx_status, qsfp2_rx_status, qsfp1_rx_status, qsfp0_rx_status}), + .mac_rx_lfc_en({qsfp3_rx_lfc_en, qsfp2_rx_lfc_en, qsfp1_rx_lfc_en, qsfp0_rx_lfc_en}), + .mac_rx_lfc_req({qsfp3_rx_lfc_req, qsfp2_rx_lfc_req, qsfp1_rx_lfc_req, qsfp0_rx_lfc_req}), + .mac_rx_lfc_ack({qsfp3_rx_lfc_ack, qsfp2_rx_lfc_ack, qsfp1_rx_lfc_ack, qsfp0_rx_lfc_ack}), + .mac_rx_pfc_en({qsfp3_rx_pfc_en, qsfp2_rx_pfc_en, qsfp1_rx_pfc_en, qsfp0_rx_pfc_en}), + .mac_rx_pfc_req({qsfp3_rx_pfc_req, qsfp2_rx_pfc_req, qsfp1_rx_pfc_req, qsfp0_rx_pfc_req}), + .mac_rx_pfc_ack({qsfp3_rx_pfc_ack, qsfp2_rx_pfc_ack, qsfp1_rx_pfc_ack, qsfp0_rx_pfc_ack}), // towards datapath .tx_clk(eth_tx_clk), @@ -1242,7 +1320,12 @@ mqnic_port_map_mac_axis_inst ( .m_axis_tx_ptp_ts_valid(axis_eth_tx_ptp_ts_valid), .m_axis_tx_ptp_ts_ready(axis_eth_tx_ptp_ts_ready), + .tx_enable(eth_tx_enable), .tx_status(eth_tx_status), + .tx_lfc_en(eth_tx_lfc_en), + .tx_lfc_req(eth_tx_lfc_req), + .tx_pfc_en(eth_tx_pfc_en), + .tx_pfc_req(eth_tx_pfc_req), .rx_clk(eth_rx_clk), .rx_rst(eth_rx_rst), @@ -1259,7 +1342,14 @@ mqnic_port_map_mac_axis_inst ( .m_axis_rx_tlast(axis_eth_rx_tlast), .m_axis_rx_tuser(axis_eth_rx_tuser), - .rx_status(eth_rx_status) + .rx_enable(eth_rx_enable), + .rx_status(eth_rx_status), + .rx_lfc_en(eth_rx_lfc_en), + .rx_lfc_req(eth_rx_lfc_req), + .rx_lfc_ack(eth_rx_lfc_ack), + .rx_pfc_en(eth_rx_pfc_en), + .rx_pfc_req(eth_rx_pfc_req), + .rx_pfc_ack(eth_rx_pfc_ack) ); mqnic_core_pcie_us #( @@ -1329,6 +1419,9 @@ mqnic_core_pcie_us #( .TX_CHECKSUM_ENABLE(TX_CHECKSUM_ENABLE), .RX_HASH_ENABLE(RX_HASH_ENABLE), .RX_CHECKSUM_ENABLE(RX_CHECKSUM_ENABLE), + .PFC_ENABLE(PFC_ENABLE), + .LFC_ENABLE(LFC_ENABLE), + .MAC_CTRL_ENABLE(0), .TX_FIFO_DEPTH(TX_FIFO_DEPTH), .RX_FIFO_DEPTH(RX_FIFO_DEPTH), .MAX_TX_SIZE(MAX_TX_SIZE), @@ -1610,7 +1703,13 @@ core_inst ( .s_axis_eth_tx_cpl_valid(axis_eth_tx_ptp_ts_valid), .s_axis_eth_tx_cpl_ready(axis_eth_tx_ptp_ts_ready), + .eth_tx_enable(eth_tx_enable), .eth_tx_status(eth_tx_status), + .eth_tx_lfc_en(eth_tx_lfc_en), + .eth_tx_lfc_req(eth_tx_lfc_req), + .eth_tx_pfc_en(eth_tx_pfc_en), + .eth_tx_pfc_req(eth_tx_pfc_req), + .eth_tx_fc_quanta_clk_en(0), .eth_rx_clk(eth_rx_clk), .eth_rx_rst(eth_rx_rst), @@ -1627,7 +1726,15 @@ core_inst ( .s_axis_eth_rx_tlast(axis_eth_rx_tlast), .s_axis_eth_rx_tuser(axis_eth_rx_tuser), + .eth_rx_enable(eth_rx_enable), .eth_rx_status(eth_rx_status), + .eth_rx_lfc_en(eth_rx_lfc_en), + .eth_rx_lfc_req(eth_rx_lfc_req), + .eth_rx_lfc_ack(eth_rx_lfc_ack), + .eth_rx_pfc_en(eth_rx_pfc_en), + .eth_rx_pfc_req(eth_rx_pfc_req), + .eth_rx_pfc_ack(eth_rx_pfc_ack), + .eth_rx_fc_quanta_clk_en(0), /* * DDR diff --git a/fpga/mqnic/XUPP3R/fpga_100g/tb/fpga_core/Makefile b/fpga/mqnic/XUPP3R/fpga_100g/tb/fpga_core/Makefile index 97a3d1229..b4d38b6b1 100644 --- a/fpga/mqnic/XUPP3R/fpga_100g/tb/fpga_core/Makefile +++ b/fpga/mqnic/XUPP3R/fpga_100g/tb/fpga_core/Makefile @@ -161,6 +161,8 @@ export PARAM_TX_CPL_FIFO_DEPTH := 32 export PARAM_TX_CHECKSUM_ENABLE := 1 export PARAM_RX_HASH_ENABLE := 1 export PARAM_RX_CHECKSUM_ENABLE := 1 +export PARAM_LFC_ENABLE := 1 +export PARAM_PFC_ENABLE := $(PARAM_LFC_ENABLE) export PARAM_TX_FIFO_DEPTH := 32768 export PARAM_RX_FIFO_DEPTH := 131072 export PARAM_MAX_TX_SIZE := 9214 diff --git a/fpga/mqnic/XUPP3R/fpga_100g/tb/fpga_core/test_fpga_core.py b/fpga/mqnic/XUPP3R/fpga_100g/tb/fpga_core/test_fpga_core.py index bb5f49167..e483ab9ba 100644 --- a/fpga/mqnic/XUPP3R/fpga_100g/tb/fpga_core/test_fpga_core.py +++ b/fpga/mqnic/XUPP3R/fpga_100g/tb/fpga_core/test_fpga_core.py @@ -307,7 +307,7 @@ class TB(object): getattr(dut, f"qsfp{k}_drp_rdy").setimmediatevalue(0) getattr(dut, f"qsfp{k}_modprsl").setimmediatevalue(0) - getattr(dut, f"qsfp{k}_intl").setimmediatevalue(0) + getattr(dut, f"qsfp{k}_intl").setimmediatevalue(1) getattr(dut, f"qsfp{k}_i2c_scl_i").setimmediatevalue(1) getattr(dut, f"qsfp{k}_i2c_sda_i").setimmediatevalue(1) @@ -725,6 +725,8 @@ def test_fpga_core(request): parameters['TX_CHECKSUM_ENABLE'] = 1 parameters['RX_HASH_ENABLE'] = 1 parameters['RX_CHECKSUM_ENABLE'] = 1 + parameters['LFC_ENABLE'] = 1 + parameters['PFC_ENABLE'] = parameters['LFC_ENABLE'] parameters['TX_FIFO_DEPTH'] = 32768 parameters['RX_FIFO_DEPTH'] = 131072 parameters['MAX_TX_SIZE'] = 9214 diff --git a/fpga/mqnic/XUPP3R/fpga_25g/fpga/Makefile b/fpga/mqnic/XUPP3R/fpga_25g/fpga/Makefile index 762553f7d..b01a601ba 100644 --- a/fpga/mqnic/XUPP3R/fpga_25g/fpga/Makefile +++ b/fpga/mqnic/XUPP3R/fpga_25g/fpga/Makefile @@ -61,6 +61,10 @@ SYN_FILES += rtl/common/tdma_ber_ch.v SYN_FILES += lib/eth/rtl/eth_mac_10g.v SYN_FILES += lib/eth/rtl/axis_xgmii_rx_64.v SYN_FILES += lib/eth/rtl/axis_xgmii_tx_64.v +SYN_FILES += lib/eth/rtl/mac_ctrl_rx.v +SYN_FILES += lib/eth/rtl/mac_ctrl_tx.v +SYN_FILES += lib/eth/rtl/mac_pause_ctrl_rx.v +SYN_FILES += lib/eth/rtl/mac_pause_ctrl_tx.v SYN_FILES += lib/eth/rtl/eth_phy_10g.v SYN_FILES += lib/eth/rtl/eth_phy_10g_rx.v SYN_FILES += lib/eth/rtl/eth_phy_10g_rx_if.v diff --git a/fpga/mqnic/XUPP3R/fpga_25g/fpga/config.tcl b/fpga/mqnic/XUPP3R/fpga_25g/fpga/config.tcl index 3166cf115..fec8e36f1 100644 --- a/fpga/mqnic/XUPP3R/fpga_25g/fpga/config.tcl +++ b/fpga/mqnic/XUPP3R/fpga_25g/fpga/config.tcl @@ -113,6 +113,8 @@ dict set params TX_CPL_FIFO_DEPTH "32" dict set params TX_CHECKSUM_ENABLE "1" dict set params RX_HASH_ENABLE "1" dict set params RX_CHECKSUM_ENABLE "1" +dict set params PFC_ENABLE "1" +dict set params LFC_ENABLE [dict get $params PFC_ENABLE] dict set params ENABLE_PADDING "1" dict set params ENABLE_DIC "1" dict set params MIN_FRAME_LENGTH "64" diff --git a/fpga/mqnic/XUPP3R/fpga_25g/fpga_10g/Makefile b/fpga/mqnic/XUPP3R/fpga_25g/fpga_10g/Makefile index 762553f7d..b01a601ba 100644 --- a/fpga/mqnic/XUPP3R/fpga_25g/fpga_10g/Makefile +++ b/fpga/mqnic/XUPP3R/fpga_25g/fpga_10g/Makefile @@ -61,6 +61,10 @@ SYN_FILES += rtl/common/tdma_ber_ch.v SYN_FILES += lib/eth/rtl/eth_mac_10g.v SYN_FILES += lib/eth/rtl/axis_xgmii_rx_64.v SYN_FILES += lib/eth/rtl/axis_xgmii_tx_64.v +SYN_FILES += lib/eth/rtl/mac_ctrl_rx.v +SYN_FILES += lib/eth/rtl/mac_ctrl_tx.v +SYN_FILES += lib/eth/rtl/mac_pause_ctrl_rx.v +SYN_FILES += lib/eth/rtl/mac_pause_ctrl_tx.v SYN_FILES += lib/eth/rtl/eth_phy_10g.v SYN_FILES += lib/eth/rtl/eth_phy_10g_rx.v SYN_FILES += lib/eth/rtl/eth_phy_10g_rx_if.v diff --git a/fpga/mqnic/XUPP3R/fpga_25g/fpga_10g/config.tcl b/fpga/mqnic/XUPP3R/fpga_25g/fpga_10g/config.tcl index 8c8c03903..861c4424c 100644 --- a/fpga/mqnic/XUPP3R/fpga_25g/fpga_10g/config.tcl +++ b/fpga/mqnic/XUPP3R/fpga_25g/fpga_10g/config.tcl @@ -113,6 +113,8 @@ dict set params TX_CPL_FIFO_DEPTH "32" dict set params TX_CHECKSUM_ENABLE "1" dict set params RX_HASH_ENABLE "1" dict set params RX_CHECKSUM_ENABLE "1" +dict set params PFC_ENABLE "1" +dict set params LFC_ENABLE [dict get $params PFC_ENABLE] dict set params ENABLE_PADDING "1" dict set params ENABLE_DIC "1" dict set params MIN_FRAME_LENGTH "64" diff --git a/fpga/mqnic/XUPP3R/fpga_25g/rtl/fpga.v b/fpga/mqnic/XUPP3R/fpga_25g/rtl/fpga.v index d36819099..122e99c31 100644 --- a/fpga/mqnic/XUPP3R/fpga_25g/rtl/fpga.v +++ b/fpga/mqnic/XUPP3R/fpga_25g/rtl/fpga.v @@ -74,6 +74,8 @@ module fpga # parameter TX_CHECKSUM_ENABLE = 1, parameter RX_HASH_ENABLE = 1, parameter RX_CHECKSUM_ENABLE = 1, + parameter PFC_ENABLE = 1, + parameter LFC_ENABLE = PFC_ENABLE, parameter ENABLE_PADDING = 1, parameter ENABLE_DIC = 1, parameter MIN_FRAME_LENGTH = 64, @@ -2491,6 +2493,8 @@ fpga_core #( .TX_CHECKSUM_ENABLE(TX_CHECKSUM_ENABLE), .RX_HASH_ENABLE(RX_HASH_ENABLE), .RX_CHECKSUM_ENABLE(RX_CHECKSUM_ENABLE), + .PFC_ENABLE(PFC_ENABLE), + .LFC_ENABLE(LFC_ENABLE), .ENABLE_PADDING(ENABLE_PADDING), .ENABLE_DIC(ENABLE_DIC), .MIN_FRAME_LENGTH(MIN_FRAME_LENGTH), diff --git a/fpga/mqnic/XUPP3R/fpga_25g/rtl/fpga_core.v b/fpga/mqnic/XUPP3R/fpga_25g/rtl/fpga_core.v index 40c8c7d99..d9c7b9da2 100644 --- a/fpga/mqnic/XUPP3R/fpga_25g/rtl/fpga_core.v +++ b/fpga/mqnic/XUPP3R/fpga_25g/rtl/fpga_core.v @@ -81,6 +81,8 @@ module fpga_core # parameter TX_CHECKSUM_ENABLE = 1, parameter RX_HASH_ENABLE = 1, parameter RX_CHECKSUM_ENABLE = 1, + parameter PFC_ENABLE = 1, + parameter LFC_ENABLE = PFC_ENABLE, parameter ENABLE_PADDING = 1, parameter ENABLE_DIC = 1, parameter MIN_FRAME_LENGTH = 64, @@ -1322,7 +1324,12 @@ wire [PORT_COUNT*TX_TAG_WIDTH-1:0] axis_eth_tx_ptp_ts_tag; wire [PORT_COUNT-1:0] axis_eth_tx_ptp_ts_valid; wire [PORT_COUNT-1:0] axis_eth_tx_ptp_ts_ready; +wire [PORT_COUNT-1:0] eth_tx_enable; wire [PORT_COUNT-1:0] eth_tx_status; +wire [PORT_COUNT-1:0] eth_tx_lfc_en; +wire [PORT_COUNT-1:0] eth_tx_lfc_req; +wire [PORT_COUNT*8-1:0] eth_tx_pfc_en; +wire [PORT_COUNT*8-1:0] eth_tx_pfc_req; wire [PORT_COUNT-1:0] eth_rx_clk; wire [PORT_COUNT-1:0] eth_rx_rst; @@ -1337,7 +1344,14 @@ wire [PORT_COUNT-1:0] axis_eth_rx_tready; wire [PORT_COUNT-1:0] axis_eth_rx_tlast; wire [PORT_COUNT*AXIS_ETH_RX_USER_WIDTH-1:0] axis_eth_rx_tuser; +wire [PORT_COUNT-1:0] eth_rx_enable; wire [PORT_COUNT-1:0] eth_rx_status; +wire [PORT_COUNT-1:0] eth_rx_lfc_en; +wire [PORT_COUNT-1:0] eth_rx_lfc_req; +wire [PORT_COUNT-1:0] eth_rx_lfc_ack; +wire [PORT_COUNT*8-1:0] eth_rx_pfc_en; +wire [PORT_COUNT*8-1:0] eth_rx_pfc_req; +wire [PORT_COUNT*8-1:0] eth_rx_pfc_ack; wire [PORT_COUNT-1:0] port_xgmii_tx_clk; wire [PORT_COUNT-1:0] port_xgmii_tx_rst; @@ -1410,12 +1424,15 @@ generate .PTP_PERIOD_FNS(IF_PTP_PERIOD_FNS), .TX_PTP_TS_ENABLE(PTP_TS_ENABLE), .TX_PTP_TS_WIDTH(PTP_TS_WIDTH), + .TX_PTP_TS_CTRL_IN_TUSER(0), .TX_PTP_TAG_ENABLE(PTP_TS_ENABLE), .TX_PTP_TAG_WIDTH(TX_TAG_WIDTH), .RX_PTP_TS_ENABLE(PTP_TS_ENABLE), .RX_PTP_TS_WIDTH(PTP_TS_WIDTH), .TX_USER_WIDTH(AXIS_ETH_TX_USER_WIDTH), - .RX_USER_WIDTH(AXIS_ETH_RX_USER_WIDTH) + .RX_USER_WIDTH(AXIS_ETH_RX_USER_WIDTH), + .PFC_ENABLE(PFC_ENABLE), + .PAUSE_ENABLE(LFC_ENABLE) ) eth_mac_inst ( .tx_clk(port_xgmii_tx_clk[n]), @@ -1423,6 +1440,9 @@ generate .rx_clk(port_xgmii_rx_clk[n]), .rx_rst(port_xgmii_rx_rst[n]), + /* + * AXI input + */ .tx_axis_tdata(axis_eth_tx_tdata[n*AXIS_ETH_DATA_WIDTH +: AXIS_ETH_DATA_WIDTH]), .tx_axis_tkeep(axis_eth_tx_tkeep[n*AXIS_ETH_KEEP_WIDTH +: AXIS_ETH_KEEP_WIDTH]), .tx_axis_tvalid(axis_eth_tx_tvalid[n +: 1]), @@ -1430,30 +1450,121 @@ generate .tx_axis_tlast(axis_eth_tx_tlast[n +: 1]), .tx_axis_tuser(axis_eth_tx_tuser[n*AXIS_ETH_TX_USER_WIDTH +: AXIS_ETH_TX_USER_WIDTH]), + /* + * AXI output + */ .rx_axis_tdata(axis_eth_rx_tdata[n*AXIS_ETH_DATA_WIDTH +: AXIS_ETH_DATA_WIDTH]), .rx_axis_tkeep(axis_eth_rx_tkeep[n*AXIS_ETH_KEEP_WIDTH +: AXIS_ETH_KEEP_WIDTH]), .rx_axis_tvalid(axis_eth_rx_tvalid[n +: 1]), .rx_axis_tlast(axis_eth_rx_tlast[n +: 1]), .rx_axis_tuser(axis_eth_rx_tuser[n*AXIS_ETH_RX_USER_WIDTH +: AXIS_ETH_RX_USER_WIDTH]), + /* + * XGMII interface + */ .xgmii_rxd(port_xgmii_rxd[n*XGMII_DATA_WIDTH +: XGMII_DATA_WIDTH]), .xgmii_rxc(port_xgmii_rxc[n*XGMII_CTRL_WIDTH +: XGMII_CTRL_WIDTH]), .xgmii_txd(port_xgmii_txd[n*XGMII_DATA_WIDTH +: XGMII_DATA_WIDTH]), .xgmii_txc(port_xgmii_txc[n*XGMII_CTRL_WIDTH +: XGMII_CTRL_WIDTH]), + /* + * PTP + */ .tx_ptp_ts(eth_tx_ptp_ts_96[n*PTP_TS_WIDTH +: PTP_TS_WIDTH]), .rx_ptp_ts(eth_rx_ptp_ts_96[n*PTP_TS_WIDTH +: PTP_TS_WIDTH]), .tx_axis_ptp_ts(axis_eth_tx_ptp_ts[n*PTP_TS_WIDTH +: PTP_TS_WIDTH]), .tx_axis_ptp_ts_tag(axis_eth_tx_ptp_ts_tag[n*TX_TAG_WIDTH +: TX_TAG_WIDTH]), .tx_axis_ptp_ts_valid(axis_eth_tx_ptp_ts_valid[n +: 1]), + /* + * Link-level Flow Control (LFC) (IEEE 802.3 annex 31B PAUSE) + */ + .tx_lfc_req(eth_tx_lfc_req[n +: 1]), + .tx_lfc_resend(1'b0), + .rx_lfc_en(eth_rx_lfc_en[n +: 1]), + .rx_lfc_req(eth_rx_lfc_req[n +: 1]), + .rx_lfc_ack(eth_rx_lfc_ack[n +: 1]), + + /* + * Priority Flow Control (PFC) (IEEE 802.3 annex 31D PFC) + */ + .tx_pfc_req(eth_tx_pfc_req[n*8 +: 8]), + .tx_pfc_resend(1'b0), + .rx_pfc_en(eth_rx_pfc_en[n*8 +: 8]), + .rx_pfc_req(eth_rx_pfc_req[n*8 +: 8]), + .rx_pfc_ack(eth_rx_pfc_ack[n*8 +: 8]), + + /* + * Pause interface + */ + .tx_lfc_pause_en(1'b1), + .tx_pause_req(1'b0), + .tx_pause_ack(), + + /* + * Status + */ + .tx_start_packet(), .tx_error_underflow(), + .rx_start_packet(), .rx_error_bad_frame(), .rx_error_bad_fcs(), + .stat_tx_mcf(), + .stat_rx_mcf(), + .stat_tx_lfc_pkt(), + .stat_tx_lfc_xon(), + .stat_tx_lfc_xoff(), + .stat_tx_lfc_paused(), + .stat_tx_pfc_pkt(), + .stat_tx_pfc_xon(), + .stat_tx_pfc_xoff(), + .stat_tx_pfc_paused(), + .stat_rx_lfc_pkt(), + .stat_rx_lfc_xon(), + .stat_rx_lfc_xoff(), + .stat_rx_lfc_paused(), + .stat_rx_pfc_pkt(), + .stat_rx_pfc_xon(), + .stat_rx_pfc_xoff(), + .stat_rx_pfc_paused(), + /* + * Configuration + */ .cfg_ifg(8'd12), - .cfg_tx_enable(1'b1), - .cfg_rx_enable(1'b1) + .cfg_tx_enable(eth_tx_enable[n +: 1]), + .cfg_rx_enable(eth_rx_enable[n +: 1]), + .cfg_mcf_rx_eth_dst_mcast(48'h01_80_C2_00_00_01), + .cfg_mcf_rx_check_eth_dst_mcast(1'b1), + .cfg_mcf_rx_eth_dst_ucast(48'd0), + .cfg_mcf_rx_check_eth_dst_ucast(1'b0), + .cfg_mcf_rx_eth_src(48'd0), + .cfg_mcf_rx_check_eth_src(1'b0), + .cfg_mcf_rx_eth_type(16'h8808), + .cfg_mcf_rx_opcode_lfc(16'h0001), + .cfg_mcf_rx_check_opcode_lfc(eth_rx_lfc_en[n +: 1]), + .cfg_mcf_rx_opcode_pfc(16'h0101), + .cfg_mcf_rx_check_opcode_pfc(eth_rx_pfc_en[n*8 +: 8] != 0), + .cfg_mcf_rx_forward(1'b0), + .cfg_mcf_rx_enable(eth_rx_lfc_en[n +: 1] || eth_rx_pfc_en[n*8 +: 8]), + .cfg_tx_lfc_eth_dst(48'h01_80_C2_00_00_01), + .cfg_tx_lfc_eth_src(48'h80_23_31_43_54_4C), + .cfg_tx_lfc_eth_type(16'h8808), + .cfg_tx_lfc_opcode(16'h0001), + .cfg_tx_lfc_en(eth_tx_lfc_en[n +: 1]), + .cfg_tx_lfc_quanta(16'hffff), + .cfg_tx_lfc_refresh(16'h7fff), + .cfg_tx_pfc_eth_dst(48'h01_80_C2_00_00_01), + .cfg_tx_pfc_eth_src(48'h80_23_31_43_54_4C), + .cfg_tx_pfc_eth_type(16'h8808), + .cfg_tx_pfc_opcode(16'h0101), + .cfg_tx_pfc_en(eth_tx_pfc_en[n*8 +: 8] != 0), + .cfg_tx_pfc_quanta({8{16'hffff}}), + .cfg_tx_pfc_refresh({8{16'h7fff}}), + .cfg_rx_lfc_opcode(16'h0001), + .cfg_rx_lfc_en(eth_rx_lfc_en[n +: 1]), + .cfg_rx_pfc_opcode(16'h0101), + .cfg_rx_pfc_en(eth_rx_pfc_en[n*8 +: 8] != 0) ); end @@ -1527,6 +1638,9 @@ mqnic_core_pcie_us #( .TX_CHECKSUM_ENABLE(TX_CHECKSUM_ENABLE), .RX_HASH_ENABLE(RX_HASH_ENABLE), .RX_CHECKSUM_ENABLE(RX_CHECKSUM_ENABLE), + .PFC_ENABLE(PFC_ENABLE), + .LFC_ENABLE(LFC_ENABLE), + .MAC_CTRL_ENABLE(0), .TX_FIFO_DEPTH(TX_FIFO_DEPTH), .RX_FIFO_DEPTH(RX_FIFO_DEPTH), .MAX_TX_SIZE(MAX_TX_SIZE), @@ -1808,7 +1922,13 @@ core_inst ( .s_axis_eth_tx_cpl_valid(axis_eth_tx_ptp_ts_valid), .s_axis_eth_tx_cpl_ready(axis_eth_tx_ptp_ts_ready), + .eth_tx_enable(eth_tx_enable), .eth_tx_status(eth_tx_status), + .eth_tx_lfc_en(eth_tx_lfc_en), + .eth_tx_lfc_req(eth_tx_lfc_req), + .eth_tx_pfc_en(eth_tx_pfc_en), + .eth_tx_pfc_req(eth_tx_pfc_req), + .eth_tx_fc_quanta_clk_en(0), .eth_rx_clk(eth_rx_clk), .eth_rx_rst(eth_rx_rst), @@ -1825,7 +1945,15 @@ core_inst ( .s_axis_eth_rx_tlast(axis_eth_rx_tlast), .s_axis_eth_rx_tuser(axis_eth_rx_tuser), + .eth_rx_enable(eth_rx_enable), .eth_rx_status(eth_rx_status), + .eth_rx_lfc_en(eth_rx_lfc_en), + .eth_rx_lfc_req(eth_rx_lfc_req), + .eth_rx_lfc_ack(eth_rx_lfc_ack), + .eth_rx_pfc_en(eth_rx_pfc_en), + .eth_rx_pfc_req(eth_rx_pfc_req), + .eth_rx_pfc_ack(eth_rx_pfc_ack), + .eth_rx_fc_quanta_clk_en(0), /* * DDR diff --git a/fpga/mqnic/XUPP3R/fpga_25g/tb/fpga_core/Makefile b/fpga/mqnic/XUPP3R/fpga_25g/tb/fpga_core/Makefile index 3e33d048b..262467f1e 100644 --- a/fpga/mqnic/XUPP3R/fpga_25g/tb/fpga_core/Makefile +++ b/fpga/mqnic/XUPP3R/fpga_25g/tb/fpga_core/Makefile @@ -62,6 +62,10 @@ VERILOG_SOURCES += ../../rtl/common/tdma_ber_ch.v VERILOG_SOURCES += ../../lib/eth/rtl/eth_mac_10g.v VERILOG_SOURCES += ../../lib/eth/rtl/axis_xgmii_rx_64.v VERILOG_SOURCES += ../../lib/eth/rtl/axis_xgmii_tx_64.v +VERILOG_SOURCES += ../../lib/eth/rtl/mac_ctrl_rx.v +VERILOG_SOURCES += ../../lib/eth/rtl/mac_ctrl_tx.v +VERILOG_SOURCES += ../../lib/eth/rtl/mac_pause_ctrl_rx.v +VERILOG_SOURCES += ../../lib/eth/rtl/mac_pause_ctrl_tx.v VERILOG_SOURCES += ../../lib/eth/rtl/lfsr.v VERILOG_SOURCES += ../../lib/eth/rtl/ptp_clock.v VERILOG_SOURCES += ../../lib/eth/rtl/ptp_clock_cdc.v @@ -167,6 +171,8 @@ export PARAM_TX_CPL_FIFO_DEPTH := 32 export PARAM_TX_CHECKSUM_ENABLE := 1 export PARAM_RX_HASH_ENABLE := 1 export PARAM_RX_CHECKSUM_ENABLE := 1 +export PARAM_LFC_ENABLE := 1 +export PARAM_PFC_ENABLE := $(PARAM_LFC_ENABLE) export PARAM_TX_FIFO_DEPTH := 32768 export PARAM_RX_FIFO_DEPTH := 32768 export PARAM_MAX_TX_SIZE := 9214 diff --git a/fpga/mqnic/XUPP3R/fpga_25g/tb/fpga_core/test_fpga_core.py b/fpga/mqnic/XUPP3R/fpga_25g/tb/fpga_core/test_fpga_core.py index e4707143f..c4369982b 100644 --- a/fpga/mqnic/XUPP3R/fpga_25g/tb/fpga_core/test_fpga_core.py +++ b/fpga/mqnic/XUPP3R/fpga_25g/tb/fpga_core/test_fpga_core.py @@ -3,6 +3,7 @@ import logging import os +import struct import sys import scapy.utils @@ -17,7 +18,7 @@ from cocotb.clock import Clock from cocotb.triggers import RisingEdge, FallingEdge, Timer from cocotbext.axi import AxiStreamBus -from cocotbext.eth import XgmiiSource, XgmiiSink +from cocotbext.eth import XgmiiSource, XgmiiSink, XgmiiFrame from cocotbext.pcie.core import RootComplex from cocotbext.pcie.xilinx.us import UltraScalePlusPcieDevice @@ -529,6 +530,35 @@ async def run_test_nic(dut): tb.loopback_enable = False + if tb.driver.interfaces[0].if_feature_lfc: + tb.log.info("Test LFC pause frame RX") + + await tb.driver.interfaces[0].ports[0].set_lfc_ctrl(mqnic.MQNIC_PORT_LFC_CTRL_TX_LFC_EN | mqnic.MQNIC_PORT_LFC_CTRL_RX_LFC_EN) + await tb.driver.hw_regs.read_dword(0) + + lfc_xoff = Ether(src='DA:D1:D2:D3:D4:D5', dst='01:80:C2:00:00:01', type=0x8808) / struct.pack('!HH', 0x0001, 2000) + + await tb.qsfp_source[0][0].send(XgmiiFrame.from_payload(bytes(lfc_xoff))) + + count = 16 + + pkts = [bytearray([(x+k) % 256 for x in range(1514)]) for k in range(count)] + + tb.loopback_enable = True + + for p in pkts: + await tb.driver.interfaces[0].start_xmit(p, 0) + + for k in range(count): + pkt = await tb.driver.interfaces[0].recv() + + tb.log.info("Packet: %s", pkt) + assert pkt.data == pkts[k] + if tb.driver.interfaces[0].if_feature_rx_csum: + assert pkt.rx_checksum == ~scapy.utils.checksum(bytes(pkt.data[14:])) & 0xffff + + tb.loopback_enable = False + await RisingEdge(dut.clk_250mhz) await RisingEdge(dut.clk_250mhz) @@ -601,6 +631,10 @@ def test_fpga_core(request): os.path.join(eth_rtl_dir, "eth_mac_10g.v"), os.path.join(eth_rtl_dir, "axis_xgmii_rx_64.v"), os.path.join(eth_rtl_dir, "axis_xgmii_tx_64.v"), + os.path.join(eth_rtl_dir, "mac_ctrl_rx.v"), + os.path.join(eth_rtl_dir, "mac_ctrl_tx.v"), + os.path.join(eth_rtl_dir, "mac_pause_ctrl_rx.v"), + os.path.join(eth_rtl_dir, "mac_pause_ctrl_tx.v"), os.path.join(eth_rtl_dir, "lfsr.v"), os.path.join(eth_rtl_dir, "ptp_clock.v"), os.path.join(eth_rtl_dir, "ptp_clock_cdc.v"), @@ -707,6 +741,8 @@ def test_fpga_core(request): parameters['TX_CHECKSUM_ENABLE'] = 1 parameters['RX_HASH_ENABLE'] = 1 parameters['RX_CHECKSUM_ENABLE'] = 1 + parameters['LFC_ENABLE'] = 1 + parameters['PFC_ENABLE'] = parameters['LFC_ENABLE'] parameters['TX_FIFO_DEPTH'] = 32768 parameters['RX_FIFO_DEPTH'] = 32768 parameters['MAX_TX_SIZE'] = 9214 diff --git a/fpga/mqnic/XUSP3S/fpga_25g/fpga/Makefile b/fpga/mqnic/XUSP3S/fpga_25g/fpga/Makefile index 49846b400..c866d921b 100644 --- a/fpga/mqnic/XUSP3S/fpga_25g/fpga/Makefile +++ b/fpga/mqnic/XUSP3S/fpga_25g/fpga/Makefile @@ -61,6 +61,10 @@ SYN_FILES += rtl/common/tdma_ber_ch.v SYN_FILES += lib/eth/rtl/eth_mac_10g.v SYN_FILES += lib/eth/rtl/axis_xgmii_rx_64.v SYN_FILES += lib/eth/rtl/axis_xgmii_tx_64.v +SYN_FILES += lib/eth/rtl/mac_ctrl_rx.v +SYN_FILES += lib/eth/rtl/mac_ctrl_tx.v +SYN_FILES += lib/eth/rtl/mac_pause_ctrl_rx.v +SYN_FILES += lib/eth/rtl/mac_pause_ctrl_tx.v SYN_FILES += lib/eth/rtl/eth_phy_10g.v SYN_FILES += lib/eth/rtl/eth_phy_10g_rx.v SYN_FILES += lib/eth/rtl/eth_phy_10g_rx_if.v diff --git a/fpga/mqnic/XUSP3S/fpga_25g/fpga/config.tcl b/fpga/mqnic/XUSP3S/fpga_25g/fpga/config.tcl index cb75c651b..fed857f71 100644 --- a/fpga/mqnic/XUSP3S/fpga_25g/fpga/config.tcl +++ b/fpga/mqnic/XUSP3S/fpga_25g/fpga/config.tcl @@ -113,6 +113,8 @@ dict set params TX_CPL_FIFO_DEPTH "32" dict set params TX_CHECKSUM_ENABLE "1" dict set params RX_HASH_ENABLE "1" dict set params RX_CHECKSUM_ENABLE "1" +dict set params PFC_ENABLE "1" +dict set params LFC_ENABLE [dict get $params PFC_ENABLE] dict set params ENABLE_PADDING "1" dict set params ENABLE_DIC "1" dict set params MIN_FRAME_LENGTH "64" diff --git a/fpga/mqnic/XUSP3S/fpga_25g/fpga_10g/Makefile b/fpga/mqnic/XUSP3S/fpga_25g/fpga_10g/Makefile index 49846b400..c866d921b 100644 --- a/fpga/mqnic/XUSP3S/fpga_25g/fpga_10g/Makefile +++ b/fpga/mqnic/XUSP3S/fpga_25g/fpga_10g/Makefile @@ -61,6 +61,10 @@ SYN_FILES += rtl/common/tdma_ber_ch.v SYN_FILES += lib/eth/rtl/eth_mac_10g.v SYN_FILES += lib/eth/rtl/axis_xgmii_rx_64.v SYN_FILES += lib/eth/rtl/axis_xgmii_tx_64.v +SYN_FILES += lib/eth/rtl/mac_ctrl_rx.v +SYN_FILES += lib/eth/rtl/mac_ctrl_tx.v +SYN_FILES += lib/eth/rtl/mac_pause_ctrl_rx.v +SYN_FILES += lib/eth/rtl/mac_pause_ctrl_tx.v SYN_FILES += lib/eth/rtl/eth_phy_10g.v SYN_FILES += lib/eth/rtl/eth_phy_10g_rx.v SYN_FILES += lib/eth/rtl/eth_phy_10g_rx_if.v diff --git a/fpga/mqnic/XUSP3S/fpga_25g/fpga_10g/config.tcl b/fpga/mqnic/XUSP3S/fpga_25g/fpga_10g/config.tcl index 97339a380..bdf936350 100644 --- a/fpga/mqnic/XUSP3S/fpga_25g/fpga_10g/config.tcl +++ b/fpga/mqnic/XUSP3S/fpga_25g/fpga_10g/config.tcl @@ -113,6 +113,8 @@ dict set params TX_CPL_FIFO_DEPTH "32" dict set params TX_CHECKSUM_ENABLE "1" dict set params RX_HASH_ENABLE "1" dict set params RX_CHECKSUM_ENABLE "1" +dict set params PFC_ENABLE "1" +dict set params LFC_ENABLE [dict get $params PFC_ENABLE] dict set params ENABLE_PADDING "1" dict set params ENABLE_DIC "1" dict set params MIN_FRAME_LENGTH "64" diff --git a/fpga/mqnic/XUSP3S/fpga_25g/fpga_app_dma_bench/Makefile b/fpga/mqnic/XUSP3S/fpga_25g/fpga_app_dma_bench/Makefile index a22295564..daf9a142e 100644 --- a/fpga/mqnic/XUSP3S/fpga_25g/fpga_app_dma_bench/Makefile +++ b/fpga/mqnic/XUSP3S/fpga_25g/fpga_app_dma_bench/Makefile @@ -64,6 +64,10 @@ SYN_FILES += app/dma_bench/rtl/dram_test_ch.v SYN_FILES += lib/eth/rtl/eth_mac_10g.v SYN_FILES += lib/eth/rtl/axis_xgmii_rx_64.v SYN_FILES += lib/eth/rtl/axis_xgmii_tx_64.v +SYN_FILES += lib/eth/rtl/mac_ctrl_rx.v +SYN_FILES += lib/eth/rtl/mac_ctrl_tx.v +SYN_FILES += lib/eth/rtl/mac_pause_ctrl_rx.v +SYN_FILES += lib/eth/rtl/mac_pause_ctrl_tx.v SYN_FILES += lib/eth/rtl/eth_phy_10g.v SYN_FILES += lib/eth/rtl/eth_phy_10g_rx.v SYN_FILES += lib/eth/rtl/eth_phy_10g_rx_if.v diff --git a/fpga/mqnic/XUSP3S/fpga_25g/fpga_app_dma_bench/config.tcl b/fpga/mqnic/XUSP3S/fpga_25g/fpga_app_dma_bench/config.tcl index aac599463..59e64046e 100644 --- a/fpga/mqnic/XUSP3S/fpga_25g/fpga_app_dma_bench/config.tcl +++ b/fpga/mqnic/XUSP3S/fpga_25g/fpga_app_dma_bench/config.tcl @@ -113,6 +113,8 @@ dict set params TX_CPL_FIFO_DEPTH "32" dict set params TX_CHECKSUM_ENABLE "1" dict set params RX_HASH_ENABLE "1" dict set params RX_CHECKSUM_ENABLE "1" +dict set params PFC_ENABLE "1" +dict set params LFC_ENABLE [dict get $params PFC_ENABLE] dict set params ENABLE_PADDING "1" dict set params ENABLE_DIC "1" dict set params MIN_FRAME_LENGTH "64" diff --git a/fpga/mqnic/XUSP3S/fpga_25g/rtl/fpga.v b/fpga/mqnic/XUSP3S/fpga_25g/rtl/fpga.v index 556f1075b..13d9ac833 100644 --- a/fpga/mqnic/XUSP3S/fpga_25g/rtl/fpga.v +++ b/fpga/mqnic/XUSP3S/fpga_25g/rtl/fpga.v @@ -74,6 +74,8 @@ module fpga # parameter TX_CHECKSUM_ENABLE = 1, parameter RX_HASH_ENABLE = 1, parameter RX_CHECKSUM_ENABLE = 1, + parameter PFC_ENABLE = 1, + parameter LFC_ENABLE = PFC_ENABLE, parameter ENABLE_PADDING = 1, parameter ENABLE_DIC = 1, parameter MIN_FRAME_LENGTH = 64, @@ -2510,6 +2512,8 @@ fpga_core #( .TX_CHECKSUM_ENABLE(TX_CHECKSUM_ENABLE), .RX_HASH_ENABLE(RX_HASH_ENABLE), .RX_CHECKSUM_ENABLE(RX_CHECKSUM_ENABLE), + .PFC_ENABLE(PFC_ENABLE), + .LFC_ENABLE(LFC_ENABLE), .ENABLE_PADDING(ENABLE_PADDING), .ENABLE_DIC(ENABLE_DIC), .MIN_FRAME_LENGTH(MIN_FRAME_LENGTH), diff --git a/fpga/mqnic/XUSP3S/fpga_25g/rtl/fpga_core.v b/fpga/mqnic/XUSP3S/fpga_25g/rtl/fpga_core.v index 28507bd8b..e88d5647d 100644 --- a/fpga/mqnic/XUSP3S/fpga_25g/rtl/fpga_core.v +++ b/fpga/mqnic/XUSP3S/fpga_25g/rtl/fpga_core.v @@ -81,6 +81,8 @@ module fpga_core # parameter TX_CHECKSUM_ENABLE = 1, parameter RX_HASH_ENABLE = 1, parameter RX_CHECKSUM_ENABLE = 1, + parameter PFC_ENABLE = 1, + parameter LFC_ENABLE = PFC_ENABLE, parameter ENABLE_PADDING = 1, parameter ENABLE_DIC = 1, parameter MIN_FRAME_LENGTH = 64, @@ -1317,7 +1319,12 @@ wire [PORT_COUNT*TX_TAG_WIDTH-1:0] axis_eth_tx_ptp_ts_tag; wire [PORT_COUNT-1:0] axis_eth_tx_ptp_ts_valid; wire [PORT_COUNT-1:0] axis_eth_tx_ptp_ts_ready; +wire [PORT_COUNT-1:0] eth_tx_enable; wire [PORT_COUNT-1:0] eth_tx_status; +wire [PORT_COUNT-1:0] eth_tx_lfc_en; +wire [PORT_COUNT-1:0] eth_tx_lfc_req; +wire [PORT_COUNT*8-1:0] eth_tx_pfc_en; +wire [PORT_COUNT*8-1:0] eth_tx_pfc_req; wire [PORT_COUNT-1:0] eth_rx_clk; wire [PORT_COUNT-1:0] eth_rx_rst; @@ -1332,7 +1339,14 @@ wire [PORT_COUNT-1:0] axis_eth_rx_tready; wire [PORT_COUNT-1:0] axis_eth_rx_tlast; wire [PORT_COUNT*AXIS_ETH_RX_USER_WIDTH-1:0] axis_eth_rx_tuser; +wire [PORT_COUNT-1:0] eth_rx_enable; wire [PORT_COUNT-1:0] eth_rx_status; +wire [PORT_COUNT-1:0] eth_rx_lfc_en; +wire [PORT_COUNT-1:0] eth_rx_lfc_req; +wire [PORT_COUNT-1:0] eth_rx_lfc_ack; +wire [PORT_COUNT*8-1:0] eth_rx_pfc_en; +wire [PORT_COUNT*8-1:0] eth_rx_pfc_req; +wire [PORT_COUNT*8-1:0] eth_rx_pfc_ack; wire [PORT_COUNT-1:0] port_xgmii_tx_clk; wire [PORT_COUNT-1:0] port_xgmii_tx_rst; @@ -1405,12 +1419,15 @@ generate .PTP_PERIOD_FNS(IF_PTP_PERIOD_FNS), .TX_PTP_TS_ENABLE(PTP_TS_ENABLE), .TX_PTP_TS_WIDTH(PTP_TS_WIDTH), + .TX_PTP_TS_CTRL_IN_TUSER(0), .TX_PTP_TAG_ENABLE(PTP_TS_ENABLE), .TX_PTP_TAG_WIDTH(TX_TAG_WIDTH), .RX_PTP_TS_ENABLE(PTP_TS_ENABLE), .RX_PTP_TS_WIDTH(PTP_TS_WIDTH), .TX_USER_WIDTH(AXIS_ETH_TX_USER_WIDTH), - .RX_USER_WIDTH(AXIS_ETH_RX_USER_WIDTH) + .RX_USER_WIDTH(AXIS_ETH_RX_USER_WIDTH), + .PFC_ENABLE(PFC_ENABLE), + .PAUSE_ENABLE(LFC_ENABLE) ) eth_mac_inst ( .tx_clk(port_xgmii_tx_clk[n]), @@ -1418,6 +1435,9 @@ generate .rx_clk(port_xgmii_rx_clk[n]), .rx_rst(port_xgmii_rx_rst[n]), + /* + * AXI input + */ .tx_axis_tdata(axis_eth_tx_tdata[n*AXIS_ETH_DATA_WIDTH +: AXIS_ETH_DATA_WIDTH]), .tx_axis_tkeep(axis_eth_tx_tkeep[n*AXIS_ETH_KEEP_WIDTH +: AXIS_ETH_KEEP_WIDTH]), .tx_axis_tvalid(axis_eth_tx_tvalid[n +: 1]), @@ -1425,30 +1445,121 @@ generate .tx_axis_tlast(axis_eth_tx_tlast[n +: 1]), .tx_axis_tuser(axis_eth_tx_tuser[n*AXIS_ETH_TX_USER_WIDTH +: AXIS_ETH_TX_USER_WIDTH]), + /* + * AXI output + */ .rx_axis_tdata(axis_eth_rx_tdata[n*AXIS_ETH_DATA_WIDTH +: AXIS_ETH_DATA_WIDTH]), .rx_axis_tkeep(axis_eth_rx_tkeep[n*AXIS_ETH_KEEP_WIDTH +: AXIS_ETH_KEEP_WIDTH]), .rx_axis_tvalid(axis_eth_rx_tvalid[n +: 1]), .rx_axis_tlast(axis_eth_rx_tlast[n +: 1]), .rx_axis_tuser(axis_eth_rx_tuser[n*AXIS_ETH_RX_USER_WIDTH +: AXIS_ETH_RX_USER_WIDTH]), + /* + * XGMII interface + */ .xgmii_rxd(port_xgmii_rxd[n*XGMII_DATA_WIDTH +: XGMII_DATA_WIDTH]), .xgmii_rxc(port_xgmii_rxc[n*XGMII_CTRL_WIDTH +: XGMII_CTRL_WIDTH]), .xgmii_txd(port_xgmii_txd[n*XGMII_DATA_WIDTH +: XGMII_DATA_WIDTH]), .xgmii_txc(port_xgmii_txc[n*XGMII_CTRL_WIDTH +: XGMII_CTRL_WIDTH]), + /* + * PTP + */ .tx_ptp_ts(eth_tx_ptp_ts_96[n*PTP_TS_WIDTH +: PTP_TS_WIDTH]), .rx_ptp_ts(eth_rx_ptp_ts_96[n*PTP_TS_WIDTH +: PTP_TS_WIDTH]), .tx_axis_ptp_ts(axis_eth_tx_ptp_ts[n*PTP_TS_WIDTH +: PTP_TS_WIDTH]), .tx_axis_ptp_ts_tag(axis_eth_tx_ptp_ts_tag[n*TX_TAG_WIDTH +: TX_TAG_WIDTH]), .tx_axis_ptp_ts_valid(axis_eth_tx_ptp_ts_valid[n +: 1]), + /* + * Link-level Flow Control (LFC) (IEEE 802.3 annex 31B PAUSE) + */ + .tx_lfc_req(eth_tx_lfc_req[n +: 1]), + .tx_lfc_resend(1'b0), + .rx_lfc_en(eth_rx_lfc_en[n +: 1]), + .rx_lfc_req(eth_rx_lfc_req[n +: 1]), + .rx_lfc_ack(eth_rx_lfc_ack[n +: 1]), + + /* + * Priority Flow Control (PFC) (IEEE 802.3 annex 31D PFC) + */ + .tx_pfc_req(eth_tx_pfc_req[n*8 +: 8]), + .tx_pfc_resend(1'b0), + .rx_pfc_en(eth_rx_pfc_en[n*8 +: 8]), + .rx_pfc_req(eth_rx_pfc_req[n*8 +: 8]), + .rx_pfc_ack(eth_rx_pfc_ack[n*8 +: 8]), + + /* + * Pause interface + */ + .tx_lfc_pause_en(1'b1), + .tx_pause_req(1'b0), + .tx_pause_ack(), + + /* + * Status + */ + .tx_start_packet(), .tx_error_underflow(), + .rx_start_packet(), .rx_error_bad_frame(), .rx_error_bad_fcs(), + .stat_tx_mcf(), + .stat_rx_mcf(), + .stat_tx_lfc_pkt(), + .stat_tx_lfc_xon(), + .stat_tx_lfc_xoff(), + .stat_tx_lfc_paused(), + .stat_tx_pfc_pkt(), + .stat_tx_pfc_xon(), + .stat_tx_pfc_xoff(), + .stat_tx_pfc_paused(), + .stat_rx_lfc_pkt(), + .stat_rx_lfc_xon(), + .stat_rx_lfc_xoff(), + .stat_rx_lfc_paused(), + .stat_rx_pfc_pkt(), + .stat_rx_pfc_xon(), + .stat_rx_pfc_xoff(), + .stat_rx_pfc_paused(), + /* + * Configuration + */ .cfg_ifg(8'd12), - .cfg_tx_enable(1'b1), - .cfg_rx_enable(1'b1) + .cfg_tx_enable(eth_tx_enable[n +: 1]), + .cfg_rx_enable(eth_rx_enable[n +: 1]), + .cfg_mcf_rx_eth_dst_mcast(48'h01_80_C2_00_00_01), + .cfg_mcf_rx_check_eth_dst_mcast(1'b1), + .cfg_mcf_rx_eth_dst_ucast(48'd0), + .cfg_mcf_rx_check_eth_dst_ucast(1'b0), + .cfg_mcf_rx_eth_src(48'd0), + .cfg_mcf_rx_check_eth_src(1'b0), + .cfg_mcf_rx_eth_type(16'h8808), + .cfg_mcf_rx_opcode_lfc(16'h0001), + .cfg_mcf_rx_check_opcode_lfc(eth_rx_lfc_en[n +: 1]), + .cfg_mcf_rx_opcode_pfc(16'h0101), + .cfg_mcf_rx_check_opcode_pfc(eth_rx_pfc_en[n*8 +: 8] != 0), + .cfg_mcf_rx_forward(1'b0), + .cfg_mcf_rx_enable(eth_rx_lfc_en[n +: 1] || eth_rx_pfc_en[n*8 +: 8]), + .cfg_tx_lfc_eth_dst(48'h01_80_C2_00_00_01), + .cfg_tx_lfc_eth_src(48'h80_23_31_43_54_4C), + .cfg_tx_lfc_eth_type(16'h8808), + .cfg_tx_lfc_opcode(16'h0001), + .cfg_tx_lfc_en(eth_tx_lfc_en[n +: 1]), + .cfg_tx_lfc_quanta(16'hffff), + .cfg_tx_lfc_refresh(16'h7fff), + .cfg_tx_pfc_eth_dst(48'h01_80_C2_00_00_01), + .cfg_tx_pfc_eth_src(48'h80_23_31_43_54_4C), + .cfg_tx_pfc_eth_type(16'h8808), + .cfg_tx_pfc_opcode(16'h0101), + .cfg_tx_pfc_en(eth_tx_pfc_en[n*8 +: 8] != 0), + .cfg_tx_pfc_quanta({8{16'hffff}}), + .cfg_tx_pfc_refresh({8{16'h7fff}}), + .cfg_rx_lfc_opcode(16'h0001), + .cfg_rx_lfc_en(eth_rx_lfc_en[n +: 1]), + .cfg_rx_pfc_opcode(16'h0101), + .cfg_rx_pfc_en(eth_rx_pfc_en[n*8 +: 8] != 0) ); end @@ -1522,6 +1633,9 @@ mqnic_core_pcie_us #( .TX_CHECKSUM_ENABLE(TX_CHECKSUM_ENABLE), .RX_HASH_ENABLE(RX_HASH_ENABLE), .RX_CHECKSUM_ENABLE(RX_CHECKSUM_ENABLE), + .PFC_ENABLE(PFC_ENABLE), + .LFC_ENABLE(LFC_ENABLE), + .MAC_CTRL_ENABLE(0), .TX_FIFO_DEPTH(TX_FIFO_DEPTH), .RX_FIFO_DEPTH(RX_FIFO_DEPTH), .MAX_TX_SIZE(MAX_TX_SIZE), @@ -1803,7 +1917,13 @@ core_inst ( .s_axis_eth_tx_cpl_valid(axis_eth_tx_ptp_ts_valid), .s_axis_eth_tx_cpl_ready(axis_eth_tx_ptp_ts_ready), + .eth_tx_enable(eth_tx_enable), .eth_tx_status(eth_tx_status), + .eth_tx_lfc_en(eth_tx_lfc_en), + .eth_tx_lfc_req(eth_tx_lfc_req), + .eth_tx_pfc_en(eth_tx_pfc_en), + .eth_tx_pfc_req(eth_tx_pfc_req), + .eth_tx_fc_quanta_clk_en(0), .eth_rx_clk(eth_rx_clk), .eth_rx_rst(eth_rx_rst), @@ -1820,7 +1940,15 @@ core_inst ( .s_axis_eth_rx_tlast(axis_eth_rx_tlast), .s_axis_eth_rx_tuser(axis_eth_rx_tuser), + .eth_rx_enable(eth_rx_enable), .eth_rx_status(eth_rx_status), + .eth_rx_lfc_en(eth_rx_lfc_en), + .eth_rx_lfc_req(eth_rx_lfc_req), + .eth_rx_lfc_ack(eth_rx_lfc_ack), + .eth_rx_pfc_en(eth_rx_pfc_en), + .eth_rx_pfc_req(eth_rx_pfc_req), + .eth_rx_pfc_ack(eth_rx_pfc_ack), + .eth_rx_fc_quanta_clk_en(0), /* * DDR diff --git a/fpga/mqnic/XUSP3S/fpga_25g/tb/fpga_core/Makefile b/fpga/mqnic/XUSP3S/fpga_25g/tb/fpga_core/Makefile index eb46883b9..bc5d0330e 100644 --- a/fpga/mqnic/XUSP3S/fpga_25g/tb/fpga_core/Makefile +++ b/fpga/mqnic/XUSP3S/fpga_25g/tb/fpga_core/Makefile @@ -62,6 +62,10 @@ VERILOG_SOURCES += ../../rtl/common/tdma_ber_ch.v VERILOG_SOURCES += ../../lib/eth/rtl/eth_mac_10g.v VERILOG_SOURCES += ../../lib/eth/rtl/axis_xgmii_rx_64.v VERILOG_SOURCES += ../../lib/eth/rtl/axis_xgmii_tx_64.v +VERILOG_SOURCES += ../../lib/eth/rtl/mac_ctrl_rx.v +VERILOG_SOURCES += ../../lib/eth/rtl/mac_ctrl_tx.v +VERILOG_SOURCES += ../../lib/eth/rtl/mac_pause_ctrl_rx.v +VERILOG_SOURCES += ../../lib/eth/rtl/mac_pause_ctrl_tx.v VERILOG_SOURCES += ../../lib/eth/rtl/lfsr.v VERILOG_SOURCES += ../../lib/eth/rtl/ptp_clock.v VERILOG_SOURCES += ../../lib/eth/rtl/ptp_clock_cdc.v @@ -167,6 +171,8 @@ export PARAM_TX_CPL_FIFO_DEPTH := 32 export PARAM_TX_CHECKSUM_ENABLE := 1 export PARAM_RX_HASH_ENABLE := 1 export PARAM_RX_CHECKSUM_ENABLE := 1 +export PARAM_LFC_ENABLE := 1 +export PARAM_PFC_ENABLE := $(PARAM_LFC_ENABLE) export PARAM_TX_FIFO_DEPTH := 32768 export PARAM_RX_FIFO_DEPTH := 32768 export PARAM_MAX_TX_SIZE := 9214 diff --git a/fpga/mqnic/XUSP3S/fpga_25g/tb/fpga_core/test_fpga_core.py b/fpga/mqnic/XUSP3S/fpga_25g/tb/fpga_core/test_fpga_core.py index 08a200315..c5685ce23 100644 --- a/fpga/mqnic/XUSP3S/fpga_25g/tb/fpga_core/test_fpga_core.py +++ b/fpga/mqnic/XUSP3S/fpga_25g/tb/fpga_core/test_fpga_core.py @@ -3,6 +3,7 @@ import logging import os +import struct import sys import scapy.utils @@ -17,7 +18,7 @@ from cocotb.clock import Clock from cocotb.triggers import RisingEdge, FallingEdge, Timer from cocotbext.axi import AxiStreamBus -from cocotbext.eth import XgmiiSource, XgmiiSink +from cocotbext.eth import XgmiiSource, XgmiiSink, XgmiiFrame from cocotbext.pcie.core import RootComplex from cocotbext.pcie.xilinx.us import UltraScalePcieDevice @@ -503,6 +504,35 @@ async def run_test_nic(dut): tb.loopback_enable = False + if tb.driver.interfaces[0].if_feature_lfc: + tb.log.info("Test LFC pause frame RX") + + await tb.driver.interfaces[0].ports[0].set_lfc_ctrl(mqnic.MQNIC_PORT_LFC_CTRL_TX_LFC_EN | mqnic.MQNIC_PORT_LFC_CTRL_RX_LFC_EN) + await tb.driver.hw_regs.read_dword(0) + + lfc_xoff = Ether(src='DA:D1:D2:D3:D4:D5', dst='01:80:C2:00:00:01', type=0x8808) / struct.pack('!HH', 0x0001, 2000) + + await tb.qsfp_source[0][0].send(XgmiiFrame.from_payload(bytes(lfc_xoff))) + + count = 16 + + pkts = [bytearray([(x+k) % 256 for x in range(1514)]) for k in range(count)] + + tb.loopback_enable = True + + for p in pkts: + await tb.driver.interfaces[0].start_xmit(p, 0) + + for k in range(count): + pkt = await tb.driver.interfaces[0].recv() + + tb.log.info("Packet: %s", pkt) + assert pkt.data == pkts[k] + if tb.driver.interfaces[0].if_feature_rx_csum: + assert pkt.rx_checksum == ~scapy.utils.checksum(bytes(pkt.data[14:])) & 0xffff + + tb.loopback_enable = False + await RisingEdge(dut.clk_250mhz) await RisingEdge(dut.clk_250mhz) @@ -575,6 +605,10 @@ def test_fpga_core(request): os.path.join(eth_rtl_dir, "eth_mac_10g.v"), os.path.join(eth_rtl_dir, "axis_xgmii_rx_64.v"), os.path.join(eth_rtl_dir, "axis_xgmii_tx_64.v"), + os.path.join(eth_rtl_dir, "mac_ctrl_rx.v"), + os.path.join(eth_rtl_dir, "mac_ctrl_tx.v"), + os.path.join(eth_rtl_dir, "mac_pause_ctrl_rx.v"), + os.path.join(eth_rtl_dir, "mac_pause_ctrl_tx.v"), os.path.join(eth_rtl_dir, "lfsr.v"), os.path.join(eth_rtl_dir, "ptp_clock.v"), os.path.join(eth_rtl_dir, "ptp_clock_cdc.v"), @@ -681,6 +715,8 @@ def test_fpga_core(request): parameters['TX_CHECKSUM_ENABLE'] = 1 parameters['RX_HASH_ENABLE'] = 1 parameters['RX_CHECKSUM_ENABLE'] = 1 + parameters['LFC_ENABLE'] = 1 + parameters['PFC_ENABLE'] = parameters['LFC_ENABLE'] parameters['TX_FIFO_DEPTH'] = 32768 parameters['RX_FIFO_DEPTH'] = 32768 parameters['MAX_TX_SIZE'] = 9214 diff --git a/fpga/mqnic/ZCU102/fpga/fpga/Makefile b/fpga/mqnic/ZCU102/fpga/fpga/Makefile index 0d49f69c3..00eb5760b 100644 --- a/fpga/mqnic/ZCU102/fpga/fpga/Makefile +++ b/fpga/mqnic/ZCU102/fpga/fpga/Makefile @@ -58,6 +58,10 @@ SYN_FILES += rtl/common/tdma_ber_ch.v SYN_FILES += lib/eth/rtl/eth_mac_10g.v SYN_FILES += lib/eth/rtl/axis_xgmii_rx_64.v SYN_FILES += lib/eth/rtl/axis_xgmii_tx_64.v +SYN_FILES += lib/eth/rtl/mac_ctrl_rx.v +SYN_FILES += lib/eth/rtl/mac_ctrl_tx.v +SYN_FILES += lib/eth/rtl/mac_pause_ctrl_rx.v +SYN_FILES += lib/eth/rtl/mac_pause_ctrl_tx.v SYN_FILES += lib/eth/rtl/eth_phy_10g.v SYN_FILES += lib/eth/rtl/eth_phy_10g_rx.v SYN_FILES += lib/eth/rtl/eth_phy_10g_rx_if.v diff --git a/fpga/mqnic/ZCU102/fpga/fpga/config.tcl b/fpga/mqnic/ZCU102/fpga/fpga/config.tcl index 82e151367..615859c84 100644 --- a/fpga/mqnic/ZCU102/fpga/fpga/config.tcl +++ b/fpga/mqnic/ZCU102/fpga/fpga/config.tcl @@ -96,6 +96,8 @@ dict set params TX_CPL_FIFO_DEPTH "32" dict set params TX_CHECKSUM_ENABLE "1" dict set params RX_HASH_ENABLE "1" dict set params RX_CHECKSUM_ENABLE "1" +dict set params PFC_ENABLE "1" +dict set params LFC_ENABLE [dict get $params PFC_ENABLE] dict set params ENABLE_PADDING "1" dict set params ENABLE_DIC "1" dict set params MIN_FRAME_LENGTH "64" diff --git a/fpga/mqnic/ZCU102/fpga/fpga_app_dma_bench/Makefile b/fpga/mqnic/ZCU102/fpga/fpga_app_dma_bench/Makefile index 1573f10d2..45f52e5ab 100644 --- a/fpga/mqnic/ZCU102/fpga/fpga_app_dma_bench/Makefile +++ b/fpga/mqnic/ZCU102/fpga/fpga_app_dma_bench/Makefile @@ -61,6 +61,10 @@ SYN_FILES += app/dma_bench/rtl/dram_test_ch.v SYN_FILES += lib/eth/rtl/eth_mac_10g.v SYN_FILES += lib/eth/rtl/axis_xgmii_rx_64.v SYN_FILES += lib/eth/rtl/axis_xgmii_tx_64.v +SYN_FILES += lib/eth/rtl/mac_ctrl_rx.v +SYN_FILES += lib/eth/rtl/mac_ctrl_tx.v +SYN_FILES += lib/eth/rtl/mac_pause_ctrl_rx.v +SYN_FILES += lib/eth/rtl/mac_pause_ctrl_tx.v SYN_FILES += lib/eth/rtl/eth_phy_10g.v SYN_FILES += lib/eth/rtl/eth_phy_10g_rx.v SYN_FILES += lib/eth/rtl/eth_phy_10g_rx_if.v diff --git a/fpga/mqnic/ZCU102/fpga/fpga_app_dma_bench/config.tcl b/fpga/mqnic/ZCU102/fpga/fpga_app_dma_bench/config.tcl index dfa2994e3..f5f4fcda3 100644 --- a/fpga/mqnic/ZCU102/fpga/fpga_app_dma_bench/config.tcl +++ b/fpga/mqnic/ZCU102/fpga/fpga_app_dma_bench/config.tcl @@ -96,6 +96,8 @@ dict set params TX_CPL_FIFO_DEPTH "32" dict set params TX_CHECKSUM_ENABLE "1" dict set params RX_HASH_ENABLE "1" dict set params RX_CHECKSUM_ENABLE "1" +dict set params PFC_ENABLE "1" +dict set params LFC_ENABLE [dict get $params PFC_ENABLE] dict set params ENABLE_PADDING "1" dict set params ENABLE_DIC "1" dict set params MIN_FRAME_LENGTH "64" diff --git a/fpga/mqnic/ZCU102/fpga/rtl/fpga.v b/fpga/mqnic/ZCU102/fpga/rtl/fpga.v index 4a2bbbf72..c5be020c2 100644 --- a/fpga/mqnic/ZCU102/fpga/rtl/fpga.v +++ b/fpga/mqnic/ZCU102/fpga/rtl/fpga.v @@ -75,6 +75,8 @@ module fpga # parameter TX_CHECKSUM_ENABLE = 1, parameter RX_HASH_ENABLE = 1, parameter RX_CHECKSUM_ENABLE = 1, + parameter PFC_ENABLE = 1, + parameter LFC_ENABLE = PFC_ENABLE, parameter ENABLE_PADDING = 1, parameter ENABLE_DIC = 1, parameter MIN_FRAME_LENGTH = 64, @@ -1013,6 +1015,8 @@ fpga_core #( .TX_CHECKSUM_ENABLE(TX_CHECKSUM_ENABLE), .RX_HASH_ENABLE(RX_HASH_ENABLE), .RX_CHECKSUM_ENABLE(RX_CHECKSUM_ENABLE), + .PFC_ENABLE(PFC_ENABLE), + .LFC_ENABLE(LFC_ENABLE), .ENABLE_PADDING(ENABLE_PADDING), .ENABLE_DIC(ENABLE_DIC), .MIN_FRAME_LENGTH(MIN_FRAME_LENGTH), diff --git a/fpga/mqnic/ZCU102/fpga/rtl/fpga_core.v b/fpga/mqnic/ZCU102/fpga/rtl/fpga_core.v index d36d4200f..3e259cd5d 100644 --- a/fpga/mqnic/ZCU102/fpga/rtl/fpga_core.v +++ b/fpga/mqnic/ZCU102/fpga/rtl/fpga_core.v @@ -82,6 +82,8 @@ module fpga_core # parameter TX_CHECKSUM_ENABLE = 1, parameter RX_HASH_ENABLE = 1, parameter RX_CHECKSUM_ENABLE = 1, + parameter PFC_ENABLE = 1, + parameter LFC_ENABLE = PFC_ENABLE, parameter ENABLE_PADDING = 1, parameter ENABLE_DIC = 1, parameter MIN_FRAME_LENGTH = 64, @@ -671,7 +673,12 @@ wire [PORT_COUNT*TX_TAG_WIDTH-1:0] axis_eth_tx_ptp_ts_tag; wire [PORT_COUNT-1:0] axis_eth_tx_ptp_ts_valid; wire [PORT_COUNT-1:0] axis_eth_tx_ptp_ts_ready; +wire [PORT_COUNT-1:0] eth_tx_enable; wire [PORT_COUNT-1:0] eth_tx_status; +wire [PORT_COUNT-1:0] eth_tx_lfc_en; +wire [PORT_COUNT-1:0] eth_tx_lfc_req; +wire [PORT_COUNT*8-1:0] eth_tx_pfc_en; +wire [PORT_COUNT*8-1:0] eth_tx_pfc_req; wire [PORT_COUNT-1:0] eth_rx_clk; wire [PORT_COUNT-1:0] eth_rx_rst; @@ -686,7 +693,14 @@ wire [PORT_COUNT-1:0] axis_eth_rx_tready; wire [PORT_COUNT-1:0] axis_eth_rx_tlast; wire [PORT_COUNT*AXIS_ETH_RX_USER_WIDTH-1:0] axis_eth_rx_tuser; +wire [PORT_COUNT-1:0] eth_rx_enable; wire [PORT_COUNT-1:0] eth_rx_status; +wire [PORT_COUNT-1:0] eth_rx_lfc_en; +wire [PORT_COUNT-1:0] eth_rx_lfc_req; +wire [PORT_COUNT-1:0] eth_rx_lfc_ack; +wire [PORT_COUNT*8-1:0] eth_rx_pfc_en; +wire [PORT_COUNT*8-1:0] eth_rx_pfc_req; +wire [PORT_COUNT*8-1:0] eth_rx_pfc_ack; wire [PORT_COUNT-1:0] port_xgmii_tx_clk; wire [PORT_COUNT-1:0] port_xgmii_tx_rst; @@ -759,12 +773,15 @@ generate .PTP_PERIOD_FNS(IF_PTP_PERIOD_FNS), .TX_PTP_TS_ENABLE(PTP_TS_ENABLE), .TX_PTP_TS_WIDTH(PTP_TS_WIDTH), + .TX_PTP_TS_CTRL_IN_TUSER(0), .TX_PTP_TAG_ENABLE(PTP_TS_ENABLE), .TX_PTP_TAG_WIDTH(TX_TAG_WIDTH), .RX_PTP_TS_ENABLE(PTP_TS_ENABLE), .RX_PTP_TS_WIDTH(PTP_TS_WIDTH), .TX_USER_WIDTH(AXIS_ETH_TX_USER_WIDTH), - .RX_USER_WIDTH(AXIS_ETH_RX_USER_WIDTH) + .RX_USER_WIDTH(AXIS_ETH_RX_USER_WIDTH), + .PFC_ENABLE(PFC_ENABLE), + .PAUSE_ENABLE(LFC_ENABLE) ) eth_mac_inst ( .tx_clk(port_xgmii_tx_clk[n]), @@ -772,6 +789,9 @@ generate .rx_clk(port_xgmii_rx_clk[n]), .rx_rst(port_xgmii_rx_rst[n]), + /* + * AXI input + */ .tx_axis_tdata(axis_eth_tx_tdata[n*AXIS_ETH_DATA_WIDTH +: AXIS_ETH_DATA_WIDTH]), .tx_axis_tkeep(axis_eth_tx_tkeep[n*AXIS_ETH_KEEP_WIDTH +: AXIS_ETH_KEEP_WIDTH]), .tx_axis_tvalid(axis_eth_tx_tvalid[n +: 1]), @@ -779,30 +799,121 @@ generate .tx_axis_tlast(axis_eth_tx_tlast[n +: 1]), .tx_axis_tuser(axis_eth_tx_tuser[n*AXIS_ETH_TX_USER_WIDTH +: AXIS_ETH_TX_USER_WIDTH]), + /* + * AXI output + */ .rx_axis_tdata(axis_eth_rx_tdata[n*AXIS_ETH_DATA_WIDTH +: AXIS_ETH_DATA_WIDTH]), .rx_axis_tkeep(axis_eth_rx_tkeep[n*AXIS_ETH_KEEP_WIDTH +: AXIS_ETH_KEEP_WIDTH]), .rx_axis_tvalid(axis_eth_rx_tvalid[n +: 1]), .rx_axis_tlast(axis_eth_rx_tlast[n +: 1]), .rx_axis_tuser(axis_eth_rx_tuser[n*AXIS_ETH_RX_USER_WIDTH +: AXIS_ETH_RX_USER_WIDTH]), + /* + * XGMII interface + */ .xgmii_rxd(port_xgmii_rxd[n*XGMII_DATA_WIDTH +: XGMII_DATA_WIDTH]), .xgmii_rxc(port_xgmii_rxc[n*XGMII_CTRL_WIDTH +: XGMII_CTRL_WIDTH]), .xgmii_txd(port_xgmii_txd[n*XGMII_DATA_WIDTH +: XGMII_DATA_WIDTH]), .xgmii_txc(port_xgmii_txc[n*XGMII_CTRL_WIDTH +: XGMII_CTRL_WIDTH]), + /* + * PTP + */ .tx_ptp_ts(eth_tx_ptp_ts_96[n*PTP_TS_WIDTH +: PTP_TS_WIDTH]), .rx_ptp_ts(eth_rx_ptp_ts_96[n*PTP_TS_WIDTH +: PTP_TS_WIDTH]), .tx_axis_ptp_ts(axis_eth_tx_ptp_ts[n*PTP_TS_WIDTH +: PTP_TS_WIDTH]), .tx_axis_ptp_ts_tag(axis_eth_tx_ptp_ts_tag[n*TX_TAG_WIDTH +: TX_TAG_WIDTH]), .tx_axis_ptp_ts_valid(axis_eth_tx_ptp_ts_valid[n +: 1]), + /* + * Link-level Flow Control (LFC) (IEEE 802.3 annex 31B PAUSE) + */ + .tx_lfc_req(eth_tx_lfc_req[n +: 1]), + .tx_lfc_resend(1'b0), + .rx_lfc_en(eth_rx_lfc_en[n +: 1]), + .rx_lfc_req(eth_rx_lfc_req[n +: 1]), + .rx_lfc_ack(eth_rx_lfc_ack[n +: 1]), + + /* + * Priority Flow Control (PFC) (IEEE 802.3 annex 31D PFC) + */ + .tx_pfc_req(eth_tx_pfc_req[n*8 +: 8]), + .tx_pfc_resend(1'b0), + .rx_pfc_en(eth_rx_pfc_en[n*8 +: 8]), + .rx_pfc_req(eth_rx_pfc_req[n*8 +: 8]), + .rx_pfc_ack(eth_rx_pfc_ack[n*8 +: 8]), + + /* + * Pause interface + */ + .tx_lfc_pause_en(1'b1), + .tx_pause_req(1'b0), + .tx_pause_ack(), + + /* + * Status + */ + .tx_start_packet(), .tx_error_underflow(), + .rx_start_packet(), .rx_error_bad_frame(), .rx_error_bad_fcs(), + .stat_tx_mcf(), + .stat_rx_mcf(), + .stat_tx_lfc_pkt(), + .stat_tx_lfc_xon(), + .stat_tx_lfc_xoff(), + .stat_tx_lfc_paused(), + .stat_tx_pfc_pkt(), + .stat_tx_pfc_xon(), + .stat_tx_pfc_xoff(), + .stat_tx_pfc_paused(), + .stat_rx_lfc_pkt(), + .stat_rx_lfc_xon(), + .stat_rx_lfc_xoff(), + .stat_rx_lfc_paused(), + .stat_rx_pfc_pkt(), + .stat_rx_pfc_xon(), + .stat_rx_pfc_xoff(), + .stat_rx_pfc_paused(), + /* + * Configuration + */ .cfg_ifg(8'd12), - .cfg_tx_enable(1'b1), - .cfg_rx_enable(1'b1) + .cfg_tx_enable(eth_tx_enable[n +: 1]), + .cfg_rx_enable(eth_rx_enable[n +: 1]), + .cfg_mcf_rx_eth_dst_mcast(48'h01_80_C2_00_00_01), + .cfg_mcf_rx_check_eth_dst_mcast(1'b1), + .cfg_mcf_rx_eth_dst_ucast(48'd0), + .cfg_mcf_rx_check_eth_dst_ucast(1'b0), + .cfg_mcf_rx_eth_src(48'd0), + .cfg_mcf_rx_check_eth_src(1'b0), + .cfg_mcf_rx_eth_type(16'h8808), + .cfg_mcf_rx_opcode_lfc(16'h0001), + .cfg_mcf_rx_check_opcode_lfc(eth_rx_lfc_en[n +: 1]), + .cfg_mcf_rx_opcode_pfc(16'h0101), + .cfg_mcf_rx_check_opcode_pfc(eth_rx_pfc_en[n*8 +: 8] != 0), + .cfg_mcf_rx_forward(1'b0), + .cfg_mcf_rx_enable(eth_rx_lfc_en[n +: 1] || eth_rx_pfc_en[n*8 +: 8]), + .cfg_tx_lfc_eth_dst(48'h01_80_C2_00_00_01), + .cfg_tx_lfc_eth_src(48'h80_23_31_43_54_4C), + .cfg_tx_lfc_eth_type(16'h8808), + .cfg_tx_lfc_opcode(16'h0001), + .cfg_tx_lfc_en(eth_tx_lfc_en[n +: 1]), + .cfg_tx_lfc_quanta(16'hffff), + .cfg_tx_lfc_refresh(16'h7fff), + .cfg_tx_pfc_eth_dst(48'h01_80_C2_00_00_01), + .cfg_tx_pfc_eth_src(48'h80_23_31_43_54_4C), + .cfg_tx_pfc_eth_type(16'h8808), + .cfg_tx_pfc_opcode(16'h0101), + .cfg_tx_pfc_en(eth_tx_pfc_en[n*8 +: 8] != 0), + .cfg_tx_pfc_quanta({8{16'hffff}}), + .cfg_tx_pfc_refresh({8{16'h7fff}}), + .cfg_rx_lfc_opcode(16'h0001), + .cfg_rx_lfc_en(eth_rx_lfc_en[n +: 1]), + .cfg_rx_pfc_opcode(16'h0101), + .cfg_rx_pfc_en(eth_rx_pfc_en[n*8 +: 8] != 0) ); end @@ -876,6 +987,9 @@ mqnic_core_axi #( .TX_CHECKSUM_ENABLE(TX_CHECKSUM_ENABLE), .RX_HASH_ENABLE(RX_HASH_ENABLE), .RX_CHECKSUM_ENABLE(RX_CHECKSUM_ENABLE), + .PFC_ENABLE(PFC_ENABLE), + .LFC_ENABLE(LFC_ENABLE), + .MAC_CTRL_ENABLE(0), .TX_FIFO_DEPTH(TX_FIFO_DEPTH), .RX_FIFO_DEPTH(RX_FIFO_DEPTH), .MAX_TX_SIZE(MAX_TX_SIZE), @@ -1137,7 +1251,13 @@ core_inst ( .s_axis_tx_cpl_valid(axis_eth_tx_ptp_ts_valid), .s_axis_tx_cpl_ready(axis_eth_tx_ptp_ts_ready), + .tx_enable(eth_tx_enable), .tx_status(eth_tx_status), + .tx_lfc_en(eth_tx_lfc_en), + .tx_lfc_req(eth_tx_lfc_req), + .tx_pfc_en(eth_tx_pfc_en), + .tx_pfc_req(eth_tx_pfc_req), + .tx_fc_quanta_clk_en(0), .rx_clk(eth_rx_clk), .rx_rst(eth_rx_rst), @@ -1154,7 +1274,15 @@ core_inst ( .s_axis_rx_tlast(axis_eth_rx_tlast), .s_axis_rx_tuser(axis_eth_rx_tuser), + .rx_enable(eth_rx_enable), .rx_status(eth_rx_status), + .rx_lfc_en(eth_rx_lfc_en), + .rx_lfc_req(eth_rx_lfc_req), + .rx_lfc_ack(eth_rx_lfc_ack), + .rx_pfc_en(eth_rx_pfc_en), + .rx_pfc_req(eth_rx_pfc_req), + .rx_pfc_ack(eth_rx_pfc_ack), + .rx_fc_quanta_clk_en(0), /* * DDR diff --git a/fpga/mqnic/ZCU102/fpga/tb/fpga_core/Makefile b/fpga/mqnic/ZCU102/fpga/tb/fpga_core/Makefile index 4d7c00175..b9f2c0643 100644 --- a/fpga/mqnic/ZCU102/fpga/tb/fpga_core/Makefile +++ b/fpga/mqnic/ZCU102/fpga/tb/fpga_core/Makefile @@ -59,6 +59,10 @@ VERILOG_SOURCES += ../../rtl/common/tdma_ber_ch.v VERILOG_SOURCES += ../../lib/eth/rtl/eth_mac_10g.v VERILOG_SOURCES += ../../lib/eth/rtl/axis_xgmii_rx_64.v VERILOG_SOURCES += ../../lib/eth/rtl/axis_xgmii_tx_64.v +VERILOG_SOURCES += ../../lib/eth/rtl/mac_ctrl_rx.v +VERILOG_SOURCES += ../../lib/eth/rtl/mac_ctrl_tx.v +VERILOG_SOURCES += ../../lib/eth/rtl/mac_pause_ctrl_rx.v +VERILOG_SOURCES += ../../lib/eth/rtl/mac_pause_ctrl_tx.v VERILOG_SOURCES += ../../lib/eth/rtl/lfsr.v VERILOG_SOURCES += ../../lib/eth/rtl/ptp_clock.v VERILOG_SOURCES += ../../lib/eth/rtl/ptp_clock_cdc.v @@ -151,6 +155,8 @@ export PARAM_TX_CPL_FIFO_DEPTH := 32 export PARAM_TX_CHECKSUM_ENABLE := 1 export PARAM_RX_HASH_ENABLE := 1 export PARAM_RX_CHECKSUM_ENABLE := 1 +export PARAM_LFC_ENABLE := 1 +export PARAM_PFC_ENABLE := $(PARAM_LFC_ENABLE) export PARAM_TX_FIFO_DEPTH := 32768 export PARAM_RX_FIFO_DEPTH := 32768 export PARAM_MAX_TX_SIZE := 9214 @@ -196,7 +202,7 @@ export PARAM_AXIS_ETH_TX_FIFO_PIPELINE := 2 export PARAM_AXIS_ETH_TX_TS_PIPELINE := 0 export PARAM_AXIS_ETH_RX_PIPELINE := 0 export PARAM_AXIS_ETH_RX_FIFO_PIPELINE := 2 - + # Statistics counter subsystem export PARAM_STAT_ENABLE := 1 export PARAM_STAT_DMA_ENABLE := 1 diff --git a/fpga/mqnic/ZCU102/fpga/tb/fpga_core/test_fpga_core.py b/fpga/mqnic/ZCU102/fpga/tb/fpga_core/test_fpga_core.py index 88aad45af..a170ecb64 100644 --- a/fpga/mqnic/ZCU102/fpga/tb/fpga_core/test_fpga_core.py +++ b/fpga/mqnic/ZCU102/fpga/tb/fpga_core/test_fpga_core.py @@ -3,6 +3,7 @@ import logging import os +import struct import sys import scapy.utils @@ -19,7 +20,7 @@ from cocotb.triggers import RisingEdge from cocotbext.axi import AddressSpace from cocotbext.axi import AxiLiteMaster, AxiLiteBus from cocotbext.axi import AxiSlave, AxiBus -from cocotbext.eth import XgmiiSource, XgmiiSink +from cocotbext.eth import XgmiiSource, XgmiiSink, XgmiiFrame try: import mqnic @@ -294,6 +295,35 @@ async def run_test_nic(dut): tb.loopback_enable = False + if tb.driver.interfaces[0].if_feature_lfc: + tb.log.info("Test LFC pause frame RX") + + await tb.driver.interfaces[0].ports[0].set_lfc_ctrl(mqnic.MQNIC_PORT_LFC_CTRL_TX_LFC_EN | mqnic.MQNIC_PORT_LFC_CTRL_RX_LFC_EN) + await tb.driver.hw_regs.read_dword(0) + + lfc_xoff = Ether(src='DA:D1:D2:D3:D4:D5', dst='01:80:C2:00:00:01', type=0x8808) / struct.pack('!HH', 0x0001, 2000) + + await tb.sfp_source[0].send(XgmiiFrame.from_payload(bytes(lfc_xoff))) + + count = 16 + + pkts = [bytearray([(x+k) % 256 for x in range(1514)]) for k in range(count)] + + tb.loopback_enable = True + + for p in pkts: + await tb.driver.interfaces[0].start_xmit(p, 0) + + for k in range(count): + pkt = await tb.driver.interfaces[0].recv() + + tb.log.info("Packet: %s", pkt) + assert pkt.data == pkts[k] + if tb.driver.interfaces[0].if_feature_rx_csum: + assert pkt.rx_checksum == ~scapy.utils.checksum(bytes(pkt.data[14:])) & 0xffff + + tb.loopback_enable = False + await RisingEdge(dut.clk_300mhz) await RisingEdge(dut.clk_300mhz) @@ -363,6 +393,10 @@ def test_fpga_core(request): os.path.join(eth_rtl_dir, "eth_mac_10g.v"), os.path.join(eth_rtl_dir, "axis_xgmii_rx_64.v"), os.path.join(eth_rtl_dir, "axis_xgmii_tx_64.v"), + os.path.join(eth_rtl_dir, "mac_ctrl_rx.v"), + os.path.join(eth_rtl_dir, "mac_ctrl_tx.v"), + os.path.join(eth_rtl_dir, "mac_pause_ctrl_rx.v"), + os.path.join(eth_rtl_dir, "mac_pause_ctrl_tx.v"), os.path.join(eth_rtl_dir, "lfsr.v"), os.path.join(eth_rtl_dir, "ptp_clock.v"), os.path.join(eth_rtl_dir, "ptp_clock_cdc.v"), @@ -456,6 +490,8 @@ def test_fpga_core(request): parameters['TX_CHECKSUM_ENABLE'] = 1 parameters['RX_HASH_ENABLE'] = 1 parameters['RX_CHECKSUM_ENABLE'] = 1 + parameters['LFC_ENABLE'] = 1 + parameters['PFC_ENABLE'] = parameters['LFC_ENABLE'] parameters['TX_FIFO_DEPTH'] = 32768 parameters['RX_FIFO_DEPTH'] = 32768 parameters['MAX_TX_SIZE'] = 9214 diff --git a/fpga/mqnic/ZCU106/fpga_pcie/fpga/Makefile b/fpga/mqnic/ZCU106/fpga_pcie/fpga/Makefile index af385dc81..23862a523 100644 --- a/fpga/mqnic/ZCU106/fpga_pcie/fpga/Makefile +++ b/fpga/mqnic/ZCU106/fpga_pcie/fpga/Makefile @@ -62,6 +62,10 @@ SYN_FILES += rtl/common/tdma_ber_ch.v SYN_FILES += lib/eth/rtl/eth_mac_10g.v SYN_FILES += lib/eth/rtl/axis_xgmii_rx_64.v SYN_FILES += lib/eth/rtl/axis_xgmii_tx_64.v +SYN_FILES += lib/eth/rtl/mac_ctrl_rx.v +SYN_FILES += lib/eth/rtl/mac_ctrl_tx.v +SYN_FILES += lib/eth/rtl/mac_pause_ctrl_rx.v +SYN_FILES += lib/eth/rtl/mac_pause_ctrl_tx.v SYN_FILES += lib/eth/rtl/eth_phy_10g.v SYN_FILES += lib/eth/rtl/eth_phy_10g_rx.v SYN_FILES += lib/eth/rtl/eth_phy_10g_rx_if.v diff --git a/fpga/mqnic/ZCU106/fpga_pcie/fpga/config.tcl b/fpga/mqnic/ZCU106/fpga_pcie/fpga/config.tcl index 6b7bfdb52..7d3d2a36f 100644 --- a/fpga/mqnic/ZCU106/fpga_pcie/fpga/config.tcl +++ b/fpga/mqnic/ZCU106/fpga_pcie/fpga/config.tcl @@ -104,6 +104,8 @@ dict set params TX_CPL_FIFO_DEPTH "32" dict set params TX_CHECKSUM_ENABLE "1" dict set params RX_HASH_ENABLE "1" dict set params RX_CHECKSUM_ENABLE "1" +dict set params PFC_ENABLE "1" +dict set params LFC_ENABLE [dict get $params PFC_ENABLE] dict set params ENABLE_PADDING "1" dict set params ENABLE_DIC "1" dict set params MIN_FRAME_LENGTH "64" diff --git a/fpga/mqnic/ZCU106/fpga_pcie/fpga_app_dma_bench/Makefile b/fpga/mqnic/ZCU106/fpga_pcie/fpga_app_dma_bench/Makefile index 010eef440..f11f4ee60 100644 --- a/fpga/mqnic/ZCU106/fpga_pcie/fpga_app_dma_bench/Makefile +++ b/fpga/mqnic/ZCU106/fpga_pcie/fpga_app_dma_bench/Makefile @@ -65,6 +65,10 @@ SYN_FILES += app/dma_bench/rtl/dram_test_ch.v SYN_FILES += lib/eth/rtl/eth_mac_10g.v SYN_FILES += lib/eth/rtl/axis_xgmii_rx_64.v SYN_FILES += lib/eth/rtl/axis_xgmii_tx_64.v +SYN_FILES += lib/eth/rtl/mac_ctrl_rx.v +SYN_FILES += lib/eth/rtl/mac_ctrl_tx.v +SYN_FILES += lib/eth/rtl/mac_pause_ctrl_rx.v +SYN_FILES += lib/eth/rtl/mac_pause_ctrl_tx.v SYN_FILES += lib/eth/rtl/eth_phy_10g.v SYN_FILES += lib/eth/rtl/eth_phy_10g_rx.v SYN_FILES += lib/eth/rtl/eth_phy_10g_rx_if.v diff --git a/fpga/mqnic/ZCU106/fpga_pcie/fpga_app_dma_bench/config.tcl b/fpga/mqnic/ZCU106/fpga_pcie/fpga_app_dma_bench/config.tcl index 37268c1e2..4fcdb331e 100644 --- a/fpga/mqnic/ZCU106/fpga_pcie/fpga_app_dma_bench/config.tcl +++ b/fpga/mqnic/ZCU106/fpga_pcie/fpga_app_dma_bench/config.tcl @@ -104,6 +104,8 @@ dict set params TX_CPL_FIFO_DEPTH "32" dict set params TX_CHECKSUM_ENABLE "1" dict set params RX_HASH_ENABLE "1" dict set params RX_CHECKSUM_ENABLE "1" +dict set params PFC_ENABLE "1" +dict set params LFC_ENABLE [dict get $params PFC_ENABLE] dict set params ENABLE_PADDING "1" dict set params ENABLE_DIC "1" dict set params MIN_FRAME_LENGTH "64" diff --git a/fpga/mqnic/ZCU106/fpga_zynqmp/fpga/Makefile b/fpga/mqnic/ZCU106/fpga_zynqmp/fpga/Makefile index 9741bc7c1..d03db2aeb 100644 --- a/fpga/mqnic/ZCU106/fpga_zynqmp/fpga/Makefile +++ b/fpga/mqnic/ZCU106/fpga_zynqmp/fpga/Makefile @@ -58,6 +58,10 @@ SYN_FILES += rtl/common/tdma_ber_ch.v SYN_FILES += lib/eth/rtl/eth_mac_10g.v SYN_FILES += lib/eth/rtl/axis_xgmii_rx_64.v SYN_FILES += lib/eth/rtl/axis_xgmii_tx_64.v +SYN_FILES += lib/eth/rtl/mac_ctrl_rx.v +SYN_FILES += lib/eth/rtl/mac_ctrl_tx.v +SYN_FILES += lib/eth/rtl/mac_pause_ctrl_rx.v +SYN_FILES += lib/eth/rtl/mac_pause_ctrl_tx.v SYN_FILES += lib/eth/rtl/eth_phy_10g.v SYN_FILES += lib/eth/rtl/eth_phy_10g_rx.v SYN_FILES += lib/eth/rtl/eth_phy_10g_rx_if.v diff --git a/fpga/mqnic/ZCU106/fpga_zynqmp/fpga/config.tcl b/fpga/mqnic/ZCU106/fpga_zynqmp/fpga/config.tcl index 8811a4205..e3ec6e9a0 100644 --- a/fpga/mqnic/ZCU106/fpga_zynqmp/fpga/config.tcl +++ b/fpga/mqnic/ZCU106/fpga_zynqmp/fpga/config.tcl @@ -96,6 +96,8 @@ dict set params TX_CPL_FIFO_DEPTH "32" dict set params TX_CHECKSUM_ENABLE "1" dict set params RX_HASH_ENABLE "1" dict set params RX_CHECKSUM_ENABLE "1" +dict set params PFC_ENABLE "1" +dict set params LFC_ENABLE [dict get $params PFC_ENABLE] dict set params ENABLE_PADDING "1" dict set params ENABLE_DIC "1" dict set params MIN_FRAME_LENGTH "64" diff --git a/fpga/mqnic/ZCU106/fpga_zynqmp/fpga_app_dma_bench/Makefile b/fpga/mqnic/ZCU106/fpga_zynqmp/fpga_app_dma_bench/Makefile index 7be215839..0580e2859 100644 --- a/fpga/mqnic/ZCU106/fpga_zynqmp/fpga_app_dma_bench/Makefile +++ b/fpga/mqnic/ZCU106/fpga_zynqmp/fpga_app_dma_bench/Makefile @@ -61,6 +61,10 @@ SYN_FILES += app/dma_bench/rtl/dram_test_ch.v SYN_FILES += lib/eth/rtl/eth_mac_10g.v SYN_FILES += lib/eth/rtl/axis_xgmii_rx_64.v SYN_FILES += lib/eth/rtl/axis_xgmii_tx_64.v +SYN_FILES += lib/eth/rtl/mac_ctrl_rx.v +SYN_FILES += lib/eth/rtl/mac_ctrl_tx.v +SYN_FILES += lib/eth/rtl/mac_pause_ctrl_rx.v +SYN_FILES += lib/eth/rtl/mac_pause_ctrl_tx.v SYN_FILES += lib/eth/rtl/eth_phy_10g.v SYN_FILES += lib/eth/rtl/eth_phy_10g_rx.v SYN_FILES += lib/eth/rtl/eth_phy_10g_rx_if.v diff --git a/fpga/mqnic/ZCU106/fpga_zynqmp/fpga_app_dma_bench/config.tcl b/fpga/mqnic/ZCU106/fpga_zynqmp/fpga_app_dma_bench/config.tcl index 61dbb9702..c875f3e52 100644 --- a/fpga/mqnic/ZCU106/fpga_zynqmp/fpga_app_dma_bench/config.tcl +++ b/fpga/mqnic/ZCU106/fpga_zynqmp/fpga_app_dma_bench/config.tcl @@ -96,6 +96,8 @@ dict set params TX_CPL_FIFO_DEPTH "32" dict set params TX_CHECKSUM_ENABLE "1" dict set params RX_HASH_ENABLE "1" dict set params RX_CHECKSUM_ENABLE "1" +dict set params PFC_ENABLE "1" +dict set params LFC_ENABLE [dict get $params PFC_ENABLE] dict set params ENABLE_PADDING "1" dict set params ENABLE_DIC "1" dict set params MIN_FRAME_LENGTH "64" diff --git a/fpga/mqnic/ZCU106/fpga_zynqmp/rtl/fpga.v b/fpga/mqnic/ZCU106/fpga_zynqmp/rtl/fpga.v index fd445391e..3f9660e74 100644 --- a/fpga/mqnic/ZCU106/fpga_zynqmp/rtl/fpga.v +++ b/fpga/mqnic/ZCU106/fpga_zynqmp/rtl/fpga.v @@ -75,6 +75,8 @@ module fpga # parameter TX_CHECKSUM_ENABLE = 1, parameter RX_HASH_ENABLE = 1, parameter RX_CHECKSUM_ENABLE = 1, + parameter PFC_ENABLE = 1, + parameter LFC_ENABLE = PFC_ENABLE, parameter ENABLE_PADDING = 1, parameter ENABLE_DIC = 1, parameter MIN_FRAME_LENGTH = 64, @@ -934,6 +936,8 @@ fpga_core #( .TX_CHECKSUM_ENABLE(TX_CHECKSUM_ENABLE), .RX_HASH_ENABLE(RX_HASH_ENABLE), .RX_CHECKSUM_ENABLE(RX_CHECKSUM_ENABLE), + .PFC_ENABLE(PFC_ENABLE), + .LFC_ENABLE(LFC_ENABLE), .ENABLE_PADDING(ENABLE_PADDING), .ENABLE_DIC(ENABLE_DIC), .MIN_FRAME_LENGTH(MIN_FRAME_LENGTH), diff --git a/fpga/mqnic/ZCU106/fpga_zynqmp/rtl/fpga_core.v b/fpga/mqnic/ZCU106/fpga_zynqmp/rtl/fpga_core.v index 333ec6961..0230ae45e 100644 --- a/fpga/mqnic/ZCU106/fpga_zynqmp/rtl/fpga_core.v +++ b/fpga/mqnic/ZCU106/fpga_zynqmp/rtl/fpga_core.v @@ -82,6 +82,8 @@ module fpga_core # parameter TX_CHECKSUM_ENABLE = 1, parameter RX_HASH_ENABLE = 1, parameter RX_CHECKSUM_ENABLE = 1, + parameter PFC_ENABLE = 1, + parameter LFC_ENABLE = PFC_ENABLE, parameter ENABLE_PADDING = 1, parameter ENABLE_DIC = 1, parameter MIN_FRAME_LENGTH = 64, @@ -625,7 +627,12 @@ wire [PORT_COUNT*TX_TAG_WIDTH-1:0] axis_eth_tx_ptp_ts_tag; wire [PORT_COUNT-1:0] axis_eth_tx_ptp_ts_valid; wire [PORT_COUNT-1:0] axis_eth_tx_ptp_ts_ready; +wire [PORT_COUNT-1:0] eth_tx_enable; wire [PORT_COUNT-1:0] eth_tx_status; +wire [PORT_COUNT-1:0] eth_tx_lfc_en; +wire [PORT_COUNT-1:0] eth_tx_lfc_req; +wire [PORT_COUNT*8-1:0] eth_tx_pfc_en; +wire [PORT_COUNT*8-1:0] eth_tx_pfc_req; wire [PORT_COUNT-1:0] eth_rx_clk; wire [PORT_COUNT-1:0] eth_rx_rst; @@ -640,7 +647,14 @@ wire [PORT_COUNT-1:0] axis_eth_rx_tready; wire [PORT_COUNT-1:0] axis_eth_rx_tlast; wire [PORT_COUNT*AXIS_ETH_RX_USER_WIDTH-1:0] axis_eth_rx_tuser; +wire [PORT_COUNT-1:0] eth_rx_enable; wire [PORT_COUNT-1:0] eth_rx_status; +wire [PORT_COUNT-1:0] eth_rx_lfc_en; +wire [PORT_COUNT-1:0] eth_rx_lfc_req; +wire [PORT_COUNT-1:0] eth_rx_lfc_ack; +wire [PORT_COUNT*8-1:0] eth_rx_pfc_en; +wire [PORT_COUNT*8-1:0] eth_rx_pfc_req; +wire [PORT_COUNT*8-1:0] eth_rx_pfc_ack; wire [PORT_COUNT-1:0] port_xgmii_tx_clk; wire [PORT_COUNT-1:0] port_xgmii_tx_rst; @@ -713,12 +727,15 @@ generate .PTP_PERIOD_FNS(IF_PTP_PERIOD_FNS), .TX_PTP_TS_ENABLE(PTP_TS_ENABLE), .TX_PTP_TS_WIDTH(PTP_TS_WIDTH), + .TX_PTP_TS_CTRL_IN_TUSER(0), .TX_PTP_TAG_ENABLE(PTP_TS_ENABLE), .TX_PTP_TAG_WIDTH(TX_TAG_WIDTH), .RX_PTP_TS_ENABLE(PTP_TS_ENABLE), .RX_PTP_TS_WIDTH(PTP_TS_WIDTH), .TX_USER_WIDTH(AXIS_ETH_TX_USER_WIDTH), - .RX_USER_WIDTH(AXIS_ETH_RX_USER_WIDTH) + .RX_USER_WIDTH(AXIS_ETH_RX_USER_WIDTH), + .PFC_ENABLE(PFC_ENABLE), + .PAUSE_ENABLE(LFC_ENABLE) ) eth_mac_inst ( .tx_clk(port_xgmii_tx_clk[n]), @@ -726,6 +743,9 @@ generate .rx_clk(port_xgmii_rx_clk[n]), .rx_rst(port_xgmii_rx_rst[n]), + /* + * AXI input + */ .tx_axis_tdata(axis_eth_tx_tdata[n*AXIS_ETH_DATA_WIDTH +: AXIS_ETH_DATA_WIDTH]), .tx_axis_tkeep(axis_eth_tx_tkeep[n*AXIS_ETH_KEEP_WIDTH +: AXIS_ETH_KEEP_WIDTH]), .tx_axis_tvalid(axis_eth_tx_tvalid[n +: 1]), @@ -733,30 +753,121 @@ generate .tx_axis_tlast(axis_eth_tx_tlast[n +: 1]), .tx_axis_tuser(axis_eth_tx_tuser[n*AXIS_ETH_TX_USER_WIDTH +: AXIS_ETH_TX_USER_WIDTH]), + /* + * AXI output + */ .rx_axis_tdata(axis_eth_rx_tdata[n*AXIS_ETH_DATA_WIDTH +: AXIS_ETH_DATA_WIDTH]), .rx_axis_tkeep(axis_eth_rx_tkeep[n*AXIS_ETH_KEEP_WIDTH +: AXIS_ETH_KEEP_WIDTH]), .rx_axis_tvalid(axis_eth_rx_tvalid[n +: 1]), .rx_axis_tlast(axis_eth_rx_tlast[n +: 1]), .rx_axis_tuser(axis_eth_rx_tuser[n*AXIS_ETH_RX_USER_WIDTH +: AXIS_ETH_RX_USER_WIDTH]), + /* + * XGMII interface + */ .xgmii_rxd(port_xgmii_rxd[n*XGMII_DATA_WIDTH +: XGMII_DATA_WIDTH]), .xgmii_rxc(port_xgmii_rxc[n*XGMII_CTRL_WIDTH +: XGMII_CTRL_WIDTH]), .xgmii_txd(port_xgmii_txd[n*XGMII_DATA_WIDTH +: XGMII_DATA_WIDTH]), .xgmii_txc(port_xgmii_txc[n*XGMII_CTRL_WIDTH +: XGMII_CTRL_WIDTH]), + /* + * PTP + */ .tx_ptp_ts(eth_tx_ptp_ts_96[n*PTP_TS_WIDTH +: PTP_TS_WIDTH]), .rx_ptp_ts(eth_rx_ptp_ts_96[n*PTP_TS_WIDTH +: PTP_TS_WIDTH]), .tx_axis_ptp_ts(axis_eth_tx_ptp_ts[n*PTP_TS_WIDTH +: PTP_TS_WIDTH]), .tx_axis_ptp_ts_tag(axis_eth_tx_ptp_ts_tag[n*TX_TAG_WIDTH +: TX_TAG_WIDTH]), .tx_axis_ptp_ts_valid(axis_eth_tx_ptp_ts_valid[n +: 1]), + /* + * Link-level Flow Control (LFC) (IEEE 802.3 annex 31B PAUSE) + */ + .tx_lfc_req(eth_tx_lfc_req[n +: 1]), + .tx_lfc_resend(1'b0), + .rx_lfc_en(eth_rx_lfc_en[n +: 1]), + .rx_lfc_req(eth_rx_lfc_req[n +: 1]), + .rx_lfc_ack(eth_rx_lfc_ack[n +: 1]), + + /* + * Priority Flow Control (PFC) (IEEE 802.3 annex 31D PFC) + */ + .tx_pfc_req(eth_tx_pfc_req[n*8 +: 8]), + .tx_pfc_resend(1'b0), + .rx_pfc_en(eth_rx_pfc_en[n*8 +: 8]), + .rx_pfc_req(eth_rx_pfc_req[n*8 +: 8]), + .rx_pfc_ack(eth_rx_pfc_ack[n*8 +: 8]), + + /* + * Pause interface + */ + .tx_lfc_pause_en(1'b1), + .tx_pause_req(1'b0), + .tx_pause_ack(), + + /* + * Status + */ + .tx_start_packet(), .tx_error_underflow(), + .rx_start_packet(), .rx_error_bad_frame(), .rx_error_bad_fcs(), + .stat_tx_mcf(), + .stat_rx_mcf(), + .stat_tx_lfc_pkt(), + .stat_tx_lfc_xon(), + .stat_tx_lfc_xoff(), + .stat_tx_lfc_paused(), + .stat_tx_pfc_pkt(), + .stat_tx_pfc_xon(), + .stat_tx_pfc_xoff(), + .stat_tx_pfc_paused(), + .stat_rx_lfc_pkt(), + .stat_rx_lfc_xon(), + .stat_rx_lfc_xoff(), + .stat_rx_lfc_paused(), + .stat_rx_pfc_pkt(), + .stat_rx_pfc_xon(), + .stat_rx_pfc_xoff(), + .stat_rx_pfc_paused(), + /* + * Configuration + */ .cfg_ifg(8'd12), - .cfg_tx_enable(1'b1), - .cfg_rx_enable(1'b1) + .cfg_tx_enable(eth_tx_enable[n +: 1]), + .cfg_rx_enable(eth_rx_enable[n +: 1]), + .cfg_mcf_rx_eth_dst_mcast(48'h01_80_C2_00_00_01), + .cfg_mcf_rx_check_eth_dst_mcast(1'b1), + .cfg_mcf_rx_eth_dst_ucast(48'd0), + .cfg_mcf_rx_check_eth_dst_ucast(1'b0), + .cfg_mcf_rx_eth_src(48'd0), + .cfg_mcf_rx_check_eth_src(1'b0), + .cfg_mcf_rx_eth_type(16'h8808), + .cfg_mcf_rx_opcode_lfc(16'h0001), + .cfg_mcf_rx_check_opcode_lfc(eth_rx_lfc_en[n +: 1]), + .cfg_mcf_rx_opcode_pfc(16'h0101), + .cfg_mcf_rx_check_opcode_pfc(eth_rx_pfc_en[n*8 +: 8] != 0), + .cfg_mcf_rx_forward(1'b0), + .cfg_mcf_rx_enable(eth_rx_lfc_en[n +: 1] || eth_rx_pfc_en[n*8 +: 8]), + .cfg_tx_lfc_eth_dst(48'h01_80_C2_00_00_01), + .cfg_tx_lfc_eth_src(48'h80_23_31_43_54_4C), + .cfg_tx_lfc_eth_type(16'h8808), + .cfg_tx_lfc_opcode(16'h0001), + .cfg_tx_lfc_en(eth_tx_lfc_en[n +: 1]), + .cfg_tx_lfc_quanta(16'hffff), + .cfg_tx_lfc_refresh(16'h7fff), + .cfg_tx_pfc_eth_dst(48'h01_80_C2_00_00_01), + .cfg_tx_pfc_eth_src(48'h80_23_31_43_54_4C), + .cfg_tx_pfc_eth_type(16'h8808), + .cfg_tx_pfc_opcode(16'h0101), + .cfg_tx_pfc_en(eth_tx_pfc_en[n*8 +: 8] != 0), + .cfg_tx_pfc_quanta({8{16'hffff}}), + .cfg_tx_pfc_refresh({8{16'h7fff}}), + .cfg_rx_lfc_opcode(16'h0001), + .cfg_rx_lfc_en(eth_rx_lfc_en[n +: 1]), + .cfg_rx_pfc_opcode(16'h0101), + .cfg_rx_pfc_en(eth_rx_pfc_en[n*8 +: 8] != 0) ); end @@ -830,6 +941,9 @@ mqnic_core_axi #( .TX_CHECKSUM_ENABLE(TX_CHECKSUM_ENABLE), .RX_HASH_ENABLE(RX_HASH_ENABLE), .RX_CHECKSUM_ENABLE(RX_CHECKSUM_ENABLE), + .PFC_ENABLE(PFC_ENABLE), + .LFC_ENABLE(LFC_ENABLE), + .MAC_CTRL_ENABLE(0), .TX_FIFO_DEPTH(TX_FIFO_DEPTH), .RX_FIFO_DEPTH(RX_FIFO_DEPTH), .MAX_TX_SIZE(MAX_TX_SIZE), @@ -1091,7 +1205,13 @@ core_inst ( .s_axis_tx_cpl_valid(axis_eth_tx_ptp_ts_valid), .s_axis_tx_cpl_ready(axis_eth_tx_ptp_ts_ready), + .tx_enable(eth_tx_enable), .tx_status(eth_tx_status), + .tx_lfc_en(eth_tx_lfc_en), + .tx_lfc_req(eth_tx_lfc_req), + .tx_pfc_en(eth_tx_pfc_en), + .tx_pfc_req(eth_tx_pfc_req), + .tx_fc_quanta_clk_en(0), .rx_clk(eth_rx_clk), .rx_rst(eth_rx_rst), @@ -1108,7 +1228,15 @@ core_inst ( .s_axis_rx_tlast(axis_eth_rx_tlast), .s_axis_rx_tuser(axis_eth_rx_tuser), + .rx_enable(eth_rx_enable), .rx_status(eth_rx_status), + .rx_lfc_en(eth_rx_lfc_en), + .rx_lfc_req(eth_rx_lfc_req), + .rx_lfc_ack(eth_rx_lfc_ack), + .rx_pfc_en(eth_rx_pfc_en), + .rx_pfc_req(eth_rx_pfc_req), + .rx_pfc_ack(eth_rx_pfc_ack), + .rx_fc_quanta_clk_en(0), /* * DDR diff --git a/fpga/mqnic/ZCU106/fpga_zynqmp/tb/fpga_core/Makefile b/fpga/mqnic/ZCU106/fpga_zynqmp/tb/fpga_core/Makefile index 4d7c00175..b9f2c0643 100644 --- a/fpga/mqnic/ZCU106/fpga_zynqmp/tb/fpga_core/Makefile +++ b/fpga/mqnic/ZCU106/fpga_zynqmp/tb/fpga_core/Makefile @@ -59,6 +59,10 @@ VERILOG_SOURCES += ../../rtl/common/tdma_ber_ch.v VERILOG_SOURCES += ../../lib/eth/rtl/eth_mac_10g.v VERILOG_SOURCES += ../../lib/eth/rtl/axis_xgmii_rx_64.v VERILOG_SOURCES += ../../lib/eth/rtl/axis_xgmii_tx_64.v +VERILOG_SOURCES += ../../lib/eth/rtl/mac_ctrl_rx.v +VERILOG_SOURCES += ../../lib/eth/rtl/mac_ctrl_tx.v +VERILOG_SOURCES += ../../lib/eth/rtl/mac_pause_ctrl_rx.v +VERILOG_SOURCES += ../../lib/eth/rtl/mac_pause_ctrl_tx.v VERILOG_SOURCES += ../../lib/eth/rtl/lfsr.v VERILOG_SOURCES += ../../lib/eth/rtl/ptp_clock.v VERILOG_SOURCES += ../../lib/eth/rtl/ptp_clock_cdc.v @@ -151,6 +155,8 @@ export PARAM_TX_CPL_FIFO_DEPTH := 32 export PARAM_TX_CHECKSUM_ENABLE := 1 export PARAM_RX_HASH_ENABLE := 1 export PARAM_RX_CHECKSUM_ENABLE := 1 +export PARAM_LFC_ENABLE := 1 +export PARAM_PFC_ENABLE := $(PARAM_LFC_ENABLE) export PARAM_TX_FIFO_DEPTH := 32768 export PARAM_RX_FIFO_DEPTH := 32768 export PARAM_MAX_TX_SIZE := 9214 @@ -196,7 +202,7 @@ export PARAM_AXIS_ETH_TX_FIFO_PIPELINE := 2 export PARAM_AXIS_ETH_TX_TS_PIPELINE := 0 export PARAM_AXIS_ETH_RX_PIPELINE := 0 export PARAM_AXIS_ETH_RX_FIFO_PIPELINE := 2 - + # Statistics counter subsystem export PARAM_STAT_ENABLE := 1 export PARAM_STAT_DMA_ENABLE := 1 diff --git a/fpga/mqnic/ZCU106/fpga_zynqmp/tb/fpga_core/test_fpga_core.py b/fpga/mqnic/ZCU106/fpga_zynqmp/tb/fpga_core/test_fpga_core.py index 8ae832739..7aa0f532c 100644 --- a/fpga/mqnic/ZCU106/fpga_zynqmp/tb/fpga_core/test_fpga_core.py +++ b/fpga/mqnic/ZCU106/fpga_zynqmp/tb/fpga_core/test_fpga_core.py @@ -3,6 +3,7 @@ import logging import os +import struct import sys import scapy.utils @@ -19,7 +20,7 @@ from cocotb.triggers import RisingEdge from cocotbext.axi import AddressSpace from cocotbext.axi import AxiLiteMaster, AxiLiteBus from cocotbext.axi import AxiSlave, AxiBus -from cocotbext.eth import XgmiiSource, XgmiiSink +from cocotbext.eth import XgmiiSource, XgmiiSink, XgmiiFrame try: import mqnic @@ -294,6 +295,35 @@ async def run_test_nic(dut): tb.loopback_enable = False + if tb.driver.interfaces[0].if_feature_lfc: + tb.log.info("Test LFC pause frame RX") + + await tb.driver.interfaces[0].ports[0].set_lfc_ctrl(mqnic.MQNIC_PORT_LFC_CTRL_TX_LFC_EN | mqnic.MQNIC_PORT_LFC_CTRL_RX_LFC_EN) + await tb.driver.hw_regs.read_dword(0) + + lfc_xoff = Ether(src='DA:D1:D2:D3:D4:D5', dst='01:80:C2:00:00:01', type=0x8808) / struct.pack('!HH', 0x0001, 2000) + + await tb.sfp_source[0].send(XgmiiFrame.from_payload(bytes(lfc_xoff))) + + count = 16 + + pkts = [bytearray([(x+k) % 256 for x in range(1514)]) for k in range(count)] + + tb.loopback_enable = True + + for p in pkts: + await tb.driver.interfaces[0].start_xmit(p, 0) + + for k in range(count): + pkt = await tb.driver.interfaces[0].recv() + + tb.log.info("Packet: %s", pkt) + assert pkt.data == pkts[k] + if tb.driver.interfaces[0].if_feature_rx_csum: + assert pkt.rx_checksum == ~scapy.utils.checksum(bytes(pkt.data[14:])) & 0xffff + + tb.loopback_enable = False + await RisingEdge(dut.clk_300mhz) await RisingEdge(dut.clk_300mhz) @@ -363,6 +393,10 @@ def test_fpga_core(request): os.path.join(eth_rtl_dir, "eth_mac_10g.v"), os.path.join(eth_rtl_dir, "axis_xgmii_rx_64.v"), os.path.join(eth_rtl_dir, "axis_xgmii_tx_64.v"), + os.path.join(eth_rtl_dir, "mac_ctrl_rx.v"), + os.path.join(eth_rtl_dir, "mac_ctrl_tx.v"), + os.path.join(eth_rtl_dir, "mac_pause_ctrl_rx.v"), + os.path.join(eth_rtl_dir, "mac_pause_ctrl_tx.v"), os.path.join(eth_rtl_dir, "lfsr.v"), os.path.join(eth_rtl_dir, "ptp_clock.v"), os.path.join(eth_rtl_dir, "ptp_clock_cdc.v"), @@ -456,6 +490,8 @@ def test_fpga_core(request): parameters['TX_CHECKSUM_ENABLE'] = 1 parameters['RX_HASH_ENABLE'] = 1 parameters['RX_CHECKSUM_ENABLE'] = 1 + parameters['LFC_ENABLE'] = 1 + parameters['PFC_ENABLE'] = parameters['LFC_ENABLE'] parameters['TX_FIFO_DEPTH'] = 32768 parameters['RX_FIFO_DEPTH'] = 32768 parameters['MAX_TX_SIZE'] = 9214 diff --git a/fpga/mqnic/fb2CG/fpga_100g/fpga/config.tcl b/fpga/mqnic/fb2CG/fpga_100g/fpga/config.tcl index d1d5e876b..02c8bfcbe 100644 --- a/fpga/mqnic/fb2CG/fpga_100g/fpga/config.tcl +++ b/fpga/mqnic/fb2CG/fpga_100g/fpga/config.tcl @@ -101,6 +101,8 @@ dict set params TX_CPL_FIFO_DEPTH "32" dict set params TX_CHECKSUM_ENABLE "1" dict set params RX_HASH_ENABLE "1" dict set params RX_CHECKSUM_ENABLE "1" +dict set params PFC_ENABLE "1" +dict set params LFC_ENABLE [dict get $params PFC_ENABLE] dict set params TX_FIFO_DEPTH "32768" dict set params RX_FIFO_DEPTH "131072" dict set params MAX_TX_SIZE "9214" diff --git a/fpga/mqnic/fb2CG/fpga_100g/fpga_app_dma_bench/config.tcl b/fpga/mqnic/fb2CG/fpga_100g/fpga_app_dma_bench/config.tcl index 1588afe04..06617eff7 100644 --- a/fpga/mqnic/fb2CG/fpga_100g/fpga_app_dma_bench/config.tcl +++ b/fpga/mqnic/fb2CG/fpga_100g/fpga_app_dma_bench/config.tcl @@ -101,6 +101,8 @@ dict set params TX_CPL_FIFO_DEPTH "32" dict set params TX_CHECKSUM_ENABLE "1" dict set params RX_HASH_ENABLE "1" dict set params RX_CHECKSUM_ENABLE "1" +dict set params PFC_ENABLE "1" +dict set params LFC_ENABLE [dict get $params PFC_ENABLE] dict set params TX_FIFO_DEPTH "32768" dict set params RX_FIFO_DEPTH "131072" dict set params MAX_TX_SIZE "9214" diff --git a/fpga/mqnic/fb2CG/fpga_100g/fpga_app_template/config.tcl b/fpga/mqnic/fb2CG/fpga_100g/fpga_app_template/config.tcl index 743de3565..e30654bc9 100644 --- a/fpga/mqnic/fb2CG/fpga_100g/fpga_app_template/config.tcl +++ b/fpga/mqnic/fb2CG/fpga_100g/fpga_app_template/config.tcl @@ -101,6 +101,8 @@ dict set params TX_CPL_FIFO_DEPTH "32" dict set params TX_CHECKSUM_ENABLE "1" dict set params RX_HASH_ENABLE "1" dict set params RX_CHECKSUM_ENABLE "1" +dict set params PFC_ENABLE "1" +dict set params LFC_ENABLE [dict get $params PFC_ENABLE] dict set params TX_FIFO_DEPTH "32768" dict set params RX_FIFO_DEPTH "131072" dict set params MAX_TX_SIZE "9214" diff --git a/fpga/mqnic/fb2CG/fpga_100g/fpga_tdma/config.tcl b/fpga/mqnic/fb2CG/fpga_100g/fpga_tdma/config.tcl index 521f7321d..5b152e876 100644 --- a/fpga/mqnic/fb2CG/fpga_100g/fpga_tdma/config.tcl +++ b/fpga/mqnic/fb2CG/fpga_100g/fpga_tdma/config.tcl @@ -101,6 +101,8 @@ dict set params TX_CPL_FIFO_DEPTH "32" dict set params TX_CHECKSUM_ENABLE "1" dict set params RX_HASH_ENABLE "1" dict set params RX_CHECKSUM_ENABLE "1" +dict set params PFC_ENABLE "1" +dict set params LFC_ENABLE [dict get $params PFC_ENABLE] dict set params TX_FIFO_DEPTH "32768" dict set params RX_FIFO_DEPTH "131072" dict set params MAX_TX_SIZE "9214" diff --git a/fpga/mqnic/fb2CG/fpga_100g/ip/cmac_usplus.tcl b/fpga/mqnic/fb2CG/fpga_100g/ip/cmac_usplus.tcl index b86d4ea5e..af9cc8265 100644 --- a/fpga/mqnic/fb2CG/fpga_100g/ip/cmac_usplus.tcl +++ b/fpga/mqnic/fb2CG/fpga_100g/ip/cmac_usplus.tcl @@ -7,8 +7,10 @@ set_property -dict [list \ CONFIG.USER_INTERFACE {AXIS} \ CONFIG.GT_DRP_CLK {125} \ CONFIG.GT_LOCATION {0} \ - CONFIG.TX_FLOW_CONTROL {0} \ - CONFIG.RX_FLOW_CONTROL {0} \ + CONFIG.TX_FLOW_CONTROL {1} \ + CONFIG.RX_FLOW_CONTROL {1} \ + CONFIG.RX_FORWARD_CONTROL_FRAMES {0} \ + CONFIG.RX_CHECK_ACK {1} \ CONFIG.INCLUDE_RS_FEC {1} \ CONFIG.ENABLE_TIME_STAMPING {1} ] [get_ips cmac_usplus] diff --git a/fpga/mqnic/fb2CG/fpga_100g/rtl/fpga.v b/fpga/mqnic/fb2CG/fpga_100g/rtl/fpga.v index b1638bc72..4bcc6d8ce 100644 --- a/fpga/mqnic/fb2CG/fpga_100g/rtl/fpga.v +++ b/fpga/mqnic/fb2CG/fpga_100g/rtl/fpga.v @@ -71,6 +71,8 @@ module fpga # parameter TX_CHECKSUM_ENABLE = 1, parameter RX_HASH_ENABLE = 1, parameter RX_CHECKSUM_ENABLE = 1, + parameter PFC_ENABLE = 1, + parameter LFC_ENABLE = PFC_ENABLE, parameter TX_FIFO_DEPTH = 32768, parameter RX_FIFO_DEPTH = 131072, parameter MAX_TX_SIZE = 9214, @@ -989,7 +991,20 @@ wire qsfp_0_drp_we; wire [15:0] qsfp_0_drp_do; wire qsfp_0_drp_rdy; -wire qsfp_0_rx_status; +wire qsfp_0_tx_enable; +wire qsfp_0_tx_lfc_en; +wire qsfp_0_tx_lfc_req; +wire [7:0] qsfp_0_tx_pfc_en; +wire [7:0] qsfp_0_tx_pfc_req; + +wire qsfp_0_rx_enable; +wire qsfp_0_rx_status; +wire qsfp_0_rx_lfc_en; +wire qsfp_0_rx_lfc_req; +wire qsfp_0_rx_lfc_ack; +wire [7:0] qsfp_0_rx_pfc_en; +wire [7:0] qsfp_0_rx_pfc_req; +wire [7:0] qsfp_0_rx_pfc_ack; wire qsfp_0_gtpowergood; @@ -1082,6 +1097,12 @@ qsfp_0_cmac_inst ( .tx_ptp_ts_tag(qsfp_0_tx_ptp_ts_tag_int), .tx_ptp_ts_valid(qsfp_0_tx_ptp_ts_valid_int), + .tx_enable(qsfp_0_tx_enable), + .tx_lfc_en(qsfp_0_tx_lfc_en), + .tx_lfc_req(qsfp_0_tx_lfc_req), + .tx_pfc_en(qsfp_0_tx_pfc_en), + .tx_pfc_req(qsfp_0_tx_pfc_req), + .rx_clk(qsfp_0_rx_clk_int), .rx_rst(qsfp_0_rx_rst_int), @@ -1095,7 +1116,14 @@ qsfp_0_cmac_inst ( .rx_ptp_rst(qsfp_0_rx_ptp_rst_int), .rx_ptp_time(qsfp_0_rx_ptp_time_int), - .rx_status(qsfp_0_rx_status) + .rx_enable(qsfp_0_rx_enable), + .rx_status(qsfp_0_rx_status), + .rx_lfc_en(qsfp_0_rx_lfc_en), + .rx_lfc_req(qsfp_0_rx_lfc_req), + .rx_lfc_ack(qsfp_0_rx_lfc_ack), + .rx_pfc_en(qsfp_0_rx_pfc_en), + .rx_pfc_req(qsfp_0_rx_pfc_req), + .rx_pfc_ack(qsfp_0_rx_pfc_ack) ); // QSFP1 CMAC @@ -1136,7 +1164,20 @@ wire qsfp_1_drp_we; wire [15:0] qsfp_1_drp_do; wire qsfp_1_drp_rdy; -wire qsfp_1_rx_status; +wire qsfp_1_tx_enable; +wire qsfp_1_tx_lfc_en; +wire qsfp_1_tx_lfc_req; +wire [7:0] qsfp_1_tx_pfc_en; +wire [7:0] qsfp_1_tx_pfc_req; + +wire qsfp_1_rx_enable; +wire qsfp_1_rx_status; +wire qsfp_1_rx_lfc_en; +wire qsfp_1_rx_lfc_req; +wire qsfp_1_rx_lfc_ack; +wire [7:0] qsfp_1_rx_pfc_en; +wire [7:0] qsfp_1_rx_pfc_req; +wire [7:0] qsfp_1_rx_pfc_ack; wire qsfp_1_gtpowergood; @@ -1229,6 +1270,12 @@ qsfp_1_cmac_inst ( .tx_ptp_ts_tag(qsfp_1_tx_ptp_ts_tag_int), .tx_ptp_ts_valid(qsfp_1_tx_ptp_ts_valid_int), + .tx_enable(qsfp_1_tx_enable), + .tx_lfc_en(qsfp_1_tx_lfc_en), + .tx_lfc_req(qsfp_1_tx_lfc_req), + .tx_pfc_en(qsfp_1_tx_pfc_en), + .tx_pfc_req(qsfp_1_tx_pfc_req), + .rx_clk(qsfp_1_rx_clk_int), .rx_rst(qsfp_1_rx_rst_int), @@ -1242,7 +1289,14 @@ qsfp_1_cmac_inst ( .rx_ptp_rst(qsfp_1_rx_ptp_rst_int), .rx_ptp_time(qsfp_1_rx_ptp_time_int), - .rx_status(qsfp_1_rx_status) + .rx_enable(qsfp_1_rx_enable), + .rx_status(qsfp_1_rx_status), + .rx_lfc_en(qsfp_1_rx_lfc_en), + .rx_lfc_req(qsfp_1_rx_lfc_req), + .rx_lfc_ack(qsfp_1_rx_lfc_ack), + .rx_pfc_en(qsfp_1_rx_pfc_en), + .rx_pfc_req(qsfp_1_rx_pfc_req), + .rx_pfc_ack(qsfp_1_rx_pfc_ack) ); wire ptp_clk; @@ -1921,6 +1975,8 @@ fpga_core #( .TX_CHECKSUM_ENABLE(TX_CHECKSUM_ENABLE), .RX_HASH_ENABLE(RX_HASH_ENABLE), .RX_CHECKSUM_ENABLE(RX_CHECKSUM_ENABLE), + .PFC_ENABLE(PFC_ENABLE), + .LFC_ENABLE(LFC_ENABLE), .TX_FIFO_DEPTH(TX_FIFO_DEPTH), .RX_FIFO_DEPTH(RX_FIFO_DEPTH), .MAX_TX_SIZE(MAX_TX_SIZE), @@ -2130,6 +2186,12 @@ core_inst ( .qsfp_0_tx_ptp_ts_tag(qsfp_0_tx_ptp_ts_tag_int), .qsfp_0_tx_ptp_ts_valid(qsfp_0_tx_ptp_ts_valid_int), + .qsfp_0_tx_enable(qsfp_0_tx_enable), + .qsfp_0_tx_lfc_en(qsfp_0_tx_lfc_en), + .qsfp_0_tx_lfc_req(qsfp_0_tx_lfc_req), + .qsfp_0_tx_pfc_en(qsfp_0_tx_pfc_en), + .qsfp_0_tx_pfc_req(qsfp_0_tx_pfc_req), + .qsfp_0_rx_clk(qsfp_0_rx_clk_int), .qsfp_0_rx_rst(qsfp_0_rx_rst_int), .qsfp_0_rx_axis_tdata(qsfp_0_rx_axis_tdata_int), @@ -2141,7 +2203,14 @@ core_inst ( .qsfp_0_rx_ptp_rst(qsfp_0_rx_ptp_rst_int), .qsfp_0_rx_ptp_time(qsfp_0_rx_ptp_time_int), + .qsfp_0_rx_enable(qsfp_0_rx_enable), .qsfp_0_rx_status(qsfp_0_rx_status), + .qsfp_0_rx_lfc_en(qsfp_0_rx_lfc_en), + .qsfp_0_rx_lfc_req(qsfp_0_rx_lfc_req), + .qsfp_0_rx_lfc_ack(qsfp_0_rx_lfc_ack), + .qsfp_0_rx_pfc_en(qsfp_0_rx_pfc_en), + .qsfp_0_rx_pfc_req(qsfp_0_rx_pfc_req), + .qsfp_0_rx_pfc_ack(qsfp_0_rx_pfc_ack), .qsfp_0_drp_clk(qsfp_0_drp_clk), .qsfp_0_drp_rst(qsfp_0_drp_rst), @@ -2177,6 +2246,12 @@ core_inst ( .qsfp_1_tx_ptp_ts_tag(qsfp_1_tx_ptp_ts_tag_int), .qsfp_1_tx_ptp_ts_valid(qsfp_1_tx_ptp_ts_valid_int), + .qsfp_1_tx_enable(qsfp_1_tx_enable), + .qsfp_1_tx_lfc_en(qsfp_1_tx_lfc_en), + .qsfp_1_tx_lfc_req(qsfp_1_tx_lfc_req), + .qsfp_1_tx_pfc_en(qsfp_1_tx_pfc_en), + .qsfp_1_tx_pfc_req(qsfp_1_tx_pfc_req), + .qsfp_1_rx_clk(qsfp_1_rx_clk_int), .qsfp_1_rx_rst(qsfp_1_rx_rst_int), .qsfp_1_rx_axis_tdata(qsfp_1_rx_axis_tdata_int), @@ -2188,7 +2263,14 @@ core_inst ( .qsfp_1_rx_ptp_rst(qsfp_1_rx_ptp_rst_int), .qsfp_1_rx_ptp_time(qsfp_1_rx_ptp_time_int), + .qsfp_1_rx_enable(qsfp_1_rx_enable), .qsfp_1_rx_status(qsfp_1_rx_status), + .qsfp_1_rx_lfc_en(qsfp_1_rx_lfc_en), + .qsfp_1_rx_lfc_req(qsfp_1_rx_lfc_req), + .qsfp_1_rx_lfc_ack(qsfp_1_rx_lfc_ack), + .qsfp_1_rx_pfc_en(qsfp_1_rx_pfc_en), + .qsfp_1_rx_pfc_req(qsfp_1_rx_pfc_req), + .qsfp_1_rx_pfc_ack(qsfp_1_rx_pfc_ack), .qsfp_1_drp_clk(qsfp_1_drp_clk), .qsfp_1_drp_rst(qsfp_1_drp_rst), diff --git a/fpga/mqnic/fb2CG/fpga_100g/rtl/fpga_core.v b/fpga/mqnic/fb2CG/fpga_100g/rtl/fpga_core.v index cc321122c..6f4ba488c 100644 --- a/fpga/mqnic/fb2CG/fpga_100g/rtl/fpga_core.v +++ b/fpga/mqnic/fb2CG/fpga_100g/rtl/fpga_core.v @@ -77,6 +77,8 @@ module fpga_core # parameter TX_CHECKSUM_ENABLE = 1, parameter RX_HASH_ENABLE = 1, parameter RX_CHECKSUM_ENABLE = 1, + parameter PFC_ENABLE = 1, + parameter LFC_ENABLE = PFC_ENABLE, parameter TX_FIFO_DEPTH = 32768, parameter RX_FIFO_DEPTH = 131072, parameter MAX_TX_SIZE = 9214, @@ -288,6 +290,12 @@ module fpga_core # input wire [15:0] qsfp_0_tx_ptp_ts_tag, input wire qsfp_0_tx_ptp_ts_valid, + output wire qsfp_0_tx_enable, + output wire qsfp_0_tx_lfc_en, + output wire qsfp_0_tx_lfc_req, + output wire [7:0] qsfp_0_tx_pfc_en, + output wire [7:0] qsfp_0_tx_pfc_req, + input wire qsfp_0_rx_clk, input wire qsfp_0_rx_rst, @@ -301,7 +309,14 @@ module fpga_core # input wire qsfp_0_rx_ptp_rst, output wire [79:0] qsfp_0_rx_ptp_time, + output wire qsfp_0_rx_enable, input wire qsfp_0_rx_status, + output wire qsfp_0_rx_lfc_en, + input wire qsfp_0_rx_lfc_req, + output wire qsfp_0_rx_lfc_ack, + output wire [7:0] qsfp_0_rx_pfc_en, + input wire [7:0] qsfp_0_rx_pfc_req, + output wire [7:0] qsfp_0_rx_pfc_ack, input wire qsfp_0_drp_clk, input wire qsfp_0_drp_rst, @@ -338,6 +353,12 @@ module fpga_core # input wire [15:0] qsfp_1_tx_ptp_ts_tag, input wire qsfp_1_tx_ptp_ts_valid, + output wire qsfp_1_tx_enable, + output wire qsfp_1_tx_lfc_en, + output wire qsfp_1_tx_lfc_req, + output wire [7:0] qsfp_1_tx_pfc_en, + output wire [7:0] qsfp_1_tx_pfc_req, + input wire qsfp_1_rx_clk, input wire qsfp_1_rx_rst, @@ -351,7 +372,14 @@ module fpga_core # input wire qsfp_1_rx_ptp_rst, output wire [79:0] qsfp_1_rx_ptp_time, + output wire qsfp_1_rx_enable, input wire qsfp_1_rx_status, + output wire qsfp_1_rx_lfc_en, + input wire qsfp_1_rx_lfc_req, + output wire qsfp_1_rx_lfc_ack, + output wire [7:0] qsfp_1_rx_pfc_en, + input wire [7:0] qsfp_1_rx_pfc_req, + output wire [7:0] qsfp_1_rx_pfc_ack, input wire qsfp_1_drp_clk, input wire qsfp_1_drp_rst, @@ -862,7 +890,12 @@ wire [PORT_COUNT*TX_TAG_WIDTH-1:0] axis_eth_tx_ptp_ts_tag; wire [PORT_COUNT-1:0] axis_eth_tx_ptp_ts_valid; wire [PORT_COUNT-1:0] axis_eth_tx_ptp_ts_ready; +wire [PORT_COUNT-1:0] eth_tx_enable; wire [PORT_COUNT-1:0] eth_tx_status; +wire [PORT_COUNT-1:0] eth_tx_lfc_en; +wire [PORT_COUNT-1:0] eth_tx_lfc_req; +wire [PORT_COUNT*8-1:0] eth_tx_pfc_en; +wire [PORT_COUNT*8-1:0] eth_tx_pfc_req; wire [PORT_COUNT-1:0] eth_rx_clk; wire [PORT_COUNT-1:0] eth_rx_rst; @@ -879,7 +912,14 @@ wire [PORT_COUNT-1:0] axis_eth_rx_tready; wire [PORT_COUNT-1:0] axis_eth_rx_tlast; wire [PORT_COUNT*AXIS_ETH_RX_USER_WIDTH-1:0] axis_eth_rx_tuser; +wire [PORT_COUNT-1:0] eth_rx_enable; wire [PORT_COUNT-1:0] eth_rx_status; +wire [PORT_COUNT-1:0] eth_rx_lfc_en; +wire [PORT_COUNT-1:0] eth_rx_lfc_req; +wire [PORT_COUNT-1:0] eth_rx_lfc_ack; +wire [PORT_COUNT*8-1:0] eth_rx_pfc_en; +wire [PORT_COUNT*8-1:0] eth_rx_pfc_req; +wire [PORT_COUNT*8-1:0] eth_rx_pfc_ack; wire [PTP_TS_WIDTH-1:0] qsfp_0_tx_ptp_time_int; wire [PTP_TS_WIDTH-1:0] qsfp_1_tx_ptp_time_int; @@ -930,7 +970,12 @@ mqnic_port_map_mac_axis_inst ( .s_axis_mac_tx_ptp_ts_valid({qsfp_1_tx_ptp_ts_valid, qsfp_0_tx_ptp_ts_valid}), .s_axis_mac_tx_ptp_ts_ready(), + .mac_tx_enable({qsfp_1_tx_enable, qsfp_0_tx_enable}), .mac_tx_status(2'b11), + .mac_tx_lfc_en({qsfp_1_tx_lfc_en, qsfp_0_tx_lfc_en}), + .mac_tx_lfc_req({qsfp_1_tx_lfc_req, qsfp_0_tx_lfc_req}), + .mac_tx_pfc_en({qsfp_1_tx_pfc_en, qsfp_0_tx_pfc_en}), + .mac_tx_pfc_req({qsfp_1_tx_pfc_req, qsfp_0_tx_pfc_req}), .mac_rx_clk({qsfp_1_rx_clk, qsfp_0_rx_clk}), .mac_rx_rst({qsfp_1_rx_rst, qsfp_0_rx_rst}), @@ -947,7 +992,14 @@ mqnic_port_map_mac_axis_inst ( .s_axis_mac_rx_tlast({qsfp_1_rx_axis_tlast, qsfp_0_rx_axis_tlast}), .s_axis_mac_rx_tuser({{qsfp_1_rx_axis_tuser[80:1], 16'd0, qsfp_1_rx_axis_tuser[0]}, {qsfp_0_rx_axis_tuser[80:1], 16'd0, qsfp_0_rx_axis_tuser[0]}}), + .mac_rx_enable({qsfp_1_rx_enable, qsfp_0_rx_enable}), .mac_rx_status({qsfp_1_rx_status, qsfp_0_rx_status}), + .mac_rx_lfc_en({qsfp_1_rx_lfc_en, qsfp_0_rx_lfc_en}), + .mac_rx_lfc_req({qsfp_1_rx_lfc_req, qsfp_0_rx_lfc_req}), + .mac_rx_lfc_ack({qsfp_1_rx_lfc_ack, qsfp_0_rx_lfc_ack}), + .mac_rx_pfc_en({qsfp_1_rx_pfc_en, qsfp_0_rx_pfc_en}), + .mac_rx_pfc_req({qsfp_1_rx_pfc_req, qsfp_0_rx_pfc_req}), + .mac_rx_pfc_ack({qsfp_1_rx_pfc_ack, qsfp_0_rx_pfc_ack}), // towards datapath .tx_clk(eth_tx_clk), @@ -970,7 +1022,12 @@ mqnic_port_map_mac_axis_inst ( .m_axis_tx_ptp_ts_valid(axis_eth_tx_ptp_ts_valid), .m_axis_tx_ptp_ts_ready(axis_eth_tx_ptp_ts_ready), + .tx_enable(eth_tx_enable), .tx_status(eth_tx_status), + .tx_lfc_en(eth_tx_lfc_en), + .tx_lfc_req(eth_tx_lfc_req), + .tx_pfc_en(eth_tx_pfc_en), + .tx_pfc_req(eth_tx_pfc_req), .rx_clk(eth_rx_clk), .rx_rst(eth_rx_rst), @@ -987,7 +1044,14 @@ mqnic_port_map_mac_axis_inst ( .m_axis_rx_tlast(axis_eth_rx_tlast), .m_axis_rx_tuser(axis_eth_rx_tuser), - .rx_status(eth_rx_status) + .rx_enable(eth_rx_enable), + .rx_status(eth_rx_status), + .rx_lfc_en(eth_rx_lfc_en), + .rx_lfc_req(eth_rx_lfc_req), + .rx_lfc_ack(eth_rx_lfc_ack), + .rx_pfc_en(eth_rx_pfc_en), + .rx_pfc_req(eth_rx_pfc_req), + .rx_pfc_ack(eth_rx_pfc_ack) ); mqnic_core_pcie_us #( @@ -1057,6 +1121,9 @@ mqnic_core_pcie_us #( .TX_CHECKSUM_ENABLE(TX_CHECKSUM_ENABLE), .RX_HASH_ENABLE(RX_HASH_ENABLE), .RX_CHECKSUM_ENABLE(RX_CHECKSUM_ENABLE), + .PFC_ENABLE(PFC_ENABLE), + .LFC_ENABLE(LFC_ENABLE), + .MAC_CTRL_ENABLE(0), .TX_FIFO_DEPTH(TX_FIFO_DEPTH), .RX_FIFO_DEPTH(RX_FIFO_DEPTH), .MAX_TX_SIZE(MAX_TX_SIZE), @@ -1338,7 +1405,13 @@ core_inst ( .s_axis_eth_tx_cpl_valid(axis_eth_tx_ptp_ts_valid), .s_axis_eth_tx_cpl_ready(axis_eth_tx_ptp_ts_ready), + .eth_tx_enable(eth_tx_enable), .eth_tx_status(eth_tx_status), + .eth_tx_lfc_en(eth_tx_lfc_en), + .eth_tx_lfc_req(eth_tx_lfc_req), + .eth_tx_pfc_en(eth_tx_pfc_en), + .eth_tx_pfc_req(eth_tx_pfc_req), + .eth_tx_fc_quanta_clk_en(0), .eth_rx_clk(eth_rx_clk), .eth_rx_rst(eth_rx_rst), @@ -1355,7 +1428,15 @@ core_inst ( .s_axis_eth_rx_tlast(axis_eth_rx_tlast), .s_axis_eth_rx_tuser(axis_eth_rx_tuser), + .eth_rx_enable(eth_rx_enable), .eth_rx_status(eth_rx_status), + .eth_rx_lfc_en(eth_rx_lfc_en), + .eth_rx_lfc_req(eth_rx_lfc_req), + .eth_rx_lfc_ack(eth_rx_lfc_ack), + .eth_rx_pfc_en(eth_rx_pfc_en), + .eth_rx_pfc_req(eth_rx_pfc_req), + .eth_rx_pfc_ack(eth_rx_pfc_ack), + .eth_rx_fc_quanta_clk_en(0), /* * DDR diff --git a/fpga/mqnic/fb2CG/fpga_100g/tb/fpga_core/Makefile b/fpga/mqnic/fb2CG/fpga_100g/tb/fpga_core/Makefile index ad8c9fcea..d67d805bf 100644 --- a/fpga/mqnic/fb2CG/fpga_100g/tb/fpga_core/Makefile +++ b/fpga/mqnic/fb2CG/fpga_100g/tb/fpga_core/Makefile @@ -162,6 +162,8 @@ export PARAM_TX_CPL_FIFO_DEPTH := 32 export PARAM_TX_CHECKSUM_ENABLE := 1 export PARAM_RX_HASH_ENABLE := 1 export PARAM_RX_CHECKSUM_ENABLE := 1 +export PARAM_LFC_ENABLE := 1 +export PARAM_PFC_ENABLE := $(PARAM_LFC_ENABLE) export PARAM_TX_FIFO_DEPTH := 32768 export PARAM_RX_FIFO_DEPTH := 131072 export PARAM_MAX_TX_SIZE := 9214 diff --git a/fpga/mqnic/fb2CG/fpga_100g/tb/fpga_core/test_fpga_core.py b/fpga/mqnic/fb2CG/fpga_100g/tb/fpga_core/test_fpga_core.py index 9540d10cc..9338ad143 100644 --- a/fpga/mqnic/fb2CG/fpga_100g/tb/fpga_core/test_fpga_core.py +++ b/fpga/mqnic/fb2CG/fpga_100g/tb/fpga_core/test_fpga_core.py @@ -300,6 +300,8 @@ class TB(object): self.qsfp_mac.append(mac) getattr(dut, f"qsfp_{k}_rx_status").setimmediatevalue(1) + getattr(dut, f"qsfp_{k}_rx_lfc_req").setimmediatevalue(0) + getattr(dut, f"qsfp_{k}_rx_pfc_req").setimmediatevalue(0) cocotb.start_soon(Clock(getattr(dut, f"qsfp_{k}_drp_clk"), 8, units="ns").start()) getattr(dut, f"qsfp_{k}_drp_rst").setimmediatevalue(0) @@ -724,6 +726,8 @@ def test_fpga_core(request): parameters['TX_CHECKSUM_ENABLE'] = 1 parameters['RX_HASH_ENABLE'] = 1 parameters['RX_CHECKSUM_ENABLE'] = 1 + parameters['LFC_ENABLE'] = 1 + parameters['PFC_ENABLE'] = parameters['LFC_ENABLE'] parameters['TX_FIFO_DEPTH'] = 32768 parameters['RX_FIFO_DEPTH'] = 131072 parameters['MAX_TX_SIZE'] = 9214 diff --git a/fpga/mqnic/fb2CG/fpga_25g/fpga/Makefile b/fpga/mqnic/fb2CG/fpga_25g/fpga/Makefile index 7773eebec..99aff6d08 100644 --- a/fpga/mqnic/fb2CG/fpga_25g/fpga/Makefile +++ b/fpga/mqnic/fb2CG/fpga_25g/fpga/Makefile @@ -63,6 +63,10 @@ SYN_FILES += rtl/common/led_sreg_driver.v SYN_FILES += lib/eth/rtl/eth_mac_10g.v SYN_FILES += lib/eth/rtl/axis_xgmii_rx_64.v SYN_FILES += lib/eth/rtl/axis_xgmii_tx_64.v +SYN_FILES += lib/eth/rtl/mac_ctrl_rx.v +SYN_FILES += lib/eth/rtl/mac_ctrl_tx.v +SYN_FILES += lib/eth/rtl/mac_pause_ctrl_rx.v +SYN_FILES += lib/eth/rtl/mac_pause_ctrl_tx.v SYN_FILES += lib/eth/rtl/eth_phy_10g.v SYN_FILES += lib/eth/rtl/eth_phy_10g_rx.v SYN_FILES += lib/eth/rtl/eth_phy_10g_rx_if.v diff --git a/fpga/mqnic/fb2CG/fpga_25g/fpga/config.tcl b/fpga/mqnic/fb2CG/fpga_25g/fpga/config.tcl index 4c1bcff6c..6df166894 100644 --- a/fpga/mqnic/fb2CG/fpga_25g/fpga/config.tcl +++ b/fpga/mqnic/fb2CG/fpga_25g/fpga/config.tcl @@ -113,6 +113,8 @@ dict set params TX_CPL_FIFO_DEPTH "32" dict set params TX_CHECKSUM_ENABLE "1" dict set params RX_HASH_ENABLE "1" dict set params RX_CHECKSUM_ENABLE "1" +dict set params PFC_ENABLE "1" +dict set params LFC_ENABLE [dict get $params PFC_ENABLE] dict set params ENABLE_PADDING "1" dict set params ENABLE_DIC "1" dict set params MIN_FRAME_LENGTH "64" diff --git a/fpga/mqnic/fb2CG/fpga_25g/fpga_10g/Makefile b/fpga/mqnic/fb2CG/fpga_25g/fpga_10g/Makefile index 7773eebec..99aff6d08 100644 --- a/fpga/mqnic/fb2CG/fpga_25g/fpga_10g/Makefile +++ b/fpga/mqnic/fb2CG/fpga_25g/fpga_10g/Makefile @@ -63,6 +63,10 @@ SYN_FILES += rtl/common/led_sreg_driver.v SYN_FILES += lib/eth/rtl/eth_mac_10g.v SYN_FILES += lib/eth/rtl/axis_xgmii_rx_64.v SYN_FILES += lib/eth/rtl/axis_xgmii_tx_64.v +SYN_FILES += lib/eth/rtl/mac_ctrl_rx.v +SYN_FILES += lib/eth/rtl/mac_ctrl_tx.v +SYN_FILES += lib/eth/rtl/mac_pause_ctrl_rx.v +SYN_FILES += lib/eth/rtl/mac_pause_ctrl_tx.v SYN_FILES += lib/eth/rtl/eth_phy_10g.v SYN_FILES += lib/eth/rtl/eth_phy_10g_rx.v SYN_FILES += lib/eth/rtl/eth_phy_10g_rx_if.v diff --git a/fpga/mqnic/fb2CG/fpga_25g/fpga_10g/config.tcl b/fpga/mqnic/fb2CG/fpga_25g/fpga_10g/config.tcl index 9f7c270ee..9de346529 100644 --- a/fpga/mqnic/fb2CG/fpga_25g/fpga_10g/config.tcl +++ b/fpga/mqnic/fb2CG/fpga_25g/fpga_10g/config.tcl @@ -113,6 +113,8 @@ dict set params TX_CPL_FIFO_DEPTH "32" dict set params TX_CHECKSUM_ENABLE "1" dict set params RX_HASH_ENABLE "1" dict set params RX_CHECKSUM_ENABLE "1" +dict set params PFC_ENABLE "1" +dict set params LFC_ENABLE [dict get $params PFC_ENABLE] dict set params ENABLE_PADDING "1" dict set params ENABLE_DIC "1" dict set params MIN_FRAME_LENGTH "64" diff --git a/fpga/mqnic/fb2CG/fpga_25g/fpga_tdma/Makefile b/fpga/mqnic/fb2CG/fpga_25g/fpga_tdma/Makefile index 183becdc8..087df4441 100644 --- a/fpga/mqnic/fb2CG/fpga_25g/fpga_tdma/Makefile +++ b/fpga/mqnic/fb2CG/fpga_25g/fpga_tdma/Makefile @@ -64,6 +64,10 @@ SYN_FILES += rtl/common/led_sreg_driver.v SYN_FILES += lib/eth/rtl/eth_mac_10g.v SYN_FILES += lib/eth/rtl/axis_xgmii_rx_64.v SYN_FILES += lib/eth/rtl/axis_xgmii_tx_64.v +SYN_FILES += lib/eth/rtl/mac_ctrl_rx.v +SYN_FILES += lib/eth/rtl/mac_ctrl_tx.v +SYN_FILES += lib/eth/rtl/mac_pause_ctrl_rx.v +SYN_FILES += lib/eth/rtl/mac_pause_ctrl_tx.v SYN_FILES += lib/eth/rtl/eth_phy_10g.v SYN_FILES += lib/eth/rtl/eth_phy_10g_rx.v SYN_FILES += lib/eth/rtl/eth_phy_10g_rx_if.v diff --git a/fpga/mqnic/fb2CG/fpga_25g/fpga_tdma/config.tcl b/fpga/mqnic/fb2CG/fpga_25g/fpga_tdma/config.tcl index b613492c3..e5c944a30 100644 --- a/fpga/mqnic/fb2CG/fpga_25g/fpga_tdma/config.tcl +++ b/fpga/mqnic/fb2CG/fpga_25g/fpga_tdma/config.tcl @@ -113,6 +113,8 @@ dict set params TX_CPL_FIFO_DEPTH "32" dict set params TX_CHECKSUM_ENABLE "1" dict set params RX_HASH_ENABLE "1" dict set params RX_CHECKSUM_ENABLE "1" +dict set params PFC_ENABLE "1" +dict set params LFC_ENABLE [dict get $params PFC_ENABLE] dict set params ENABLE_PADDING "1" dict set params ENABLE_DIC "1" dict set params MIN_FRAME_LENGTH "64" diff --git a/fpga/mqnic/fb2CG/fpga_25g/rtl/fpga.v b/fpga/mqnic/fb2CG/fpga_25g/rtl/fpga.v index 948e33078..d9a95c636 100644 --- a/fpga/mqnic/fb2CG/fpga_25g/rtl/fpga.v +++ b/fpga/mqnic/fb2CG/fpga_25g/rtl/fpga.v @@ -74,6 +74,8 @@ module fpga # parameter TX_CHECKSUM_ENABLE = 1, parameter RX_HASH_ENABLE = 1, parameter RX_CHECKSUM_ENABLE = 1, + parameter PFC_ENABLE = 1, + parameter LFC_ENABLE = PFC_ENABLE, parameter ENABLE_PADDING = 1, parameter ENABLE_DIC = 1, parameter MIN_FRAME_LENGTH = 64, @@ -2070,6 +2072,8 @@ fpga_core #( .TX_CHECKSUM_ENABLE(TX_CHECKSUM_ENABLE), .RX_HASH_ENABLE(RX_HASH_ENABLE), .RX_CHECKSUM_ENABLE(RX_CHECKSUM_ENABLE), + .PFC_ENABLE(PFC_ENABLE), + .LFC_ENABLE(LFC_ENABLE), .ENABLE_PADDING(ENABLE_PADDING), .ENABLE_DIC(ENABLE_DIC), .MIN_FRAME_LENGTH(MIN_FRAME_LENGTH), diff --git a/fpga/mqnic/fb2CG/fpga_25g/rtl/fpga_core.v b/fpga/mqnic/fb2CG/fpga_25g/rtl/fpga_core.v index 10ff8e39a..55c1f554a 100644 --- a/fpga/mqnic/fb2CG/fpga_25g/rtl/fpga_core.v +++ b/fpga/mqnic/fb2CG/fpga_25g/rtl/fpga_core.v @@ -81,6 +81,8 @@ module fpga_core # parameter TX_CHECKSUM_ENABLE = 1, parameter RX_HASH_ENABLE = 1, parameter RX_CHECKSUM_ENABLE = 1, + parameter PFC_ENABLE = 1, + parameter LFC_ENABLE = PFC_ENABLE, parameter ENABLE_PADDING = 1, parameter ENABLE_DIC = 1, parameter MIN_FRAME_LENGTH = 64, @@ -1011,7 +1013,12 @@ wire [PORT_COUNT*TX_TAG_WIDTH-1:0] axis_eth_tx_ptp_ts_tag; wire [PORT_COUNT-1:0] axis_eth_tx_ptp_ts_valid; wire [PORT_COUNT-1:0] axis_eth_tx_ptp_ts_ready; +wire [PORT_COUNT-1:0] eth_tx_enable; wire [PORT_COUNT-1:0] eth_tx_status; +wire [PORT_COUNT-1:0] eth_tx_lfc_en; +wire [PORT_COUNT-1:0] eth_tx_lfc_req; +wire [PORT_COUNT*8-1:0] eth_tx_pfc_en; +wire [PORT_COUNT*8-1:0] eth_tx_pfc_req; wire [PORT_COUNT-1:0] eth_rx_clk; wire [PORT_COUNT-1:0] eth_rx_rst; @@ -1026,7 +1033,14 @@ wire [PORT_COUNT-1:0] axis_eth_rx_tready; wire [PORT_COUNT-1:0] axis_eth_rx_tlast; wire [PORT_COUNT*AXIS_ETH_RX_USER_WIDTH-1:0] axis_eth_rx_tuser; +wire [PORT_COUNT-1:0] eth_rx_enable; wire [PORT_COUNT-1:0] eth_rx_status; +wire [PORT_COUNT-1:0] eth_rx_lfc_en; +wire [PORT_COUNT-1:0] eth_rx_lfc_req; +wire [PORT_COUNT-1:0] eth_rx_lfc_ack; +wire [PORT_COUNT*8-1:0] eth_rx_pfc_en; +wire [PORT_COUNT*8-1:0] eth_rx_pfc_req; +wire [PORT_COUNT*8-1:0] eth_rx_pfc_ack; wire [PORT_COUNT-1:0] port_xgmii_tx_clk; wire [PORT_COUNT-1:0] port_xgmii_tx_rst; @@ -1099,12 +1113,15 @@ generate .PTP_PERIOD_FNS(IF_PTP_PERIOD_FNS), .TX_PTP_TS_ENABLE(PTP_TS_ENABLE), .TX_PTP_TS_WIDTH(PTP_TS_WIDTH), + .TX_PTP_TS_CTRL_IN_TUSER(0), .TX_PTP_TAG_ENABLE(PTP_TS_ENABLE), .TX_PTP_TAG_WIDTH(TX_TAG_WIDTH), .RX_PTP_TS_ENABLE(PTP_TS_ENABLE), .RX_PTP_TS_WIDTH(PTP_TS_WIDTH), .TX_USER_WIDTH(AXIS_ETH_TX_USER_WIDTH), - .RX_USER_WIDTH(AXIS_ETH_RX_USER_WIDTH) + .RX_USER_WIDTH(AXIS_ETH_RX_USER_WIDTH), + .PFC_ENABLE(PFC_ENABLE), + .PAUSE_ENABLE(LFC_ENABLE) ) eth_mac_inst ( .tx_clk(port_xgmii_tx_clk[n]), @@ -1112,6 +1129,9 @@ generate .rx_clk(port_xgmii_rx_clk[n]), .rx_rst(port_xgmii_rx_rst[n]), + /* + * AXI input + */ .tx_axis_tdata(axis_eth_tx_tdata[n*AXIS_ETH_DATA_WIDTH +: AXIS_ETH_DATA_WIDTH]), .tx_axis_tkeep(axis_eth_tx_tkeep[n*AXIS_ETH_KEEP_WIDTH +: AXIS_ETH_KEEP_WIDTH]), .tx_axis_tvalid(axis_eth_tx_tvalid[n +: 1]), @@ -1119,30 +1139,121 @@ generate .tx_axis_tlast(axis_eth_tx_tlast[n +: 1]), .tx_axis_tuser(axis_eth_tx_tuser[n*AXIS_ETH_TX_USER_WIDTH +: AXIS_ETH_TX_USER_WIDTH]), + /* + * AXI output + */ .rx_axis_tdata(axis_eth_rx_tdata[n*AXIS_ETH_DATA_WIDTH +: AXIS_ETH_DATA_WIDTH]), .rx_axis_tkeep(axis_eth_rx_tkeep[n*AXIS_ETH_KEEP_WIDTH +: AXIS_ETH_KEEP_WIDTH]), .rx_axis_tvalid(axis_eth_rx_tvalid[n +: 1]), .rx_axis_tlast(axis_eth_rx_tlast[n +: 1]), .rx_axis_tuser(axis_eth_rx_tuser[n*AXIS_ETH_RX_USER_WIDTH +: AXIS_ETH_RX_USER_WIDTH]), + /* + * XGMII interface + */ .xgmii_rxd(port_xgmii_rxd[n*XGMII_DATA_WIDTH +: XGMII_DATA_WIDTH]), .xgmii_rxc(port_xgmii_rxc[n*XGMII_CTRL_WIDTH +: XGMII_CTRL_WIDTH]), .xgmii_txd(port_xgmii_txd[n*XGMII_DATA_WIDTH +: XGMII_DATA_WIDTH]), .xgmii_txc(port_xgmii_txc[n*XGMII_CTRL_WIDTH +: XGMII_CTRL_WIDTH]), + /* + * PTP + */ .tx_ptp_ts(eth_tx_ptp_ts_96[n*PTP_TS_WIDTH +: PTP_TS_WIDTH]), .rx_ptp_ts(eth_rx_ptp_ts_96[n*PTP_TS_WIDTH +: PTP_TS_WIDTH]), .tx_axis_ptp_ts(axis_eth_tx_ptp_ts[n*PTP_TS_WIDTH +: PTP_TS_WIDTH]), .tx_axis_ptp_ts_tag(axis_eth_tx_ptp_ts_tag[n*TX_TAG_WIDTH +: TX_TAG_WIDTH]), .tx_axis_ptp_ts_valid(axis_eth_tx_ptp_ts_valid[n +: 1]), + /* + * Link-level Flow Control (LFC) (IEEE 802.3 annex 31B PAUSE) + */ + .tx_lfc_req(eth_tx_lfc_req[n +: 1]), + .tx_lfc_resend(1'b0), + .rx_lfc_en(eth_rx_lfc_en[n +: 1]), + .rx_lfc_req(eth_rx_lfc_req[n +: 1]), + .rx_lfc_ack(eth_rx_lfc_ack[n +: 1]), + + /* + * Priority Flow Control (PFC) (IEEE 802.3 annex 31D PFC) + */ + .tx_pfc_req(eth_tx_pfc_req[n*8 +: 8]), + .tx_pfc_resend(1'b0), + .rx_pfc_en(eth_rx_pfc_en[n*8 +: 8]), + .rx_pfc_req(eth_rx_pfc_req[n*8 +: 8]), + .rx_pfc_ack(eth_rx_pfc_ack[n*8 +: 8]), + + /* + * Pause interface + */ + .tx_lfc_pause_en(1'b1), + .tx_pause_req(1'b0), + .tx_pause_ack(), + + /* + * Status + */ + .tx_start_packet(), .tx_error_underflow(), + .rx_start_packet(), .rx_error_bad_frame(), .rx_error_bad_fcs(), + .stat_tx_mcf(), + .stat_rx_mcf(), + .stat_tx_lfc_pkt(), + .stat_tx_lfc_xon(), + .stat_tx_lfc_xoff(), + .stat_tx_lfc_paused(), + .stat_tx_pfc_pkt(), + .stat_tx_pfc_xon(), + .stat_tx_pfc_xoff(), + .stat_tx_pfc_paused(), + .stat_rx_lfc_pkt(), + .stat_rx_lfc_xon(), + .stat_rx_lfc_xoff(), + .stat_rx_lfc_paused(), + .stat_rx_pfc_pkt(), + .stat_rx_pfc_xon(), + .stat_rx_pfc_xoff(), + .stat_rx_pfc_paused(), + /* + * Configuration + */ .cfg_ifg(8'd12), - .cfg_tx_enable(1'b1), - .cfg_rx_enable(1'b1) + .cfg_tx_enable(eth_tx_enable[n +: 1]), + .cfg_rx_enable(eth_rx_enable[n +: 1]), + .cfg_mcf_rx_eth_dst_mcast(48'h01_80_C2_00_00_01), + .cfg_mcf_rx_check_eth_dst_mcast(1'b1), + .cfg_mcf_rx_eth_dst_ucast(48'd0), + .cfg_mcf_rx_check_eth_dst_ucast(1'b0), + .cfg_mcf_rx_eth_src(48'd0), + .cfg_mcf_rx_check_eth_src(1'b0), + .cfg_mcf_rx_eth_type(16'h8808), + .cfg_mcf_rx_opcode_lfc(16'h0001), + .cfg_mcf_rx_check_opcode_lfc(eth_rx_lfc_en[n +: 1]), + .cfg_mcf_rx_opcode_pfc(16'h0101), + .cfg_mcf_rx_check_opcode_pfc(eth_rx_pfc_en[n*8 +: 8] != 0), + .cfg_mcf_rx_forward(1'b0), + .cfg_mcf_rx_enable(eth_rx_lfc_en[n +: 1] || eth_rx_pfc_en[n*8 +: 8]), + .cfg_tx_lfc_eth_dst(48'h01_80_C2_00_00_01), + .cfg_tx_lfc_eth_src(48'h80_23_31_43_54_4C), + .cfg_tx_lfc_eth_type(16'h8808), + .cfg_tx_lfc_opcode(16'h0001), + .cfg_tx_lfc_en(eth_tx_lfc_en[n +: 1]), + .cfg_tx_lfc_quanta(16'hffff), + .cfg_tx_lfc_refresh(16'h7fff), + .cfg_tx_pfc_eth_dst(48'h01_80_C2_00_00_01), + .cfg_tx_pfc_eth_src(48'h80_23_31_43_54_4C), + .cfg_tx_pfc_eth_type(16'h8808), + .cfg_tx_pfc_opcode(16'h0101), + .cfg_tx_pfc_en(eth_tx_pfc_en[n*8 +: 8] != 0), + .cfg_tx_pfc_quanta({8{16'hffff}}), + .cfg_tx_pfc_refresh({8{16'h7fff}}), + .cfg_rx_lfc_opcode(16'h0001), + .cfg_rx_lfc_en(eth_rx_lfc_en[n +: 1]), + .cfg_rx_pfc_opcode(16'h0101), + .cfg_rx_pfc_en(eth_rx_pfc_en[n*8 +: 8] != 0) ); end @@ -1216,6 +1327,9 @@ mqnic_core_pcie_us #( .TX_CHECKSUM_ENABLE(TX_CHECKSUM_ENABLE), .RX_HASH_ENABLE(RX_HASH_ENABLE), .RX_CHECKSUM_ENABLE(RX_CHECKSUM_ENABLE), + .PFC_ENABLE(PFC_ENABLE), + .LFC_ENABLE(LFC_ENABLE), + .MAC_CTRL_ENABLE(0), .TX_FIFO_DEPTH(TX_FIFO_DEPTH), .RX_FIFO_DEPTH(RX_FIFO_DEPTH), .MAX_TX_SIZE(MAX_TX_SIZE), @@ -1497,7 +1611,13 @@ core_inst ( .s_axis_eth_tx_cpl_valid(axis_eth_tx_ptp_ts_valid), .s_axis_eth_tx_cpl_ready(axis_eth_tx_ptp_ts_ready), + .eth_tx_enable(eth_tx_enable), .eth_tx_status(eth_tx_status), + .eth_tx_lfc_en(eth_tx_lfc_en), + .eth_tx_lfc_req(eth_tx_lfc_req), + .eth_tx_pfc_en(eth_tx_pfc_en), + .eth_tx_pfc_req(eth_tx_pfc_req), + .eth_tx_fc_quanta_clk_en(0), .eth_rx_clk(eth_rx_clk), .eth_rx_rst(eth_rx_rst), @@ -1514,7 +1634,15 @@ core_inst ( .s_axis_eth_rx_tlast(axis_eth_rx_tlast), .s_axis_eth_rx_tuser(axis_eth_rx_tuser), + .eth_rx_enable(eth_rx_enable), .eth_rx_status(eth_rx_status), + .eth_rx_lfc_en(eth_rx_lfc_en), + .eth_rx_lfc_req(eth_rx_lfc_req), + .eth_rx_lfc_ack(eth_rx_lfc_ack), + .eth_rx_pfc_en(eth_rx_pfc_en), + .eth_rx_pfc_req(eth_rx_pfc_req), + .eth_rx_pfc_ack(eth_rx_pfc_ack), + .eth_rx_fc_quanta_clk_en(0), /* * DDR diff --git a/fpga/mqnic/fb2CG/fpga_25g/tb/fpga_core/Makefile b/fpga/mqnic/fb2CG/fpga_25g/tb/fpga_core/Makefile index 0c3b6a46f..a086503cd 100644 --- a/fpga/mqnic/fb2CG/fpga_25g/tb/fpga_core/Makefile +++ b/fpga/mqnic/fb2CG/fpga_25g/tb/fpga_core/Makefile @@ -63,6 +63,10 @@ VERILOG_SOURCES += ../../rtl/common/tdma_ber_ch.v VERILOG_SOURCES += ../../lib/eth/rtl/eth_mac_10g.v VERILOG_SOURCES += ../../lib/eth/rtl/axis_xgmii_rx_64.v VERILOG_SOURCES += ../../lib/eth/rtl/axis_xgmii_tx_64.v +VERILOG_SOURCES += ../../lib/eth/rtl/mac_ctrl_rx.v +VERILOG_SOURCES += ../../lib/eth/rtl/mac_ctrl_tx.v +VERILOG_SOURCES += ../../lib/eth/rtl/mac_pause_ctrl_rx.v +VERILOG_SOURCES += ../../lib/eth/rtl/mac_pause_ctrl_tx.v VERILOG_SOURCES += ../../lib/eth/rtl/lfsr.v VERILOG_SOURCES += ../../lib/eth/rtl/ptp_clock.v VERILOG_SOURCES += ../../lib/eth/rtl/ptp_clock_cdc.v @@ -168,6 +172,8 @@ export PARAM_TX_CPL_FIFO_DEPTH := 32 export PARAM_TX_CHECKSUM_ENABLE := 1 export PARAM_RX_HASH_ENABLE := 1 export PARAM_RX_CHECKSUM_ENABLE := 1 +export PARAM_LFC_ENABLE := 1 +export PARAM_PFC_ENABLE := $(PARAM_LFC_ENABLE) export PARAM_TX_FIFO_DEPTH := 32768 export PARAM_RX_FIFO_DEPTH := 32768 export PARAM_MAX_TX_SIZE := 9214 diff --git a/fpga/mqnic/fb2CG/fpga_25g/tb/fpga_core/test_fpga_core.py b/fpga/mqnic/fb2CG/fpga_25g/tb/fpga_core/test_fpga_core.py index dd76e0298..97df2ae0b 100644 --- a/fpga/mqnic/fb2CG/fpga_25g/tb/fpga_core/test_fpga_core.py +++ b/fpga/mqnic/fb2CG/fpga_25g/tb/fpga_core/test_fpga_core.py @@ -3,6 +3,7 @@ import logging import os +import struct import sys import scapy.utils @@ -17,7 +18,7 @@ from cocotb.clock import Clock from cocotb.triggers import RisingEdge, FallingEdge, Timer from cocotbext.axi import AxiStreamBus -from cocotbext.eth import XgmiiSource, XgmiiSink +from cocotbext.eth import XgmiiSource, XgmiiSink, XgmiiFrame from cocotbext.pcie.core import RootComplex from cocotbext.pcie.xilinx.us import UltraScalePlusPcieDevice @@ -528,6 +529,35 @@ async def run_test_nic(dut): tb.loopback_enable = False + if tb.driver.interfaces[0].if_feature_lfc: + tb.log.info("Test LFC pause frame RX") + + await tb.driver.interfaces[0].ports[0].set_lfc_ctrl(mqnic.MQNIC_PORT_LFC_CTRL_TX_LFC_EN | mqnic.MQNIC_PORT_LFC_CTRL_RX_LFC_EN) + await tb.driver.hw_regs.read_dword(0) + + lfc_xoff = Ether(src='DA:D1:D2:D3:D4:D5', dst='01:80:C2:00:00:01', type=0x8808) / struct.pack('!HH', 0x0001, 2000) + + await tb.qsfp_source[0][0].send(XgmiiFrame.from_payload(bytes(lfc_xoff))) + + count = 16 + + pkts = [bytearray([(x+k) % 256 for x in range(1514)]) for k in range(count)] + + tb.loopback_enable = True + + for p in pkts: + await tb.driver.interfaces[0].start_xmit(p, 0) + + for k in range(count): + pkt = await tb.driver.interfaces[0].recv() + + tb.log.info("Packet: %s", pkt) + assert pkt.data == pkts[k] + if tb.driver.interfaces[0].if_feature_rx_csum: + assert pkt.rx_checksum == ~scapy.utils.checksum(bytes(pkt.data[14:])) & 0xffff + + tb.loopback_enable = False + await RisingEdge(dut.clk_250mhz) await RisingEdge(dut.clk_250mhz) @@ -601,6 +631,10 @@ def test_fpga_core(request): os.path.join(eth_rtl_dir, "eth_mac_10g.v"), os.path.join(eth_rtl_dir, "axis_xgmii_rx_64.v"), os.path.join(eth_rtl_dir, "axis_xgmii_tx_64.v"), + os.path.join(eth_rtl_dir, "mac_ctrl_rx.v"), + os.path.join(eth_rtl_dir, "mac_ctrl_tx.v"), + os.path.join(eth_rtl_dir, "mac_pause_ctrl_rx.v"), + os.path.join(eth_rtl_dir, "mac_pause_ctrl_tx.v"), os.path.join(eth_rtl_dir, "lfsr.v"), os.path.join(eth_rtl_dir, "ptp_clock.v"), os.path.join(eth_rtl_dir, "ptp_clock_cdc.v"), @@ -707,6 +741,8 @@ def test_fpga_core(request): parameters['TX_CHECKSUM_ENABLE'] = 1 parameters['RX_HASH_ENABLE'] = 1 parameters['RX_CHECKSUM_ENABLE'] = 1 + parameters['LFC_ENABLE'] = 1 + parameters['PFC_ENABLE'] = parameters['LFC_ENABLE'] parameters['TX_FIFO_DEPTH'] = 32768 parameters['RX_FIFO_DEPTH'] = 32768 parameters['MAX_TX_SIZE'] = 9214 diff --git a/fpga/mqnic/fb4CGg3/fpga_100g/fpga/config.tcl b/fpga/mqnic/fb4CGg3/fpga_100g/fpga/config.tcl index 6a7ad89ee..3a21cd405 100644 --- a/fpga/mqnic/fb4CGg3/fpga_100g/fpga/config.tcl +++ b/fpga/mqnic/fb4CGg3/fpga_100g/fpga/config.tcl @@ -101,6 +101,8 @@ dict set params TX_CPL_FIFO_DEPTH "32" dict set params TX_CHECKSUM_ENABLE "1" dict set params RX_HASH_ENABLE "1" dict set params RX_CHECKSUM_ENABLE "1" +dict set params PFC_ENABLE "1" +dict set params LFC_ENABLE [dict get $params PFC_ENABLE] dict set params TX_FIFO_DEPTH "32768" dict set params RX_FIFO_DEPTH "131072" dict set params MAX_TX_SIZE "9214" diff --git a/fpga/mqnic/fb4CGg3/fpga_100g/fpga_app_dma_bench/config.tcl b/fpga/mqnic/fb4CGg3/fpga_100g/fpga_app_dma_bench/config.tcl index 0a788bf3c..2f713b7bf 100644 --- a/fpga/mqnic/fb4CGg3/fpga_100g/fpga_app_dma_bench/config.tcl +++ b/fpga/mqnic/fb4CGg3/fpga_100g/fpga_app_dma_bench/config.tcl @@ -101,6 +101,8 @@ dict set params TX_CPL_FIFO_DEPTH "32" dict set params TX_CHECKSUM_ENABLE "1" dict set params RX_HASH_ENABLE "1" dict set params RX_CHECKSUM_ENABLE "1" +dict set params PFC_ENABLE "1" +dict set params LFC_ENABLE [dict get $params PFC_ENABLE] dict set params TX_FIFO_DEPTH "32768" dict set params RX_FIFO_DEPTH "131072" dict set params MAX_TX_SIZE "9214" diff --git a/fpga/mqnic/fb4CGg3/fpga_100g/ip/cmac_usplus.tcl b/fpga/mqnic/fb4CGg3/fpga_100g/ip/cmac_usplus.tcl index b86d4ea5e..af9cc8265 100644 --- a/fpga/mqnic/fb4CGg3/fpga_100g/ip/cmac_usplus.tcl +++ b/fpga/mqnic/fb4CGg3/fpga_100g/ip/cmac_usplus.tcl @@ -7,8 +7,10 @@ set_property -dict [list \ CONFIG.USER_INTERFACE {AXIS} \ CONFIG.GT_DRP_CLK {125} \ CONFIG.GT_LOCATION {0} \ - CONFIG.TX_FLOW_CONTROL {0} \ - CONFIG.RX_FLOW_CONTROL {0} \ + CONFIG.TX_FLOW_CONTROL {1} \ + CONFIG.RX_FLOW_CONTROL {1} \ + CONFIG.RX_FORWARD_CONTROL_FRAMES {0} \ + CONFIG.RX_CHECK_ACK {1} \ CONFIG.INCLUDE_RS_FEC {1} \ CONFIG.ENABLE_TIME_STAMPING {1} ] [get_ips cmac_usplus] diff --git a/fpga/mqnic/fb4CGg3/fpga_100g/rtl/fpga.v b/fpga/mqnic/fb4CGg3/fpga_100g/rtl/fpga.v index 4119e4886..0da4d2645 100644 --- a/fpga/mqnic/fb4CGg3/fpga_100g/rtl/fpga.v +++ b/fpga/mqnic/fb4CGg3/fpga_100g/rtl/fpga.v @@ -71,6 +71,8 @@ module fpga # parameter TX_CHECKSUM_ENABLE = 1, parameter RX_HASH_ENABLE = 1, parameter RX_CHECKSUM_ENABLE = 1, + parameter PFC_ENABLE = 1, + parameter LFC_ENABLE = PFC_ENABLE, parameter TX_FIFO_DEPTH = 32768, parameter RX_FIFO_DEPTH = 131072, parameter MAX_TX_SIZE = 9214, @@ -967,7 +969,20 @@ wire qsfp_0_drp_we; wire [15:0] qsfp_0_drp_do; wire qsfp_0_drp_rdy; -wire qsfp_0_rx_status; +wire qsfp_0_tx_enable; +wire qsfp_0_tx_lfc_en; +wire qsfp_0_tx_lfc_req; +wire [7:0] qsfp_0_tx_pfc_en; +wire [7:0] qsfp_0_tx_pfc_req; + +wire qsfp_0_rx_enable; +wire qsfp_0_rx_status; +wire qsfp_0_rx_lfc_en; +wire qsfp_0_rx_lfc_req; +wire qsfp_0_rx_lfc_ack; +wire [7:0] qsfp_0_rx_pfc_en; +wire [7:0] qsfp_0_rx_pfc_req; +wire [7:0] qsfp_0_rx_pfc_ack; wire qsfp_0_gtpowergood; @@ -1068,6 +1083,12 @@ qsfp_0_cmac_inst ( .tx_ptp_ts_tag(qsfp_0_tx_ptp_ts_tag_int), .tx_ptp_ts_valid(qsfp_0_tx_ptp_ts_valid_int), + .tx_enable(qsfp_0_tx_enable), + .tx_lfc_en(qsfp_0_tx_lfc_en), + .tx_lfc_req(qsfp_0_tx_lfc_req), + .tx_pfc_en(qsfp_0_tx_pfc_en), + .tx_pfc_req(qsfp_0_tx_pfc_req), + .rx_clk(qsfp_0_rx_clk_int), .rx_rst(qsfp_0_rx_rst_int), @@ -1081,7 +1102,14 @@ qsfp_0_cmac_inst ( .rx_ptp_rst(qsfp_0_rx_ptp_rst_int), .rx_ptp_time(qsfp_0_rx_ptp_time_int), - .rx_status(qsfp_0_rx_status) + .rx_enable(qsfp_0_rx_enable), + .rx_status(qsfp_0_rx_status), + .rx_lfc_en(qsfp_0_rx_lfc_en), + .rx_lfc_req(qsfp_0_rx_lfc_req), + .rx_lfc_ack(qsfp_0_rx_lfc_ack), + .rx_pfc_en(qsfp_0_rx_pfc_en), + .rx_pfc_req(qsfp_0_rx_pfc_req), + .rx_pfc_ack(qsfp_0_rx_pfc_ack) ); // QSFP1 CMAC @@ -1122,7 +1150,20 @@ wire qsfp_1_drp_we; wire [15:0] qsfp_1_drp_do; wire qsfp_1_drp_rdy; -wire qsfp_1_rx_status; +wire qsfp_1_tx_enable; +wire qsfp_1_tx_lfc_en; +wire qsfp_1_tx_lfc_req; +wire [7:0] qsfp_1_tx_pfc_en; +wire [7:0] qsfp_1_tx_pfc_req; + +wire qsfp_1_rx_enable; +wire qsfp_1_rx_status; +wire qsfp_1_rx_lfc_en; +wire qsfp_1_rx_lfc_req; +wire qsfp_1_rx_lfc_ack; +wire [7:0] qsfp_1_rx_pfc_en; +wire [7:0] qsfp_1_rx_pfc_req; +wire [7:0] qsfp_1_rx_pfc_ack; wire qsfp_1_gtpowergood; @@ -1223,6 +1264,12 @@ qsfp_1_cmac_inst ( .tx_ptp_ts_tag(qsfp_1_tx_ptp_ts_tag_int), .tx_ptp_ts_valid(qsfp_1_tx_ptp_ts_valid_int), + .tx_enable(qsfp_1_tx_enable), + .tx_lfc_en(qsfp_1_tx_lfc_en), + .tx_lfc_req(qsfp_1_tx_lfc_req), + .tx_pfc_en(qsfp_1_tx_pfc_en), + .tx_pfc_req(qsfp_1_tx_pfc_req), + .rx_clk(qsfp_1_rx_clk_int), .rx_rst(qsfp_1_rx_rst_int), @@ -1236,7 +1283,14 @@ qsfp_1_cmac_inst ( .rx_ptp_rst(qsfp_1_rx_ptp_rst_int), .rx_ptp_time(qsfp_1_rx_ptp_time_int), - .rx_status(qsfp_1_rx_status) + .rx_enable(qsfp_1_rx_enable), + .rx_status(qsfp_1_rx_status), + .rx_lfc_en(qsfp_1_rx_lfc_en), + .rx_lfc_req(qsfp_1_rx_lfc_req), + .rx_lfc_ack(qsfp_1_rx_lfc_ack), + .rx_pfc_en(qsfp_1_rx_pfc_en), + .rx_pfc_req(qsfp_1_rx_pfc_req), + .rx_pfc_ack(qsfp_1_rx_pfc_ack) ); // QSFP2 CMAC @@ -1277,7 +1331,20 @@ wire qsfp_2_drp_we; wire [15:0] qsfp_2_drp_do; wire qsfp_2_drp_rdy; -wire qsfp_2_rx_status; +wire qsfp_2_tx_enable; +wire qsfp_2_tx_lfc_en; +wire qsfp_2_tx_lfc_req; +wire [7:0] qsfp_2_tx_pfc_en; +wire [7:0] qsfp_2_tx_pfc_req; + +wire qsfp_2_rx_enable; +wire qsfp_2_rx_status; +wire qsfp_2_rx_lfc_en; +wire qsfp_2_rx_lfc_req; +wire qsfp_2_rx_lfc_ack; +wire [7:0] qsfp_2_rx_pfc_en; +wire [7:0] qsfp_2_rx_pfc_req; +wire [7:0] qsfp_2_rx_pfc_ack; wire qsfp_2_gtpowergood; @@ -1378,6 +1445,12 @@ qsfp_2_cmac_inst ( .tx_ptp_ts_tag(qsfp_2_tx_ptp_ts_tag_int), .tx_ptp_ts_valid(qsfp_2_tx_ptp_ts_valid_int), + .tx_enable(qsfp_2_tx_enable), + .tx_lfc_en(qsfp_2_tx_lfc_en), + .tx_lfc_req(qsfp_2_tx_lfc_req), + .tx_pfc_en(qsfp_2_tx_pfc_en), + .tx_pfc_req(qsfp_2_tx_pfc_req), + .rx_clk(qsfp_2_rx_clk_int), .rx_rst(qsfp_2_rx_rst_int), @@ -1391,7 +1464,14 @@ qsfp_2_cmac_inst ( .rx_ptp_rst(qsfp_2_rx_ptp_rst_int), .rx_ptp_time(qsfp_2_rx_ptp_time_int), - .rx_status(qsfp_2_rx_status) + .rx_enable(qsfp_2_rx_enable), + .rx_status(qsfp_2_rx_status), + .rx_lfc_en(qsfp_2_rx_lfc_en), + .rx_lfc_req(qsfp_2_rx_lfc_req), + .rx_lfc_ack(qsfp_2_rx_lfc_ack), + .rx_pfc_en(qsfp_2_rx_pfc_en), + .rx_pfc_req(qsfp_2_rx_pfc_req), + .rx_pfc_ack(qsfp_2_rx_pfc_ack) ); // QSFP3 CMAC @@ -1432,7 +1512,20 @@ wire qsfp_3_drp_we; wire [15:0] qsfp_3_drp_do; wire qsfp_3_drp_rdy; -wire qsfp_3_rx_status; +wire qsfp_3_tx_enable; +wire qsfp_3_tx_lfc_en; +wire qsfp_3_tx_lfc_req; +wire [7:0] qsfp_3_tx_pfc_en; +wire [7:0] qsfp_3_tx_pfc_req; + +wire qsfp_3_rx_enable; +wire qsfp_3_rx_status; +wire qsfp_3_rx_lfc_en; +wire qsfp_3_rx_lfc_req; +wire qsfp_3_rx_lfc_ack; +wire [7:0] qsfp_3_rx_pfc_en; +wire [7:0] qsfp_3_rx_pfc_req; +wire [7:0] qsfp_3_rx_pfc_ack; wire qsfp_3_gtpowergood; @@ -1533,6 +1626,12 @@ qsfp_3_cmac_inst ( .tx_ptp_ts_tag(qsfp_3_tx_ptp_ts_tag_int), .tx_ptp_ts_valid(qsfp_3_tx_ptp_ts_valid_int), + .tx_enable(qsfp_3_tx_enable), + .tx_lfc_en(qsfp_3_tx_lfc_en), + .tx_lfc_req(qsfp_3_tx_lfc_req), + .tx_pfc_en(qsfp_3_tx_pfc_en), + .tx_pfc_req(qsfp_3_tx_pfc_req), + .rx_clk(qsfp_3_rx_clk_int), .rx_rst(qsfp_3_rx_rst_int), @@ -1546,7 +1645,14 @@ qsfp_3_cmac_inst ( .rx_ptp_rst(qsfp_3_rx_ptp_rst_int), .rx_ptp_time(qsfp_3_rx_ptp_time_int), - .rx_status(qsfp_3_rx_status) + .rx_enable(qsfp_3_rx_enable), + .rx_status(qsfp_3_rx_status), + .rx_lfc_en(qsfp_3_rx_lfc_en), + .rx_lfc_req(qsfp_3_rx_lfc_req), + .rx_lfc_ack(qsfp_3_rx_lfc_ack), + .rx_pfc_en(qsfp_3_rx_pfc_en), + .rx_pfc_req(qsfp_3_rx_pfc_req), + .rx_pfc_ack(qsfp_3_rx_pfc_ack) ); wire ptp_clk; @@ -2115,6 +2221,8 @@ fpga_core #( .TX_CHECKSUM_ENABLE(TX_CHECKSUM_ENABLE), .RX_HASH_ENABLE(RX_HASH_ENABLE), .RX_CHECKSUM_ENABLE(RX_CHECKSUM_ENABLE), + .PFC_ENABLE(PFC_ENABLE), + .LFC_ENABLE(LFC_ENABLE), .TX_FIFO_DEPTH(TX_FIFO_DEPTH), .RX_FIFO_DEPTH(RX_FIFO_DEPTH), .MAX_TX_SIZE(MAX_TX_SIZE), @@ -2322,6 +2430,12 @@ core_inst ( .qsfp_0_tx_ptp_ts_tag(qsfp_0_tx_ptp_ts_tag_int), .qsfp_0_tx_ptp_ts_valid(qsfp_0_tx_ptp_ts_valid_int), + .qsfp_0_tx_enable(qsfp_0_tx_enable), + .qsfp_0_tx_lfc_en(qsfp_0_tx_lfc_en), + .qsfp_0_tx_lfc_req(qsfp_0_tx_lfc_req), + .qsfp_0_tx_pfc_en(qsfp_0_tx_pfc_en), + .qsfp_0_tx_pfc_req(qsfp_0_tx_pfc_req), + .qsfp_0_rx_clk(qsfp_0_rx_clk_int), .qsfp_0_rx_rst(qsfp_0_rx_rst_int), .qsfp_0_rx_axis_tdata(qsfp_0_rx_axis_tdata_int), @@ -2333,7 +2447,14 @@ core_inst ( .qsfp_0_rx_ptp_rst(qsfp_0_rx_ptp_rst_int), .qsfp_0_rx_ptp_time(qsfp_0_rx_ptp_time_int), + .qsfp_0_rx_enable(qsfp_0_rx_enable), .qsfp_0_rx_status(qsfp_0_rx_status), + .qsfp_0_rx_lfc_en(qsfp_0_rx_lfc_en), + .qsfp_0_rx_lfc_req(qsfp_0_rx_lfc_req), + .qsfp_0_rx_lfc_ack(qsfp_0_rx_lfc_ack), + .qsfp_0_rx_pfc_en(qsfp_0_rx_pfc_en), + .qsfp_0_rx_pfc_req(qsfp_0_rx_pfc_req), + .qsfp_0_rx_pfc_ack(qsfp_0_rx_pfc_ack), .qsfp_0_drp_clk(qsfp_0_drp_clk), .qsfp_0_drp_rst(qsfp_0_drp_rst), @@ -2369,6 +2490,12 @@ core_inst ( .qsfp_1_tx_ptp_ts_tag(qsfp_1_tx_ptp_ts_tag_int), .qsfp_1_tx_ptp_ts_valid(qsfp_1_tx_ptp_ts_valid_int), + .qsfp_1_tx_enable(qsfp_1_tx_enable), + .qsfp_1_tx_lfc_en(qsfp_1_tx_lfc_en), + .qsfp_1_tx_lfc_req(qsfp_1_tx_lfc_req), + .qsfp_1_tx_pfc_en(qsfp_1_tx_pfc_en), + .qsfp_1_tx_pfc_req(qsfp_1_tx_pfc_req), + .qsfp_1_rx_clk(qsfp_1_rx_clk_int), .qsfp_1_rx_rst(qsfp_1_rx_rst_int), .qsfp_1_rx_axis_tdata(qsfp_1_rx_axis_tdata_int), @@ -2380,7 +2507,14 @@ core_inst ( .qsfp_1_rx_ptp_rst(qsfp_1_rx_ptp_rst_int), .qsfp_1_rx_ptp_time(qsfp_1_rx_ptp_time_int), + .qsfp_1_rx_enable(qsfp_1_rx_enable), .qsfp_1_rx_status(qsfp_1_rx_status), + .qsfp_1_rx_lfc_en(qsfp_1_rx_lfc_en), + .qsfp_1_rx_lfc_req(qsfp_1_rx_lfc_req), + .qsfp_1_rx_lfc_ack(qsfp_1_rx_lfc_ack), + .qsfp_1_rx_pfc_en(qsfp_1_rx_pfc_en), + .qsfp_1_rx_pfc_req(qsfp_1_rx_pfc_req), + .qsfp_1_rx_pfc_ack(qsfp_1_rx_pfc_ack), .qsfp_1_drp_clk(qsfp_1_drp_clk), .qsfp_1_drp_rst(qsfp_1_drp_rst), @@ -2416,6 +2550,12 @@ core_inst ( .qsfp_2_tx_ptp_ts_tag(qsfp_2_tx_ptp_ts_tag_int), .qsfp_2_tx_ptp_ts_valid(qsfp_2_tx_ptp_ts_valid_int), + .qsfp_2_tx_enable(qsfp_2_tx_enable), + .qsfp_2_tx_lfc_en(qsfp_2_tx_lfc_en), + .qsfp_2_tx_lfc_req(qsfp_2_tx_lfc_req), + .qsfp_2_tx_pfc_en(qsfp_2_tx_pfc_en), + .qsfp_2_tx_pfc_req(qsfp_2_tx_pfc_req), + .qsfp_2_rx_clk(qsfp_2_rx_clk_int), .qsfp_2_rx_rst(qsfp_2_rx_rst_int), .qsfp_2_rx_axis_tdata(qsfp_2_rx_axis_tdata_int), @@ -2427,7 +2567,14 @@ core_inst ( .qsfp_2_rx_ptp_rst(qsfp_2_rx_ptp_rst_int), .qsfp_2_rx_ptp_time(qsfp_2_rx_ptp_time_int), + .qsfp_2_rx_enable(qsfp_2_rx_enable), .qsfp_2_rx_status(qsfp_2_rx_status), + .qsfp_2_rx_lfc_en(qsfp_2_rx_lfc_en), + .qsfp_2_rx_lfc_req(qsfp_2_rx_lfc_req), + .qsfp_2_rx_lfc_ack(qsfp_2_rx_lfc_ack), + .qsfp_2_rx_pfc_en(qsfp_2_rx_pfc_en), + .qsfp_2_rx_pfc_req(qsfp_2_rx_pfc_req), + .qsfp_2_rx_pfc_ack(qsfp_2_rx_pfc_ack), .qsfp_2_drp_clk(qsfp_2_drp_clk), .qsfp_2_drp_rst(qsfp_2_drp_rst), @@ -2463,6 +2610,12 @@ core_inst ( .qsfp_3_tx_ptp_ts_tag(qsfp_3_tx_ptp_ts_tag_int), .qsfp_3_tx_ptp_ts_valid(qsfp_3_tx_ptp_ts_valid_int), + .qsfp_3_tx_enable(qsfp_3_tx_enable), + .qsfp_3_tx_lfc_en(qsfp_3_tx_lfc_en), + .qsfp_3_tx_lfc_req(qsfp_3_tx_lfc_req), + .qsfp_3_tx_pfc_en(qsfp_3_tx_pfc_en), + .qsfp_3_tx_pfc_req(qsfp_3_tx_pfc_req), + .qsfp_3_rx_clk(qsfp_3_rx_clk_int), .qsfp_3_rx_rst(qsfp_3_rx_rst_int), .qsfp_3_rx_axis_tdata(qsfp_3_rx_axis_tdata_int), @@ -2474,7 +2627,14 @@ core_inst ( .qsfp_3_rx_ptp_rst(qsfp_3_rx_ptp_rst_int), .qsfp_3_rx_ptp_time(qsfp_3_rx_ptp_time_int), + .qsfp_3_rx_enable(qsfp_3_rx_enable), .qsfp_3_rx_status(qsfp_3_rx_status), + .qsfp_3_rx_lfc_en(qsfp_3_rx_lfc_en), + .qsfp_3_rx_lfc_req(qsfp_3_rx_lfc_req), + .qsfp_3_rx_lfc_ack(qsfp_3_rx_lfc_ack), + .qsfp_3_rx_pfc_en(qsfp_3_rx_pfc_en), + .qsfp_3_rx_pfc_req(qsfp_3_rx_pfc_req), + .qsfp_3_rx_pfc_ack(qsfp_3_rx_pfc_ack), .qsfp_3_drp_clk(qsfp_3_drp_clk), .qsfp_3_drp_rst(qsfp_3_drp_rst), diff --git a/fpga/mqnic/fb4CGg3/fpga_100g/rtl/fpga_core.v b/fpga/mqnic/fb4CGg3/fpga_100g/rtl/fpga_core.v index b67468353..1f07231df 100644 --- a/fpga/mqnic/fb4CGg3/fpga_100g/rtl/fpga_core.v +++ b/fpga/mqnic/fb4CGg3/fpga_100g/rtl/fpga_core.v @@ -77,6 +77,8 @@ module fpga_core # parameter TX_CHECKSUM_ENABLE = 1, parameter RX_HASH_ENABLE = 1, parameter RX_CHECKSUM_ENABLE = 1, + parameter PFC_ENABLE = 1, + parameter LFC_ENABLE = PFC_ENABLE, parameter TX_FIFO_DEPTH = 32768, parameter RX_FIFO_DEPTH = 131072, parameter MAX_TX_SIZE = 9214, @@ -286,6 +288,12 @@ module fpga_core # input wire [15:0] qsfp_0_tx_ptp_ts_tag, input wire qsfp_0_tx_ptp_ts_valid, + output wire qsfp_0_tx_enable, + output wire qsfp_0_tx_lfc_en, + output wire qsfp_0_tx_lfc_req, + output wire [7:0] qsfp_0_tx_pfc_en, + output wire [7:0] qsfp_0_tx_pfc_req, + input wire qsfp_0_rx_clk, input wire qsfp_0_rx_rst, @@ -299,7 +307,14 @@ module fpga_core # input wire qsfp_0_rx_ptp_rst, output wire [79:0] qsfp_0_rx_ptp_time, + output wire qsfp_0_rx_enable, input wire qsfp_0_rx_status, + output wire qsfp_0_rx_lfc_en, + input wire qsfp_0_rx_lfc_req, + output wire qsfp_0_rx_lfc_ack, + output wire [7:0] qsfp_0_rx_pfc_en, + input wire [7:0] qsfp_0_rx_pfc_req, + output wire [7:0] qsfp_0_rx_pfc_ack, input wire qsfp_0_drp_clk, input wire qsfp_0_drp_rst, @@ -336,6 +351,12 @@ module fpga_core # input wire [15:0] qsfp_1_tx_ptp_ts_tag, input wire qsfp_1_tx_ptp_ts_valid, + output wire qsfp_1_tx_enable, + output wire qsfp_1_tx_lfc_en, + output wire qsfp_1_tx_lfc_req, + output wire [7:0] qsfp_1_tx_pfc_en, + output wire [7:0] qsfp_1_tx_pfc_req, + input wire qsfp_1_rx_clk, input wire qsfp_1_rx_rst, @@ -349,7 +370,14 @@ module fpga_core # input wire qsfp_1_rx_ptp_rst, output wire [79:0] qsfp_1_rx_ptp_time, + output wire qsfp_1_rx_enable, input wire qsfp_1_rx_status, + output wire qsfp_1_rx_lfc_en, + input wire qsfp_1_rx_lfc_req, + output wire qsfp_1_rx_lfc_ack, + output wire [7:0] qsfp_1_rx_pfc_en, + input wire [7:0] qsfp_1_rx_pfc_req, + output wire [7:0] qsfp_1_rx_pfc_ack, input wire qsfp_1_drp_clk, input wire qsfp_1_drp_rst, @@ -386,6 +414,12 @@ module fpga_core # input wire [15:0] qsfp_2_tx_ptp_ts_tag, input wire qsfp_2_tx_ptp_ts_valid, + output wire qsfp_2_tx_enable, + output wire qsfp_2_tx_lfc_en, + output wire qsfp_2_tx_lfc_req, + output wire [7:0] qsfp_2_tx_pfc_en, + output wire [7:0] qsfp_2_tx_pfc_req, + input wire qsfp_2_rx_clk, input wire qsfp_2_rx_rst, @@ -399,7 +433,14 @@ module fpga_core # input wire qsfp_2_rx_ptp_rst, output wire [79:0] qsfp_2_rx_ptp_time, + output wire qsfp_2_rx_enable, input wire qsfp_2_rx_status, + output wire qsfp_2_rx_lfc_en, + input wire qsfp_2_rx_lfc_req, + output wire qsfp_2_rx_lfc_ack, + output wire [7:0] qsfp_2_rx_pfc_en, + input wire [7:0] qsfp_2_rx_pfc_req, + output wire [7:0] qsfp_2_rx_pfc_ack, input wire qsfp_2_drp_clk, input wire qsfp_2_drp_rst, @@ -436,6 +477,12 @@ module fpga_core # input wire [15:0] qsfp_3_tx_ptp_ts_tag, input wire qsfp_3_tx_ptp_ts_valid, + output wire qsfp_3_tx_enable, + output wire qsfp_3_tx_lfc_en, + output wire qsfp_3_tx_lfc_req, + output wire [7:0] qsfp_3_tx_pfc_en, + output wire [7:0] qsfp_3_tx_pfc_req, + input wire qsfp_3_rx_clk, input wire qsfp_3_rx_rst, @@ -449,7 +496,14 @@ module fpga_core # input wire qsfp_3_rx_ptp_rst, output wire [79:0] qsfp_3_rx_ptp_time, + output wire qsfp_3_rx_enable, input wire qsfp_3_rx_status, + output wire qsfp_3_rx_lfc_en, + input wire qsfp_3_rx_lfc_req, + output wire qsfp_3_rx_lfc_ack, + output wire [7:0] qsfp_3_rx_pfc_en, + input wire [7:0] qsfp_3_rx_pfc_req, + output wire [7:0] qsfp_3_rx_pfc_ack, input wire qsfp_3_drp_clk, input wire qsfp_3_drp_rst, @@ -1093,7 +1147,12 @@ wire [PORT_COUNT*TX_TAG_WIDTH-1:0] axis_eth_tx_ptp_ts_tag; wire [PORT_COUNT-1:0] axis_eth_tx_ptp_ts_valid; wire [PORT_COUNT-1:0] axis_eth_tx_ptp_ts_ready; +wire [PORT_COUNT-1:0] eth_tx_enable; wire [PORT_COUNT-1:0] eth_tx_status; +wire [PORT_COUNT-1:0] eth_tx_lfc_en; +wire [PORT_COUNT-1:0] eth_tx_lfc_req; +wire [PORT_COUNT*8-1:0] eth_tx_pfc_en; +wire [PORT_COUNT*8-1:0] eth_tx_pfc_req; wire [PORT_COUNT-1:0] eth_rx_clk; wire [PORT_COUNT-1:0] eth_rx_rst; @@ -1110,7 +1169,14 @@ wire [PORT_COUNT-1:0] axis_eth_rx_tready; wire [PORT_COUNT-1:0] axis_eth_rx_tlast; wire [PORT_COUNT*AXIS_ETH_RX_USER_WIDTH-1:0] axis_eth_rx_tuser; +wire [PORT_COUNT-1:0] eth_rx_enable; wire [PORT_COUNT-1:0] eth_rx_status; +wire [PORT_COUNT-1:0] eth_rx_lfc_en; +wire [PORT_COUNT-1:0] eth_rx_lfc_req; +wire [PORT_COUNT-1:0] eth_rx_lfc_ack; +wire [PORT_COUNT*8-1:0] eth_rx_pfc_en; +wire [PORT_COUNT*8-1:0] eth_rx_pfc_req; +wire [PORT_COUNT*8-1:0] eth_rx_pfc_ack; wire [PTP_TS_WIDTH-1:0] qsfp_0_tx_ptp_time_int; wire [PTP_TS_WIDTH-1:0] qsfp_1_tx_ptp_time_int; @@ -1169,7 +1235,12 @@ mqnic_port_map_mac_axis_inst ( .s_axis_mac_tx_ptp_ts_valid({qsfp_3_tx_ptp_ts_valid, qsfp_2_tx_ptp_ts_valid, qsfp_1_tx_ptp_ts_valid, qsfp_0_tx_ptp_ts_valid}), .s_axis_mac_tx_ptp_ts_ready(), + .mac_tx_enable({qsfp_3_tx_enable, qsfp_2_tx_enable, qsfp_1_tx_enable, qsfp_0_tx_enable}), .mac_tx_status(4'b1111), + .mac_tx_lfc_en({qsfp_3_tx_lfc_en, qsfp_2_tx_lfc_en, qsfp_1_tx_lfc_en, qsfp_0_tx_lfc_en}), + .mac_tx_lfc_req({qsfp_3_tx_lfc_req, qsfp_2_tx_lfc_req, qsfp_1_tx_lfc_req, qsfp_0_tx_lfc_req}), + .mac_tx_pfc_en({qsfp_3_tx_pfc_en, qsfp_2_tx_pfc_en, qsfp_1_tx_pfc_en, qsfp_0_tx_pfc_en}), + .mac_tx_pfc_req({qsfp_3_tx_pfc_req, qsfp_2_tx_pfc_req, qsfp_1_tx_pfc_req, qsfp_0_tx_pfc_req}), .mac_rx_clk({qsfp_3_rx_clk, qsfp_2_rx_clk, qsfp_1_rx_clk, qsfp_0_rx_clk}), .mac_rx_rst({qsfp_3_rx_rst, qsfp_2_rx_rst, qsfp_1_rx_rst, qsfp_0_rx_rst}), @@ -1186,7 +1257,14 @@ mqnic_port_map_mac_axis_inst ( .s_axis_mac_rx_tlast({qsfp_3_rx_axis_tlast, qsfp_2_rx_axis_tlast, qsfp_1_rx_axis_tlast, qsfp_0_rx_axis_tlast}), .s_axis_mac_rx_tuser({{qsfp_3_rx_axis_tuser[80:1], 16'd0, qsfp_3_rx_axis_tuser[0]}, {qsfp_2_rx_axis_tuser[80:1], 16'd0, qsfp_2_rx_axis_tuser[0]}, {qsfp_1_rx_axis_tuser[80:1], 16'd0, qsfp_1_rx_axis_tuser[0]}, {qsfp_0_rx_axis_tuser[80:1], 16'd0, qsfp_0_rx_axis_tuser[0]}}), + .mac_rx_enable({qsfp_3_rx_enable, qsfp_2_rx_enable, qsfp_1_rx_enable, qsfp_0_rx_enable}), .mac_rx_status({qsfp_3_rx_status, qsfp_2_rx_status, qsfp_1_rx_status, qsfp_0_rx_status}), + .mac_rx_lfc_en({qsfp_3_rx_lfc_en, qsfp_2_rx_lfc_en, qsfp_1_rx_lfc_en, qsfp_0_rx_lfc_en}), + .mac_rx_lfc_req({qsfp_3_rx_lfc_req, qsfp_2_rx_lfc_req, qsfp_1_rx_lfc_req, qsfp_0_rx_lfc_req}), + .mac_rx_lfc_ack({qsfp_3_rx_lfc_ack, qsfp_2_rx_lfc_ack, qsfp_1_rx_lfc_ack, qsfp_0_rx_lfc_ack}), + .mac_rx_pfc_en({qsfp_3_rx_pfc_en, qsfp_2_rx_pfc_en, qsfp_1_rx_pfc_en, qsfp_0_rx_pfc_en}), + .mac_rx_pfc_req({qsfp_3_rx_pfc_req, qsfp_2_rx_pfc_req, qsfp_1_rx_pfc_req, qsfp_0_rx_pfc_req}), + .mac_rx_pfc_ack({qsfp_3_rx_pfc_ack, qsfp_2_rx_pfc_ack, qsfp_1_rx_pfc_ack, qsfp_0_rx_pfc_ack}), // towards datapath .tx_clk(eth_tx_clk), @@ -1209,7 +1287,12 @@ mqnic_port_map_mac_axis_inst ( .m_axis_tx_ptp_ts_valid(axis_eth_tx_ptp_ts_valid), .m_axis_tx_ptp_ts_ready(axis_eth_tx_ptp_ts_ready), + .tx_enable(eth_tx_enable), .tx_status(eth_tx_status), + .tx_lfc_en(eth_tx_lfc_en), + .tx_lfc_req(eth_tx_lfc_req), + .tx_pfc_en(eth_tx_pfc_en), + .tx_pfc_req(eth_tx_pfc_req), .rx_clk(eth_rx_clk), .rx_rst(eth_rx_rst), @@ -1226,7 +1309,14 @@ mqnic_port_map_mac_axis_inst ( .m_axis_rx_tlast(axis_eth_rx_tlast), .m_axis_rx_tuser(axis_eth_rx_tuser), - .rx_status(eth_rx_status) + .rx_enable(eth_rx_enable), + .rx_status(eth_rx_status), + .rx_lfc_en(eth_rx_lfc_en), + .rx_lfc_req(eth_rx_lfc_req), + .rx_lfc_ack(eth_rx_lfc_ack), + .rx_pfc_en(eth_rx_pfc_en), + .rx_pfc_req(eth_rx_pfc_req), + .rx_pfc_ack(eth_rx_pfc_ack) ); mqnic_core_pcie_us #( @@ -1296,6 +1386,9 @@ mqnic_core_pcie_us #( .TX_CHECKSUM_ENABLE(TX_CHECKSUM_ENABLE), .RX_HASH_ENABLE(RX_HASH_ENABLE), .RX_CHECKSUM_ENABLE(RX_CHECKSUM_ENABLE), + .PFC_ENABLE(PFC_ENABLE), + .LFC_ENABLE(LFC_ENABLE), + .MAC_CTRL_ENABLE(0), .TX_FIFO_DEPTH(TX_FIFO_DEPTH), .RX_FIFO_DEPTH(RX_FIFO_DEPTH), .MAX_TX_SIZE(MAX_TX_SIZE), @@ -1577,7 +1670,13 @@ core_inst ( .s_axis_eth_tx_cpl_valid(axis_eth_tx_ptp_ts_valid), .s_axis_eth_tx_cpl_ready(axis_eth_tx_ptp_ts_ready), + .eth_tx_enable(eth_tx_enable), .eth_tx_status(eth_tx_status), + .eth_tx_lfc_en(eth_tx_lfc_en), + .eth_tx_lfc_req(eth_tx_lfc_req), + .eth_tx_pfc_en(eth_tx_pfc_en), + .eth_tx_pfc_req(eth_tx_pfc_req), + .eth_tx_fc_quanta_clk_en(0), .eth_rx_clk(eth_rx_clk), .eth_rx_rst(eth_rx_rst), @@ -1594,7 +1693,15 @@ core_inst ( .s_axis_eth_rx_tlast(axis_eth_rx_tlast), .s_axis_eth_rx_tuser(axis_eth_rx_tuser), + .eth_rx_enable(eth_rx_enable), .eth_rx_status(eth_rx_status), + .eth_rx_lfc_en(eth_rx_lfc_en), + .eth_rx_lfc_req(eth_rx_lfc_req), + .eth_rx_lfc_ack(eth_rx_lfc_ack), + .eth_rx_pfc_en(eth_rx_pfc_en), + .eth_rx_pfc_req(eth_rx_pfc_req), + .eth_rx_pfc_ack(eth_rx_pfc_ack), + .eth_rx_fc_quanta_clk_en(0), /* * DDR diff --git a/fpga/mqnic/fb4CGg3/fpga_100g/tb/fpga_core/Makefile b/fpga/mqnic/fb4CGg3/fpga_100g/tb/fpga_core/Makefile index ff81f9bb4..a14e056c2 100644 --- a/fpga/mqnic/fb4CGg3/fpga_100g/tb/fpga_core/Makefile +++ b/fpga/mqnic/fb4CGg3/fpga_100g/tb/fpga_core/Makefile @@ -162,6 +162,8 @@ export PARAM_TX_CPL_FIFO_DEPTH := 32 export PARAM_TX_CHECKSUM_ENABLE := 1 export PARAM_RX_HASH_ENABLE := 1 export PARAM_RX_CHECKSUM_ENABLE := 1 +export PARAM_LFC_ENABLE := 1 +export PARAM_PFC_ENABLE := $(PARAM_LFC_ENABLE) export PARAM_TX_FIFO_DEPTH := 32768 export PARAM_RX_FIFO_DEPTH := 131072 export PARAM_MAX_TX_SIZE := 9214 diff --git a/fpga/mqnic/fb4CGg3/fpga_100g/tb/fpga_core/test_fpga_core.py b/fpga/mqnic/fb4CGg3/fpga_100g/tb/fpga_core/test_fpga_core.py index 3b149830b..fa040e912 100644 --- a/fpga/mqnic/fb4CGg3/fpga_100g/tb/fpga_core/test_fpga_core.py +++ b/fpga/mqnic/fb4CGg3/fpga_100g/tb/fpga_core/test_fpga_core.py @@ -721,6 +721,8 @@ def test_fpga_core(request): parameters['TX_CHECKSUM_ENABLE'] = 1 parameters['RX_HASH_ENABLE'] = 1 parameters['RX_CHECKSUM_ENABLE'] = 1 + parameters['LFC_ENABLE'] = 1 + parameters['PFC_ENABLE'] = parameters['LFC_ENABLE'] parameters['TX_FIFO_DEPTH'] = 32768 parameters['RX_FIFO_DEPTH'] = 131072 parameters['MAX_TX_SIZE'] = 9214 diff --git a/fpga/mqnic/fb4CGg3/fpga_25g/fpga/Makefile b/fpga/mqnic/fb4CGg3/fpga_25g/fpga/Makefile index c8ef4eca7..4a68f5aba 100644 --- a/fpga/mqnic/fb4CGg3/fpga_25g/fpga/Makefile +++ b/fpga/mqnic/fb4CGg3/fpga_25g/fpga/Makefile @@ -63,6 +63,10 @@ SYN_FILES += rtl/common/led_sreg_driver.v SYN_FILES += lib/eth/rtl/eth_mac_10g.v SYN_FILES += lib/eth/rtl/axis_xgmii_rx_64.v SYN_FILES += lib/eth/rtl/axis_xgmii_tx_64.v +SYN_FILES += lib/eth/rtl/mac_ctrl_rx.v +SYN_FILES += lib/eth/rtl/mac_ctrl_tx.v +SYN_FILES += lib/eth/rtl/mac_pause_ctrl_rx.v +SYN_FILES += lib/eth/rtl/mac_pause_ctrl_tx.v SYN_FILES += lib/eth/rtl/eth_phy_10g.v SYN_FILES += lib/eth/rtl/eth_phy_10g_rx.v SYN_FILES += lib/eth/rtl/eth_phy_10g_rx_if.v diff --git a/fpga/mqnic/fb4CGg3/fpga_25g/fpga/config.tcl b/fpga/mqnic/fb4CGg3/fpga_25g/fpga/config.tcl index f677705f0..137c7be95 100644 --- a/fpga/mqnic/fb4CGg3/fpga_25g/fpga/config.tcl +++ b/fpga/mqnic/fb4CGg3/fpga_25g/fpga/config.tcl @@ -113,6 +113,8 @@ dict set params TX_CPL_FIFO_DEPTH "32" dict set params TX_CHECKSUM_ENABLE "1" dict set params RX_HASH_ENABLE "1" dict set params RX_CHECKSUM_ENABLE "1" +dict set params PFC_ENABLE "1" +dict set params LFC_ENABLE [dict get $params PFC_ENABLE] dict set params ENABLE_PADDING "1" dict set params ENABLE_DIC "1" dict set params MIN_FRAME_LENGTH "64" diff --git a/fpga/mqnic/fb4CGg3/fpga_25g/fpga_10g/Makefile b/fpga/mqnic/fb4CGg3/fpga_25g/fpga_10g/Makefile index c8ef4eca7..4a68f5aba 100644 --- a/fpga/mqnic/fb4CGg3/fpga_25g/fpga_10g/Makefile +++ b/fpga/mqnic/fb4CGg3/fpga_25g/fpga_10g/Makefile @@ -63,6 +63,10 @@ SYN_FILES += rtl/common/led_sreg_driver.v SYN_FILES += lib/eth/rtl/eth_mac_10g.v SYN_FILES += lib/eth/rtl/axis_xgmii_rx_64.v SYN_FILES += lib/eth/rtl/axis_xgmii_tx_64.v +SYN_FILES += lib/eth/rtl/mac_ctrl_rx.v +SYN_FILES += lib/eth/rtl/mac_ctrl_tx.v +SYN_FILES += lib/eth/rtl/mac_pause_ctrl_rx.v +SYN_FILES += lib/eth/rtl/mac_pause_ctrl_tx.v SYN_FILES += lib/eth/rtl/eth_phy_10g.v SYN_FILES += lib/eth/rtl/eth_phy_10g_rx.v SYN_FILES += lib/eth/rtl/eth_phy_10g_rx_if.v diff --git a/fpga/mqnic/fb4CGg3/fpga_25g/fpga_10g/config.tcl b/fpga/mqnic/fb4CGg3/fpga_25g/fpga_10g/config.tcl index dc4e569fc..83976b598 100644 --- a/fpga/mqnic/fb4CGg3/fpga_25g/fpga_10g/config.tcl +++ b/fpga/mqnic/fb4CGg3/fpga_25g/fpga_10g/config.tcl @@ -113,6 +113,8 @@ dict set params TX_CPL_FIFO_DEPTH "32" dict set params TX_CHECKSUM_ENABLE "1" dict set params RX_HASH_ENABLE "1" dict set params RX_CHECKSUM_ENABLE "1" +dict set params PFC_ENABLE "1" +dict set params LFC_ENABLE [dict get $params PFC_ENABLE] dict set params ENABLE_PADDING "1" dict set params ENABLE_DIC "1" dict set params MIN_FRAME_LENGTH "64" diff --git a/fpga/mqnic/fb4CGg3/fpga_25g/rtl/fpga.v b/fpga/mqnic/fb4CGg3/fpga_25g/rtl/fpga.v index d6affd110..afc0f92cc 100644 --- a/fpga/mqnic/fb4CGg3/fpga_25g/rtl/fpga.v +++ b/fpga/mqnic/fb4CGg3/fpga_25g/rtl/fpga.v @@ -74,6 +74,8 @@ module fpga # parameter TX_CHECKSUM_ENABLE = 1, parameter RX_HASH_ENABLE = 1, parameter RX_CHECKSUM_ENABLE = 1, + parameter PFC_ENABLE = 1, + parameter LFC_ENABLE = PFC_ENABLE, parameter ENABLE_PADDING = 1, parameter ENABLE_DIC = 1, parameter MIN_FRAME_LENGTH = 64, @@ -2396,6 +2398,8 @@ fpga_core #( .TX_CHECKSUM_ENABLE(TX_CHECKSUM_ENABLE), .RX_HASH_ENABLE(RX_HASH_ENABLE), .RX_CHECKSUM_ENABLE(RX_CHECKSUM_ENABLE), + .PFC_ENABLE(PFC_ENABLE), + .LFC_ENABLE(LFC_ENABLE), .ENABLE_PADDING(ENABLE_PADDING), .ENABLE_DIC(ENABLE_DIC), .MIN_FRAME_LENGTH(MIN_FRAME_LENGTH), diff --git a/fpga/mqnic/fb4CGg3/fpga_25g/rtl/fpga_core.v b/fpga/mqnic/fb4CGg3/fpga_25g/rtl/fpga_core.v index 27a013350..f07eee4ea 100644 --- a/fpga/mqnic/fb4CGg3/fpga_25g/rtl/fpga_core.v +++ b/fpga/mqnic/fb4CGg3/fpga_25g/rtl/fpga_core.v @@ -81,6 +81,8 @@ module fpga_core # parameter TX_CHECKSUM_ENABLE = 1, parameter RX_HASH_ENABLE = 1, parameter RX_CHECKSUM_ENABLE = 1, + parameter PFC_ENABLE = 1, + parameter LFC_ENABLE = PFC_ENABLE, parameter ENABLE_PADDING = 1, parameter ENABLE_DIC = 1, parameter MIN_FRAME_LENGTH = 64, @@ -1302,7 +1304,12 @@ wire [PORT_COUNT*TX_TAG_WIDTH-1:0] axis_eth_tx_ptp_ts_tag; wire [PORT_COUNT-1:0] axis_eth_tx_ptp_ts_valid; wire [PORT_COUNT-1:0] axis_eth_tx_ptp_ts_ready; +wire [PORT_COUNT-1:0] eth_tx_enable; wire [PORT_COUNT-1:0] eth_tx_status; +wire [PORT_COUNT-1:0] eth_tx_lfc_en; +wire [PORT_COUNT-1:0] eth_tx_lfc_req; +wire [PORT_COUNT*8-1:0] eth_tx_pfc_en; +wire [PORT_COUNT*8-1:0] eth_tx_pfc_req; wire [PORT_COUNT-1:0] eth_rx_clk; wire [PORT_COUNT-1:0] eth_rx_rst; @@ -1317,7 +1324,14 @@ wire [PORT_COUNT-1:0] axis_eth_rx_tready; wire [PORT_COUNT-1:0] axis_eth_rx_tlast; wire [PORT_COUNT*AXIS_ETH_RX_USER_WIDTH-1:0] axis_eth_rx_tuser; +wire [PORT_COUNT-1:0] eth_rx_enable; wire [PORT_COUNT-1:0] eth_rx_status; +wire [PORT_COUNT-1:0] eth_rx_lfc_en; +wire [PORT_COUNT-1:0] eth_rx_lfc_req; +wire [PORT_COUNT-1:0] eth_rx_lfc_ack; +wire [PORT_COUNT*8-1:0] eth_rx_pfc_en; +wire [PORT_COUNT*8-1:0] eth_rx_pfc_req; +wire [PORT_COUNT*8-1:0] eth_rx_pfc_ack; wire [PORT_COUNT-1:0] port_xgmii_tx_clk; wire [PORT_COUNT-1:0] port_xgmii_tx_rst; @@ -1390,12 +1404,15 @@ generate .PTP_PERIOD_FNS(IF_PTP_PERIOD_FNS), .TX_PTP_TS_ENABLE(PTP_TS_ENABLE), .TX_PTP_TS_WIDTH(PTP_TS_WIDTH), + .TX_PTP_TS_CTRL_IN_TUSER(0), .TX_PTP_TAG_ENABLE(PTP_TS_ENABLE), .TX_PTP_TAG_WIDTH(TX_TAG_WIDTH), .RX_PTP_TS_ENABLE(PTP_TS_ENABLE), .RX_PTP_TS_WIDTH(PTP_TS_WIDTH), .TX_USER_WIDTH(AXIS_ETH_TX_USER_WIDTH), - .RX_USER_WIDTH(AXIS_ETH_RX_USER_WIDTH) + .RX_USER_WIDTH(AXIS_ETH_RX_USER_WIDTH), + .PFC_ENABLE(PFC_ENABLE), + .PAUSE_ENABLE(LFC_ENABLE) ) eth_mac_inst ( .tx_clk(port_xgmii_tx_clk[n]), @@ -1403,6 +1420,9 @@ generate .rx_clk(port_xgmii_rx_clk[n]), .rx_rst(port_xgmii_rx_rst[n]), + /* + * AXI input + */ .tx_axis_tdata(axis_eth_tx_tdata[n*AXIS_ETH_DATA_WIDTH +: AXIS_ETH_DATA_WIDTH]), .tx_axis_tkeep(axis_eth_tx_tkeep[n*AXIS_ETH_KEEP_WIDTH +: AXIS_ETH_KEEP_WIDTH]), .tx_axis_tvalid(axis_eth_tx_tvalid[n +: 1]), @@ -1410,30 +1430,121 @@ generate .tx_axis_tlast(axis_eth_tx_tlast[n +: 1]), .tx_axis_tuser(axis_eth_tx_tuser[n*AXIS_ETH_TX_USER_WIDTH +: AXIS_ETH_TX_USER_WIDTH]), + /* + * AXI output + */ .rx_axis_tdata(axis_eth_rx_tdata[n*AXIS_ETH_DATA_WIDTH +: AXIS_ETH_DATA_WIDTH]), .rx_axis_tkeep(axis_eth_rx_tkeep[n*AXIS_ETH_KEEP_WIDTH +: AXIS_ETH_KEEP_WIDTH]), .rx_axis_tvalid(axis_eth_rx_tvalid[n +: 1]), .rx_axis_tlast(axis_eth_rx_tlast[n +: 1]), .rx_axis_tuser(axis_eth_rx_tuser[n*AXIS_ETH_RX_USER_WIDTH +: AXIS_ETH_RX_USER_WIDTH]), + /* + * XGMII interface + */ .xgmii_rxd(port_xgmii_rxd[n*XGMII_DATA_WIDTH +: XGMII_DATA_WIDTH]), .xgmii_rxc(port_xgmii_rxc[n*XGMII_CTRL_WIDTH +: XGMII_CTRL_WIDTH]), .xgmii_txd(port_xgmii_txd[n*XGMII_DATA_WIDTH +: XGMII_DATA_WIDTH]), .xgmii_txc(port_xgmii_txc[n*XGMII_CTRL_WIDTH +: XGMII_CTRL_WIDTH]), + /* + * PTP + */ .tx_ptp_ts(eth_tx_ptp_ts_96[n*PTP_TS_WIDTH +: PTP_TS_WIDTH]), .rx_ptp_ts(eth_rx_ptp_ts_96[n*PTP_TS_WIDTH +: PTP_TS_WIDTH]), .tx_axis_ptp_ts(axis_eth_tx_ptp_ts[n*PTP_TS_WIDTH +: PTP_TS_WIDTH]), .tx_axis_ptp_ts_tag(axis_eth_tx_ptp_ts_tag[n*TX_TAG_WIDTH +: TX_TAG_WIDTH]), .tx_axis_ptp_ts_valid(axis_eth_tx_ptp_ts_valid[n +: 1]), + /* + * Link-level Flow Control (LFC) (IEEE 802.3 annex 31B PAUSE) + */ + .tx_lfc_req(eth_tx_lfc_req[n +: 1]), + .tx_lfc_resend(1'b0), + .rx_lfc_en(eth_rx_lfc_en[n +: 1]), + .rx_lfc_req(eth_rx_lfc_req[n +: 1]), + .rx_lfc_ack(eth_rx_lfc_ack[n +: 1]), + + /* + * Priority Flow Control (PFC) (IEEE 802.3 annex 31D PFC) + */ + .tx_pfc_req(eth_tx_pfc_req[n*8 +: 8]), + .tx_pfc_resend(1'b0), + .rx_pfc_en(eth_rx_pfc_en[n*8 +: 8]), + .rx_pfc_req(eth_rx_pfc_req[n*8 +: 8]), + .rx_pfc_ack(eth_rx_pfc_ack[n*8 +: 8]), + + /* + * Pause interface + */ + .tx_lfc_pause_en(1'b1), + .tx_pause_req(1'b0), + .tx_pause_ack(), + + /* + * Status + */ + .tx_start_packet(), .tx_error_underflow(), + .rx_start_packet(), .rx_error_bad_frame(), .rx_error_bad_fcs(), + .stat_tx_mcf(), + .stat_rx_mcf(), + .stat_tx_lfc_pkt(), + .stat_tx_lfc_xon(), + .stat_tx_lfc_xoff(), + .stat_tx_lfc_paused(), + .stat_tx_pfc_pkt(), + .stat_tx_pfc_xon(), + .stat_tx_pfc_xoff(), + .stat_tx_pfc_paused(), + .stat_rx_lfc_pkt(), + .stat_rx_lfc_xon(), + .stat_rx_lfc_xoff(), + .stat_rx_lfc_paused(), + .stat_rx_pfc_pkt(), + .stat_rx_pfc_xon(), + .stat_rx_pfc_xoff(), + .stat_rx_pfc_paused(), + /* + * Configuration + */ .cfg_ifg(8'd12), - .cfg_tx_enable(1'b1), - .cfg_rx_enable(1'b1) + .cfg_tx_enable(eth_tx_enable[n +: 1]), + .cfg_rx_enable(eth_rx_enable[n +: 1]), + .cfg_mcf_rx_eth_dst_mcast(48'h01_80_C2_00_00_01), + .cfg_mcf_rx_check_eth_dst_mcast(1'b1), + .cfg_mcf_rx_eth_dst_ucast(48'd0), + .cfg_mcf_rx_check_eth_dst_ucast(1'b0), + .cfg_mcf_rx_eth_src(48'd0), + .cfg_mcf_rx_check_eth_src(1'b0), + .cfg_mcf_rx_eth_type(16'h8808), + .cfg_mcf_rx_opcode_lfc(16'h0001), + .cfg_mcf_rx_check_opcode_lfc(eth_rx_lfc_en[n +: 1]), + .cfg_mcf_rx_opcode_pfc(16'h0101), + .cfg_mcf_rx_check_opcode_pfc(eth_rx_pfc_en[n*8 +: 8] != 0), + .cfg_mcf_rx_forward(1'b0), + .cfg_mcf_rx_enable(eth_rx_lfc_en[n +: 1] || eth_rx_pfc_en[n*8 +: 8]), + .cfg_tx_lfc_eth_dst(48'h01_80_C2_00_00_01), + .cfg_tx_lfc_eth_src(48'h80_23_31_43_54_4C), + .cfg_tx_lfc_eth_type(16'h8808), + .cfg_tx_lfc_opcode(16'h0001), + .cfg_tx_lfc_en(eth_tx_lfc_en[n +: 1]), + .cfg_tx_lfc_quanta(16'hffff), + .cfg_tx_lfc_refresh(16'h7fff), + .cfg_tx_pfc_eth_dst(48'h01_80_C2_00_00_01), + .cfg_tx_pfc_eth_src(48'h80_23_31_43_54_4C), + .cfg_tx_pfc_eth_type(16'h8808), + .cfg_tx_pfc_opcode(16'h0101), + .cfg_tx_pfc_en(eth_tx_pfc_en[n*8 +: 8] != 0), + .cfg_tx_pfc_quanta({8{16'hffff}}), + .cfg_tx_pfc_refresh({8{16'h7fff}}), + .cfg_rx_lfc_opcode(16'h0001), + .cfg_rx_lfc_en(eth_rx_lfc_en[n +: 1]), + .cfg_rx_pfc_opcode(16'h0101), + .cfg_rx_pfc_en(eth_rx_pfc_en[n*8 +: 8] != 0) ); end @@ -1507,6 +1618,9 @@ mqnic_core_pcie_us #( .TX_CHECKSUM_ENABLE(TX_CHECKSUM_ENABLE), .RX_HASH_ENABLE(RX_HASH_ENABLE), .RX_CHECKSUM_ENABLE(RX_CHECKSUM_ENABLE), + .PFC_ENABLE(PFC_ENABLE), + .LFC_ENABLE(LFC_ENABLE), + .MAC_CTRL_ENABLE(0), .TX_FIFO_DEPTH(TX_FIFO_DEPTH), .RX_FIFO_DEPTH(RX_FIFO_DEPTH), .MAX_TX_SIZE(MAX_TX_SIZE), @@ -1788,7 +1902,13 @@ core_inst ( .s_axis_eth_tx_cpl_valid(axis_eth_tx_ptp_ts_valid), .s_axis_eth_tx_cpl_ready(axis_eth_tx_ptp_ts_ready), + .eth_tx_enable(eth_tx_enable), .eth_tx_status(eth_tx_status), + .eth_tx_lfc_en(eth_tx_lfc_en), + .eth_tx_lfc_req(eth_tx_lfc_req), + .eth_tx_pfc_en(eth_tx_pfc_en), + .eth_tx_pfc_req(eth_tx_pfc_req), + .eth_tx_fc_quanta_clk_en(0), .eth_rx_clk(eth_rx_clk), .eth_rx_rst(eth_rx_rst), @@ -1805,7 +1925,15 @@ core_inst ( .s_axis_eth_rx_tlast(axis_eth_rx_tlast), .s_axis_eth_rx_tuser(axis_eth_rx_tuser), + .eth_rx_enable(eth_rx_enable), .eth_rx_status(eth_rx_status), + .eth_rx_lfc_en(eth_rx_lfc_en), + .eth_rx_lfc_req(eth_rx_lfc_req), + .eth_rx_lfc_ack(eth_rx_lfc_ack), + .eth_rx_pfc_en(eth_rx_pfc_en), + .eth_rx_pfc_req(eth_rx_pfc_req), + .eth_rx_pfc_ack(eth_rx_pfc_ack), + .eth_rx_fc_quanta_clk_en(0), /* * DDR diff --git a/fpga/mqnic/fb4CGg3/fpga_25g/tb/fpga_core/Makefile b/fpga/mqnic/fb4CGg3/fpga_25g/tb/fpga_core/Makefile index 41e0256b7..2a53e518c 100644 --- a/fpga/mqnic/fb4CGg3/fpga_25g/tb/fpga_core/Makefile +++ b/fpga/mqnic/fb4CGg3/fpga_25g/tb/fpga_core/Makefile @@ -63,6 +63,10 @@ VERILOG_SOURCES += ../../rtl/common/tdma_ber_ch.v VERILOG_SOURCES += ../../lib/eth/rtl/eth_mac_10g.v VERILOG_SOURCES += ../../lib/eth/rtl/axis_xgmii_rx_64.v VERILOG_SOURCES += ../../lib/eth/rtl/axis_xgmii_tx_64.v +VERILOG_SOURCES += ../../lib/eth/rtl/mac_ctrl_rx.v +VERILOG_SOURCES += ../../lib/eth/rtl/mac_ctrl_tx.v +VERILOG_SOURCES += ../../lib/eth/rtl/mac_pause_ctrl_rx.v +VERILOG_SOURCES += ../../lib/eth/rtl/mac_pause_ctrl_tx.v VERILOG_SOURCES += ../../lib/eth/rtl/lfsr.v VERILOG_SOURCES += ../../lib/eth/rtl/ptp_clock.v VERILOG_SOURCES += ../../lib/eth/rtl/ptp_clock_cdc.v @@ -168,6 +172,8 @@ export PARAM_TX_CPL_FIFO_DEPTH := 32 export PARAM_TX_CHECKSUM_ENABLE := 1 export PARAM_RX_HASH_ENABLE := 1 export PARAM_RX_CHECKSUM_ENABLE := 1 +export PARAM_LFC_ENABLE := 1 +export PARAM_PFC_ENABLE := $(PARAM_LFC_ENABLE) export PARAM_TX_FIFO_DEPTH := 32768 export PARAM_RX_FIFO_DEPTH := 32768 export PARAM_MAX_TX_SIZE := 9214 diff --git a/fpga/mqnic/fb4CGg3/fpga_25g/tb/fpga_core/test_fpga_core.py b/fpga/mqnic/fb4CGg3/fpga_25g/tb/fpga_core/test_fpga_core.py index 7b92873f3..41d278092 100644 --- a/fpga/mqnic/fb4CGg3/fpga_25g/tb/fpga_core/test_fpga_core.py +++ b/fpga/mqnic/fb4CGg3/fpga_25g/tb/fpga_core/test_fpga_core.py @@ -3,6 +3,7 @@ import logging import os +import struct import sys import scapy.utils @@ -17,7 +18,7 @@ from cocotb.clock import Clock from cocotb.triggers import RisingEdge, FallingEdge, Timer from cocotbext.axi import AxiStreamBus -from cocotbext.eth import XgmiiSource, XgmiiSink +from cocotbext.eth import XgmiiSource, XgmiiSink, XgmiiFrame from cocotbext.pcie.core import RootComplex from cocotbext.pcie.xilinx.us import UltraScalePlusPcieDevice @@ -525,6 +526,35 @@ async def run_test_nic(dut): tb.loopback_enable = False + if tb.driver.interfaces[0].if_feature_lfc: + tb.log.info("Test LFC pause frame RX") + + await tb.driver.interfaces[0].ports[0].set_lfc_ctrl(mqnic.MQNIC_PORT_LFC_CTRL_TX_LFC_EN | mqnic.MQNIC_PORT_LFC_CTRL_RX_LFC_EN) + await tb.driver.hw_regs.read_dword(0) + + lfc_xoff = Ether(src='DA:D1:D2:D3:D4:D5', dst='01:80:C2:00:00:01', type=0x8808) / struct.pack('!HH', 0x0001, 2000) + + await tb.qsfp_source[0][0].send(XgmiiFrame.from_payload(bytes(lfc_xoff))) + + count = 16 + + pkts = [bytearray([(x+k) % 256 for x in range(1514)]) for k in range(count)] + + tb.loopback_enable = True + + for p in pkts: + await tb.driver.interfaces[0].start_xmit(p, 0) + + for k in range(count): + pkt = await tb.driver.interfaces[0].recv() + + tb.log.info("Packet: %s", pkt) + assert pkt.data == pkts[k] + if tb.driver.interfaces[0].if_feature_rx_csum: + assert pkt.rx_checksum == ~scapy.utils.checksum(bytes(pkt.data[14:])) & 0xffff + + tb.loopback_enable = False + await RisingEdge(dut.clk_250mhz) await RisingEdge(dut.clk_250mhz) @@ -598,6 +628,10 @@ def test_fpga_core(request): os.path.join(eth_rtl_dir, "eth_mac_10g.v"), os.path.join(eth_rtl_dir, "axis_xgmii_rx_64.v"), os.path.join(eth_rtl_dir, "axis_xgmii_tx_64.v"), + os.path.join(eth_rtl_dir, "mac_ctrl_rx.v"), + os.path.join(eth_rtl_dir, "mac_ctrl_tx.v"), + os.path.join(eth_rtl_dir, "mac_pause_ctrl_rx.v"), + os.path.join(eth_rtl_dir, "mac_pause_ctrl_tx.v"), os.path.join(eth_rtl_dir, "lfsr.v"), os.path.join(eth_rtl_dir, "ptp_clock.v"), os.path.join(eth_rtl_dir, "ptp_clock_cdc.v"), @@ -704,6 +738,8 @@ def test_fpga_core(request): parameters['TX_CHECKSUM_ENABLE'] = 1 parameters['RX_HASH_ENABLE'] = 1 parameters['RX_CHECKSUM_ENABLE'] = 1 + parameters['LFC_ENABLE'] = 1 + parameters['PFC_ENABLE'] = parameters['LFC_ENABLE'] parameters['TX_FIFO_DEPTH'] = 32768 parameters['RX_FIFO_DEPTH'] = 32768 parameters['MAX_TX_SIZE'] = 9214 diff --git a/lib/mqnic/mqnic.h b/lib/mqnic/mqnic.h index 8a0d08dda..b5d21f7a4 100644 --- a/lib/mqnic/mqnic.h +++ b/lib/mqnic/mqnic.h @@ -184,8 +184,11 @@ uint32_t mqnic_interface_get_rx_queue_map_indir_table(struct mqnic_if *interface // mqnic_port.c struct mqnic_port *mqnic_port_open(struct mqnic_if *interface, int index, struct mqnic_reg_block *port_rb); void mqnic_port_close(struct mqnic_port *port); -uint32_t mqnic_port_get_tx_status(struct mqnic_port *port); -uint32_t mqnic_port_get_rx_status(struct mqnic_port *port); +uint32_t mqnic_port_get_tx_ctrl(struct mqnic_port *port); +uint32_t mqnic_port_get_rx_ctrl(struct mqnic_port *port); +uint32_t mqnic_port_get_fc_ctrl(struct mqnic_port *port); +uint32_t mqnic_port_get_lfc_ctrl(struct mqnic_port *port); +uint32_t mqnic_port_get_pfc_ctrl(struct mqnic_port *port, int index); // mqnic_sched_block.c struct mqnic_sched_block *mqnic_sched_block_open(struct mqnic_if *interface, int index, struct mqnic_reg_block *block_rb); diff --git a/lib/mqnic/mqnic_port.c b/lib/mqnic/mqnic_port.c index 80cfaaed5..7722ef23d 100644 --- a/lib/mqnic/mqnic_port.c +++ b/lib/mqnic/mqnic_port.c @@ -57,12 +57,27 @@ void mqnic_port_close(struct mqnic_port *port) free(port); } -uint32_t mqnic_port_get_tx_status(struct mqnic_port *port) +uint32_t mqnic_port_get_tx_ctrl(struct mqnic_port *port) { - return mqnic_reg_read32(port->port_ctrl_rb->regs, MQNIC_RB_PORT_CTRL_REG_TX_STATUS); + return mqnic_reg_read32(port->port_ctrl_rb->regs, MQNIC_RB_PORT_CTRL_REG_TX_CTRL); } -uint32_t mqnic_port_get_rx_status(struct mqnic_port *port) +uint32_t mqnic_port_get_rx_ctrl(struct mqnic_port *port) { - return mqnic_reg_read32(port->port_ctrl_rb->regs, MQNIC_RB_PORT_CTRL_REG_RX_STATUS); + return mqnic_reg_read32(port->port_ctrl_rb->regs, MQNIC_RB_PORT_CTRL_REG_RX_CTRL); +} + +uint32_t mqnic_port_get_fc_ctrl(struct mqnic_port *port) +{ + return mqnic_reg_read32(port->port_ctrl_rb->regs, MQNIC_RB_PORT_CTRL_REG_FC_CTRL); +} + +uint32_t mqnic_port_get_lfc_ctrl(struct mqnic_port *port) +{ + return mqnic_reg_read32(port->port_ctrl_rb->regs, MQNIC_RB_PORT_CTRL_REG_LFC_CTRL); +} + +uint32_t mqnic_port_get_pfc_ctrl(struct mqnic_port *port, int index) +{ + return mqnic_reg_read32(port->port_ctrl_rb->regs, MQNIC_RB_PORT_CTRL_REG_PFC_CTRL0 + index*4); } diff --git a/modules/mqnic/mqnic.h b/modules/mqnic/mqnic.h index 65074c8a2..faba4c708 100644 --- a/modules/mqnic/mqnic.h +++ b/modules/mqnic/mqnic.h @@ -502,8 +502,16 @@ void mqnic_interface_set_rx_queue_map_indir_table(struct mqnic_if *interface, in struct mqnic_port *mqnic_create_port(struct mqnic_if *interface, int index, struct mqnic_reg_block *port_rb); void mqnic_destroy_port(struct mqnic_port *port); -u32 mqnic_port_get_tx_status(struct mqnic_port *port); -u32 mqnic_port_get_rx_status(struct mqnic_port *port); +u32 mqnic_port_get_tx_ctrl(struct mqnic_port *port); +void mqnic_port_set_tx_ctrl(struct mqnic_port *port, u32 val); +u32 mqnic_port_get_rx_ctrl(struct mqnic_port *port); +void mqnic_port_set_rx_ctrl(struct mqnic_port *port, u32 val); +u32 mqnic_port_get_fc_ctrl(struct mqnic_port *port); +void mqnic_port_set_fc_ctrl(struct mqnic_port *port, u32 val); +u32 mqnic_port_get_lfc_ctrl(struct mqnic_port *port); +void mqnic_port_set_lfc_ctrl(struct mqnic_port *port, u32 val); +u32 mqnic_port_get_pfc_ctrl(struct mqnic_port *port, int index); +void mqnic_port_set_pfc_ctrl(struct mqnic_port *port, int index, u32 val); // mqnic_netdev.c int mqnic_start_port(struct net_device *ndev); diff --git a/modules/mqnic/mqnic_ethtool.c b/modules/mqnic/mqnic_ethtool.c index 8bffb9347..613e1af64 100644 --- a/modules/mqnic/mqnic_ethtool.c +++ b/modules/mqnic/mqnic_ethtool.c @@ -130,6 +130,54 @@ static int mqnic_set_ringparam(struct net_device *ndev, return ret; } +static void mqnic_get_pauseparam(struct net_device *ndev, + struct ethtool_pauseparam *param) +{ + struct mqnic_priv *priv = netdev_priv(ndev); + u32 val; + + param->autoneg = 0; + param->rx_pause = 0; + param->tx_pause = 0; + + if (!(priv->if_features & MQNIC_IF_FEATURE_LFC)) + return; + + val = mqnic_port_get_lfc_ctrl(priv->port[0]); + + param->rx_pause = !!(val & MQNIC_PORT_LFC_CTRL_RX_LFC_EN); + param->tx_pause = !!(val & MQNIC_PORT_LFC_CTRL_TX_LFC_EN); +} + +static int mqnic_set_pauseparam(struct net_device *ndev, + struct ethtool_pauseparam *param) +{ + struct mqnic_priv *priv = netdev_priv(ndev); + u32 val; + + if (!(priv->if_features & MQNIC_IF_FEATURE_LFC)) + return -EOPNOTSUPP; + + if (param->autoneg) + return -EINVAL; + + val = mqnic_port_get_lfc_ctrl(priv->port[0]); + + if (param->rx_pause) + val |= MQNIC_PORT_LFC_CTRL_RX_LFC_EN; + else + val &= ~MQNIC_PORT_LFC_CTRL_RX_LFC_EN; + + if (param->tx_pause) + val |= MQNIC_PORT_LFC_CTRL_TX_LFC_EN; + else + val &= ~MQNIC_PORT_LFC_CTRL_TX_LFC_EN; + + mqnic_port_set_lfc_ctrl(priv->port[0], val); + + return 0; +} + static int mqnic_get_rxnfc(struct net_device *ndev, struct ethtool_rxnfc *rxnfc, u32 *rule_locs) { @@ -560,6 +608,8 @@ const struct ethtool_ops mqnic_ethtool_ops = { .get_link = ethtool_op_get_link, .get_ringparam = mqnic_get_ringparam, .set_ringparam = mqnic_set_ringparam, + .get_pauseparam = mqnic_get_pauseparam, + .set_pauseparam = mqnic_set_pauseparam, .get_rxnfc = mqnic_get_rxnfc, .get_rxfh_indir_size = mqnic_get_rxfh_indir_size, .get_rxfh = mqnic_get_rxfh, diff --git a/modules/mqnic/mqnic_hw.h b/modules/mqnic/mqnic_hw.h index ea8a0477d..669856d7d 100644 --- a/modules/mqnic/mqnic_hw.h +++ b/modules/mqnic/mqnic_hw.h @@ -187,6 +187,8 @@ #define MQNIC_IF_FEATURE_TX_CSUM (1 << 8) #define MQNIC_IF_FEATURE_RX_CSUM (1 << 9) #define MQNIC_IF_FEATURE_RX_HASH (1 << 10) +#define MQNIC_IF_FEATURE_LFC (1 << 11) +#define MQNIC_IF_FEATURE_PFC (1 << 12) #define MQNIC_RB_RX_QUEUE_MAP_TYPE 0x0000C090 #define MQNIC_RB_RX_QUEUE_MAP_VER 0x00000200 @@ -226,10 +228,48 @@ #define MQNIC_RB_PORT_REG_OFFSET 0x0C #define MQNIC_RB_PORT_CTRL_TYPE 0x0000C003 -#define MQNIC_RB_PORT_CTRL_VER 0x00000200 +#define MQNIC_RB_PORT_CTRL_VER 0x00000300 #define MQNIC_RB_PORT_CTRL_REG_FEATURES 0x0C -#define MQNIC_RB_PORT_CTRL_REG_TX_STATUS 0x10 -#define MQNIC_RB_PORT_CTRL_REG_RX_STATUS 0x14 +#define MQNIC_RB_PORT_CTRL_REG_TX_CTRL 0x10 +#define MQNIC_RB_PORT_CTRL_REG_RX_CTRL 0x14 +#define MQNIC_RB_PORT_CTRL_REG_FC_CTRL 0x18 +#define MQNIC_RB_PORT_CTRL_REG_LFC_CTRL 0x1C +#define MQNIC_RB_PORT_CTRL_REG_PFC_CTRL0 0x20 +#define MQNIC_RB_PORT_CTRL_REG_PFC_CTRL1 0x24 +#define MQNIC_RB_PORT_CTRL_REG_PFC_CTRL2 0x28 +#define MQNIC_RB_PORT_CTRL_REG_PFC_CTRL3 0x2C +#define MQNIC_RB_PORT_CTRL_REG_PFC_CTRL4 0x30 +#define MQNIC_RB_PORT_CTRL_REG_PFC_CTRL5 0x34 +#define MQNIC_RB_PORT_CTRL_REG_PFC_CTRL6 0x38 +#define MQNIC_RB_PORT_CTRL_REG_PFC_CTRL7 0x3C + +#define MQNIC_PORT_FEATURE_LFC (1 << 0) +#define MQNIC_PORT_FEATURE_PFC (1 << 1) +#define MQNIC_PORT_FEATURE_INT_MAC_CTRL (1 << 2) + +#define MQNIC_PORT_TX_CTRL_EN (1 << 0) +#define MQNIC_PORT_TX_CTRL_PAUSE (1 << 8) +#define MQNIC_PORT_TX_CTRL_STATUS (1 << 16) +#define MQNIC_PORT_TX_CTRL_RESET (1 << 17) +#define MQNIC_PORT_TX_CTRL_PAUSE_REQ (1 << 24) +#define MQNIC_PORT_TX_CTRL_PAUSE_ACK (1 << 25) + +#define MQNIC_PORT_RX_CTRL_EN (1 << 0) +#define MQNIC_PORT_RX_CTRL_PAUSE (1 << 8) +#define MQNIC_PORT_RX_CTRL_STATUS (1 << 16) +#define MQNIC_PORT_RX_CTRL_RESET (1 << 17) +#define MQNIC_PORT_RX_CTRL_PAUSE_REQ (1 << 24) +#define MQNIC_PORT_RX_CTRL_PAUSE_ACK (1 << 25) + +#define MQNIC_PORT_LFC_CTRL_TX_LFC_EN (1 << 24) +#define MQNIC_PORT_LFC_CTRL_RX_LFC_EN (1 << 25) +#define MQNIC_PORT_LFC_CTRL_TX_LFC_REQ (1 << 28) +#define MQNIC_PORT_LFC_CTRL_RX_LFC_REQ (1 << 29) + +#define MQNIC_PORT_PFC_CTRL_TX_PFC_EN (1 << 24) +#define MQNIC_PORT_PFC_CTRL_RX_PFC_EN (1 << 25) +#define MQNIC_PORT_PFC_CTRL_TX_PFC_REQ (1 << 28) +#define MQNIC_PORT_PFC_CTRL_RX_PFC_REQ (1 << 29) #define MQNIC_RB_SCHED_BLOCK_TYPE 0x0000C004 #define MQNIC_RB_SCHED_BLOCK_VER 0x00000300 diff --git a/modules/mqnic/mqnic_netdev.c b/modules/mqnic/mqnic_netdev.c index 7177203a1..06972c4c4 100644 --- a/modules/mqnic/mqnic_netdev.c +++ b/modules/mqnic/mqnic_netdev.c @@ -162,6 +162,9 @@ int mqnic_start_port(struct net_device *ndev) // enable first scheduler mqnic_activate_sched_block(priv->sched_block[0]); + // enable first port + mqnic_port_set_tx_ctrl(priv->port[0], MQNIC_PORT_TX_CTRL_EN); + netif_tx_start_all_queues(ndev); netif_device_attach(ndev); @@ -173,6 +176,8 @@ int mqnic_start_port(struct net_device *ndev) netif_carrier_on(ndev); } + mqnic_port_set_rx_ctrl(priv->port[0], MQNIC_PORT_RX_CTRL_EN); + return 0; fail: @@ -194,6 +199,8 @@ void mqnic_stop_port(struct net_device *ndev) if (mqnic_link_status_poll) del_timer_sync(&priv->link_status_timer); + mqnic_port_set_rx_ctrl(priv->port[0], 0); + netif_tx_lock_bh(ndev); // if (detach) // netif_device_detach(ndev); @@ -230,6 +237,8 @@ void mqnic_stop_port(struct net_device *ndev) msleep(20); + mqnic_port_set_tx_ctrl(priv->port[0], 0); + priv->port_up = false; // shut down NAPI and clean queues @@ -494,9 +503,9 @@ static void mqnic_link_status_timeout(struct timer_list *timer) // "combine" all TX/RX status signals of all ports of this netdev for (k = 0, up = 0; k < priv->port_count; k++) { - if (!(mqnic_port_get_tx_status(priv->port[k]) & 0x1)) + if (!(mqnic_port_get_tx_ctrl(priv->port[k]) & MQNIC_PORT_TX_CTRL_STATUS)) continue; - if (!(mqnic_port_get_rx_status(priv->port[k]) & 0x1)) + if (!(mqnic_port_get_rx_ctrl(priv->port[k]) & MQNIC_PORT_RX_CTRL_STATUS)) continue; up++; diff --git a/modules/mqnic/mqnic_port.c b/modules/mqnic/mqnic_port.c index a43c32b2e..fe13f14b0 100644 --- a/modules/mqnic/mqnic_port.c +++ b/modules/mqnic/mqnic_port.c @@ -13,6 +13,7 @@ struct mqnic_port *mqnic_create_port(struct mqnic_if *interface, int index, struct mqnic_reg_block *rb; u32 offset; int ret = 0; + int k; port = kzalloc(sizeof(*port), GFP_KERNEL); if (!port) @@ -52,8 +53,15 @@ struct mqnic_port *mqnic_create_port(struct mqnic_if *interface, int index, dev_info(dev, "Port features: 0x%08x", port->port_features); - dev_info(dev, "Port TX status: 0x%08x", mqnic_port_get_tx_status(port)); - dev_info(dev, "Port RX status: 0x%08x", mqnic_port_get_rx_status(port)); + mqnic_port_set_tx_ctrl(port, 0); + mqnic_port_set_rx_ctrl(port, 0); + mqnic_port_set_lfc_ctrl(port, 0); + + for (k = 0; k < 8; k++) + mqnic_port_set_pfc_ctrl(port, k, 0); + + dev_info(dev, "Port RX ctrl: 0x%08x", mqnic_port_get_rx_ctrl(port)); + dev_info(dev, "Port TX ctrl: 0x%08x", mqnic_port_get_tx_ctrl(port)); return port; @@ -70,14 +78,62 @@ void mqnic_destroy_port(struct mqnic_port *port) kfree(port); } -u32 mqnic_port_get_tx_status(struct mqnic_port *port) +u32 mqnic_port_get_tx_ctrl(struct mqnic_port *port) { - return ioread32(port->port_ctrl_rb->regs + MQNIC_RB_PORT_CTRL_REG_TX_STATUS); + return ioread32(port->port_ctrl_rb->regs + MQNIC_RB_PORT_CTRL_REG_TX_CTRL); } -EXPORT_SYMBOL(mqnic_port_get_tx_status); +EXPORT_SYMBOL(mqnic_port_get_tx_ctrl); -u32 mqnic_port_get_rx_status(struct mqnic_port *port) +void mqnic_port_set_tx_ctrl(struct mqnic_port *port, u32 val) { - return ioread32(port->port_ctrl_rb->regs + MQNIC_RB_PORT_CTRL_REG_RX_STATUS); + iowrite32(val, port->port_ctrl_rb->regs + MQNIC_RB_PORT_CTRL_REG_TX_CTRL); } -EXPORT_SYMBOL(mqnic_port_get_rx_status); +EXPORT_SYMBOL(mqnic_port_set_tx_ctrl); + +u32 mqnic_port_get_rx_ctrl(struct mqnic_port *port) +{ + return ioread32(port->port_ctrl_rb->regs + MQNIC_RB_PORT_CTRL_REG_RX_CTRL); +} +EXPORT_SYMBOL(mqnic_port_get_rx_ctrl); + +void mqnic_port_set_rx_ctrl(struct mqnic_port *port, u32 val) +{ + iowrite32(val, port->port_ctrl_rb->regs + MQNIC_RB_PORT_CTRL_REG_RX_CTRL); +} +EXPORT_SYMBOL(mqnic_port_set_rx_ctrl); + +u32 mqnic_port_get_fc_ctrl(struct mqnic_port *port) +{ + return ioread32(port->port_ctrl_rb->regs + MQNIC_RB_PORT_CTRL_REG_FC_CTRL); +} +EXPORT_SYMBOL(mqnic_port_get_fc_ctrl); + +void mqnic_port_set_fc_ctrl(struct mqnic_port *port, u32 val) +{ + iowrite32(val, port->port_ctrl_rb->regs + MQNIC_RB_PORT_CTRL_REG_FC_CTRL); +} +EXPORT_SYMBOL(mqnic_port_set_fc_ctrl); + +u32 mqnic_port_get_lfc_ctrl(struct mqnic_port *port) +{ + return ioread32(port->port_ctrl_rb->regs + MQNIC_RB_PORT_CTRL_REG_LFC_CTRL); +} +EXPORT_SYMBOL(mqnic_port_get_lfc_ctrl); + +void mqnic_port_set_lfc_ctrl(struct mqnic_port *port, u32 val) +{ + iowrite32(val, port->port_ctrl_rb->regs + MQNIC_RB_PORT_CTRL_REG_LFC_CTRL); +} +EXPORT_SYMBOL(mqnic_port_set_lfc_ctrl); + +u32 mqnic_port_get_pfc_ctrl(struct mqnic_port *port, int index) +{ + return ioread32(port->port_ctrl_rb->regs + MQNIC_RB_PORT_CTRL_REG_PFC_CTRL0 + index*4); +} +EXPORT_SYMBOL(mqnic_port_get_pfc_ctrl); + +void mqnic_port_set_pfc_ctrl(struct mqnic_port *port, int index, u32 val) +{ + iowrite32(val, port->port_ctrl_rb->regs + MQNIC_RB_PORT_CTRL_REG_PFC_CTRL0 + index*4); +} +EXPORT_SYMBOL(mqnic_port_set_pfc_ctrl); diff --git a/utils/mqnic-dump.c b/utils/mqnic-dump.c index 6078417da..6a9d0721c 100644 --- a/utils/mqnic-dump.c +++ b/utils/mqnic-dump.c @@ -281,8 +281,12 @@ int main(int argc, char *argv[]) (rb->version >> 16) & 0xff, (rb->version >> 8) & 0xff, rb->version & 0xff); printf("Port features: 0x%08x\n", dev_port->port_features); - printf("Port TX status: 0x%08x\n", mqnic_port_get_tx_status(dev_port)); - printf("Port RX status: 0x%08x\n", mqnic_port_get_rx_status(dev_port)); + printf("Port TX ctrl: 0x%08x\n", mqnic_port_get_tx_ctrl(dev_port)); + printf("Port RX ctrl: 0x%08x\n", mqnic_port_get_rx_ctrl(dev_port)); + printf("Port FC ctrl: 0x%08x\n", mqnic_port_get_fc_ctrl(dev_port)); + printf("Port LFC ctrl: 0x%08x\n", mqnic_port_get_lfc_ctrl(dev_port)); + for (int k = 0; k < 8; k++) + printf("Port PFC ctrl %d: 0x%08x\n", k, mqnic_port_get_pfc_ctrl(dev_port, k)); sched_block = port;