]> git.karo-electronics.de Git - linux-beck.git/commitdiff
Merge tag 'rdma-for-3.5' of git://git.kernel.org/pub/scm/linux/kernel/git/roland...
authorLinus Torvalds <torvalds@linux-foundation.org>
Tue, 22 May 2012 00:54:55 +0000 (17:54 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Tue, 22 May 2012 00:54:55 +0000 (17:54 -0700)
Pull InfiniBand/RDMA changes from Roland Dreier:
 - Add ocrdma hardware driver for Emulex IB-over-Ethernet adapters
 - Add generic and mlx4 support for "raw" QPs: allow suitably privileged
   applications to send and receive arbitrary packets directly to/from
   the hardware
 - Add "doorbell drop" handling to the cxgb4 driver
 - A fairly large batch of qib hardware driver changes
 - A few fixes for lockdep-detected issues
 - A few other miscellaneous fixes and cleanups

Fix up trivial conflict in drivers/net/ethernet/emulex/benet/be.h.

* tag 'rdma-for-3.5' of git://git.kernel.org/pub/scm/linux/kernel/git/roland/infiniband: (53 commits)
  RDMA/cxgb4: Include vmalloc.h for vmalloc and vfree
  IB/mlx4: Fix mlx4_ib_add() error flow
  IB/core: Fix IB_SA_COMP_MASK macro
  IB/iser: Fix error flow in iser ep connection establishment
  IB/mlx4: Increase the number of vectors (EQs) available for ULPs
  RDMA/cxgb4: Add query_qp support
  RDMA/cxgb4: Remove kfifo usage
  RDMA/cxgb4: Use vmalloc() for debugfs QP dump
  RDMA/cxgb4: DB Drop Recovery for RDMA and LLD queues
  RDMA/cxgb4: Disable interrupts in c4iw_ev_dispatch()
  RDMA/cxgb4: Add DB Overflow Avoidance
  RDMA/cxgb4: Add debugfs RDMA memory stats
  cxgb4: DB Drop Recovery for RDMA and LLD queues
  cxgb4: Common platform specific changes for DB Drop Recovery
  cxgb4: Detect DB FULL events and notify RDMA ULD
  RDMA/cxgb4: Drop peer_abort when no endpoint found
  RDMA/cxgb4: Always wake up waiters in c4iw_peer_abort_intr()
  mlx4_core: Change bitmap allocator to work in round-robin fashion
  RDMA/nes: Don't call event handler if pointer is NULL
  RDMA/nes: Fix for the ORD value of the connecting peer
  ...

1  2 
MAINTAINERS
drivers/infiniband/core/cma.c
drivers/net/ethernet/emulex/benet/be.h
drivers/net/ethernet/emulex/benet/be_cmds.c
drivers/net/ethernet/emulex/benet/be_cmds.h
drivers/net/ethernet/emulex/benet/be_hw.h
drivers/net/ethernet/emulex/benet/be_main.c
drivers/net/ethernet/mellanox/mlx4/fw.c
drivers/net/ethernet/mellanox/mlx4/main.c
include/linux/mlx4/device.h
include/linux/mlx4/qp.h

diff --combined MAINTAINERS
index fddf29c057a1b8f6ee5a8679ddb775f2b523f68c,5e8a9328e3f17fa0a9bb767c680d0a75a481ebbd..73a8b561414b8ae657f5f9975b194ffa520ffd78
@@@ -1431,7 -1431,6 +1431,7 @@@ F:      include/linux/backlight.
  BATMAN ADVANCED
  M:    Marek Lindner <lindner_marek@yahoo.de>
  M:    Simon Wunderlich <siwu@hrz.tu-chemnitz.de>
 +M:    Antonio Quartulli <ordex@autistici.org>
  L:    b.a.t.m.a.n@lists.open-mesh.org
  W:    http://www.open-mesh.org/
  S:    Maintained
@@@ -1599,7 -1598,6 +1599,7 @@@ F:      include/linux/bcma
  
  BROCADE BFA FC SCSI DRIVER
  M:    Jing Huang <huangj@brocade.com>
 +M:    Krishna C Gudipati <kgudipat@brocade.com>
  L:    linux-scsi@vger.kernel.org
  S:    Supported
  F:    drivers/scsi/bfa/
@@@ -1970,9 -1968,7 +1970,9 @@@ S:      Maintaine
  F:    drivers/net/ethernet/ti/cpmac.c
  
  CPU FREQUENCY DRIVERS
 +M:    Rafael J. Wysocki <rjw@sisk.pl>
  L:    cpufreq@vger.kernel.org
 +L:    linux-pm@vger.kernel.org
  S:    Maintained
  F:    drivers/cpufreq/
  F:    include/linux/cpufreq.h
@@@ -3520,6 -3516,12 +3520,6 @@@ M:     Deepak Saxena <dsaxena@plexity.net
  S:    Maintained
  F:    drivers/char/hw_random/ixp4xx-rng.c
  
 -INTEL IXP2000 ETHERNET DRIVER
 -M:    Lennert Buytenhek <kernel@wantstofly.org>
 -L:    netdev@vger.kernel.org
 -S:    Maintained
 -F:    drivers/net/ethernet/xscale/ixp2000/
 -
  INTEL ETHERNET DRIVERS (e100/e1000/e1000e/igb/igbvf/ixgb/ixgbe/ixgbevf)
  M:    Jeff Kirsher <jeffrey.t.kirsher@intel.com>
  M:    Jesse Brandeburg <jesse.brandeburg@intel.com>
@@@ -3629,7 -3631,7 +3629,7 @@@ S:      Maintaine
  F:    drivers/net/ethernet/icplus/ipg.*
  
  IPATH DRIVER
- M:    Mike Marciniszyn <infinipath@qlogic.com>
+ M:    Mike Marciniszyn <infinipath@intel.com>
  L:    linux-rdma@vger.kernel.org
  S:    Maintained
  F:    drivers/infiniband/hw/ipath/
@@@ -4032,7 -4034,6 +4032,7 @@@ F:      Documentation/scsi/53c700.tx
  F:    drivers/scsi/53c700*
  
  LED SUBSYSTEM
 +M:    Bryan Wu <bryan.wu@canonical.com>
  M:    Richard Purdie <rpurdie@rpsys.net>
  S:    Maintained
  F:    drivers/leds/
@@@ -5129,13 -5130,19 +5129,13 @@@ F:   Documentation/powerpc/eeh-pci-error-
  PCI SUBSYSTEM
  M:    Bjorn Helgaas <bhelgaas@google.com>
  L:    linux-pci@vger.kernel.org
 -Q:    http://patchwork.kernel.org/project/linux-pci/list/
 -T:    git git://git.kernel.org/pub/scm/linux/kernel/git/jbarnes/pci.git
 +Q:    http://patchwork.ozlabs.org/project/linux-pci/list/
 +T:    git git://git.kernel.org/pub/scm/linux/kernel/git/helgaas/linux.git
  S:    Supported
  F:    Documentation/PCI/
  F:    drivers/pci/
  F:    include/linux/pci*
  
 -PCI HOTPLUG
 -M:    Bjorn Helgaas <bhelgaas@google.com>
 -L:    linux-pci@vger.kernel.org
 -S:    Supported
 -F:    drivers/pci/hotplug
 -
  PCMCIA SUBSYSTEM
  P:    Linux PCMCIA Team
  L:    linux-pcmcia@lists.infradead.org
@@@ -5198,7 -5205,7 +5198,7 @@@ S:      Maintaine
  F:    include/linux/personality.h
  
  PHONET PROTOCOL
 -M:    Remi Denis-Courmont <remi.denis-courmont@nokia.com>
 +M:    Remi Denis-Courmont <courmisch@gmail.com>
  S:    Supported
  F:    Documentation/networking/phonet.txt
  F:    include/linux/phonet.h
@@@ -5448,7 -5455,7 +5448,7 @@@ L:      rtc-linux@googlegroups.co
  S:    Maintained
  
  QIB DRIVER
- M:    Mike Marciniszyn <infinipath@qlogic.com>
+ M:    Mike Marciniszyn <infinipath@intel.com>
  L:    linux-rdma@vger.kernel.org
  S:    Supported
  F:    drivers/infiniband/hw/qib/
@@@ -6666,16 -6673,6 +6666,16 @@@ L:    alsa-devel@alsa-project.org (moderat
  S:    Maintained
  F:    sound/soc/codecs/twl4030*
  
 +TI WILINK WIRELESS DRIVERS
 +M:    Luciano Coelho <coelho@ti.com>
 +L:    linux-wireless@vger.kernel.org
 +W:    http://wireless.kernel.org/en/users/Drivers/wl12xx
 +W:    http://wireless.kernel.org/en/users/Drivers/wl1251
 +T:    git git://git.kernel.org/pub/scm/linux/kernel/git/luca/wl12xx.git
 +S:    Maintained
 +F:    drivers/net/wireless/ti/
 +F:    include/linux/wl12xx.h
 +
  TIPC NETWORK LAYER
  M:    Jon Maloy <jon.maloy@ericsson.com>
  M:    Allan Stephens <allan.stephens@windriver.com>
@@@ -6883,14 -6880,6 +6883,14 @@@ F:    Documentation/cdrom
  F:    drivers/cdrom/cdrom.c
  F:    include/linux/cdrom.h
  
 +UNIVERSAL FLASH STORAGE HOST CONTROLLER DRIVER
 +M:    Vinayak Holikatti <vinholikatti@gmail.com>
 +M:    Santosh Y <santoshsy@gmail.com>
 +L:    linux-scsi@vger.kernel.org
 +S:    Supported
 +F:    Documentation/scsi/ufs.txt
 +F:    drivers/scsi/ufs/
 +
  UNSORTED BLOCK IMAGES (UBI)
  M:    Artem Bityutskiy <dedekind1@gmail.com>
  W:    http://www.linux-mtd.infradead.org/
@@@ -7440,6 -7429,23 +7440,6 @@@ M:     Miloslav Trmac <mitr@volny.cz
  S:    Maintained
  F:    drivers/input/misc/wistron_btns.c
  
 -WL1251 WIRELESS DRIVER
 -M:    Luciano Coelho <coelho@ti.com>
 -L:    linux-wireless@vger.kernel.org
 -W:    http://wireless.kernel.org/en/users/Drivers/wl1251
 -T:    git git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-testing.git
 -S:    Maintained
 -F:    drivers/net/wireless/wl1251/*
 -
 -WL1271 WIRELESS DRIVER
 -M:    Luciano Coelho <coelho@ti.com>
 -L:    linux-wireless@vger.kernel.org
 -W:    http://wireless.kernel.org/en/users/Drivers/wl12xx
 -T:    git git://git.kernel.org/pub/scm/linux/kernel/git/luca/wl12xx.git
 -S:    Maintained
 -F:    drivers/net/wireless/wl12xx/
 -F:    include/linux/wl12xx.h
 -
  WL3501 WIRELESS PCMCIA CARD DRIVER
  M:    Arnaldo Carvalho de Melo <acme@ghostprotocols.net>
  L:    linux-wireless@vger.kernel.org
index 59fbd704a1eca60a06ce7ec7e833e73bf86b5fc2,79c7eebb970fde92262a775e0ec22503854c1de7..55d5642eb10ada70ec2f87419e5909ae52906323
@@@ -42,7 -42,6 +42,7 @@@
  #include <linux/inetdevice.h>
  #include <linux/slab.h>
  #include <linux/module.h>
 +#include <net/route.h>
  
  #include <net/tcp.h>
  #include <net/ipv6.h>
@@@ -1219,13 -1218,13 +1219,13 @@@ static int cma_req_handler(struct ib_cm
        }
        if (!conn_id) {
                ret = -ENOMEM;
-               goto out;
+               goto err1;
        }
  
        mutex_lock_nested(&conn_id->handler_mutex, SINGLE_DEPTH_NESTING);
        ret = cma_acquire_dev(conn_id);
        if (ret)
-               goto release_conn_id;
+               goto err2;
  
        conn_id->cm_id.ib = cm_id;
        cm_id->context = conn_id;
         */
        atomic_inc(&conn_id->refcount);
        ret = conn_id->id.event_handler(&conn_id->id, &event);
-       if (!ret) {
-               /*
-                * Acquire mutex to prevent user executing rdma_destroy_id()
-                * while we're accessing the cm_id.
-                */
-               mutex_lock(&lock);
-               if (cma_comp(conn_id, RDMA_CM_CONNECT) && (conn_id->id.qp_type != IB_QPT_UD))
-                       ib_send_cm_mra(cm_id, CMA_CM_MRA_SETTING, NULL, 0);
-               mutex_unlock(&lock);
-               mutex_unlock(&conn_id->handler_mutex);
-               cma_deref_id(conn_id);
-               goto out;
-       }
+       if (ret)
+               goto err3;
+       /*
+        * Acquire mutex to prevent user executing rdma_destroy_id()
+        * while we're accessing the cm_id.
+        */
+       mutex_lock(&lock);
+       if (cma_comp(conn_id, RDMA_CM_CONNECT) && (conn_id->id.qp_type != IB_QPT_UD))
+               ib_send_cm_mra(cm_id, CMA_CM_MRA_SETTING, NULL, 0);
+       mutex_unlock(&lock);
+       mutex_unlock(&conn_id->handler_mutex);
+       mutex_unlock(&listen_id->handler_mutex);
        cma_deref_id(conn_id);
+       return 0;
  
+ err3:
+       cma_deref_id(conn_id);
        /* Destroy the CM ID by returning a non-zero value. */
        conn_id->cm_id.ib = NULL;
- release_conn_id:
+ err2:
        cma_exch(conn_id, RDMA_CM_DESTROYING);
        mutex_unlock(&conn_id->handler_mutex);
-       rdma_destroy_id(&conn_id->id);
- out:
+ err1:
        mutex_unlock(&listen_id->handler_mutex);
+       if (conn_id)
+               rdma_destroy_id(&conn_id->id);
        return ret;
  }
  
@@@ -1827,10 -1828,7 +1829,10 @@@ static int cma_resolve_iboe_route(struc
        route->path_rec->reversible = 1;
        route->path_rec->pkey = cpu_to_be16(0xffff);
        route->path_rec->mtu_selector = IB_SA_EQ;
 -      route->path_rec->sl = id_priv->tos >> 5;
 +      route->path_rec->sl = netdev_get_prio_tc_map(
 +                      ndev->priv_flags & IFF_802_1Q_VLAN ?
 +                              vlan_dev_real_dev(ndev) : ndev,
 +                      rt_tos2priority(id_priv->tos));
  
        route->path_rec->mtu = iboe_get_mtu(ndev->mtu);
        route->path_rec->rate_selector = IB_SA_EQ;
index ff4eb8fe25d575135126cef526c4f0fff1d6123d,7bb2e97af8986e900e81c48e8fe1eb51cdba8a14..c5c4c0e83bd16303f893c7a2cf76569ec1b60006
@@@ -32,8 -32,9 +32,9 @@@
  #include <linux/u64_stats_sync.h>
  
  #include "be_hw.h"
+ #include "be_roce.h"
  
 -#define DRV_VER                       "4.2.116u"
 +#define DRV_VER                       "4.2.220u"
  #define DRV_NAME              "be2net"
  #define BE_NAME                       "ServerEngines BladeEngine2 10Gbps NIC"
  #define BE3_NAME              "ServerEngines BladeEngine3 10Gbps NIC"
@@@ -102,7 -103,8 +103,8 @@@ static inline char *nic_name(struct pci
  #define MAX_RX_QS             (MAX_RSS_QS + 1) /* RSS qs + 1 def Rx */
  
  #define MAX_TX_QS             8
- #define MAX_MSIX_VECTORS      MAX_RSS_QS
+ #define MAX_ROCE_EQS          5
+ #define MAX_MSIX_VECTORS      (MAX_RSS_QS + MAX_ROCE_EQS) /* RSS qs + RoCE */
  #define BE_TX_BUDGET          256
  #define BE_NAPI_WEIGHT                64
  #define MAX_RX_POST           BE_NAPI_WEIGHT /* Frags posted at a time */
@@@ -162,11 -164,6 +164,11 @@@ static inline void queue_head_inc(struc
        index_inc(&q->head, q->len);
  }
  
 +static inline void index_dec(u16 *index, u16 limit)
 +{
 +      *index = MODULO((*index - 1), limit);
 +}
 +
  static inline void queue_tail_inc(struct be_queue_info *q)
  {
        index_inc(&q->tail, q->len);
@@@ -313,33 -310,11 +315,33 @@@ struct be_vf_cfg 
        u32 tx_rate;
  };
  
 +enum vf_state {
 +      ENABLED = 0,
 +      ASSIGNED = 1
 +};
 +
  #define BE_FLAGS_LINK_STATUS_INIT             1
  #define BE_FLAGS_WORKER_SCHEDULED             (1 << 3)
  #define BE_UC_PMAC_COUNT              30
  #define BE_VF_UC_PMAC_COUNT           2
  
 +struct phy_info {
 +      u8 transceiver;
 +      u8 autoneg;
 +      u8 fc_autoneg;
 +      u8 port_type;
 +      u16 phy_type;
 +      u16 interface_type;
 +      u32 misc_params;
 +      u16 auto_speeds_supported;
 +      u16 fixed_speeds_supported;
 +      int link_speed;
 +      int forced_port_speed;
 +      u32 dac_cable_len;
 +      u32 advertising;
 +      u32 supported;
 +};
 +
  struct be_adapter {
        struct pci_dev *pdev;
        struct net_device *netdev;
        u32 rx_fc;              /* Rx flow control */
        u32 tx_fc;              /* Tx flow control */
        bool stats_cmd_sent;
 -      int link_speed;
 -      u8 port_type;
 -      u8 transceiver;
 -      u8 autoneg;
        u8 generation;          /* BladeEngine ASIC generation */
+       u32 if_type;
+       struct {
+               u8 __iomem *base;       /* Door Bell */
+               u32 size;
+               u32 total_size;
+               u64 io_addr;
+       } roce_db;
+       u32 num_msix_roce_vec;
+       struct ocrdma_dev *ocrdma_dev;
+       struct list_head entry;
        u32 flash_status;
        struct completion flash_compl;
  
 -      u32 num_vfs;
 -      u8 is_virtfn;
 +      u32 num_vfs;            /* Number of VFs provisioned by PF driver */
 +      u32 dev_num_vfs;        /* Number of VFs supported by HW */
 +      u8 virtfn;
        struct be_vf_cfg *vf_cfg;
        bool be3_native;
        u32 sli_family;
        u8 hba_port_num;
        u16 pvid;
 +      struct phy_info phy;
        u8 wol_cap;
        bool wol;
        u32 max_pmac_cnt;       /* Max secondary UC MACs programmable */
        u32 uc_macs;            /* Count of secondary UC MAC programmed */
 +      u32 msg_enable;
  };
  
 -#define be_physfn(adapter) (!adapter->is_virtfn)
 +#define be_physfn(adapter)            (!adapter->virtfn)
  #define       sriov_enabled(adapter)          (adapter->num_vfs > 0)
 +#define       sriov_want(adapter)             (adapter->dev_num_vfs && num_vfs && \
 +                                       be_physfn(adapter))
  #define for_all_vfs(adapter, vf_cfg, i)                                       \
        for (i = 0, vf_cfg = &adapter->vf_cfg[i]; i < adapter->num_vfs; \
                i++, vf_cfg++)
  #define lancer_chip(adapter)  ((adapter->pdev->device == OC_DEVICE_ID3) || \
                                 (adapter->pdev->device == OC_DEVICE_ID4))
  
+ #define be_roce_supported(adapter) ((adapter->if_type == SLI_INTF_TYPE_3 || \
+                               adapter->sli_family == SKYHAWK_SLI_FAMILY) && \
+                               (adapter->function_mode & RDMA_ENABLED))
  extern const struct ethtool_ops be_ethtool_ops;
  
  #define msix_enabled(adapter)         (adapter->num_msix_vec > 0)
