net/cxgbe: add devargs to control filtermode and filtermask
authorKarra Satwik <kaara.satwik@chelsio.com>
Wed, 11 Mar 2020 09:05:51 +0000 (14:35 +0530)
committerFerruh Yigit <ferruh.yigit@intel.com>
Wed, 18 Mar 2020 14:29:39 +0000 (15:29 +0100)
Apart from the 4-tuple (IP src/dst addresses and TCP/UDP src/dst
port addresses), there are only 40-bits available to match other
fields in packet headers. Not all combinations of packet header
fields can fit in the 40-bit tuple.

Currently, the combination of packet header fields to match are
configured via filterMode for LETCAM filters and filterMask for
HASH filters in firmware config files (t5/t6-config.txt). So, add
devargs to allow User to dynamically select the filterMode and
filterMask combination during runtime, without having to modify the
firmware config files and reflashing them onto the adapter. A table
of supported combinations is maintained by the driver to internally
translate the User specified devargs combination to hardware's internal
format before writing the requested combination to hardware

Signed-off-by: Karra Satwik <kaara.satwik@chelsio.com>
Signed-off-by: Rahul Lakkireddy <rahul.lakkireddy@chelsio.com>
doc/guides/nics/cxgbe.rst
drivers/net/cxgbe/base/adapter.h
drivers/net/cxgbe/base/t4fw_interface.h
drivers/net/cxgbe/cxgbe.h
drivers/net/cxgbe/cxgbe_ethdev.c
drivers/net/cxgbe/cxgbe_main.c

index cae78a3..54a4c13 100644 (file)
@@ -70,7 +70,7 @@ in :ref:`t5-nics` and :ref:`t6-nics`.
 Prerequisites
 -------------
 
-- Requires firmware version **1.23.4.0** and higher. Visit
+- Requires firmware version **1.24.11.0** and higher. Visit
   `Chelsio Download Center <http://service.chelsio.com>`_ to get latest firmware
   bundled with the latest Chelsio Unified Wire package.
 
@@ -141,6 +141,211 @@ CXGBE VF Only Runtime Options
   underlying Chelsio NICs. This enables multiple VFs on the same NIC
   to send traffic to each other even when the physical link is down.
 
