From patchwork Fri Aug 18 00:02:50 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tom Lendacky X-Patchwork-Id: 802979 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@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; dkim=pass (1024-bit key; unprotected) header.d=amdcloud.onmicrosoft.com header.i=@amdcloud.onmicrosoft.com header.b="n5SxxT7O"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 3xYNZV0YVhz9t3m for ; Fri, 18 Aug 2017 10:02:58 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753875AbdHRAC4 (ORCPT ); Thu, 17 Aug 2017 20:02:56 -0400 Received: from mail-sn1nam02on0075.outbound.protection.outlook.com ([104.47.36.75]:22560 "EHLO NAM02-SN1-obe.outbound.protection.outlook.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1753471AbdHRACy (ORCPT ); Thu, 17 Aug 2017 20:02:54 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=amdcloud.onmicrosoft.com; s=selector1-amd-com; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version; bh=OgAWzO1C/lGGQI0NihfPmJM18DJW1RqC6099uSGF3Jo=; b=n5SxxT7OhRHqpkmOMuA3A29xigO6SMHIkWa22WyTBtK2J4qozXkNRQ5vg7QvvYL34IhBbE5k6ls25woz5rjO0EU1eR9bnhCJ8BerTkQkerzZXy6qw9nHqwJbmQRwZZf5m49tUUqDtKkQry4GpRF3iEfFMgaISBVtELgpb+c68FY= Authentication-Results: spf=none (sender IP is ) smtp.mailfrom=Thomas.Lendacky@amd.com; Received: from tlendack-t1.amdoffice.net (165.204.77.1) by DM5PR12MB1147.namprd12.prod.outlook.com (10.168.236.142) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.1362.18; Fri, 18 Aug 2017 00:02:52 +0000 From: Tom Lendacky Subject: [PATCH net-next v1 05/14] amd-xgbe: Add additional debugfs support To: netdev@vger.kernel.org Cc: David Miller Date: Thu, 17 Aug 2017 19:02:50 -0500 Message-ID: <20170818000250.10005.87855.stgit@tlendack-t1.amdoffice.net> In-Reply-To: <20170818000201.10005.36182.stgit@tlendack-t1.amdoffice.net> References: <20170818000201.10005.36182.stgit@tlendack-t1.amdoffice.net> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 X-Originating-IP: [165.204.77.1] X-ClientProxiedBy: BN6PR17CA0008.namprd17.prod.outlook.com (10.173.147.18) To DM5PR12MB1147.namprd12.prod.outlook.com (10.168.236.142) X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: dc837c13-a72b-4449-0043-08d4e5cc790c X-MS-Office365-Filtering-HT: Tenant X-Microsoft-Antispam: UriScan:; BCL:0; PCL:0; RULEID:(300000500095)(300135000095)(300000501095)(300135300095)(22001)(300000502095)(300135100095)(2017030254152)(300000503095)(300135400095)(48565401081)(201703131423075)(201703031133081)(201702281549075)(300000504095)(300135200095)(300000505095)(300135600095)(300000506095)(300135500095); SRVR:DM5PR12MB1147; X-Microsoft-Exchange-Diagnostics: 1; DM5PR12MB1147; 3:NCOK/hJ024862DQ9lVBMSVwc0dIf5TA1otD9m1xe9uAATiz12CRkv/muuRjux5a/oU597ZEhXrE9AuHoKDmwTOe8ZCTtWuzCgomwtjQiNX92Fm+6YUoqPGCw7aiXv1aCwl4Lbqbi63yjh4Z1YAcZeL2CbrJlkg3+orVog81cmtX617n1oKtG4vOv3T3dSTvYpwhzxbrwkIVlhzNCycCfiKsKDvU54VU4Y2e9XKnyVCbL2b7Oegok1hp89GwZrm6E; 25:Ca9URachJf5qjO+dioWBkkoit5gD+5UcCs8yKRgSr50PffdCY/YPVMVx/wNrd0CFOoxyezqqH3B9zBAUW+eO6fPx/1LhYHWT06+kbolctaQTVUa3LH7u6S8kaM2osrykJfitQxKZXLLxqAoudmaqh2x6DFtgQ9ZoNZAn1He6WIMsLQb6nmY1+o4TRUGqh+MAv6l/ynQjrofr6qVkEhZq8McXu06lr0w4aXPHVjqHtsZKHPqV0xpqo4KYX7kGh1OFPsaSuCgZLdjLpJeJdFj65aoPfrJ5u2KAQ7dEDQjCi7E26XB+WiXaE9ja3v5FJwXal4dujEX3x9fpznNj9Z9KKg==; 31:jgRU0jOMN8dECNNOO/3xi8NM089vaUkl1SclQArcLYY5hl7XP39uLDgmdcsf9oL8LFnXLNOt6PusLuqhOhxqajIBjK0FLEWud/xmTmSxBU7AnnVqyDENZPmIKneYnYfP/fJHIDAAgDcF/SosAeVy4Q2AlrKpXrEmcplhgFELM6mY0YEACEK7A+/Z4mmc1fTajlQhhBQAlNn7YdBQltG4c4TH/4eRDB76Mvwbup9axEE= X-MS-TrafficTypeDiagnostic: DM5PR12MB1147: X-Microsoft-Exchange-Diagnostics: 1; DM5PR12MB1147; 20:gLA65Ng87Fmgf094uZyWM461F+TolgGI5wbXXtZV4dYkkTyljwMA2qdOOP0ErOJ+rPrMpA6XjjTUYkBHkZbzA+R/4Hg4Jnc4FsBzl0yLLNy6TZcR1NXdn1sq95iNdHNzJ6iccozuaW5w051KL/ttaW9f4csIotq/0YLi5liAlj5zKaaLEqfUb5r2skc+zS6KoyKcgsJ1DReFnp/pKsZqGqHpwlMXpFW4Rm54+rLVzryxlp4zc1b+LDpO5zFes+3B0PA2QeRv5q9zICCC8T+2BEsH5YAbUNgbSU6O+LMaIPPlsPzkPBu55ASIQjs4jFXZ3zU+BqM/q4IpC0ZK/D7MLfTHjje7hah3SkT7kv2YaPd67/RC2lMOLHh7Iz/MGv4ryJhSNAlzR1MmJ3M8QXYySmqMxyNShyqUDK/hh/aUgCfU99I97AuwnTo3xsI85mb3YhDdWIS4jumnQsW8Atia2YE7iWxZhf4HxqhrTVH7TYzfWDL8qXwdZy9OLIhsu+U8; 4:BDglV1qcttePKzXLXfvNVZ2Stn+FraEp/3vt4LBvtPtw0YsKaFZtKgLs1TFhV6i8SlFVk+ANi2Yf2FrZ5Y0tA3zdtrGDw2tTMuHascGbOe/dUfhncuWYGdDc6kHtLBJy/u0FakxP7GPEVcGbgEI2qvrnAP3dt0axGKUj1Gan8X9K9E+kfA4QjhFbS+jam/QCbLlVJp07Lhl8eyOMaV8XznpW1dkOYUtof91yO/lvtYFVN9ZILjBg0GIOQ76KYeWFFlzi6XoWd0LrQIAtR4VRMXCX8cJECoJC+bUyCSs7Ntw= X-Exchange-Antispam-Report-Test: UriScan:(767451399110); X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-CFA-Test: BCL:0; PCL:0; RULEID:(100000700101)(100105000095)(100000701101)(100105300095)(100000702101)(100105100095)(6040450)(601004)(2401047)(5005006)(8121501046)(10201501046)(100000703101)(100105400095)(93006095)(93001095)(3002001)(6055026)(6041248)(20161123558100)(20161123562025)(20161123564025)(201703131423075)(201702281528075)(201703061421075)(201703061406153)(20161123560025)(20161123555025)(6072148)(201708071742011)(100000704101)(100105200095)(100000705101)(100105500095); SRVR:DM5PR12MB1147; BCL:0; PCL:0; RULEID:(100000800101)(100110000095)(100000801101)(100110300095)(100000802101)(100110100095)(100000803101)(100110400095)(100000804101)(100110200095)(100000805101)(100110500095); SRVR:DM5PR12MB1147; X-Forefront-PRVS: 040359335D X-Forefront-Antispam-Report: SFV:NSPM; SFS:(10009020)(4630300001)(7370300001)(6009001)(39860400002)(199003)(189002)(2361001)(8676002)(97736004)(105586002)(106356001)(2351001)(4326008)(50466002)(3846002)(76176999)(9686003)(53416004)(50986999)(66066001)(2906002)(54356999)(1076002)(47776003)(42186005)(305945005)(101416001)(55016002)(6916009)(2950100002)(6116002)(23676002)(81156014)(81166006)(68736007)(5660300001)(7350300001)(4001350100001)(7736002)(72206003)(6506006)(103116003)(33646002)(189998001)(86362001)(5890100001)(53936002)(230700001)(83506001)(110136004)(25786009)(97746001)(478600001)(69596002); DIR:OUT; SFP:1101; SCL:1; SRVR:DM5PR12MB1147; H:tlendack-t1.amdoffice.net; FPR:; SPF:None; PTR:InfoNoRecords; A:1; MX:1; LANG:en; Received-SPF: None (protection.outlook.com: amd.com does not designate permitted sender hosts) X-Microsoft-Exchange-Diagnostics: =?utf-8?B?MTtETTVQUjEyTUIxMTQ3OzIzOmNRYWNSUkRSWFZYbTFvQUYxdThiZ1VoNUdW?= =?utf-8?B?T1lGTHQ0TnVPdnNKSkF0T1FmYTZnRWp6UmVDNzd5T2ZuU1VOZEtwM0hTNkYr?= =?utf-8?B?alZYeVZHYStrcFhPc0pZbHhaaDB1ZldwaWE1d1JSREZTMlVsZ3NaRERpRjVv?= =?utf-8?B?d1IxMXJ5UWNYb2hYTUhRNjgzSkFnZ1laYjVYTEsyQ1FldDhjTGozQjcxQVk0?= =?utf-8?B?eWVxL1VkZTNqSTJORERUVERQb0ZqbkVtWjdFRTZXTG1IMis0WEpXU255N3F2?= =?utf-8?B?NWpnZFdXUUprTXBLOXAxMHZHVnlvYUZhMzhGckg2MzlHYnBrUlYxdHdYRjRk?= =?utf-8?B?UnRxa0FLdGw1SXJtTHphbGU2NEZyeDh5SFpZdHEyYWdvODJoS2laR2xDL3VL?= =?utf-8?B?QWRUU3pDZ3VIYi84cFVnR2VqN0s1QmdjWWZjQ3dpeUtTenBoZW92c1ZNUXYv?= =?utf-8?B?MGhjd1MzMDdzYVVXY3dFNVRndmR1RkJOcnRXeEtYMmZtNTFNUys1VkthT2hr?= =?utf-8?B?cTNJUmpMWDQ2YkxoK09JdGRiaUlVK2J6M2lCSllWbEo2ZytEZWJCa0Z6ZTBz?= =?utf-8?B?MVN5YmVXaVNLS2JuSG5QaWNub1NkdXhxYUtPQ1V4ZkxWbWc2NEU2di9tY0FI?= =?utf-8?B?RE50TklmSFR0UjVBdnA2S3VzcjNiZzROOExKSCtSVUxIdHR1NnlnVHUrSVVU?= =?utf-8?B?cEthaWoxek91YkFBZmd2QXZaTDRudy9udFNSeEp5TTQ1NHkzcXpEenF3TDFy?= =?utf-8?B?Ti8rSzRkY2FrTFFQZFVING1maGFmR05xNEk3MHd3enQvSlJLNXJyZmlabUJr?= =?utf-8?B?MmFndHdkRk8zQ1h1aEVCMEZBeVM2MjRuM3AxSUJoZTJaOHFWNVhyOWtjd1hC?= =?utf-8?B?TWRiU05pWnJFWXZiMUszNExSYXdJaDM0Y3R0bFN0VmVnK1V2eXNhMng2M1NC?= =?utf-8?B?Z0dQN2I4aFR4N1Y2NzFRSFVnTWlrb2JHWmVXeGEvN3h2eG9LUG5zZTcweFRF?= =?utf-8?B?SzhoQmZLUDVZRGgyMHVSQXdESklWT1JRV0xhWVZPaTk5enRoUEVQV29CWkNY?= =?utf-8?B?ajNrOGViUFV2RnM5M3VtMTdqZVFnRkNZalFUUHVDZEhRK3ZQVzM2YU1hbTB4?= =?utf-8?B?b2owS1pWQUFVeDltYXFiSzFoZHJla2F2VVRlb0dTYW9DSGtDTGFPcUd1K041?= =?utf-8?B?L1VkRmNKR0J3MnZuVGZ1NmU4b0xvbUJGYlRSYjQ2MWhvUm1VaG9rcFNsSFNH?= =?utf-8?B?clNSdldKU05hU3pSdVZ1bnhEdDNqaGw3a0dRTVBxMk05V05Mc0c1V2FBNU40?= =?utf-8?B?akVONHJRaXhFcnphekJXcE04dWlqQS9ycnBFOUJzb2F1Q1hoMmpvVURYT1B0?= =?utf-8?B?cHRScDhqVHRvZnlIaXhTRXZUTit4Ti9neldlT0Rpa3pmQWp0Q1BSbzBuSGhO?= =?utf-8?B?aE40QkZZL0k0TTJGRXFYWDZGeDBtQTB6NDJZMHROWHRZeHdkS0JVRFp0Uk5K?= =?utf-8?B?RHVhQ1V2aHFDcmc1WWl2STYzWlhJaXhoKzJoanBXeWJhU2QwTmkzTUxaSExj?= =?utf-8?B?NTVqb2JlbW5uTDY1Wnd0b0ZiVXQ3RFZuSlNNdGlBWkNuVklOdC9LcHdEbXIw?= =?utf-8?B?Ump2eDVQUXpIalp2Y1VJQ2dpbmpncmZyMUFIaUhYenFVNzIrSXYrUHA0UkF3?= =?utf-8?B?S0FyV3ArYTRHdlljWGVvMnpkRzVTU1F3TnR4YWdhSU5sY25YWTJHandveito?= =?utf-8?Q?psEOCI6q/imP/PYmReUNYrykFdOo46VVBiKN8=3D?= X-Microsoft-Exchange-Diagnostics: 1; DM5PR12MB1147; 6:adOkUDDGs8X1UTUpuPq59mLSMJxaEHREl+Y7t4nDI/ggNWPxQ5cEh9qTNhsdoj6OYq01URmtgVTadADZ2wFl+cUk8dMv8BBNwS2vPJIYiGBZpW705PPscRyD/avrnyTU+neu5hF5NO3okwKPZeoPXp0U2hX2fg9ZNj/QRvsD9qUkOA23TnUm8tPimjqPH0ANTcSZyT++wMLsad8NK78R6r9WEcNtfQCsvXrU25lr0/H3/NDCa+HXM9irs+GFQ9afTuFJcHePQ1X9HNDnnVmAwDYUELZaj2GfI+D5OxqXkh3XzxLUXXOCtCxpm11s6Kxxc6YF+KCg7VnzmrIZPQOcrw==; 5:ZbS166yX/FFig92Z7fBgQMN4jSPRFgmkaTjlzF0UCWTcdsaRc8VyPXwa+icB2YDjjyyGa6K5ySXm5mknBbz6x80OLbLBRXIX6RSEgO3strKxQkSLSyskPGpyDFUJn5F62SahCA1cYfMqfLt2SQ5gqw==; 24:+2zhZFbJZAFMfgMQF+XI+B36PM8ECevWieJaNKv9efXXMAjPJKjgCLejdXPlEEfl4XqqisezLtho9jevTls0c+Itqge+BixTLoDmvbX6FGA=; 7:KNcnlgdxDk0qOEcOlP1BTX6mYltWb1B5/BDJ3/tUZWOJHzxJS6UQevv/aovhLvuA8d+eI+goNKTBv0kzJu8ERfCxKaNGluQpuqYvYDk+N8Ucd+7xiU4fqQjcC0RiylShFnSjdY+0a0aXjLTpOM5d63Q5UNby5fWGjHWZP2NaOE2vRE8UIfYLHrCwv9h5m3iw0XiLK1wz83sWvElgH2z7OgZd6okS/S/B22zMSfytLPw= SpamDiagnosticOutput: 1:99 SpamDiagnosticMetadata: NSPM X-Microsoft-Exchange-Diagnostics: 1; DM5PR12MB1147; 20:5Fa3WmxB3hRGbZeDIcdJZkfJZVu+eDm1Dy/ObkOBO8W4wRzWR04p8UqlkxjWj2mwpf9CPfv2z4+GGWd2TvD72mljc6Cnq2HhGW6IS/NbVO/cWV9xVl2oD16ucQJvbxjPbgVEXWXPclSkem/+ZFgcgXkKmNA9wiGPZs/4V3/P/glITbEhw2OZS9nGBOVAv2HfY3R5esvJ0hQGeX232daBL7JihF74D/koxG183KS8KA6bCafogxP0QDL+kJ2adqxD X-OriginatorOrg: amd.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 18 Aug 2017 00:02:52.8727 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-Transport-CrossTenantHeadersStamped: DM5PR12MB1147 Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org Add additional debugfs support for reading / writing registers of any attached external phy devices as well as the SFP eeprom data. These debugfs files will only be created if the phy implementation supports them. Signed-off-by: Tom Lendacky --- drivers/net/ethernet/amd/xgbe/xgbe-debugfs.c | 151 ++++++++++++++++++++++++++ drivers/net/ethernet/amd/xgbe/xgbe-phy-v2.c | 87 +++++++++++++++ drivers/net/ethernet/amd/xgbe/xgbe.h | 12 ++ 3 files changed, 250 insertions(+) diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-debugfs.c b/drivers/net/ethernet/amd/xgbe/xgbe-debugfs.c index 7546b66..7409705 100644 --- a/drivers/net/ethernet/amd/xgbe/xgbe-debugfs.c +++ b/drivers/net/ethernet/amd/xgbe/xgbe-debugfs.c @@ -436,6 +436,126 @@ static ssize_t xi2c_reg_value_write(struct file *filp, .write = xi2c_reg_value_write, }; +static ssize_t sfp_eeprom_read(struct file *filp, char __user *buffer, + size_t count, loff_t *ppos) +{ + struct xgbe_prv_data *pdata = filp->private_data; + struct xgbe_phy_impl_if *phy_impl; + unsigned char *eeprom; + ssize_t len; + + phy_impl = &pdata->phy_if.phy_impl; + eeprom = phy_impl->sfp_eeprom(pdata); + if (!eeprom) + return 0; + + len = simple_read_from_buffer(buffer, count, ppos, + eeprom, strlen(eeprom)); + + kfree(eeprom); + + return len; +} + +static const struct file_operations sfp_eeprom_fops = { + .owner = THIS_MODULE, + .open = simple_open, + .read = sfp_eeprom_read, +}; + +static ssize_t phydev_mmd_read(struct file *filp, char __user *buffer, + size_t count, loff_t *ppos) +{ + struct xgbe_prv_data *pdata = filp->private_data; + + return xgbe_common_read(buffer, count, ppos, pdata->debugfs_phydev_mmd); +} + +static ssize_t phydev_mmd_write(struct file *filp, const char __user *buffer, + size_t count, loff_t *ppos) +{ + struct xgbe_prv_data *pdata = filp->private_data; + + return xgbe_common_write(buffer, count, ppos, + &pdata->debugfs_phydev_mmd); +} + +static ssize_t phydev_reg_addr_read(struct file *filp, char __user *buffer, + size_t count, loff_t *ppos) +{ + struct xgbe_prv_data *pdata = filp->private_data; + + return xgbe_common_read(buffer, count, ppos, pdata->debugfs_phydev_reg); +} + +static ssize_t phydev_reg_addr_write(struct file *filp, + const char __user *buffer, + size_t count, loff_t *ppos) +{ + struct xgbe_prv_data *pdata = filp->private_data; + + return xgbe_common_write(buffer, count, ppos, + &pdata->debugfs_phydev_reg); +} + +static ssize_t phydev_reg_value_read(struct file *filp, char __user *buffer, + size_t count, loff_t *ppos) +{ + struct xgbe_prv_data *pdata = filp->private_data; + struct xgbe_phy_impl_if *phy_impl; + unsigned int value; + + phy_impl = &pdata->phy_if.phy_impl; + value = phy_impl->phydev_read(pdata, + pdata->debugfs_phydev_mmd, + pdata->debugfs_phydev_reg); + + return xgbe_common_read(buffer, count, ppos, value); +} + +static ssize_t phydev_reg_value_write(struct file *filp, + const char __user *buffer, + size_t count, loff_t *ppos) +{ + struct xgbe_prv_data *pdata = filp->private_data; + struct xgbe_phy_impl_if *phy_impl; + unsigned int value; + ssize_t len; + + len = xgbe_common_write(buffer, count, ppos, &value); + if (len < 0) + return len; + + phy_impl = &pdata->phy_if.phy_impl; + phy_impl->phydev_write(pdata, + pdata->debugfs_phydev_mmd, + pdata->debugfs_phydev_reg, + value); + + return len; +} + +static const struct file_operations phydev_mmd_fops = { + .owner = THIS_MODULE, + .open = simple_open, + .read = phydev_mmd_read, + .write = phydev_mmd_write, +}; + +static const struct file_operations phydev_reg_addr_fops = { + .owner = THIS_MODULE, + .open = simple_open, + .read = phydev_reg_addr_read, + .write = phydev_reg_addr_write, +}; + +static const struct file_operations phydev_reg_value_fops = { + .owner = THIS_MODULE, + .open = simple_open, + .read = phydev_reg_value_read, + .write = phydev_reg_value_write, +}; + void xgbe_debugfs_init(struct xgbe_prv_data *pdata) { struct dentry *pfile; @@ -445,6 +565,8 @@ void xgbe_debugfs_init(struct xgbe_prv_data *pdata) pdata->debugfs_xgmac_reg = 0; pdata->debugfs_xpcs_mmd = 1; pdata->debugfs_xpcs_reg = 0; + pdata->debugfs_phydev_mmd = 1; + pdata->debugfs_phydev_reg = 0; buf = kasprintf(GFP_KERNEL, "amd-xgbe-%s", pdata->netdev->name); if (!buf) @@ -519,6 +641,35 @@ void xgbe_debugfs_init(struct xgbe_prv_data *pdata) "debugfs_create_file failed\n"); } + if (pdata->phy_if.phy_impl.sfp_eeprom) { + pfile = debugfs_create_file("sfp_eeprom", 0400, + pdata->xgbe_debugfs, pdata, + &sfp_eeprom_fops); + if (!pfile) + netdev_err(pdata->netdev, "debugfs_create_file failed\n"); + } + + if (pdata->phy_if.phy_impl.phydev_read && + pdata->phy_if.phy_impl.phydev_write) { + pfile = debugfs_create_file("phydev_mmd", 0600, + pdata->xgbe_debugfs, pdata, + &phydev_mmd_fops); + if (!pfile) + netdev_err(pdata->netdev, "debugfs_create_file failed\n"); + + pfile = debugfs_create_file("phydev_register", 0600, + pdata->xgbe_debugfs, pdata, + &phydev_reg_addr_fops); + if (!pfile) + netdev_err(pdata->netdev, "debugfs_create_file failed\n"); + + pfile = debugfs_create_file("phydev_register_value", 0600, + pdata->xgbe_debugfs, pdata, + &phydev_reg_value_fops); + if (!pfile) + netdev_err(pdata->netdev, "debugfs_create_file failed\n"); + } + kfree(buf); } diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-phy-v2.c b/drivers/net/ethernet/amd/xgbe/xgbe-phy-v2.c index 81c45fa..4463487 100644 --- a/drivers/net/ethernet/amd/xgbe/xgbe-phy-v2.c +++ b/drivers/net/ethernet/amd/xgbe/xgbe-phy-v2.c @@ -258,6 +258,8 @@ struct xgbe_sfp_eeprom { u8 vendor[32]; }; +#define XGBE_SFP_EEPROM_LINE 16 + #define XGBE_BEL_FUSE_VENDOR "BEL-FUSE " #define XGBE_BEL_FUSE_PARTNO "1GBT-SFP06 " @@ -1275,6 +1277,79 @@ static void xgbe_phy_sfp_detect(struct xgbe_prv_data *pdata) xgbe_phy_put_comm_ownership(pdata); } +static int xgbe_phy_phydev_write(struct xgbe_prv_data *pdata, unsigned int mmd, + unsigned int reg, unsigned int val) +{ + struct xgbe_phy_data *phy_data = pdata->phy_data; + unsigned int ret; + + if (!phy_data->phydev) + return -ENOTSUPP; + + if (phy_data->phydev_mode == XGBE_MDIO_MODE_CL45) + reg = MII_ADDR_C45 | (mmd << 16) | (reg & 0xffff); + + ret = xgbe_phy_mii_write(phy_data->mii, phy_data->mdio_addr, reg, val); + + return ret; +} + +static int xgbe_phy_phydev_read(struct xgbe_prv_data *pdata, unsigned int mmd, + unsigned int reg) +{ + struct xgbe_phy_data *phy_data = pdata->phy_data; + unsigned int ret; + + if (!phy_data->phydev) + return -ENOTSUPP; + + if (phy_data->phydev_mode == XGBE_MDIO_MODE_CL45) + reg = MII_ADDR_C45 | (mmd << 16) | (reg & 0xffff); + + ret = xgbe_phy_mii_read(phy_data->mii, phy_data->mdio_addr, reg); + + return ret; +} + +static unsigned char *xgbe_phy_sfp_eeprom(struct xgbe_prv_data *pdata) +{ + struct xgbe_phy_data *phy_data = pdata->phy_data; + unsigned char *eeprom, *eeprom_end; + char *buffer, *cur; + size_t size; + + /* Calculate the buffer needed for hex_dump_to_buffer() + * assuming XGBE_SFP_EEPROM_LINE bytes per line and ASCII data: + * sizeof(struct xgbe_sfp_eeprom) * 3 for the hex output + * sizeof(struct xgbe_sfp_eeprom) for the ASCII output + * sizeof(struct xgbe_sfp_eeprom) + * / XGBE_SFP_EEPROM_LINE * 4 for extra spaces and newlines + */ + size = (sizeof(struct xgbe_sfp_eeprom) * 4) + + (sizeof(struct xgbe_sfp_eeprom) / XGBE_SFP_EEPROM_LINE * 4); + buffer = kzalloc(size, GFP_ATOMIC); + if (!buffer) + return NULL; + + cur = buffer; + eeprom = (unsigned char *)&phy_data->sfp_eeprom; + eeprom_end = eeprom + sizeof(struct xgbe_sfp_eeprom); + for (; eeprom < eeprom_end; eeprom += XGBE_SFP_EEPROM_LINE) { + hex_dump_to_buffer(eeprom, XGBE_SFP_EEPROM_LINE, + XGBE_SFP_EEPROM_LINE, 1, cur, size, true); + + /* Reduce size by new string length (including newline) */ + size -= strlen(cur); + size--; + + /* Adjust buffer and add a new line */ + cur += strlen(cur); + *cur++ = '\n'; + } + + return buffer; +} + static void xgbe_phy_phydev_flowctrl(struct xgbe_prv_data *pdata) { struct xgbe_phy_data *phy_data = pdata->phy_data; @@ -2744,6 +2819,7 @@ static void xgbe_phy_exit(struct xgbe_prv_data *pdata) static int xgbe_phy_init(struct xgbe_prv_data *pdata) { + struct xgbe_phy_impl_if *phy_impl = &pdata->phy_if.phy_impl; struct xgbe_phy_data *phy_data; struct mii_bus *mii; unsigned int reg; @@ -2869,6 +2945,8 @@ static int xgbe_phy_init(struct xgbe_prv_data *pdata) } phy_data->phydev_mode = XGBE_MDIO_MODE_CL22; + phy_impl->phydev_read = xgbe_phy_phydev_read; + phy_impl->phydev_write = xgbe_phy_phydev_write; break; /* MDIO Base-X support */ @@ -2880,6 +2958,8 @@ static int xgbe_phy_init(struct xgbe_prv_data *pdata) phy_data->start_mode = XGBE_MODE_X; phy_data->phydev_mode = XGBE_MDIO_MODE_CL22; + phy_impl->phydev_read = xgbe_phy_phydev_read; + phy_impl->phydev_write = xgbe_phy_phydev_write; break; /* MDIO NBase-T support */ @@ -2901,6 +2981,8 @@ static int xgbe_phy_init(struct xgbe_prv_data *pdata) } phy_data->phydev_mode = XGBE_MDIO_MODE_CL45; + phy_impl->phydev_read = xgbe_phy_phydev_read; + phy_impl->phydev_write = xgbe_phy_phydev_write; break; /* 10GBase-T support */ @@ -2922,6 +3004,8 @@ static int xgbe_phy_init(struct xgbe_prv_data *pdata) } phy_data->phydev_mode = XGBE_MDIO_MODE_CL45; + phy_impl->phydev_read = xgbe_phy_phydev_read; + phy_impl->phydev_write = xgbe_phy_phydev_write; break; /* 10GBase-R support */ @@ -2957,8 +3041,11 @@ static int xgbe_phy_init(struct xgbe_prv_data *pdata) } phy_data->phydev_mode = XGBE_MDIO_MODE_CL22; + phy_impl->phydev_read = xgbe_phy_phydev_read; + phy_impl->phydev_write = xgbe_phy_phydev_write; xgbe_phy_sfp_setup(pdata); + phy_impl->sfp_eeprom = xgbe_phy_sfp_eeprom; break; default: return -EINVAL; diff --git a/drivers/net/ethernet/amd/xgbe/xgbe.h b/drivers/net/ethernet/amd/xgbe/xgbe.h index e9282c9..8a3fb9d 100644 --- a/drivers/net/ethernet/amd/xgbe/xgbe.h +++ b/drivers/net/ethernet/amd/xgbe/xgbe.h @@ -776,6 +776,7 @@ struct xgbe_hw_if { * implementation of a PHY. All routines are required unless noted below. * Optional routines: * kr_training_pre, kr_training_post + * eeprom_data, phydev_read, phydev_write */ struct xgbe_phy_impl_if { /* Perform Setup/teardown actions */ @@ -819,6 +820,14 @@ struct xgbe_phy_impl_if { /* Pre/Post KR training enablement support */ void (*kr_training_pre)(struct xgbe_prv_data *); void (*kr_training_post)(struct xgbe_prv_data *); + + /* Return the eeprom data for an SFP */ + unsigned char *(*sfp_eeprom)(struct xgbe_prv_data *); + + /* Read the register of an attached PHY device */ + int (*phydev_read)(struct xgbe_prv_data *, unsigned int, unsigned int); + int (*phydev_write)(struct xgbe_prv_data *, unsigned int, unsigned int, + unsigned int); }; struct xgbe_phy_if { @@ -1183,6 +1192,9 @@ struct xgbe_prv_data { unsigned int debugfs_xprop_reg; unsigned int debugfs_xi2c_reg; + + unsigned int debugfs_phydev_mmd; + unsigned int debugfs_phydev_reg; #endif };