@@@ -556,6 -545,14 +573,6 @@@ static inline u8 is_udp_pkt(struct sk_b
        return val;
  }
  
 -static inline void be_check_sriov_fn_type(struct be_adapter *adapter)
 -{
 -      u32 sli_intf;
 -
 -      pci_read_config_dword(adapter->pdev, SLI_INTF_REG_OFFSET, &sli_intf);
 -      adapter->is_virtfn = (sli_intf & SLI_INTF_FT_MASK) ? 1 : 0;
 -}
 -
  static inline void be_vf_eth_addr_generate(struct be_adapter *adapter, u8 *mac)
  {
        u32 addr;
@@@ -597,13 -594,29 +614,31 @@@ static inline bool be_is_wol_excluded(s
        }
  }
  
+ static inline bool be_type_2_3(struct be_adapter *adapter)
+ {
+       return (adapter->if_type == SLI_INTF_TYPE_2 ||
+               adapter->if_type == SLI_INTF_TYPE_3) ? true : false;
+ }
  extern void be_cq_notify(struct be_adapter *adapter, u16 qid, bool arm,
                u16 num_popped);
  extern void be_link_status_update(struct be_adapter *adapter, u8 link_status);
  extern void be_parse_stats(struct be_adapter *adapter);
  extern int be_load_fw(struct be_adapter *adapter, u8 *func);
  extern bool be_is_wol_supported(struct be_adapter *adapter);
 +extern bool be_pause_supported(struct be_adapter *adapter);
 +extern u32 be_get_fw_log_level(struct be_adapter *adapter);
  
+ /*
+  * internal function to initialize-cleanup roce device.
+  */
+ extern void be_roce_dev_add(struct be_adapter *);
+ extern void be_roce_dev_remove(struct be_adapter *);
+ /*
+  * internal function to open-close roce device during ifup-ifdown.
+  */
+ extern void be_roce_dev_open(struct be_adapter *);
+ extern void be_roce_dev_close(struct be_adapter *);
  #endif                                /* BE_H */
index b24623cce07b0f507e54147606dd3f5103035fb2,1c7c7d06a0b772160982f15f713004dcb86ef657..8d06ea381741cca9178534c843838452872d1cf3
@@@ -15,6 -15,7 +15,7 @@@
   * Costa Mesa, CA 92626
   */
  
+ #include <linux/module.h>
  #include "be.h"
  #include "be_cmds.h"
  