+CXGBE PF Only Runtime Options
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+- ``filtermode`` (default **0**)
+
+  Apart from the 4-tuple (IP src/dst addresses and TCP/UDP src/dst port
+  addresses), there are only 40-bits available to match other fields in
+  packet headers. So, ``filtermode`` devarg allows user to dynamically
+  select a 40-bit supported match field combination for LETCAM (wildcard)
+  filters.
+
+  Default value of **0** makes driver pick the combination configured in
+  the firmware configuration file on the adapter.
+
+  The supported flags and their corresponding values are shown in table below.
+  These flags can be OR'd to create 1 of the multiple supported combinations
+  for LETCAM filters.
+
+        ==================      ======
+        FLAG                    VALUE
+        ==================      ======
+        Physical Port           0x1
+        PFVF                    0x2
+        Destination MAC         0x4
+        Ethertype               0x8
+        Inner VLAN              0x10
+        Outer VLAN              0x20
+        IP TOS                  0x40
+        IP Protocol             0x80
+        ==================      ======
+
+  The supported ``filtermode`` combinations and their corresponding OR'd
+  values are shown in table below.
+
+        +-----------------------------------+-----------+
+        | FILTERMODE COMBINATIONS           |   VALUE   |
+        +===================================+===========+
+        | Protocol, TOS, Outer VLAN, Port   |     0xE1  |
+        +-----------------------------------+-----------+
+        | Protocol, TOS, Outer VLAN         |     0xE0  |
+        +-----------------------------------+-----------+
+        | Protocol, TOS, Inner VLAN, Port   |     0xD1  |
+        +-----------------------------------+-----------+
+        | Protocol, TOS, Inner VLAN         |     0xD0  |
+        +-----------------------------------+-----------+
+        | Protocol, TOS, PFVF, Port         |     0xC3  |
+        +-----------------------------------+-----------+
+        | Protocol, TOS, PFVF               |     0xC2  |
+        +-----------------------------------+-----------+
+        | Protocol, TOS, Port               |     0xC1  |
+        +-----------------------------------+-----------+
+        | Protocol, TOS                     |     0xC0  |
+        +-----------------------------------+-----------+
+        | Protocol, Outer VLAN, Port        |     0xA1  |
+        +-----------------------------------+-----------+
+        | Protocol, Outer VLAN              |     0xA0  |
+        +-----------------------------------+-----------+
+        | Protocol, Inner VLAN, Port        |     0x91  |
+        +-----------------------------------+-----------+
+        | Protocol, Inner VLAN              |     0x90  |
+        +-----------------------------------+-----------+
+        | Protocol, Ethertype, DstMAC, Port |     0x8D  |
+        +-----------------------------------+-----------+
+        | Protocol, Ethertype, DstMAC       |     0x8C  |
+        +-----------------------------------+-----------+
+        | Protocol, Ethertype, Port         |     0x89  |
+        +-----------------------------------+-----------+
+        | Protocol, Ethertype               |     0x88  |
+        +-----------------------------------+-----------+
+        | Protocol, DstMAC, PFVF, Port      |     0x87  |
+        +-----------------------------------+-----------+
+        | Protocol, DstMAC, PFVF            |     0x86  |
+        +-----------------------------------+-----------+
+        | Protocol, DstMAC, Port            |     0x85  |
+        +-----------------------------------+-----------+
+        | Protocol, DstMAC                  |     0x84  |
+        +-----------------------------------+-----------+
+        | Protocol, PFVF, Port              |     0x83  |
+        +-----------------------------------+-----------+
+        | Protocol, PFVF                    |     0x82  |
+        +-----------------------------------+-----------+
+        | Protocol, Port                    |     0x81  |
+        +-----------------------------------+-----------+
+        | Protocol                          |     0x80  |
+        +-----------------------------------+-----------+
+        | TOS, Outer VLAN, Port             |     0x61  |
+        +-----------------------------------+-----------+
+        | TOS, Outer VLAN                   |     0x60  |
+        +-----------------------------------+-----------+
+        | TOS, Inner VLAN, Port             |     0x51  |
+        +-----------------------------------+-----------+
+        | TOS, Inner VLAN                   |     0x50  |
+        +-----------------------------------+-----------+
+        | TOS, Ethertype, DstMAC, Port      |     0x4D  |
+        +-----------------------------------+-----------+
+        | TOS, Ethertype, DstMAC            |     0x4C  |
+        +-----------------------------------+-----------+
+        | TOS, Ethertype, Port              |     0x49  |
+        +-----------------------------------+-----------+
+        | TOS, Ethertype                    |     0x48  |
+        +-----------------------------------+-----------+
+        | TOS, DstMAC, PFVF, Port           |     0x47  |
+        +-----------------------------------+-----------+
+        | TOS, DstMAC, PFVF                 |     0x46  |
+        +-----------------------------------+-----------+
+        | TOS, DstMAC, Port                 |     0x45  |
+        +-----------------------------------+-----------+
+        | TOS, DstMAC                       |     0x44  |
+        +-----------------------------------+-----------+
+        | TOS, PFVF, Port                   |     0x43  |
+        +-----------------------------------+-----------+
+        | TOS, PFVF                         |     0x42  |
+        +-----------------------------------+-----------+
+        | TOS, Port                         |     0x41  |
+        +-----------------------------------+-----------+
+        | TOS                               |     0x40  |
+        +-----------------------------------+-----------+
+        | Outer VLAN, Inner VLAN, Port      |     0x31  |
+        +-----------------------------------+-----------+
+        | Outer VLAN, Ethertype, Port       |     0x29  |
+        +-----------------------------------+-----------+
+        | Outer VLAN, Ethertype             |     0x28  |
+        +-----------------------------------+-----------+
+        | Outer VLAN, DstMAC, Port          |     0x25  |
+        +-----------------------------------+-----------+
+        | Outer VLAN, DstMAC                |     0x24  |
+        +-----------------------------------+-----------+
+        | Outer VLAN, Port                  |     0x21  |
+        +-----------------------------------+-----------+
+        | Outer VLAN                        |     0x20  |
+        +-----------------------------------+-----------+
+        | Inner VLAN, Ethertype, Port       |     0x19  |
+        +-----------------------------------+-----------+
+        | Inner VLAN, Ethertype             |     0x18  |
+        +-----------------------------------+-----------+
+        | Inner VLAN, DstMAC, Port          |     0x15  |
+        +-----------------------------------+-----------+
+        | Inner VLAN, DstMAC                |     0x14  |
+        +-----------------------------------+-----------+
+        | Inner VLAN, Port                  |     0x11  |
+        +-----------------------------------+-----------+
+        | Inner VLAN                        |     0x10  |
+        +-----------------------------------+-----------+
+        | Ethertype, DstMAC, Port           |     0xD   |
+        +-----------------------------------+-----------+
+        | Ethertype, DstMAC                 |     0xC   |
+        +-----------------------------------+-----------+
+        | Ethertype, PFVF, Port             |     0xB   |
+        +-----------------------------------+-----------+
+        | Ethertype, PFVF                   |     0xA   |
+        +-----------------------------------+-----------+
+        | Ethertype, Port                   |     0x9   |
+        +-----------------------------------+-----------+
+        | Ethertype                         |     0x8   |
+        +-----------------------------------+-----------+
+        | DstMAC, PFVF, Port                |     0x7   |
+        +-----------------------------------+-----------+
+        | DstMAC, PFVF                      |     0x6   |
+        +-----------------------------------+-----------+
+        | DstMAC, Port                      |     0x5   |
+        +-----------------------------------+-----------+
+        | Destination MAC                   |     0x4   |
+        +-----------------------------------+-----------+
+        | PFVF, Port                        |     0x3   |
+        +-----------------------------------+-----------+
+        | PFVF                              |     0x2   |
+        +-----------------------------------+-----------+
+        | Physical Port                     |     0x1   +
+        +-----------------------------------+-----------+
+
+  For example, to enable matching ``ethertype`` field in Ethernet
+  header, and ``protocol`` field in IPv4 header, the ``filtermode``
+  combination must be given as:
+
+  .. code-block:: console
+
+     testpmd -w 02:00.4,filtermode=0x88 -- -i
+
+- ``filtermask`` (default **0**)
+
+  ``filtermask`` devarg works similar to ``filtermode``, but is used
+  to configure a filter mode combination for HASH (exact-match) filters.
+
+  .. note::
+
+     The combination chosen for ``filtermask`` devarg **must be a subset** of
+     the combination chosen for ``filtermode`` devarg.
+
+  Default value of **0** makes driver pick the combination configured in
+  the firmware configuration file on the adapter.
+
+  Note that the filter rule will only be inserted in HASH region, if the
+  rule contains **all** the fields specified in the ``filtermask`` combination.
+  Otherwise, the filter rule will get inserted in LETCAM region.
+
+  The same combination list explained in the tables in ``filtermode`` devarg
+  section earlier applies for ``filtermask`` devarg, as well.
+
+  For example, to enable matching only protocol field in IPv4 header, the
+  ``filtermask`` combination must be given as:
+
+  .. code-block:: console
+
+     testpmd -w 02:00.4,filtermode=0x88,filtermask=0x80 -- -i
+
 .. _driver-compilation:
 
 Driver compilation and testing
