From patchwork Mon Jun 10 07:38:34 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrew Rybchenko X-Patchwork-Id: 54613 X-Patchwork-Delegate: ferruh.yigit@amd.com Return-Path: X-Original-To: patchwork@dpdk.org Delivered-To: patchwork@dpdk.org Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id 375FA1BF61; Mon, 10 Jun 2019 09:39:47 +0200 (CEST) Received: from dispatch1-us1.ppe-hosted.com (dispatch1-us1.ppe-hosted.com [67.231.154.164]) by dpdk.org (Postfix) with ESMTP id BF18D1BEA6 for ; Mon, 10 Jun 2019 09:39:02 +0200 (CEST) X-Virus-Scanned: Proofpoint Essentials engine Received: from webmail.solarflare.com (webmail.solarflare.com [12.187.104.26]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-SHA384 (256/256 bits)) (No client certificate requested) by mx1-us1.ppe-hosted.com (PPE Hosted ESMTP Server) with ESMTPS id 62382140058 for ; Mon, 10 Jun 2019 07:38:59 +0000 (UTC) Received: from ocex03.SolarFlarecom.com (10.20.40.36) by ocex03.SolarFlarecom.com (10.20.40.36) with Microsoft SMTP Server (TLS) id 15.0.1395.4; Mon, 10 Jun 2019 00:38:52 -0700 Received: from opal.uk.solarflarecom.com (10.17.10.1) by ocex03.SolarFlarecom.com (10.20.40.36) with Microsoft SMTP Server (TLS) id 15.0.1395.4 via Frontend Transport; Mon, 10 Jun 2019 00:38:51 -0700 Received: from ukv-loginhost.uk.solarflarecom.com (ukv-loginhost.uk.solarflarecom.com [10.17.10.39]) by opal.uk.solarflarecom.com (8.13.8/8.13.8) with ESMTP id x5A7cn0U008832; Mon, 10 Jun 2019 08:38:50 +0100 Received: from ukv-loginhost.uk.solarflarecom.com (localhost [127.0.0.1]) by ukv-loginhost.uk.solarflarecom.com (Postfix) with ESMTP id E66F11627D7; Mon, 10 Jun 2019 08:38:49 +0100 (BST) From: Andrew Rybchenko To: CC: Gautam Dawar Date: Mon, 10 Jun 2019 08:38:34 +0100 Message-ID: <1560152324-20538-20-git-send-email-arybchenko@solarflare.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1560152324-20538-1-git-send-email-arybchenko@solarflare.com> References: <1560152324-20538-1-git-send-email-arybchenko@solarflare.com> MIME-Version: 1.0 X-TM-AS-Product-Ver: SMEX-12.5.0.1300-8.5.1010-24664.003 X-TM-AS-Result: No-7.565700-4.000000-10 X-TMASE-MatchedRID: qR7nF2Wf8maioKUtUDGXZbsHVDDM5xAPhVDnkfzD7uYGmHr1eMxt2UAc 6DyoS2rI1rH4Rg0AOT23nkIqH6M4JTkz8rxzPB1EbrJ9gVnOsZ33+mUqDWUKyFVkJxysad/I5Ne iQRB8ToU48oM6Nl53yfabu9IFe9V/M2R/zs7lmY8wjFu8zcBWiNLKOgBq74UZc8idZA/Hf6rxaD g7Q6F9kCUU0Q3EwNK5C7G20cjQ7SM+YoPOMX63ULdHEv7sR/OwuoYFb0nRiqNZ+YxyNxdzRxGXN nD2NmndnDS8peVxhr/wCYbUR7eAYo8bqSqUWVHidhnFihmbnwWrlTqw7wfC08YnQg0xziu3WbA8 i7TsQRLi8zVgXoAltsIJ+4gwXrEtIAcCikR3vq85j+TA2k1VwKVJwDclE6/tIKnN6OcWHkaryaV XNRIaRkCqUfJX3SRb X-TM-AS-User-Approved-Sender: No X-TM-AS-User-Blocked-Sender: No X-TMASE-Result: 10--7.565700-4.000000 X-TMASE-Version: SMEX-12.5.0.1300-8.5.1010-24664.003 X-MDID: 1560152340-KG6GMB7q8yDW Subject: [dpdk-dev] [PATCH 19/29] net/sfc/base: add MCDI wrappers for vPort and vSwitch in EVB X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" From: Gautam Dawar Add the functions to implement the vPort and vSwitch MCDI calls. Signed-off-by: Gautam Dawar Signed-off-by: Andrew Rybchenko --- drivers/net/sfc/base/ef10_evb.c | 299 ++++++++++++++++++++++++++++++++++++++++ drivers/net/sfc/base/efx.h | 18 +++ 2 files changed, 317 insertions(+) diff --git a/drivers/net/sfc/base/ef10_evb.c b/drivers/net/sfc/base/ef10_evb.c index 03ac19a..18cecc2 100644 --- a/drivers/net/sfc/base/ef10_evb.c +++ b/drivers/net/sfc/base/ef10_evb.c @@ -31,5 +31,304 @@ enp->en_family == EFX_FAMILY_MEDFORD2); } + __checkReturn efx_rc_t +efx_mcdi_vswitch_alloc( + __in efx_nic_t *enp, + __in efx_vport_id_t vport_id, + __in efx_vswitch_type_t vswitch_type) +{ + EFX_MCDI_DECLARE_BUF(payload, MC_CMD_VSWITCH_ALLOC_IN_LEN, + MC_CMD_VSWITCH_ALLOC_OUT_LEN); + efx_mcdi_req_t req; + efx_rc_t rc; + uint8_t ntags; + + /* Ensure EFX and MCDI use same values for vswitch types */ + EFX_STATIC_ASSERT(EFX_VSWITCH_TYPE_VLAN == + MC_CMD_VSWITCH_ALLOC_IN_VSWITCH_TYPE_VLAN); + EFX_STATIC_ASSERT(EFX_VSWITCH_TYPE_VEB == + MC_CMD_VSWITCH_ALLOC_IN_VSWITCH_TYPE_VEB); + EFX_STATIC_ASSERT(EFX_VSWITCH_TYPE_MUX == + MC_CMD_VSWITCH_ALLOC_IN_VSWITCH_TYPE_MUX); + + /* First try with maximum number of VLAN tags FW supports */ + ntags = 2; +retry: + req.emr_cmd = MC_CMD_VSWITCH_ALLOC; + req.emr_in_buf = payload; + req.emr_in_length = MC_CMD_VSWITCH_ALLOC_IN_LEN; + req.emr_out_buf = payload; + req.emr_out_length = MC_CMD_VSWITCH_ALLOC_OUT_LEN; + + MCDI_IN_SET_DWORD(req, VSWITCH_ALLOC_IN_UPSTREAM_PORT_ID, vport_id); + MCDI_IN_SET_DWORD(req, VSWITCH_ALLOC_IN_TYPE, vswitch_type); + MCDI_IN_SET_DWORD(req, VSWITCH_ALLOC_IN_NUM_VLAN_TAGS, ntags); + MCDI_IN_POPULATE_DWORD_1(req, VSWITCH_ALLOC_IN_FLAGS, + VSWITCH_ALLOC_IN_FLAG_AUTO_PORT, 0); + + efx_mcdi_execute(enp, &req); + + if (req.emr_rc != 0) { + rc = req.emr_rc; + /* + * efx_rc_t error codes in libefx are translated from MCDI + * error codes in efx_mcdi_request_errcode. As this conversion + * is not a 1:1, here we check the specific MCDI error code. + */ + if (req.emr_err_code == MC_CMD_ERR_VLAN_LIMIT) { + /* Too many VLAN tags, retry with fewer */ + EFSYS_PROBE(vlan_limit); + ntags--; + if (ntags > 0) { + /* + * Zero the buffer before reusing it + * for another request + */ + memset(payload, 0, sizeof (payload)); + goto retry; + } + goto fail1; + } + } + + return (0); + +fail1: + EFSYS_PROBE1(fail1, efx_rc_t, rc); + return (rc); +} + + __checkReturn efx_rc_t +efx_mcdi_vswitch_free( + __in efx_nic_t *enp) +{ + EFX_MCDI_DECLARE_BUF(payload, MC_CMD_VSWITCH_FREE_IN_LEN, + MC_CMD_VSWITCH_FREE_OUT_LEN); + efx_mcdi_req_t req; + efx_rc_t rc; + + req.emr_cmd = MC_CMD_VSWITCH_FREE; + req.emr_in_buf = payload; + req.emr_in_length = MC_CMD_VSWITCH_FREE_IN_LEN; + req.emr_out_buf = payload; + req.emr_out_length = MC_CMD_VSWITCH_FREE_OUT_LEN; + + MCDI_IN_SET_DWORD(req, VSWITCH_FREE_IN_UPSTREAM_PORT_ID, + EVB_PORT_ID_ASSIGNED); + efx_mcdi_execute(enp, &req); + + if (req.emr_rc != 0) { + rc = req.emr_rc; + goto fail1; + } + + return (0); + +fail1: + EFSYS_PROBE1(fail1, efx_rc_t, rc); + return (rc); +} + + __checkReturn efx_rc_t +efx_mcdi_vport_alloc( + __in efx_nic_t *enp, + __in efx_vport_type_t vport_type, + __in uint16_t vid, + __in boolean_t vlan_restrict, + __out efx_vport_id_t *vport_idp) +{ + EFX_MCDI_DECLARE_BUF(payload, MC_CMD_VPORT_ALLOC_IN_LEN, + MC_CMD_VPORT_ALLOC_OUT_LEN); + efx_mcdi_req_t req; + efx_rc_t rc; + + /* Ensure EFX and MCDI use same values for vport types */ + EFX_STATIC_ASSERT(EFX_VPORT_TYPE_NORMAL == + MC_CMD_VPORT_ALLOC_IN_VPORT_TYPE_NORMAL); + EFX_STATIC_ASSERT(EFX_VPORT_TYPE_EXPANSION == + MC_CMD_VPORT_ALLOC_IN_VPORT_TYPE_EXPANSION); + EFX_STATIC_ASSERT(EFX_VPORT_TYPE_TEST == + MC_CMD_VPORT_ALLOC_IN_VPORT_TYPE_TEST); + + req.emr_cmd = MC_CMD_VPORT_ALLOC; + req.emr_in_buf = payload; + req.emr_in_length = MC_CMD_VPORT_ALLOC_IN_LEN; + req.emr_out_buf = payload; + req.emr_out_length = MC_CMD_VPORT_ALLOC_OUT_LEN; + + MCDI_IN_SET_DWORD(req, VPORT_ALLOC_IN_UPSTREAM_PORT_ID, + EVB_PORT_ID_ASSIGNED); + MCDI_IN_SET_DWORD(req, VPORT_ALLOC_IN_TYPE, vport_type); + MCDI_IN_SET_DWORD(req, VPORT_ALLOC_IN_NUM_VLAN_TAGS, + (vid != EFX_FILTER_VID_UNSPEC)); + + MCDI_IN_POPULATE_DWORD_2(req, VPORT_ALLOC_IN_FLAGS, + VPORT_ALLOC_IN_FLAG_AUTO_PORT, 0, + VPORT_ALLOC_IN_FLAG_VLAN_RESTRICT, vlan_restrict); + + if (vid != EFX_FILTER_VID_UNSPEC) + MCDI_IN_POPULATE_DWORD_1(req, VPORT_ALLOC_IN_VLAN_TAGS, + VPORT_ALLOC_IN_VLAN_TAG_0, vid); + + efx_mcdi_execute(enp, &req); + + if (req.emr_rc != 0) { + rc = req.emr_rc; + goto fail1; + } + + if (req.emr_out_length_used < MC_CMD_VPORT_ALLOC_OUT_LEN) { + rc = EMSGSIZE; + goto fail2; + } + + *vport_idp = *MCDI_OUT2(req, uint32_t, VPORT_ALLOC_OUT_VPORT_ID); + return (0); + +fail2: + EFSYS_PROBE(fail2); +fail1: + EFSYS_PROBE1(fail1, efx_rc_t, rc); + return (rc); +} + + __checkReturn efx_rc_t +efx_mcdi_vport_free( + __in efx_nic_t *enp, + __in efx_vport_id_t vport_id) +{ + EFX_MCDI_DECLARE_BUF(payload, MC_CMD_VPORT_FREE_IN_LEN, + MC_CMD_VPORT_FREE_OUT_LEN); + efx_mcdi_req_t req; + efx_rc_t rc; + + req.emr_cmd = MC_CMD_VPORT_FREE; + req.emr_in_buf = payload; + req.emr_in_length = MC_CMD_VPORT_FREE_IN_LEN; + req.emr_out_buf = payload; + req.emr_out_length = MC_CMD_VPORT_FREE_OUT_LEN; + + MCDI_IN_SET_DWORD(req, VPORT_FREE_IN_VPORT_ID, vport_id); + efx_mcdi_execute(enp, &req); + + if (req.emr_rc != 0) { + rc = req.emr_rc; + goto fail1; + } + + return (0); + +fail1: + EFSYS_PROBE1(fail1, efx_rc_t, rc); + return (rc); +} + + __checkReturn efx_rc_t +efx_mcdi_vport_mac_addr_add( + __in efx_nic_t *enp, + __in efx_vport_id_t vport_id, + __in_ecount(6) uint8_t *addrp) +{ + EFX_MCDI_DECLARE_BUF(payload, MC_CMD_VPORT_ADD_MAC_ADDRESS_IN_LEN, + MC_CMD_VPORT_ADD_MAC_ADDRESS_OUT_LEN); + efx_mcdi_req_t req; + efx_rc_t rc; + + req.emr_cmd = MC_CMD_VPORT_ADD_MAC_ADDRESS; + req.emr_in_buf = payload; + req.emr_in_length = MC_CMD_VPORT_ADD_MAC_ADDRESS_IN_LEN; + req.emr_out_buf = payload; + req.emr_out_length = MC_CMD_VPORT_ADD_MAC_ADDRESS_OUT_LEN; + + MCDI_IN_SET_DWORD(req, VPORT_ADD_MAC_ADDRESS_IN_VPORT_ID, vport_id); + EFX_MAC_ADDR_COPY(MCDI_IN2(req, uint8_t, + VPORT_ADD_MAC_ADDRESS_IN_MACADDR), addrp); + + efx_mcdi_execute(enp, &req); + + if (req.emr_rc != 0) { + rc = req.emr_rc; + goto fail1; + } + + return (0); + +fail1: + EFSYS_PROBE1(fail1, efx_rc_t, rc); + return (rc); +} + + __checkReturn efx_rc_t +efx_mcdi_vport_mac_addr_del( + __in efx_nic_t *enp, + __in efx_vport_id_t vport_id, + __in_ecount(6) uint8_t *addrp) +{ + EFX_MCDI_DECLARE_BUF(payload, MC_CMD_VPORT_DEL_MAC_ADDRESS_IN_LEN, + MC_CMD_VPORT_DEL_MAC_ADDRESS_OUT_LEN); + efx_mcdi_req_t req; + efx_rc_t rc; + + req.emr_cmd = MC_CMD_VPORT_DEL_MAC_ADDRESS; + req.emr_in_buf = payload; + req.emr_in_length = MC_CMD_VPORT_DEL_MAC_ADDRESS_IN_LEN; + req.emr_out_buf = payload; + req.emr_out_length = MC_CMD_VPORT_DEL_MAC_ADDRESS_OUT_LEN; + + MCDI_IN_SET_DWORD(req, VPORT_DEL_MAC_ADDRESS_IN_VPORT_ID, vport_id); + EFX_MAC_ADDR_COPY(MCDI_IN2(req, uint8_t, + VPORT_DEL_MAC_ADDRESS_IN_MACADDR), addrp); + + efx_mcdi_execute(enp, &req); + + if (req.emr_rc != 0) { + rc = req.emr_rc; + goto fail1; + } + + return (0); + +fail1: + EFSYS_PROBE1(fail1, efx_rc_t, rc); + return (rc); +} + + __checkReturn efx_rc_t +efx_mcdi_port_assign( + __in efx_nic_t *enp, + __in efx_vport_id_t vport_id, + __in uint32_t vf_index) +{ + EFX_MCDI_DECLARE_BUF(payload, MC_CMD_EVB_PORT_ASSIGN_IN_LEN, + MC_CMD_EVB_PORT_ASSIGN_OUT_LEN); + efx_mcdi_req_t req; + efx_nic_cfg_t *encp = &(enp->en_nic_cfg); + efx_rc_t rc; + + req.emr_cmd = MC_CMD_EVB_PORT_ASSIGN; + req.emr_in_buf = payload; + req.emr_in_length = MC_CMD_EVB_PORT_ASSIGN_IN_LEN; + req.emr_out_buf = payload; + req.emr_out_length = MC_CMD_EVB_PORT_ASSIGN_OUT_LEN; + + MCDI_IN_SET_DWORD(req, EVB_PORT_ASSIGN_IN_PORT_ID, vport_id); + MCDI_IN_POPULATE_DWORD_2(req, EVB_PORT_ASSIGN_IN_FUNCTION, + EVB_PORT_ASSIGN_IN_PF, encp->enc_pf, + EVB_PORT_ASSIGN_IN_VF, vf_index); + + efx_mcdi_execute(enp, &req); + + if (req.emr_rc != 0) { + rc = req.emr_rc; + goto fail1; + } + + return 0; + +fail1: + EFSYS_PROBE1(fail1, efx_rc_t, rc); + return (rc); +} + #endif /* EFSYS_OPT_HUNTINGTON || EFSYS_OPT_MEDFORD || EFSYS_OPT_MEDFORD2 */ #endif /* EFSYS_OPT_EVB */ diff --git a/drivers/net/sfc/base/efx.h b/drivers/net/sfc/base/efx.h index ca8a399..1287505 100644 --- a/drivers/net/sfc/base/efx.h +++ b/drivers/net/sfc/base/efx.h @@ -3349,6 +3349,24 @@ extern __checkReturn __success(return != B_FALSE) boolean_t #if EFSYS_OPT_EVB +typedef uint32_t efx_vport_id_t; + +typedef enum efx_vswitch_type_e { + EFX_VSWITCH_TYPE_VLAN = 1, + EFX_VSWITCH_TYPE_VEB, + /* VSWITCH_TYPE_VEPA: obsolete */ + EFX_VSWITCH_TYPE_MUX = 4, +} efx_vswitch_type_t; + +typedef enum efx_vport_type_e { + EFX_VPORT_TYPE_NORMAL = 4, + EFX_VPORT_TYPE_EXPANSION, + EFX_VPORT_TYPE_TEST, +} efx_vport_type_t; + +/* Unspecified VLAN ID to support disabling of VLAN filtering */ +#define EFX_FILTER_VID_UNSPEC 0xffff + extern __checkReturn efx_rc_t efx_evb_init( __in efx_nic_t *enp);