From owner-svn-src-head@freebsd.org Fri Nov 30 07:10:40 2018 Return-Path: Delivered-To: svn-src-head@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 9A4F3115ADB6; Fri, 30 Nov 2018 07:10:40 +0000 (UTC) (envelope-from arybchik@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client CN "mxrelay.nyi.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 69C60724E5; Fri, 30 Nov 2018 07:10:33 +0000 (UTC) (envelope-from arybchik@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id BFD57252A2; Fri, 30 Nov 2018 07:10:32 +0000 (UTC) (envelope-from arybchik@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id wAU7AWvr084389; Fri, 30 Nov 2018 07:10:32 GMT (envelope-from arybchik@FreeBSD.org) Received: (from arybchik@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id wAU7AWnt084388; Fri, 30 Nov 2018 07:10:32 GMT (envelope-from arybchik@FreeBSD.org) Message-Id: <201811300710.wAU7AWnt084388@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: arybchik set sender to arybchik@FreeBSD.org using -f From: Andrew Rybchenko Date: Fri, 30 Nov 2018 07:10:32 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r341324 - head/sys/dev/sfxge/common X-SVN-Group: head X-SVN-Commit-Author: arybchik X-SVN-Commit-Paths: head/sys/dev/sfxge/common X-SVN-Commit-Revision: 341324 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-Rspamd-Queue-Id: 69C60724E5 X-Spamd-Result: default: False [0.62 / 15.00]; local_wl_from(0.00)[FreeBSD.org]; NEURAL_HAM_SHORT(-0.03)[-0.026,0]; NEURAL_SPAM_LONG(0.34)[0.335,0]; NEURAL_SPAM_MEDIUM(0.31)[0.312,0]; ASN(0.00)[asn:11403, ipnet:2610:1c1:1::/48, country:US] X-Rspamd-Server: mx1.freebsd.org X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 30 Nov 2018 07:10:41 -0000 Author: arybchik Date: Fri Nov 30 07:10:32 2018 New Revision: 341324 URL: https://svnweb.freebsd.org/changeset/base/341324 Log: sfxge(4): update external port number calculation Revise the external port calculation to support all X2 port modes. The previous algorithm could not handle different port numbering schemes on each cage. Submitted by: Richard Houldsworth Sponsored by: Solarflare Communications, Inc. Differential Revision: https://reviews.freebsd.org/D18285 Modified: head/sys/dev/sfxge/common/ef10_nic.c Modified: head/sys/dev/sfxge/common/ef10_nic.c ============================================================================== --- head/sys/dev/sfxge/common/ef10_nic.c Fri Nov 30 07:10:20 2018 (r341323) +++ head/sys/dev/sfxge/common/ef10_nic.c Fri Nov 30 07:10:32 2018 (r341324) @@ -1468,6 +1468,9 @@ fail1: } +#define EFX_EXT_PORT_MAX 4 +#define EFX_EXT_PORT_NA 0xFF + /* * Table of mapping schemes from port number to external number. * @@ -1481,7 +1484,7 @@ fail1: * port mapping (n:1) * | * v - * External port number (normally 1-based) + * External port number (1-based) * | * fixed (1:1) or cable assembly (1:m) * | @@ -1493,9 +1496,8 @@ fail1: * how to determine which external cage/magjack corresponds to the port * numbers used by the driver. * - * The count of adjacent port numbers that map to each external number, - * and the offset in the numbering, is determined by the chip family and - * current port mode. + * The count of consecutive port numbers that map to each external number, + * is determined by the chip family and the current port mode. * * For the Huntington family, the current port mode cannot be discovered, * but a single mapping is used by all modes for a given chip variant, @@ -1506,8 +1508,7 @@ fail1: static struct ef10_external_port_map_s { efx_family_t family; uint32_t modes_mask; - int32_t count; - int32_t offset; + uint8_t base_port[EFX_EXT_PORT_MAX]; } __ef10_external_port_mappings[] = { /* * Modes used by Huntington family controllers where each port @@ -1526,8 +1527,7 @@ static struct ef10_external_port_map_s { (1U << TLV_PORT_MODE_10G) | /* mode 0 */ (1U << TLV_PORT_MODE_10G_10G) | /* mode 2 */ (1U << TLV_PORT_MODE_10G_10G_10G_10G), /* mode 4 */ - 1, /* ports per cage */ - 1 /* first cage */ + { 0, 1, 2, 3 } }, /* * Modes which for Huntington identify a chip variant where 2 @@ -1544,8 +1544,7 @@ static struct ef10_external_port_map_s { (1U << TLV_PORT_MODE_40G_40G) | /* mode 3 */ (1U << TLV_PORT_MODE_40G_10G_10G) | /* mode 6 */ (1U << TLV_PORT_MODE_10G_10G_40G), /* mode 7 */ - 2, /* ports per cage */ - 1 /* first cage */ + { 0, 2, EFX_EXT_PORT_NA, EFX_EXT_PORT_NA } }, /* * Modes that on Medford allocate each port number to a separate @@ -1559,8 +1558,7 @@ static struct ef10_external_port_map_s { EFX_FAMILY_MEDFORD, (1U << TLV_PORT_MODE_1x1_NA) | /* mode 0 */ (1U << TLV_PORT_MODE_1x1_1x1), /* mode 2 */ - 1, /* ports per cage */ - 1 /* first cage */ + { 0, 1, 2, 3 } }, /* * Modes that on Medford allocate 2 adjacent port numbers to each @@ -1578,8 +1576,7 @@ static struct ef10_external_port_map_s { (1U << TLV_PORT_MODE_2x1_1x4) | /* mode 7 */ /* Do not use 10G_10G_10G_10G_Q1_Q2 (see bug63270) */ (1U << TLV_PORT_MODE_10G_10G_10G_10G_Q1_Q2), /* mode 9 */ - 2, /* ports per cage */ - 1 /* first cage */ + { 0, 2, EFX_EXT_PORT_NA, EFX_EXT_PORT_NA } }, /* * Modes that on Medford allocate 4 adjacent port numbers to each @@ -1594,8 +1591,7 @@ static struct ef10_external_port_map_s { (1U << TLV_PORT_MODE_2x1_2x1) | /* mode 5 */ /* Do not use 10G_10G_10G_10G_Q1 (see bug63270) */ (1U << TLV_PORT_MODE_4x1_NA), /* mode 4 */ - 4, /* ports per cage */ - 1 /* first cage */ + { 0, EFX_EXT_PORT_NA, EFX_EXT_PORT_NA, EFX_EXT_PORT_NA } }, /* * Modes that on Medford allocate 4 adjacent port numbers to each @@ -1608,8 +1604,7 @@ static struct ef10_external_port_map_s { { EFX_FAMILY_MEDFORD, (1U << TLV_PORT_MODE_NA_4x1), /* mode 8 */ - 4, /* ports per cage */ - 2 /* first cage */ + { EFX_EXT_PORT_NA, 0, EFX_EXT_PORT_NA, EFX_EXT_PORT_NA } }, /* * Modes that on Medford2 allocate each port number to a separate @@ -1628,16 +1623,21 @@ static struct ef10_external_port_map_s { (1U << TLV_PORT_MODE_1x2_1x2) | /* mode 12 */ (1U << TLV_PORT_MODE_1x4_1x2) | /* mode 15 */ (1U << TLV_PORT_MODE_1x2_1x4), /* mode 16 */ - 1, /* ports per cage */ - 1 /* first cage */ + { 0, 1, 2, 3 } }, /* - * FIXME: Some port modes are not representable in this mapping: - * - TLV_PORT_MODE_1x2_2x1 (mode 17): + * Modes that on Medford2 allocate 1 port to cage 1 and the rest + * to cage 2. * port 0 -> cage 1 * port 1 -> cage 2 * port 2 -> cage 2 */ + { + EFX_FAMILY_MEDFORD2, + (1U << TLV_PORT_MODE_1x2_2x1) | /* mode 17 */ + (1U << TLV_PORT_MODE_1x4_2x1), /* mode 6 */ + { 0, 1, EFX_EXT_PORT_NA, EFX_EXT_PORT_NA } + }, /* * Modes that on Medford2 allocate 2 adjacent port numbers to each * cage, starting on cage 1. @@ -1654,8 +1654,7 @@ static struct ef10_external_port_map_s { (1U << TLV_PORT_MODE_2x1_1x4) | /* mode 7 */ (1U << TLV_PORT_MODE_2x2_NA) | /* mode 13 */ (1U << TLV_PORT_MODE_2x1_1x2), /* mode 18 */ - 2, /* ports per cage */ - 1 /* first cage */ + { 0, 2, EFX_EXT_PORT_NA, EFX_EXT_PORT_NA } }, /* * Modes that on Medford2 allocate 2 adjacent port numbers to each @@ -1666,8 +1665,7 @@ static struct ef10_external_port_map_s { { EFX_FAMILY_MEDFORD2, (1U << TLV_PORT_MODE_NA_2x2), /* mode 14 */ - 2, /* ports per cage */ - 2 /* first cage */ + { EFX_EXT_PORT_NA, 0, EFX_EXT_PORT_NA, EFX_EXT_PORT_NA } }, /* * Modes that on Medford2 allocate 4 adjacent port numbers to each @@ -1680,8 +1678,7 @@ static struct ef10_external_port_map_s { { EFX_FAMILY_MEDFORD2, (1U << TLV_PORT_MODE_4x1_NA), /* mode 5 */ - 4, /* ports per cage */ - 1 /* first cage */ + { 0, EFX_EXT_PORT_NA, EFX_EXT_PORT_NA, EFX_EXT_PORT_NA } }, /* * Modes that on Medford2 allocate 4 adjacent port numbers to each @@ -1695,8 +1692,7 @@ static struct ef10_external_port_map_s { EFX_FAMILY_MEDFORD2, (1U << TLV_PORT_MODE_NA_4x1) | /* mode 8 */ (1U << TLV_PORT_MODE_NA_1x2), /* mode 11 */ - 4, /* ports per cage */ - 2 /* first cage */ + { EFX_EXT_PORT_NA, 0, EFX_EXT_PORT_NA, EFX_EXT_PORT_NA } }, }; @@ -1711,8 +1707,8 @@ ef10_external_port_mapping( uint32_t port_modes; uint32_t matches; uint32_t current; - int32_t count = 1; /* Default 1-1 mapping */ - int32_t offset = 1; /* Default starting external port number */ + struct ef10_external_port_map_s *mapp = NULL; + int ext_index = port; /* Default 1-1 mapping */ if ((rc = efx_mcdi_get_port_modes(enp, &port_modes, ¤t, NULL)) != 0) { @@ -1749,8 +1745,7 @@ ef10_external_port_mapping( * there will be multiple matches. The mapping on the * last match is used. */ - count = eepmp->count; - offset = eepmp->offset; + mapp = eepmp; port_modes &= ~matches; } } @@ -1762,11 +1757,25 @@ ef10_external_port_mapping( } out: - /* - * Scale as required by last matched mode and then convert to - * correctly offset numbering - */ - *external_portp = (uint8_t)((port / count) + offset); + if (mapp != NULL) { + /* + * External ports are assigned a sequence of consecutive + * port numbers, so find the one with the closest base_port. + */ + uint32_t delta = EFX_EXT_PORT_NA; + + for (i = 0; i < EFX_EXT_PORT_MAX; i++) { + uint32_t base = mapp->base_port[i]; + if ((base != EFX_EXT_PORT_NA) && (base <= port)) { + if ((port - base) < delta) { + delta = (port - base); + ext_index = i; + } + } + } + } + *external_portp = (uint8_t)(ext_index + 1); + return (0); fail1: