From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id 48091455D0; Wed, 10 Jul 2024 11:06:00 +0200 (CEST) Received: from mails.dpdk.org (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 2FC63427D9; Wed, 10 Jul 2024 11:06:00 +0200 (CEST) Received: from NAM10-DM6-obe.outbound.protection.outlook.com (mail-dm6nam10on2074.outbound.protection.outlook.com [40.107.93.74]) by mails.dpdk.org (Postfix) with ESMTP id D9F2E40647 for ; Wed, 10 Jul 2024 11:05:58 +0200 (CEST) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=HUE0Jz8myBhPmWwy3e7qdtoW3GYgOBxY0ZDti3jZT++YTAMg+L9iVutxzPDYc6xvs6sVuaT8sCuZQR8S/ZPDgoCV+WCxtEHgGiOK2CIIPwWdAhAzAKXiM9L685dfWRJyPFv2bDFw9uehPgoYT0zRwIR9kRdxmewbB9Ur95L7HH/VaiAroeWv1bQdtxkXCN49M6kb8U6LiGv5qFGJQv3sq4W3ux9ankVQPtslSCw+X1MxjQJWEzuGP7uojkVuLKabo6d+OMBd/dRHOoO+LFLMMikfQChyJNar2lgOqktC941lHH976g89f+sX5WB+H2y/UcZqyDjKASFZRVDAV5n2gg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=WSufytuDEjyxx5TWqOzG2udWJZ7ximdX1leYLrT2B54=; b=H/OlItCS076J44O0Q1znszt2AmslmJc7quaMs4dcqzEGiYPM6vnGmlLiP++8eh/dvXjqawnHKPBhMXxR/fqlfo39ljWxSa+lr2dd3kDwCU1gv35kXX9tNcC81m5fU5kVlasVMvPXEMin0SHwD2eC8WYRv3ygqTrGG6q8BINTAULfHWycjcBLwCKknZU0q9PZ44ZeMoi220r2dUE/xD0N/0vi/8tyPsL2vrImkvjPT7+GWCMH+ll8n3QM26AJe4Df+K02/5dLBcmFtuJZwJh7z8e+N/LFNMrcTl5AuqQ6gHmN9yGfZ/54CsLsKVtZt8Rv0L8tnVTeNZ8mWGpLJD/szw== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=amd.com; dmarc=pass action=none header.from=amd.com; dkim=pass header.d=amd.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=amd.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=WSufytuDEjyxx5TWqOzG2udWJZ7ximdX1leYLrT2B54=; b=aEjU8+Fian0epI8ZRx16ZkCeevhI8Sa//zbMIgtPbjR2/U9cpMcT/jeEPHS/99zz3UYHr5Za1IyP3FygELBV9NQ48qCgGccS37W2QU6PU+crMJlUrw7aO73Z6t2N0DrSifXDChORKvzGtnHWguQ+juwSFjfoec+aSFpK3ohjDy0= Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=amd.com; Received: from CH2PR12MB4294.namprd12.prod.outlook.com (2603:10b6:610:a9::11) by CH0PR12MB8530.namprd12.prod.outlook.com (2603:10b6:610:188::10) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.7741.35; Wed, 10 Jul 2024 09:05:54 +0000 Received: from CH2PR12MB4294.namprd12.prod.outlook.com ([fe80::ebfb:2f9f:f9ca:82cd]) by CH2PR12MB4294.namprd12.prod.outlook.com ([fe80::ebfb:2f9f:f9ca:82cd%4]) with mapi id 15.20.7762.016; Wed, 10 Jul 2024 09:05:53 +0000 Message-ID: <17127642-49bf-409f-98ff-0059720ec9ec@amd.com> Date: Wed, 10 Jul 2024 10:05:49 +0100 User-Agent: Mozilla Thunderbird Subject: Re: [PATCH v4] ethdev: Add link_speed lanes support To: Damodharam Ammepalli Cc: ajit.khaparde@broadcom.com, dev@dpdk.org, huangdengdui@huawei.com, kalesh-anakkur.purayil@broadcom.com References: <20240708232351.491529-1-damodharam.ammepalli@broadcom.com> <3577879f-4652-4633-8ea8-badd36aaeb8a@amd.com> Content-Language: en-US From: Ferruh Yigit Autocrypt: addr=ferruh.yigit@amd.com; keydata= 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 8Zk= In-Reply-To: Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-ClientProxiedBy: LO4P265CA0023.GBRP265.PROD.OUTLOOK.COM (2603:10a6:600:2ae::13) To CH2PR12MB4294.namprd12.prod.outlook.com (2603:10b6:610:a9::11) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: CH2PR12MB4294:EE_|CH0PR12MB8530:EE_ X-MS-Office365-Filtering-Correlation-Id: 0a5fc6d7-60e9-4f93-cc57-08dca0bf8091 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0;ARA:13230040|1800799024|376014|366016; X-Microsoft-Antispam-Message-Info: =?utf-8?B?bkdyb0RLOC9rZ1VYQjlFbm5XMTRDeThFUnhGRHpJbVZoaERSdnZPamljblNs?= =?utf-8?B?VXJhTTNGOHhDOE50MSt1dkc3Qm9PblE3S0R4d3M5R21kRVV6bE14M3k1UWZM?= =?utf-8?B?U2NHZlVuNjFsYzBDRDdGSEc1aVBuRXNubTgwOGpjR3lwZUNxQ2dHWjdPVlIy?= =?utf-8?B?bXhMRTJCaFB0V0FEb25mNHBtM2Y3cHNnU0I1Vjg3UG4wMk1OOFBHMmRpSTds?= =?utf-8?B?c0h6cGNhQ3hMcHNwREZlNWN0Q2cwMmttaWYyNkRPNnZuWlFieUFMSklkaTRZ?= =?utf-8?B?RjhRYzdUajZON0VhMFFGSzFzRXVhQXRYNDJHdXlpTUE3R3JxS1A0eXlXd1or?= =?utf-8?B?djZlTnFjR2o3WDZjeUttdEFUSlJ2VWtsUVFMM0duekRhL3ZjMmQ3bTVRbmd5?= =?utf-8?B?MXlETDFxbkt5Q3QwQ2Y0YXI2OU54MHV0N09LTGxUZVdPQURFa2pGMHRDWFFZ?= =?utf-8?B?RlphTytJVWs1WjFtK0h2cWdPYkFDVHUzOERuUXRiYUppbFVmTDltM2NQeTVy?= =?utf-8?B?ZXF2SmR4bW82eFdINnJKeC9oT2dLSjV5YUpNN1lEY2pCeU9YZlMyRXN2SGI5?= =?utf-8?B?QTZUdEo0azcxeHQ1dzRZY0FHNTR3bFgrc2NGVVpwdXNrWG0xWG85YVlkcWNj?= =?utf-8?B?ZkxUNlpIanozMEJWbUJPck9uVFhMS29zcjFGQ3dDN3lldHhlVXU2QW04NTh3?= =?utf-8?B?L0w4M2tRcUxDWG1za0NQODArNTR6OE50aFAvUHVkMWhkVmF5WUxNbnR4ajVV?= =?utf-8?B?dFMwZ3JKYlQyVC9paWN1bTJuN0d4YU5MWVJhQUR0VmRHYlJ4MVBCTlg4UXV4?= =?utf-8?B?QXk2djR3SytDRTRUMHhWVzRoRUhPMEhyZ3BMQXp3cTNsVnN3S29RY3VVejg0?= =?utf-8?B?eGtVNkltMzd3YVVpVmFpRTVFY0RqSmNNQ3ZsM1VoRHNnTkFIVkZBN2J6YkNu?= =?utf-8?B?ZnNVTWN6UkZKa3RreUdMTUprQmgvSjRjUjM3VjdIc25UR0RmcXVQY0Y2bVZz?= =?utf-8?B?cHdlZytuRmZQSzhoUUpOL05RMXhqdXI1RHNWRmw4S2dhUncyY2ZWQUwxSDJG?= =?utf-8?B?OXBMMldpNlJqRFl2Y1l2eEZ6dS9kNkRmUkUvb1VyNG1JdDVFK1JnUmVZOW90?= =?utf-8?B?cXc1bnRQalhhWHMrQURVSmpzMjluN0F4SitXUG9YNW9jTlVITWcwTzdpZVV3?= =?utf-8?B?eVVlcmJFR2QxTHNSNEY3aHdnL1RMcmtWYVhpWGk2cVVDRTNYRE0vY0xwZ3k5?= =?utf-8?B?cnR4SDFxZHVYYkFRSmxsM3lXMXZra3BRYUtrSEFHNFpTckVlcHkzRVF5VlRi?= =?utf-8?B?MVVQYnExd2ZPbkJSVTBwY3ZndWdGbXpLZzhnc2Q4d3J2WGRMd3lZRGt6ZXRq?= =?utf-8?B?N2VYTnp2dmUwNUhLT29FKzR1NTdsRkxNa3lNaDdOUlE4SFdPTXBscnhhU0Er?= =?utf-8?B?dVpZRFcra3RlZGxnWk9nM0E0TFVBSU50QkhWT1NaWVdiRWZVemZOSzFuTS9l?= =?utf-8?B?UldtWEFncDR1dVhRejZiUXBRS0VnOUpGaEZwSGJLd0JiR25Db1BUS0VET1Bs?= =?utf-8?B?dmJ2dDAzcHBrYm5tU3Y2OHk5V0RUU3JhV0VVcEZrWkhBc290ZzlkWjV4SU9J?= =?utf-8?B?OVViTEUzbWZmSWRzZk91aGdKTW1lMngyUjZWc1hSYmxEMTA4OWJYN2ZCZnZu?= =?utf-8?B?T0VoRktTMGlqL1dwTW81L291R1VyOUR5K3RhelhOdG1WcVFPa0srNFpRTm5r?= =?utf-8?B?eUR4cU5MUXBQVG9EUHR0Y1VNUkFIOTh2OGlWT013RDVvdGlNRnR0WHBmV1Rr?= =?utf-8?B?UzIwMWtnbmd6TDdPa2lyQT09?= X-Forefront-Antispam-Report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:CH2PR12MB4294.namprd12.prod.outlook.com; PTR:; CAT:NONE; SFS:(13230040)(1800799024)(376014)(366016); DIR:OUT; SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: =?utf-8?B?VDJhbFYwL1I1OXdTdURnZjZvZUh0UEx1Y0p5NzRZby9rNTg4TlI3UlZsSHBG?= =?utf-8?B?YzJ1MkM4OFJuMzlTWkx1SlUrUHdsRUR4My8yUTAzN1lSUlFTM3pjMnlQNnlQ?= =?utf-8?B?WTd2cW1BdU1rWVFRdVdNK2twVFNpcGFKampNNldyR3kyVGl0cWNnaTBjQnYy?= =?utf-8?B?dWl2dnZ1bXR5M3NFQnZucXVPTVVkZmgzbVVMRUFGQU92MnR0STN4cTVkeTdz?= =?utf-8?B?cmpKcmhva2U0YlgwcVZ0SXhlUnhFZ3BvN0JIejFBOCtvSnptL0pHbHlKeGYx?= =?utf-8?B?VHg0Z2ZOb2toUkduTlljMk9wR2o4US8zRGFkeUtrdDhUalc0MUlRMll4RERD?= =?utf-8?B?dHRLc1JkR1l6dGRVdHdCbFo5b1lmdk5vK1IxditTczVmNFR4ZGdQcWd4M3o4?= =?utf-8?B?WDZLSFNTNEVWTU1rdXROeVhtdEtvYy9OMVkwUlFLTjVmYm5LcjBHRFFkSXVW?= =?utf-8?B?OGJrcGs4Yi9vdVRjK3RNUTB4MXcwN0E1cWhWaFpDNi80Z0NvOEZxTTBSR0Fm?= =?utf-8?B?NXdZeUN2RVZzeW03ZFR4Umd0OEZvaERwL2Z4TXVycWJRUlJkSDliOTd0NkNr?= =?utf-8?B?aVhRZllRUGlvMjBDYWtSOTY2NVJCUUtGU2lRK1IvMVhEUXk2dWo1QnFxcXV4?= =?utf-8?B?ZHNYR2djSktqYkc5N01EajBGaDlMbWxLNjRQYk5WTGt3UEwxWDExZzJ1cUpU?= =?utf-8?B?aUtFeXByQUhIUVc0cXdvei8vV0Jwb1ZmZHZYdXNNNUxOeWdyNlp0YVU2ckps?= =?utf-8?B?ZUkwemNZNk9kRlBmbzgwdzRkYzdTZFZROE50Z215aDAzZnpVYTduSWlzMmcx?= =?utf-8?B?cG9tY2ZzSkFNcDk4c3RaY05ndUI1aGZLRllFTnZRU0tGTlhZUjRlai9MMVpH?= =?utf-8?B?K2JmRmlRN1l6NWNnOFQvZEVZanZsYnZSenFMeDZyeDVtLzJWNGxIdDNTZk1S?= =?utf-8?B?cklzWm5jZmdVWnIzR0JWdW0xYVB5WEg2TVlET2VPM3VweFNhbm9tWlhtM3U2?= =?utf-8?B?ZU5URDE0bW5DVWdVMm1IUXBIbE8yd202U1F5Z3BHRXBHQWdXK1Z3L3BJbWhy?= =?utf-8?B?Y3B4d2wwM21iTjM3VnJqSFBhRDZjTVMzcDdWS3AwRmFadGd0eHlCZkU3Njgx?= =?utf-8?B?Sy9NUTdxd09jSXlkdDBWZWhPMEpVajYwU2VqL2lwaHJtWG1JUDFjM1dMQ0Fz?= =?utf-8?B?dG5qNlBGN25rLzhPRENlcUVXVE1RZkxmTUladW1NL204YkF6ajZWSVg3d1NQ?= =?utf-8?B?dXplY2FsNWl2R253alpsSi9hQ0NmMmY5NjRGMGNFcldHSEZKQjdlL004bS93?= =?utf-8?B?dlRVVGsrOGMzM0RHY3g1eExtcElFcTJZSmdmZW9OV1NKc2dqd2xnV09ROVBU?= =?utf-8?B?bmJKYUMvVzFheGNZalpOclZUeGFrNVJUaE1mTlBJbElneThKUm1BcDVBV3Vs?= =?utf-8?B?STJ3K0N6VDAzdzBMZzI3SU5LTkFkODRNbnk0OEo1M3BDVDBhcUg2djRrb0ZT?= =?utf-8?B?VUoyRGhOOVgrYTRYcTRVNkl2cjI2aGE2SXFjczcyeFMvS1pxbWVlQjE5SVRU?= =?utf-8?B?dW9remtua2V2Y3Z5dTBRSEExaE5tb1cwanNLL1ZBSjR0SDdzaDFML1Fjbzk5?= =?utf-8?B?RFNRaFdWNXRPa09yY3VwWjErQWlQM3oyMW1tMCtPbENvNE8zMmtTejIzWjFJ?= =?utf-8?B?RElPdW5xeU5EU3I4ZURFeUdxM21DcVd2aXhsa3FDbERUY3VzRzhCem5RSTly?= =?utf-8?B?U05YbUlLOElOYXJ0MXBSamtnUndGbXp6dm9TWkthZkFianRMcVllKzBYWXpE?= =?utf-8?B?c1RSKzhWSWRGeDhocFpKeStJbFBCL0lJQlk3c1RDbk9ndzhWcDVYd3NWeU41?= =?utf-8?B?dnNTd0dLS01pVElPS0E4S2trdW9xQXpwZUZxK3pVYlRmYU91dVJEVjZHTHM5?= =?utf-8?B?MU9kem13Z3JIWHgwT0Q1bGpMdGdUVFphWE5ReWx1RHl6Ri9KU01RR3YxVnll?= =?utf-8?B?SCtkbkY1MEw3ZGlNUk0wQzBma016aDN2Y2ZoOFdIb3BtaDJUdU93dXR6UFph?= =?utf-8?B?NGR5RXdrM2pFakh5T0p6bUJOV0p0di8wNU9yTXVFSUF1K2pyTWFZOHdqSzc1?= =?utf-8?Q?8fwBuRs8hhgq0hsP9MnW4+WhI?= X-OriginatorOrg: amd.com X-MS-Exchange-CrossTenant-Network-Message-Id: 0a5fc6d7-60e9-4f93-cc57-08dca0bf8091 X-MS-Exchange-CrossTenant-AuthSource: CH2PR12MB4294.namprd12.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 10 Jul 2024 09:05:53.8561 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 3dd8961f-e488-4e60-8e11-a82d994e183d X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: Tiqlu87gjb2mEHbcMUC8RirJUJCeGavdMHSLGoDB97Ep5/pDDOwbp7s0OdkAK7Bw X-MS-Exchange-Transport-CrossTenantHeadersStamped: CH0PR12MB8530 X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org On 7/9/2024 10:20 PM, Damodharam Ammepalli wrote: > On Tue, Jul 9, 2024 at 4:10 AM Ferruh Yigit wrote: >> >> On 7/9/2024 12:22 AM, Damodharam Ammepalli wrote: >>> Update the eth_dev_ops structure with new function vectors >>> to get, get capabilities and set ethernet link speed lanes. >>> Update the testpmd to provide required config and information >>> display infrastructure. >>> >>> The supporting ethernet controller driver will register callbacks >>> to avail link speed lanes config and get services. This lanes >>> configuration is applicable only when the nic is forced to fixed >>> speeds. In Autonegiation mode, the hardware automatically >>> negotiates the number of lanes. >>> >>> These are the new commands. >>> >>> testpmd> show port 0 speed_lanes capabilities >>> >>> Supported speeds Valid lanes >>> ----------------------------------- >>> 10 Gbps 1 >>> 25 Gbps 1 >>> 40 Gbps 4 >>> 50 Gbps 1 2 >>> 100 Gbps 1 2 4 >>> 200 Gbps 2 4 >>> 400 Gbps 4 8 >>> testpmd> >>> >>> testpmd> >>> testpmd> port stop 0 >>> testpmd> port config 0 speed_lanes 4 >>> testpmd> port config 0 speed 200000 duplex full >>> >> >> Is there a requirement to set speed before speed_lane? >> Because I expect driver will verify if a speed_lane value is valid or >> not for a specific speed value. In above usage, driver will verify based >> on existing speed, whatever it is, later chaning speed may cause invalid >> speed_lane configuration. >> >> > There is no requirement to set speed before speed_lane. > If the controller supports lanes configuration capability, if no lanes > are given (which is 0) > the driver will pick up the lowest speed (eg: 200 gbps with NRZ mode), > if a fixed speed > already exists or is configured in tandem with speed_lanes. If speed > is already Auto, > test-pmd's speed_lane config is ignored. > We don't see your driver code yet, so it is hard to know the intention, but for your case will it work if first speed is set, later lane is set? (Btw, in the context of lanes, I am always assuming it is fixed speed configuration.) Assume that default speed is 10G, when speed_lane is set first, is it expected that driver verify the lane for that speed? If so, perhaps that specific lane config is not valid for the default speed and fails to set, do you think is this a valid case? Overall, the issue I am trying to clarify is the reason why Dengdui went with having different desing to couple speed and lanes. We said we will go with this separated design, but lets clarify relation/order in user perspective, since this is something that impacts driver implementation. And not clarifying this enough for sure will cause confusion and inconsistency in different driver implemntations. >>> testpmd> port start 0 >>> testpmd> >>> testpmd> show port info 0 >>> >>> ********************* Infos for port 0 ********************* >>> MAC address: 14:23:F2:C3:BA:D2 >>> Device name: 0000:b1:00.0 >>> Driver name: net_bnxt >>> Firmware-version: 228.9.115.0 >>> Connect to socket: 2 >>> memory allocation on the socket: 2 >>> Link status: up >>> Link speed: 200 Gbps >>> Active Lanes: 4 >>> Link duplex: full-duplex >>> Autoneg status: Off >>> >>> Signed-off-by: Damodharam Ammepalli >>> --- >>> v2->v3 Consolidating the testpmd and rtelib patches into a single patch >>> as requested. >>> v3->v4 Addressed comments and fix help string and documentation. >>> >>> app/test-pmd/cmdline.c | 230 +++++++++++++++++++++++++++++++++++++ >>> app/test-pmd/config.c | 69 ++++++++++- >>> app/test-pmd/testpmd.h | 4 + >>> lib/ethdev/ethdev_driver.h | 77 +++++++++++++ >>> lib/ethdev/rte_ethdev.c | 51 ++++++++ >>> lib/ethdev/rte_ethdev.h | 92 +++++++++++++++ >>> lib/ethdev/version.map | 5 + >>> 7 files changed, 526 insertions(+), 2 deletions(-) >>> >>> diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c >>> index b7759e38a8..a507df31d8 100644 >>> --- a/app/test-pmd/cmdline.c >>> +++ b/app/test-pmd/cmdline.c >>> @@ -284,6 +284,9 @@ static void cmd_help_long_parsed(void *parsed_result, >>> >>> "dump_log_types\n" >>> " Dumps the log level for all the dpdk modules\n\n" >>> + >>> + "show port (port_id) speed_lanes capabilities" >>> + " Show speed lanes capabilities of a port.\n\n" >>> ); >>> } >>> >>> @@ -823,6 +826,9 @@ static void cmd_help_long_parsed(void *parsed_result, >>> "port config (port_id) txq (queue_id) affinity (value)\n" >>> " Map a Tx queue with an aggregated port " >>> "of the DPDK port\n\n" >>> + >>> + "port config (port_id|all) speed_lanes (0|1|4|8)\n" >>> + " Set number of lanes for all ports or port_id for a forced speed\n\n" >>> ); >>> } >>> >>> @@ -1560,6 +1566,110 @@ static cmdline_parse_inst_t cmd_config_speed_specific = { >>> }, >>> }; >>> >>> +static int >>> +parse_speed_lanes_cfg(portid_t pid, uint32_t lanes) >>> +{ >>> + int ret; >>> + uint32_t lanes_capa; >>> + >>> + ret = parse_speed_lanes(lanes, &lanes_capa); >>> + if (ret < 0) { >>> + fprintf(stderr, "Unknown speed lane value: %d for port %d\n", lanes, pid); >>> + return -1; >>> + } >>> + >>> + ret = rte_eth_speed_lanes_set(pid, lanes_capa); >>> + if (ret == -ENOTSUP) { >>> + fprintf(stderr, "Function not implemented\n"); >>> + return -1; >>> + } else if (ret < 0) { >>> + fprintf(stderr, "Set speed lanes failed\n"); >>> + return -1; >>> + } >>> + >>> + return 0; >>> +} >>> + >>> +/* *** display speed lanes per port capabilities *** */ >>> +struct cmd_show_speed_lanes_result { >>> + cmdline_fixed_string_t cmd_show; >>> + cmdline_fixed_string_t cmd_port; >>> + cmdline_fixed_string_t cmd_keyword; >>> + portid_t cmd_pid; >>> +}; >>> + >>> +static void >>> +cmd_show_speed_lanes_parsed(void *parsed_result, >>> + __rte_unused struct cmdline *cl, >>> + __rte_unused void *data) >>> +{ >>> + struct cmd_show_speed_lanes_result *res = parsed_result; >>> + struct rte_eth_speed_lanes_capa *speed_lanes_capa; >>> + unsigned int num; >>> + int ret; >>> + >>> + if (!rte_eth_dev_is_valid_port(res->cmd_pid)) { >>> + fprintf(stderr, "Invalid port id %u\n", res->cmd_pid); >>> + return; >>> + } >>> + >>> + ret = rte_eth_speed_lanes_get_capability(res->cmd_pid, NULL, 0); >>> + if (ret == -ENOTSUP) { >>> + fprintf(stderr, "Function not implemented\n"); >>> + return; >>> + } else if (ret < 0) { >>> + fprintf(stderr, "Get speed lanes capability failed: %d\n", ret); >>> + return; >>> + } >>> + >>> + num = (unsigned int)ret; >>> + speed_lanes_capa = calloc(num, sizeof(*speed_lanes_capa)); >>> + if (speed_lanes_capa == NULL) { >>> + fprintf(stderr, "Failed to alloc speed lanes capability buffer\n"); >>> + return; >>> + } >>> + >>> + ret = rte_eth_speed_lanes_get_capability(res->cmd_pid, speed_lanes_capa, num); >>> + if (ret < 0) { >>> + fprintf(stderr, "Error getting speed lanes capability: %d\n", ret); >>> + goto out; >>> + } >>> + >>> + show_speed_lanes_capability(num, speed_lanes_capa); >>> +out: >>> + free(speed_lanes_capa); >>> +} >>> + >>> +static cmdline_parse_token_string_t cmd_show_speed_lanes_show = >>> + TOKEN_STRING_INITIALIZER(struct cmd_show_speed_lanes_result, >>> + cmd_show, "show"); >>> +static cmdline_parse_token_string_t cmd_show_speed_lanes_port = >>> + TOKEN_STRING_INITIALIZER(struct cmd_show_speed_lanes_result, >>> + cmd_port, "port"); >>> +static cmdline_parse_token_num_t cmd_show_speed_lanes_pid = >>> + TOKEN_NUM_INITIALIZER(struct cmd_show_speed_lanes_result, >>> + cmd_pid, RTE_UINT16); >>> +static cmdline_parse_token_string_t cmd_show_speed_lanes_keyword = >>> + TOKEN_STRING_INITIALIZER(struct cmd_show_speed_lanes_result, >>> + cmd_keyword, "speed_lanes"); >>> +static cmdline_parse_token_string_t cmd_show_speed_lanes_cap_keyword = >>> + TOKEN_STRING_INITIALIZER(struct cmd_show_speed_lanes_result, >>> + cmd_keyword, "capabilities"); >>> + >>> +static cmdline_parse_inst_t cmd_show_speed_lanes = { >>> + .f = cmd_show_speed_lanes_parsed, >>> + .data = NULL, >>> + .help_str = "show port speed_lanes capabilities", >>> + .tokens = { >>> + (void *)&cmd_show_speed_lanes_show, >>> + (void *)&cmd_show_speed_lanes_port, >>> + (void *)&cmd_show_speed_lanes_pid, >>> + (void *)&cmd_show_speed_lanes_keyword, >>> + (void *)&cmd_show_speed_lanes_cap_keyword, >>> + NULL, >>> + }, >>> +}; >>> + >>> /* *** configure loopback for all ports *** */ >>> struct cmd_config_loopback_all { >>> cmdline_fixed_string_t port; >>> @@ -1676,6 +1786,123 @@ static cmdline_parse_inst_t cmd_config_loopback_specific = { >>> }, >>> }; >>> >>> +/* *** configure speed_lanes for all ports *** */ >>> +struct cmd_config_speed_lanes_all { >>> + cmdline_fixed_string_t port; >>> + cmdline_fixed_string_t keyword; >>> + cmdline_fixed_string_t all; >>> + cmdline_fixed_string_t item; >>> + uint32_t lanes; >>> +}; >>> + >>> +static void >>> +cmd_config_speed_lanes_all_parsed(void *parsed_result, >>> + __rte_unused struct cmdline *cl, >>> + __rte_unused void *data) >>> +{ >>> + struct cmd_config_speed_lanes_all *res = parsed_result; >>> + portid_t pid; >>> + >>> + if (!all_ports_stopped()) { >>> + fprintf(stderr, "Please stop all ports first\n"); >>> + return; >>> + } >>> + >>> + RTE_ETH_FOREACH_DEV(pid) { >>> + if (parse_speed_lanes_cfg(pid, res->lanes)) >>> + return; >>> + } >>> + >>> + cmd_reconfig_device_queue(RTE_PORT_ALL, 1, 1); >>> +} >>> + >>> +static cmdline_parse_token_string_t cmd_config_speed_lanes_all_port = >>> + TOKEN_STRING_INITIALIZER(struct cmd_config_speed_lanes_all, port, "port"); >>> +static cmdline_parse_token_string_t cmd_config_speed_lanes_all_keyword = >>> + TOKEN_STRING_INITIALIZER(struct cmd_config_speed_lanes_all, keyword, >>> + "config"); >>> +static cmdline_parse_token_string_t cmd_config_speed_lanes_all_all = >>> + TOKEN_STRING_INITIALIZER(struct cmd_config_speed_lanes_all, all, "all"); >>> +static cmdline_parse_token_string_t cmd_config_speed_lanes_all_item = >>> + TOKEN_STRING_INITIALIZER(struct cmd_config_speed_lanes_all, item, >>> + "speed_lanes"); >>> +static cmdline_parse_token_num_t cmd_config_speed_lanes_all_lanes = >>> + TOKEN_NUM_INITIALIZER(struct cmd_config_speed_lanes_all, lanes, RTE_UINT32); >>> + >>> +static cmdline_parse_inst_t cmd_config_speed_lanes_all = { >>> + .f = cmd_config_speed_lanes_all_parsed, >>> + .data = NULL, >>> + .help_str = "port config all speed_lanes ", >>> + .tokens = { >>> + (void *)&cmd_config_speed_lanes_all_port, >>> + (void *)&cmd_config_speed_lanes_all_keyword, >>> + (void *)&cmd_config_speed_lanes_all_all, >>> + (void *)&cmd_config_speed_lanes_all_item, >>> + (void *)&cmd_config_speed_lanes_all_lanes, >>> + NULL, >>> + }, >>> +}; >>> + >>> +/* *** configure speed_lanes for specific port *** */ >>> +struct cmd_config_speed_lanes_specific { >>> + cmdline_fixed_string_t port; >>> + cmdline_fixed_string_t keyword; >>> + uint16_t port_id; >>> + cmdline_fixed_string_t item; >>> + uint32_t lanes; >>> +}; >>> + >>> +static void >>> +cmd_config_speed_lanes_specific_parsed(void *parsed_result, >>> + __rte_unused struct cmdline *cl, >>> + __rte_unused void *data) >>> +{ >>> + struct cmd_config_speed_lanes_specific *res = parsed_result; >>> + >>> + if (port_id_is_invalid(res->port_id, ENABLED_WARN)) >>> + return; >>> + >>> + if (!port_is_stopped(res->port_id)) { >>> + fprintf(stderr, "Please stop port %u first\n", res->port_id); >>> + return; >>> + } >>> >> >> There is a requirement here, that port needs to be stopped before >> calling the rte_eth_speed_lanes_set(), >> is this requirement documented in the API documentation? >> >> > Speed link mode needs a phy reset, hence port stop is a requirement. > I will update this in the documentation in the next patch. > That is OK to have the stop requirement, only it needs to be clear. And addition to document this in the API documentation, what do you think to add this check in the API, so it guarantees in coding level that this requirement is satified. So this check in application level can be dropped. >>> + >>> + if (parse_speed_lanes_cfg(res->port_id, res->lanes)) >>> + return; >>> + >>> + cmd_reconfig_device_queue(res->port_id, 1, 1); >>> +} >>> + >>> +static cmdline_parse_token_string_t cmd_config_speed_lanes_specific_port = >>> + TOKEN_STRING_INITIALIZER(struct cmd_config_speed_lanes_specific, port, >>> + "port"); >>> +static cmdline_parse_token_string_t cmd_config_speed_lanes_specific_keyword = >>> + TOKEN_STRING_INITIALIZER(struct cmd_config_speed_lanes_specific, keyword, >>> + "config"); >>> +static cmdline_parse_token_num_t cmd_config_speed_lanes_specific_id = >>> + TOKEN_NUM_INITIALIZER(struct cmd_config_speed_lanes_specific, port_id, >>> + RTE_UINT16); >>> +static cmdline_parse_token_string_t cmd_config_speed_lanes_specific_item = >>> + TOKEN_STRING_INITIALIZER(struct cmd_config_speed_lanes_specific, item, >>> + "speed_lanes"); >>> +static cmdline_parse_token_num_t cmd_config_speed_lanes_specific_lanes = >>> + TOKEN_NUM_INITIALIZER(struct cmd_config_speed_lanes_specific, lanes, >>> + RTE_UINT32); >>> + >>> +static cmdline_parse_inst_t cmd_config_speed_lanes_specific = { >>> + .f = cmd_config_speed_lanes_specific_parsed, >>> + .data = NULL, >>> + .help_str = "port config speed_lanes ", >>> + .tokens = { >>> + (void *)&cmd_config_speed_lanes_specific_port, >>> + (void *)&cmd_config_speed_lanes_specific_keyword, >>> + (void *)&cmd_config_speed_lanes_specific_id, >>> + (void *)&cmd_config_speed_lanes_specific_item, >>> + (void *)&cmd_config_speed_lanes_specific_lanes, >>> + NULL, >>> + }, >>> +}; >>> + >>> /* *** configure txq/rxq, txd/rxd *** */ >>> struct cmd_config_rx_tx { >>> cmdline_fixed_string_t port; >>> @@ -13238,6 +13465,9 @@ static cmdline_parse_ctx_t builtin_ctx[] = { >>> (cmdline_parse_inst_t *)&cmd_set_port_setup_on, >>> (cmdline_parse_inst_t *)&cmd_config_speed_all, >>> (cmdline_parse_inst_t *)&cmd_config_speed_specific, >>> + (cmdline_parse_inst_t *)&cmd_config_speed_lanes_all, >>> + (cmdline_parse_inst_t *)&cmd_config_speed_lanes_specific, >>> + (cmdline_parse_inst_t *)&cmd_show_speed_lanes, >>> (cmdline_parse_inst_t *)&cmd_config_loopback_all, >>> (cmdline_parse_inst_t *)&cmd_config_loopback_specific, >>> (cmdline_parse_inst_t *)&cmd_config_rx_tx, >>> diff --git a/app/test-pmd/config.c b/app/test-pmd/config.c >>> index 66c3a68c1d..498a7db467 100644 >>> --- a/app/test-pmd/config.c >>> +++ b/app/test-pmd/config.c >>> @@ -207,6 +207,32 @@ static const struct { >>> {"gtpu", RTE_ETH_FLOW_GTPU}, >>> }; >>> >>> +static const struct { >>> + enum rte_eth_speed_lanes lane; >>> + const uint32_t value; >>> +} speed_lane_name[] = { >>> + { >>> + .lane = RTE_ETH_SPEED_LANE_UNKNOWN, >>> + .value = 0, >>> + }, >>> + { >>> + .lane = RTE_ETH_SPEED_LANE_1, >>> + .value = 1, >>> + }, >>> + { >>> + .lane = RTE_ETH_SPEED_LANE_2, >>> + .value = 2, >>> + }, >>> + { >>> + .lane = RTE_ETH_SPEED_LANE_4, >>> + .value = 4, >>> + }, >>> + { >>> + .lane = RTE_ETH_SPEED_LANE_8, >>> + .value = 8, >>> + }, >>> +}; >>> + >>> static void >>> print_ethaddr(const char *name, struct rte_ether_addr *eth_addr) >>> { >>> @@ -786,6 +812,7 @@ port_infos_display(portid_t port_id) >>> char name[RTE_ETH_NAME_MAX_LEN]; >>> int ret; >>> char fw_version[ETHDEV_FWVERS_LEN]; >>> + uint32_t lanes; >>> >>> if (port_id_is_invalid(port_id, ENABLED_WARN)) { >>> print_valid_ports(); >>> @@ -828,6 +855,12 @@ port_infos_display(portid_t port_id) >>> >>> printf("\nLink status: %s\n", (link.link_status) ? ("up") : ("down")); >>> printf("Link speed: %s\n", rte_eth_link_speed_to_str(link.link_speed)); >>> + if (rte_eth_speed_lanes_get(port_id, &lanes) == 0) { >>> + if (lanes > 0) >>> + printf("Active Lanes: %d\n", lanes); >>> + else >>> + printf("Active Lanes: %s\n", "Unknown"); >>> >> >> What can be the 'else' case? >> As 'lanes' is unsigned, only option is it being zero. Is API allowed to >> return zero as lane number? >> >> > Yes. link is down, but controller supports speed_lanes capability, > then we can show "unknown" > Other cases from brcm spec. > 1gb 1Gb link speed < no lane info > (theoretically it can't be zero, > but we need to show what controller provides in the query). > 10Gb (NRZ: 10G per lane, 1 lane) link speed > I don't understand how application proccess the information that 'rte_eth_speed_lanes_get()' returns success but lane is zero. For the link down case, doesn't it make sense to return error for the 'rte_eth_speed_lanes_get()' API? And for other cases, like 1G that doesn't support the lane configuration, does it make sense to return 1? And for these cases what is the capability value you are returning? >>> + } >>> printf("Link duplex: %s\n", (link.link_duplex == RTE_ETH_LINK_FULL_DUPLEX) ? >>> ("full-duplex") : ("half-duplex")); >>> printf("Autoneg status: %s\n", (link.link_autoneg == RTE_ETH_LINK_AUTONEG) ? >>> @@ -962,7 +995,7 @@ port_summary_header_display(void) >>> >>> port_number = rte_eth_dev_count_avail(); >>> printf("Number of available ports: %i\n", port_number); >>> - printf("%-4s %-17s %-12s %-14s %-8s %s\n", "Port", "MAC Address", "Name", >>> + printf("%-4s %-17s %-12s %-14s %-8s %-8s\n", "Port", "MAC Address", "Name", >>> "Driver", "Status", "Link"); >>> } >>> >>> @@ -993,7 +1026,7 @@ port_summary_display(portid_t port_id) >>> if (ret != 0) >>> return; >>> >>> - printf("%-4d " RTE_ETHER_ADDR_PRT_FMT " %-12s %-14s %-8s %s\n", >>> + printf("%-4d " RTE_ETHER_ADDR_PRT_FMT " %-12s %-14s %-8s %-8s\n", >>> >> >> Summary updates are irrelevant in the patch, can you please drop them. >> >> > Sure I will. > >>> port_id, RTE_ETHER_ADDR_BYTES(&mac_addr), name, >>> dev_info.driver_name, (link.link_status) ? ("up") : ("down"), >>> rte_eth_link_speed_to_str(link.link_speed)); >>> @@ -7244,3 +7277,35 @@ show_mcast_macs(portid_t port_id) >>> printf(" %s\n", buf); >>> } >>> } >>> + >>> +int >>> +parse_speed_lanes(uint32_t lane, uint32_t *speed_lane) >>> +{ >>> + uint8_t i; >>> + >>> + for (i = 0; i < RTE_DIM(speed_lane_name); i++) { >>> + if (speed_lane_name[i].value == lane) { >>> + *speed_lane = lane; >>> >> >> This converts from 8 -> 8, 4 -> 4 .... >> >> Why not completely eliminate this fucntion? See below. >> > Sure, will evaluate and do the needful. > >>> + return 0; >>> + } >>> + } >>> + return -1; >>> +} >>> + >>> +void >>> +show_speed_lanes_capability(unsigned int num, struct rte_eth_speed_lanes_capa *speed_lanes_capa) >>> +{ >>> + unsigned int i, j; >>> + >>> + printf("\n%-15s %-10s", "Supported-speeds", "Valid-lanes"); >>> + printf("\n-----------------------------------\n"); >>> + for (i = 0; i < num; i++) { >>> + printf("%-17s ", rte_eth_link_speed_to_str(speed_lanes_capa[i].speed)); >>> + >>> + for (j = 0; j < RTE_ETH_SPEED_LANE_MAX; j++) { >>> + if (RTE_ETH_SPEED_LANES_TO_CAPA(j) & speed_lanes_capa[i].capa) >>> + printf("%-2d ", speed_lane_name[j].value); >>> + } >> >> To eliminate both RTE_ETH_SPEED_LANE_MAX & speed_lane_name, what do you >> think about: >> >> capa = speed_lanes_capa[i].capa; >> int s = 0; >> while (capa) { >> if (capa & 0x1) >> printf("%-2d ", 1 << s); >> s++; >> capa = capa >> 1; >> } >> > Am new to the DPDK world. > Followed the FEC driver conventions for consistency. > Will update it as you suggested and it makes sense. > FEC values goes sequential, but lane values in power of two, we can benefit from this fact. (though if we have lane value not power of two later, this logic may need to change.) Btw, I can see some of the code copies existing FEC implementation, which makes sense, but it seems FEC code could be improved as well but we missed at that time. Instead of copying FEC exactly, lets try to improve whatever we can for first merge, otherwise less likely these things will be fixed later. Thanks, ferruh