diff options
-rw-r--r-- | drivers/net/ethernet/emulex/benet/be_cmds.c | 32 | ||||
-rw-r--r-- | drivers/net/ethernet/emulex/benet/be_cmds.h | 8 | ||||
-rw-r--r-- | drivers/net/ethernet/emulex/benet/be_main.c | 13 |
3 files changed, 53 insertions, 0 deletions
diff --git a/drivers/net/ethernet/emulex/benet/be_cmds.c b/drivers/net/ethernet/emulex/benet/be_cmds.c index 632c0d323867..5d37601df03f 100644 --- a/drivers/net/ethernet/emulex/benet/be_cmds.c +++ b/drivers/net/ethernet/emulex/benet/be_cmds.c @@ -2606,6 +2606,38 @@ err: return status; } +/* Set privilege(s) for a function */ +int be_cmd_set_fn_privileges(struct be_adapter *adapter, u32 privileges, + u32 domain) +{ + struct be_mcc_wrb *wrb; + struct be_cmd_req_set_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_SET_FN_PRIVILEGES, sizeof(*req), + wrb, NULL); + req->hdr.domain = domain; + if (lancer_chip(adapter)) + req->privileges_lancer = cpu_to_le32(privileges); + else + req->privileges = cpu_to_le32(privileges); + + status = be_mcc_notify_wait(adapter); +err: + spin_unlock_bh(&adapter->mcc_lock); + return status; +} + /* pmac_id_valid: true => pmac_id is supplied and MAC address is requested. * pmac_id_valid: false => pmac_id or MAC address is requested. * If pmac_id is returned, pmac_id_valid is returned as true diff --git a/drivers/net/ethernet/emulex/benet/be_cmds.h b/drivers/net/ethernet/emulex/benet/be_cmds.h index 7ecca3b591a6..671a89d84f98 100644 --- a/drivers/net/ethernet/emulex/benet/be_cmds.h +++ b/drivers/net/ethernet/emulex/benet/be_cmds.h @@ -202,6 +202,7 @@ struct be_mcc_mailbox { #define OPCODE_COMMON_READ_TRANSRECV_DATA 73 #define OPCODE_COMMON_GET_PORT_NAME 77 #define OPCODE_COMMON_SET_INTERRUPT_ENABLE 89 +#define OPCODE_COMMON_SET_FN_PRIVILEGES 100 #define OPCODE_COMMON_GET_PHY_DETAILS 102 #define OPCODE_COMMON_SET_DRIVER_FUNCTION_CAP 103 #define OPCODE_COMMON_GET_CNTL_ADDITIONAL_ATTRIBUTES 121 @@ -1474,6 +1475,11 @@ struct be_cmd_resp_get_fn_privileges { u32 privilege_mask; }; +struct be_cmd_req_set_fn_privileges { + struct be_cmd_req_hdr hdr; + u32 privileges; /* Used by BE3, SH-R */ + u32 privileges_lancer; /* Used by Lancer */ +}; /******************** GET/SET_MACLIST **************************/ #define BE_MAX_MAC 64 @@ -1921,6 +1927,8 @@ 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_set_fn_privileges(struct be_adapter *adapter, + u32 privileges, u32 vf_num); extern int be_cmd_get_mac_from_list(struct be_adapter *adapter, u8 *mac, bool *pmac_id_active, u32 *pmac_id, u8 domain); diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c index 29e7870e0b35..858bb473bd42 100644 --- a/drivers/net/ethernet/emulex/benet/be_main.c +++ b/drivers/net/ethernet/emulex/benet/be_main.c @@ -2880,6 +2880,7 @@ static int be_vf_setup(struct be_adapter *adapter) u16 def_vlan, lnk_speed; int status, old_vfs, vf; struct device *dev = &adapter->pdev->dev; + u32 privileges; old_vfs = pci_num_vf(adapter->pdev); if (old_vfs) { @@ -2923,6 +2924,18 @@ static int be_vf_setup(struct be_adapter *adapter) } for_all_vfs(adapter, vf_cfg, vf) { + /* Allow VFs to programs MAC/VLAN filters */ + status = be_cmd_get_fn_privileges(adapter, &privileges, vf + 1); + if (!status && !(privileges & BE_PRIV_FILTMGMT)) { + status = be_cmd_set_fn_privileges(adapter, + privileges | + BE_PRIV_FILTMGMT, + vf + 1); + if (!status) + dev_info(dev, "VF%d has FILTMGMT privilege\n", + vf); + } + /* BE3 FW, by default, caps VF TX-rate to 100mbps. * Allow full available bandwidth */ |