From patchwork Tue Feb 14 19:26:29 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ajit Khaparde X-Patchwork-Id: 141172 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 10B71B6FC8 for ; Wed, 15 Feb 2012 06:27:09 +1100 (EST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1760126Ab2BNT1G (ORCPT ); Tue, 14 Feb 2012 14:27:06 -0500 Received: from exht1.emulex.com ([138.239.113.183]:31047 "EHLO exht1.ad.emulex.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1759949Ab2BNT1B (ORCPT ); Tue, 14 Feb 2012 14:27:01 -0500 Received: from akhaparde-VBox (138.239.131.139) by exht1.ad.emulex.com (138.239.113.183) with Microsoft SMTP Server (TLS) id 8.3.159.2; Tue, 14 Feb 2012 11:26:46 -0800 Date: Tue, 14 Feb 2012 13:26:29 -0600 From: Ajit Khaparde To: CC: Subject: [RFC net-next 2/2] be2net: add support for VF privileges Message-ID: <20120214192629.GA14205@akhaparde-VBox> Reply-To: Ajit Khaparde MIME-Version: 1.0 Content-Disposition: inline X-URL: http://www.emulex.com Organization: Emulex Corp User-Agent: "Ajit's Mutt" X-OS: Linux i686 Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org Signed-off-by: Ajit Khaparde --- drivers/net/ethernet/emulex/benet/be.h | 2 + drivers/net/ethernet/emulex/benet/be_cmds.c | 69 +++++++++++++++++++++++++ drivers/net/ethernet/emulex/benet/be_cmds.h | 45 ++++++++++++++++ drivers/net/ethernet/emulex/benet/be_main.c | 73 ++++++++++++++++++++++++++- 4 files changed, 188 insertions(+), 1 deletions(-) diff --git a/drivers/net/ethernet/emulex/benet/be.h b/drivers/net/ethernet/emulex/benet/be.h index 86f51de..e0a612a 100644 --- a/drivers/net/ethernet/emulex/benet/be.h +++ b/drivers/net/ethernet/emulex/benet/be.h @@ -301,6 +301,7 @@ struct be_vf_cfg { int pmac_id; u16 vlan_tag; u32 tx_rate; + u32 privileges; }; #define BE_FLAGS_LINK_STATUS_INIT 1 @@ -379,6 +380,7 @@ struct be_adapter { struct completion flash_compl; u32 num_vfs; + u32 privileges; u8 is_virtfn; struct be_vf_cfg *vf_cfg; bool be3_native; diff --git a/drivers/net/ethernet/emulex/benet/be_cmds.c b/drivers/net/ethernet/emulex/benet/be_cmds.c index 6432efa..3c38f2f 100644 --- a/drivers/net/ethernet/emulex/benet/be_cmds.c +++ b/drivers/net/ethernet/emulex/benet/be_cmds.c @@ -2293,6 +2293,75 @@ err: return status; } +/* Set privilege(s) for a function */ +int be_cmd_set_fn_privileges(struct be_adapter *adapter, u32 mask, u32 *prev, + 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; + req->privilege_mask = cpu_to_le32(mask); + + status = be_mcc_notify_wait(adapter); + +err: + spin_unlock_bh(&adapter->mcc_lock); + 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); + } else + *privilege = 0; + +err: + spin_unlock_bh(&adapter->mcc_lock); + return status; +} + /* Uses synchronous MCCQ */ int be_cmd_get_mac_from_list(struct be_adapter *adapter, u32 domain, bool *pmac_id_active, u32 *pmac_id, u8 *mac) diff --git a/drivers/net/ethernet/emulex/benet/be_cmds.h b/drivers/net/ethernet/emulex/benet/be_cmds.h index 687c420..7fe0922 100644 --- a/drivers/net/ethernet/emulex/benet/be_cmds.h +++ b/drivers/net/ethernet/emulex/benet/be_cmds.h @@ -186,9 +186,11 @@ struct be_mcc_mailbox { #define OPCODE_COMMON_ENABLE_DISABLE_BEACON 69 #define OPCODE_COMMON_GET_BEACON_STATE 70 #define OPCODE_COMMON_READ_TRANSRECV_DATA 73 +#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 +#define OPCODE_COMMON_GET_FN_PRIVILEGES 170 #define OPCODE_COMMON_GET_MAC_LIST 147 #define OPCODE_COMMON_SET_MAC_LIST 148 #define OPCODE_COMMON_READ_OBJECT 171 @@ -1489,6 +1491,45 @@ static inline void *be_erx_stats_from_cmd(struct be_adapter *adapter) } } +/*********************** 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 BE_VF_DEFAULT_PRIV (BE_PRIV_LNKQUERY |\ + BE_PRIV_IFACEMGMT |\ + BE_PRIV_LNKSTATS) + +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; +}; + +struct be_cmd_req_set_fn_privileges { + struct be_cmd_req_hdr hdr; + u32 privilege_mask; +}; + +struct be_cmd_resp_set_fn_privileges { + struct be_cmd_resp_hdr hdr; + u32 prev_privilege_mask; +}; + 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, @@ -1586,6 +1627,10 @@ 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_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 mask, u32 *prev, u32 domain); extern int be_cmd_get_mac_from_list(struct be_adapter *adapter, u32 domain, bool *pmac_id_active, u32 *pmac_id, u8 *mac); extern int be_cmd_set_mac_list(struct be_adapter *adapter, u8 *mac_array, diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c index 28f2b25..8d1b6cc 100644 --- a/drivers/net/ethernet/emulex/benet/be_main.c +++ b/drivers/net/ethernet/emulex/benet/be_main.c @@ -919,6 +919,24 @@ static int be_set_vf_mac(struct net_device *netdev, int vf, u8 *mac) return status; } +static u32 to_ip_privilege(u32 privileges) +{ + u32 priv = IFLA_VF_PRIVILEGE_DEFAULT; + + if (privileges & BE_PRIV_FILTMGMT) + priv |= IFLA_VF_PRIVILEGE_MAC | IFLA_VF_PRIVILEGE_VLAN; + if (privileges & BE_PRIV_LNKDIAG) + priv |= IFLA_VF_PRIVILEGE_DIAG; + if (privileges & BE_PRIV_DEVCFG) + priv |= IFLA_VF_PRIVILEGE_DEV_CFG; + if (privileges & BE_PRIV_DEVSEC) + priv |= IFLA_VF_PRIVILEGE_SECURE; + if (privileges & BE_PRIV_LNKMGMT) + priv |= IFLA_VF_PRIVILEGE_LNK_MGMT; + + return priv; +} + static int be_get_vf_config(struct net_device *netdev, int vf, struct ifla_vf_info *vi) { @@ -935,11 +953,56 @@ static int be_get_vf_config(struct net_device *netdev, int vf, vi->tx_rate = vf_cfg->tx_rate; vi->vlan = vf_cfg->vlan_tag; vi->qos = 0; + vi->privilege = to_ip_privilege(vf_cfg->privileges); memcpy(&vi->mac, vf_cfg->mac_addr, ETH_ALEN); return 0; } +static u32 to_be_privilege(struct be_adapter *adapter, u32 privilege) +{ + u32 priv = BE_VF_DEFAULT_PRIV; + + if ((privilege & IFLA_VF_PRIVILEGE_MAC) || + (privilege & IFLA_VF_PRIVILEGE_VLAN)) + priv |= BE_PRIV_FILTMGMT; + if (privilege & IFLA_VF_PRIVILEGE_DIAG) + priv |= BE_PRIV_LNKDIAG; + if (privilege & IFLA_VF_PRIVILEGE_DEV_CFG) + priv |= BE_PRIV_DEVCFG; + if (privilege & IFLA_VF_PRIVILEGE_LNK_MGMT) + priv |= BE_PRIV_LNKMGMT; + if (privilege & IFLA_VF_PRIVILEGE_SECURE) + priv |= BE_PRIV_DEVSEC; + + return priv; +} + +static int be_set_vf_privilege(struct net_device *netdev, int vf, u32 privilege) +{ + struct be_adapter *adapter = netdev_priv(netdev); + int status = 0; + u32 priv; + + if (!sriov_enabled(adapter)) + return -EPERM; + + if (vf >= adapter->num_vfs) + return -EINVAL; + + /* Convert OS priv type to BE priv type. */ + priv = to_be_privilege(adapter, privilege); + status = be_cmd_set_fn_privileges(adapter, priv, NULL, vf + 1); + + if (status) + dev_err(&adapter->pdev->dev, + "set privilege on VF %d failed\n", vf); + else + dev_info(&adapter->pdev->dev, + "set privilege %x on VF %d succeeded\n", priv, vf); + return status; +} + static int be_set_vf_vlan(struct net_device *netdev, int vf, u16 vlan, u8 qos) { @@ -2478,7 +2541,7 @@ static void be_vf_setup_init(struct be_adapter *adapter) static int be_vf_setup(struct be_adapter *adapter) { struct be_vf_cfg *vf_cfg; - u32 cap_flags, en_flags, vf; + u32 cap_flags, en_flags, vf, privileges; u16 lnk_speed; int status; @@ -2504,6 +2567,12 @@ static int be_vf_setup(struct be_adapter *adapter) goto err; vf_cfg->tx_rate = lnk_speed * 10; } + + for_all_vfs(adapter, vf_cfg, vf) { + status = be_cmd_get_fn_privileges(adapter, &privileges, vf + 1); + if (!status) + vf_cfg->privileges = privileges; + } return 0; err: return status; @@ -2648,6 +2717,7 @@ static int be_setup(struct be_adapter *adapter) goto err; } + be_cmd_get_fn_privileges(adapter, &adapter->privileges, 0); return 0; err: be_clear(adapter); @@ -3016,6 +3086,7 @@ static const struct net_device_ops be_netdev_ops = { .ndo_set_vf_mac = be_set_vf_mac, .ndo_set_vf_vlan = be_set_vf_vlan, .ndo_set_vf_tx_rate = be_set_vf_tx_rate, + .ndo_set_vf_privilege = be_set_vf_privilege, .ndo_get_vf_config = be_get_vf_config, #ifdef CONFIG_NET_POLL_CONTROLLER .ndo_poll_controller = be_netpoll,