From patchwork Thu Oct 12 13:34:20 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Steve Lin X-Patchwork-Id: 824850 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=linux-pci-owner@vger.kernel.org; receiver=) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 3yCX034qf3z9t3B for ; Fri, 13 Oct 2017 00:34:59 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1757524AbdJLNe5 (ORCPT ); Thu, 12 Oct 2017 09:34:57 -0400 Received: from rnd-relay.smtp.broadcom.com ([192.19.229.170]:50310 "EHLO rnd-relay.smtp.broadcom.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1757244AbdJLNe4 (ORCPT ); Thu, 12 Oct 2017 09:34:56 -0400 Received: from mail-irv-17.broadcom.com (mail-irv-17.lvn.broadcom.net [10.75.224.233]) by rnd-relay.smtp.broadcom.com (Postfix) with ESMTP id 8195730C016; Thu, 12 Oct 2017 06:34:55 -0700 (PDT) Received: from xl-rtp-02.broadcom.com (xl-rtp-02.ash.broadcom.net [10.85.234.3]) by mail-irv-17.broadcom.com (Postfix) with ESMTP id 6509481EAD; Thu, 12 Oct 2017 06:34:55 -0700 (PDT) Received: by xl-rtp-02.broadcom.com (Postfix, from userid 113764) id DCB694C0807; Thu, 12 Oct 2017 09:34:54 -0400 (EDT) From: Steve Lin To: netdev@vger.kernel.org Cc: jiri@mellanox.com, davem@davemloft.net, michael.chan@broadcom.com, linux-pci@vger.kernel.org, linville@tuxdriver.com, gospo@broadcom.com, steven.lin1@broadcom.com Subject: [RFC 1/3] devlink: Add config parameter get/set operations Date: Thu, 12 Oct 2017 09:34:20 -0400 Message-Id: <1507815262-33294-2-git-send-email-steven.lin1@broadcom.com> X-Mailer: git-send-email 2.1.0 In-Reply-To: <1507815262-33294-1-git-send-email-steven.lin1@broadcom.com> References: <1507815262-33294-1-git-send-email-steven.lin1@broadcom.com> Sender: linux-pci-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pci@vger.kernel.org Add support for config parameter get/set commands. Initially used by bnxt driver, but other drivers can use the same, or new, attributes. The config_get() and config_set() operations operate as expected, but note that the driver implementation of the config_set() operation can indicate whether a restart is necessary for the setting to take effect. Signed-off-by: Steve Lin Acked-by: Andy Gospodarek --- include/net/devlink.h | 4 + include/uapi/linux/devlink.h | 108 ++++++++++++++++++++++ net/core/devlink.c | 207 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 319 insertions(+) diff --git a/include/net/devlink.h b/include/net/devlink.h index b9654e1..952966c 100644 --- a/include/net/devlink.h +++ b/include/net/devlink.h @@ -270,6 +270,10 @@ struct devlink_ops { int (*eswitch_inline_mode_set)(struct devlink *devlink, u8 inline_mode); int (*eswitch_encap_mode_get)(struct devlink *devlink, u8 *p_encap_mode); int (*eswitch_encap_mode_set)(struct devlink *devlink, u8 encap_mode); + int (*config_get)(struct devlink *devlink, enum devlink_attr attr, + u32 *value); + int (*config_set)(struct devlink *devlink, enum devlink_attr attr, + u32 value, u8 *restart_reqd); }; static inline void *devlink_priv(struct devlink *devlink) diff --git a/include/uapi/linux/devlink.h b/include/uapi/linux/devlink.h index 0cbca96..e959716 100644 --- a/include/uapi/linux/devlink.h +++ b/include/uapi/linux/devlink.h @@ -70,6 +70,9 @@ enum devlink_command { DEVLINK_CMD_DPIPE_HEADERS_GET, DEVLINK_CMD_DPIPE_TABLE_COUNTERS_SET, + DEVLINK_CMD_CONFIG_GET, + DEVLINK_CMD_CONFIG_SET, + /* add new commands above here */ __DEVLINK_CMD_MAX, DEVLINK_CMD_MAX = __DEVLINK_CMD_MAX - 1 @@ -124,6 +127,68 @@ enum devlink_eswitch_encap_mode { DEVLINK_ESWITCH_ENCAP_MODE_BASIC, }; +enum devlink_dcbx_mode { + DEVLINK_DCBX_MODE_DISABLED, + DEVLINK_DCBX_MODE_IEEE, + DEVLINK_DCBX_MODE_CEE, + DEVLINK_DCBX_MODE_IEEE_CEE, +}; + +enum devlink_multifunc_mode { + DEVLINK_MULTIFUNC_MODE_ALLOWED, /* Ext switch activates MF */ + DEVLINK_MULTIFUNC_MODE_FORCE_SINGFUNC, + DEVLINK_MULTIFUNC_MODE_NPAR10, /* NPAR 1.0 */ + DEVLINK_MULTIFUNC_MODE_NPAR15, /* NPAR 1.5 */ + DEVLINK_MULTIFUNC_MODE_NPAR20, /* NPAR 2.0 */ +}; + +enum devlink_autoneg_protocol { + DEVLINK_AUTONEG_PROTOCOL_IEEE8023BY_BAM, + DEVLINK_AUTONEG_PROTOCOL_IEEE8023BY_CONSORTIUM, + DEVLINK_AUTONEG_PROTOCOL_IEEE8023BY, + DEVLINK_AUTONEG_PROTOCOL_BAM, /* Broadcom Autoneg Mode */ + DEVLINK_AUTONEG_PROTOCOL_CONSORTIUM, /* Consortium Autoneg Mode */ +}; + +enum devlink_pre_os_link_speed { + DEVLINK_PRE_OS_LINK_SPEED_AUTONEG, + DEVLINK_PRE_OS_LINK_SPEED_1G, + DEVLINK_PRE_OS_LINK_SPEED_10G, + DEVLINK_PRE_OS_LINK_SPEED_25G, + DEVLINK_PRE_OS_LINK_SPEED_40G, + DEVLINK_PRE_OS_LINK_SPEED_50G, + DEVLINK_PRE_OS_LINK_SPEED_100G, + DEVLINK_PRE_OS_LINK_SPEED_5G = 0xe, + DEVLINK_PRE_OS_LINK_SPEED_100M = 0xf, +}; + +enum devlink_mba_boot_type { + DEVLINK_MBA_BOOT_TYPE_AUTO_DETECT, + DEVLINK_MBA_BOOT_TYPE_BBS, /* BIOS Boot Specification */ + DEVLINK_MBA_BOOT_TYPE_INTR18, /* Hook interrupt 0x18 */ + DEVLINK_MBA_BOOT_TYPE_INTR19, /* Hook interrupt 0x19 */ +}; + +enum devlink_mba_setup_hot_key { + DEVLINK_MBA_SETUP_HOT_KEY_CTRL_S, + DEVLINK_MBA_SETUP_HOT_KEY_CTRL_B, +}; + +enum devlink_mba_boot_protocol { + DEVLINK_MBA_BOOT_PROTOCOL_PXE, + DEVLINK_MBA_BOOT_PROTOCOL_ISCSI, + DEVLINK_MBA_BOOT_PROTOCOL_NONE = 0x7, +}; + +enum devlink_mba_link_speed { + DEVLINK_MBA_LINK_SPEED_AUTONEG, + DEVLINK_MBA_LINK_SPEED_1G, + DEVLINK_MBA_LINK_SPEED_10G, + DEVLINK_MBA_LINK_SPEED_25G, + DEVLINK_MBA_LINK_SPEED_40G, + DEVLINK_MBA_LINK_SPEED_50G, +}; + enum devlink_attr { /* don't change the order or add anything between, this is ABI! */ DEVLINK_ATTR_UNSPEC, @@ -202,6 +267,49 @@ enum devlink_attr { DEVLINK_ATTR_ESWITCH_ENCAP_MODE, /* u8 */ + /* Configuration Parameters */ + DEVLINK_ATTR_SRIOV_ENABLED, /* u8 */ + DEVLINK_ATTR_NUM_VF_PER_PF, /* u32 */ + DEVLINK_ATTR_MAX_NUM_PF_MSIX_VECT, /* u32 */ + DEVLINK_ATTR_MSIX_VECTORS_PER_VF, /* u32 */ + DEVLINK_ATTR_NPAR_NUM_PARTITIONS_PER_PORT, /* u32 */ + DEVLINK_ATTR_NPAR_BW_IN_PERCENT, /* u8 */ + DEVLINK_ATTR_NPAR_BW_RESERVATION, /* u8 */ + DEVLINK_ATTR_NPAR_BW_RESERVATION_VALID, /* u8 */ + DEVLINK_ATTR_NPAR_BW_LIMIT, /* u8 */ + DEVLINK_ATTR_NPAR_BW_LIMIT_VALID, /* u8 */ + DEVLINK_ATTR_DCBX_MODE, /* u8 */ + DEVLINK_ATTR_RDMA_ENABLED, /* u8 */ + DEVLINK_ATTR_MULTIFUNC_MODE, /* u8 */ + DEVLINK_ATTR_SECURE_NIC_ENABLED, /* u8 */ + DEVLINK_ATTR_IGNORE_ARI_CAPABILITY, /* u8 */ + DEVLINK_ATTR_LLDP_NEAREST_BRIDGE_ENABLED, /* u8 */ + DEVLINK_ATTR_LLDP_NEAREST_NONTPMR_BRIDGE_ENABLED, /* u8 */ + DEVLINK_ATTR_PME_CAPABILITY_ENABLED, /* u8 */ + DEVLINK_ATTR_MAGIC_PACKET_WOL_ENABLED, /* u8 */ + DEVLINK_ATTR_EEE_PWR_SAVE_ENABLED, /* u8 */ + DEVLINK_ATTR_AUTONEG_PROTOCOL, /* u8 */ + DEVLINK_ATTR_MEDIA_AUTO_DETECT, /* u8 */ + DEVLINK_ATTR_PHY_SELECT, /* u8 */ + DEVLINK_ATTR_PRE_OS_LINK_SPEED_D0, /* u8 */ + DEVLINK_ATTR_PRE_OS_LINK_SPEED_D3, /* u8 */ + DEVLINK_ATTR_MBA_ENABLED, /* u8 */ + DEVLINK_ATTR_MBA_BOOT_TYPE, /* u8 */ + DEVLINK_ATTR_MBA_DELAY_TIME, /* u32 */ + DEVLINK_ATTR_MBA_SETUP_HOT_KEY, /* u8 */ + DEVLINK_ATTR_MBA_HIDE_SETUP_PROMPT, /* u8 */ + DEVLINK_ATTR_MBA_BOOT_RETRY_COUNT, /* u32 */ + DEVLINK_ATTR_MBA_VLAN_ENABLED, /* u8 */ + DEVLINK_ATTR_MBA_VLAN_TAG, /* u16 */ + DEVLINK_ATTR_MBA_BOOT_PROTOCOL, /* u8 */ + DEVLINK_ATTR_MBA_LINK_SPEED, /* u8 */ + + /* When config doesn't take effect until next reboot (config + * just changed NVM which isn't read until boot, for example), + * this attribute should be set by the driver. + */ + DEVLINK_ATTR_RESTART_REQUIRED, /* u8 */ + /* add new attributes above here, update the policy in devlink.c */ __DEVLINK_ATTR_MAX, diff --git a/net/core/devlink.c b/net/core/devlink.c index 7d430c1..701c84b 100644 --- a/net/core/devlink.c +++ b/net/core/devlink.c @@ -1566,6 +1566,164 @@ static int devlink_nl_cmd_eswitch_set_doit(struct sk_buff *skb, return 0; } +static const struct nla_policy devlink_nl_policy[DEVLINK_ATTR_MAX + 1]; + +static int devlink_nl_config_fill(struct sk_buff *msg, + struct devlink *devlink, + enum devlink_command cmd, + struct genl_info *info) +{ + const struct devlink_ops *ops = devlink->ops; + void *hdr; + int err; + enum devlink_attr attr = -1; + u32 value; + int i; + struct nla_policy policy; + u8 restart_reqd; + + if (!ops->config_get) + return -EOPNOTSUPP; + + hdr = genlmsg_put(msg, info->snd_portid, info->snd_seq, + &devlink_nl_family, 0, cmd); + if (!hdr) { + err = -EMSGSIZE; + goto nla_msg_failure; + } + + err = devlink_nl_put_handle(msg, devlink); + if (err) + goto nla_put_failure; + + for (i = 0; i < DEVLINK_ATTR_MAX; i++) + if (info->attrs[i]) + attr = i; + + if (attr == -1) { + /* Not found - invalid/unknown attribute? */ + err = -EINVAL; + goto nla_put_failure; + } + + policy = devlink_nl_policy[attr]; + + if (cmd == DEVLINK_CMD_CONFIG_GET) { + err = ops->config_get(devlink, attr, &value); + + if (err) + goto nla_put_failure; + + switch (policy.type) { + case NLA_U8: + err = nla_put_u8(msg, attr, value); + break; + case NLA_U16: + err = nla_put_u16(msg, attr, value); + break; + case NLA_U32: + err = nla_put_u32(msg, attr, value); + break; + default: + goto nla_put_failure; + } + + if (err) + goto nla_put_failure; + } else { + /* Must be config_set command */ + u8 *val8; + u16 *val16; + u32 *val32; + + switch (policy.type) { + case NLA_U8: + val8 = nla_data(info->attrs[attr]); + value = *val8; + break; + case NLA_U16: + val16 = nla_data(info->attrs[attr]); + value = *val16; + break; + case NLA_U32: + val32 = nla_data(info->attrs[attr]); + value = *val32; + break; + default: + goto nla_put_failure; + } + + err = ops->config_set(devlink, attr, value, &restart_reqd); + if (err) + goto nla_put_failure; + + if (restart_reqd) { + err = nla_put_u8(msg, DEVLINK_ATTR_RESTART_REQUIRED, + restart_reqd); + if (err) + goto nla_put_failure; + } + } + + genlmsg_end(msg, hdr); + return 0; + +nla_put_failure: + genlmsg_cancel(msg, hdr); +nla_msg_failure: + return err; +} + +static int devlink_nl_cmd_config_get_doit(struct sk_buff *skb, + struct genl_info *info) +{ + struct devlink *devlink = info->user_ptr[0]; + struct sk_buff *msg; + int err; + + if (!devlink->ops) + return -EOPNOTSUPP; + + msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); + if (!msg) + return -ENOMEM; + + err = devlink_nl_config_fill(msg, devlink, DEVLINK_CMD_CONFIG_GET, + info); + + if (err) { + nlmsg_free(msg); + return err; + } + + return genlmsg_reply(msg, info); +} + +static int devlink_nl_cmd_config_set_doit(struct sk_buff *skb, + struct genl_info *info) +{ + struct devlink *devlink = info->user_ptr[0]; + struct sk_buff *msg; + int err; + + if (!devlink->ops) + return -EOPNOTSUPP; + + msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); + if (!msg) + return -ENOMEM; + + err = devlink_nl_config_fill(msg, devlink, DEVLINK_CMD_CONFIG_SET, + info); + + if (err) { + nlmsg_free(msg); + return err; + } + + return genlmsg_reply(msg, info); +} + int devlink_dpipe_match_put(struct sk_buff *skb, struct devlink_dpipe_match *match) { @@ -2291,6 +2449,41 @@ static const struct nla_policy devlink_nl_policy[DEVLINK_ATTR_MAX + 1] = { [DEVLINK_ATTR_ESWITCH_ENCAP_MODE] = { .type = NLA_U8 }, [DEVLINK_ATTR_DPIPE_TABLE_NAME] = { .type = NLA_NUL_STRING }, [DEVLINK_ATTR_DPIPE_TABLE_COUNTERS_ENABLED] = { .type = NLA_U8 }, + [DEVLINK_ATTR_SRIOV_ENABLED] = { .type = NLA_U8 }, + [DEVLINK_ATTR_NUM_VF_PER_PF] = { .type = NLA_U32 }, + [DEVLINK_ATTR_MAX_NUM_PF_MSIX_VECT] = { .type = NLA_U32 }, + [DEVLINK_ATTR_MSIX_VECTORS_PER_VF] = { .type = NLA_U32 }, + [DEVLINK_ATTR_NPAR_NUM_PARTITIONS_PER_PORT] = { .type = NLA_U32 }, + [DEVLINK_ATTR_NPAR_BW_IN_PERCENT] = { .type = NLA_U32 }, + [DEVLINK_ATTR_NPAR_BW_RESERVATION] = { .type = NLA_U32 }, + [DEVLINK_ATTR_NPAR_BW_RESERVATION_VALID] = { .type = NLA_U8 }, + [DEVLINK_ATTR_NPAR_BW_LIMIT] = { .type = NLA_U32 }, + [DEVLINK_ATTR_NPAR_BW_LIMIT_VALID] = { .type = NLA_U8 }, + [DEVLINK_ATTR_DCBX_MODE] = { .type = NLA_U32 }, + [DEVLINK_ATTR_RDMA_ENABLED] = { .type = NLA_U8 }, + [DEVLINK_ATTR_MULTIFUNC_MODE] = { .type = NLA_U32 }, + [DEVLINK_ATTR_SECURE_NIC_ENABLED] = { .type = NLA_U8 }, + [DEVLINK_ATTR_IGNORE_ARI_CAPABILITY] = { .type = NLA_U8 }, + [DEVLINK_ATTR_LLDP_NEAREST_BRIDGE_ENABLED] = { .type = NLA_U8 }, + [DEVLINK_ATTR_LLDP_NEAREST_NONTPMR_BRIDGE_ENABLED] = { .type = NLA_U8 }, + [DEVLINK_ATTR_PME_CAPABILITY_ENABLED] = { .type = NLA_U8 }, + [DEVLINK_ATTR_MAGIC_PACKET_WOL_ENABLED] = { .type = NLA_U8 }, + [DEVLINK_ATTR_EEE_PWR_SAVE_ENABLED] = { .type = NLA_U8 }, + [DEVLINK_ATTR_AUTONEG_PROTOCOL] = { .type = NLA_U32 }, + [DEVLINK_ATTR_MEDIA_AUTO_DETECT] = { .type = NLA_U8 }, + [DEVLINK_ATTR_PHY_SELECT] = { .type = NLA_U8 }, + [DEVLINK_ATTR_PRE_OS_LINK_SPEED_D0] = { .type = NLA_U32 }, + [DEVLINK_ATTR_PRE_OS_LINK_SPEED_D3] = { .type = NLA_U32 }, + [DEVLINK_ATTR_MBA_ENABLED] = { .type = NLA_U8 }, + [DEVLINK_ATTR_MBA_BOOT_TYPE] = { .type = NLA_U32 }, + [DEVLINK_ATTR_MBA_DELAY_TIME] = { .type = NLA_U32 }, + [DEVLINK_ATTR_MBA_SETUP_HOT_KEY] = { .type = NLA_U32 }, + [DEVLINK_ATTR_MBA_HIDE_SETUP_PROMPT] = { .type = NLA_U8 }, + [DEVLINK_ATTR_MBA_BOOT_RETRY_COUNT] = { .type = NLA_U32 }, + [DEVLINK_ATTR_MBA_VLAN_ENABLED] = { .type = NLA_U8 }, + [DEVLINK_ATTR_MBA_VLAN_TAG] = { .type = NLA_U16 }, + [DEVLINK_ATTR_MBA_BOOT_PROTOCOL] = { .type = NLA_U32 }, + [DEVLINK_ATTR_MBA_LINK_SPEED] = { .type = NLA_U32 }, }; static const struct genl_ops devlink_nl_ops[] = { @@ -2451,6 +2644,20 @@ static const struct genl_ops devlink_nl_ops[] = { .flags = GENL_ADMIN_PERM, .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK, }, + { + .cmd = DEVLINK_CMD_CONFIG_GET, + .doit = devlink_nl_cmd_config_get_doit, + .policy = devlink_nl_policy, + .flags = GENL_ADMIN_PERM, + .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK, + }, + { + .cmd = DEVLINK_CMD_CONFIG_SET, + .doit = devlink_nl_cmd_config_set_doit, + .policy = devlink_nl_policy, + .flags = GENL_ADMIN_PERM, + .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK, + }, }; static struct genl_family devlink_nl_family __ro_after_init = { From patchwork Thu Oct 12 13:34:21 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Steve Lin X-Patchwork-Id: 824853 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=linux-pci-owner@vger.kernel.org; receiver=) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 3yCX081xyjz9sNw for ; Fri, 13 Oct 2017 00:35:04 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1757572AbdJLNe6 (ORCPT ); Thu, 12 Oct 2017 09:34:58 -0400 Received: from rnd-relay.smtp.broadcom.com ([192.19.229.170]:50316 "EHLO rnd-relay.smtp.broadcom.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1757567AbdJLNe5 (ORCPT ); Thu, 12 Oct 2017 09:34:57 -0400 Received: from mail-irv-17.broadcom.com (mail-irv-17.lvn.broadcom.net [10.75.224.233]) by rnd-relay.smtp.broadcom.com (Postfix) with ESMTP id 9883130C017; Thu, 12 Oct 2017 06:34:56 -0700 (PDT) Received: from xl-rtp-02.broadcom.com (xl-rtp-02.ash.broadcom.net [10.85.234.3]) by mail-irv-17.broadcom.com (Postfix) with ESMTP id 7D07C81EAD; Thu, 12 Oct 2017 06:34:56 -0700 (PDT) Received: by xl-rtp-02.broadcom.com (Postfix, from userid 113764) id 02F344C0807; Thu, 12 Oct 2017 09:34:56 -0400 (EDT) From: Steve Lin To: netdev@vger.kernel.org Cc: jiri@mellanox.com, davem@davemloft.net, michael.chan@broadcom.com, linux-pci@vger.kernel.org, linville@tuxdriver.com, gospo@broadcom.com, steven.lin1@broadcom.com Subject: [RFC 2/3] bnxt: Move generic devlink code to new file Date: Thu, 12 Oct 2017 09:34:21 -0400 Message-Id: <1507815262-33294-3-git-send-email-steven.lin1@broadcom.com> X-Mailer: git-send-email 2.1.0 In-Reply-To: <1507815262-33294-1-git-send-email-steven.lin1@broadcom.com> References: <1507815262-33294-1-git-send-email-steven.lin1@broadcom.com> Sender: linux-pci-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pci@vger.kernel.org Moving generic devlink code (registration, etc.) out of VF-R code into new bnxt_devlink file. Signed-off-by: Steve Lin Acked-by: Andy Gospodarek --- drivers/net/ethernet/broadcom/bnxt/Makefile | 2 +- drivers/net/ethernet/broadcom/bnxt/bnxt.c | 1 + drivers/net/ethernet/broadcom/bnxt/bnxt_devlink.c | 109 ++++++++++++++++++++++ drivers/net/ethernet/broadcom/bnxt/bnxt_devlink.h | 39 ++++++++ drivers/net/ethernet/broadcom/bnxt/bnxt_vfr.c | 97 +------------------ drivers/net/ethernet/broadcom/bnxt/bnxt_vfr.h | 35 +------ 6 files changed, 152 insertions(+), 131 deletions(-) create mode 100644 drivers/net/ethernet/broadcom/bnxt/bnxt_devlink.c create mode 100644 drivers/net/ethernet/broadcom/bnxt/bnxt_devlink.h diff --git a/drivers/net/ethernet/broadcom/bnxt/Makefile b/drivers/net/ethernet/broadcom/bnxt/Makefile index 457201f..59c8ec9 100644 --- a/drivers/net/ethernet/broadcom/bnxt/Makefile +++ b/drivers/net/ethernet/broadcom/bnxt/Makefile @@ -1,4 +1,4 @@ obj-$(CONFIG_BNXT) += bnxt_en.o -bnxt_en-y := bnxt.o bnxt_sriov.o bnxt_ethtool.o bnxt_dcb.o bnxt_ulp.o bnxt_xdp.o bnxt_vfr.o +bnxt_en-y := bnxt.o bnxt_sriov.o bnxt_ethtool.o bnxt_dcb.o bnxt_ulp.o bnxt_xdp.o bnxt_vfr.o bnxt_devlink.o bnxt_en-$(CONFIG_BNXT_FLOWER_OFFLOAD) += bnxt_tc.o diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c index 5ba4993..52cc38d 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c @@ -61,6 +61,7 @@ #include "bnxt_xdp.h" #include "bnxt_vfr.h" #include "bnxt_tc.h" +#include "bnxt_devlink.h" #define BNXT_TX_TIMEOUT (5 * HZ) diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_devlink.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_devlink.c new file mode 100644 index 0000000..d159cce --- /dev/null +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_devlink.c @@ -0,0 +1,109 @@ +/* Broadcom NetXtreme-C/E network driver. + * + * Copyright (c) 2017 Broadcom Limited + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation. + */ + +#include +#include +#include "bnxt_hsi.h" +#include "bnxt.h" +#include "bnxt_vfr.h" +#include "bnxt_devlink.h" + +static int bnxt_dl_eswitch_mode_get(struct devlink *devlink, u16 *mode) +{ + struct bnxt *bp = bnxt_get_bp_from_dl(devlink); + + *mode = bp->eswitch_mode; + return 0; +} + +static int bnxt_dl_eswitch_mode_set(struct devlink *devlink, u16 mode) +{ + struct bnxt *bp = bnxt_get_bp_from_dl(devlink); + int rc = 0; + + mutex_lock(&bp->sriov_lock); + if (bp->eswitch_mode == mode) { + netdev_info(bp->dev, "already in %s eswitch mode", + mode == DEVLINK_ESWITCH_MODE_LEGACY ? + "legacy" : "switchdev"); + rc = -EINVAL; + goto done; + } + + switch (mode) { + case DEVLINK_ESWITCH_MODE_LEGACY: + bnxt_vf_reps_destroy(bp); + break; + + case DEVLINK_ESWITCH_MODE_SWITCHDEV: + if (pci_num_vf(bp->pdev) == 0) { + netdev_info(bp->dev, + "Enable VFs before setting switchdev mode"); + rc = -EPERM; + goto done; + } + rc = bnxt_vf_reps_create(bp); + break; + + default: + rc = -EINVAL; + goto done; + } +done: + mutex_unlock(&bp->sriov_lock); + return rc; +} + +static const struct devlink_ops bnxt_dl_ops = { + .eswitch_mode_set = bnxt_dl_eswitch_mode_set, + .eswitch_mode_get = bnxt_dl_eswitch_mode_get, +}; + +int bnxt_dl_register(struct bnxt *bp) +{ + struct devlink *dl; + int rc; + + if (!pci_find_ext_capability(bp->pdev, PCI_EXT_CAP_ID_SRIOV)) + return 0; + + if (bp->hwrm_spec_code < 0x10800) { + netdev_warn(bp->dev, "Firmware does not support SR-IOV E-Switch SWITCHDEV mode.\n"); + return -ENOTSUPP; + } + + dl = devlink_alloc(&bnxt_dl_ops, sizeof(struct bnxt_dl)); + if (!dl) { + netdev_warn(bp->dev, "devlink_alloc failed"); + return -ENOMEM; + } + + bnxt_link_bp_to_dl(bp, dl); + bp->eswitch_mode = DEVLINK_ESWITCH_MODE_LEGACY; + rc = devlink_register(dl, &bp->pdev->dev); + if (rc) { + bnxt_link_bp_to_dl(bp, NULL); + devlink_free(dl); + netdev_warn(bp->dev, "devlink_register failed. rc=%d", rc); + return rc; + } + + return 0; +} + +void bnxt_dl_unregister(struct bnxt *bp) +{ + struct devlink *dl = bp->dl; + + if (!dl) + return; + + devlink_unregister(dl); + devlink_free(dl); +} diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_devlink.h b/drivers/net/ethernet/broadcom/bnxt/bnxt_devlink.h new file mode 100644 index 0000000..e92a35d --- /dev/null +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_devlink.h @@ -0,0 +1,39 @@ +/* Broadcom NetXtreme-C/E network driver. + * + * Copyright (c) 2017 Broadcom Limited + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation. + */ + +#ifndef BNXT_DEVLINK_H +#define BNXT_DEVLINK_H + +/* Struct to hold housekeeping info needed by devlink interface */ +struct bnxt_dl { + struct bnxt *bp; /* back ptr to the controlling dev */ +}; + +static inline struct bnxt *bnxt_get_bp_from_dl(struct devlink *dl) +{ + return ((struct bnxt_dl *)devlink_priv(dl))->bp; +} + +/* To clear devlink pointer from bp, pass NULL dl */ +static inline void bnxt_link_bp_to_dl(struct bnxt *bp, struct devlink *dl) +{ + bp->dl = dl; + + /* add a back pointer in dl to bp */ + if (dl) { + struct bnxt_dl *bp_dl = devlink_priv(dl); + + bp_dl->bp = bp; + } +} + +int bnxt_dl_register(struct bnxt *bp); +void bnxt_dl_unregister(struct bnxt *bp); + +#endif /* BNXT_DEVLINK_H */ diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_vfr.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_vfr.c index e75db04..1ed2bcf 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt_vfr.c +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_vfr.c @@ -338,7 +338,7 @@ static void bnxt_vf_rep_netdev_init(struct bnxt *bp, struct bnxt_vf_rep *vf_rep, ether_addr_copy(dev->dev_addr, dev->perm_addr); } -static int bnxt_vf_reps_create(struct bnxt *bp) +int bnxt_vf_reps_create(struct bnxt *bp) { u16 *cfa_code_map = NULL, num_vfs = pci_num_vf(bp->pdev); struct bnxt_vf_rep *vf_rep; @@ -415,99 +415,4 @@ static int bnxt_vf_reps_create(struct bnxt *bp) return rc; } -/* Devlink related routines */ -static int bnxt_dl_eswitch_mode_get(struct devlink *devlink, u16 *mode) -{ - struct bnxt *bp = bnxt_get_bp_from_dl(devlink); - - *mode = bp->eswitch_mode; - return 0; -} - -static int bnxt_dl_eswitch_mode_set(struct devlink *devlink, u16 mode) -{ - struct bnxt *bp = bnxt_get_bp_from_dl(devlink); - int rc = 0; - - mutex_lock(&bp->sriov_lock); - if (bp->eswitch_mode == mode) { - netdev_info(bp->dev, "already in %s eswitch mode", - mode == DEVLINK_ESWITCH_MODE_LEGACY ? - "legacy" : "switchdev"); - rc = -EINVAL; - goto done; - } - - switch (mode) { - case DEVLINK_ESWITCH_MODE_LEGACY: - bnxt_vf_reps_destroy(bp); - break; - - case DEVLINK_ESWITCH_MODE_SWITCHDEV: - if (pci_num_vf(bp->pdev) == 0) { - netdev_info(bp->dev, - "Enable VFs before setting switchdev mode"); - rc = -EPERM; - goto done; - } - rc = bnxt_vf_reps_create(bp); - break; - - default: - rc = -EINVAL; - goto done; - } -done: - mutex_unlock(&bp->sriov_lock); - return rc; -} - -static const struct devlink_ops bnxt_dl_ops = { - .eswitch_mode_set = bnxt_dl_eswitch_mode_set, - .eswitch_mode_get = bnxt_dl_eswitch_mode_get -}; - -int bnxt_dl_register(struct bnxt *bp) -{ - struct devlink *dl; - int rc; - - if (!pci_find_ext_capability(bp->pdev, PCI_EXT_CAP_ID_SRIOV)) - return 0; - - if (bp->hwrm_spec_code < 0x10800) { - netdev_warn(bp->dev, "Firmware does not support SR-IOV E-Switch SWITCHDEV mode.\n"); - return -ENOTSUPP; - } - - dl = devlink_alloc(&bnxt_dl_ops, sizeof(struct bnxt_dl)); - if (!dl) { - netdev_warn(bp->dev, "devlink_alloc failed"); - return -ENOMEM; - } - - bnxt_link_bp_to_dl(bp, dl); - bp->eswitch_mode = DEVLINK_ESWITCH_MODE_LEGACY; - rc = devlink_register(dl, &bp->pdev->dev); - if (rc) { - bnxt_link_bp_to_dl(bp, NULL); - devlink_free(dl); - netdev_warn(bp->dev, "devlink_register failed. rc=%d", rc); - return rc; - } - - return 0; -} - -void bnxt_dl_unregister(struct bnxt *bp) -{ - struct devlink *dl = bp->dl; - - if (!dl) - return; - - devlink_unregister(dl); - devlink_free(dl); -} - #endif diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_vfr.h b/drivers/net/ethernet/broadcom/bnxt/bnxt_vfr.h index 7787cd24..1b67ce1 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt_vfr.h +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_vfr.h @@ -14,36 +14,12 @@ #define MAX_CFA_CODE 65536 -/* Struct to hold housekeeping info needed by devlink interface */ -struct bnxt_dl { - struct bnxt *bp; /* back ptr to the controlling dev */ -}; - -static inline struct bnxt *bnxt_get_bp_from_dl(struct devlink *dl) -{ - return ((struct bnxt_dl *)devlink_priv(dl))->bp; -} - -/* To clear devlink pointer from bp, pass NULL dl */ -static inline void bnxt_link_bp_to_dl(struct bnxt *bp, struct devlink *dl) -{ - bp->dl = dl; - - /* add a back pointer in dl to bp */ - if (dl) { - struct bnxt_dl *bp_dl = devlink_priv(dl); - - bp_dl->bp = bp; - } -} - -int bnxt_dl_register(struct bnxt *bp); -void bnxt_dl_unregister(struct bnxt *bp); void bnxt_vf_reps_destroy(struct bnxt *bp); void bnxt_vf_reps_close(struct bnxt *bp); void bnxt_vf_reps_open(struct bnxt *bp); void bnxt_vf_rep_rx(struct bnxt *bp, struct sk_buff *skb); struct net_device *bnxt_get_vf_rep(struct bnxt *bp, u16 cfa_code); +int bnxt_vf_reps_create(struct bnxt *bp); static inline u16 bnxt_vf_rep_get_fid(struct net_device *dev) { @@ -55,15 +31,6 @@ static inline u16 bnxt_vf_rep_get_fid(struct net_device *dev) #else -static inline int bnxt_dl_register(struct bnxt *bp) -{ - return 0; -} - -static inline void bnxt_dl_unregister(struct bnxt *bp) -{ -} - static inline void bnxt_vf_reps_close(struct bnxt *bp) { } From patchwork Thu Oct 12 13:34:22 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Steve Lin X-Patchwork-Id: 824855 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=linux-pci-owner@vger.kernel.org; receiver=) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 3yCX0G5R09z9sNw for ; Fri, 13 Oct 2017 00:35:09 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1757586AbdJLNfF (ORCPT ); Thu, 12 Oct 2017 09:35:05 -0400 Received: from rnd-relay.smtp.broadcom.com ([192.19.229.170]:50326 "EHLO rnd-relay.smtp.broadcom.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1757569AbdJLNe6 (ORCPT ); Thu, 12 Oct 2017 09:34:58 -0400 Received: from mail-irv-17.broadcom.com (mail-irv-17.lvn.broadcom.net [10.75.224.233]) by rnd-relay.smtp.broadcom.com (Postfix) with ESMTP id 7331730C018; Thu, 12 Oct 2017 06:34:57 -0700 (PDT) Received: from xl-rtp-02.broadcom.com (xl-rtp-02.ash.broadcom.net [10.85.234.3]) by mail-irv-17.broadcom.com (Postfix) with ESMTP id 558D981EAD; Thu, 12 Oct 2017 06:34:57 -0700 (PDT) Received: by xl-rtp-02.broadcom.com (Postfix, from userid 113764) id CC9B94C0807; Thu, 12 Oct 2017 09:34:56 -0400 (EDT) From: Steve Lin To: netdev@vger.kernel.org Cc: jiri@mellanox.com, davem@davemloft.net, michael.chan@broadcom.com, linux-pci@vger.kernel.org, linville@tuxdriver.com, gospo@broadcom.com, steven.lin1@broadcom.com Subject: [RFC 3/3] bnxt: Add devlink support for config get/set Date: Thu, 12 Oct 2017 09:34:22 -0400 Message-Id: <1507815262-33294-4-git-send-email-steven.lin1@broadcom.com> X-Mailer: git-send-email 2.1.0 In-Reply-To: <1507815262-33294-1-git-send-email-steven.lin1@broadcom.com> References: <1507815262-33294-1-git-send-email-steven.lin1@broadcom.com> Sender: linux-pci-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pci@vger.kernel.org Implements get and set of configuration parameters using new devlink config get/set API. Signed-off-by: Steve Lin Acked-by: Andy Gospodarek --- drivers/net/ethernet/broadcom/bnxt/bnxt_devlink.c | 306 +++++++++++++++++++++- drivers/net/ethernet/broadcom/bnxt/bnxt_devlink.h | 17 ++ drivers/net/ethernet/broadcom/bnxt/bnxt_hsi.h | 100 +++++++ 3 files changed, 417 insertions(+), 6 deletions(-) diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_devlink.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_devlink.c index d159cce..32319d5 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt_devlink.c +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_devlink.c @@ -14,6 +14,83 @@ #include "bnxt_vfr.h" #include "bnxt_devlink.h" +struct bnxt_drv_cfgparam bnxt_drv_cfgparam_list[] = { + {DEVLINK_ATTR_MAX_NUM_PF_MSIX_VECT, BNXT_DRV_PF, + BNXT_DRV_APPL_SHARED, 10, 108}, + {DEVLINK_ATTR_IGNORE_ARI_CAPABILITY, BNXT_DRV_PF, + BNXT_DRV_APPL_SHARED, 1, 164}, + {DEVLINK_ATTR_PME_CAPABILITY_ENABLED, BNXT_DRV_PF, + BNXT_DRV_APPL_SHARED, 1, 166}, + {DEVLINK_ATTR_LLDP_NEAREST_BRIDGE_ENABLED, BNXT_DRV_PF, + BNXT_DRV_APPL_SHARED, 1, 269}, + {DEVLINK_ATTR_LLDP_NEAREST_NONTPMR_BRIDGE_ENABLED, BNXT_DRV_PF, + BNXT_DRV_APPL_SHARED, 1, 270}, + {DEVLINK_ATTR_SECURE_NIC_ENABLED, BNXT_DRV_PF, + BNXT_DRV_APPL_SHARED, 1, 162}, + {DEVLINK_ATTR_PHY_SELECT, BNXT_DRV_PF, + BNXT_DRV_APPL_SHARED, 1, 329}, + {DEVLINK_ATTR_SRIOV_ENABLED, BNXT_DRV_PF, + BNXT_DRV_APPL_SHARED, 1, 401}, + + {DEVLINK_ATTR_MBA_ENABLED, BNXT_DRV_PF, + BNXT_DRV_APPL_FUNCTION, 1, 351}, + {DEVLINK_ATTR_MBA_BOOT_TYPE, BNXT_DRV_PF, + BNXT_DRV_APPL_FUNCTION, 2, 352}, + {DEVLINK_ATTR_MBA_DELAY_TIME, BNXT_DRV_PF, + BNXT_DRV_APPL_FUNCTION, 4, 353}, + {DEVLINK_ATTR_MBA_SETUP_HOT_KEY, BNXT_DRV_PF, + BNXT_DRV_APPL_FUNCTION, 1, 354}, + {DEVLINK_ATTR_MBA_HIDE_SETUP_PROMPT, BNXT_DRV_PF, + BNXT_DRV_APPL_FUNCTION, 1, 355}, + {DEVLINK_ATTR_MBA_VLAN_TAG, BNXT_DRV_PF, + BNXT_DRV_APPL_FUNCTION, 16, 357}, + {DEVLINK_ATTR_MBA_VLAN_ENABLED, BNXT_DRV_PF, + BNXT_DRV_APPL_FUNCTION, 1, 358}, + {DEVLINK_ATTR_MBA_LINK_SPEED, BNXT_DRV_PF, + BNXT_DRV_APPL_FUNCTION, 4, 359}, + {DEVLINK_ATTR_MBA_BOOT_RETRY_COUNT, BNXT_DRV_PF, + BNXT_DRV_APPL_FUNCTION, 3, 360}, + {DEVLINK_ATTR_MBA_BOOT_PROTOCOL, BNXT_DRV_PF, + BNXT_DRV_APPL_FUNCTION, 3, 361}, + {DEVLINK_ATTR_NUM_VF_PER_PF, BNXT_DRV_PF, + BNXT_DRV_APPL_FUNCTION, 8, 404}, + {DEVLINK_ATTR_MSIX_VECTORS_PER_VF, BNXT_DRV_PF, + BNXT_DRV_APPL_FUNCTION, 10, 406}, + {DEVLINK_ATTR_NPAR_BW_RESERVATION, BNXT_DRV_PF, + BNXT_DRV_APPL_FUNCTION, 10, 501}, + {DEVLINK_ATTR_NPAR_BW_LIMIT, BNXT_DRV_PF, + BNXT_DRV_APPL_FUNCTION, 10, 502}, + {DEVLINK_ATTR_RDMA_ENABLED, BNXT_DRV_PF, + BNXT_DRV_APPL_FUNCTION, 1, 506}, + {DEVLINK_ATTR_NPAR_BW_IN_PERCENT, BNXT_DRV_PF, + BNXT_DRV_APPL_FUNCTION, 1, 507}, + {DEVLINK_ATTR_NPAR_BW_RESERVATION_VALID, BNXT_DRV_PF, + BNXT_DRV_APPL_FUNCTION, 1, 508}, + {DEVLINK_ATTR_NPAR_BW_LIMIT_VALID, BNXT_DRV_PF, + BNXT_DRV_APPL_FUNCTION, 1, 509}, + + {DEVLINK_ATTR_MAGIC_PACKET_WOL_ENABLED, BNXT_DRV_PF, + BNXT_DRV_APPL_PORT, 1, 152}, + {DEVLINK_ATTR_DCBX_MODE, BNXT_DRV_PF, + BNXT_DRV_APPL_PORT, 4, 155}, + {DEVLINK_ATTR_MULTIFUNC_MODE, BNXT_DRV_PF, + BNXT_DRV_APPL_PORT, 5, 157}, + {DEVLINK_ATTR_PRE_OS_LINK_SPEED_D0, BNXT_DRV_PF, + BNXT_DRV_APPL_PORT, 4, 205}, + {DEVLINK_ATTR_EEE_PWR_SAVE_ENABLED, BNXT_DRV_PF, + BNXT_DRV_APPL_PORT, 1, 208}, + {DEVLINK_ATTR_PRE_OS_LINK_SPEED_D3, BNXT_DRV_PF, + BNXT_DRV_APPL_PORT, 4, 210}, + {DEVLINK_ATTR_MEDIA_AUTO_DETECT, BNXT_DRV_PF, + BNXT_DRV_APPL_PORT, 1, 213}, + {DEVLINK_ATTR_AUTONEG_PROTOCOL, BNXT_DRV_PF, + BNXT_DRV_APPL_PORT, 8, 312}, + {DEVLINK_ATTR_NPAR_NUM_PARTITIONS_PER_PORT, BNXT_DRV_PF, + BNXT_DRV_APPL_PORT, 8, 503}, +}; + +#define BNXT_NUM_DRV_CFGPARAM ARRAY_SIZE(bnxt_drv_cfgparam_list) + static int bnxt_dl_eswitch_mode_get(struct devlink *devlink, u16 *mode) { struct bnxt *bp = bnxt_get_bp_from_dl(devlink); @@ -60,9 +137,226 @@ static int bnxt_dl_eswitch_mode_set(struct devlink *devlink, u16 mode) return rc; } -static const struct devlink_ops bnxt_dl_ops = { +static int bnxt_nvm_read(struct bnxt *bp, int nvm_param, int idx, + void *buf, int size) +{ + struct hwrm_nvm_get_variable_input req = {0}; + void *dest_data_addr = NULL; + dma_addr_t dest_data_dma_addr; + int rc; + int bytesize; + + bytesize = (size + 7) / 8; + dest_data_addr = dma_alloc_coherent(&bp->pdev->dev, bytesize, + &dest_data_dma_addr, GFP_KERNEL); + if (!dest_data_addr) { + netdev_err(bp->dev, "dma_alloc_coherent failure\n"); + return -ENOMEM; + } + + bnxt_hwrm_cmd_hdr_init(bp, &req, HWRM_NVM_GET_VARIABLE, -1, -1); + req.dest_data_addr = cpu_to_le64(dest_data_dma_addr); + req.data_len = cpu_to_le16(size); + req.option_num = cpu_to_le16(nvm_param); + req.index_0 = cpu_to_le16(idx); + if (idx != 0) + req.dimensions = cpu_to_le16(1); + + rc = _hwrm_send_message(bp, &req, sizeof(req), HWRM_CMD_TIMEOUT); + + memcpy(buf, dest_data_addr, size); + + dma_free_coherent(&bp->pdev->dev, bytesize, dest_data_addr, + dest_data_dma_addr); + + return rc; +} + +static int bnxt_nvm_write(struct bnxt *bp, int nvm_param, int idx, + const void *buf, int size) +{ + struct hwrm_nvm_set_variable_input req = {0}; + void *src_data_addr = NULL; + dma_addr_t src_data_dma_addr; + int rc; + int bytesize; + + bytesize = (size + 7) / 8; + + src_data_addr = dma_alloc_coherent(&bp->pdev->dev, bytesize, + &src_data_dma_addr, GFP_KERNEL); + if (!src_data_addr) { + netdev_err(bp->dev, "dma_alloc_coherent failure\n"); + return -ENOMEM; + } + + memcpy(src_data_addr, buf, bytesize); + + bnxt_hwrm_cmd_hdr_init(bp, &req, HWRM_NVM_SET_VARIABLE, -1, -1); + req.src_data_addr = cpu_to_le64(src_data_dma_addr); + req.data_len = cpu_to_le16(size); + req.option_num = cpu_to_le16(nvm_param); + req.index_0 = cpu_to_le16(idx); + if (idx != 0) + req.dimensions = cpu_to_le16(1); + + rc = _hwrm_send_message(bp, &req, sizeof(req), HWRM_CMD_TIMEOUT); + + dma_free_coherent(&bp->pdev->dev, bytesize, src_data_addr, + src_data_dma_addr); + + return 0; +} + +static int bnxt_dl_config_set(struct devlink *devlink, + enum devlink_attr attr, u32 value, + u8 *restart_reqd) +{ + struct bnxt *bp = bnxt_get_bp_from_dl(devlink); + int i; + int idx = 0; + void *data; + int ret = 0; + u32 bytesize; + struct bnxt_drv_cfgparam *entry; + + *restart_reqd = 0; + + /* Find parameter in table */ + for (i = 0; i < BNXT_NUM_DRV_CFGPARAM; i++) { + if (attr == bnxt_drv_cfgparam_list[i].attr) { + entry = &bnxt_drv_cfgparam_list[i]; + break; + } + } + + /* Not found */ + if (i == BNXT_NUM_DRV_CFGPARAM) + return -EINVAL; + + /* Check to see if this func type can access variable */ + if (BNXT_PF(bp) && !(entry->func & BNXT_DRV_PF)) + return -EOPNOTSUPP; + if (BNXT_VF(bp) && !(entry->func & BNXT_DRV_VF)) + return -EOPNOTSUPP; + + /* If parameter is per port or function, compute index */ + if (entry->appl == BNXT_DRV_APPL_PORT) { + idx = bp->pf.port_id; + } else if (entry->appl == BNXT_DRV_APPL_FUNCTION) { + if (BNXT_PF(bp)) + idx = bp->pf.fw_fid - BNXT_FIRST_PF_FID; + else + idx = bp->vf.fw_fid - BNXT_FIRST_VF_FID; + } + + bytesize = (entry->bitlength + 7) / 8; + data = kmalloc(bytesize, GFP_KERNEL); + if (!data) + return -ENOMEM; + + if (bytesize == 1) { + u8 val8 = (value & 0xff); + + memcpy(data, &val8, sizeof(u8)); + } else if (bytesize == 2) { + u16 val16 = (value & 0xffff); + + memcpy(data, &val16, sizeof(u16)); + } else { + memcpy(data, &value, sizeof(u32)); + } + + ret = bnxt_nvm_write(bp, entry->nvm_param, idx, data, + entry->bitlength); + + /* Restart required for all nvm parameter writes */ + *restart_reqd = 1; + + kfree(data); + + return ret; +} + +static int bnxt_dl_config_get(struct devlink *devlink, + enum devlink_attr attr, u32 *value) +{ + struct bnxt *bp = bnxt_get_bp_from_dl(devlink); + + int i; + int idx = 0; + void *data; + int ret = 0; + u32 bytesize; + struct bnxt_drv_cfgparam *entry; + + /* Find parameter in table */ + for (i = 0; i < BNXT_NUM_DRV_CFGPARAM; i++) { + if (attr == bnxt_drv_cfgparam_list[i].attr) { + entry = &bnxt_drv_cfgparam_list[i]; + break; + } + } + + /* Not found */ + if (i == BNXT_NUM_DRV_CFGPARAM) + return -EINVAL; + + /* Check to see if this func type can access variable */ + if (BNXT_PF(bp) && !(entry->func & BNXT_DRV_PF)) + return -EOPNOTSUPP; + if (BNXT_VF(bp) && !(entry->func & BNXT_DRV_VF)) + return -EOPNOTSUPP; + + /* If parameter is per port or function, compute index */ + if (entry->appl == BNXT_DRV_APPL_PORT) { + idx = bp->pf.port_id; + } else if (entry->appl == BNXT_DRV_APPL_FUNCTION) { + if (BNXT_PF(bp)) + idx = bp->pf.fw_fid - BNXT_FIRST_PF_FID; + else + idx = bp->vf.fw_fid - BNXT_FIRST_VF_FID; + } + + /* Allocate space, retrieve value, and copy to result */ + bytesize = (entry->bitlength + 7) / 8; + data = kmalloc(bytesize, GFP_KERNEL); + if (!data) + return -ENOMEM; + ret = bnxt_nvm_read(bp, entry->nvm_param, idx, data, entry->bitlength); + + if (ret) { + kfree(data); + return ret; + } + + if (bytesize == 1) { + u8 val; + + memcpy(&val, data, sizeof(u8)); + *value = val; + } else if (bytesize == 2) { + u16 val; + + memcpy(&val, data, sizeof(u16)); + *value = val; + } else { + u32 val; + + memcpy(&val, data, sizeof(u32)); + *value = val; + } + + kfree(data); + + return 0; +} + +static struct devlink_ops bnxt_dl_ops = { .eswitch_mode_set = bnxt_dl_eswitch_mode_set, .eswitch_mode_get = bnxt_dl_eswitch_mode_get, + .config_get = bnxt_dl_config_get, + .config_set = bnxt_dl_config_set, }; int bnxt_dl_register(struct bnxt *bp) @@ -70,12 +364,12 @@ int bnxt_dl_register(struct bnxt *bp) struct devlink *dl; int rc; - if (!pci_find_ext_capability(bp->pdev, PCI_EXT_CAP_ID_SRIOV)) - return 0; - - if (bp->hwrm_spec_code < 0x10800) { + if ((!pci_find_ext_capability(bp->pdev, PCI_EXT_CAP_ID_SRIOV)) || + bp->hwrm_spec_code < 0x10800) { + /* eswitch switchdev mode not supported */ + bnxt_dl_ops.eswitch_mode_set = NULL; + bnxt_dl_ops.eswitch_mode_get = NULL; netdev_warn(bp->dev, "Firmware does not support SR-IOV E-Switch SWITCHDEV mode.\n"); - return -ENOTSUPP; } dl = devlink_alloc(&bnxt_dl_ops, sizeof(struct bnxt_dl)); diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_devlink.h b/drivers/net/ethernet/broadcom/bnxt/bnxt_devlink.h index e92a35d..ee28890 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt_devlink.h +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_devlink.h @@ -10,6 +10,23 @@ #ifndef BNXT_DEVLINK_H #define BNXT_DEVLINK_H +#define BNXT_DRV_PF 1 +#define BNXT_DRV_VF 2 + +enum bnxt_drv_appl { + BNXT_DRV_APPL_SHARED, + BNXT_DRV_APPL_PORT, + BNXT_DRV_APPL_FUNCTION +}; + +struct bnxt_drv_cfgparam { + enum devlink_attr attr; + u8 func; /* BNXT_DRV_PF | BNXT_DRV_VF */ + enum bnxt_drv_appl appl; /* applicability (shared, func, port) */ + u32 bitlength; /* length, in bits */ + u32 nvm_param; +}; + /* Struct to hold housekeeping info needed by devlink interface */ struct bnxt_dl { struct bnxt *bp; /* back ptr to the controlling dev */ diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_hsi.h b/drivers/net/ethernet/broadcom/bnxt/bnxt_hsi.h index cb04cc7..8c25731 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt_hsi.h +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_hsi.h @@ -5676,6 +5676,106 @@ struct hwrm_nvm_install_update_cmd_err { u8 unused_0[7]; }; +/* hwrm_nvm_get_variable */ +/* Input (40 bytes) */ +struct hwrm_nvm_get_variable_input { + __le16 req_type; + __le16 cmpl_ring; + __le16 seq_id; + __le16 target_id; + __le64 resp_addr; + __le64 dest_data_addr; + __le16 data_len; + __le16 option_num; + #define NVM_GET_VARIABLE_REQ_OPTION_NUM_RSVD_0 0x0UL + #define NVM_GET_VARIABLE_REQ_OPTION_NUM_RSVD_FFFF 0xffffUL + __le16 dimensions; + __le16 index_0; + __le16 index_1; + __le16 index_2; + __le16 index_3; + u8 flags; + #define NVM_GET_VARIABLE_REQ_FLAGS_FACTORY_DFLT 0x1UL + u8 unused_0; +}; + +/* Output (16 bytes) */ +struct hwrm_nvm_get_variable_output { + __le16 error_code; + __le16 req_type; + __le16 seq_id; + __le16 resp_len; + __le16 data_len; + __le16 option_num; + #define NVM_GET_VARIABLE_RESP_OPTION_NUM_RSVD_0 0x0UL + #define NVM_GET_VARIABLE_RESP_OPTION_NUM_RSVD_FFFF 0xffffUL + u8 unused_0; + u8 unused_1; + u8 unused_2; + u8 valid; +}; + +/* Command specific Error Codes (8 bytes) */ +struct hwrm_nvm_get_variable_cmd_err { + u8 code; + #define NVM_GET_VARIABLE_CMD_ERR_CODE_UNKNOWN 0x0UL + #define NVM_GET_VARIABLE_CMD_ERR_CODE_VAR_NOT_EXIST 0x1UL + #define NVM_GET_VARIABLE_CMD_ERR_CODE_CORRUPT_VAR 0x2UL + #define NVM_GET_VARIABLE_CMD_ERR_CODE_LEN_TOO_SHORT 0x3UL + u8 unused_0[7]; +}; + +/* hwrm_nvm_set_variable */ +/* Input (40 bytes) */ +struct hwrm_nvm_set_variable_input { + __le16 req_type; + __le16 cmpl_ring; + __le16 seq_id; + __le16 target_id; + __le64 resp_addr; + __le64 src_data_addr; + __le16 data_len; + __le16 option_num; + #define NVM_SET_VARIABLE_REQ_OPTION_NUM_RSVD_0 0x0UL + #define NVM_SET_VARIABLE_REQ_OPTION_NUM_RSVD_FFFF 0xffffUL + __le16 dimensions; + __le16 index_0; + __le16 index_1; + __le16 index_2; + __le16 index_3; + u8 flags; + #define NVM_SET_VARIABLE_REQ_FLAGS_FORCE_FLUSH 0x1UL + #define NVM_SET_VARIABLE_REQ_FLAGS_ENCRYPT_MODE_MASK 0xeUL + #define NVM_SET_VARIABLE_REQ_FLAGS_ENCRYPT_MODE_SFT 1 + #define NVM_SET_VARIABLE_REQ_FLAGS_ENCRYPT_MODE_NONE (0x0UL << 1) + #define NVM_SET_VARIABLE_REQ_FLAGS_ENCRYPT_MODE_HMAC_SHA1 (0x1UL << 1) + #define NVM_SET_VARIABLE_REQ_FLAGS_ENCRYPT_MODE_LAST \ + NVM_SET_VARIABLE_REQ_FLAGS_ENCRYPT_MODE_HMAC_SHA1 + u8 unused_0; +}; + +/* Output (16 bytes) */ +struct hwrm_nvm_set_variable_output { + __le16 error_code; + __le16 req_type; + __le16 seq_id; + __le16 resp_len; + __le32 unused_0; + u8 unused_1; + u8 unused_2; + u8 unused_3; + u8 valid; +}; + +/* Command specific Error Codes (8 bytes) */ +struct hwrm_nvm_set_variable_cmd_err { + u8 code; + #define NVM_SET_VARIABLE_CMD_ERR_CODE_UNKNOWN 0x0UL + #define NVM_SET_VARIABLE_CMD_ERR_CODE_VAR_NOT_EXIST 0x1UL + #define NVM_SET_VARIABLE_CMD_ERR_CODE_CORRUPT_VAR 0x2UL + u8 unused_0[7]; +}; + /* hwrm_selftest_qlist */ /* Input (16 bytes) */ struct hwrm_selftest_qlist_input {