@@ -215,7 +420,7 @@ Unified Wire package for Linux operating system are as follows:
 
    .. code-block:: console
 
-      firmware-version: 1.23.4.0, TP 0.1.23.2
+      firmware-version: 1.24.11.0, TP 0.1.23.2
 
 Running testpmd
 ~~~~~~~~~~~~~~~
@@ -273,7 +478,7 @@ devices managed by librte_pmd_cxgbe in Linux operating system.
       EAL:   PCI memory mapped at 0x7fd7c0200000
       EAL:   PCI memory mapped at 0x7fd77cdfd000
       EAL:   PCI memory mapped at 0x7fd7c10b7000
-      PMD: rte_cxgbe_pmd: fw: 1.23.4.0, TP: 0.1.23.2
+      PMD: rte_cxgbe_pmd: fw: 1.24.11.0, TP: 0.1.23.2
       PMD: rte_cxgbe_pmd: Coming up as MASTER: Initializing adapter
       Interactive-mode selected
       Configuring Port 0 (socket 0)
@@ -379,7 +584,7 @@ virtual functions.
       [...]
       EAL: PCI device 0000:02:01.0 on NUMA socket 0
       EAL:   probe driver: 1425:5803 net_cxgbevf
-      PMD: rte_cxgbe_pmd: Firmware version: 1.23.4.0
+      PMD: rte_cxgbe_pmd: Firmware version: 1.24.11.0
       PMD: rte_cxgbe_pmd: TP Microcode version: 0.1.23.2
       PMD: rte_cxgbe_pmd: Chelsio rev 0
       PMD: rte_cxgbe_pmd: No bootstrap loaded
