From 6b256f82d3bd097d1b2222366da31798a645c25c Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Sun, 10 Sep 2023 23:22:50 -0700 Subject: [PATCH] Generate pause frames on TX Signed-off-by: Alex Forencich --- docs/source/rb/if_ctrl.rst | 28 +++++++++++++++ fpga/common/rtl/mqnic_interface.v | 25 ++++++++++++- fpga/common/rtl/mqnic_port.v | 28 ++++++++++++--- fpga/common/rtl/rx_fifo.v | 58 +++++++++++++++++++------------ fpga/common/rtl/tx_fifo.v | 58 +++++++++++++++++++------------ fpga/common/tb/mqnic.py | 24 ++++++++----- lib/mqnic/mqnic.h | 2 ++ lib/mqnic/mqnic_if.c | 2 ++ modules/mqnic/mqnic.h | 2 ++ modules/mqnic/mqnic_hw.h | 20 ++++++----- modules/mqnic/mqnic_if.c | 2 ++ modules/mqnic/mqnic_port.c | 2 +- utils/mqnic-dump.c | 10 +++--- 13 files changed, 189 insertions(+), 72 deletions(-) diff --git a/docs/source/rb/if_ctrl.rst b/docs/source/rb/if_ctrl.rst index 355245d8d..38178de4f 100644 --- a/docs/source/rb/if_ctrl.rst +++ b/docs/source/rb/if_ctrl.rst @@ -34,6 +34,10 @@ The interface control register block has a header with type 0x0000C001, version RBB+0x28 TX MTU TX MTU RW - -------- ------------- ------------------------------ ------------- RBB+0x2C RX MTU RX MTU RW - + -------- ------------- ------------------------------ ------------- + RBB+0x30 TX FIFO depth TX FIFO depth RO - + -------- ------------- ------------------------------ ------------- + RBB+0x34 RX FIFO depth RX FIFO depth RO - ======== ============= ============================== ============= See :ref:`rb_overview` for definitions of the standard register block header fields. @@ -137,3 +141,27 @@ See :ref:`rb_overview` for definitions of the standard register block header fie ======== ====== ====== ====== ====== ============= RBB+0x2C RX MTU RW - ======== ============================== ============= + +.. object:: TX FIFO depth + + The TX FIFO depth field contains the size of the transmit FIFO in bytes, as configured via Verilog parameters during synthesis. + + .. table:: + + ======== ====== ====== ====== ====== ============= + Address 31..24 23..16 15..8 7..0 Reset value + ======== ====== ====== ====== ====== ============= + RBB+0x30 TX FIFO depth RO - + ======== ============================== ============= + +.. object:: RX FIFO depth + + The RX FIFO depth field contains the size of the receive FIFO in bytes, as configured via Verilog parameters during synthesis. + + .. table:: + + ======== ====== ====== ====== ====== ============= + Address 31..24 23..16 15..8 7..0 Reset value + ======== ====== ====== ====== ====== ============= + RBB+0x34 RX FIFO depth RO - + ======== ============================== ============= diff --git a/fpga/common/rtl/mqnic_interface.v b/fpga/common/rtl/mqnic_interface.v index d55b83958..7984a32ca 100644 --- a/fpga/common/rtl/mqnic_interface.v +++ b/fpga/common/rtl/mqnic_interface.v @@ -545,6 +545,9 @@ localparam PORT_RB_STRIDE = 16'h1000; localparam SCHED_RB_BASE_ADDR = (PORT_RB_BASE_ADDR + PORT_RB_STRIDE*PORTS); localparam SCHED_RB_STRIDE = 16'h1000; +localparam TX_FIFO_DEPTH_WIDTH = $clog2(TX_FIFO_DEPTH)+1; +localparam RX_FIFO_DEPTH_WIDTH = $clog2(RX_FIFO_DEPTH)+1; + // parameter sizing helpers function [31:0] w_32(input [31:0] val); w_32 = val; @@ -1110,6 +1113,8 @@ always @(posedge clk) begin RBB+8'h24: ctrl_reg_rd_data_reg <= MAX_RX_SIZE; // IF ctrl: Max RX MTU RBB+8'h28: ctrl_reg_rd_data_reg <= tx_mtu_reg; // IF ctrl: TX MTU RBB+8'h2C: ctrl_reg_rd_data_reg <= rx_mtu_reg; // IF ctrl: RX MTU + RBB+8'h30: ctrl_reg_rd_data_reg <= TX_FIFO_DEPTH; // IF ctrl: TX FIFO depth + RBB+8'h34: ctrl_reg_rd_data_reg <= RX_FIFO_DEPTH; // IF ctrl: RX FIFO depth // Event queue manager RBB+8'h40: ctrl_reg_rd_data_reg <= 32'h0000C010; // Event QM: Type RBB+8'h44: ctrl_reg_rd_data_reg <= 32'h00000400; // Event QM: Version @@ -2899,6 +2904,8 @@ wire [PORTS-1:0] axis_if_tx_fifo_tlast; wire [PORTS*AXIS_IF_TX_ID_WIDTH-1:0] axis_if_tx_fifo_tid; wire [PORTS*AXIS_IF_TX_USER_WIDTH-1:0] axis_if_tx_fifo_tuser; +wire [RX_FIFO_DEPTH_WIDTH*PORTS-1:0] tx_fifo_status_depth; + if (APP_AXIS_IF_ENABLE) begin assign m_axis_app_if_tx_tdata = if_tx_axis_tdata; @@ -2944,6 +2951,7 @@ end tx_fifo #( .FIFO_DEPTH(TX_FIFO_DEPTH), + .FIFO_DEPTH_WIDTH(TX_FIFO_DEPTH_WIDTH), .PORTS(PORTS), .S_DATA_WIDTH(AXIS_IF_DATA_WIDTH), .S_KEEP_ENABLE(AXIS_IF_KEEP_WIDTH > 1), @@ -2990,6 +2998,8 @@ tx_fifo_inst ( /* * Status */ + .status_depth(tx_fifo_status_depth), + .status_depth_commit(), .status_overflow(), .status_bad_frame(), .status_good_frame() @@ -3014,8 +3024,11 @@ wire [AXIS_IF_RX_ID_WIDTH-1:0] axis_if_rx_tid; wire [AXIS_IF_RX_DEST_WIDTH-1:0] axis_if_rx_tdest; wire [AXIS_IF_RX_USER_WIDTH-1:0] axis_if_rx_tuser; +wire [RX_FIFO_DEPTH_WIDTH*PORTS-1:0] rx_fifo_status_depth; + rx_fifo #( .FIFO_DEPTH(RX_FIFO_DEPTH), + .FIFO_DEPTH_WIDTH(RX_FIFO_DEPTH_WIDTH), .PORTS(PORTS), .S_DATA_WIDTH(AXIS_SYNC_DATA_WIDTH), .S_KEEP_ENABLE(AXIS_SYNC_KEEP_WIDTH > 1), @@ -3061,6 +3074,8 @@ rx_fifo_inst ( /* * Status */ + .status_depth(rx_fifo_status_depth), + .status_depth_commit(), .status_overflow(), .status_bad_frame(), .status_good_frame() @@ -3123,6 +3138,10 @@ for (n = 0; n < PORTS; n = n + 1) begin : port .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), + .TX_FIFO_DEPTH_WIDTH(TX_FIFO_DEPTH_WIDTH), + .RX_FIFO_DEPTH_WIDTH(RX_FIFO_DEPTH_WIDTH), .MAX_TX_SIZE(MAX_TX_SIZE), .MAX_RX_SIZE(MAX_RX_SIZE), @@ -3305,6 +3324,8 @@ for (n = 0; n < PORTS; n = n + 1) begin : port .tx_pfc_req(tx_pfc_req[n*8 +: 8]), .tx_fc_quanta_clk_en(tx_fc_quanta_clk_en[n +: 1]), + .tx_fifo_status_depth(tx_fifo_status_depth[n*TX_FIFO_DEPTH_WIDTH +: TX_FIFO_DEPTH_WIDTH]), + /* * Receive data input */ @@ -3326,7 +3347,9 @@ for (n = 0; n < PORTS; n = n + 1) begin : port .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]) + .rx_fc_quanta_clk_en(rx_fc_quanta_clk_en[n +: 1]), + + .rx_fifo_status_depth(rx_fifo_status_depth[n*RX_FIFO_DEPTH_WIDTH +: RX_FIFO_DEPTH_WIDTH]) ); end diff --git a/fpga/common/rtl/mqnic_port.v b/fpga/common/rtl/mqnic_port.v index f54a461a4..d0ac9a625 100644 --- a/fpga/common/rtl/mqnic_port.v +++ b/fpga/common/rtl/mqnic_port.v @@ -25,6 +25,10 @@ module mqnic_port # 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 TX_FIFO_DEPTH_WIDTH = $clog2(TX_FIFO_DEPTH)+1, + parameter RX_FIFO_DEPTH_WIDTH = $clog2(RX_FIFO_DEPTH)+1, parameter MAX_TX_SIZE = 9214, parameter MAX_RX_SIZE = 9214, @@ -207,6 +211,8 @@ module mqnic_port # output wire [7:0] tx_pfc_req, input wire tx_fc_quanta_clk_en, + input wire [TX_FIFO_DEPTH_WIDTH-1:0] tx_fifo_status_depth, + /* * Receive data input */ @@ -228,7 +234,9 @@ module mqnic_port # 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 + input wire rx_fc_quanta_clk_en, + + input wire [RX_FIFO_DEPTH_WIDTH-1:0] rx_fifo_status_depth ); localparam RBB = RB_BASE_ADDR & {REG_ADDR_WIDTH{1'b1}}; @@ -414,8 +422,7 @@ 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; +reg [RX_FIFO_DEPTH_WIDTH-1:0] rx_lfc_watermark_reg = RX_FIFO_DEPTH/2; 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; @@ -435,7 +442,16 @@ always @(posedge clk) begin ctrl_reg_rd_data_reg <= {REG_DATA_WIDTH{1'b0}}; ctrl_reg_rd_ack_reg <= 1'b0; - tx_lfc_req_reg <= 1'b0; + if (tx_lfc_req_reg) begin + if (rx_fifo_status_depth == 0) begin + tx_lfc_req_reg <= 1'b0; + end + end else begin + if (rx_fifo_status_depth > rx_lfc_watermark_reg) begin + tx_lfc_req_reg <= 1'b1; + end + end + tx_pfc_req_reg <= 8'd0; rx_lfc_ack_reg <= tx_fifo_pause_ack; @@ -469,6 +485,7 @@ always @(posedge clk) begin if (LFC_ENABLE) begin if ({ctrl_reg_wr_addr >> 2, 2'b00} == RBB+8'h2C) begin // Port ctrl: LFC control + rx_lfc_watermark_reg <= ctrl_reg_wr_data[23:0]; 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; @@ -536,6 +553,7 @@ always @(posedge clk) begin 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[23:0] <= rx_lfc_watermark_reg; 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; @@ -576,6 +594,8 @@ always @(posedge clk) begin rx_pfc_en_reg <= 8'd0; rx_pfc_ack_reg <= 8'd0; rx_fc_quanta_step_reg <= (AXIS_DATA_WIDTH*256)/512; + + rx_lfc_watermark_reg <= RX_FIFO_DEPTH/2; end end diff --git a/fpga/common/rtl/rx_fifo.v b/fpga/common/rtl/rx_fifo.v index c10815152..424d96376 100644 --- a/fpga/common/rtl/rx_fifo.v +++ b/fpga/common/rtl/rx_fifo.v @@ -18,6 +18,8 @@ module rx_fifo # // KEEP_WIDTH words per cycle if KEEP_ENABLE set // Rounded up to nearest power of 2 cycles parameter FIFO_DEPTH = 4096, + // Width of FIFO depth status signals + parameter FIFO_DEPTH_WIDTH = $clog2(FIFO_DEPTH)+1, // Number of AXI stream inputs parameter PORTS = 4, // Width of input AXI stream interfaces in bits @@ -50,39 +52,41 @@ module rx_fifo # parameter RAM_PIPELINE = 1 ) ( - input wire clk, - input wire rst, + input wire clk, + input wire rst, /* * AXI Stream inputs */ - input wire [PORTS*S_DATA_WIDTH-1:0] s_axis_tdata, - input wire [PORTS*S_KEEP_WIDTH-1:0] s_axis_tkeep, - input wire [PORTS-1:0] s_axis_tvalid, - output wire [PORTS-1:0] s_axis_tready, - input wire [PORTS-1:0] s_axis_tlast, - input wire [PORTS*S_ID_WIDTH-1:0] s_axis_tid, - input wire [PORTS*DEST_WIDTH-1:0] s_axis_tdest, - input wire [PORTS*USER_WIDTH-1:0] s_axis_tuser, + input wire [PORTS*S_DATA_WIDTH-1:0] s_axis_tdata, + input wire [PORTS*S_KEEP_WIDTH-1:0] s_axis_tkeep, + input wire [PORTS-1:0] s_axis_tvalid, + output wire [PORTS-1:0] s_axis_tready, + input wire [PORTS-1:0] s_axis_tlast, + input wire [PORTS*S_ID_WIDTH-1:0] s_axis_tid, + input wire [PORTS*DEST_WIDTH-1:0] s_axis_tdest, + input wire [PORTS*USER_WIDTH-1:0] s_axis_tuser, /* * AXI Stream output */ - output wire [M_DATA_WIDTH-1:0] m_axis_tdata, - output wire [M_KEEP_WIDTH-1:0] m_axis_tkeep, - output wire m_axis_tvalid, - input wire m_axis_tready, - output wire m_axis_tlast, - output wire [M_ID_WIDTH-1:0] m_axis_tid, - output wire [DEST_WIDTH-1:0] m_axis_tdest, - output wire [USER_WIDTH-1:0] m_axis_tuser, + output wire [M_DATA_WIDTH-1:0] m_axis_tdata, + output wire [M_KEEP_WIDTH-1:0] m_axis_tkeep, + output wire m_axis_tvalid, + input wire m_axis_tready, + output wire m_axis_tlast, + output wire [M_ID_WIDTH-1:0] m_axis_tid, + output wire [DEST_WIDTH-1:0] m_axis_tdest, + output wire [USER_WIDTH-1:0] m_axis_tuser, /* * Status */ - output wire [PORTS-1:0] status_overflow, - output wire [PORTS-1:0] status_bad_frame, - output wire [PORTS-1:0] status_good_frame + output wire [FIFO_DEPTH_WIDTH*PORTS-1:0] status_depth, + output wire [FIFO_DEPTH_WIDTH*PORTS-1:0] status_depth_commit, + output wire [PORTS-1:0] status_overflow, + output wire [PORTS-1:0] status_bad_frame, + output wire [PORTS-1:0] status_good_frame ); wire [PORTS*M_DATA_WIDTH-1:0] axis_fifo_tdata; @@ -118,8 +122,12 @@ for (n = 0; n < PORTS; n = n + 1) begin : fifo .FRAME_FIFO(1), .USER_BAD_FRAME_VALUE(1'b1), .USER_BAD_FRAME_MASK(1'b1), + .DROP_OVERSIZE_FRAME(1), .DROP_BAD_FRAME(USER_ENABLE), - .DROP_WHEN_FULL(0) + .DROP_WHEN_FULL(0), + .MARK_WHEN_FULL(0), + .PAUSE_ENABLE(0), + .FRAME_PAUSE(1) ) fifo_inst ( .clk(clk), @@ -145,7 +153,13 @@ for (n = 0; n < PORTS; n = n + 1) begin : fifo .m_axis_tdest(axis_fifo_tdest[n*DEST_WIDTH +: DEST_WIDTH]), .m_axis_tuser(axis_fifo_tuser[n*USER_WIDTH +: USER_WIDTH]), + // Pause + .pause_req(1'b0), + .pause_ack(), + // Status + .status_depth(status_depth[n*FIFO_DEPTH_WIDTH +: FIFO_DEPTH_WIDTH]), + .status_depth_commit(status_depth_commit[n*FIFO_DEPTH_WIDTH +: FIFO_DEPTH_WIDTH]), .status_overflow(status_overflow[n]), .status_bad_frame(status_bad_frame[n]), .status_good_frame(status_good_frame[n]) diff --git a/fpga/common/rtl/tx_fifo.v b/fpga/common/rtl/tx_fifo.v index 169ce1ced..19fa7cbe1 100644 --- a/fpga/common/rtl/tx_fifo.v +++ b/fpga/common/rtl/tx_fifo.v @@ -18,6 +18,8 @@ module tx_fifo # // KEEP_WIDTH words per cycle if KEEP_ENABLE set // Rounded up to nearest power of 2 cycles parameter FIFO_DEPTH = 4096, + // Width of FIFO depth status signals + parameter FIFO_DEPTH_WIDTH = $clog2(FIFO_DEPTH)+1, // Number of AXI stream outputs parameter PORTS = 4, // Width of input AXI stream interfaces in bits @@ -49,39 +51,41 @@ module tx_fifo # parameter RAM_PIPELINE = 1 ) ( - input wire clk, - input wire rst, + input wire clk, + input wire rst, /* * AXI Stream input */ - input wire [S_DATA_WIDTH-1:0] s_axis_tdata, - input wire [S_KEEP_WIDTH-1:0] s_axis_tkeep, - input wire s_axis_tvalid, - output wire s_axis_tready, - input wire s_axis_tlast, - input wire [ID_WIDTH-1:0] s_axis_tid, - input wire [S_DEST_WIDTH-1:0] s_axis_tdest, - input wire [USER_WIDTH-1:0] s_axis_tuser, + input wire [S_DATA_WIDTH-1:0] s_axis_tdata, + input wire [S_KEEP_WIDTH-1:0] s_axis_tkeep, + input wire s_axis_tvalid, + output wire s_axis_tready, + input wire s_axis_tlast, + input wire [ID_WIDTH-1:0] s_axis_tid, + input wire [S_DEST_WIDTH-1:0] s_axis_tdest, + input wire [USER_WIDTH-1:0] s_axis_tuser, /* * AXI Stream outputs */ - output wire [PORTS*M_DATA_WIDTH-1:0] m_axis_tdata, - output wire [PORTS*M_KEEP_WIDTH-1:0] m_axis_tkeep, - output wire [PORTS-1:0] m_axis_tvalid, - input wire [PORTS-1:0] m_axis_tready, - output wire [PORTS-1:0] m_axis_tlast, - output wire [PORTS*ID_WIDTH-1:0] m_axis_tid, - output wire [PORTS*M_DEST_WIDTH-1:0] m_axis_tdest, - output wire [PORTS*USER_WIDTH-1:0] m_axis_tuser, + output wire [PORTS*M_DATA_WIDTH-1:0] m_axis_tdata, + output wire [PORTS*M_KEEP_WIDTH-1:0] m_axis_tkeep, + output wire [PORTS-1:0] m_axis_tvalid, + input wire [PORTS-1:0] m_axis_tready, + output wire [PORTS-1:0] m_axis_tlast, + output wire [PORTS*ID_WIDTH-1:0] m_axis_tid, + output wire [PORTS*M_DEST_WIDTH-1:0] m_axis_tdest, + output wire [PORTS*USER_WIDTH-1:0] m_axis_tuser, /* * Status */ - output wire [PORTS-1:0] status_overflow, - output wire [PORTS-1:0] status_bad_frame, - output wire [PORTS-1:0] status_good_frame + output wire [FIFO_DEPTH_WIDTH*PORTS-1:0] status_depth, + output wire [FIFO_DEPTH_WIDTH*PORTS-1:0] status_depth_commit, + output wire [PORTS-1:0] status_overflow, + output wire [PORTS-1:0] status_bad_frame, + output wire [PORTS-1:0] status_good_frame ); wire [PORTS*S_DATA_WIDTH-1:0] axis_fifo_tdata; @@ -176,8 +180,12 @@ for (n = 0; n < PORTS; n = n + 1) begin : fifo .FRAME_FIFO(1), .USER_BAD_FRAME_VALUE(1'b1), .USER_BAD_FRAME_MASK(1'b1), + .DROP_OVERSIZE_FRAME(1), .DROP_BAD_FRAME(USER_ENABLE), - .DROP_WHEN_FULL(0) + .DROP_WHEN_FULL(0), + .MARK_WHEN_FULL(0), + .PAUSE_ENABLE(0), + .FRAME_PAUSE(1) ) fifo_inst ( .clk(clk), @@ -203,7 +211,13 @@ for (n = 0; n < PORTS; n = n + 1) begin : fifo .m_axis_tdest(m_axis_tdest[n*M_DEST_WIDTH +: M_DEST_WIDTH]), .m_axis_tuser(m_axis_tuser[n*USER_WIDTH +: USER_WIDTH]), + // Pause + .pause_req(1'b0), + .pause_ack(), + // Status + .status_depth(status_depth[n*FIFO_DEPTH_WIDTH +: FIFO_DEPTH_WIDTH]), + .status_depth_commit(status_depth_commit[n*FIFO_DEPTH_WIDTH +: FIFO_DEPTH_WIDTH]), .status_overflow(status_overflow[n]), .status_bad_frame(status_bad_frame[n]), .status_good_frame(status_good_frame[n]) diff --git a/fpga/common/tb/mqnic.py b/fpga/common/tb/mqnic.py index e5cdac7a1..4e8bec389 100644 --- a/fpga/common/tb/mqnic.py +++ b/fpga/common/tb/mqnic.py @@ -132,15 +132,17 @@ MQNIC_RB_IF_REG_COUNT = 0x10 MQNIC_RB_IF_REG_STRIDE = 0x14 MQNIC_RB_IF_REG_CSR_OFFSET = 0x18 -MQNIC_RB_IF_CTRL_TYPE = 0x0000C001 -MQNIC_RB_IF_CTRL_VER = 0x00000400 -MQNIC_RB_IF_CTRL_REG_FEATURES = 0x0C -MQNIC_RB_IF_CTRL_REG_PORT_COUNT = 0x10 -MQNIC_RB_IF_CTRL_REG_SCHED_COUNT = 0x14 -MQNIC_RB_IF_CTRL_REG_MAX_TX_MTU = 0x20 -MQNIC_RB_IF_CTRL_REG_MAX_RX_MTU = 0x24 -MQNIC_RB_IF_CTRL_REG_TX_MTU = 0x28 -MQNIC_RB_IF_CTRL_REG_RX_MTU = 0x2C +MQNIC_RB_IF_CTRL_TYPE = 0x0000C001 +MQNIC_RB_IF_CTRL_VER = 0x00000400 +MQNIC_RB_IF_CTRL_REG_FEATURES = 0x0C +MQNIC_RB_IF_CTRL_REG_PORT_COUNT = 0x10 +MQNIC_RB_IF_CTRL_REG_SCHED_COUNT = 0x14 +MQNIC_RB_IF_CTRL_REG_MAX_TX_MTU = 0x20 +MQNIC_RB_IF_CTRL_REG_MAX_RX_MTU = 0x24 +MQNIC_RB_IF_CTRL_REG_TX_MTU = 0x28 +MQNIC_RB_IF_CTRL_REG_RX_MTU = 0x2C +MQNIC_RB_IF_CTRL_REG_TX_FIFO_DEPTH = 0x20 +MQNIC_RB_IF_CTRL_REG_RX_FIFO_DEPTH = 0x24 MQNIC_IF_FEATURE_RSS = (1 << 0) MQNIC_IF_FEATURE_PTP_TS = (1 << 4) @@ -1235,6 +1237,8 @@ class Interface: self.max_tx_mtu = 0 self.max_rx_mtu = 0 + self.tx_fifo_depth = 0 + self.rx_fifo_depth = 0 self.eq_res = None self.cq_res = None @@ -1273,6 +1277,8 @@ class Interface: self.sched_block_count = await self.if_ctrl_rb.read_dword(MQNIC_RB_IF_CTRL_REG_SCHED_COUNT) self.max_tx_mtu = await self.if_ctrl_rb.read_dword(MQNIC_RB_IF_CTRL_REG_MAX_TX_MTU) self.max_rx_mtu = await self.if_ctrl_rb.read_dword(MQNIC_RB_IF_CTRL_REG_MAX_RX_MTU) + self.tx_fifo_depth = await self.if_ctrl_rb.read_dword(MQNIC_RB_IF_CTRL_REG_TX_FIFO_DEPTH) + self.rx_fifo_depth = await self.if_ctrl_rb.read_dword(MQNIC_RB_IF_CTRL_REG_RX_FIFO_DEPTH) self.if_feature_rss = bool(self.if_features & MQNIC_IF_FEATURE_RSS) self.if_feature_ptp_ts = bool(self.if_features & MQNIC_IF_FEATURE_PTP_TS) diff --git a/lib/mqnic/mqnic.h b/lib/mqnic/mqnic.h index b5d21f7a4..eb029bdb4 100644 --- a/lib/mqnic/mqnic.h +++ b/lib/mqnic/mqnic.h @@ -86,6 +86,8 @@ struct mqnic_if { uint32_t max_tx_mtu; uint32_t max_rx_mtu; + uint32_t tx_fifo_depth; + uint32_t rx_fifo_depth; uint32_t rx_queue_map_indir_table_size; volatile uint8_t *rx_queue_map_indir_table[MQNIC_MAX_PORTS]; diff --git a/lib/mqnic/mqnic_if.c b/lib/mqnic/mqnic_if.c index f5083cb12..61b312100 100644 --- a/lib/mqnic/mqnic_if.c +++ b/lib/mqnic/mqnic_if.c @@ -53,6 +53,8 @@ struct mqnic_if *mqnic_if_open(struct mqnic *dev, int index, volatile uint8_t *r interface->sched_block_count = mqnic_reg_read32(interface->if_ctrl_rb->regs, MQNIC_RB_IF_CTRL_REG_SCHED_COUNT); interface->max_tx_mtu = mqnic_reg_read32(interface->if_ctrl_rb->regs, MQNIC_RB_IF_CTRL_REG_MAX_TX_MTU); interface->max_rx_mtu = mqnic_reg_read32(interface->if_ctrl_rb->regs, MQNIC_RB_IF_CTRL_REG_MAX_RX_MTU); + interface->tx_fifo_depth = mqnic_reg_read32(interface->if_ctrl_rb->regs, MQNIC_RB_IF_CTRL_REG_TX_FIFO_DEPTH); + interface->rx_fifo_depth = mqnic_reg_read32(interface->if_ctrl_rb->regs, MQNIC_RB_IF_CTRL_REG_RX_FIFO_DEPTH); interface->eq_rb = mqnic_find_reg_block(interface->rb_list, MQNIC_RB_EQM_TYPE, MQNIC_RB_EQM_VER, 0); diff --git a/modules/mqnic/mqnic.h b/modules/mqnic/mqnic.h index faba4c708..3a298b4c4 100644 --- a/modules/mqnic/mqnic.h +++ b/modules/mqnic/mqnic.h @@ -386,6 +386,8 @@ struct mqnic_if { u32 max_tx_mtu; u32 max_rx_mtu; + u32 tx_fifo_depth; + u32 rx_fifo_depth; struct mqnic_res *eq_res; struct mqnic_res *cq_res; diff --git a/modules/mqnic/mqnic_hw.h b/modules/mqnic/mqnic_hw.h index 669856d7d..05ca11ee5 100644 --- a/modules/mqnic/mqnic_hw.h +++ b/modules/mqnic/mqnic_hw.h @@ -172,15 +172,17 @@ #define MQNIC_RB_IF_REG_STRIDE 0x14 #define MQNIC_RB_IF_REG_CSR_OFFSET 0x18 -#define MQNIC_RB_IF_CTRL_TYPE 0x0000C001 -#define MQNIC_RB_IF_CTRL_VER 0x00000400 -#define MQNIC_RB_IF_CTRL_REG_FEATURES 0x0C -#define MQNIC_RB_IF_CTRL_REG_PORT_COUNT 0x10 -#define MQNIC_RB_IF_CTRL_REG_SCHED_COUNT 0x14 -#define MQNIC_RB_IF_CTRL_REG_MAX_TX_MTU 0x20 -#define MQNIC_RB_IF_CTRL_REG_MAX_RX_MTU 0x24 -#define MQNIC_RB_IF_CTRL_REG_TX_MTU 0x28 -#define MQNIC_RB_IF_CTRL_REG_RX_MTU 0x2C +#define MQNIC_RB_IF_CTRL_TYPE 0x0000C001 +#define MQNIC_RB_IF_CTRL_VER 0x00000400 +#define MQNIC_RB_IF_CTRL_REG_FEATURES 0x0C +#define MQNIC_RB_IF_CTRL_REG_PORT_COUNT 0x10 +#define MQNIC_RB_IF_CTRL_REG_SCHED_COUNT 0x14 +#define MQNIC_RB_IF_CTRL_REG_MAX_TX_MTU 0x20 +#define MQNIC_RB_IF_CTRL_REG_MAX_RX_MTU 0x24 +#define MQNIC_RB_IF_CTRL_REG_TX_MTU 0x28 +#define MQNIC_RB_IF_CTRL_REG_RX_MTU 0x2C +#define MQNIC_RB_IF_CTRL_REG_TX_FIFO_DEPTH 0x30 +#define MQNIC_RB_IF_CTRL_REG_RX_FIFO_DEPTH 0x34 #define MQNIC_IF_FEATURE_RSS (1 << 0) #define MQNIC_IF_FEATURE_PTP_TS (1 << 4) diff --git a/modules/mqnic/mqnic_if.c b/modules/mqnic/mqnic_if.c index d106dfecb..4ca99fec8 100644 --- a/modules/mqnic/mqnic_if.c +++ b/modules/mqnic/mqnic_if.c @@ -55,6 +55,8 @@ struct mqnic_if *mqnic_create_interface(struct mqnic_dev *mdev, int index, u8 __ interface->sched_block_count = ioread32(interface->if_ctrl_rb->regs + MQNIC_RB_IF_CTRL_REG_SCHED_COUNT); interface->max_tx_mtu = ioread32(interface->if_ctrl_rb->regs + MQNIC_RB_IF_CTRL_REG_MAX_TX_MTU); interface->max_rx_mtu = ioread32(interface->if_ctrl_rb->regs + MQNIC_RB_IF_CTRL_REG_MAX_RX_MTU); + interface->tx_fifo_depth = ioread32(interface->if_ctrl_rb->regs + MQNIC_RB_IF_CTRL_REG_TX_FIFO_DEPTH); + interface->rx_fifo_depth = ioread32(interface->if_ctrl_rb->regs + MQNIC_RB_IF_CTRL_REG_RX_FIFO_DEPTH); dev_info(dev, "IF features: 0x%08x", interface->if_features); dev_info(dev, "Port count: %d", interface->port_count); diff --git a/modules/mqnic/mqnic_port.c b/modules/mqnic/mqnic_port.c index fe13f14b0..8dffc0fdd 100644 --- a/modules/mqnic/mqnic_port.c +++ b/modules/mqnic/mqnic_port.c @@ -55,7 +55,7 @@ struct mqnic_port *mqnic_create_port(struct mqnic_if *interface, int index, mqnic_port_set_tx_ctrl(port, 0); mqnic_port_set_rx_ctrl(port, 0); - mqnic_port_set_lfc_ctrl(port, 0); + mqnic_port_set_lfc_ctrl(port, max_t(u32, interface->rx_fifo_depth / 2, interface->max_rx_mtu * 2)); for (k = 0; k < 8; k++) mqnic_port_set_pfc_ctrl(port, k, 0); diff --git a/utils/mqnic-dump.c b/utils/mqnic-dump.c index 6a9d0721c..896ffb1be 100644 --- a/utils/mqnic-dump.c +++ b/utils/mqnic-dump.c @@ -221,10 +221,12 @@ int main(int argc, char *argv[]) printf("IF features: 0x%08x\n", dev_interface->if_features); printf("Port count: %d\n", dev_interface->port_count); printf("Scheduler block count: %d\n", dev_interface->sched_block_count); - printf("Max TX MTU: %d\n", dev_interface->max_tx_mtu); - printf("Max RX MTU: %d\n", dev_interface->max_rx_mtu); - printf("TX MTU: %d\n", mqnic_interface_get_tx_mtu(dev_interface)); - printf("RX MTU: %d\n", mqnic_interface_get_rx_mtu(dev_interface)); + printf("Max TX MTU: %d B\n", dev_interface->max_tx_mtu); + printf("Max RX MTU: %d B\n", dev_interface->max_rx_mtu); + printf("TX MTU: %d B\n", mqnic_interface_get_tx_mtu(dev_interface)); + printf("RX MTU: %d B\n", mqnic_interface_get_rx_mtu(dev_interface)); + printf("TX FIFO depth: %d B\n", dev_interface->tx_fifo_depth); + printf("RX FIFO depth: %d B\n", dev_interface->rx_fifo_depth); printf("EQ offset: 0x%08lx\n", dev_interface->eq_res->base - dev_interface->regs); printf("EQ count: %d\n", mqnic_res_get_count(dev_interface->eq_res));