summaryrefslogtreecommitdiffstats
path: root/src/vnet/session
diff options
context:
space:
mode:
authorFlorin Coras <fcoras@cisco.com>2017-06-09 21:07:32 -0700
committerDamjan Marion <dmarion.lists@gmail.com>2017-06-19 14:06:34 +0000
commitf03a59ab008908f98fd7d1b187a8c0fb78b01add (patch)
tree8ce1ab091e288d5edbc5df712f668e2e4888c90e /src/vnet/session
parent328dbc886d7acd3491cff86a7a85176e511acf35 (diff)
Overall tcp performance improvements (VPP-846)
- limit minimum rto per connection - cleanup sack scoreboard - switched svm fifo out-of-order data handling from absolute offsets to relative offsets. - improve cwnd handling when using sacks - add cc event debug stats - improved uri tcp test client/server: bugfixes and added half-duplex mode - expanded builtin client/server - updated uri socket client/server code to work in half-duplex - ensure session node unsets fifo event for empty fifo - fix session detach Change-Id: Ia446972340e32a65e0694ee2844355167d0c170d Signed-off-by: Florin Coras <fcoras@cisco.com>
Diffstat (limited to 'src/vnet/session')
-rw-r--r--src/vnet/session/application.c2
-rw-r--r--src/vnet/session/node.c7
-rw-r--r--src/vnet/session/segment_manager.c5
-rw-r--r--src/vnet/session/session.c25
-rw-r--r--src/vnet/session/session.h4
-rwxr-xr-xsrc/vnet/session/session_api.c2
-rw-r--r--src/vnet/session/transport.h2
7 files changed, 34 insertions, 13 deletions
diff --git a/src/vnet/session/application.c b/src/vnet/session/application.c
index c679b1f53f8..4bdb10271ab 100644
--- a/src/vnet/session/application.c
+++ b/src/vnet/session/application.c
@@ -117,7 +117,7 @@ application_del (application_t * app)
/* Actual listener cleanup */
for (i = 0; i < vec_len (handles); i++)
{
- a->app_index = app->api_client_index;
+ a->app_index = app->index;
a->handle = handles[i];
/* seg manager is removed when unbind completes */
vnet_unbind (a);
diff --git a/src/vnet/session/node.c b/src/vnet/session/node.c
index 07eeae82915..c0ab1bf096f 100644
--- a/src/vnet/session/node.c
+++ b/src/vnet/session/node.c
@@ -171,7 +171,10 @@ session_tx_fifo_read_and_snd_i (vlib_main_t * vm, vlib_node_runtime_t * node,
/* Nothing to read return */
if (max_dequeue0 == 0)
- return 0;
+ {
+ svm_fifo_unset_event (s0->server_tx_fifo);
+ return 0;
+ }
/* Ensure we're not writing more than transport window allows */
if (max_dequeue0 < snd_space0)
@@ -393,7 +396,7 @@ session_event_get_session (session_fifo_event_t * e0, u8 thread_index)
s0 = stream_session_get_if_valid (session_index0, thread_index);
- ASSERT (s0->thread_index == thread_index);
+ ASSERT (s0 == 0 || s0->thread_index == thread_index);
return s0;
}
diff --git a/src/vnet/session/segment_manager.c b/src/vnet/session/segment_manager.c
index caf8eaa308a..bf571963b0e 100644
--- a/src/vnet/session/segment_manager.c
+++ b/src/vnet/session/segment_manager.c
@@ -306,11 +306,13 @@ again:
if (added_a_segment)
{
clib_warning ("added a segment, still cant allocate a fifo");
+ clib_spinlock_unlock (&sm->lockp);
return SESSION_ERROR_NEW_SEG_NO_SPACE;
}
if (session_manager_add_segment (sm))
{
+ clib_spinlock_unlock (&sm->lockp);
return VNET_API_ERROR_URI_FIFO_CREATE_FAILED;
}
@@ -320,6 +322,7 @@ again:
else
{
clib_warning ("No space to allocate fifos!");
+ clib_spinlock_unlock (&sm->lockp);
return SESSION_ERROR_NO_SPACE;
}
}
@@ -361,8 +364,10 @@ segment_manager_dealloc_fifos (u32 svm_segment_index, svm_fifo_t * rx_fifo,
if (sm->segment_indices[0] != svm_segment_index
&& !svm_fifo_segment_has_fifos (fifo_segment))
{
+ clib_spinlock_lock (&sm->lockp);
svm_fifo_segment_delete (fifo_segment);
vec_del1 (sm->segment_indices, svm_segment_index);
+ clib_spinlock_unlock (&sm->lockp);
}
}
diff --git a/src/vnet/session/session.c b/src/vnet/session/session.c
index 534598d637f..fe198044db9 100644
--- a/src/vnet/session/session.c
+++ b/src/vnet/session/session.c
@@ -700,7 +700,7 @@ stream_session_init_fifos_pointers (transport_connection_t * tc,
svm_fifo_init_pointers (s->server_tx_fifo, tx_pointer);
}
-void
+int
stream_session_connect_notify (transport_connection_t * tc, u8 sst,
u8 is_fail)
{
@@ -709,6 +709,7 @@ stream_session_connect_notify (transport_connection_t * tc, u8 sst,
stream_session_t *new_s = 0;
u64 handle;
u32 api_context = 0;
+ int error = 0;
handle = stream_session_half_open_lookup (smm, &tc->lcl_ip, &tc->rmt_ip,
tc->lcl_port, tc->rmt_port,
@@ -716,7 +717,7 @@ stream_session_connect_notify (transport_connection_t * tc, u8 sst,
if (handle == HALF_OPEN_LOOKUP_INVALID_VALUE)
{
clib_warning ("This can't be good!");
- return;
+ return -1;
}
/* Get the app's index from the handle we stored when opening connection */
@@ -730,9 +731,12 @@ stream_session_connect_notify (transport_connection_t * tc, u8 sst,
/* Create new session (svm segments are allocated if needed) */
if (stream_session_create_i (sm, tc, &new_s))
- return;
-
- new_s->app_index = app->index;
+ {
+ is_fail = 1;
+ error = -1;
+ }
+ else
+ new_s->app_index = app->index;
}
/* Notify client */
@@ -741,6 +745,8 @@ stream_session_connect_notify (transport_connection_t * tc, u8 sst,
/* Cleanup session lookup */
stream_session_half_open_table_del (smm, sst, tc);
+
+ return error;
}
void
@@ -981,8 +987,13 @@ session_send_session_evt_to_thread (u64 session_handle,
/* Based on request block (or not) for lack of space */
if (PREDICT_TRUE (q->cursize < q->maxsize))
- unix_shared_memory_queue_add (q, (u8 *) & evt,
- 0 /* do wait for mutex */ );
+ {
+ if (unix_shared_memory_queue_add (q, (u8 *) & evt,
+ 1 /* do wait for mutex */ ))
+ {
+ clib_warning ("failed to enqueue evt");
+ }
+ }
else
{
clib_warning ("queue full");
diff --git a/src/vnet/session/session.h b/src/vnet/session/session.h
index d9c38bd1ad8..5fa4225c4ed 100644
--- a/src/vnet/session/session.h
+++ b/src/vnet/session/session.h
@@ -368,8 +368,8 @@ stream_session_peek_bytes (transport_connection_t * tc, u8 * buffer,
u32 offset, u32 max_bytes);
u32 stream_session_dequeue_drop (transport_connection_t * tc, u32 max_bytes);
-void stream_session_connect_notify (transport_connection_t * tc, u8 sst,
- u8 is_fail);
+int stream_session_connect_notify (transport_connection_t * tc, u8 sst,
+ u8 is_fail);
void stream_session_init_fifos_pointers (transport_connection_t * tc,
u32 rx_pointer, u32 tx_pointer);
diff --git a/src/vnet/session/session_api.c b/src/vnet/session/session_api.c
index f772cb9fdb4..60f764af48a 100755
--- a/src/vnet/session/session_api.c
+++ b/src/vnet/session/session_api.c
@@ -419,7 +419,7 @@ done:
REPLY_MACRO (VL_API_UNBIND_URI_REPLY);
}
-void
+static void
vl_api_connect_uri_t_handler (vl_api_connect_uri_t * mp)
{
vl_api_connect_uri_reply_t *rmp;
diff --git a/src/vnet/session/transport.h b/src/vnet/session/transport.h
index e5f788bee08..04bd5ca0f29 100644
--- a/src/vnet/session/transport.h
+++ b/src/vnet/session/transport.h
@@ -39,6 +39,7 @@ typedef struct _transport_connection
#if TRANSPORT_DEBUG
elog_track_t elog_track; /**< Event logging */
+ u32 cc_stat_tstamp; /**< CC stats timestamp */
#endif
/** Macros for 'derived classes' where base is named "connection" */
@@ -57,6 +58,7 @@ typedef struct _transport_connection
#define c_is_ip4 connection.is_ip4
#define c_thread_index connection.thread_index
#define c_elog_track connection.elog_track
+#define c_cc_stat_tstamp connection.cc_stat_tstamp
} transport_connection_t;
/*
*/ .highlight .py { color: #f8f8f2 } /* Name.Property */ .highlight .nt { color: #f92672 } /* Name.Tag */ .highlight .nv { color: #f8f8f2 } /* Name.Variable */ .highlight .ow { color: #f92672 } /* Operator.Word */ .highlight .w { color: #f8f8f2 } /* Text.Whitespace */ .highlight .mb { color: #ae81ff } /* Literal.Number.Bin */ .highlight .mf { color: #ae81ff } /* Literal.Number.Float */ .highlight .mh { color: #ae81ff } /* Literal.Number.Hex */ .highlight .mi { color: #ae81ff } /* Literal.Number.Integer */ .highlight .mo { color: #ae81ff } /* Literal.Number.Oct */ .highlight .sa { color: #e6db74 } /* Literal.String.Affix */ .highlight .sb { color: #e6db74 } /* Literal.String.Backtick */ .highlight .sc { color: #e6db74 } /* Literal.String.Char */ .highlight .dl { color: #e6db74 } /* Literal.String.Delimiter */ .highlight .sd { color: #e6db74 } /* Literal.String.Doc */ .highlight .s2 { color: #e6db74 } /* Literal.String.Double */ .highlight .se { color: #ae81ff } /* Literal.String.Escape */ .highlight .sh { color: #e6db74 } /* Literal.String.Heredoc */ .highlight .si { color: #e6db74 } /* Literal.String.Interpol */ .highlight .sx { color: #e6db74 } /* Literal.String.Other */ .highlight .sr { color: #e6db74 } /* Literal.String.Regex */ .highlight .s1 { color: #e6db74 } /* Literal.String.Single */ .highlight .ss { color: #e6db74 } /* Literal.String.Symbol */ .highlight .bp { color: #f8f8f2 } /* Name.Builtin.Pseudo */ .highlight .fm { color: #a6e22e } /* Name.Function.Magic */ .highlight .vc { color: #f8f8f2 } /* Name.Variable.Class */ .highlight .vg { color: #f8f8f2 } /* Name.Variable.Global */ .highlight .vi { color: #f8f8f2 } /* Name.Variable.Instance */ .highlight .vm { color: #f8f8f2 } /* Name.Variable.Magic */ .highlight .il { color: #ae81ff } /* Literal.Number.Integer.Long */ } @media (prefers-color-scheme: light) { .highlight .hll { background-color: #ffffcc } .highlight .c { color: #888888 } /* Comment */ .highlight .err { color: #a61717; background-color: #e3d2d2 } /* Error */ .highlight .k { color: #008800; font-weight: bold } /* Keyword */ .highlight .ch { color: #888888 } /* Comment.Hashbang */ .highlight .cm { color: #888888 } /* Comment.Multiline */ .highlight .cp { color: #cc0000; font-weight: bold } /* Comment.Preproc */ .highlight .cpf { color: #888888 } /* Comment.PreprocFile */ .highlight .c1 { color: #888888 } /* Comment.Single */ .highlight .cs { color: #cc0000; font-weight: bold; background-color: #fff0f0 } /* Comment.Special */ .highlight .gd { color: #000000; background-color: #ffdddd } /* Generic.Deleted */ .highlight .ge { font-style: italic } /* Generic.Emph */ .highlight .gr { color: #aa0000 } /* Generic.Error */ .highlight .gh { color: #333333 } /* Generic.Heading */ .highlight .gi { color: #000000; background-color: #ddffdd } /* Generic.Inserted */ .highlight .go { color: #888888 } /* Generic.Output */ .highlight .gp { color: #555555 } /* Generic.Prompt */ .highlight .gs { font-weight: bold } /* Generic.Strong */ .highlight .gu { color: #666666 } /* Generic.Subheading */ .highlight .gt { color: #aa0000 } /* Generic.Traceback */ .highlight .kc { color: #008800; font-weight: bold } /* Keyword.Constant */ .highlight .kd { color: #008800; font-weight: bold } /* Keyword.Declaration */ .highlight .kn { color: #008800; font-weight: bold } /* Keyword.Namespace */ .highlight .kp { color: #008800 } /* Keyword.Pseudo */ .highlight .kr { color: #008800; font-weight: bold } /* Keyword.Reserved */ .highlight .kt { color: #888888; font-weight: bold } /* Keyword.Type */ .highlight .m { color: #0000DD; font-weight: bold } /* Literal.Number */ .highlight .s { color: #dd2200; background-color: #fff0f0 } /* Literal.String */ .highlight .na { color: #336699 } /* Name.Attribute */ .highlight .nb { color: #003388 } /* Name.Builtin */ .highlight .nc { color: #bb0066; font-weight: bold } /* Name.Class */ .highlight .no { color: #003366; font-weight: bold } /* Name.Constant */ .highlight .nd { color: #555555 } /* Name.Decorator */ .highlight .ne { color: #bb0066; font-weight: bold } /* Name.Exception */ .highlight .nf { color: #0066bb; font-weight: bold } /* Name.Function */ .highlight .nl { color: #336699; font-style: italic } /* Name.Label */ .highlight .nn { color: #bb0066; font-weight: bold } /* Name.Namespace */ .highlight .py { color: #336699; font-weight: bold } /* Name.Property */ .highlight .nt { color: #bb0066; font-weight: bold } /* Name.Tag */ .highlight .nv { color: #336699 } /* Name.Variable */ .highlight .ow { color: #008800 } /* Operator.Word */ .highlight .w { color: #bbbbbb } /* Text.Whitespace */ .highlight .mb { color: #0000DD; font-weight: bold } /* Literal.Number.Bin */ .highlight .mf { color: #0000DD; font-weight: bold } /* Literal.Number.Float */ .highlight .mh { color: #0000DD; font-weight: bold } /* Literal.Number.Hex */ .highlight .mi { color: #0000DD; font-weight: bold } /* Literal.Number.Integer */ .highlight .mo { color: #0000DD; font-weight: bold } /* Literal.Number.Oct */ .highlight .sa { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Affix */ .highlight .sb { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Backtick */ .highlight .sc { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Char */ .highlight .dl { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Delimiter */ .highlight .sd { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Doc */ .highlight .s2 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Double */ .highlight .se { color: #0044dd; background-color: #fff0f0 } /* Literal.String.Escape */ .highlight .sh { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Heredoc */ .highlight .si { color: #3333bb; background-color: #fff0f0 } /* Literal.String.Interpol */ .highlight .sx { color: #22bb22; background-color: #f0fff0 } /* Literal.String.Other */ .highlight .sr { color: #008800; background-color: #fff0ff } /* Literal.String.Regex */ .highlight .s1 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Single */ .highlight .ss { color: #aa6600; background-color: #fff0f0 } /* Literal.String.Symbol */ .highlight .bp { color: #003388 } /* Name.Builtin.Pseudo */ .highlight .fm { color: #0066bb; font-weight: bold } /* Name.Function.Magic */ .highlight .vc { color: #336699 } /* Name.Variable.Class */ .highlight .vg { color: #dd7700 } /* Name.Variable.Global */ .highlight .vi { color: #3333bb } /* Name.Variable.Instance */ .highlight .vm { color: #336699 } /* Name.Variable.Magic */ .highlight .il { color: #0000DD; font-weight: bold } /* Literal.Number.Integer.Long */ }
/*
 * Copyright (c) 2016 QLogic Corporation.
 * All rights reserved.
 * www.qlogic.com
 *
 * See LICENSE.qede_pmd for copyright and licensing details.
 */

#ifndef __ETH_COMMON__
#define __ETH_COMMON__
/********************/
/* ETH FW CONSTANTS */
/********************/
#define ETH_CACHE_LINE_SIZE                 64
#define ETH_RX_CQE_GAP						32
#define ETH_MAX_RAMROD_PER_CON				8
#define ETH_TX_BD_PAGE_SIZE_BYTES			4096
#define ETH_RX_BD_PAGE_SIZE_BYTES			4096
#define ETH_RX_CQE_PAGE_SIZE_BYTES			4096
#define ETH_RX_NUM_NEXT_PAGE_BDS			2

#define ETH_TX_MIN_BDS_PER_NON_LSO_PKT				1
#define ETH_TX_MAX_BDS_PER_NON_LSO_PACKET			18
#define ETH_TX_MAX_LSO_HDR_NBD						4
#define ETH_TX_MIN_BDS_PER_LSO_PKT					3
#define ETH_TX_MIN_BDS_PER_TUNN_IPV6_WITH_EXT_PKT	3
#define ETH_TX_MIN_BDS_PER_IPV6_WITH_EXT_PKT		2
#define ETH_TX_MIN_BDS_PER_PKT_W_LOOPBACK_MODE		2
#define ETH_TX_MAX_NON_LSO_PKT_LEN                  (9700 - (4 + 12 + 8))
#define ETH_TX_MAX_LSO_HDR_BYTES                    510
#define ETH_TX_LSO_WINDOW_BDS_NUM                   18
#define ETH_TX_LSO_WINDOW_MIN_LEN                   9700
#define ETH_TX_MAX_LSO_PAYLOAD_LEN                  0xFFFF

#define ETH_NUM_STATISTIC_COUNTERS			MAX_NUM_VPORTS

#define ETH_RX_MAX_BUFF_PER_PKT             5

/* num of MAC/VLAN filters */
#define ETH_NUM_MAC_FILTERS					512
#define ETH_NUM_VLAN_FILTERS				512

/* approx. multicast constants */
#define ETH_MULTICAST_BIN_FROM_MAC_SEED	    0
#define ETH_MULTICAST_MAC_BINS				256
#define ETH_MULTICAST_MAC_BINS_IN_REGS		(ETH_MULTICAST_MAC_BINS / 32)

/*  ethernet vport update constants */
#define ETH_FILTER_RULES_COUNT				10
#define ETH_RSS_IND_TABLE_ENTRIES_NUM		128
#define ETH_RSS_KEY_SIZE_REGS			    10
#define ETH_RSS_ENGINE_NUM_K2               207
#define ETH_RSS_ENGINE_NUM_BB               127

/* TPA constants */
#define ETH_TPA_MAX_AGGS_NUM              64
#define ETH_TPA_CQE_START_LEN_LIST_SIZE   ETH_RX_MAX_BUFF_PER_PKT
#define ETH_TPA_CQE_CONT_LEN_LIST_SIZE    6
#define ETH_TPA_CQE_END_LEN_LIST_SIZE     4

/*
 * Interrupt coalescing TimeSet
 */
struct coalescing_timeset {
	u8 timeset;
	u8 valid /* Only if this flag is set, timeset will take effect */;
};

/*
 * Destination port mode
 */
enum dest_port_mode {
	DEST_PORT_PHY /* Send to physical port. */,
	DEST_PORT_LOOPBACK /* Send to loopback port. */,
	DEST_PORT_PHY_LOOPBACK /* Send to physical and loopback port. */,
	DEST_PORT_DROP /* Drop the packet in PBF. */,
	MAX_DEST_PORT_MODE
};

/*
 * Ethernet address type
 */
enum eth_addr_type {
	BROADCAST_ADDRESS,
	MULTICAST_ADDRESS,
	UNICAST_ADDRESS,
	UNKNOWN_ADDRESS,
	MAX_ETH_ADDR_TYPE
};

struct eth_tx_1st_bd_flags {
	u8 bitfields;
#define ETH_TX_1ST_BD_FLAGS_START_BD_MASK         0x1
#define ETH_TX_1ST_BD_FLAGS_START_BD_SHIFT        0
#define ETH_TX_1ST_BD_FLAGS_FORCE_VLAN_MODE_MASK  0x1
#define ETH_TX_1ST_BD_FLAGS_FORCE_VLAN_MODE_SHIFT 1
#define ETH_TX_1ST_BD_FLAGS_IP_CSUM_MASK          0x1
#define ETH_TX_1ST_BD_FLAGS_IP_CSUM_SHIFT         2
#define ETH_TX_1ST_BD_FLAGS_L4_CSUM_MASK          0x1
#define ETH_TX_1ST_BD_FLAGS_L4_CSUM_SHIFT         3
#define ETH_TX_1ST_BD_FLAGS_VLAN_INSERTION_MASK   0x1
#define ETH_TX_1ST_BD_FLAGS_VLAN_INSERTION_SHIFT  4
#define ETH_TX_1ST_BD_FLAGS_LSO_MASK              0x1
#define ETH_TX_1ST_BD_FLAGS_LSO_SHIFT             5
#define ETH_TX_1ST_BD_FLAGS_TUNN_IP_CSUM_MASK     0x1
#define ETH_TX_1ST_BD_FLAGS_TUNN_IP_CSUM_SHIFT    6
#define ETH_TX_1ST_BD_FLAGS_TUNN_L4_CSUM_MASK     0x1
#define ETH_TX_1ST_BD_FLAGS_TUNN_L4_CSUM_SHIFT    7
};

/*
 * The parsing information data for the first tx bd of a given packet.
 */
struct eth_tx_data_1st_bd {
	__le16 vlan /* VLAN to insert to packet (if needed). */;
		/* Number of BDs in packet. Should be at least 2 in non-LSO
		* packet and at least 3 in LSO (or Tunnel with IPv6+ext) packet.
		*/
	u8 nbds;
	struct eth_tx_1st_bd_flags bd_flags;
	__le16 bitfields;
#define ETH_TX_DATA_1ST_BD_TUNN_CFG_OVERRIDE_MASK  0x1
#define ETH_TX_DATA_1ST_BD_TUNN_CFG_OVERRIDE_SHIFT 0
#define ETH_TX_DATA_1ST_BD_RESERVED0_MASK          0x1
#define ETH_TX_DATA_1ST_BD_RESERVED0_SHIFT         1
#define ETH_TX_DATA_1ST_BD_FW_USE_ONLY_MASK        0x3FFF
#define ETH_TX_DATA_1ST_BD_FW_USE_ONLY_SHIFT       2
};

/*
 * The parsing information data for the second tx bd of a given packet.
 */
struct eth_tx_data_2nd_bd {
	__le16 tunn_ip_size;
	__le16 bitfields1;
#define ETH_TX_DATA_2ND_BD_TUNN_INNER_L2_HDR_SIZE_W_MASK  0xF
#define ETH_TX_DATA_2ND_BD_TUNN_INNER_L2_HDR_SIZE_W_SHIFT 0
#define ETH_TX_DATA_2ND_BD_TUNN_INNER_ETH_TYPE_MASK       0x3
#define ETH_TX_DATA_2ND_BD_TUNN_INNER_ETH_TYPE_SHIFT      4
#define ETH_TX_DATA_2ND_BD_DEST_PORT_MODE_MASK            0x3
#define ETH_TX_DATA_2ND_BD_DEST_PORT_MODE_SHIFT           6
#define ETH_TX_DATA_2ND_BD_START_BD_MASK                  0x1
#define ETH_TX_DATA_2ND_BD_START_BD_SHIFT                 8
#define ETH_TX_DATA_2ND_BD_TUNN_TYPE_MASK                 0x3
#define ETH_TX_DATA_2ND_BD_TUNN_TYPE_SHIFT                9
#define ETH_TX_DATA_2ND_BD_TUNN_INNER_IPV6_MASK           0x1
#define ETH_TX_DATA_2ND_BD_TUNN_INNER_IPV6_SHIFT          11
#define ETH_TX_DATA_2ND_BD_IPV6_EXT_MASK                  0x1
#define ETH_TX_DATA_2ND_BD_IPV6_EXT_SHIFT                 12
#define ETH_TX_DATA_2ND_BD_TUNN_IPV6_EXT_MASK             0x1
#define ETH_TX_DATA_2ND_BD_TUNN_IPV6_EXT_SHIFT            13
#define ETH_TX_DATA_2ND_BD_L4_UDP_MASK                    0x1
#define ETH_TX_DATA_2ND_BD_L4_UDP_SHIFT                   14
#define ETH_TX_DATA_2ND_BD_L4_PSEUDO_CSUM_MODE_MASK       0x1
#define ETH_TX_DATA_2ND_BD_L4_PSEUDO_CSUM_MODE_SHIFT      15
	__le16 bitfields2;
#define ETH_TX_DATA_2ND_BD_L4_HDR_START_OFFSET_W_MASK     0x1FFF
#define ETH_TX_DATA_2ND_BD_L4_HDR_START_OFFSET_W_SHIFT    0
#define ETH_TX_DATA_2ND_BD_RESERVED0_MASK                 0x7
#define ETH_TX_DATA_2ND_BD_RESERVED0_SHIFT                13
};

/*
 * Firmware data for L2-EDPM packet.
 */
struct eth_edpm_fw_data {
	struct eth_tx_data_1st_bd data_1st_bd
	    /* Parsing information data from the 1st BD. */;
	struct eth_tx_data_2nd_bd data_2nd_bd
	    /* Parsing information data from the 2nd BD. */;
	__le32 reserved;
};

/*
 * FW debug.
 */
struct eth_fast_path_cqe_fw_debug {
	u8 reserved0 /* FW reserved. */;
	u8 reserved1 /* FW reserved. */;
	__le16 reserved2 /* FW reserved. */;
};

struct tunnel_parsing_flags {
	u8 flags;
#define TUNNEL_PARSING_FLAGS_TYPE_MASK              0x3
#define TUNNEL_PARSING_FLAGS_TYPE_SHIFT             0
#define TUNNEL_PARSING_FLAGS_TENNANT_ID_EXIST_MASK  0x1
#define TUNNEL_PARSING_FLAGS_TENNANT_ID_EXIST_SHIFT 2
#define TUNNEL_PARSING_FLAGS_NEXT_PROTOCOL_MASK     0x3
#define TUNNEL_PARSING_FLAGS_NEXT_PROTOCOL_SHIFT    3
#define TUNNEL_PARSING_FLAGS_FIRSTHDRIPMATCH_MASK   0x1
#define TUNNEL_PARSING_FLAGS_FIRSTHDRIPMATCH_SHIFT  5
#define TUNNEL_PARSING_FLAGS_IPV4_FRAGMENT_MASK     0x1
#define TUNNEL_PARSING_FLAGS_IPV4_FRAGMENT_SHIFT    6
#define TUNNEL_PARSING_FLAGS_IPV4_OPTIONS_MASK      0x1
#define TUNNEL_PARSING_FLAGS_IPV4_OPTIONS_SHIFT     7
};

/*
 * Regular ETH Rx FP CQE.
 */
struct eth_fast_path_rx_reg_cqe {
	u8 type /* CQE type */;
	u8 bitfields;
#define ETH_FAST_PATH_RX_REG_CQE_RSS_HASH_TYPE_MASK  0x7
#define ETH_FAST_PATH_RX_REG_CQE_RSS_HASH_TYPE_SHIFT 0
#define ETH_FAST_PATH_RX_REG_CQE_TC_MASK             0xF
#define ETH_FAST_PATH_RX_REG_CQE_TC_SHIFT            3
#define ETH_FAST_PATH_RX_REG_CQE_RESERVED0_MASK      0x1
#define ETH_FAST_PATH_RX_REG_CQE_RESERVED0_SHIFT     7
	__le16 pkt_len /* Total packet length (from the parser) */;
	struct parsing_and_err_flags pars_flags
	    /* Parsing and error flags from the parser */;
	__le16 vlan_tag /* 802.1q VLAN tag */;
	__le32 rss_hash /* RSS hash result */;
	__le16 len_on_first_bd /* Number of bytes placed on first BD */;
	u8 placement_offset /* Offset of placement from BD start */;
	struct tunnel_parsing_flags tunnel_pars_flags /* Tunnel Parsing Flags */
	  ;
	u8 bd_num /* Number of BDs, used for packet */;
	u8 reserved[7];
	struct eth_fast_path_cqe_fw_debug fw_debug /* FW reserved. */;
	u8 reserved1[3];
	u8 flags;
#define ETH_FAST_PATH_RX_REG_CQE_VALID_MASK          0x1
#define ETH_FAST_PATH_RX_REG_CQE_VALID_SHIFT         0
#define ETH_FAST_PATH_RX_REG_CQE_VALID_TOGGLE_MASK   0x1
#define ETH_FAST_PATH_RX_REG_CQE_VALID_TOGGLE_SHIFT  1
#define ETH_FAST_PATH_RX_REG_CQE_RESERVED2_MASK      0x3F
#define ETH_FAST_PATH_RX_REG_CQE_RESERVED2_SHIFT     2
};

/*
 * TPA-continue ETH Rx FP CQE.
 */
struct eth_fast_path_rx_tpa_cont_cqe {
	u8 type /* CQE type */;
	u8 tpa_agg_index /* TPA aggregation index */;
	__le16 len_list[ETH_TPA_CQE_CONT_LEN_LIST_SIZE]
	    /* List of the segment sizes */;
	u8 reserved[5];
	u8 reserved1 /* FW reserved. */;
	__le16 reserved2[ETH_TPA_CQE_CONT_LEN_LIST_SIZE] /* FW reserved. */;
};

/*
 * TPA-end ETH Rx FP CQE .
 */
struct eth_fast_path_rx_tpa_end_cqe {
	u8 type /* CQE type */;
	u8 tpa_agg_index /* TPA aggregation index */;
	__le16 total_packet_len /* Total aggregated packet length */;
	u8 num_of_bds /* Total number of BDs comprising the packet */;
	u8 end_reason /* Aggregation end reason. Use enum eth_tpa_end_reason */
	  ;
	__le16 num_of_coalesced_segs /* Number of coalesced TCP segments */;
	__le32 ts_delta /* TCP timestamp delta */;
	__le16 len_list[ETH_TPA_CQE_END_LEN_LIST_SIZE]
	    /* List of the segment sizes */;
	u8 reserved1[3];
	u8 reserved2 /* FW reserved. */;
	__le16 reserved3[ETH_TPA_CQE_END_LEN_LIST_SIZE] /* FW reserved. */;
};

/*
 * TPA-start ETH Rx FP CQE.
 */
struct eth_fast_path_rx_tpa_start_cqe {
	u8 type /* CQE type */;
	u8 bitfields;
#define ETH_FAST_PATH_RX_TPA_START_CQE_RSS_HASH_TYPE_MASK  0x7
#define ETH_FAST_PATH_RX_TPA_START_CQE_RSS_HASH_TYPE_SHIFT 0
#define ETH_FAST_PATH_RX_TPA_START_CQE_TC_MASK             0xF
#define ETH_FAST_PATH_RX_TPA_START_CQE_TC_SHIFT            3
#define ETH_FAST_PATH_RX_TPA_START_CQE_RESERVED0_MASK      0x1
#define ETH_FAST_PATH_RX_TPA_START_CQE_RESERVED0_SHIFT     7
	__le16 seg_len /* Segment length (packetLen from the parser) */;
	struct parsing_and_err_flags pars_flags
	    /* Parsing and error flags from the parser */;
	__le16 vlan_tag /* 802.1q VLAN tag */;
	__le32 rss_hash /* RSS hash result */;
	__le16 len_on_first_bd /* Number of bytes placed on first BD */;
	u8 placement_offset /* Offset of placement from BD start */;
	struct tunnel_parsing_flags tunnel_pars_flags /* Tunnel Parsing Flags */
	  ;
	u8 tpa_agg_index /* TPA aggregation index */;
	u8 header_len /* Packet L2+L3+L4 header length */;
	__le16 ext_bd_len_list[ETH_TPA_CQE_START_LEN_LIST_SIZE]
	    /* Additional BDs length list. */;
	struct eth_fast_path_cqe_fw_debug fw_debug /* FW reserved. */;
};

/*
 * The L4 pseudo checksum mode for Ethernet
 */
enum eth_l4_pseudo_checksum_mode {
	ETH_L4_PSEUDO_CSUM_CORRECT_LENGTH
		/* Pseudo Header checksum on packet is calculated
		 * with the correct packet length field.
		*/
	   ,
	ETH_L4_PSEUDO_CSUM_ZERO_LENGTH
	    /* Pseudo Hdr checksum on packet is calc with zero len field. */
	   ,
	MAX_ETH_L4_PSEUDO_CHECKSUM_MODE
};

struct eth_rx_bd {
	struct regpair addr /* single continues buffer */;
};

/*
 * regular ETH Rx SP CQE
 */
struct eth_slow_path_rx_cqe {
	u8 type /* CQE type */;
	u8 ramrod_cmd_id;
	u8 error_flag;
	u8 reserved[25];
	__le16 echo;
	u8 reserved1;
	u8 flags;
#define ETH_SLOW_PATH_RX_CQE_VALID_MASK         0x1
#define ETH_SLOW_PATH_RX_CQE_VALID_SHIFT        0
#define ETH_SLOW_PATH_RX_CQE_VALID_TOGGLE_MASK  0x1
#define ETH_SLOW_PATH_RX_CQE_VALID_TOGGLE_SHIFT 1
#define ETH_SLOW_PATH_RX_CQE_RESERVED2_MASK     0x3F
#define ETH_SLOW_PATH_RX_CQE_RESERVED2_SHIFT    2
};

/*
 * union for all ETH Rx CQE types
 */
union eth_rx_cqe {
	struct eth_fast_path_rx_reg_cqe fast_path_regular /* Regular FP CQE */;
	struct eth_fast_path_rx_tpa_start_cqe fast_path_tpa_start
	    /* TPA-start CQE */;
	struct eth_fast_path_rx_tpa_cont_cqe fast_path_tpa_cont
	    /* TPA-continue CQE */;
	struct eth_fast_path_rx_tpa_end_cqe fast_path_tpa_end /* TPA-end CQE */
	  ;
	struct eth_slow_path_rx_cqe slow_path /* SP CQE */;
};

/*
 * ETH Rx CQE type
 */
enum eth_rx_cqe_type {
	ETH_RX_CQE_TYPE_UNUSED,
	ETH_RX_CQE_TYPE_REGULAR /* Regular FP ETH Rx CQE */,
	ETH_RX_CQE_TYPE_SLOW_PATH /* Slow path ETH Rx CQE */,
	ETH_RX_CQE_TYPE_TPA_START /* TPA start ETH Rx CQE */,
	ETH_RX_CQE_TYPE_TPA_CONT /* TPA Continue ETH Rx CQE */,
	ETH_RX_CQE_TYPE_TPA_END /* TPA end ETH Rx CQE */,
	MAX_ETH_RX_CQE_TYPE
};

/*
 * Wrapp for PD RX CQE used in order to cover full cache line when writing CQE
 */
struct eth_rx_pmd_cqe {
	union eth_rx_cqe cqe /* CQE data itself */;
	u8 reserved[ETH_RX_CQE_GAP];
};

/*
 * ETH Rx producers data
 */
struct eth_rx_prod_data {
	__le16 bd_prod /* BD producer */;
	__le16 cqe_prod /* CQE producer */;
	__le16 reserved;
	__le16 reserved1 /* FW reserved. */;
};

/*
 * Aggregation end reason.
 */
enum eth_tpa_end_reason {
	ETH_AGG_END_UNUSED,
	ETH_AGG_END_SP_UPDATE /* SP configuration update */,
	ETH_AGG_END_MAX_LEN
	    /* Maximum aggregation length or maximum buffer number used. */,
	ETH_AGG_END_LAST_SEG
	    /* TCP PSH flag or TCP payload length below continue threshold. */,
	ETH_AGG_END_TIMEOUT /* Timeout expiration. */,
	ETH_AGG_END_NOT_CONSISTENT,
	ETH_AGG_END_OUT_OF_ORDER,
	ETH_AGG_END_NON_TPA_SEG,
	MAX_ETH_TPA_END_REASON
};

/*
 * Eth Tunnel Type
 */
enum eth_tunn_type {
	ETH_TUNN_GENEVE /* GENEVE Tunnel. */,
	ETH_TUNN_TTAG /* T-Tag Tunnel. */,
	ETH_TUNN_GRE /* GRE Tunnel. */,
	ETH_TUNN_VXLAN /* VXLAN Tunnel. */,
	MAX_ETH_TUNN_TYPE
};

/*
 * The first tx bd of a given packet
 */
struct eth_tx_1st_bd {
	struct regpair addr /* Single continuous buffer */;
	__le16 nbytes /* Number of bytes in this BD. */;
	struct eth_tx_data_1st_bd data /* Parsing information data. */;
};

/*
 * The second tx bd of a given packet
 */
struct eth_tx_2nd_bd {
	struct regpair addr /* Single continuous buffer */;
	__le16 nbytes /* Number of bytes in this BD. */;
	struct eth_tx_data_2nd_bd data /* Parsing information data. */;
};

/*
 * The parsing information data for the third tx bd of a given packet.
 */
struct eth_tx_data_3rd_bd {
	__le16 lso_mss /* For LSO packet - the MSS in bytes. */;
	__le16 bitfields;
#define ETH_TX_DATA_3RD_BD_TCP_HDR_LEN_DW_MASK  0xF
#define ETH_TX_DATA_3RD_BD_TCP_HDR_LEN_DW_SHIFT 0
#define ETH_TX_DATA_3RD_BD_HDR_NBD_MASK         0xF
#define ETH_TX_DATA_3RD_BD_HDR_NBD_SHIFT        4
#define ETH_TX_DATA_3RD_BD_START_BD_MASK        0x1
#define ETH_TX_DATA_3RD_BD_START_BD_SHIFT       8
#define ETH_TX_DATA_3RD_BD_RESERVED0_MASK       0x7F
#define ETH_TX_DATA_3RD_BD_RESERVED0_SHIFT      9
	u8 tunn_l4_hdr_start_offset_w;
	u8 tunn_hdr_size_w;
};

/*
 * The third tx bd of a given packet
 */
struct eth_tx_3rd_bd {
	struct regpair addr /* Single continuous buffer */;
	__le16 nbytes /* Number of bytes in this BD. */;
	struct eth_tx_data_3rd_bd data /* Parsing information data. */;
};

/*
 * Complementary information for the regular tx bd of a given packet.
 */
struct eth_tx_data_bd {
	__le16 reserved0;
	__le16 bitfields;
#define ETH_TX_DATA_BD_RESERVED1_MASK  0xFF
#define ETH_TX_DATA_BD_RESERVED1_SHIFT 0
#define ETH_TX_DATA_BD_START_BD_MASK   0x1
#define ETH_TX_DATA_BD_START_BD_SHIFT  8
#define ETH_TX_DATA_BD_RESERVED2_MASK  0x7F
#define ETH_TX_DATA_BD_RESERVED2_SHIFT 9
	__le16 reserved3;
};

/*
 * The common regular TX BD ring element
 */
struct eth_tx_bd {
	struct regpair addr /* Single continuous buffer */;
	__le16 nbytes /* Number of bytes in this BD. */;
	struct eth_tx_data_bd data /* Complementary information. */;
};

union eth_tx_bd_types {
	struct eth_tx_1st_bd first_bd /* The first tx bd of a given packet */;
	struct eth_tx_2nd_bd second_bd /* The second tx bd of a given packet */
	  ;
	struct eth_tx_3rd_bd third_bd /* The third tx bd of a given packet */;
	struct eth_tx_bd reg_bd /* The common non-special bd */;
};

/*
 * Mstorm Queue Zone
 */
struct mstorm_eth_queue_zone {
	struct eth_rx_prod_data rx_producers;
	__le32 reserved[2];
};

/*
 * Ustorm Queue Zone
 */
struct ustorm_eth_queue_zone {
	struct coalescing_timeset int_coalescing_timeset
	    /* Rx interrupt coalescing TimeSet */;
	__le16 reserved[3];
};

/*
 * Ystorm Queue Zone
 */
struct ystorm_eth_queue_zone {
	struct coalescing_timeset int_coalescing_timeset
	    /* Tx interrupt coalescing TimeSet */;
	__le16 reserved[3];
};

/*
 * ETH doorbell data
 */
struct eth_db_data {
	u8 params;
#define ETH_DB_DATA_DEST_MASK         0x3
#define ETH_DB_DATA_DEST_SHIFT        0
#define ETH_DB_DATA_AGG_CMD_MASK      0x3
#define ETH_DB_DATA_AGG_CMD_SHIFT     2
#define ETH_DB_DATA_BYPASS_EN_MASK    0x1
#define ETH_DB_DATA_BYPASS_EN_SHIFT   4
#define ETH_DB_DATA_RESERVED_MASK     0x1
#define ETH_DB_DATA_RESERVED_SHIFT    5
#define ETH_DB_DATA_AGG_VAL_SEL_MASK  0x3
#define ETH_DB_DATA_AGG_VAL_SEL_SHIFT 6
	u8 agg_flags;
	__le16 bd_prod;
};

#endif /* __ETH_COMMON__ */