@@ -387,7 +592,7 @@ virtual functions.
       PMD: rte_cxgbe_pmd:  0000:02:01.0 Chelsio rev 0 1G/10GBASE-SFP
       EAL: PCI device 0000:02:01.1 on NUMA socket 0
       EAL:   probe driver: 1425:5803 net_cxgbevf
-      PMD: rte_cxgbe_pmd: Firmware version: 1.23.4.0
+      PMD: rte_cxgbe_pmd: Firmware version: 1.24.11.0
       PMD: rte_cxgbe_pmd: TP Microcode version: 0.1.23.2
       PMD: rte_cxgbe_pmd: Chelsio rev 0
       PMD: rte_cxgbe_pmd: No bootstrap loaded
@@ -465,7 +670,7 @@ Unified Wire package for FreeBSD operating system are as follows:
 
    .. code-block:: console
 
-      dev.t5nex.0.firmware_version: 1.23.4.0
+      dev.t5nex.0.firmware_version: 1.24.11.0
 
 Running testpmd
 ~~~~~~~~~~~~~~~
@@ -583,7 +788,7 @@ devices managed by librte_pmd_cxgbe in FreeBSD operating system.
       EAL:   PCI memory mapped at 0x8007ec000
       EAL:   PCI memory mapped at 0x842800000
       EAL:   PCI memory mapped at 0x80086c000
-      PMD: rte_cxgbe_pmd: fw: 1.23.4.0, TP: 0.1.23.2
+      PMD: rte_cxgbe_pmd: fw: 1.24.11.0, TP: 0.1.23.2
       PMD: rte_cxgbe_pmd: Coming up as MASTER: Initializing adapter
       Interactive-mode selected
       Configuring Port 0 (socket 0)
