diff --git a/include/infiniband/verbs.h b/include/infiniband/verbs.h
index cfa1156..624e1fc 100644
--- a/include/infiniband/verbs.h
+++ b/include/infiniband/verbs.h
@@ -116,7 +116,13 @@ enum ibv_device_cap_flags {
 	IBV_DEVICE_SRQ_RESIZE		= 1 << 13,
 	IBV_DEVICE_N_NOTIFY_CQ		= 1 << 14,
 	IBV_DEVICE_XRC			= 1 << 20,
-	IBV_DEVICE_MANAGED_FLOW_STEERING = 1 << 29
+	IBV_DEVICE_MANAGED_FLOW_STEERING = 1 << 29,
+	/* Devices should set IBV_DEVICE_RAW_PACKET_RX_HASH if they
+	* support IBV_QPT_RAW_PACKET QPs that can spread incoming traffic
+	* to different Receive Work Queues, by applying hash function
+	* on selected packet fields.
+	*/
+	IBV_DEVICE_RAW_PACKET_RX_HASH	= 1 << 30
 };
 
 enum ibv_atomic_cap {
@@ -241,6 +247,7 @@ struct ibv_async_event {
 	union {
 		struct ibv_cq  *cq;
 		struct ibv_qp  *qp;
+		struct ibv_wq  *wq;
 		struct ibv_srq *srq;
 		int		port_num;
 	} element;
@@ -300,6 +307,7 @@ struct ibv_wc {
 	uint32_t		vendor_err;
 	uint32_t		byte_len;
 	uint32_t		imm_data;	/* in network byte order */
+	/* WQ number for WC generated by WQ */
 	uint32_t		qp_num;
 	uint32_t		src_qp;
 	int			wc_flags;
@@ -481,6 +489,83 @@ struct ibv_srq_init_attr_ex {
 	struct ibv_cq	       *cq;
 };
 
+enum ibv_wq_type {
+	IBV_WQT_RQ,
+	IBV_WQT_SRQ
+};
+
+struct ibv_wq_init_attr {
+	/* Associated Context of the WQ */
+	void		       *wq_context;
+	enum ibv_wq_type	wq_type;
+	/* Valid for non IBV_WQT_SRQ WQ */
+	uint32_t		max_wr;
+	/* Valid for non IBV_WQT_SRQ WQ */
+	uint32_t		max_sge;
+	/* Protection domain WQ should be associated with */
+	struct	ibv_pd	       *pd;
+	/* CQ to be associated with the WQ */
+	struct	ibv_cq	       *cq;
+	/* SRQ handle if WQ is of type IBV_WQT_SRQ, otherwise NULL */
+	struct	ibv_srq	       *srq;
+	uint32_t		comp_mask;
+};
+
+enum ibv_wq_state {
+	IBV_WQS_RESET,
+	IBV_WQS_RDY,
+	IBV_WQS_ERR,
+	IBV_WQS_UNKNOWN
+};
+
+enum ibv_wq_attr_mask {
+	IBV_WQ_ATTR_STATE	= 1 << 0,
+	IBV_WQ_ATTR_CURR_STATE	= 1 << 1,
+	IBV_WQ_ATTR_RESERVED	= 1 << 2
+};
+
+struct ibv_wq_attr {
+	/* enum ibv_wq_attr_mask */
+	uint32_t		attr_mask;
+	/* Move the RQ to this state */
+	enum	ibv_wq_state	wq_state;
+	/* Assume this is the current RQ state */
+	enum	ibv_wq_state	curr_wq_state;
+};
+
+/*
+ * Receive Work Queue Indirection Table attributes
+*/
+struct ibv_rwq_ind_table_init_attr {
+	struct ibv_pd	       *pd;
+	/* Log, base 2, of Indirection table size */
+	uint32_t		log_rwq_ind_tbl_size;
+	/* Each entry is a pointer to Receive Work Queue */
+	struct ibv_wq	      **rwq_ind_tbl;
+	uint32_t		comp_mask;
+};
+
+/*
+ * Receive Work Queue Indirection Table attributes mask
+*/
+enum ibv_rwq_ind_table_attr_mask {
+	IBV_RWQ_IND_TABLE_ATTR_TABLE		= 1 << 0,
+	IBV_RWQ_IND_TABLE_ATTR_TABLE_SIZE	= 1 << 1,
+	IBV_RWQ_IND_TABLE_ATTR_RESERVED		= 1 << 2
+};
+
+/*
+ * Receive Work Queue Indirection Table attributes
+*/
+struct ibv_rwq_ind_table_attr {
+	/* enum ibv_rwq_ind_table_attr_mask */
+	uint32_t		attr_mask;
+	/* Log, base 2, of Indirection table size */
+	uint32_t		log_rwq_ind_tbl_size;
+	/* Each entry is a pointer to Receive Work Queue */
+	struct ibv_wq	      **rwq_ind_tbl;
+};
+
 enum ibv_qp_type {
 	IBV_QPT_RC = 2,
 	IBV_QPT_UC,
@@ -511,7 +596,50 @@ struct ibv_qp_init_attr {
 enum ibv_qp_init_attr_mask {
 	IBV_QP_INIT_ATTR_PD		= 1 << 0,
 	IBV_QP_INIT_ATTR_XRCD		= 1 << 1,
-	IBV_QP_INIT_ATTR_RESERVED	= 1 << 2
+	IBV_QP_INIT_ATTR_RX_HASH	= 1 << 2,
+	IBV_QP_INIT_ATTR_PORT		= 1 << 3,
+	IBV_QP_INIT_ATTR_RESERVED	= 1 << 4
+};
+
+/*
+ * RX Hash Function flags.
+*/
+enum ibv_rx_hash_function_flags {
+	IBV_EX_RX_HASH_FUNC_TOEPLTIZ	= 1 << 0,
+	IBV_EX_RX_HASH_FUNC_XOR		= 1 << 1
+};
+
+/*
+ * RX Hash flags, these flags allows to set which incoming packet field should
+ * participates in RX Hash. Each flag represent certain packet's field,
+ * when the flag is set the field that is represented by the flag will
+ * participate in RX Hash calculation.
+ * Notice: *IPV4 and *IPV6 flags can't be enabled together on the same QP
+ * and *TCP and *UDP flags can't be enabled together on the same QP.
+*/
+enum ibv_rx_hash_fields {
+	IBV_RX_HASH_SRC_IPV4		= 1 << 0,
+	IBV_RX_HASH_DST_IPV4		= 1 << 1,
+	IBV_RX_HASH_SRC_IPV6		= 1 << 2,
+	IBV_RX_HASH_DST_IPV6		= 1 << 3,
+	IBV_RX_HASH_SRC_PORT_TCP	= 1 << 4,
+	IBV_RX_HASH_DST_PORT_TCP	= 1 << 5,
+	IBV_RX_HASH_SRC_PORT_UDP	= 1 << 6,
+	IBV_RX_HASH_DST_PORT_UDP	= 1 << 7
+};
+
+/*
+ * RX Hash QP configuration. Sets hash function, hash types and
+ * Indirection table for QPs with enabled IBV_QP_INIT_ATTR_RX_HASH flag.
+*/
+struct ibv_rx_hash_conf {
+	/* enum ib_rx_hash_fnction */
+	uint8_t				rx_hash_function;
+	/* valid only for Toeplitz */
+	uint8_t                        *rx_hash_key;
+	/* enum ib_rx_hash_fields */
+	uint64_t			rx_hash_fields_mask;
+	struct ibv_rwq_ind_table       *rwq_ind_tbl;
 };
 
 struct ibv_qp_init_attr_ex {
@@ -526,6 +654,8 @@ struct ibv_qp_init_attr_ex {
 	uint32_t		comp_mask;
 	struct ibv_pd	       *pd;
 	struct ibv_xrcd	       *xrcd;
+	struct ibv_rx_hash_conf	       *rx_hash_conf;
+	uint8_t			port_num;
 };
 
 enum ibv_qp_open_attr_mask {
@@ -695,6 +825,51 @@ struct ibv_srq {
 	uint32_t		events_completed;
 };
 
+/*
+ * Work Queue. QP can be created without internal WQs "packaged" inside it,
+ * this QPs can be configured to use "external" WQ object as its
+ * receive/send queue.
+ * WQ associated (many to one) with Completion Queue it owns WQ properties
+ * (PD, WQ size etc).
+ * WQ of type IBV_RQ contains receive WQEs, in which case its PD serves
+ * scatter as well.
+ * WQ of type IBV_SRQ is associated (many to one) with IB_SRQT_BASIC SRQ,
+ * in which case it does not hold receive WQEs.
+ * QPs can be associated with IBV_S/RQ WQs via WQ Indirection Table
+ * (many to many).
+ */
+struct ibv_wq {
+	struct ibv_context     *context;
+	void		       *wq_context; /* Associated Context of the WQ */
+	uint32_t		handle;
+	/* Protection domain WQ should be associated with */
+	struct	ibv_pd	       *pd;
+	/* CQ to be associated with the Receive Queue (WQ) */
+	struct	ibv_cq	       *cq;
+	/* SRQ handle if WQ is to be associated with an SRQ, otherwise NULL */
+	struct	ibv_srq	       *srq;
+	uint32_t		wq_num;
+	enum ibv_wq_state       state;
+	enum ibv_wq_type	wq_type;
+	uint32_t		comp_mask;
+};
+
+/*
+ * Receive Work Queue Indirection Table.
+ * QPs with IBV_QP_INIT_ATTR_RX_HASH flag enabled use Indirection Table
+ * in order to distribute incoming packets between different
+ * Receive Work Queues. Associating Receive WQs with different CPU cores
+ * allows to workload the traffic between different CPU cores.
+ * The Indirection Table can contain only WQs of type IBV_RQ/IBV_SRQ.
+ * Notice: Multiple QP can point to the same Indirection Table.
+*/
+struct ibv_rwq_ind_table {
+	struct ibv_context     *context;
+	struct ibv_pd	       *pd;
+	int			ind_tbl_num;
+	uint32_t		comp_mask;
+};
+
 struct ibv_qp {
 	struct ibv_context     *context;
 	void		       *qp_context;
@@ -1355,6 +1530,11 @@ static inline int ibv_post_srq_recv(struct ibv_srq *srq,
 struct ibv_qp *ibv_create_qp(struct ibv_pd *pd,
 			     struct ibv_qp_init_attr *qp_init_attr);
 
+/*
+* The following QP init attributes are supported and required for
+* IBV_QPT_RAW_PACKET QP that supports packet spreading using RX Hash:
+* IBV_QP_INIT_ATTR_PD, IBV_QP_INIT_ATTR_RX_HASH, IBV_QP_INIT_ATTR_PORT
+*/
 static inline struct ibv_qp *
 ibv_create_qp_ex(struct ibv_context *context, struct ibv_qp_init_attr_ex *qp_init_attr_ex)
 {
@@ -1413,6 +1593,114 @@ int ibv_query_qp(struct ibv_qp *qp, struct ibv_qp_attr *attr,
  */
 int ibv_destroy_qp(struct ibv_qp *qp);
 
+/*
+ * ibv_create_wq - Creates a WQ associated with the specified protection
+ * domain.
+ * @context: ibv_context.
+ * @wq_init_attr: A list of initial attributes required to create the
+ * WQ. If WQ creation succeeds, then the attributes are updated to
+ * the actual capabilities of the created WQ.
+ *
+ * wq_init_attr->wq_cap.max_wr and wq_init_attr->max_sge determine
+ * the requested size of the RQ's WQ, and set to the actual values allocated
+ * on return.
+ * If ibv_create_wq() succeeds, then max_wr and max_sge will always be
+ * at least as large as the requested values.
+ *
+ * Return Value
+ * ibv_create_wq() returns a pointer to the created WQ, or NULL if the request
+ * fails.
+ */
+struct ibv_wq *ibv_create_wq(struct ibv_context *context,
+				struct ibv_wq_init_attr *wq_init_attr);
+
+/*
+ * ib_modify_wq - Modifies the attributes for the specified WQ.
+ * @wq: The WQ to modify.
+ * @wq_init_attr: On input, specifies the WQ attributes to modify.
+ * On output, the current values of selected WQ attributes are returned.
+ * @wq_attr_mask: A bit-mask used to specify which attributes of the WQ
+ * are being modified.
+ *
+ * Return Value
+ * ibv_modify_wq() returns 0 on success, or the value of errno
+ * on failure (which indicates the failure reason).
+ *
+ * WQ States Transition Properties
+ * -------------------------------
+ * IB_RQ WQ Type:
+ * Transition    Required Attributes    Optional Attributes
+ * ----------    --------------------   -------------------
+ * RESET2RDY     IBV_WQ_ATTR_STATE	IBV_WQ_ATTR_CURR_STATE
+ * RDY2RDY       IBV_WQ_ATTR_STATE	IBV_WQ_ATTR_CURR_STATE
+ *
+ * IB_SRQ WQ  Type:
+ * Transition    Required Attributes    Optional Attributes
+ * ----------    --------------------   -------------------
+ * RESET2RDY     IBV_WQ_ATTR_STATE	IBV_WQ_ATTR_CURR_STATE
+ * RESET2RDY     IBV_WQ_ATTR_STATE	IBV_WQ_ATTR_CURR_STATE
+ *
+*/
+int ibv_modify_wq(struct ibv_wq *wq, struct ibv_wq_attr *wq_attr);
+
+/*
+ * ibv_destroy_wq - Destroys the specified WQ.
+ * @ibv_wq: The WQ to destroy.
+ * Return Value
+ * ibv_destroy_wq() returns 0 on success, or the value of errno
+ * on failure (which indicates the failure reason).
+*/
+int ibv_destroy_wq(struct ibv_wq *wq);
+
+/*
+ * ib_post_rq_recv - Posts a list of work requests to the specified WQ
+ * of type IBV_RQ.
+ * @wq: The WQ to post the work request on.
+ * @recv_wr: A list of work requests to post on the receive queue.
+ * @bad_recv_wr: On an immediate failure, this parameter will reference
+ * the work request that failed to be posted on the WQ.
+ * Return Value
+ * ibv_post_wq_recv() returns 0 on success, or the value of errno
+ * on failure (which indicates the failure reason).
+*/
+static inline int ibv_post_wq_recv(struct ibv_wq *wq,
+				  struct ibv_recv_wr *recv_wr,
+				  struct ibv_recv_wr **bad_recv_wr);
+
+/*
+ * ibv_create_rwq_ind_table - Creates a RQ Indirection Table associated
+ * with the specified protection domain.
+ * @pd: The protection domain associated with the Indirection Table.
+ * @ibv_rwq_ind_table_init_attr: A list of initial attributes required to
+ * create the Indirection Table.
+ * If Indirection Table creation succeeds, then the attributes are updated to
+ * the actual capabilities of the created Indirection Table.
+ *
+ * Return Value
+ * ibv_create_rwq_ind_table returns a pointer to the created
+ * Indirection Table, or NULL if the request fails.
+ */
+struct ibv_wq_ind_tbl *ibv_create_rwq_ind_table(struct ibv_context *context,
+					struct ibv_rwq_ind_table_init_attr*
+					wq_ind_table_init_attr);
+/*
+ * ibv_modify_rwq_ind_table - Modify the specified Indirection Table.
+ * @wq_ind_table: The Indirection Table to modify.
+ * Return Value
+ * ibv_modify_rwq_ind_table() returns 0 on success, or the value of errno
+ * on failure (which indicates the failure reason).
+*/
+int ibv_modify_rwq_ind_table(struct ibv_rwq_ind_table *wq_ind_table);
+
+/*
+ * ibv_destroy_rwq_ind_table - Destroys the specified Indirection Table.
+ * @wq_ind_table: The Indirection Table to destroy.
+ * Return Value
+ * ibv_destroy_rwq_ind_table() returns 0 on success, or the value of errno
+ * on failure (which indicates the failure reason).
+*/
+int ibv_destroy_rwq_ind_table(struct ibv_rwq_ind_table *wq_ind_table);
+
 /**
  * ibv_post_send - Post a list of work requests to a send queue.
  *