@@@ -61,21 -62,10 +62,21 @@@ static inline void be_mcc_compl_use(str
        compl->flags = 0;
  }
  
 +static struct be_cmd_resp_hdr *be_decode_resp_hdr(u32 tag0, u32 tag1)
 +{
 +      unsigned long addr;
 +
 +      addr = tag1;
 +      addr = ((addr << 16) << 16) | tag0;
 +      return (void *)addr;
 +}
 +
  static int be_mcc_compl_process(struct be_adapter *adapter,
 -      struct be_mcc_compl *compl)
 +                              struct be_mcc_compl *compl)
  {
        u16 compl_status, extd_status;
 +      struct be_cmd_resp_hdr *resp_hdr;
 +      u8 opcode = 0, subsystem = 0;
  
        /* Just swap the status to host endian; mcc tag is opaquely copied
         * from mcc_wrb */
        compl_status = (compl->status >> CQE_STATUS_COMPL_SHIFT) &
                                CQE_STATUS_COMPL_MASK;
  
 -      if (((compl->tag0 == OPCODE_COMMON_WRITE_FLASHROM) ||
 -              (compl->tag0 == OPCODE_COMMON_WRITE_OBJECT)) &&
 -              (compl->tag1 == CMD_SUBSYSTEM_COMMON)) {
 +      resp_hdr = be_decode_resp_hdr(compl->tag0, compl->tag1);
 +
 +      if (resp_hdr) {
 +              opcode = resp_hdr->opcode;
 +              subsystem = resp_hdr->subsystem;
 +      }
 +
 +      if (((opcode == OPCODE_COMMON_WRITE_FLASHROM) ||
 +           (opcode == OPCODE_COMMON_WRITE_OBJECT)) &&
 +          (subsystem == CMD_SUBSYSTEM_COMMON)) {
                adapter->flash_status = compl_status;
                complete(&adapter->flash_compl);
        }
  
        if (compl_status == MCC_STATUS_SUCCESS) {
 -              if (((compl->tag0 == OPCODE_ETH_GET_STATISTICS) ||
 -                       (compl->tag0 == OPCODE_ETH_GET_PPORT_STATS)) &&
 -                      (compl->tag1 == CMD_SUBSYSTEM_ETH)) {
 +              if (((opcode == OPCODE_ETH_GET_STATISTICS) ||
 +                   (opcode == OPCODE_ETH_GET_PPORT_STATS)) &&
 +                  (subsystem == CMD_SUBSYSTEM_ETH)) {
                        be_parse_stats(adapter);
                        adapter->stats_cmd_sent = false;
                }
 -              if (compl->tag0 ==
 -                              OPCODE_COMMON_GET_CNTL_ADDITIONAL_ATTRIBUTES) {
 -                      struct be_mcc_wrb *mcc_wrb =
 -                              queue_index_node(&adapter->mcc_obj.q,
 -                                              compl->tag1);
 +              if (opcode == OPCODE_COMMON_GET_CNTL_ADDITIONAL_ATTRIBUTES &&
 +                  subsystem == CMD_SUBSYSTEM_COMMON) {
                        struct be_cmd_resp_get_cntl_addnl_attribs *resp =
 -                              embedded_payload(mcc_wrb);
 +                              (void *)resp_hdr;
                        adapter->drv_stats.be_on_die_temperature =
                                resp->on_die_temperature;
                }
        } else {
 -              if (compl->tag0 == OPCODE_COMMON_GET_CNTL_ADDITIONAL_ATTRIBUTES)
 +              if (opcode == OPCODE_COMMON_GET_CNTL_ADDITIONAL_ATTRIBUTES)
                        be_get_temp_freq = 0;
  
                if (compl_status == MCC_STATUS_NOT_SUPPORTED ||
                if (compl_status == MCC_STATUS_UNAUTHORIZED_REQUEST) {
                        dev_warn(&adapter->pdev->dev, "This domain(VM) is not "
                                "permitted to execute this cmd (opcode %d)\n",
 -                              compl->tag0);
 +                              opcode);
                } else {
                        extd_status = (compl->status >> CQE_STATUS_EXTD_SHIFT) &
                                        CQE_STATUS_EXTD_MASK;
                        dev_err(&adapter->pdev->dev, "Cmd (opcode %d) failed:"
                                "status %d, extd-status %d\n",
 -                              compl->tag0, compl_status, extd_status);
 +                              opcode, compl_status, extd_status);
                }
        }
  done:
@@@ -141,7 -127,7 +142,7 @@@ static void be_async_link_state_process
                struct be_async_event_link_state *evt)
  {
        /* When link status changes, link speed must be re-queried from FW */
 -      adapter->link_speed = -1;
 +      adapter->phy.link_speed = -1;
  
        /* For the initial link status do not rely on the ASYNC event as
         * it may not be received in some cases.
@@@ -168,7 -154,7 +169,7 @@@ static void be_async_grp5_qos_speed_pro
  {
        if (evt->physical_port == adapter->port_num) {
                /* qos_link_speed is in units of 10 Mbps */
 -              adapter->link_speed = evt->qos_link_speed * 10;
 +              adapter->phy.link_speed = evt->qos_link_speed * 10;
        }
  }
  
@@@ -301,7 -287,7 +302,7 @@@ static int be_mcc_wait_compl(struct be_
        if (i == mcc_timeout) {
                dev_err(&adapter->pdev->dev, "FW not responding\n");
                adapter->fw_timeout = true;
 -              return -1;
 +              return -EIO;
        }
        return status;
  }
  /* Notify MCC requests and wait for completion */
  static int be_mcc_notify_wait(struct be_adapter *adapter)
  {
 +      int status;
 +      struct be_mcc_wrb *wrb;
 +      struct be_mcc_obj *mcc_obj = &adapter->mcc_obj;
 +      u16 index = mcc_obj->q.head;
 +      struct be_cmd_resp_hdr *resp;
 +
 +      index_dec(&index, mcc_obj->q.len);
 +      wrb = queue_index_node(&mcc_obj->q, index);
 +
 +      resp = be_decode_resp_hdr(wrb->tag0, wrb->tag1);
 +
        be_mcc_notify(adapter);
 -      return be_mcc_wait_compl(adapter);
 +
 +      status = be_mcc_wait_compl(adapter);
 +      if (status == -EIO)
 +              goto out;
 +
 +      status = resp->status;
 +out:
 +      return status;
  }
  
  static int be_mbox_db_ready_wait(struct be_adapter *adapter, void __iomem *db)
@@@ -468,17 -436,14 +469,17 @@@ static void be_wrb_cmd_hdr_prepare(stru
                                struct be_mcc_wrb *wrb, struct be_dma_mem *mem)
  {
        struct be_sge *sge;
 +      unsigned long addr = (unsigned long)req_hdr;
 +      u64 req_addr = addr;
  
        req_hdr->opcode = opcode;
        req_hdr->subsystem = subsystem;
        req_hdr->request_length = cpu_to_le32(cmd_len - sizeof(*req_hdr));
        req_hdr->version = 0;
  
 -      wrb->tag0 = opcode;
 -      wrb->tag1 = subsystem;
 +      wrb->tag0 = req_addr & 0xFFFFFFFF;
 +      wrb->tag1 = upper_32_bits(req_addr);
 +
        wrb->payload_length = cmd_len;
        if (mem) {
                wrb->embedded |= (1 & MCC_WRB_SGE_CNT_MASK) <<
@@@ -1257,7 -1222,7 +1258,7 @@@ int lancer_cmd_get_pport_stats(struct b
                        OPCODE_ETH_GET_PPORT_STATS, nonemb_cmd->size, wrb,
                        nonemb_cmd);
  
 -      req->cmd_params.params.pport_num = cpu_to_le16(adapter->port_num);
 +      req->cmd_params.params.pport_num = cpu_to_le16(adapter->hba_port_num);
        req->cmd_params.params.reset_stats = 0;
  
        be_mcc_notify(adapter);
@@@ -1319,10 -1284,13 +1320,10 @@@ int be_cmd_get_die_temperature(struct b
  {
        struct be_mcc_wrb *wrb;
        struct be_cmd_req_get_cntl_addnl_attribs *req;
 -      u16 mccq_index;
        int status;
  
        spin_lock_bh(&adapter->mcc_lock);
  
 -      mccq_index = adapter->mcc_obj.q.head;
 -
        wrb = wrb_from_mccq(adapter);
        if (!wrb) {
                status = -EBUSY;
                OPCODE_COMMON_GET_CNTL_ADDITIONAL_ATTRIBUTES, sizeof(*req),
                wrb, NULL);
  
 -      wrb->tag1 = mccq_index;
 -
        be_mcc_notify(adapter);
  
  err:
@@@ -1855,16 -1825,18 +1856,16 @@@ int lancer_cmd_write_object(struct be_a
        spin_unlock_bh(&adapter->mcc_lock);
  
        if (!wait_for_completion_timeout(&adapter->flash_compl,
 -                      msecs_to_jiffies(12000)))
 +                                       msecs_to_jiffies(30000)))
                status = -1;
        else
                status = adapter->flash_status;
  
        resp = embedded_payload(wrb);
 -      if (!status) {
 +      if (!status)
                *data_written = le32_to_cpu(resp->actual_write_len);
 -      } else {
 +      else
                *addn_status = resp->additional_status;
 -              status = resp->status;
 -      }
  
        return status;
  
@@@ -1979,7 -1951,7 +1980,7 @@@ int be_cmd_get_flash_crc(struct be_adap
        be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
                OPCODE_COMMON_READ_FLASHROM, sizeof(*req)+4, wrb, NULL);
  
 -      req->params.op_type = cpu_to_le32(IMG_TYPE_REDBOOT);
 +      req->params.op_type = cpu_to_le32(OPTYPE_REDBOOT);
        req->params.op_code = cpu_to_le32(FLASHROM_OPER_REPORT);
        req->params.offset = cpu_to_le32(offset);
        req->params.data_buf_size = cpu_to_le32(0x4);
@@@ -2165,7 -2137,8 +2166,7 @@@ err
        return status;
  }
  
 -int be_cmd_get_phy_info(struct be_adapter *adapter,
 -                              struct be_phy_info *phy_info)
 +int be_cmd_get_phy_info(struct be_adapter *adapter)
  {
        struct be_mcc_wrb *wrb;
        struct be_cmd_req_get_phy_info *req;
        if (!status) {
                struct be_phy_info *resp_phy_info =
                                cmd.va + sizeof(struct be_cmd_req_hdr);
 -              phy_info->phy_type = le16_to_cpu(resp_phy_info->phy_type);
 -              phy_info->interface_type =
 +              adapter->phy.phy_type = le16_to_cpu(resp_phy_info->phy_type);
 +              adapter->phy.interface_type =
                        le16_to_cpu(resp_phy_info->interface_type);
 +              adapter->phy.auto_speeds_supported =
 +                      le16_to_cpu(resp_phy_info->auto_speeds_supported);
 +              adapter->phy.fixed_speeds_supported =
 +                      le16_to_cpu(resp_phy_info->fixed_speeds_supported);
 +              adapter->phy.misc_params =
 +                      le32_to_cpu(resp_phy_info->misc_params);
        }
        pci_free_consistent(adapter->pdev, cmd.size,
                                cmd.va, cmd.dma);
        mutex_unlock(&adapter->mbox_lock);
        pci_free_consistent(adapter->pdev, cmd.size, cmd.va, cmd.dma);
        return status;
 +
 +}
 +int be_cmd_get_ext_fat_capabilites(struct be_adapter *adapter,
 +                                 struct be_dma_mem *cmd)
 +{
 +      struct be_mcc_wrb *wrb;
 +      struct be_cmd_req_get_ext_fat_caps *req;
 +      int status;
 +
 +      if (mutex_lock_interruptible(&adapter->mbox_lock))
 +              return -1;
 +
 +      wrb = wrb_from_mbox(adapter);
 +      if (!wrb) {
 +              status = -EBUSY;
 +              goto err;
 +      }
 +
 +      req = cmd->va;
 +      be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
 +                             OPCODE_COMMON_GET_EXT_FAT_CAPABILITES,
 +                             cmd->size, wrb, cmd);
 +      req->parameter_type = cpu_to_le32(1);
 +
 +      status = be_mbox_notify_wait(adapter);
 +err:
 +      mutex_unlock(&adapter->mbox_lock);
 +      return status;
 +}
 +
 +int be_cmd_set_ext_fat_capabilites(struct be_adapter *adapter,
 +                                 struct be_dma_mem *cmd,
 +                                 struct be_fat_conf_params *configs)
 +{
 +      struct be_mcc_wrb *wrb;
 +      struct be_cmd_req_set_ext_fat_caps *req;
 +      int status;
 +
 +      spin_lock_bh(&adapter->mcc_lock);
 +
 +      wrb = wrb_from_mccq(adapter);
 +      if (!wrb) {
 +              status = -EBUSY;
 +              goto err;
 +      }
 +
 +      req = cmd->va;
 +      memcpy(&req->set_params, configs, sizeof(struct be_fat_conf_params));
 +      be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
 +                             OPCODE_COMMON_SET_EXT_FAT_CAPABILITES,
 +                             cmd->size, wrb, cmd);
 +
 +      status = be_mcc_notify_wait(adapter);
 +err:
 +      spin_unlock_bh(&adapter->mcc_lock);
 +      return status;
  }
+ int be_roce_mcc_cmd(void *netdev_handle, void *wrb_payload,
+                       int wrb_payload_size, u16 *cmd_status, u16 *ext_status)
+ {
+       struct be_adapter *adapter = netdev_priv(netdev_handle);
+       struct be_mcc_wrb *wrb;
+       struct be_cmd_req_hdr *hdr = (struct be_cmd_req_hdr *) wrb_payload;
+       struct be_cmd_req_hdr *req;
+       struct be_cmd_resp_hdr *resp;
+       int status;
+       spin_lock_bh(&adapter->mcc_lock);
+       wrb = wrb_from_mccq(adapter);
+       if (!wrb) {
+               status = -EBUSY;
+               goto err;
+       }
+       req = embedded_payload(wrb);
+       resp = embedded_payload(wrb);
+       be_wrb_cmd_hdr_prepare(req, hdr->subsystem,
+                              hdr->opcode, wrb_payload_size, wrb, NULL);
+       memcpy(req, wrb_payload, wrb_payload_size);
+       be_dws_cpu_to_le(req, wrb_payload_size);
+       status = be_mcc_notify_wait(adapter);
+       if (cmd_status)
+               *cmd_status = (status & 0xffff);
+       if (ext_status)
+               *ext_status = 0;
+       memcpy(wrb_payload, resp, sizeof(*resp) + resp->response_length);
+       be_dws_le_to_cpu(wrb_payload, sizeof(*resp) + resp->response_length);
+ err:
+       spin_unlock_bh(&adapter->mcc_lock);
+       return status;
+ }
+ EXPORT_SYMBOL(be_roce_mcc_cmd);
index 0b1029b60f694572293d87955528156008fa730e,54eabd8ff397a66e6fdda24fbccabf3aea49aa87..9625bf420c161efb92ccc89c16b18b1fa4c90c68
@@@ -189,8 -189,6 +189,8 @@@ struct be_mcc_mailbox 
  #define OPCODE_COMMON_GET_PHY_DETAILS                 102
  #define OPCODE_COMMON_SET_DRIVER_FUNCTION_CAP         103
  #define OPCODE_COMMON_GET_CNTL_ADDITIONAL_ATTRIBUTES  121
 +#define OPCODE_COMMON_GET_EXT_FAT_CAPABILITES         125
 +#define OPCODE_COMMON_SET_EXT_FAT_CAPABILITES         126
  #define OPCODE_COMMON_GET_MAC_LIST                    147
  #define OPCODE_COMMON_SET_MAC_LIST                    148
  #define OPCODE_COMMON_GET_HSW_CONFIG                  152
@@@ -227,12 -225,8 +227,12 @@@ struct be_cmd_req_hdr 
  #define RESP_HDR_INFO_OPCODE_SHIFT    0       /* bits 0 - 7 */
  #define RESP_HDR_INFO_SUBSYS_SHIFT    8       /* bits 8 - 15 */
  struct be_cmd_resp_hdr {
 -      u32 info;               /* dword 0 */
 -      u32 status;             /* dword 1 */
 +      u8 opcode;              /* dword 0 */
 +      u8 subsystem;           /* dword 0 */
 +      u8 rsvd[2];             /* dword 0 */
 +      u8 status;              /* dword 1 */
 +      u8 add_status;          /* dword 1 */
 +      u8 rsvd1[2];            /* dword 1 */
        u32 response_length;    /* dword 2 */
        u32 actual_resp_len;    /* dword 3 */
  };
@@@ -1062,6 -1056,7 +1062,7 @@@ struct be_cmd_resp_modify_eq_delay 
  /* The HW can come up in either of the following multi-channel modes
   * based on the skew/IPL.
   */
+ #define RDMA_ENABLED                          0x4
  #define FLEX10_MODE                           0x400
  #define VNIC_MODE                             0x20000
  #define UMC_ENABLED                           0x1000000
@@@ -1315,36 -1310,9 +1316,36 @@@ enum 
        PHY_TYPE_KX4_10GB,
        PHY_TYPE_BASET_10GB,
        PHY_TYPE_BASET_1GB,
 +      PHY_TYPE_BASEX_1GB,
 +      PHY_TYPE_SGMII,
        PHY_TYPE_DISABLED = 255
  };
  
 +#define BE_SUPPORTED_SPEED_NONE               0
 +#define BE_SUPPORTED_SPEED_10MBPS     1
 +#define BE_SUPPORTED_SPEED_100MBPS    2
 +#define BE_SUPPORTED_SPEED_1GBPS      4
 +#define BE_SUPPORTED_SPEED_10GBPS     8
 +
 +#define BE_AN_EN                      0x2
 +#define BE_PAUSE_SYM_EN                       0x80
 +
 +/* MAC speed valid values */
 +#define SPEED_DEFAULT  0x0
 +#define SPEED_FORCED_10GB  0x1
 +#define SPEED_FORCED_1GB  0x2
 +#define SPEED_AUTONEG_10GB  0x3
 +#define SPEED_AUTONEG_1GB  0x4
 +#define SPEED_AUTONEG_100MB  0x5
 +#define SPEED_AUTONEG_10GB_1GB 0x6
 +#define SPEED_AUTONEG_10GB_1GB_100MB 0x7
 +#define SPEED_AUTONEG_1GB_100MB  0x8
 +#define SPEED_AUTONEG_10MB  0x9
 +#define SPEED_AUTONEG_1GB_100MB_10MB 0xa
 +#define SPEED_AUTONEG_100MB_10MB 0xb
 +#define SPEED_FORCED_100MB  0xc
 +#define SPEED_FORCED_10MB  0xd
 +
  struct be_cmd_req_get_phy_info {
        struct be_cmd_req_hdr hdr;
        u8 rsvd0[24];
@@@ -1354,11 -1322,7 +1355,11 @@@ struct be_phy_info 
        u16 phy_type;
        u16 interface_type;
        u32 misc_params;
 -      u32 future_use[4];
 +      u16 ext_phy_details;
 +      u16 rsvd;
 +      u16 auto_speeds_supported;
 +      u16 fixed_speeds_supported;
 +      u32 future_use[2];
  };
  
  struct be_cmd_resp_get_phy_info {
@@@ -1604,56 -1568,6 +1605,56 @@@ static inline void *be_erx_stats_from_c
        }
  }
  
 +
 +/************** get fat capabilites *******************/
 +#define MAX_MODULES 27
 +#define MAX_MODES 4
 +#define MODE_UART 0
 +#define FW_LOG_LEVEL_DEFAULT 48
 +#define FW_LOG_LEVEL_FATAL 64
 +
 +struct ext_fat_mode {
 +      u8 mode;
 +      u8 rsvd0;
 +      u16 port_mask;
 +      u32 dbg_lvl;
 +      u64 fun_mask;
 +} __packed;
 +
 +struct ext_fat_modules {
 +      u8 modules_str[32];
 +      u32 modules_id;
 +      u32 num_modes;
 +      struct ext_fat_mode trace_lvl[MAX_MODES];
 +} __packed;
 +
 +struct be_fat_conf_params {
 +      u32 max_log_entries;
 +      u32 log_entry_size;
 +      u8 log_type;
 +      u8 max_log_funs;
 +      u8 max_log_ports;
 +      u8 rsvd0;
 +      u32 supp_modes;
 +      u32 num_modules;
 +      struct ext_fat_modules module[MAX_MODULES];
 +} __packed;
 +
 +struct be_cmd_req_get_ext_fat_caps {
 +      struct be_cmd_req_hdr hdr;
 +      u32 parameter_type;
 +};
 +
 +struct be_cmd_resp_get_ext_fat_caps {
 +      struct be_cmd_resp_hdr hdr;
 +      struct be_fat_conf_params get_params;
 +};
 +
 +struct be_cmd_req_set_ext_fat_caps {
 +      struct be_cmd_req_hdr hdr;
 +      struct be_fat_conf_params set_params;
 +};
 +
  extern int be_pci_fnum_get(struct be_adapter *adapter);
  extern int be_cmd_POST(struct be_adapter *adapter);
  extern int be_cmd_mac_addr_query(struct be_adapter *adapter, u8 *mac_addr,
@@@ -1742,7 -1656,8 +1743,7 @@@ extern int be_cmd_get_seeprom_data(stru
                                struct be_dma_mem *nonemb_cmd);
  extern int be_cmd_set_loopback(struct be_adapter *adapter, u8 port_num,
                                u8 loopback_type, u8 enable);
 -extern int be_cmd_get_phy_info(struct be_adapter *adapter,
 -                              struct be_phy_info *phy_info);
 +extern int be_cmd_get_phy_info(struct be_adapter *adapter);
  extern int be_cmd_set_qos(struct be_adapter *adapter, u32 bps, u32 domain);
  extern void be_detect_dump_ue(struct be_adapter *adapter);
  extern int be_cmd_get_die_temperature(struct be_adapter *adapter);
@@@ -1759,9 -1674,4 +1760,9 @@@ extern int be_cmd_set_hsw_config(struc
  extern int be_cmd_get_hsw_config(struct be_adapter *adapter, u16 *pvid,
                        u32 domain, u16 intf_id);
  extern int be_cmd_get_acpi_wol_cap(struct be_adapter *adapter);
 +extern int be_cmd_get_ext_fat_capabilites(struct be_adapter *adapter,
 +                                        struct be_dma_mem *cmd);
 +extern int be_cmd_set_ext_fat_capabilites(struct be_adapter *adapter,
 +                                        struct be_dma_mem *cmd,
 +                                        struct be_fat_conf_params *cfgs);
  
index f38b58c8dbba1adede8db7d359503ad5fea1c2fc,23a345486564b4f64f9e4b46ee27124923e22b6d..d9fb0c501fa15aa9b6b5f55ee4a4504adacb1bc8
@@@ -58,8 -58,6 +58,8 @@@
  
  #define SLI_PORT_CONTROL_IP_MASK      0x08000000
  
 +#define PCICFG_CUST_SCRATCHPAD_CSR    0x1EC
 +
  /********* Memory BAR register ************/
  #define PCICFG_MEMBAR_CTRL_INT_CTRL_OFFSET    0xfc
  /* Host Interrupt Enable, if set interrupts are enabled although "PCI Interrupt
  #define SLI_INTF_REV_SHIFT                    4
  #define SLI_INTF_FT_MASK                      0x00000001
  
+ #define SLI_INTF_TYPE_2               2
+ #define SLI_INTF_TYPE_3               3
  
  /* SLI family */
  #define BE_SLI_FAMILY         0x0
  #define LANCER_A0_SLI_FAMILY  0xA
+ #define SKYHAWK_SLI_FAMILY      0x2
  
  /********* ISR0 Register offset **********/
  #define CEV_ISR0_OFFSET                       0xC18
  #define QUERY_FAT     1
  
  /* Flashrom related descriptors */
 +#define MAX_FLASH_COMP                        32
  #define IMAGE_TYPE_FIRMWARE           160
  #define IMAGE_TYPE_BOOTCODE           224
  #define IMAGE_TYPE_OPTIONROM          32
  
  #define NUM_FLASHDIR_ENTRIES          32
  
 -#define IMG_TYPE_ISCSI_ACTIVE         0
 -#define IMG_TYPE_REDBOOT              1
 -#define IMG_TYPE_BIOS                 2
 -#define IMG_TYPE_PXE_BIOS             3
 -#define IMG_TYPE_FCOE_BIOS            8
 -#define IMG_TYPE_ISCSI_BACKUP         9
 -#define IMG_TYPE_FCOE_FW_ACTIVE               10
 -#define IMG_TYPE_FCOE_FW_BACKUP       11
 -#define IMG_TYPE_NCSI_FW              13
 -#define IMG_TYPE_PHY_FW                       99
 +#define OPTYPE_ISCSI_ACTIVE           0
 +#define OPTYPE_REDBOOT                        1
 +#define OPTYPE_BIOS                   2
 +#define OPTYPE_PXE_BIOS                       3
 +#define OPTYPE_FCOE_BIOS              8
 +#define OPTYPE_ISCSI_BACKUP           9
 +#define OPTYPE_FCOE_FW_ACTIVE         10
 +#define OPTYPE_FCOE_FW_BACKUP         11
 +#define OPTYPE_NCSI_FW                        13
 +#define OPTYPE_PHY_FW                 99
  #define TN_8022                               13
  
  #define ILLEGAL_IOCTL_REQ             2
  #define FLASH_REDBOOT_START_g3             (262144)
  #define FLASH_PHY_FW_START_g3            1310720
  
 +#define IMAGE_NCSI                    16
 +#define IMAGE_OPTION_ROM_PXE          32
 +#define IMAGE_OPTION_ROM_FCoE         33
 +#define IMAGE_OPTION_ROM_ISCSI                34
 +#define IMAGE_FLASHISM_JUMPVECTOR     48
 +#define IMAGE_FLASH_ISM                       49
 +#define IMAGE_JUMP_VECTOR             50
 +#define IMAGE_FIRMWARE_iSCSI          160
 +#define IMAGE_FIRMWARE_COMP_iSCSI     161
 +#define IMAGE_FIRMWARE_FCoE           162
 +#define IMAGE_FIRMWARE_COMP_FCoE      163
 +#define IMAGE_FIRMWARE_BACKUP_iSCSI   176
 +#define IMAGE_FIRMWARE_BACKUP_COMP_iSCSI 177
 +#define IMAGE_FIRMWARE_BACKUP_FCoE    178
 +#define IMAGE_FIRMWARE_BACKUP_COMP_FCoE 179
 +#define IMAGE_FIRMWARE_PHY            192
 +#define IMAGE_BOOT_CODE                       224
 +
  /************* Rx Packet Type Encoding **************/
  #define BE_UNICAST_PACKET             0
  #define BE_MULTICAST_PACKET           1
@@@ -466,7 -447,6 +468,7 @@@ struct flash_comp 
        unsigned long offset;
        int optype;
        int size;
 +      int img_type;
  };
  
  struct image_hdr {
@@@ -503,19 -483,17 +505,19 @@@ struct flash_section_hdr 
        u32 format_rev;
        u32 cksum;
        u32 antidote;
 -      u32 build_no;
 -      u8 id_string[64];
 -      u32 active_entry_mask;
 -      u32 valid_entry_mask;
 -      u32 org_content_mask;
 -      u32 rsvd0;
 -      u32 rsvd1;
 -      u32 rsvd2;
 -      u32 rsvd3;
 -      u32 rsvd4;
 -};
 +      u32 num_images;
 +      u8 id_string[128];
 +      u32 rsvd[4];
 +} __packed;
 +
 +struct flash_section_hdr_g2 {
 +      u32 format_rev;
 +      u32 cksum;
 +      u32 antidote;
 +      u32 build_num;
 +      u8 id_string[128];
 +      u32 rsvd[8];
 +} __packed;
  
  struct flash_section_entry {
        u32 type;
        u32 rsvd0;
        u32 rsvd1;
        u8 ver_data[32];
 -};
 +} __packed;
  
  struct flash_section_info {
        u8 cookie[32];
        struct flash_section_hdr fsec_hdr;
        struct flash_section_entry fsec_entry[32];
 -};
 +} __packed;
 +
 +struct flash_section_info_g2 {
 +      u8 cookie[32];
 +      struct flash_section_hdr_g2 fsec_hdr;
 +      struct flash_section_entry fsec_entry[32];
 +} __packed;