index ae318cc..62de35c 100644 (file)
@@ -309,6 +309,8 @@ struct adapter_devargs {
        bool keep_ovlan;
        bool force_link_up;
        bool tx_mode_latency;
+       u32 filtermode;
+       u32 filtermask;
 };
 
 struct adapter {
index 46d087a..0032178 100644 (file)
@@ -674,12 +674,16 @@ enum fw_params_mnem {
 
 #define S_FW_PARAMS_PARAM_FILTER_MODE 16
 #define M_FW_PARAMS_PARAM_FILTER_MODE 0xffff
+#define V_FW_PARAMS_PARAM_FILTER_MODE(x)          \
+       ((x) << S_FW_PARAMS_PARAM_FILTER_MODE)
 #define G_FW_PARAMS_PARAM_FILTER_MODE(x)          \
        (((x) >> S_FW_PARAMS_PARAM_FILTER_MODE) & \
        M_FW_PARAMS_PARAM_FILTER_MODE)
 
 #define S_FW_PARAMS_PARAM_FILTER_MASK 0
 #define M_FW_PARAMS_PARAM_FILTER_MASK 0xffff
+#define V_FW_PARAMS_PARAM_FILTER_MASK(x)          \
+       ((x) << S_FW_PARAMS_PARAM_FILTER_MASK)
 #define G_FW_PARAMS_PARAM_FILTER_MASK(x)          \
        (((x) >> S_FW_PARAMS_PARAM_FILTER_MASK) & \
        M_FW_PARAMS_PARAM_FILTER_MASK)
@@ -725,6 +729,7 @@ enum fw_params_param_dmaq {
 };
 
 enum fw_params_param_dev_filter {
+       FW_PARAM_DEV_FILTER_VNIC_MODE   = 0x00,
        FW_PARAM_DEV_FILTER_MODE_MASK   = 0x01,
 };
 
index 75a2e99..0bf6061 100644 (file)
                           DEV_RX_OFFLOAD_SCATTER | \
                           DEV_RX_OFFLOAD_RSS_HASH)
 
+/* Devargs filtermode and filtermask representation */
+enum cxgbe_devargs_filter_mode_flags {
+       CXGBE_DEVARGS_FILTER_MODE_PHYSICAL_PORT = (1 << 0),
+       CXGBE_DEVARGS_FILTER_MODE_PF_VF = (1 << 1),
+
+       CXGBE_DEVARGS_FILTER_MODE_ETHERNET_DSTMAC = (1 << 2),
+       CXGBE_DEVARGS_FILTER_MODE_ETHERNET_ETHTYPE = (1 << 3),
+       CXGBE_DEVARGS_FILTER_MODE_VLAN_INNER = (1 << 4),
+       CXGBE_DEVARGS_FILTER_MODE_VLAN_OUTER = (1 << 5),
+       CXGBE_DEVARGS_FILTER_MODE_IP_TOS = (1 << 6),
+       CXGBE_DEVARGS_FILTER_MODE_IP_PROTOCOL = (1 << 7),
+       CXGBE_DEVARGS_FILTER_MODE_MAX = (1 << 8),
+};
+
+enum cxgbe_filter_vnic_mode {
+       CXGBE_FILTER_VNIC_MODE_NONE,
+       CXGBE_FILTER_VNIC_MODE_PFVF,
+       CXGBE_FILTER_VNIC_MODE_OVLAN,
+};
 
 /* Common PF and VF devargs */
 #define CXGBE_DEVARG_CMN_KEEP_OVLAN "keep_ovlan"
 /* VF only devargs */
 #define CXGBE_DEVARG_VF_FORCE_LINK_UP "force_link_up"
 
+/* Filter Mode/Mask devargs */
+#define CXGBE_DEVARG_PF_FILTER_MODE "filtermode"
+#define CXGBE_DEVARG_PF_FILTER_MASK "filtermask"
+
 bool cxgbe_force_linkup(struct adapter *adap);
 int cxgbe_probe(struct adapter *adapter);
 int cxgbevf_probe(struct adapter *adapter);
index 51b63ef..1deee2f 100644 (file)
@@ -1244,7 +1244,9 @@ RTE_PMD_REGISTER_PCI_TABLE(net_cxgbe, cxgb4_pci_tbl);
 RTE_PMD_REGISTER_KMOD_DEP(net_cxgbe, "* igb_uio | uio_pci_generic | vfio-pci");
 RTE_PMD_REGISTER_PARAM_STRING(net_cxgbe,
                              CXGBE_DEVARG_CMN_KEEP_OVLAN "=<0|1> "
-                             CXGBE_DEVARG_CMN_TX_MODE_LATENCY "=<0|1> ");
+                             CXGBE_DEVARG_CMN_TX_MODE_LATENCY "=<0|1> "
+                             CXGBE_DEVARG_PF_FILTER_MODE "=<uint32> "
+                             CXGBE_DEVARG_PF_FILTER_MASK "=<uint32> ");
 
 RTE_INIT(cxgbe_init_log)
 {
index df54e54..a541d95 100644 (file)
 #include "smt.h"
 #include "mps_tcam.h"
 
+static const u16 cxgbe_filter_mode_features[] = {
+       (F_FRAGMENTATION | F_MPSHITTYPE | F_MACMATCH | F_ETHERTYPE |
+        F_PROTOCOL | F_PORT),
+       (F_FRAGMENTATION | F_MPSHITTYPE | F_MACMATCH | F_ETHERTYPE |
+        F_PROTOCOL | F_FCOE),
+       (F_FRAGMENTATION | F_MPSHITTYPE | F_MACMATCH | F_ETHERTYPE | F_TOS |
+        F_PORT),
+       (F_FRAGMENTATION | F_MPSHITTYPE | F_MACMATCH | F_ETHERTYPE | F_TOS |
+        F_FCOE),
+       (F_FRAGMENTATION | F_MPSHITTYPE | F_MACMATCH | F_ETHERTYPE | F_PORT |
+        F_FCOE),
+       (F_FRAGMENTATION | F_MPSHITTYPE | F_MACMATCH | F_PROTOCOL | F_TOS |
+        F_PORT | F_FCOE),
+       (F_FRAGMENTATION | F_MPSHITTYPE | F_MACMATCH | F_PROTOCOL | F_VLAN |
+        F_FCOE),
+       (F_FRAGMENTATION | F_MPSHITTYPE | F_MACMATCH | F_PROTOCOL | F_VNIC_ID |
+        F_FCOE),
+       (F_FRAGMENTATION | F_MPSHITTYPE | F_MACMATCH | F_TOS | F_VLAN |
+        F_FCOE),
+       (F_FRAGMENTATION | F_MPSHITTYPE | F_MACMATCH | F_TOS | F_VNIC_ID |
+        F_FCOE),
+       (F_FRAGMENTATION | F_MPSHITTYPE | F_MACMATCH | F_VLAN | F_PORT |
+        F_FCOE),
+       (F_FRAGMENTATION | F_MPSHITTYPE | F_MACMATCH | F_VNIC_ID | F_PORT |
+        F_FCOE),
+       (F_FRAGMENTATION | F_MPSHITTYPE | F_ETHERTYPE | F_PROTOCOL | F_TOS |
+        F_PORT | F_FCOE),
+       (F_FRAGMENTATION | F_MPSHITTYPE | F_ETHERTYPE | F_VLAN | F_PORT),
+       (F_FRAGMENTATION | F_MPSHITTYPE | F_ETHERTYPE | F_VLAN | F_FCOE),
+       (F_FRAGMENTATION | F_MPSHITTYPE | F_ETHERTYPE | F_VNIC_ID | F_PORT),
+       (F_FRAGMENTATION | F_MPSHITTYPE | F_ETHERTYPE | F_VNIC_ID | F_FCOE),
+       (F_FRAGMENTATION | F_MPSHITTYPE | F_PROTOCOL | F_TOS | F_VLAN | F_PORT),
+       (F_FRAGMENTATION | F_MPSHITTYPE | F_PROTOCOL | F_TOS | F_VLAN | F_FCOE),
+       (F_FRAGMENTATION | F_MPSHITTYPE | F_PROTOCOL | F_TOS | F_VNIC_ID |
+        F_PORT),
+       (F_FRAGMENTATION | F_MPSHITTYPE | F_PROTOCOL | F_TOS | F_VNIC_ID |
+        F_FCOE),
+       (F_FRAGMENTATION | F_MPSHITTYPE | F_PROTOCOL | F_VLAN | F_PORT |
+        F_FCOE),
+       (F_FRAGMENTATION | F_MPSHITTYPE | F_PROTOCOL | F_VNIC_ID | F_PORT |
+        F_FCOE),
+       (F_FRAGMENTATION | F_MPSHITTYPE | F_TOS | F_VLAN | F_PORT | F_FCOE),
+       (F_FRAGMENTATION | F_MPSHITTYPE | F_TOS | F_VNIC_ID | F_PORT | F_FCOE),
+       (F_FRAGMENTATION | F_MPSHITTYPE | F_VLAN | F_VNIC_ID | F_FCOE),
+       (F_FRAGMENTATION | F_MACMATCH | F_ETHERTYPE | F_PROTOCOL | F_PORT |
+        F_FCOE),
+       (F_FRAGMENTATION | F_MACMATCH | F_ETHERTYPE | F_TOS | F_PORT | F_FCOE),
+       (F_FRAGMENTATION | F_MACMATCH | F_PROTOCOL | F_VLAN | F_PORT | F_FCOE),
+       (F_FRAGMENTATION | F_MACMATCH | F_PROTOCOL | F_VNIC_ID | F_PORT |
+        F_FCOE),
+       (F_FRAGMENTATION | F_MACMATCH | F_TOS | F_VLAN | F_PORT | F_FCOE),
+       (F_FRAGMENTATION | F_MACMATCH | F_TOS | F_VNIC_ID | F_PORT | F_FCOE),
+       (F_FRAGMENTATION | F_ETHERTYPE | F_VLAN | F_PORT | F_FCOE),
+       (F_FRAGMENTATION | F_ETHERTYPE | F_VNIC_ID | F_PORT | F_FCOE),
+       (F_FRAGMENTATION | F_PROTOCOL | F_TOS | F_VLAN | F_FCOE),
+       (F_FRAGMENTATION | F_PROTOCOL | F_TOS | F_VNIC_ID | F_FCOE),
+       (F_FRAGMENTATION | F_VLAN | F_VNIC_ID | F_PORT | F_FCOE),
+       (F_MPSHITTYPE | F_MACMATCH | F_ETHERTYPE | F_PROTOCOL | F_PORT |
+        F_FCOE),
+       (F_MPSHITTYPE | F_MACMATCH | F_ETHERTYPE | F_TOS | F_PORT | F_FCOE),
+       (F_MPSHITTYPE | F_MACMATCH | F_PROTOCOL | F_VLAN | F_PORT),
+       (F_MPSHITTYPE | F_MACMATCH | F_PROTOCOL | F_VNIC_ID | F_PORT),
+       (F_MPSHITTYPE | F_MACMATCH | F_TOS | F_VLAN | F_PORT),
+       (F_MPSHITTYPE | F_MACMATCH | F_TOS | F_VNIC_ID | F_PORT),
+       (F_MPSHITTYPE | F_ETHERTYPE | F_VLAN | F_PORT | F_FCOE),
+       (F_MPSHITTYPE | F_ETHERTYPE | F_VNIC_ID | F_PORT | F_FCOE),
+       (F_MPSHITTYPE | F_PROTOCOL | F_TOS | F_VLAN | F_PORT | F_FCOE),
+       (F_MPSHITTYPE | F_PROTOCOL | F_TOS | F_VNIC_ID | F_PORT | F_FCOE),
+       (F_MPSHITTYPE | F_VLAN | F_VNIC_ID | F_PORT),
+};
+
 /**
  * Allocate a chunk of memory. The allocated memory is cleared.
  */
@@ -687,6 +758,19 @@ static int check_devargs_handler(const char *key, const char *value, void *p)
                }
        }
 
