Commit f25b119c authored by Padmanabh Ratnakar's avatar Padmanabh Ratnakar Committed by David S. Miller

be2net: Fix error messages while driver load for VFs

VF does not have privileges to execute many commands. When VFs try
to execute those commands there are unnecessary error messages.
Fix this by executing only those commands for which VF has privilege.
Signed-off-by: default avatarPadmanabh Ratnakar <padmanabh.ratnakar@emulex.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent a85e9986
...@@ -390,6 +390,7 @@ struct be_adapter { ...@@ -390,6 +390,7 @@ struct be_adapter {
struct delayed_work func_recovery_work; struct delayed_work func_recovery_work;
u32 flags; u32 flags;
u32 cmd_privileges;
/* Ethtool knobs and info */ /* Ethtool knobs and info */
char fw_ver[FW_VER_LEN]; char fw_ver[FW_VER_LEN];
int if_handle; /* Used to configure filtering */ int if_handle; /* Used to configure filtering */
......
...@@ -19,6 +19,55 @@ ...@@ -19,6 +19,55 @@
#include "be.h" #include "be.h"
#include "be_cmds.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) static inline void *embedded_payload(struct be_mcc_wrb *wrb)
{ {
return wrb->payload.embedded_payload; return wrb->payload.embedded_payload;
...@@ -1332,6 +1381,10 @@ int lancer_cmd_get_pport_stats(struct be_adapter *adapter, ...@@ -1332,6 +1381,10 @@ int lancer_cmd_get_pport_stats(struct be_adapter *adapter,
struct lancer_cmd_req_pport_stats *req; struct lancer_cmd_req_pport_stats *req;
int status = 0; int status = 0;
if (!be_cmd_allowed(adapter, OPCODE_ETH_GET_PPORT_STATS,
CMD_SUBSYSTEM_ETH))
return -EPERM;
spin_lock_bh(&adapter->mcc_lock); spin_lock_bh(&adapter->mcc_lock);
wrb = wrb_from_mccq(adapter); wrb = wrb_from_mccq(adapter);
...@@ -1711,6 +1764,10 @@ int be_cmd_set_flow_control(struct be_adapter *adapter, u32 tx_fc, u32 rx_fc) ...@@ -1711,6 +1764,10 @@ int be_cmd_set_flow_control(struct be_adapter *adapter, u32 tx_fc, u32 rx_fc)
struct be_cmd_req_set_flow_control *req; struct be_cmd_req_set_flow_control *req;
int status; int status;
if (!be_cmd_allowed(adapter, OPCODE_COMMON_SET_FLOW_CONTROL,
CMD_SUBSYSTEM_COMMON))
return -EPERM;
spin_lock_bh(&adapter->mcc_lock); spin_lock_bh(&adapter->mcc_lock);
wrb = wrb_from_mccq(adapter); wrb = wrb_from_mccq(adapter);
...@@ -1740,6 +1797,10 @@ int be_cmd_get_flow_control(struct be_adapter *adapter, u32 *tx_fc, u32 *rx_fc) ...@@ -1740,6 +1797,10 @@ int be_cmd_get_flow_control(struct be_adapter *adapter, u32 *tx_fc, u32 *rx_fc)
struct be_cmd_req_get_flow_control *req; struct be_cmd_req_get_flow_control *req;
int status; int status;
if (!be_cmd_allowed(adapter, OPCODE_COMMON_GET_FLOW_CONTROL,
CMD_SUBSYSTEM_COMMON))
return -EPERM;
spin_lock_bh(&adapter->mcc_lock); spin_lock_bh(&adapter->mcc_lock);
wrb = wrb_from_mccq(adapter); wrb = wrb_from_mccq(adapter);
...@@ -2306,6 +2367,10 @@ int be_cmd_get_phy_info(struct be_adapter *adapter) ...@@ -2306,6 +2367,10 @@ int be_cmd_get_phy_info(struct be_adapter *adapter)
struct be_dma_mem cmd; struct be_dma_mem cmd;
int status; int status;
if (!be_cmd_allowed(adapter, OPCODE_COMMON_GET_PHY_DETAILS,
CMD_SUBSYSTEM_COMMON))
return -EPERM;
spin_lock_bh(&adapter->mcc_lock); spin_lock_bh(&adapter->mcc_lock);
wrb = wrb_from_mccq(adapter); wrb = wrb_from_mccq(adapter);
...@@ -2465,6 +2530,42 @@ int be_cmd_req_native_mode(struct be_adapter *adapter) ...@@ -2465,6 +2530,42 @@ int be_cmd_req_native_mode(struct be_adapter *adapter)
return status; 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 */ /* Uses synchronous MCCQ */
int be_cmd_get_mac_from_list(struct be_adapter *adapter, u8 *mac, int be_cmd_get_mac_from_list(struct be_adapter *adapter, u8 *mac,
bool *pmac_id_active, u32 *pmac_id, u8 domain) bool *pmac_id_active, u32 *pmac_id, u8 domain)
...@@ -2682,6 +2783,10 @@ int be_cmd_get_acpi_wol_cap(struct be_adapter *adapter) ...@@ -2682,6 +2783,10 @@ int be_cmd_get_acpi_wol_cap(struct be_adapter *adapter)
int payload_len = sizeof(*req); int payload_len = sizeof(*req);
struct be_dma_mem cmd; 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)); memset(&cmd, 0, sizeof(struct be_dma_mem));
cmd.size = sizeof(struct be_cmd_resp_acpi_wol_magic_config_v1); cmd.size = sizeof(struct be_cmd_resp_acpi_wol_magic_config_v1);
cmd.va = pci_alloc_consistent(adapter->pdev, cmd.size, cmd.va = pci_alloc_consistent(adapter->pdev, cmd.size,
......
...@@ -200,6 +200,7 @@ struct be_mcc_mailbox { ...@@ -200,6 +200,7 @@ struct be_mcc_mailbox {
#define OPCODE_COMMON_GET_PROFILE_CONFIG 164 #define OPCODE_COMMON_GET_PROFILE_CONFIG 164
#define OPCODE_COMMON_SET_PROFILE_CONFIG 165 #define OPCODE_COMMON_SET_PROFILE_CONFIG 165
#define OPCODE_COMMON_SET_HSW_CONFIG 153 #define OPCODE_COMMON_SET_HSW_CONFIG 153
#define OPCODE_COMMON_GET_FN_PRIVILEGES 170
#define OPCODE_COMMON_READ_OBJECT 171 #define OPCODE_COMMON_READ_OBJECT 171
#define OPCODE_COMMON_WRITE_OBJECT 172 #define OPCODE_COMMON_WRITE_OBJECT 172
...@@ -1432,6 +1433,41 @@ struct be_cmd_resp_set_func_cap { ...@@ -1432,6 +1433,41 @@ struct be_cmd_resp_set_func_cap {
u8 rsvd[212]; 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 **************************/ /******************** GET/SET_MACLIST **************************/
#define BE_MAX_MAC 64 #define BE_MAX_MAC 64
struct be_cmd_req_get_mac_list { struct be_cmd_req_get_mac_list {
...@@ -1766,6 +1802,11 @@ struct be_cmd_resp_set_profile_config { ...@@ -1766,6 +1802,11 @@ struct be_cmd_resp_set_profile_config {
struct be_cmd_req_hdr hdr; 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_pci_fnum_get(struct be_adapter *adapter);
extern int be_fw_wait_ready(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_mac_addr_query(struct be_adapter *adapter, u8 *mac_addr,
...@@ -1862,6 +1903,8 @@ extern int be_cmd_get_cntl_attributes(struct be_adapter *adapter); ...@@ -1862,6 +1903,8 @@ extern int be_cmd_get_cntl_attributes(struct be_adapter *adapter);
extern int be_cmd_req_native_mode(struct be_adapter *adapter); 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 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 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, extern int be_cmd_get_mac_from_list(struct be_adapter *adapter, u8 *mac,
bool *pmac_id_active, u32 *pmac_id, bool *pmac_id_active, u32 *pmac_id,
u8 domain); u8 domain);
......
...@@ -261,6 +261,9 @@ be_get_reg_len(struct net_device *netdev) ...@@ -261,6 +261,9 @@ be_get_reg_len(struct net_device *netdev)
struct be_adapter *adapter = netdev_priv(netdev); struct be_adapter *adapter = netdev_priv(netdev);
u32 log_size = 0; u32 log_size = 0;
if (!check_privilege(adapter, MAX_PRIVILEGES))
return 0;
if (be_physfn(adapter)) { if (be_physfn(adapter)) {
if (lancer_chip(adapter)) if (lancer_chip(adapter))
log_size = lancer_cmd_get_file_len(adapter, log_size = lancer_cmd_get_file_len(adapter,
...@@ -787,6 +790,10 @@ static int ...@@ -787,6 +790,10 @@ static int
be_get_eeprom_len(struct net_device *netdev) be_get_eeprom_len(struct net_device *netdev)
{ {
struct be_adapter *adapter = netdev_priv(netdev); struct be_adapter *adapter = netdev_priv(netdev);
if (!check_privilege(adapter, MAX_PRIVILEGES))
return 0;
if (lancer_chip(adapter)) { if (lancer_chip(adapter)) {
if (be_physfn(adapter)) if (be_physfn(adapter))
return lancer_cmd_get_file_len(adapter, return lancer_cmd_get_file_len(adapter,
......
...@@ -2745,6 +2745,11 @@ static void be_setup_init(struct be_adapter *adapter) ...@@ -2745,6 +2745,11 @@ static void be_setup_init(struct be_adapter *adapter)
adapter->be3_native = false; adapter->be3_native = false;
adapter->promiscuous = false; adapter->promiscuous = false;
adapter->eq_next_idx = 0; 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, static int be_get_mac_addr(struct be_adapter *adapter, u8 *mac, u32 if_handle,
...@@ -2917,6 +2922,13 @@ static int be_setup(struct be_adapter *adapter) ...@@ -2917,6 +2922,13 @@ static int be_setup(struct be_adapter *adapter)
if (status) if (status)
goto err; 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 | en_flags = BE_IF_FLAGS_UNTAGGED | BE_IF_FLAGS_BROADCAST |
BE_IF_FLAGS_MULTICAST | BE_IF_FLAGS_PASS_L3L4_ERRORS; BE_IF_FLAGS_MULTICAST | BE_IF_FLAGS_PASS_L3L4_ERRORS;
...@@ -2973,8 +2985,8 @@ static int be_setup(struct be_adapter *adapter) ...@@ -2973,8 +2985,8 @@ static int be_setup(struct be_adapter *adapter)
dev_warn(dev, "device doesn't support SRIOV\n"); dev_warn(dev, "device doesn't support SRIOV\n");
} }
be_cmd_get_phy_info(adapter); status = be_cmd_get_phy_info(adapter);
if (be_pause_supported(adapter)) if (!status && be_pause_supported(adapter))
adapter->phy.fc_autoneg = 1; adapter->phy.fc_autoneg = 1;
schedule_delayed_work(&adapter->work, msecs_to_jiffies(1000)); schedule_delayed_work(&adapter->work, msecs_to_jiffies(1000));
...@@ -3711,6 +3723,9 @@ u32 be_get_fw_log_level(struct be_adapter *adapter) ...@@ -3711,6 +3723,9 @@ u32 be_get_fw_log_level(struct be_adapter *adapter)
u32 level = 0; u32 level = 0;
int j; int j;
if (lancer_chip(adapter))
return 0;
memset(&extfat_cmd, 0, sizeof(struct be_dma_mem)); memset(&extfat_cmd, 0, sizeof(struct be_dma_mem));
extfat_cmd.size = sizeof(struct be_cmd_resp_get_ext_fat_caps); 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.va = pci_alloc_consistent(adapter->pdev, extfat_cmd.size,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment