struct delayed_work func_recovery_work;
        u32 flags;
+       u32 cmd_privileges;
        /* Ethtool knobs and info */
        char fw_ver[FW_VER_LEN];
        int if_handle;          /* Used to configure filtering */
 
 #include "be.h"
 #include "be_cmds.h"
 
+static struct be_cmd_priv_map cmd_priv_map[] = {
+       {
+               OPCODE_ETH_ACPI_WOL_MAGIC_CONFIG,
+               CMD_SUBSYSTEM_ETH,
+               BE_PRIV_LNKMGMT | BE_PRIV_VHADM |
+               BE_PRIV_DEVCFG | BE_PRIV_DEVSEC
+       },
+       {
+               OPCODE_COMMON_GET_FLOW_CONTROL,
+               CMD_SUBSYSTEM_COMMON,
+               BE_PRIV_LNKQUERY | BE_PRIV_VHADM |
+               BE_PRIV_DEVCFG | BE_PRIV_DEVSEC
+       },
+       {
+               OPCODE_COMMON_SET_FLOW_CONTROL,
+               CMD_SUBSYSTEM_COMMON,
+               BE_PRIV_LNKMGMT | BE_PRIV_VHADM |
+               BE_PRIV_DEVCFG | BE_PRIV_DEVSEC
+       },
+       {
+               OPCODE_ETH_GET_PPORT_STATS,
+               CMD_SUBSYSTEM_ETH,
+               BE_PRIV_LNKMGMT | BE_PRIV_VHADM |
+               BE_PRIV_DEVCFG | BE_PRIV_DEVSEC
+       },
+       {
+               OPCODE_COMMON_GET_PHY_DETAILS,
+               CMD_SUBSYSTEM_COMMON,
+               BE_PRIV_LNKMGMT | BE_PRIV_VHADM |
+               BE_PRIV_DEVCFG | BE_PRIV_DEVSEC
+       }
+};
+
+static bool be_cmd_allowed(struct be_adapter *adapter, u8 opcode,
+                          u8 subsystem)
+{
+       int i;
+       int num_entries = sizeof(cmd_priv_map)/sizeof(struct be_cmd_priv_map);
+       u32 cmd_privileges = adapter->cmd_privileges;
+
+       for (i = 0; i < num_entries; i++)
+               if (opcode == cmd_priv_map[i].opcode &&
+                   subsystem == cmd_priv_map[i].subsystem)
+                       if (!(cmd_privileges & cmd_priv_map[i].priv_mask))
+                               return false;
+
+       return true;
+}
+
 static inline void *embedded_payload(struct be_mcc_wrb *wrb)
 {
        return wrb->payload.embedded_payload;
        struct lancer_cmd_req_pport_stats *req;
        int status = 0;
 
+       if (!be_cmd_allowed(adapter, OPCODE_ETH_GET_PPORT_STATS,
+                           CMD_SUBSYSTEM_ETH))
+               return -EPERM;
+
        spin_lock_bh(&adapter->mcc_lock);
 
        wrb = wrb_from_mccq(adapter);
        struct be_cmd_req_set_flow_control *req;
        int status;
 
+       if (!be_cmd_allowed(adapter, OPCODE_COMMON_SET_FLOW_CONTROL,
+                           CMD_SUBSYSTEM_COMMON))
+               return -EPERM;
+
        spin_lock_bh(&adapter->mcc_lock);
 
        wrb = wrb_from_mccq(adapter);
        struct be_cmd_req_get_flow_control *req;
        int status;
 
+       if (!be_cmd_allowed(adapter, OPCODE_COMMON_GET_FLOW_CONTROL,
+                           CMD_SUBSYSTEM_COMMON))
+               return -EPERM;
+
        spin_lock_bh(&adapter->mcc_lock);
 
        wrb = wrb_from_mccq(adapter);
        struct be_dma_mem cmd;
        int status;
 
+       if (!be_cmd_allowed(adapter, OPCODE_COMMON_GET_PHY_DETAILS,
+                           CMD_SUBSYSTEM_COMMON))
+               return -EPERM;
+
        spin_lock_bh(&adapter->mcc_lock);
 
        wrb = wrb_from_mccq(adapter);
        return status;
 }
 
+/* Get privilege(s) for a function */
+int be_cmd_get_fn_privileges(struct be_adapter *adapter, u32 *privilege,
+                            u32 domain)
+{
+       struct be_mcc_wrb *wrb;
+       struct be_cmd_req_get_fn_privileges *req;
+       int status;
+
+       spin_lock_bh(&adapter->mcc_lock);
+
+       wrb = wrb_from_mccq(adapter);
+       if (!wrb) {
+               status = -EBUSY;
+               goto err;
+       }
+
+       req = embedded_payload(wrb);
+
+       be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
+                              OPCODE_COMMON_GET_FN_PRIVILEGES, sizeof(*req),
+                              wrb, NULL);
+
+       req->hdr.domain = domain;
+
+       status = be_mcc_notify_wait(adapter);
+       if (!status) {
+               struct be_cmd_resp_get_fn_privileges *resp =
+                                               embedded_payload(wrb);
+               *privilege = le32_to_cpu(resp->privilege_mask);
+       }
+
+err:
+       spin_unlock_bh(&adapter->mcc_lock);
+       return status;
+}
+
 /* Uses synchronous MCCQ */
 int be_cmd_get_mac_from_list(struct be_adapter *adapter, u8 *mac,
                             bool *pmac_id_active, u32 *pmac_id, u8 domain)
        int payload_len = sizeof(*req);
        struct be_dma_mem cmd;
 