+       if (!strncmp(key, CXGBE_DEVARG_PF_FILTER_MODE, strlen(key)) ||
+           !strncmp(key, CXGBE_DEVARG_PF_FILTER_MASK, strlen(key))) {
+               u32 *dst_val = (u32 *)p;
+               char *endptr = NULL;
+               u32 arg_val;
+
+               arg_val = strtoul(value, &endptr, 16);
+               if (errno || endptr == value)
+                       return -EINVAL;
+
+               *dst_val = arg_val;
+       }
+
        return 0;
 }
 
@@ -732,6 +816,24 @@ static void cxgbe_get_devargs_int(struct adapter *adap, bool *dst,
        *dst = devarg_value;
 }
 
+static void cxgbe_get_devargs_u32(struct adapter *adap, u32 *dst,
+                                 const char *key, u32 default_value)
+{
+       struct rte_pci_device *pdev = adap->pdev;
+       u32 devarg_value = default_value;
+       int ret;
+
+       *dst = default_value;
+       if (!pdev)
+               return;
+
+       ret = cxgbe_get_devargs(pdev->device.devargs, key, &devarg_value);
+       if (ret)
+               return;
+
+       *dst = devarg_value;
+}
+
 void cxgbe_process_devargs(struct adapter *adap)
 {
        cxgbe_get_devargs_int(adap, &adap->devargs.keep_ovlan,
@@ -740,6 +842,10 @@ void cxgbe_process_devargs(struct adapter *adap)
                              CXGBE_DEVARG_CMN_TX_MODE_LATENCY, false);
        cxgbe_get_devargs_int(adap, &adap->devargs.force_link_up,
                              CXGBE_DEVARG_VF_FORCE_LINK_UP, false);
+       cxgbe_get_devargs_u32(adap, &adap->devargs.filtermode,
+                             CXGBE_DEVARG_PF_FILTER_MODE, 0);
+       cxgbe_get_devargs_u32(adap, &adap->devargs.filtermask,
+                             CXGBE_DEVARG_PF_FILTER_MASK, 0);
 }
 
 static void configure_vlan_types(struct adapter *adapter)