index 081c7770116811324d153318d8ca220acb2d30ad,fcc15e755d5cbda177d175a8a06a1e3dafa98edc..08efd308d78ae40640f73953a41531aabba2c054
@@@ -421,9 -421,6 +421,9 @@@ void be_parse_stats(struct be_adapter *
                populate_be2_stats(adapter);
        }
  
 +      if (lancer_chip(adapter))
 +              goto done;
 +
        /* as erx_v1 is longer than v0, ok to use v1 defn for v0 access */
        for_all_rx_queues(adapter, rxo, i) {
                /* below erx HW counter can actually wrap around after
                accumulate_16bit_val(&rx_stats(rxo)->rx_drops_no_frags,
                                (u16)erx->rx_drops_no_fragments[rxo->q.id]);
        }
 +done:
 +      return;
  }
  
  static struct rtnl_link_stats64 *be_get_stats64(struct net_device *netdev,
@@@ -802,30 -797,22 +802,30 @@@ static int be_vid_config(struct be_adap
        if (adapter->promiscuous)
                return 0;
  
 -      if (adapter->vlans_added <= adapter->max_vlans)  {
 -              /* Construct VLAN Table to give to HW */
 -              for (i = 0; i < VLAN_N_VID; i++) {
 -                      if (adapter->vlan_tag[i]) {
 -                              vtag[ntags] = cpu_to_le16(i);
 -                              ntags++;
 -                      }
 -              }
 -              status = be_cmd_vlan_config(adapter, adapter->if_handle,
 -                                      vtag, ntags, 1, 0);
 -      } else {
 -              status = be_cmd_vlan_config(adapter, adapter->if_handle,
 -                                      NULL, 0, 1, 1);
 +      if (adapter->vlans_added > adapter->max_vlans)
 +              goto set_vlan_promisc;
 +
 +      /* Construct VLAN Table to give to HW */
 +      for (i = 0; i < VLAN_N_VID; i++)
 +              if (adapter->vlan_tag[i])
 +                      vtag[ntags++] = cpu_to_le16(i);
 +
 +      status = be_cmd_vlan_config(adapter, adapter->if_handle,
 +                                  vtag, ntags, 1, 0);
 +
 +      /* Set to VLAN promisc mode as setting VLAN filter failed */
 +      if (status) {
 +              dev_info(&adapter->pdev->dev, "Exhausted VLAN HW filters.\n");
 +              dev_info(&adapter->pdev->dev, "Disabling HW VLAN filtering.\n");
 +              goto set_vlan_promisc;
        }
  
        return status;
 +
 +set_vlan_promisc:
 +      status = be_cmd_vlan_config(adapter, adapter->if_handle,
 +                                  NULL, 0, 1, 1);
 +      return status;
  }
  
  static int be_vlan_add_vid(struct net_device *netdev, u16 vid)
