aboutsummaryrefslogtreecommitdiff
path: root/drivers/net/ethernet/emulex/benet/be_cmds.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/ethernet/emulex/benet/be_cmds.c')
-rw-r--r--drivers/net/ethernet/emulex/benet/be_cmds.c105
1 files changed, 105 insertions, 0 deletions
diff --git a/drivers/net/ethernet/emulex/benet/be_cmds.c b/drivers/net/ethernet/emulex/benet/be_cmds.c
index 9a12c4b99e2..9d602f4a09d 100644
--- a/drivers/net/ethernet/emulex/benet/be_cmds.c
+++ b/drivers/net/ethernet/emulex/benet/be_cmds.c
@@ -19,6 +19,55 @@
#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;
@@ -1332,6 +1381,10 @@ int lancer_cmd_get_pport_stats(struct be_adapter *adapter,
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);
@@ -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;
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);
@@ -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;
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);
@@ -2306,6 +2367,10 @@ int be_cmd_get_phy_info(struct be_adapter *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);
@@ -2465,6 +2530,42 @@ err:
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)
@@ -2682,6 +2783,10 @@ int be_cmd_get_acpi_wol_cap(struct be_adapter *adapter)
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,