@@ -776,6 +882,134 @@ static void configure_vlan_types(struct adapter *adapter)
                               V_RM_OVLAN(!adapter->devargs.keep_ovlan));
 }
 
+static int cxgbe_get_filter_vnic_mode_from_devargs(u32 val)
+{
+       u32 vnic_mode;
+
+       vnic_mode = val & (CXGBE_DEVARGS_FILTER_MODE_PF_VF |
+                          CXGBE_DEVARGS_FILTER_MODE_VLAN_OUTER);
+       if (vnic_mode) {
+               switch (vnic_mode) {
+               case CXGBE_DEVARGS_FILTER_MODE_VLAN_OUTER:
+                       return CXGBE_FILTER_VNIC_MODE_OVLAN;
+               case CXGBE_DEVARGS_FILTER_MODE_PF_VF:
+                       return CXGBE_FILTER_VNIC_MODE_PFVF;
+               default:
+                       return -EINVAL;
+               }
+       }
+
+       return CXGBE_FILTER_VNIC_MODE_NONE;
+}
+
+static int cxgbe_get_filter_mode_from_devargs(u32 val, bool closest_match)
+{
+       int vnic_mode, fmode = 0;
+       bool found = false;
+       u8 i;
+
+       if (val >= CXGBE_DEVARGS_FILTER_MODE_MAX) {
+               pr_err("Unsupported flags set in filter mode. Must be < 0x%x\n",
+                      CXGBE_DEVARGS_FILTER_MODE_MAX);
+               return -ERANGE;
+       }
+
+       vnic_mode = cxgbe_get_filter_vnic_mode_from_devargs(val);
+       if (vnic_mode < 0) {
+               pr_err("Unsupported Vnic-mode, more than 1 Vnic-mode selected\n");
+               return vnic_mode;
+       }
+
+       if (vnic_mode)
+               fmode |= F_VNIC_ID;
+       if (val & CXGBE_DEVARGS_FILTER_MODE_PHYSICAL_PORT)
+               fmode |= F_PORT;
+       if (val & CXGBE_DEVARGS_FILTER_MODE_ETHERNET_DSTMAC)
+               fmode |= F_MACMATCH;
+       if (val & CXGBE_DEVARGS_FILTER_MODE_ETHERNET_ETHTYPE)
+               fmode |= F_ETHERTYPE;
+       if (val & CXGBE_DEVARGS_FILTER_MODE_VLAN_INNER)
+               fmode |= F_VLAN;
+       if (val & CXGBE_DEVARGS_FILTER_MODE_IP_TOS)
+               fmode |= F_TOS;
+       if (val & CXGBE_DEVARGS_FILTER_MODE_IP_PROTOCOL)
+               fmode |= F_PROTOCOL;
+
+       for (i = 0; i < ARRAY_SIZE(cxgbe_filter_mode_features); i++) {
+               if ((cxgbe_filter_mode_features[i] & fmode) == fmode) {
+                       found = true;
+                       break;
+               }
+       }
+
+       if (!found)
+               return -EINVAL;
+
+       return closest_match ? cxgbe_filter_mode_features[i] : fmode;
+}
+
+static int configure_filter_mode_mask(struct adapter *adap)
+{
+       u32 params[2], val[2], nparams = 0;
+       int ret;
+
+       if (!adap->devargs.filtermode && !adap->devargs.filtermask)
+               return 0;
+
+       if (!adap->devargs.filtermode || !adap->devargs.filtermask) {
+               pr_err("Unsupported, Provide both filtermode and filtermask devargs\n");
+               return -EINVAL;
+       }
+
+       if (adap->devargs.filtermask & ~adap->devargs.filtermode) {
+               pr_err("Unsupported, filtermask (0x%x) must be subset of filtermode (0x%x)\n",
+                      adap->devargs.filtermask, adap->devargs.filtermode);
+
+               return -EINVAL;
+       }
+
+       params[0] = CXGBE_FW_PARAM_DEV(FILTER) |
+                   V_FW_PARAMS_PARAM_Y(FW_PARAM_DEV_FILTER_MODE_MASK);
+
+       ret = cxgbe_get_filter_mode_from_devargs(adap->devargs.filtermode,
+                                                true);
+       if (ret < 0) {
+               pr_err("Unsupported filtermode devargs combination:0x%x\n",
+                      adap->devargs.filtermode);
+               return ret;
+       }
+
+       val[0] = V_FW_PARAMS_PARAM_FILTER_MODE(ret);
+
+       ret = cxgbe_get_filter_mode_from_devargs(adap->devargs.filtermask,
+                                                false);
+       if (ret < 0) {
+               pr_err("Unsupported filtermask devargs combination:0x%x\n",
+                      adap->devargs.filtermask);
+               return ret;
+       }
+
+       val[0] |= V_FW_PARAMS_PARAM_FILTER_MASK(ret);
+
+       nparams++;
+
+       ret = cxgbe_get_filter_vnic_mode_from_devargs(adap->devargs.filtermode);
+       if (ret < 0)
+               return ret;
+
+       if (ret) {
+               params[1] = CXGBE_FW_PARAM_DEV(FILTER) |
+                           V_FW_PARAMS_PARAM_Y(FW_PARAM_DEV_FILTER_VNIC_MODE);
+
+               val[1] = ret - 1;
+
+               nparams++;
+       }
+
+       return t4_set_params(adap, adap->mbox, adap->pf, 0, nparams,
+                            params, val);
+}
+
 static void configure_pcie_ext_tag(struct adapter *adapter)
 {
        u16 v;
@@ -1300,6 +1534,9 @@ static int adap_init0(struct adapter *adap)
                             adap->params.b_wnd);
        }
        t4_init_sge_params(adap);
+       ret = configure_filter_mode_mask(adap);
+       if (ret < 0)
+               goto bye;
        t4_init_tp_params(adap);
        configure_pcie_ext_tag(adap);
        configure_vlan_types(adap);