@@@ -875,7 -862,6 +875,7 @@@ ret
  static void be_set_rx_mode(struct net_device *netdev)
  {
        struct be_adapter *adapter = netdev_priv(netdev);
 +      int status;
  
        if (netdev->flags & IFF_PROMISC) {
                be_cmd_rx_filter(adapter, IFF_PROMISC, ON);
                }
        }
  
 -      be_cmd_rx_filter(adapter, IFF_MULTICAST, ON);
 +      status = be_cmd_rx_filter(adapter, IFF_MULTICAST, ON);
 +
 +      /* Set to MCAST promisc mode if setting MULTICAST address fails */
 +      if (status) {
 +              dev_info(&adapter->pdev->dev, "Exhausted multicast HW filters.\n");
 +              dev_info(&adapter->pdev->dev, "Disabling HW multicast filtering.\n");
 +              be_cmd_rx_filter(adapter, IFF_ALLMULTI, ON);
 +      }
  done:
        return;
  }
@@@ -1049,29 -1028,6 +1049,29 @@@ static int be_set_vf_tx_rate(struct net
        return status;
  }
  
 +static int be_find_vfs(struct be_adapter *adapter, int vf_state)
 +{
 +      struct pci_dev *dev, *pdev = adapter->pdev;
 +      int vfs = 0, assigned_vfs = 0, pos, vf_fn;
 +      u16 offset, stride;
 +
 +      pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_SRIOV);
 +      pci_read_config_word(pdev, pos + PCI_SRIOV_VF_OFFSET, &offset);
 +      pci_read_config_word(pdev, pos + PCI_SRIOV_VF_STRIDE, &stride);
 +
 +      dev = pci_get_device(pdev->vendor, PCI_ANY_ID, NULL);
 +      while (dev) {
 +              vf_fn = (pdev->devfn + offset + stride * vfs) & 0xFFFF;
 +              if (dev->is_virtfn && dev->devfn == vf_fn) {
 +                      vfs++;
 +                      if (dev->dev_flags & PCI_DEV_FLAGS_ASSIGNED)
 +                              assigned_vfs++;
 +              }
 +              dev = pci_get_device(pdev->vendor, PCI_ANY_ID, dev);
 +      }
 +      return (vf_state == ASSIGNED) ? assigned_vfs : vfs;
 +}
 +
  static void be_eqd_update(struct be_adapter *adapter, struct be_eq_obj *eqo)
  {
        struct be_rx_stats *stats = rx_stats(&adapter->rx_obj[eqo->idx]);
@@@ -1282,7 -1238,6 +1282,7 @@@ static void be_rx_compl_process(struct 
                skb_checksum_none_assert(skb);
  
        skb->protocol = eth_type_trans(skb, netdev);
 +      skb_record_rx_queue(skb, rxo - &adapter->rx_obj[0]);
        if (netdev->features & NETIF_F_RXHASH)
                skb->rxhash = rxcp->rss_hash;
  
@@@ -1339,7 -1294,6 +1339,7 @@@ void be_rx_compl_process_gro(struct be_
        skb->len = rxcp->pkt_size;
        skb->data_len = rxcp->pkt_size;
        skb->ip_summed = CHECKSUM_UNNECESSARY;
 +      skb_record_rx_queue(skb, rxo - &adapter->rx_obj[0]);
        if (adapter->netdev->features & NETIF_F_RXHASH)
                skb->rxhash = rxcp->rss_hash;
  
@@@ -1601,9 -1555,7 +1601,9 @@@ static int event_handle(struct be_eq_ob
        if (!num)
                rearm = true;
  
 -      be_eq_notify(eqo->adapter, eqo->q.id, rearm, true, num);
 +      if (num || msix_enabled(eqo->adapter))
 +              be_eq_notify(eqo->adapter, eqo->q.id, rearm, true, num);
 +
        if (num)
                napi_schedule(&eqo->napi);
  
@@@ -1812,9 -1764,9 +1812,9 @@@ static void be_tx_queues_destroy(struc
  
  static int be_num_txqs_want(struct be_adapter *adapter)
  {
 -      if (sriov_enabled(adapter) || be_is_mc(adapter) ||
 -              lancer_chip(adapter) || !be_physfn(adapter) ||
 -              adapter->generation == BE_GEN2)
 +      if (sriov_want(adapter) || be_is_mc(adapter) ||
 +          lancer_chip(adapter) || !be_physfn(adapter) ||
 +          adapter->generation == BE_GEN2)
                return 1;
        else
                return MAX_TX_QS;
@@@ -2141,7 -2093,7 +2141,7 @@@ static void be_msix_disable(struct be_a
  static uint be_num_rss_want(struct be_adapter *adapter)
  {
        if ((adapter->function_caps & BE_FUNCTION_CAPS_RSS) &&
 -           adapter->num_vfs == 0 && be_physfn(adapter) &&
 +           !sriov_want(adapter) && be_physfn(adapter) &&
             !be_is_mc(adapter))
                return (adapter->be3_native) ? BE3_MAX_RSS_QS : BE2_MAX_RSS_QS;
        else
  static void be_msix_enable(struct be_adapter *adapter)
  {
  #define BE_MIN_MSIX_VECTORS           1
-       int i, status, num_vec;
+       int i, status, num_vec, num_roce_vec = 0;
  
        /* If RSS queues are not used, need a vec for default RX Q */
        num_vec = min(be_num_rss_want(adapter), num_online_cpus());
+       if (be_roce_supported(adapter)) {
+               num_roce_vec = min_t(u32, MAX_ROCE_MSIX_VECTORS,
+                                       (num_online_cpus() + 1));
+               num_roce_vec = min(num_roce_vec, MAX_ROCE_EQS);
+               num_vec += num_roce_vec;
+               num_vec = min(num_vec, MAX_MSIX_VECTORS);
+       }
        num_vec = max(num_vec, BE_MIN_MSIX_VECTORS);
  
        for (i = 0; i < num_vec; i++)
        }
        return;
  done:
-       adapter->num_msix_vec = num_vec;
+       if (be_roce_supported(adapter)) {
+               if (num_vec > num_roce_vec) {
+                       adapter->num_msix_vec = num_vec - num_roce_vec;
+                       adapter->num_msix_roce_vec =
+                               num_vec - adapter->num_msix_vec;
+               } else {
+                       adapter->num_msix_vec = num_vec;
+                       adapter->num_msix_roce_vec = 0;
+               }
+       } else
+               adapter->num_msix_vec = num_vec;
        return;
  }
  
 -static int be_sriov_enable(struct be_adapter *adapter)
 -{
 -      be_check_sriov_fn_type(adapter);
 -
 -#ifdef CONFIG_PCI_IOV
 -      if (be_physfn(adapter) && num_vfs) {
 -              int status, pos;
 -              u16 dev_vfs;
 -
 -              pos = pci_find_ext_capability(adapter->pdev,
 -                                              PCI_EXT_CAP_ID_SRIOV);
 -              pci_read_config_word(adapter->pdev,
 -                                   pos + PCI_SRIOV_TOTAL_VF, &dev_vfs);
 -
 -              adapter->num_vfs = min_t(u16, num_vfs, dev_vfs);
 -              if (adapter->num_vfs != num_vfs)
 -                      dev_info(&adapter->pdev->dev,
 -                               "Device supports %d VFs and not %d\n",
 -                               adapter->num_vfs, num_vfs);
 -
 -              status = pci_enable_sriov(adapter->pdev, adapter->num_vfs);
 -              if (status)
 -                      adapter->num_vfs = 0;
 -
 -              if (adapter->num_vfs) {
 -                      adapter->vf_cfg = kcalloc(num_vfs,
 -                                              sizeof(struct be_vf_cfg),
 -                                              GFP_KERNEL);
 -                      if (!adapter->vf_cfg)
 -                              return -ENOMEM;
 -              }
 -      }
 -#endif
 -      return 0;
 -}
 -
 -static void be_sriov_disable(struct be_adapter *adapter)
 -{
 -#ifdef CONFIG_PCI_IOV
 -      if (sriov_enabled(adapter)) {
 -              pci_disable_sriov(adapter->pdev);
 -              kfree(adapter->vf_cfg);
 -              adapter->num_vfs = 0;
 -      }
 -#endif
 -}
 -
  static inline int be_msix_vec_get(struct be_adapter *adapter,
                                struct be_eq_obj *eqo)
  {
@@@ -2283,6 -2299,8 +2300,8 @@@ static int be_close(struct net_device *
        struct be_eq_obj *eqo;
        int i;
  
+       be_roce_dev_close(adapter);
        be_async_mcc_disable(adapter);
  
        if (!lancer_chip(adapter))
@@@ -2391,6 -2409,7 +2410,7 @@@ static int be_open(struct net_device *n
        if (!status)
                be_link_status_update(adapter, link_status);
  
+       be_roce_dev_open(adapter);
        return 0;
  err:
        be_close(adapter->netdev);
@@@ -2476,11 -2495,6 +2496,11 @@@ static void be_vf_clear(struct be_adapt
        struct be_vf_cfg *vf_cfg;
        u32 vf;
  
 +      if (be_find_vfs(adapter, ASSIGNED)) {
 +              dev_warn(&adapter->pdev->dev, "VFs are assigned to VMs\n");
 +              goto done;
 +      }
 +
        for_all_vfs(adapter, vf_cfg, vf) {
                if (lancer_chip(adapter))
                        be_cmd_set_mac_list(adapter, NULL, 0, vf + 1);
  
                be_cmd_if_destroy(adapter, vf_cfg->if_handle, vf + 1);
        }
 +      pci_disable_sriov(adapter->pdev);
 +done:
 +      kfree(adapter->vf_cfg);
 +      adapter->num_vfs = 0;
  }
  
  static int be_clear(struct be_adapter *adapter)
        be_cmd_fw_clean(adapter);
  
        be_msix_disable(adapter);
 -      kfree(adapter->pmac_id);
 +      pci_write_config_dword(adapter->pdev, PCICFG_CUST_SCRATCHPAD_CSR, 0);
        return 0;
  }
  
 -static void be_vf_setup_init(struct be_adapter *adapter)
 +static int be_vf_setup_init(struct be_adapter *adapter)
  {
        struct be_vf_cfg *vf_cfg;
        int vf;
  
 +      adapter->vf_cfg = kcalloc(adapter->num_vfs, sizeof(*vf_cfg),
 +                                GFP_KERNEL);
 +      if (!adapter->vf_cfg)
 +              return -ENOMEM;
 +
        for_all_vfs(adapter, vf_cfg, vf) {
                vf_cfg->if_handle = -1;
                vf_cfg->pmac_id = -1;
        }
 +      return 0;
  }
  
  static int be_vf_setup(struct be_adapter *adapter)
  {
        struct be_vf_cfg *vf_cfg;
 +      struct device *dev = &adapter->pdev->dev;
        u32 cap_flags, en_flags, vf;
        u16 def_vlan, lnk_speed;
 -      int status;
 +      int status, enabled_vfs;
  
 -      be_vf_setup_init(adapter);
 +      enabled_vfs = be_find_vfs(adapter, ENABLED);
 +      if (enabled_vfs) {
 +              dev_warn(dev, "%d VFs are already enabled\n", enabled_vfs);
 +              dev_warn(dev, "Ignoring num_vfs=%d setting\n", num_vfs);
 +              return 0;
 +      }
 +
 +      if (num_vfs > adapter->dev_num_vfs) {
 +              dev_warn(dev, "Device supports %d VFs and not %d\n",
 +                       adapter->dev_num_vfs, num_vfs);
 +              num_vfs = adapter->dev_num_vfs;
 +      }
 +
 +      status = pci_enable_sriov(adapter->pdev, num_vfs);
 +      if (!status) {
 +              adapter->num_vfs = num_vfs;
 +      } else {
 +              /* Platform doesn't support SRIOV though device supports it */
 +              dev_warn(dev, "SRIOV enable failed\n");
 +              return 0;
 +      }
 +
 +      status = be_vf_setup_init(adapter);
 +      if (status)
 +              goto err;
  
        cap_flags = en_flags = BE_IF_FLAGS_UNTAGGED | BE_IF_FLAGS_BROADCAST |
                                BE_IF_FLAGS_MULTICAST;
                        goto err;
        }
  
 -      status = be_vf_eth_addr_config(adapter);
 -      if (status)
 -              goto err;
 +      if (!enabled_vfs) {
 +              status = be_vf_eth_addr_config(adapter);
 +              if (status)
 +                      goto err;
 +      }
  
        for_all_vfs(adapter, vf_cfg, vf) {
                status = be_cmd_link_status_query(adapter, NULL, &lnk_speed,
  static void be_setup_init(struct be_adapter *adapter)
  {
        adapter->vlan_prio_bmap = 0xff;
 -      adapter->link_speed = -1;
 +      adapter->phy.link_speed = -1;
        adapter->if_handle = -1;
        adapter->be3_native = false;
        adapter->promiscuous = false;
        adapter->eq_next_idx = 0;
 +      adapter->phy.forced_port_speed = -1;
  }
  
  static int be_add_mac_from_list(struct be_adapter *adapter, u8 *mac)
@@@ -2648,25 -2624,9 +2668,25 @@@ do_none
        return status;
  }
  
 +/* Routine to query per function resource limits */
 +static int be_get_config(struct be_adapter *adapter)
 +{
 +      int pos;
 +      u16 dev_num_vfs;
 +
 +      pos = pci_find_ext_capability(adapter->pdev, PCI_EXT_CAP_ID_SRIOV);
 +      if (pos) {
 +              pci_read_config_word(adapter->pdev, pos + PCI_SRIOV_TOTAL_VF,
 +                                   &dev_num_vfs);
 +              adapter->dev_num_vfs = dev_num_vfs;
 +      }
 +      return 0;
 +}
 +
  static int be_setup(struct be_adapter *adapter)
  {
        struct net_device *netdev = adapter->netdev;
 +      struct device *dev = &adapter->pdev->dev;
        u32 cap_flags, en_flags;
        u32 tx_fc, rx_fc;
        int status;
  
        be_setup_init(adapter);
  
 +      be_get_config(adapter);
 +
        be_cmd_req_native_mode(adapter);
  
        be_msix_enable(adapter);
  
        be_cmd_get_fw_ver(adapter, adapter->fw_ver, NULL);
  
 -      status = be_vid_config(adapter, false, 0);
 -      if (status)
 -              goto err;
 +      be_vid_config(adapter, false, 0);
  
        be_set_rx_mode(adapter->netdev);
  
 -      status = be_cmd_get_flow_control(adapter, &tx_fc, &rx_fc);
 -      /* For Lancer: It is legal for this cmd to fail on VF */
 -      if (status && (be_physfn(adapter) || !lancer_chip(adapter)))
 -              goto err;
 +      be_cmd_get_flow_control(adapter, &tx_fc, &rx_fc);
  
 -      if (rx_fc != adapter->rx_fc || tx_fc != adapter->tx_fc) {
 -              status = be_cmd_set_flow_control(adapter, adapter->tx_fc,
 +      if (rx_fc != adapter->rx_fc || tx_fc != adapter->tx_fc)
 +              be_cmd_set_flow_control(adapter, adapter->tx_fc,
                                        adapter->rx_fc);
 -              /* For Lancer: It is legal for this cmd to fail on VF */
 -              if (status && (be_physfn(adapter) || !lancer_chip(adapter)))
 -                      goto err;
 -      }
  
        pcie_set_readrq(adapter->pdev, 4096);
  
 -      if (sriov_enabled(adapter)) {
 -              status = be_vf_setup(adapter);
 -              if (status)
 -                      goto err;
 +      if (be_physfn(adapter) && num_vfs) {
 +              if (adapter->dev_num_vfs)
 +                      be_vf_setup(adapter);
 +              else
 +                      dev_warn(dev, "device doesn't support SRIOV\n");
        }
  
 +      be_cmd_get_phy_info(adapter);
 +      if (be_pause_supported(adapter))
 +              adapter->phy.fc_autoneg = 1;
 +
        schedule_delayed_work(&adapter->work, msecs_to_jiffies(1000));
        adapter->flags |= BE_FLAGS_WORKER_SCHEDULED;
  
 +      pci_write_config_dword(adapter->pdev, PCICFG_CUST_SCRATCHPAD_CSR, 1);
        return 0;
  err:
        be_clear(adapter);
@@@ -2790,8 -2751,6 +2810,8 @@@ static void be_netpoll(struct net_devic
  #endif
  
  #define FW_FILE_HDR_SIGN      "ServerEngines Corp. "
 +char flash_cookie[2][16] =      {"*** SE FLAS", "H DIRECTORY *** "};
 +
  static bool be_flash_redboot(struct be_adapter *adapter,
                        const u8 *p, u32 img_start, int image_size,
                        int hdr_size)
  
  static bool phy_flashing_required(struct be_adapter *adapter)
  {
 -      int status = 0;
 -      struct be_phy_info phy_info;
 +      return (adapter->phy.phy_type == TN_8022 &&
 +              adapter->phy.interface_type == PHY_TYPE_BASET_10GB);
 +}
  
 -      status = be_cmd_get_phy_info(adapter, &phy_info);
 -      if (status)
 -              return false;
 -      if ((phy_info.phy_type == TN_8022) &&
 -              (phy_info.interface_type == PHY_TYPE_BASET_10GB)) {
 -              return true;
 +static bool is_comp_in_ufi(struct be_adapter *adapter,
 +                         struct flash_section_info *fsec, int type)
 +{
 +      int i = 0, img_type = 0;
 +      struct flash_section_info_g2 *fsec_g2 = NULL;
 +
 +      if (adapter->generation != BE_GEN3)
 +              fsec_g2 = (struct flash_section_info_g2 *)fsec;
 +
 +      for (i = 0; i < MAX_FLASH_COMP; i++) {
 +              if (fsec_g2)
 +                      img_type = le32_to_cpu(fsec_g2->fsec_entry[i].type);
 +              else
 +                      img_type = le32_to_cpu(fsec->fsec_entry[i].type);
 +
 +              if (img_type == type)
 +                      return true;
        }
        return false;
 +
 +}
 +
 +struct flash_section_info *get_fsec_info(struct be_adapter *adapter,
 +                                       int header_size,
 +                                       const struct firmware *fw)
 +{
 +      struct flash_section_info *fsec = NULL;
 +      const u8 *p = fw->data;
 +
 +      p += header_size;
 +      while (p < (fw->data + fw->size)) {
 +              fsec = (struct flash_section_info *)p;
 +              if (!memcmp(flash_cookie, fsec->cookie, sizeof(flash_cookie)))
 +                      return fsec;
 +              p += 32;
 +      }
 +      return NULL;
  }
  
  static int be_flash_data(struct be_adapter *adapter,
 -                      const struct firmware *fw,
 -                      struct be_dma_mem *flash_cmd, int num_of_images)
 +                       const struct firmware *fw,
 +                       struct be_dma_mem *flash_cmd,
 +                       int num_of_images)
  
  {
        int status = 0, i, filehdr_size = 0;
 +      int img_hdrs_size = (num_of_images * sizeof(struct image_hdr));
        u32 total_bytes = 0, flash_op;
        int num_bytes;
        const u8 *p = fw->data;
        struct be_cmd_write_flashrom *req = flash_cmd->va;
        const struct flash_comp *pflashcomp;
 -      int num_comp;
 -
 -      static const struct flash_comp gen3_flash_types[10] = {
 -              { FLASH_iSCSI_PRIMARY_IMAGE_START_g3, IMG_TYPE_ISCSI_ACTIVE,
 -                      FLASH_IMAGE_MAX_SIZE_g3},
 -              { FLASH_REDBOOT_START_g3, IMG_TYPE_REDBOOT,
 -                      FLASH_REDBOOT_IMAGE_MAX_SIZE_g3},
 -              { FLASH_iSCSI_BIOS_START_g3, IMG_TYPE_BIOS,
 -                      FLASH_BIOS_IMAGE_MAX_SIZE_g3},
 -              { FLASH_PXE_BIOS_START_g3, IMG_TYPE_PXE_BIOS,
 -                      FLASH_BIOS_IMAGE_MAX_SIZE_g3},
 -              { FLASH_FCoE_BIOS_START_g3, IMG_TYPE_FCOE_BIOS,
 -                      FLASH_BIOS_IMAGE_MAX_SIZE_g3},
 -              { FLASH_iSCSI_BACKUP_IMAGE_START_g3, IMG_TYPE_ISCSI_BACKUP,
 -                      FLASH_IMAGE_MAX_SIZE_g3},
 -              { FLASH_FCoE_PRIMARY_IMAGE_START_g3, IMG_TYPE_FCOE_FW_ACTIVE,
 -                      FLASH_IMAGE_MAX_SIZE_g3},
 -              { FLASH_FCoE_BACKUP_IMAGE_START_g3, IMG_TYPE_FCOE_FW_BACKUP,
 -                      FLASH_IMAGE_MAX_SIZE_g3},
 -              { FLASH_NCSI_START_g3, IMG_TYPE_NCSI_FW,
 -                      FLASH_NCSI_IMAGE_MAX_SIZE_g3},
 -              { FLASH_PHY_FW_START_g3, IMG_TYPE_PHY_FW,
 -                      FLASH_PHY_FW_IMAGE_MAX_SIZE_g3}
 +      int num_comp, hdr_size;
 +      struct flash_section_info *fsec = NULL;
 +
 +      struct flash_comp gen3_flash_types[] = {
 +              { FLASH_iSCSI_PRIMARY_IMAGE_START_g3, OPTYPE_ISCSI_ACTIVE,
 +                      FLASH_IMAGE_MAX_SIZE_g3, IMAGE_FIRMWARE_iSCSI},
 +              { FLASH_REDBOOT_START_g3, OPTYPE_REDBOOT,
 +                      FLASH_REDBOOT_IMAGE_MAX_SIZE_g3, IMAGE_BOOT_CODE},
 +              { FLASH_iSCSI_BIOS_START_g3, OPTYPE_BIOS,
 +                      FLASH_BIOS_IMAGE_MAX_SIZE_g3, IMAGE_OPTION_ROM_ISCSI},
 +              { FLASH_PXE_BIOS_START_g3, OPTYPE_PXE_BIOS,
 +                      FLASH_BIOS_IMAGE_MAX_SIZE_g3, IMAGE_OPTION_ROM_PXE},
 +              { FLASH_FCoE_BIOS_START_g3, OPTYPE_FCOE_BIOS,
 +                      FLASH_BIOS_IMAGE_MAX_SIZE_g3, IMAGE_OPTION_ROM_FCoE},
 +              { FLASH_iSCSI_BACKUP_IMAGE_START_g3, OPTYPE_ISCSI_BACKUP,
 +                      FLASH_IMAGE_MAX_SIZE_g3, IMAGE_FIRMWARE_BACKUP_iSCSI},
 +              { FLASH_FCoE_PRIMARY_IMAGE_START_g3, OPTYPE_FCOE_FW_ACTIVE,
 +                      FLASH_IMAGE_MAX_SIZE_g3, IMAGE_FIRMWARE_FCoE},
 +              { FLASH_FCoE_BACKUP_IMAGE_START_g3, OPTYPE_FCOE_FW_BACKUP,
 +                      FLASH_IMAGE_MAX_SIZE_g3, IMAGE_FIRMWARE_BACKUP_FCoE},
 +              { FLASH_NCSI_START_g3, OPTYPE_NCSI_FW,
 +                      FLASH_NCSI_IMAGE_MAX_SIZE_g3, IMAGE_NCSI},
 +              { FLASH_PHY_FW_START_g3, OPTYPE_PHY_FW,
 +                      FLASH_PHY_FW_IMAGE_MAX_SIZE_g3, IMAGE_FIRMWARE_PHY}
        };
 -      static const struct flash_comp gen2_flash_types[8] = {
 -              { FLASH_iSCSI_PRIMARY_IMAGE_START_g2, IMG_TYPE_ISCSI_ACTIVE,
 -                      FLASH_IMAGE_MAX_SIZE_g2},
 -              { FLASH_REDBOOT_START_g2, IMG_TYPE_REDBOOT,
 -                      FLASH_REDBOOT_IMAGE_MAX_SIZE_g2},
 -              { FLASH_iSCSI_BIOS_START_g2, IMG_TYPE_BIOS,
 -                      FLASH_BIOS_IMAGE_MAX_SIZE_g2},
 -              { FLASH_PXE_BIOS_START_g2, IMG_TYPE_PXE_BIOS,
 -                      FLASH_BIOS_IMAGE_MAX_SIZE_g2},
 -              { FLASH_FCoE_BIOS_START_g2, IMG_TYPE_FCOE_BIOS,
 -                      FLASH_BIOS_IMAGE_MAX_SIZE_g2},
 -              { FLASH_iSCSI_BACKUP_IMAGE_START_g2, IMG_TYPE_ISCSI_BACKUP,
 -                      FLASH_IMAGE_MAX_SIZE_g2},
 -              { FLASH_FCoE_PRIMARY_IMAGE_START_g2, IMG_TYPE_FCOE_FW_ACTIVE,
 -                      FLASH_IMAGE_MAX_SIZE_g2},
 -              { FLASH_FCoE_BACKUP_IMAGE_START_g2, IMG_TYPE_FCOE_FW_BACKUP,
 -                       FLASH_IMAGE_MAX_SIZE_g2}
 +
 +      struct flash_comp gen2_flash_types[] = {
 +              { FLASH_iSCSI_PRIMARY_IMAGE_START_g2, OPTYPE_ISCSI_ACTIVE,
 +                      FLASH_IMAGE_MAX_SIZE_g2, IMAGE_FIRMWARE_iSCSI},
 +              { FLASH_REDBOOT_START_g2, OPTYPE_REDBOOT,
 +                      FLASH_REDBOOT_IMAGE_MAX_SIZE_g2, IMAGE_BOOT_CODE},
 +              { FLASH_iSCSI_BIOS_START_g2, OPTYPE_BIOS,
 +                      FLASH_BIOS_IMAGE_MAX_SIZE_g2, IMAGE_OPTION_ROM_ISCSI},
 +              { FLASH_PXE_BIOS_START_g2, OPTYPE_PXE_BIOS,
 +                      FLASH_BIOS_IMAGE_MAX_SIZE_g2, IMAGE_OPTION_ROM_PXE},
 +              { FLASH_FCoE_BIOS_START_g2, OPTYPE_FCOE_BIOS,
 +                      FLASH_BIOS_IMAGE_MAX_SIZE_g2, IMAGE_OPTION_ROM_FCoE},
 +              { FLASH_iSCSI_BACKUP_IMAGE_START_g2, OPTYPE_ISCSI_BACKUP,
 +                      FLASH_IMAGE_MAX_SIZE_g2, IMAGE_FIRMWARE_BACKUP_iSCSI},
 +              { FLASH_FCoE_PRIMARY_IMAGE_START_g2, OPTYPE_FCOE_FW_ACTIVE,
 +                      FLASH_IMAGE_MAX_SIZE_g2, IMAGE_FIRMWARE_FCoE},
 +              { FLASH_FCoE_BACKUP_IMAGE_START_g2, OPTYPE_FCOE_FW_BACKUP,
 +                       FLASH_IMAGE_MAX_SIZE_g2, IMAGE_FIRMWARE_BACKUP_FCoE}
        };
  
        if (adapter->generation == BE_GEN3) {
                filehdr_size = sizeof(struct flash_file_hdr_g2);
                num_comp = ARRAY_SIZE(gen2_flash_types);
        }
 +      /* Get flash section info*/
 +      fsec = get_fsec_info(adapter, filehdr_size + img_hdrs_size, fw);
 +      if (!fsec) {
 +              dev_err(&adapter->pdev->dev,
 +                      "Invalid Cookie. UFI corrupted ?\n");
 +              return -1;
 +      }
        for (i = 0; i < num_comp; i++) {
 -              if ((pflashcomp[i].optype == IMG_TYPE_NCSI_FW) &&
 -                              memcmp(adapter->fw_ver, "3.102.148.0", 11) < 0)
 +              if (!is_comp_in_ufi(adapter, fsec, pflashcomp[i].img_type))
 +                      continue;
 +
 +              if ((pflashcomp[i].optype == OPTYPE_NCSI_FW) &&
 +                  memcmp(adapter->fw_ver, "3.102.148.0", 11) < 0)
                        continue;
 -              if (pflashcomp[i].optype == IMG_TYPE_PHY_FW) {
 +
 +              if (pflashcomp[i].optype == OPTYPE_PHY_FW) {
                        if (!phy_flashing_required(adapter))
                                continue;
                }
 -              if ((pflashcomp[i].optype == IMG_TYPE_REDBOOT) &&
 -                      (!be_flash_redboot(adapter, fw->data,
 -                      pflashcomp[i].offset, pflashcomp[i].size, filehdr_size +
 -                      (num_of_images * sizeof(struct image_hdr)))))
 +
 +              hdr_size = filehdr_size +
 +                         (num_of_images * sizeof(struct image_hdr));
 +
 +              if ((pflashcomp[i].optype == OPTYPE_REDBOOT) &&
 +                  (!be_flash_redboot(adapter, fw->data, pflashcomp[i].offset,
 +                                     pflashcomp[i].size, hdr_size)))
                        continue;
 +
 +              /* Flash the component */
                p = fw->data;
 -              p += filehdr_size + pflashcomp[i].offset
 -                      + (num_of_images * sizeof(struct image_hdr));
 +              p += filehdr_size + pflashcomp[i].offset + img_hdrs_size;
                if (p + pflashcomp[i].size > fw->data + fw->size)
                        return -1;
                total_bytes = pflashcomp[i].size;
                                num_bytes = total_bytes;
                        total_bytes -= num_bytes;
                        if (!total_bytes) {
 -                              if (pflashcomp[i].optype == IMG_TYPE_PHY_FW)
 +                              if (pflashcomp[i].optype == OPTYPE_PHY_FW)
                                        flash_op = FLASHROM_OPER_PHY_FLASH;
                                else
                                        flash_op = FLASHROM_OPER_FLASH;
                        } else {
 -                              if (pflashcomp[i].optype == IMG_TYPE_PHY_FW)
 +                              if (pflashcomp[i].optype == OPTYPE_PHY_FW)
                                        flash_op = FLASHROM_OPER_PHY_SAVE;
                                else
                                        flash_op = FLASHROM_OPER_SAVE;
                        if (status) {
                                if ((status == ILLEGAL_IOCTL_REQ) &&
                                        (pflashcomp[i].optype ==
 -                                              IMG_TYPE_PHY_FW))
 +                                              OPTYPE_PHY_FW))
                                        break;
                                dev_err(&adapter->pdev->dev,
                                        "cmd to write to flash rom failed.\n");
@@@ -3232,6 -3142,24 +3252,24 @@@ static void be_unmap_pci_bars(struct be
                iounmap(adapter->csr);
        if (adapter->db)
                iounmap(adapter->db);
+       if (adapter->roce_db.base)
+               pci_iounmap(adapter->pdev, adapter->roce_db.base);
+ }
+ static int lancer_roce_map_pci_bars(struct be_adapter *adapter)
+ {
+       struct pci_dev *pdev = adapter->pdev;
+       u8 __iomem *addr;
+       addr = pci_iomap(pdev, 2, 0);
+       if (addr == NULL)
+               return -ENOMEM;
+       adapter->roce_db.base = addr;
+       adapter->roce_db.io_addr = pci_resource_start(pdev, 2);
+       adapter->roce_db.size = 8192;
+       adapter->roce_db.total_size = pci_resource_len(pdev, 2);
+       return 0;
  }
  
  static int be_map_pci_bars(struct be_adapter *adapter)
        int db_reg;
  
        if (lancer_chip(adapter)) {
-               addr = ioremap_nocache(pci_resource_start(adapter->pdev, 0),
-                       pci_resource_len(adapter->pdev, 0));
-               if (addr == NULL)
-                       return -ENOMEM;
-               adapter->db = addr;
+               if (be_type_2_3(adapter)) {
+                       addr = ioremap_nocache(
+                                       pci_resource_start(adapter->pdev, 0),
+                                       pci_resource_len(adapter->pdev, 0));
+                       if (addr == NULL)
+                               return -ENOMEM;
+                       adapter->db = addr;
+               }
+               if (adapter->if_type == SLI_INTF_TYPE_3) {
+                       if (lancer_roce_map_pci_bars(adapter))
+                               goto pci_map_err;
+               }
                return 0;
        }
  
        if (addr == NULL)
                goto pci_map_err;
        adapter->db = addr;
+       if (adapter->sli_family == SKYHAWK_SLI_FAMILY) {
+               adapter->roce_db.size = 4096;
+               adapter->roce_db.io_addr =
+                               pci_resource_start(adapter->pdev, db_reg);
+               adapter->roce_db.total_size =
+                               pci_resource_len(adapter->pdev, db_reg);
+       }
        return 0;
  pci_map_err:
        be_unmap_pci_bars(adapter);
        return -ENOMEM;
  }
  
  static void be_ctrl_cleanup(struct be_adapter *adapter)
  {
        struct be_dma_mem *mem = &adapter->mbox_mem_alloced;
@@@ -3382,6 -3322,8 +3432,8 @@@ static void __devexit be_remove(struct 
        if (!adapter)
                return;
  
+       be_roce_dev_remove(adapter);
        unregister_netdev(adapter->netdev);
  
        be_clear(adapter);
  
        be_ctrl_cleanup(adapter);
  
 -      be_sriov_disable(adapter);
 -
        pci_set_drvdata(pdev, NULL);
        pci_release_regions(pdev);
        pci_disable_device(pdev);
@@@ -3403,43 -3347,9 +3455,43 @@@ bool be_is_wol_supported(struct be_adap
                !be_is_wol_excluded(adapter)) ? true : false;
  }
  
 -static int be_get_config(struct be_adapter *adapter)
 +u32 be_get_fw_log_level(struct be_adapter *adapter)
  {
 +      struct be_dma_mem extfat_cmd;
 +      struct be_fat_conf_params *cfgs;
        int status;
 +      u32 level = 0;
 +      int j;
 +
 +      memset(&extfat_cmd, 0, sizeof(struct be_dma_mem));
 +      extfat_cmd.size = sizeof(struct be_cmd_resp_get_ext_fat_caps);
 +      extfat_cmd.va = pci_alloc_consistent(adapter->pdev, extfat_cmd.size,
 +                                           &extfat_cmd.dma);
 +
 +      if (!extfat_cmd.va) {
 +              dev_err(&adapter->pdev->dev, "%s: Memory allocation failure\n",
 +                      __func__);
 +              goto err;
 +      }
 +
 +      status = be_cmd_get_ext_fat_capabilites(adapter, &extfat_cmd);
 +      if (!status) {
 +              cfgs = (struct be_fat_conf_params *)(extfat_cmd.va +
 +                                              sizeof(struct be_cmd_resp_hdr));
 +              for (j = 0; j < cfgs->module[0].num_modes; j++) {
 +                      if (cfgs->module[0].trace_lvl[j].mode == MODE_UART)
 +                              level = cfgs->module[0].trace_lvl[j].dbg_lvl;
 +              }
 +      }
 +      pci_free_consistent(adapter->pdev, extfat_cmd.size, extfat_cmd.va,
 +                          extfat_cmd.dma);
 +err:
 +      return level;
 +}
 +static int be_get_initial_config(struct be_adapter *adapter)
 +{
 +      int status;
 +      u32 level;
  
        status = be_cmd_query_fw_cfg(adapter, &adapter->port_num,
                        &adapter->function_mode, &adapter->function_caps);
        if (be_is_wol_supported(adapter))
                adapter->wol = true;
  
 +      level = be_get_fw_log_level(adapter);
 +      adapter->msg_enable = level <= FW_LOG_LEVEL_DEFAULT ? NETIF_MSG_HW : 0;
 +
        return 0;
  }
  
 -static int be_dev_family_check(struct be_adapter *adapter)
 +static int be_dev_type_check(struct be_adapter *adapter)
  {
        struct pci_dev *pdev = adapter->pdev;
        u32 sli_intf = 0, if_type;
                break;
        case BE_DEVICE_ID2:
        case OC_DEVICE_ID2:
-       case OC_DEVICE_ID5:
                adapter->generation = BE_GEN3;
                break;
        case OC_DEVICE_ID3:
        case OC_DEVICE_ID4:
                pci_read_config_dword(pdev, SLI_INTF_REG_OFFSET, &sli_intf);
+               adapter->if_type = (sli_intf & SLI_INTF_IF_TYPE_MASK) >>
+                                               SLI_INTF_IF_TYPE_SHIFT;
                if_type = (sli_intf & SLI_INTF_IF_TYPE_MASK) >>
                                                SLI_INTF_IF_TYPE_SHIFT;
                if (((sli_intf & SLI_INTF_VALID_MASK) != SLI_INTF_VALID) ||
-                       if_type != 0x02) {
+                       !be_type_2_3(adapter)) {
+                       dev_err(&pdev->dev, "SLI_INTF reg val is not valid\n");
+                       return -EINVAL;
+               }
+               adapter->sli_family = ((sli_intf & SLI_INTF_FAMILY_MASK) >>
+                                        SLI_INTF_FAMILY_SHIFT);
+               adapter->generation = BE_GEN3;
+               break;
+       case OC_DEVICE_ID5:
+               pci_read_config_dword(pdev, SLI_INTF_REG_OFFSET, &sli_intf);
+               if ((sli_intf & SLI_INTF_VALID_MASK) != SLI_INTF_VALID) {
                        dev_err(&pdev->dev, "SLI_INTF reg val is not valid\n");
                        return -EINVAL;
                }
        default:
                adapter->generation = 0;
        }
 +
 +      pci_read_config_dword(adapter->pdev, SLI_INTF_REG_OFFSET, &sli_intf);
 +      adapter->virtfn = (sli_intf & SLI_INTF_FT_MASK) ? 1 : 0;
        return 0;
  }
  
@@@ -3662,14 -3576,6 +3724,14 @@@ reschedule
        schedule_delayed_work(&adapter->work, msecs_to_jiffies(1000));
  }
  
 +static bool be_reset_required(struct be_adapter *adapter)
 +{
 +      u32 reg;
 +
 +      pci_read_config_dword(adapter->pdev, PCICFG_CUST_SCRATCHPAD_CSR, &reg);
 +      return reg;
 +}
 +
  static int __devinit be_probe(struct pci_dev *pdev,
                        const struct pci_device_id *pdev_id)
  {
        adapter->pdev = pdev;
        pci_set_drvdata(pdev, adapter);
  
 -      status = be_dev_family_check(adapter);
 +      status = be_dev_type_check(adapter);
        if (status)
                goto free_netdev;
  
                }
        }
  
 -      status = be_sriov_enable(adapter);
 -      if (status)
 -              goto free_netdev;
 -
        status = be_ctrl_init(adapter);
        if (status)
 -              goto disable_sriov;
 +              goto free_netdev;
  
        if (lancer_chip(adapter)) {
                status = lancer_wait_ready(adapter);
        if (status)
                goto ctrl_clean;
  
 -      status = be_cmd_reset_function(adapter);
 -      if (status)
 -              goto ctrl_clean;
 +      if (be_reset_required(adapter)) {
 +              status = be_cmd_reset_function(adapter);
 +              if (status)
 +                      goto ctrl_clean;
 +      }
  
        /* The INTR bit may be set in the card when probed by a kdump kernel
         * after a crash.
        if (status)
                goto ctrl_clean;
  
 -      status = be_get_config(adapter);
 +      status = be_get_initial_config(adapter);
        if (status)
                goto stats_clean;
  
        if (status != 0)
                goto unsetup;
  
+       be_roce_dev_add(adapter);
        dev_info(&pdev->dev, "%s: %s port %d\n", netdev->name, nic_name(pdev),
                adapter->port_num);
  
@@@ -3787,6 -3697,8 +3851,6 @@@ stats_clean
        be_stats_cleanup(adapter);
  ctrl_clean:
        be_ctrl_cleanup(adapter);
 -disable_sriov:
 -      be_sriov_disable(adapter);
  free_netdev:
        free_netdev(netdev);
        pci_set_drvdata(pdev, NULL);
@@@ -3901,11 -3813,6 +3965,11 @@@ static pci_ers_result_t be_eeh_err_dete
  
        pci_disable_device(pdev);
  
 +      /* The error could cause the FW to trigger a flash debug dump.
 +       * Resetting the card while flash dump is in progress
 +       * can cause it not to recover; wait for it to finish
 +       */
 +      ssleep(30);
        return PCI_ERS_RESULT_NEED_RESET;
  }
  
index 24429a99190d9101a10ed8c092fef6e56caca7bf,f7488dfef8ebcd67f7b25f884df671a97887930a..68f5cd6cb3c7c4291edd5f0972d586389ccd1fa1
@@@ -118,6 -118,20 +118,20 @@@ static void dump_dev_cap_flags(struct m
                        mlx4_dbg(dev, "    %s\n", fname[i]);
  }
  
+ static void dump_dev_cap_flags2(struct mlx4_dev *dev, u64 flags)
+ {
+       static const char * const fname[] = {
+               [0] = "RSS support",
+               [1] = "RSS Toeplitz Hash Function support",
+               [2] = "RSS XOR Hash Function support"
+       };
+       int i;
+       for (i = 0; i < ARRAY_SIZE(fname); ++i)
+               if (fname[i] && (flags & (1LL << i)))
+                       mlx4_dbg(dev, "    %s\n", fname[i]);
+ }
  int mlx4_MOD_STAT_CFG(struct mlx4_dev *dev, struct mlx4_mod_stat_cfg *cfg)
  {
        struct mlx4_cmd_mailbox *mailbox;
@@@ -346,6 -360,7 +360,7 @@@ int mlx4_QUERY_DEV_CAP(struct mlx4_dev 
  #define QUERY_DEV_CAP_MAX_REQ_QP_OFFSET               0x29
  #define QUERY_DEV_CAP_MAX_RES_QP_OFFSET               0x2b
  #define QUERY_DEV_CAP_MAX_GSO_OFFSET          0x2d
+ #define QUERY_DEV_CAP_RSS_OFFSET              0x2e
  #define QUERY_DEV_CAP_MAX_RDMA_OFFSET         0x2f
  #define QUERY_DEV_CAP_RSZ_SRQ_OFFSET          0x33
  #define QUERY_DEV_CAP_ACK_DELAY_OFFSET                0x35
  #define QUERY_DEV_CAP_RSVD_LKEY_OFFSET                0x98
  #define QUERY_DEV_CAP_MAX_ICM_SZ_OFFSET               0xa0
  
+       dev_cap->flags2 = 0;
        mailbox = mlx4_alloc_cmd_mailbox(dev);
        if (IS_ERR(mailbox))
                return PTR_ERR(mailbox);
        else
                dev_cap->max_gso_sz = 1 << field;
  
+       MLX4_GET(field, outbox, QUERY_DEV_CAP_RSS_OFFSET);
+       if (field & 0x20)
+               dev_cap->flags2 |= MLX4_DEV_CAP_FLAG2_RSS_XOR;
+       if (field & 0x10)
+               dev_cap->flags2 |= MLX4_DEV_CAP_FLAG2_RSS_TOP;
+       field &= 0xf;
+       if (field) {
+               dev_cap->flags2 |= MLX4_DEV_CAP_FLAG2_RSS;
+               dev_cap->max_rss_tbl_sz = 1 << field;
+       } else
+               dev_cap->max_rss_tbl_sz = 0;
        MLX4_GET(field, outbox, QUERY_DEV_CAP_MAX_RDMA_OFFSET);
        dev_cap->max_rdma_global = 1 << (field & 0x3f);
        MLX4_GET(field, outbox, QUERY_DEV_CAP_ACK_DELAY_OFFSET);
                 dev_cap->max_rq_desc_sz, dev_cap->max_rq_sg);
        mlx4_dbg(dev, "Max GSO size: %d\n", dev_cap->max_gso_sz);
        mlx4_dbg(dev, "Max counters: %d\n", dev_cap->max_counters);
+       mlx4_dbg(dev, "Max RSS Table size: %d\n", dev_cap->max_rss_tbl_sz);
  
        dump_dev_cap_flags(dev, dev_cap->flags);
+       dump_dev_cap_flags2(dev, dev_cap->flags2);
  
  out:
        mlx4_free_cmd_mailbox(dev, mailbox);
@@@ -1164,8 -1193,9 +1193,8 @@@ int mlx4_INIT_PORT_wrapper(struct mlx4_
                               MLX4_CMD_TIME_CLASS_A, MLX4_CMD_NATIVE);
                if (err)
                        return err;
 -              priv->mfunc.master.slave_state[slave].init_port_mask |=
 -                      (1 << port);
        }
 +      priv->mfunc.master.slave_state[slave].init_port_mask |= (1 << port);
        ++priv->mfunc.master.init_port_ref[port];
        return 0;
  }
index 984ace44104f6418850198a2c13ea558d17abc85,bb04a82087802335aaf5ffa89694b8e307bbd122..2e024a68fa814573d858ac382147f1f4d923b835
@@@ -272,10 -272,12 +272,12 @@@ static int mlx4_dev_cap(struct mlx4_de
        dev->caps.max_msg_sz         = dev_cap->max_msg_sz;
        dev->caps.page_size_cap      = ~(u32) (dev_cap->min_page_sz - 1);
        dev->caps.flags              = dev_cap->flags;
+       dev->caps.flags2             = dev_cap->flags2;
        dev->caps.bmme_flags         = dev_cap->bmme_flags;
        dev->caps.reserved_lkey      = dev_cap->reserved_lkey;
        dev->caps.stat_rate_support  = dev_cap->stat_rate_support;
        dev->caps.max_gso_sz         = dev_cap->max_gso_sz;
+       dev->caps.max_rss_tbl_sz     = dev_cap->max_rss_tbl_sz;
  
        /* Sense port always allowed on supported devices for ConnectX1 and 2 */
        if (dev->pdev->device != 0x1003)
@@@ -1306,7 -1308,7 +1308,7 @@@ static void mlx4_cleanup_counters_table
        mlx4_bitmap_cleanup(&mlx4_priv(dev)->counters_bitmap);
  }
  
 -int mlx4_counter_alloc(struct mlx4_dev *dev, u32 *idx)
 +int __mlx4_counter_alloc(struct mlx4_dev *dev, u32 *idx)
  {
        struct mlx4_priv *priv = mlx4_priv(dev);
  
  
        return 0;
  }
 +
 +int mlx4_counter_alloc(struct mlx4_dev *dev, u32 *idx)
 +{
 +      u64 out_param;
 +      int err;
 +
 +      if (mlx4_is_mfunc(dev)) {
 +              err = mlx4_cmd_imm(dev, 0, &out_param, RES_COUNTER,
 +                                 RES_OP_RESERVE, MLX4_CMD_ALLOC_RES,
 +                                 MLX4_CMD_TIME_CLASS_A, MLX4_CMD_WRAPPED);
 +              if (!err)
 +                      *idx = get_param_l(&out_param);
 +
 +              return err;
 +      }
 +      return __mlx4_counter_alloc(dev, idx);
 +}
  EXPORT_SYMBOL_GPL(mlx4_counter_alloc);
  
 -void mlx4_counter_free(struct mlx4_dev *dev, u32 idx)
 +void __mlx4_counter_free(struct mlx4_dev *dev, u32 idx)
  {
        mlx4_bitmap_free(&mlx4_priv(dev)->counters_bitmap, idx);
        return;
  }
 +
 +void mlx4_counter_free(struct mlx4_dev *dev, u32 idx)
 +{
 +      u64 in_param;
 +
 +      if (mlx4_is_mfunc(dev)) {
 +              set_param_l(&in_param, idx);
 +              mlx4_cmd(dev, in_param, RES_COUNTER, RES_OP_RESERVE,
 +                       MLX4_CMD_FREE_RES, MLX4_CMD_TIME_CLASS_A,
 +                       MLX4_CMD_WRAPPED);
 +              return;
 +      }
 +      __mlx4_counter_free(dev, idx);
 +}
  EXPORT_SYMBOL_GPL(mlx4_counter_free);
  
  static int mlx4_setup_hca(struct mlx4_dev *dev)
@@@ -1896,6 -1867,7 +1898,6 @@@ static int __mlx4_init_one(struct pci_d
                                mlx4_err(dev, "Failed to enable sriov,"
                                         "continuing without sriov enabled"
                                         " (err = %d).\n", err);
 -                              num_vfs = 0;
                                err = 0;
                        } else {
                                mlx4_warn(dev, "Running in master mode\n");
@@@ -2052,7 -2024,7 +2054,7 @@@ err_cmd
        mlx4_cmd_cleanup(dev);
  
  err_sriov:
 -      if (num_vfs && (dev->flags & MLX4_FLAG_SRIOV))
 +      if (dev->flags & MLX4_FLAG_SRIOV)
                pci_disable_sriov(pdev);
  
  err_rel_own:
@@@ -2100,10 -2072,6 +2102,10 @@@ static void mlx4_remove_one(struct pci_
                        mlx4_CLOSE_PORT(dev, p);
                }
  
 +              if (mlx4_is_master(dev))
 +                      mlx4_free_resource_tracker(dev,
 +                                                 RES_TR_FREE_SLAVES_ONLY);
 +
                mlx4_cleanup_counters_table(dev);
                mlx4_cleanup_mcg_table(dev);
                mlx4_cleanup_qp_table(dev);
                mlx4_cleanup_pd_table(dev);
  
                if (mlx4_is_master(dev))
 -                      mlx4_free_resource_tracker(dev);
 +                      mlx4_free_resource_tracker(dev,
 +                                                 RES_TR_FREE_STRUCTS_ONLY);
  
                iounmap(priv->kar);
                mlx4_uar_free(dev, &priv->driver_uar);
  
                if (dev->flags & MLX4_FLAG_MSI_X)
                        pci_disable_msix(pdev);
 -              if (num_vfs && (dev->flags & MLX4_FLAG_SRIOV)) {
 +              if (dev->flags & MLX4_FLAG_SRIOV) {
                        mlx4_warn(dev, "Disabling sriov\n");
                        pci_disable_sriov(pdev);
                }
index 6d028247f79dedef0067482c04cf17b408480fd4,7f5e8d564e8e5e0d22d1540ce5d186ec3cbb6701..6e27fa99e8b978d785c196ca5acb89123058f14d
@@@ -98,6 -98,12 +98,12 @@@ enum 
        MLX4_DEV_CAP_FLAG_SENSE_SUPPORT = 1LL << 55
  };
  
+ enum {
+       MLX4_DEV_CAP_FLAG2_RSS                  = 1LL <<  0,
+       MLX4_DEV_CAP_FLAG2_RSS_TOP              = 1LL <<  1,
+       MLX4_DEV_CAP_FLAG2_RSS_XOR              = 1LL <<  2
+ };
  #define MLX4_ATTR_EXTENDED_PORT_INFO  cpu_to_be16(0xff90)
  
  enum {
@@@ -292,11 -298,13 +298,13 @@@ struct mlx4_caps 
        u32                     max_msg_sz;
        u32                     page_size_cap;
        u64                     flags;
+       u64                     flags2;
        u32                     bmme_flags;
        u32                     reserved_lkey;
        u16                     stat_rate_support;
        u8                      port_width_cap[MLX4_MAX_PORTS + 1];
        int                     max_gso_sz;
+       int                     max_rss_tbl_sz;
        int                     reserved_qps_cnt[MLX4_NUM_QP_REGION];
        int                     reserved_qps;
        int                     reserved_qps_base[MLX4_NUM_QP_REGION];
@@@ -628,9 -636,6 +636,9 @@@ int mlx4_SET_PORT_general(struct mlx4_d
                          u8 pptx, u8 pfctx, u8 pprx, u8 pfcrx);
  int mlx4_SET_PORT_qpn_calc(struct mlx4_dev *dev, u8 port, u32 base_qpn,
                           u8 promisc);
 +int mlx4_SET_PORT_PRIO2TC(struct mlx4_dev *dev, u8 port, u8 *prio2tc);
 +int mlx4_SET_PORT_SCHEDULER(struct mlx4_dev *dev, u8 port, u8 *tc_tx_bw,
 +              u8 *pg, u16 *ratelimit);
  int mlx4_find_cached_vlan(struct mlx4_dev *dev, u8 port, u16 vid, int *idx);
  int mlx4_register_vlan(struct mlx4_dev *dev, u8 port, u16 vlan, int *index);
  void mlx4_unregister_vlan(struct mlx4_dev *dev, u8 port, int index);
diff --combined include/linux/mlx4/qp.h
index 96005d75893c7b91abcfb6e38ddd3c65e74463ff,bb57d5c58df2fea4ee6c821d3bb8a8dbc87a8653..338388ba260a14887321889ee25fb8b3d64cb9e4
@@@ -139,8 -139,7 +139,8 @@@ struct mlx4_qp_path 
        u8                      rgid[16];
        u8                      sched_queue;
        u8                      vlan_index;
 -      u8                      reserved3[2];
 +      u8                      feup;
 +      u8                      reserved3;
        u8                      reserved4[2];
        u8                      dmac[6];
  };
@@@ -234,7 -233,8 +234,8 @@@ struct mlx4_wqe_mlx_seg 
        u8                      owner;
        u8                      reserved1[2];
        u8                      opcode;
-       u8                      reserved2[3];
+       __be16                  sched_prio;
+       u8                      reserved2;
        u8                      size;
        /*
         * [17]    VL15