+       if (!be_cmd_allowed(adapter, OPCODE_ETH_ACPI_WOL_MAGIC_CONFIG,
+                           CMD_SUBSYSTEM_ETH))
+               return -EPERM;
+
        memset(&cmd, 0, sizeof(struct be_dma_mem));
        cmd.size = sizeof(struct be_cmd_resp_acpi_wol_magic_config_v1);
        cmd.va = pci_alloc_consistent(adapter->pdev, cmd.size,
 
 #define OPCODE_COMMON_GET_PROFILE_CONFIG               164
 #define OPCODE_COMMON_SET_PROFILE_CONFIG               165
 #define OPCODE_COMMON_SET_HSW_CONFIG                   153
+#define OPCODE_COMMON_GET_FN_PRIVILEGES                        170
 #define OPCODE_COMMON_READ_OBJECT                      171
 #define OPCODE_COMMON_WRITE_OBJECT                     172
 
        u8 rsvd[212];
 };
 
+/*********************** Function Privileges ***********************/
+enum {
+       BE_PRIV_DEFAULT = 0x1,
+       BE_PRIV_LNKQUERY = 0x2,
+       BE_PRIV_LNKSTATS = 0x4,
+       BE_PRIV_LNKMGMT = 0x8,
+       BE_PRIV_LNKDIAG = 0x10,
+       BE_PRIV_UTILQUERY = 0x20,
+       BE_PRIV_FILTMGMT = 0x40,
+       BE_PRIV_IFACEMGMT = 0x80,
+       BE_PRIV_VHADM = 0x100,
+       BE_PRIV_DEVCFG = 0x200,
+       BE_PRIV_DEVSEC = 0x400
+};
+#define MAX_PRIVILEGES         (BE_PRIV_VHADM | BE_PRIV_DEVCFG | \
+                                BE_PRIV_DEVSEC)
+#define MIN_PRIVILEGES         BE_PRIV_DEFAULT
+
+struct be_cmd_priv_map {
+       u8 opcode;
+       u8 subsystem;
+       u32 priv_mask;
+};
+
+struct be_cmd_req_get_fn_privileges {
+       struct be_cmd_req_hdr hdr;
+       u32 rsvd;
+};
+
+struct be_cmd_resp_get_fn_privileges {
+       struct be_cmd_resp_hdr hdr;
+       u32 privilege_mask;
+};
+
+
 /******************** GET/SET_MACLIST  **************************/
 #define BE_MAX_MAC                     64
 struct be_cmd_req_get_mac_list {
        struct be_cmd_req_hdr hdr;
 };
 
+static inline bool check_privilege(struct be_adapter *adapter, u32 flags)
+{
+       return flags & adapter->cmd_privileges ? true : false;
+}
+
 extern int be_pci_fnum_get(struct be_adapter *adapter);
 extern int be_fw_wait_ready(struct be_adapter *adapter);
 extern int be_cmd_mac_addr_query(struct be_adapter *adapter, u8 *mac_addr,
 extern int be_cmd_req_native_mode(struct be_adapter *adapter);
 extern int be_cmd_get_reg_len(struct be_adapter *adapter, u32 *log_size);
 extern void be_cmd_get_regs(struct be_adapter *adapter, u32 buf_len, void *buf);
+extern int be_cmd_get_fn_privileges(struct be_adapter *adapter,
+                                   u32 *privilege, u32 domain);
 extern int be_cmd_get_mac_from_list(struct be_adapter *adapter, u8 *mac,
                                    bool *pmac_id_active, u32 *pmac_id,
                                    u8 domain);
 
        struct be_adapter *adapter = netdev_priv(netdev);
        u32 log_size = 0;
 
+       if (!check_privilege(adapter, MAX_PRIVILEGES))
+               return 0;
+
        if (be_physfn(adapter)) {
                if (lancer_chip(adapter))
                        log_size = lancer_cmd_get_file_len(adapter,
 be_get_eeprom_len(struct net_device *netdev)
 {
        struct be_adapter *adapter = netdev_priv(netdev);
+
+       if (!check_privilege(adapter, MAX_PRIVILEGES))
+               return 0;
+
        if (lancer_chip(adapter)) {
                if (be_physfn(adapter))
                        return lancer_cmd_get_file_len(adapter,
 
        adapter->be3_native = false;
        adapter->promiscuous = false;
        adapter->eq_next_idx = 0;
+
+       if (be_physfn(adapter))
+               adapter->cmd_privileges = MAX_PRIVILEGES;
+       else
+               adapter->cmd_privileges = MIN_PRIVILEGES;
 }
 
 static int be_get_mac_addr(struct be_adapter *adapter, u8 *mac, u32 if_handle,
        if (status)
                goto err;
 
+       be_cmd_get_fn_privileges(adapter, &adapter->cmd_privileges, 0);
+       /* In UMC mode FW does not return right privileges.
+        * Override with correct privilege equivalent to PF.
+        */
+       if (be_is_mc(adapter))
+               adapter->cmd_privileges = MAX_PRIVILEGES;
+
        en_flags = BE_IF_FLAGS_UNTAGGED | BE_IF_FLAGS_BROADCAST |
                        BE_IF_FLAGS_MULTICAST | BE_IF_FLAGS_PASS_L3L4_ERRORS;
 
                        dev_warn(dev, "device doesn't support SRIOV\n");
        }
 
-       be_cmd_get_phy_info(adapter);
-       if (be_pause_supported(adapter))
+       status = be_cmd_get_phy_info(adapter);
+       if (!status && be_pause_supported(adapter))
                adapter->phy.fc_autoneg = 1;
 
        schedule_delayed_work(&adapter->work, msecs_to_jiffies(1000));
        u32 level = 0;
        int j;
 
+       if (lancer_chip(adapter))
+               return 0;
+
        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,