diff --git a/doc/guides/nics/mlx4.rst b/doc/guides/nics/mlx4.rst
index 98b9716..02cea79 100644
--- a/doc/guides/nics/mlx4.rst
+++ b/doc/guides/nics/mlx4.rst
@@ -515,3 +515,386 @@ devices managed by librte_pmd_mlx4.
       Port 3 Link Up - speed 40000 Mbps - full-duplex
       Done
       testpmd>
+
+Flow Limitations
+----------------
+
+- Flows are specified by rte_flow API (defined in **rte_flow.h**) which provides
+  a generic means to match specific traffic. Please refer to
+  http://dpdk.org/doc/guides/prog_guide/rte_flow.html
+- testpmd application **(app/test-pmd/)** has a command line interface where
+  flows can be specified. These flows are translated by testpmd
+  to rte_flow calls.
+- **drivers/net/mlx4/mlx4_flow.c** can be used as a reference to flow
+  limitations written in source code.
+
+General
+~~~~~~~
+
+.. code-block:: console
+
+    struct rte_flow_attr {
+        uint32_t group; /**< Priority group. */
+        uint32_t priority; /**< Priority level within group. */
+        uint32_t ingress:1; /**< Rule applies to ingress traffic. */
+        uint32_t egress:1; /**< Rule applies to egress traffic. */
+        uint32_t reserved:30; /**< Reserved, must be zero. */
+    }
+
+    struct rte_flow_attr *attr;
+
+- No support for mlx4 group rte_flow
+
+.. code-block:: console
+
+    if (attr->group)
+             print_err("groups are not supported");
+
+- No support for mlx4 rte_flow priority above 0xfff
+
+.. code-block:: console
+
+    if (attr->priority > 0xfff)
+             print_err("maximum priority level is 0xfff");
+
+- No support for mlx4 rte_flow egress filters
+
+.. code-block:: console
+
+    if (attr->egress)
+             print_err("egress is not supported");
+
+- Must specify mlx4 rte_flow ingress filters
+
+.. code-block:: console
+
+    if (!attr->ingress)
+             print_err("only ingress is supported");
+
+Flow rules filters
+~~~~~~~~~~~~~~~~~~
+
+Flow rules filters can be validated using testpmd **flow validate** syntax.
+
+L2 (ETH)
+^^^^^^^^
+
+This section documents flow rules limitations related to RTE_FLOW_ITEM_TYPE_ETH.
+It does not apply to an inner ETH used after VXLAN since mlx4 can't match those
+yet.
+
+.. code-block:: console
+
+    /**
+     * RTE_FLOW_ITEM_TYPE_ETH
+     *
+     * Matches an Ethernet header.
+     */
+    struct rte_flow_item_eth {
+    	struct ether_addr dst; /**< Destination MAC. */
+    	struct ether_addr src; /**< Source MAC. */
+    	rte_be16_t type; /**< EtherType. */
+    };
+
+    struct rte_flow_item_eth *mask;
+
+- Can only use real destination MAC.
+- EtherType is not taken into consideration.
+- Source MAC is not taken into consideration and should be set to 0
+
+.. code-block:: console
+
+    /**
+     * Summarize all src adrresses
+     **/
+    for (i = 0; i != sizeof(mask->src.addr_bytes); ++i)
+			sum_src += mask->src.addr_bytes[i];
+
+    if (sum_src)
+        print_err("mlx4 does not support source MAC matching");
+
+
+Using testpmd application - src mask must be 00:00:00:00:00:00
+otherwise the following command will fail.
+
+.. code-block:: console
+
+     testpmd> flow validate 1 ingress pattern eth
+              src spec 00:16:3e:2b:e6:47 src mask FF:FF:FF:FF:FF:FF
+              / end actions drop / end
+
+- Supports only full mask.
+- No support for partial masks, except in the specific case of matching
+  all multicast traffic (spec->dst and mask->dst equal to
+  01:00:00:00:00:00).
+
+.. code-block:: console
+
+    /**
+     * Summarize all dst adrresses
+     */
+    for (i = 0; i != sizeof(mask->dst.addr_bytes); ++i) {
+	sum_dst += mask->dst.addr_bytes[i];
+
+        if (sum_dst != (0xffui8 * ETHER_ADDR_LEN))
+            print_err("mlx4 does not support matching partial"
+                         " Ethernet fields");
+    }
+
+Using the following testpmd command with partial mask will fail.
+
+.. code-block:: console
+
+     testpmd> flow validate 1 ingress pattern eth
+              src spec 00:16:3e:2b:e6:47
+              dst spec 4A:11:6C:FA:60:D0 dst mask FF:00:FF:FF:FF:00
+              / end actions drop / end
+
+- When configured to run in promiscuous or all-multicast modes does
+  not support additional rules
+
+.. code-block:: console
+
+        if (flow->promisc || flow->allmulti)
+                print_err("mlx4 does not support additional matching"
+                        " criteria combined with indiscriminate"
+                        " matching on Ethernet headers");
+
+- Does not support the explicit exclusion of all multicast traffic
+
+.. code-block:: console
+
+    if (sum_dst == 1 && mask->dst.addr_bytes[0] == 1)
+        if (!(spec->dst.addr_bytes[0] & 1))
+            print_err("mlx4 does not support the explicit"
+            " exclusion of all multicast traffic");
+
+VLAN
+^^^^
+
+This section documents flow rules limitations related to
+RTE_FLOW_ITEM_TYPE_VLAN.
+
+.. code-block:: console
+
+    /**
+     * RTE_FLOW_ITEM_TYPE_VLAN
+     *
+     * Matches an 802.1Q/ad VLAN tag.
+     *
+     * This type normally follows either RTE_FLOW_ITEM_TYPE_ETH or
+     * RTE_FLOW_ITEM_TYPE_VLAN.
+     */
+    struct rte_flow_item_vlan {
+        rte_be16_t tpid; /**< Tag protocol identifier. */
+        rte_be16_t tci; /**< Tag control information. */
+    };
+
+    struct rte_flow_item_vlan mask;
+
+- TCI VID must be specified
+
+.. code-block:: console
+
+    if (!mask || !mask->tci)
+        print_err("mlx4 cannot match all VLAN traffic while excluding"
+            " non-VLAN traffic, TCI VID must be specified");
+
+- Does not support partial VLAN TCI VID matching
+
+.. code-block:: console
+
+    if (mask->tci != RTE_BE16(0x0fff))
+        print_err("mlx4 does not support partial TCI VID matching");
+
+L3 (IPv4)
+^^^^^^^^^
+
+This section documents flow rules limitations related to
+RTE_FLOW_ITEM_TYPE_IPV4.
+
+.. code-block:: console
+
+    /**
+     * RTE_FLOW_ITEM_TYPE_IPV4
+     *
+     * Matches an IPv4 header.
+     *
+     * Note: IPv4 options are handled by dedicated pattern items.
+     */
+    struct rte_flow_item_ipv4 {
+        struct ipv4_hdr hdr; /**< IPv4 header definition. */
+    };
+
+    struct rte_flow_item_ipv4 *mask;
+
+- Prerequisites: must follow eth dst spec definition.
+- Supports only zero or full one's source and destinatin masks.
+
+.. code-block:: console
+
+    if (mask &&
+        (uint32_t)(mask->hdr.src_addr + 1) > 1U ||
+        (uint32_t)(mask->hdr.dst_addr + 1) > 1U))
+            print_err("mlx4 does not support matching partial IPv4 fields");
+
+Using the following testpmd command with ipv4 prefix 16 will fail.
+
+.. code-block:: console
+
+     testpmd> flow validate 0 ingress pattern eth
+              src spec e4:1d:2d:2d:8d:22
+              dst spec 00:15:5D:10:8D:00 dst mask FF:FF:FF:FF:FF:FF
+              / ipv4 src spec 144.144.92.0 src prefix 16
+              / end actions drop / end
+
+L3 (IPv6)
+^^^^^^^^^
+
+mlx4 does not support IPv6 filters
+
+L4 UDP
+^^^^^^
+
+This section documents flow rules limitations related to RTE_FLOW_ITEM_TYPE_UDP.
+
+.. code-block:: console
+
+    /**
+     * RTE_FLOW_ITEM_TYPE_UDP.
+     *
+     * Matches a UDP header.
+     */
+    struct rte_flow_item_udp {
+        struct udp_hdr hdr; /**< UDP header definition. */
+    };
+
+    struct rte_flow_item_udp mask;
+
+- Prerequisites - must follow eth dst followed by IPv4 specs
+- Supports only zero or full source and destination ports masks.
+
+.. code-block:: console
+
+    if (mask &&
+        ((uint16_t)(mask->hdr.src_port + 1) > 1ui16 ||
+         (uint16_t)(mask->hdr.dst_port + 1) > 1ui16))
+        print_err("mlx4 does not support matching partial UDP fields");
+
+L4 TCP
+^^^^^^
+
+This section documents flow rules limitations related to RTE_FLOW_ITEM_TYPE_TCP.
+
+.. code-block:: console
+
+    /**
+     * RTE_FLOW_ITEM_TYPE_TCP.
+     *
+     * Matches a TCP header.
+     */
+    struct rte_flow_item_tcp {
+        struct tcp_hdr hdr; /**< TCP header definition. */
+    };
+
+    struct rte_flow_item_tcp *mask;
+
+- Prerequisites - must follow eth dst spec followed by IPv4 spec
+- Supports only zero or full source and destination ports masks.
+
+.. code-block:: console
+
+    if (mask &&
+        ((uint16_t)(mask->hdr.src_port + 1) > 1ui16 ||
+         (uint16_t)(mask->hdr.dst_port + 1) > 1ui16))
+        print_err("mlx4 does not support matching partial TCP fields");
+
+Flow actions
+~~~~~~~~~~~~
+
+RSS
+^^^
+
+RSS is performed on packets to spread them among several queues based on hash
+function calculation and according to provided parameters.
+
+.. code-block:: console
+
+    struct rte_eth_rss_conf {
+        uint8_t *rss_key;    /**< If not NULL, 40-byte hash key. */
+        uint8_t rss_key_len; /**< hash key length in bytes. */
+        uint64_t rss_hf;     /**< Hash functions to apply - see below. */
+    };
+
+    struct rte_flow_action_rss {
+        const struct rte_eth_rss_conf *rss_conf; /**< RSS parameters. */
+        uint16_t num; /**< Number of entries in queue[]. */
+        uint16_t queue[]; /**< Queues indices to use. */
+    };
+
+    struct rte_flow_action_rss *rss;
+
+- RSS hash is calculated on fixed packet fields including: L3 source and
+  destination addresses (ipv4 or ipv6) and L4 source and destination addresses
+  (upd or tcp ports)
+- Every Rx queue can be specified only once in RSS action
+
+- Only power of two number of queues is supported
+
+.. code-block:: console
+
+    if (!rte_is_power_of_2(rss->num))
+        print_err("for RSS, mlx4 requires the number of"
+              " queues to be a power of two");
+
+Using the following RSS action with three RSS ports (0 1 2) will fail.
+
+.. code-block:: console
+
+    testpmd> flow create 0  ingress pattern eth dst is f4:52:14:7a:59:81
+    / ipv4 / tcp / end actions rss queues 0 1 2 end / end
+
+- RSS hash key must be 40 characters
+
+.. code-block:: console
+
+    if (rss_conf->rss_key_len !=
+        sizeof(flow->rss->key))
+        print_err("mlx4 supports exactly one RSS hash key"
+                  " length: 40"
+
+- Packets must be distributed over consecutive queue indeces only
+
+.. code-block:: console
+
+    for (i = 1; i < rss->num; ++i)
+            if (rss->queue[i] - rss->queue[i - 1] != 1)
+                break;
+    if (i != rss->num)
+        "mlx4 requires RSS contexts to use"
+                " consecutive queue indices only");
+
+Using the following RSS action with non-consecutive ports (0 2) will fail.
+
+.. code-block:: console
+
+    testpmd> flow create 0  ingress pattern eth dst is f4:52:14:7a:59:81
+    / ipv4 / tcp / end actions rss queues 0 2 end / end
+
+- The first queue index specified in RSS context must be aligned
+  to context size
+
+.. code-block:: console
+
+    if (rss->queue[0] % rss->num)
+        print_err("mlx4 requires the first queue of a RSS"
+                " context to be aligned on a multiple"
+                " of the context size");
+
+Using the following RSS action with a fist queue index set as 1 - will fail.
+
+.. code-block:: console
+
+    testpmd> flow create 0  ingress pattern eth dst is f4:52:14:7a:59:81
+    / ipv4 / tcp / end actions rss queues 1 2 end / end
+
