From patchwork Fri May 4 18:07:19 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Manlunas, Felix" X-Patchwork-Id: 908945 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming-netdev@ozlabs.org Delivered-To: patchwork-incoming-netdev@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=netdev-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=cavium.com Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=CAVIUMNETWORKS.onmicrosoft.com header.i=@CAVIUMNETWORKS.onmicrosoft.com header.b="QPY8x8+6"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 40d0NK27m9z9s3G for ; Sat, 5 May 2018 04:07:29 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751492AbeEDSH1 (ORCPT ); Fri, 4 May 2018 14:07:27 -0400 Received: from mail-by2nam01on0088.outbound.protection.outlook.com ([104.47.34.88]:2688 "EHLO NAM01-BY2-obe.outbound.protection.outlook.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1751346AbeEDSHZ (ORCPT ); Fri, 4 May 2018 14:07:25 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=CAVIUMNETWORKS.onmicrosoft.com; s=selector1-cavium-com; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version; bh=5dvjAr/HlggWe5NQXFhtro0wjfmAp557FNlHlHW5siI=; b=QPY8x8+65skf818pdns43aHOH9i7ZzqGTOjVsSkJVFnueSp1nRYO2PX1xmVWDNRsFmRbIZamqsuT2cE0OOZWbBVgA9zR6tZa2TuKWQmejB+gpalKMyPGe7OUAwq4n7yFFvPlyOHW0GEfDmuwTK/eGbn4c4h+kAE66e1MMoh/w/M= Received: from localhost (50.233.148.156) by DM6PR07MB4218.namprd07.prod.outlook.com (2603:10b6:5:bd::27) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384_P256) id 15.20.735.16; Fri, 4 May 2018 18:07:23 +0000 Date: Fri, 4 May 2018 11:07:19 -0700 From: Felix Manlunas To: davem@davemloft.net Cc: netdev@vger.kernel.org, raghu.vatsavayi@cavium.com, derek.chickles@cavium.com, satananda.burla@cavium.com, felix.manlunas@cavium.com, weilin.chang@cavium.com Subject: [PATCH V2 net-next] liquidio: support use of ethtool to set link speed of CN23XX-225 cards Message-ID: <20180504180719.GA2053@felix-thinkpad.cavium.com> MIME-Version: 1.0 Content-Disposition: inline User-Agent: Mutt/1.6.1 (2016-04-27) X-Originating-IP: [50.233.148.156] X-ClientProxiedBy: CO2PR06CA0065.namprd06.prod.outlook.com (2603:10b6:104:3::23) To DM6PR07MB4218.namprd07.prod.outlook.com (2603:10b6:5:bd::27) X-MS-PublicTrafficType: Email X-Microsoft-Antispam: UriScan:; BCL:0; PCL:0; RULEID:(7020095)(4652020)(4534165)(4627221)(201703031133081)(201702281549075)(5600026)(2017052603328)(7153060)(7193020); SRVR:DM6PR07MB4218; X-Microsoft-Exchange-Diagnostics: 1; DM6PR07MB4218; 3:cmR962BBk//bnOVipJMXFm2XXjDXKRD5Fvqzc/j0NQSadt+SzZDHgwJUEnsBf/599XSFY6Db8UlweetItNpXptuZmMI8oiA4DZFSpv2WSrzDTbW9q0k6HoK5Aon/JSxZqYeNaYLtMdNhgDG6obqiNLKePccTdiTvtYkLarTBIgwkenNrd57IN/XCdXbsTuEFiPHvr1/ANRIEi7w+SNX6pcNPdaU3Hyc8ji8DbRfS8zMY+RoaSkxwKM2/K65m+VD+; 25:26idO7z5gW3rqwS9R8Z2HqGQ5pTTuybsJTaCKWCqnDKX97gkVh5dOilKHxBP9m2ZJj35gxzje6Zj7u5cs+WS3S4JaKVz6NaPID+P/rwPBLcNFLklecq1bqvs7O9zf5Ddkx2htpaxWdjOkr+mlryNvWoY8jctWtVcklAn/DiYiZFBkUFVE5DEFIweJNjbXrbmsg5p6tEwhvweiVJjCtpcNtwfJMIDBOtfhXZrvdG8gMY/ru93yGeCBdfyvVDXRyVcDG56XatZigSoHyj2eySjyxyUCO+BZULYxmzIl//DxBP+/izi9EcipoNCjxJCOya36MC8gBh2sENTwnMpSo53ug==; 31:+r0QCzBlWONtX74f/CjTXzBr2PI5Cys6Zi0/AeHFBngTzFRtLDdCX3LgBf+cgDVchT9TBr+31oN7blEom2qhDQPOs5ufIXqzPZWXpbCuRmILvXOCmnQ1zyO+9fC3DpzBzEN1W5qBRIKs0G07hP1l7A51X71rsXZQJR3Ww3s9Clk7UgcjYCVMyLIGJGf16bphT9IJmaKmoM+qqEw7LCIdgNrvvPwm/fzVLfIRRhPGKWo= X-MS-TrafficTypeDiagnostic: DM6PR07MB4218: Authentication-Results: spf=none (sender IP is ) smtp.mailfrom=Felix.Manlunas@cavium.com; X-Microsoft-Exchange-Diagnostics: 1; DM6PR07MB4218; 20:SDN3IWJHxWpJ/6WqUQqOA+XsYb3TzBi/GUfH2gtsI6TCWt6WYekwUFIG7WU83a3Q3BSHg1SyHf2rj11qCz1iZZrQ5ab8Kmv8C1curgGJa9jGxJcJIvIWlEoZxaq7P0RZRPfLU2maWgVWA77pY7pY4atwmaVFGJGpnGOSP4yzpvh0Q3nSbXE2QZjY6t/YMkHGI2lOM1WDQUJ5fE6Nit/4AJltiSB+09tniWZkTOQTCCyAZkVb2ulpN8nurHThPnfPF9v+As/Nlr9BlMPjaQumVrbYqSRKKmmA/P7e8deVtAzBrGkhQnVWfNLT6QOxAJA/rWawu1buStbugPn3IPsqLzs5tA1NxT8RctpX4KaWtoDqpQAznfSjV2bPcHqdMOWKXoDhgBKsxqkHQXefqDbrOtOEE0kR78AEroAOCOK7D7BnuO1+mfciPFiaSJeZiJL7M/Kc4CjGiHygMXbl+FK1vWikP/dz2ZR5XBzwt6g/TvRFDNnq8ade+N3DO9RQFuVy; 4:CEcG0WKmbNR2gsbfOTdodGHTnj0LMWOV7kQIhEpfVode2g6nqWQAmBeNxjDjwz3ilTnAp9mJwC5xGFYSW1iYU3Qk37OQnDo85Ojcczk5d9ZpZxWDwtn1wm4CAJTnsYt+r/E9mYyR2cFe1cyvfqtsosD+xP4BuDFVcMzLZWDn3vIEbcINMWYJrvxTDPULLerM59YsWVhWTu6aLTXVzVSMnqHZixzOKDS07qMZIP+xo9/Oy/JfV2SfC+55znDJDqpjJs2YG1b4fbQx+t9uzkbp1w== X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:; X-Exchange-Antispam-Report-CFA-Test: BCL:0; PCL:0; RULEID:(8211001083)(6040522)(2401047)(8121501046)(5005006)(10201501046)(3231254)(944501410)(52105095)(3002001)(93006095)(93001095)(6041310)(20161123564045)(20161123558120)(20161123562045)(20161123560045)(201703131423095)(201702281528075)(20161123555045)(201703061421075)(201703061406153)(6072148)(201708071742011); SRVR:DM6PR07MB4218; BCL:0; PCL:0; RULEID:; SRVR:DM6PR07MB4218; X-Forefront-PRVS: 06628F7CA4 X-Forefront-Antispam-Report: SFV:NSPM; SFS:(10009020)(6069001)(39850400004)(39380400002)(346002)(376002)(366004)(396003)(54534003)(199004)(189003)(86362001)(186003)(6496006)(316002)(3846002)(50466002)(16586007)(53936002)(26005)(58126008)(59450400001)(47776003)(97736004)(386003)(23726003)(66066001)(2906002)(16526019)(6116002)(575784001)(52116002)(1076002)(5660300001)(8936002)(6486002)(76506005)(81166006)(33656002)(4326008)(81156014)(8676002)(476003)(956004)(25786009)(486006)(478600001)(107886003)(7736002)(2361001)(6916009)(72206003)(106356001)(6666003)(68736007)(305945005)(44832011)(2351001)(105586002)(18370500001); DIR:OUT; SFP:1101; SCL:1; SRVR:DM6PR07MB4218; H:localhost; FPR:; SPF:None; LANG:en; PTR:InfoNoRecords; A:1; MX:1; Received-SPF: None (protection.outlook.com: cavium.com does not designate permitted sender hosts) X-Microsoft-Exchange-Diagnostics: 1; DM6PR07MB4218; 23:UR/4SJCPm/gGTChvVOtlzvzgGUPlLvGWn3LhyfJsqaJbiKjWmZYBm+iJmqjirTJNfs9UHA1xIw0B+ZSNmq5DSdKGFzbLtgxPcch8vKBVHuEfwAEy2yGHo/qNEMwArUUyrqhySCtpFbRnn8z0e9Iw3cNDRnPedgCt/Yo2/MjOpWzL1t6p2EawdD/grhifXQ1SjUrxHHzWiuMKdPebucUSPmcV7XlRLlcVGBHie4s+Ne0hQFfb6tqMBjfN0vnAOUXOnIN0aFyO/U0TV/V/k7QGljA3ONfHQjPCPRyWJL6UCduGWPMbzAacb49sRrX8xcBKKCHGuRjei6OjVFhTOa7CTIKNM2mxL6/wgNpZQvstQl98D3J42Z19xSKV0l09UQdT6mbDzgteJeFJgG9gPSuNv0vUhLGcBGFZcVfyvBpUBZxXy1NJx++A3Yfo5eK/ZkFVmdz46mOHpOaKrgxsBSq/iD6/IPRkbAzC5g2/XTHDDYQT1JMCHzEOGE7eAdSI96deChkhrppqj3Iod3kqn2HXoyDcIdQORwODa+klE7IeEtsvbsldyvsoPPXnZ5IasKKubsJ9DJmQC5wAUbhCpU8KeJvod9veEpoKDai+Qv9bMh5fEQIGP03R1hxROdzhCbOTjyfblSnXK74HbAhw8+cvvPdQDOb9OiStjxvPOQG6Mq42MOA5u8Y5dpkPpikLKN+9DjlXy/76N4WUZnPf3ieKGS2CkRIprJ/VMuaLxLTnoZ9UV5kdBseN8CodO1JuvNvOUsw0xcZjn3TC3l9addLsJUgerGI0Y3oh/JZCPbG8ScCGeGnkUTqLeYZ0uF+rUIdT3mD6QCtw/1Q/rzSj4NWhiaLa8JYMRbQWeyj+t68WWVOZsNHif9wTLSdshD1gCb7c1Ep5+Y7y/EzyB6RZnfBW2AqFo905tXvZT1Ip0quAsJrGX6vwkltNvXkIPVR7yFtycAdUQDhoTzmvvOByom0UdDoLJ+qCYFyVZhGDNACmQqLNMER4Mldm3v3u9nO8wqOSwSXm731QJC7cycfp1C/KWN6N840xXkNRA6WHIaON4r1m0Rv8Jn1l+k1uSAHtprVNa92OqmgAMhJKV+fGfQv/eu5nagwM9RKKiw3BAbcJZcFWjNmBvWhvzwKpfVNgnMeHnPYTX5SbNkD9rY/jjKBu4YUqnKk52SDybcP9AiUc4Kqt3p12cGcICXUOeOCgFKTUWZgWJN03ib3ZkC5ui4YjBSGxHx75Dm/lWMlpo7ORnRV+epbTrsOe1GuQ132vohVIyML2259pBvWZJrNedleipw9OL3wif95Qq0UVq9uAvxM= X-Microsoft-Antispam-Message-Info: lX7/lTG0/LuEnwtwBGCsB+J8kyNrClsy7BiPNe1T5pOqacWaiS9Cs+ZtxQgmsYh05bNHBGmM/PdxJlTwtn9d+A/bJYfOeOwGqwRy+Y+cq8wT0OiQfFKtKwPy7+oAXoDGhMYIOpqc0+WP2RP0kSR1/k4GsqiXeR2TmW7m4cHnuMDsdDJvxC9P89up68699tIE X-Microsoft-Exchange-Diagnostics: 1; DM6PR07MB4218; 6:O40CNvwLGBuPZdrx1jgCcr5vdAoU7UYftQk5pMDo9FP1fWOs2+52v8HBtuTxROnVYjEFhDrDfEDCegQ5Dq3eVR5nATpKqsC8HCpvulsgGMhbGDGB9wH1j9blPDxUm774awJGeELd6pq+yuxVg4jXzN58o0G292GsQ9JZXGzd829c1LcG3X1G77PlUzLMSJrnI5hKyceh3E6aZld2ceiu5hdWUn0nnBz+Ob7aQ8blH+kBNszyvFaUQW9qmt+D6mNFYK3GRrG8iXNW+RcE4f1XowlniMKx6JVn0Qrd/IPZWYKyEpXi6qjpDmQBoWV7x5TWSR7lvgfrsK55b9h338Xxuiwy7MUz9mbcmRkbJ7C34614ppSTSnq6vRzXUStXoctji7rFU867QsjZZo/G54X48tbxxpNX1pultr5jLkFGODgI+8zzLWmCY1O6XwpyqtlJyfkI7dKSi9VA0NjH3GhfgQ==; 5:zyQNffIb/Pc+XBEcKo2LFc2iS3jstY/0WuvdZHCdsSc1zNPthgdCTCP0ZMj3Q0E8mrH9Nm6CccEwhNscNLfBiMXcUvfu6wG7y7rfwYB8mB+sbdPz6LSE5Ntz/RhTGarmwZzBeU0aR2h184P4WFi1YjM/buDP1GbeA/YT+5X+EQY=; 24:F2//JjJaPNUsJBVegDhuKBZqeDHxghj6j0MKJzZ7pLjr2glH21CRkL+CoYWKux6KUDf4cGd38kQ4XpVQzUyvujwYD5yRovuZ249ZjHhmvik= SpamDiagnosticOutput: 1:99 SpamDiagnosticMetadata: NSPM X-Microsoft-Exchange-Diagnostics: 1; DM6PR07MB4218; 7:twj7i2vXoRuMWS+tQ68PTHlDVHscpQ1e5B+paxRG0/Ya/mq9lOaJnjfE5x0xdlccQx89WEnZD8AUOrfj7cMnW/PMOpJUJxFb70zD01xL5+3C0dffAI5y6l4wHwp/kxgq3ALsuZofcoXMPBZtocNjz0JOGYMP3b7UXo0wwNKdDw7cuaoOrwXptnt4MtnJ0Vdaj/NHyR+o4M9N4yaR++es4HT4AWZYtOeRMIZ03eN8NF2oKZnrPjsW71cz2JB0KkDS X-MS-Office365-Filtering-Correlation-Id: 63ad7689-ae0c-44a5-7e8b-08d5b1e9e2b5 X-OriginatorOrg: cavium.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 04 May 2018 18:07:23.0272 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 63ad7689-ae0c-44a5-7e8b-08d5b1e9e2b5 X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 711e4ccf-2e9b-4bcf-a551-4094005b6194 X-MS-Exchange-Transport-CrossTenantHeadersStamped: DM6PR07MB4218 Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org From: Weilin Chang Support setting the link speed of CN23XX-225 cards (which can do 25Gbps or 10Gbps) via ethtool_ops.set_link_ksettings. Also fix the function assigned to ethtool_ops.get_link_ksettings to use the new link_ksettings api completely (instead of partially via ethtool_convert_legacy_u32_to_link_mode). Signed-off-by: Weilin Chang Acked-by: Raghu Vatsavayi Signed-off-by: Felix Manlunas --- Patch Change Log: V1 -> V2: In lio_set_link_ksettings(), set the order of local variable declarations from longest to shortest line. drivers/net/ethernet/cavium/liquidio/lio_core.c | 196 +++++++++++++++++++++ drivers/net/ethernet/cavium/liquidio/lio_ethtool.c | 195 +++++++++++++++++--- drivers/net/ethernet/cavium/liquidio/lio_main.c | 20 +++ drivers/net/ethernet/cavium/liquidio/lio_vf_main.c | 5 + .../net/ethernet/cavium/liquidio/liquidio_common.h | 4 + .../net/ethernet/cavium/liquidio/octeon_device.h | 14 ++ .../net/ethernet/cavium/liquidio/octeon_network.h | 15 ++ 7 files changed, 425 insertions(+), 24 deletions(-) diff --git a/drivers/net/ethernet/cavium/liquidio/lio_core.c b/drivers/net/ethernet/cavium/liquidio/lio_core.c index 6821afc..8093c5e 100644 --- a/drivers/net/ethernet/cavium/liquidio/lio_core.c +++ b/drivers/net/ethernet/cavium/liquidio/lio_core.c @@ -1481,3 +1481,199 @@ int octnet_get_link_stats(struct net_device *netdev) return 0; } + +static void liquidio_nic_seapi_ctl_callback(struct octeon_device *oct, + u32 status, + void *buf) +{ + struct liquidio_nic_seapi_ctl_context *ctx; + struct octeon_soft_command *sc = buf; + + ctx = sc->ctxptr; + + oct = lio_get_device(ctx->octeon_id); + if (status) { + dev_err(&oct->pci_dev->dev, "%s: instruction failed. Status: %llx\n", + __func__, + CVM_CAST64(status)); + } + ctx->status = status; + complete(&ctx->complete); +} + +int liquidio_set_speed(struct lio *lio, int speed) +{ + struct liquidio_nic_seapi_ctl_context *ctx; + struct octeon_device *oct = lio->oct_dev; + struct oct_nic_seapi_resp *resp; + struct octeon_soft_command *sc; + union octnet_cmd *ncmd; + u32 ctx_size; + int retval; + u32 var; + + if (oct->speed_setting == speed) + return 0; + + if (!OCTEON_CN23XX_PF(oct)) { + dev_err(&oct->pci_dev->dev, "%s: SET SPEED only for PF\n", + __func__); + return -EOPNOTSUPP; + } + + ctx_size = sizeof(struct liquidio_nic_seapi_ctl_context); + sc = octeon_alloc_soft_command(oct, OCTNET_CMD_SIZE, + sizeof(struct oct_nic_seapi_resp), + ctx_size); + if (!sc) + return -ENOMEM; + + ncmd = sc->virtdptr; + ctx = sc->ctxptr; + resp = sc->virtrptr; + memset(resp, 0, sizeof(struct oct_nic_seapi_resp)); + + ctx->octeon_id = lio_get_device_id(oct); + ctx->status = 0; + init_completion(&ctx->complete); + + ncmd->u64 = 0; + ncmd->s.cmd = SEAPI_CMD_SPEED_SET; + ncmd->s.param1 = speed; + + octeon_swap_8B_data((u64 *)ncmd, (OCTNET_CMD_SIZE >> 3)); + + sc->iq_no = lio->linfo.txpciq[0].s.q_no; + + octeon_prepare_soft_command(oct, sc, OPCODE_NIC, + OPCODE_NIC_UBOOT_CTL, 0, 0, 0); + + sc->callback = liquidio_nic_seapi_ctl_callback; + sc->callback_arg = sc; + sc->wait_time = 5000; + + retval = octeon_send_soft_command(oct, sc); + if (retval == IQ_SEND_FAILED) { + dev_info(&oct->pci_dev->dev, "Failed to send soft command\n"); + retval = -EBUSY; + } else { + /* Wait for response or timeout */ + if (wait_for_completion_timeout(&ctx->complete, + msecs_to_jiffies(10000)) == 0) { + dev_err(&oct->pci_dev->dev, "%s: sc timeout\n", + __func__); + octeon_free_soft_command(oct, sc); + return -EINTR; + } + + retval = resp->status; + + if (retval) { + dev_err(&oct->pci_dev->dev, "%s failed, retval=%d\n", + __func__, retval); + octeon_free_soft_command(oct, sc); + return -EIO; + } + + var = be32_to_cpu((__force __be32)resp->speed); + if (var != speed) { + dev_err(&oct->pci_dev->dev, + "%s: setting failed speed= %x, expect %x\n", + __func__, var, speed); + } + + oct->speed_setting = var; + } + + octeon_free_soft_command(oct, sc); + + return retval; +} + +int liquidio_get_speed(struct lio *lio) +{ + struct liquidio_nic_seapi_ctl_context *ctx; + struct octeon_device *oct = lio->oct_dev; + struct oct_nic_seapi_resp *resp; + struct octeon_soft_command *sc; + union octnet_cmd *ncmd; + u32 ctx_size; + int retval; + + ctx_size = sizeof(struct liquidio_nic_seapi_ctl_context); + sc = octeon_alloc_soft_command(oct, OCTNET_CMD_SIZE, + sizeof(struct oct_nic_seapi_resp), + ctx_size); + if (!sc) + return -ENOMEM; + + ncmd = sc->virtdptr; + ctx = sc->ctxptr; + resp = sc->virtrptr; + memset(resp, 0, sizeof(struct oct_nic_seapi_resp)); + + ctx->octeon_id = lio_get_device_id(oct); + ctx->status = 0; + init_completion(&ctx->complete); + + ncmd->u64 = 0; + ncmd->s.cmd = SEAPI_CMD_SPEED_GET; + + octeon_swap_8B_data((u64 *)ncmd, (OCTNET_CMD_SIZE >> 3)); + + sc->iq_no = lio->linfo.txpciq[0].s.q_no; + + octeon_prepare_soft_command(oct, sc, OPCODE_NIC, + OPCODE_NIC_UBOOT_CTL, 0, 0, 0); + + sc->callback = liquidio_nic_seapi_ctl_callback; + sc->callback_arg = sc; + sc->wait_time = 5000; + + retval = octeon_send_soft_command(oct, sc); + if (retval == IQ_SEND_FAILED) { + dev_info(&oct->pci_dev->dev, "Failed to send soft command\n"); + oct->no_speed_setting = 1; + oct->speed_setting = 25; + + retval = -EBUSY; + } else { + if (wait_for_completion_timeout(&ctx->complete, + msecs_to_jiffies(10000)) == 0) { + dev_err(&oct->pci_dev->dev, "%s: sc timeout\n", + __func__); + + oct->speed_setting = 25; + oct->no_speed_setting = 1; + + octeon_free_soft_command(oct, sc); + + return -EINTR; + } + retval = resp->status; + if (retval) { + dev_err(&oct->pci_dev->dev, + "%s failed retval=%d\n", __func__, retval); + oct->no_speed_setting = 1; + oct->speed_setting = 25; + octeon_free_soft_command(oct, sc); + retval = -EIO; + } else { + u32 var; + + var = be32_to_cpu((__force __be32)resp->speed); + oct->speed_setting = var; + if (var == 0xffff) { + oct->no_speed_setting = 1; + /* unable to access boot variables + * get the default value based on the NIC type + */ + oct->speed_setting = 25; + } + } + } + + octeon_free_soft_command(oct, sc); + + return retval; +} diff --git a/drivers/net/ethernet/cavium/liquidio/lio_ethtool.c b/drivers/net/ethernet/cavium/liquidio/lio_ethtool.c index a1d8430..06f7449 100644 --- a/drivers/net/ethernet/cavium/liquidio/lio_ethtool.c +++ b/drivers/net/ethernet/cavium/liquidio/lio_ethtool.c @@ -230,46 +230,147 @@ static int lio_get_link_ksettings(struct net_device *netdev, struct lio *lio = GET_LIO(netdev); struct octeon_device *oct = lio->oct_dev; struct oct_link_info *linfo; - u32 supported = 0, advertising = 0; linfo = &lio->linfo; + ethtool_link_ksettings_zero_link_mode(ecmd, supported); + ethtool_link_ksettings_zero_link_mode(ecmd, advertising); + switch (linfo->link.s.phy_type) { case LIO_PHY_PORT_TP: ecmd->base.port = PORT_TP; - supported = (SUPPORTED_10000baseT_Full | - SUPPORTED_TP | SUPPORTED_Pause); - advertising = (ADVERTISED_10000baseT_Full | ADVERTISED_Pause); ecmd->base.autoneg = AUTONEG_DISABLE; + ethtool_link_ksettings_add_link_mode(ecmd, supported, TP); + ethtool_link_ksettings_add_link_mode(ecmd, supported, Pause); + ethtool_link_ksettings_add_link_mode(ecmd, supported, + 10000baseT_Full); + + ethtool_link_ksettings_add_link_mode(ecmd, advertising, Pause); + ethtool_link_ksettings_add_link_mode(ecmd, advertising, + 10000baseT_Full); + break; case LIO_PHY_PORT_FIBRE: - ecmd->base.port = PORT_FIBRE; - - if (linfo->link.s.speed == SPEED_10000) { - supported = SUPPORTED_10000baseT_Full; - advertising = ADVERTISED_10000baseT_Full; + if (linfo->link.s.if_mode == INTERFACE_MODE_XAUI || + linfo->link.s.if_mode == INTERFACE_MODE_RXAUI || + linfo->link.s.if_mode == INTERFACE_MODE_XLAUI || + linfo->link.s.if_mode == INTERFACE_MODE_XFI) { + dev_dbg(&oct->pci_dev->dev, "ecmd->base.transceiver is XCVR_EXTERNAL\n"); + } else { + dev_err(&oct->pci_dev->dev, "Unknown link interface mode: %d\n", + linfo->link.s.if_mode); } - supported |= SUPPORTED_FIBRE | SUPPORTED_Pause; - advertising |= ADVERTISED_Pause; + ecmd->base.port = PORT_FIBRE; ecmd->base.autoneg = AUTONEG_DISABLE; + ethtool_link_ksettings_add_link_mode(ecmd, supported, FIBRE); + + ethtool_link_ksettings_add_link_mode(ecmd, supported, Pause); + ethtool_link_ksettings_add_link_mode(ecmd, advertising, Pause); + if (oct->subsystem_id == OCTEON_CN2350_25GB_SUBSYS_ID || + oct->subsystem_id == OCTEON_CN2360_25GB_SUBSYS_ID) { + if (OCTEON_CN23XX_PF(oct)) { + ethtool_link_ksettings_add_link_mode + (ecmd, supported, 25000baseSR_Full); + ethtool_link_ksettings_add_link_mode + (ecmd, supported, 25000baseKR_Full); + ethtool_link_ksettings_add_link_mode + (ecmd, supported, 25000baseCR_Full); + + if (oct->no_speed_setting == 0) { + ethtool_link_ksettings_add_link_mode + (ecmd, supported, + 10000baseSR_Full); + ethtool_link_ksettings_add_link_mode + (ecmd, supported, + 10000baseKR_Full); + ethtool_link_ksettings_add_link_mode + (ecmd, supported, + 10000baseCR_Full); + } + + if (oct->no_speed_setting == 0) + liquidio_get_speed(lio); + else + oct->speed_setting = 25; + + if (oct->speed_setting == 10) { + ethtool_link_ksettings_add_link_mode + (ecmd, advertising, + 10000baseSR_Full); + ethtool_link_ksettings_add_link_mode + (ecmd, advertising, + 10000baseKR_Full); + ethtool_link_ksettings_add_link_mode + (ecmd, advertising, + 10000baseCR_Full); + } + if (oct->speed_setting == 25) { + ethtool_link_ksettings_add_link_mode + (ecmd, advertising, + 25000baseSR_Full); + ethtool_link_ksettings_add_link_mode + (ecmd, advertising, + 25000baseKR_Full); + ethtool_link_ksettings_add_link_mode + (ecmd, advertising, + 25000baseCR_Full); + } + } else { /* VF */ + if (linfo->link.s.speed == 10000) { + ethtool_link_ksettings_add_link_mode + (ecmd, supported, + 10000baseSR_Full); + ethtool_link_ksettings_add_link_mode + (ecmd, supported, + 10000baseKR_Full); + ethtool_link_ksettings_add_link_mode + (ecmd, supported, + 10000baseCR_Full); + + ethtool_link_ksettings_add_link_mode + (ecmd, advertising, + 10000baseSR_Full); + ethtool_link_ksettings_add_link_mode + (ecmd, advertising, + 10000baseKR_Full); + ethtool_link_ksettings_add_link_mode + (ecmd, advertising, + 10000baseCR_Full); + } + + if (linfo->link.s.speed == 25000) { + ethtool_link_ksettings_add_link_mode + (ecmd, supported, + 25000baseSR_Full); + ethtool_link_ksettings_add_link_mode + (ecmd, supported, + 25000baseKR_Full); + ethtool_link_ksettings_add_link_mode + (ecmd, supported, + 25000baseCR_Full); + + ethtool_link_ksettings_add_link_mode + (ecmd, advertising, + 25000baseSR_Full); + ethtool_link_ksettings_add_link_mode + (ecmd, advertising, + 25000baseKR_Full); + ethtool_link_ksettings_add_link_mode + (ecmd, advertising, + 25000baseCR_Full); + } + } + } else { + ethtool_link_ksettings_add_link_mode(ecmd, supported, + 10000baseT_Full); + ethtool_link_ksettings_add_link_mode(ecmd, advertising, + 10000baseT_Full); + } break; } - if (linfo->link.s.if_mode == INTERFACE_MODE_XAUI || - linfo->link.s.if_mode == INTERFACE_MODE_RXAUI || - linfo->link.s.if_mode == INTERFACE_MODE_XLAUI || - linfo->link.s.if_mode == INTERFACE_MODE_XFI) { - ethtool_convert_legacy_u32_to_link_mode( - ecmd->link_modes.supported, supported); - ethtool_convert_legacy_u32_to_link_mode( - ecmd->link_modes.advertising, advertising); - } else { - dev_err(&oct->pci_dev->dev, "Unknown link interface reported %d\n", - linfo->link.s.if_mode); - } - if (linfo->link.s.link_up) { ecmd->base.speed = linfo->link.s.speed; ecmd->base.duplex = linfo->link.s.duplex; @@ -281,6 +382,51 @@ static int lio_get_link_ksettings(struct net_device *netdev, return 0; } +static int lio_set_link_ksettings(struct net_device *netdev, + const struct ethtool_link_ksettings *ecmd) +{ + const int speed = ecmd->base.speed; + struct lio *lio = GET_LIO(netdev); + struct oct_link_info *linfo; + struct octeon_device *oct; + u32 is25G = 0; + + oct = lio->oct_dev; + + linfo = &lio->linfo; + + if (oct->subsystem_id == OCTEON_CN2350_25GB_SUBSYS_ID || + oct->subsystem_id == OCTEON_CN2360_25GB_SUBSYS_ID) { + is25G = 1; + } else { + return -EOPNOTSUPP; + } + + if (oct->no_speed_setting) { + dev_err(&oct->pci_dev->dev, "%s: Changing speed is not supported\n", + __func__); + return -EOPNOTSUPP; + } + + if ((ecmd->base.duplex != DUPLEX_UNKNOWN && + ecmd->base.duplex != linfo->link.s.duplex) || + ecmd->base.autoneg != AUTONEG_DISABLE || + (ecmd->base.speed != 10000 && ecmd->base.speed != 25000 && + ecmd->base.speed != SPEED_UNKNOWN)) + return -EOPNOTSUPP; + + if ((oct->speed_boot == speed / 1000) && + oct->speed_boot == oct->speed_setting) + return 0; + + liquidio_set_speed(lio, speed / 1000); + + dev_dbg(&oct->pci_dev->dev, "Port speed is set to %dG\n", + oct->speed_setting); + + return 0; +} + static void lio_get_drvinfo(struct net_device *netdev, struct ethtool_drvinfo *drvinfo) { @@ -2966,6 +3112,7 @@ static int lio_set_priv_flags(struct net_device *netdev, u32 flags) static const struct ethtool_ops lio_ethtool_ops = { .get_link_ksettings = lio_get_link_ksettings, + .set_link_ksettings = lio_set_link_ksettings, .get_link = ethtool_op_get_link, .get_drvinfo = lio_get_drvinfo, .get_ringparam = lio_ethtool_get_ringparam, diff --git a/drivers/net/ethernet/cavium/liquidio/lio_main.c b/drivers/net/ethernet/cavium/liquidio/lio_main.c index ee75048..e500528 100644 --- a/drivers/net/ethernet/cavium/liquidio/lio_main.c +++ b/drivers/net/ethernet/cavium/liquidio/lio_main.c @@ -912,6 +912,9 @@ liquidio_probe(struct pci_dev *pdev, /* set linux specific device pointer */ oct_dev->pci_dev = (void *)pdev; + oct_dev->subsystem_id = pdev->subsystem_vendor | + (pdev->subsystem_device << 16); + hs = &handshake[oct_dev->octeon_id]; init_completion(&hs->init); init_completion(&hs->started); @@ -3664,6 +3667,23 @@ static int setup_nic_devices(struct octeon_device *octeon_dev) "NIC ifidx:%d Setup successful\n", i); octeon_free_soft_command(octeon_dev, sc); + + if (octeon_dev->subsystem_id == + OCTEON_CN2350_25GB_SUBSYS_ID || + octeon_dev->subsystem_id == + OCTEON_CN2360_25GB_SUBSYS_ID) { + liquidio_get_speed(lio); + + if (octeon_dev->speed_setting == 0) { + octeon_dev->speed_setting = 25; + octeon_dev->no_speed_setting = 1; + } + } else { + octeon_dev->no_speed_setting = 1; + octeon_dev->speed_setting = 10; + } + octeon_dev->speed_boot = octeon_dev->speed_setting; + } devlink = devlink_alloc(&liquidio_devlink_ops, diff --git a/drivers/net/ethernet/cavium/liquidio/lio_vf_main.c b/drivers/net/ethernet/cavium/liquidio/lio_vf_main.c index 6295eee..7fa0212 100644 --- a/drivers/net/ethernet/cavium/liquidio/lio_vf_main.c +++ b/drivers/net/ethernet/cavium/liquidio/lio_vf_main.c @@ -411,6 +411,9 @@ liquidio_vf_probe(struct pci_dev *pdev, /* set linux specific device pointer */ oct_dev->pci_dev = pdev; + oct_dev->subsystem_id = pdev->subsystem_vendor | + (pdev->subsystem_device << 16); + if (octeon_device_init(oct_dev)) { liquidio_vf_remove(pdev); return -ENOMEM; @@ -2199,6 +2202,8 @@ static int setup_nic_devices(struct octeon_device *octeon_dev) "NIC ifidx:%d Setup successful\n", i); octeon_free_soft_command(octeon_dev, sc); + + octeon_dev->no_speed_setting = 1; } return 0; diff --git a/drivers/net/ethernet/cavium/liquidio/liquidio_common.h b/drivers/net/ethernet/cavium/liquidio/liquidio_common.h index 0265704..285b248 100644 --- a/drivers/net/ethernet/cavium/liquidio/liquidio_common.h +++ b/drivers/net/ethernet/cavium/liquidio/liquidio_common.h @@ -93,6 +93,7 @@ enum octeon_tag_type { #define OPCODE_NIC_VF_REP_PKT 0x15 #define OPCODE_NIC_VF_REP_CMD 0x16 +#define OPCODE_NIC_UBOOT_CTL 0x17 #define CORE_DRV_TEST_SCATTER_OP 0xFFF5 @@ -249,6 +250,9 @@ static inline void add_sg_size(struct octeon_sg_entry *sg_entry, #define OCTNET_CMD_VLAN_FILTER_ENABLE 0x1 #define OCTNET_CMD_VLAN_FILTER_DISABLE 0x0 +#define SEAPI_CMD_SPEED_SET 0x2 +#define SEAPI_CMD_SPEED_GET 0x3 + #define LIO_CMD_WAIT_TM 100 /* RX(packets coming from wire) Checksum verification flags */ diff --git a/drivers/net/ethernet/cavium/liquidio/octeon_device.h b/drivers/net/ethernet/cavium/liquidio/octeon_device.h index 9430c0a..94a4ed88d 100644 --- a/drivers/net/ethernet/cavium/liquidio/octeon_device.h +++ b/drivers/net/ethernet/cavium/liquidio/octeon_device.h @@ -43,6 +43,13 @@ #define OCTEON_CN23XX_REV_1_1 0x01 #define OCTEON_CN23XX_REV_2_0 0x80 +/**SubsystemId for the chips */ +#define OCTEON_CN2350_10GB_SUBSYS_ID_1 0X3177d +#define OCTEON_CN2350_10GB_SUBSYS_ID_2 0X4177d +#define OCTEON_CN2360_10GB_SUBSYS_ID 0X5177d +#define OCTEON_CN2350_25GB_SUBSYS_ID 0X7177d +#define OCTEON_CN2360_25GB_SUBSYS_ID 0X6177d + /** Endian-swap modes supported by Octeon. */ enum octeon_pci_swap_mode { OCTEON_PCI_PASSTHROUGH = 0, @@ -430,6 +437,8 @@ struct octeon_device { u16 rev_id; + u32 subsystem_id; + u16 pf_num; u16 vf_num; @@ -584,6 +593,11 @@ struct octeon_device { struct lio_vf_rep_list vf_rep_list; struct devlink *devlink; enum devlink_eswitch_mode eswitch_mode; + + /* for 25G NIC speed change */ + u8 speed_boot; + u8 speed_setting; + u8 no_speed_setting; }; #define OCT_DRV_ONLINE 1 diff --git a/drivers/net/ethernet/cavium/liquidio/octeon_network.h b/drivers/net/ethernet/cavium/liquidio/octeon_network.h index 8571f11..dd3177a 100644 --- a/drivers/net/ethernet/cavium/liquidio/octeon_network.h +++ b/drivers/net/ethernet/cavium/liquidio/octeon_network.h @@ -81,6 +81,18 @@ struct oct_nic_stats_ctrl { struct net_device *netdev; }; +struct oct_nic_seapi_resp { + u64 rh; + u32 speed; + u64 status; +}; + +struct liquidio_nic_seapi_ctl_context { + int octeon_id; + u32 status; + struct completion complete; +}; + /** LiquidIO per-interface network private data */ struct lio { /** State of the interface. Rx/Tx happens only in the RUNNING state. */ @@ -230,6 +242,9 @@ void lio_delete_glists(struct lio *lio); int lio_setup_glists(struct octeon_device *oct, struct lio *lio, int num_qs); +int liquidio_get_speed(struct lio *lio); +int liquidio_set_speed(struct lio *lio, int speed); + /** * \brief Net device change_mtu * @param netdev network device