cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

xgbe-debugfs.c (16365B)


      1/*
      2 * AMD 10Gb Ethernet driver
      3 *
      4 * This file is available to you under your choice of the following two
      5 * licenses:
      6 *
      7 * License 1: GPLv2
      8 *
      9 * Copyright (c) 2014 Advanced Micro Devices, Inc.
     10 *
     11 * This file is free software; you may copy, redistribute and/or modify
     12 * it under the terms of the GNU General Public License as published by
     13 * the Free Software Foundation, either version 2 of the License, or (at
     14 * your option) any later version.
     15 *
     16 * This file is distributed in the hope that it will be useful, but
     17 * WITHOUT ANY WARRANTY; without even the implied warranty of
     18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
     19 * General Public License for more details.
     20 *
     21 * You should have received a copy of the GNU General Public License
     22 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
     23 *
     24 * This file incorporates work covered by the following copyright and
     25 * permission notice:
     26 *     The Synopsys DWC ETHER XGMAC Software Driver and documentation
     27 *     (hereinafter "Software") is an unsupported proprietary work of Synopsys,
     28 *     Inc. unless otherwise expressly agreed to in writing between Synopsys
     29 *     and you.
     30 *
     31 *     The Software IS NOT an item of Licensed Software or Licensed Product
     32 *     under any End User Software License Agreement or Agreement for Licensed
     33 *     Product with Synopsys or any supplement thereto.  Permission is hereby
     34 *     granted, free of charge, to any person obtaining a copy of this software
     35 *     annotated with this license and the Software, to deal in the Software
     36 *     without restriction, including without limitation the rights to use,
     37 *     copy, modify, merge, publish, distribute, sublicense, and/or sell copies
     38 *     of the Software, and to permit persons to whom the Software is furnished
     39 *     to do so, subject to the following conditions:
     40 *
     41 *     The above copyright notice and this permission notice shall be included
     42 *     in all copies or substantial portions of the Software.
     43 *
     44 *     THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS"
     45 *     BASIS AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     46 *     TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
     47 *     PARTICULAR PURPOSE ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS
     48 *     BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     49 *     CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     50 *     SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     51 *     INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     52 *     CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     53 *     ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
     54 *     THE POSSIBILITY OF SUCH DAMAGE.
     55 *
     56 *
     57 * License 2: Modified BSD
     58 *
     59 * Copyright (c) 2014 Advanced Micro Devices, Inc.
     60 * All rights reserved.
     61 *
     62 * Redistribution and use in source and binary forms, with or without
     63 * modification, are permitted provided that the following conditions are met:
     64 *     * Redistributions of source code must retain the above copyright
     65 *       notice, this list of conditions and the following disclaimer.
     66 *     * Redistributions in binary form must reproduce the above copyright
     67 *       notice, this list of conditions and the following disclaimer in the
     68 *       documentation and/or other materials provided with the distribution.
     69 *     * Neither the name of Advanced Micro Devices, Inc. nor the
     70 *       names of its contributors may be used to endorse or promote products
     71 *       derived from this software without specific prior written permission.
     72 *
     73 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
     74 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     75 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     76 * ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
     77 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
     78 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
     79 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
     80 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     81 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     82 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     83 *
     84 * This file incorporates work covered by the following copyright and
     85 * permission notice:
     86 *     The Synopsys DWC ETHER XGMAC Software Driver and documentation
     87 *     (hereinafter "Software") is an unsupported proprietary work of Synopsys,
     88 *     Inc. unless otherwise expressly agreed to in writing between Synopsys
     89 *     and you.
     90 *
     91 *     The Software IS NOT an item of Licensed Software or Licensed Product
     92 *     under any End User Software License Agreement or Agreement for Licensed
     93 *     Product with Synopsys or any supplement thereto.  Permission is hereby
     94 *     granted, free of charge, to any person obtaining a copy of this software
     95 *     annotated with this license and the Software, to deal in the Software
     96 *     without restriction, including without limitation the rights to use,
     97 *     copy, modify, merge, publish, distribute, sublicense, and/or sell copies
     98 *     of the Software, and to permit persons to whom the Software is furnished
     99 *     to do so, subject to the following conditions:
    100 *
    101 *     The above copyright notice and this permission notice shall be included
    102 *     in all copies or substantial portions of the Software.
    103 *
    104 *     THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS"
    105 *     BASIS AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
    106 *     TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
    107 *     PARTICULAR PURPOSE ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS
    108 *     BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
    109 *     CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
    110 *     SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
    111 *     INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
    112 *     CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
    113 *     ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
    114 *     THE POSSIBILITY OF SUCH DAMAGE.
    115 */
    116
    117#include <linux/debugfs.h>
    118#include <linux/module.h>
    119#include <linux/slab.h>
    120
    121#include "xgbe.h"
    122#include "xgbe-common.h"
    123
    124static ssize_t xgbe_common_read(char __user *buffer, size_t count,
    125				loff_t *ppos, unsigned int value)
    126{
    127	char *buf;
    128	ssize_t len;
    129
    130	if (*ppos != 0)
    131		return 0;
    132
    133	buf = kasprintf(GFP_KERNEL, "0x%08x\n", value);
    134	if (!buf)
    135		return -ENOMEM;
    136
    137	if (count < strlen(buf)) {
    138		kfree(buf);
    139		return -ENOSPC;
    140	}
    141
    142	len = simple_read_from_buffer(buffer, count, ppos, buf, strlen(buf));
    143	kfree(buf);
    144
    145	return len;
    146}
    147
    148static ssize_t xgbe_common_write(const char __user *buffer, size_t count,
    149				 loff_t *ppos, unsigned int *value)
    150{
    151	char workarea[32];
    152	ssize_t len;
    153	int ret;
    154
    155	if (*ppos != 0)
    156		return -EINVAL;
    157
    158	if (count >= sizeof(workarea))
    159		return -ENOSPC;
    160
    161	len = simple_write_to_buffer(workarea, sizeof(workarea) - 1, ppos,
    162				     buffer, count);
    163	if (len < 0)
    164		return len;
    165
    166	workarea[len] = '\0';
    167	ret = kstrtouint(workarea, 16, value);
    168	if (ret)
    169		return -EIO;
    170
    171	return len;
    172}
    173
    174static ssize_t xgmac_reg_addr_read(struct file *filp, char __user *buffer,
    175				   size_t count, loff_t *ppos)
    176{
    177	struct xgbe_prv_data *pdata = filp->private_data;
    178
    179	return xgbe_common_read(buffer, count, ppos, pdata->debugfs_xgmac_reg);
    180}
    181
    182static ssize_t xgmac_reg_addr_write(struct file *filp,
    183				    const char __user *buffer,
    184				    size_t count, loff_t *ppos)
    185{
    186	struct xgbe_prv_data *pdata = filp->private_data;
    187
    188	return xgbe_common_write(buffer, count, ppos,
    189				 &pdata->debugfs_xgmac_reg);
    190}
    191
    192static ssize_t xgmac_reg_value_read(struct file *filp, char __user *buffer,
    193				    size_t count, loff_t *ppos)
    194{
    195	struct xgbe_prv_data *pdata = filp->private_data;
    196	unsigned int value;
    197
    198	value = XGMAC_IOREAD(pdata, pdata->debugfs_xgmac_reg);
    199
    200	return xgbe_common_read(buffer, count, ppos, value);
    201}
    202
    203static ssize_t xgmac_reg_value_write(struct file *filp,
    204				     const char __user *buffer,
    205				     size_t count, loff_t *ppos)
    206{
    207	struct xgbe_prv_data *pdata = filp->private_data;
    208	unsigned int value;
    209	ssize_t len;
    210
    211	len = xgbe_common_write(buffer, count, ppos, &value);
    212	if (len < 0)
    213		return len;
    214
    215	XGMAC_IOWRITE(pdata, pdata->debugfs_xgmac_reg, value);
    216
    217	return len;
    218}
    219
    220static const struct file_operations xgmac_reg_addr_fops = {
    221	.owner = THIS_MODULE,
    222	.open = simple_open,
    223	.read =  xgmac_reg_addr_read,
    224	.write = xgmac_reg_addr_write,
    225};
    226
    227static const struct file_operations xgmac_reg_value_fops = {
    228	.owner = THIS_MODULE,
    229	.open = simple_open,
    230	.read =  xgmac_reg_value_read,
    231	.write = xgmac_reg_value_write,
    232};
    233
    234static ssize_t xpcs_mmd_read(struct file *filp, char __user *buffer,
    235			     size_t count, loff_t *ppos)
    236{
    237	struct xgbe_prv_data *pdata = filp->private_data;
    238
    239	return xgbe_common_read(buffer, count, ppos, pdata->debugfs_xpcs_mmd);
    240}
    241
    242static ssize_t xpcs_mmd_write(struct file *filp, const char __user *buffer,
    243			      size_t count, loff_t *ppos)
    244{
    245	struct xgbe_prv_data *pdata = filp->private_data;
    246
    247	return xgbe_common_write(buffer, count, ppos,
    248				 &pdata->debugfs_xpcs_mmd);
    249}
    250
    251static ssize_t xpcs_reg_addr_read(struct file *filp, char __user *buffer,
    252				  size_t count, loff_t *ppos)
    253{
    254	struct xgbe_prv_data *pdata = filp->private_data;
    255
    256	return xgbe_common_read(buffer, count, ppos, pdata->debugfs_xpcs_reg);
    257}
    258
    259static ssize_t xpcs_reg_addr_write(struct file *filp, const char __user *buffer,
    260				   size_t count, loff_t *ppos)
    261{
    262	struct xgbe_prv_data *pdata = filp->private_data;
    263
    264	return xgbe_common_write(buffer, count, ppos,
    265				 &pdata->debugfs_xpcs_reg);
    266}
    267
    268static ssize_t xpcs_reg_value_read(struct file *filp, char __user *buffer,
    269				   size_t count, loff_t *ppos)
    270{
    271	struct xgbe_prv_data *pdata = filp->private_data;
    272	unsigned int value;
    273
    274	value = XMDIO_READ(pdata, pdata->debugfs_xpcs_mmd,
    275			   pdata->debugfs_xpcs_reg);
    276
    277	return xgbe_common_read(buffer, count, ppos, value);
    278}
    279
    280static ssize_t xpcs_reg_value_write(struct file *filp,
    281				    const char __user *buffer,
    282				    size_t count, loff_t *ppos)
    283{
    284	struct xgbe_prv_data *pdata = filp->private_data;
    285	unsigned int value;
    286	ssize_t len;
    287
    288	len = xgbe_common_write(buffer, count, ppos, &value);
    289	if (len < 0)
    290		return len;
    291
    292	XMDIO_WRITE(pdata, pdata->debugfs_xpcs_mmd, pdata->debugfs_xpcs_reg,
    293		    value);
    294
    295	return len;
    296}
    297
    298static const struct file_operations xpcs_mmd_fops = {
    299	.owner = THIS_MODULE,
    300	.open = simple_open,
    301	.read =  xpcs_mmd_read,
    302	.write = xpcs_mmd_write,
    303};
    304
    305static const struct file_operations xpcs_reg_addr_fops = {
    306	.owner = THIS_MODULE,
    307	.open = simple_open,
    308	.read =  xpcs_reg_addr_read,
    309	.write = xpcs_reg_addr_write,
    310};
    311
    312static const struct file_operations xpcs_reg_value_fops = {
    313	.owner = THIS_MODULE,
    314	.open = simple_open,
    315	.read =  xpcs_reg_value_read,
    316	.write = xpcs_reg_value_write,
    317};
    318
    319static ssize_t xprop_reg_addr_read(struct file *filp, char __user *buffer,
    320				   size_t count, loff_t *ppos)
    321{
    322	struct xgbe_prv_data *pdata = filp->private_data;
    323
    324	return xgbe_common_read(buffer, count, ppos, pdata->debugfs_xprop_reg);
    325}
    326
    327static ssize_t xprop_reg_addr_write(struct file *filp,
    328				    const char __user *buffer,
    329				    size_t count, loff_t *ppos)
    330{
    331	struct xgbe_prv_data *pdata = filp->private_data;
    332
    333	return xgbe_common_write(buffer, count, ppos,
    334				 &pdata->debugfs_xprop_reg);
    335}
    336
    337static ssize_t xprop_reg_value_read(struct file *filp, char __user *buffer,
    338				    size_t count, loff_t *ppos)
    339{
    340	struct xgbe_prv_data *pdata = filp->private_data;
    341	unsigned int value;
    342
    343	value = XP_IOREAD(pdata, pdata->debugfs_xprop_reg);
    344
    345	return xgbe_common_read(buffer, count, ppos, value);
    346}
    347
    348static ssize_t xprop_reg_value_write(struct file *filp,
    349				     const char __user *buffer,
    350				     size_t count, loff_t *ppos)
    351{
    352	struct xgbe_prv_data *pdata = filp->private_data;
    353	unsigned int value;
    354	ssize_t len;
    355
    356	len = xgbe_common_write(buffer, count, ppos, &value);
    357	if (len < 0)
    358		return len;
    359
    360	XP_IOWRITE(pdata, pdata->debugfs_xprop_reg, value);
    361
    362	return len;
    363}
    364
    365static const struct file_operations xprop_reg_addr_fops = {
    366	.owner = THIS_MODULE,
    367	.open = simple_open,
    368	.read =  xprop_reg_addr_read,
    369	.write = xprop_reg_addr_write,
    370};
    371
    372static const struct file_operations xprop_reg_value_fops = {
    373	.owner = THIS_MODULE,
    374	.open = simple_open,
    375	.read =  xprop_reg_value_read,
    376	.write = xprop_reg_value_write,
    377};
    378
    379static ssize_t xi2c_reg_addr_read(struct file *filp, char __user *buffer,
    380				  size_t count, loff_t *ppos)
    381{
    382	struct xgbe_prv_data *pdata = filp->private_data;
    383
    384	return xgbe_common_read(buffer, count, ppos, pdata->debugfs_xi2c_reg);
    385}
    386
    387static ssize_t xi2c_reg_addr_write(struct file *filp,
    388				   const char __user *buffer,
    389				   size_t count, loff_t *ppos)
    390{
    391	struct xgbe_prv_data *pdata = filp->private_data;
    392
    393	return xgbe_common_write(buffer, count, ppos,
    394				 &pdata->debugfs_xi2c_reg);
    395}
    396
    397static ssize_t xi2c_reg_value_read(struct file *filp, char __user *buffer,
    398				   size_t count, loff_t *ppos)
    399{
    400	struct xgbe_prv_data *pdata = filp->private_data;
    401	unsigned int value;
    402
    403	value = XI2C_IOREAD(pdata, pdata->debugfs_xi2c_reg);
    404
    405	return xgbe_common_read(buffer, count, ppos, value);
    406}
    407
    408static ssize_t xi2c_reg_value_write(struct file *filp,
    409				    const char __user *buffer,
    410				    size_t count, loff_t *ppos)
    411{
    412	struct xgbe_prv_data *pdata = filp->private_data;
    413	unsigned int value;
    414	ssize_t len;
    415
    416	len = xgbe_common_write(buffer, count, ppos, &value);
    417	if (len < 0)
    418		return len;
    419
    420	XI2C_IOWRITE(pdata, pdata->debugfs_xi2c_reg, value);
    421
    422	return len;
    423}
    424
    425static const struct file_operations xi2c_reg_addr_fops = {
    426	.owner = THIS_MODULE,
    427	.open = simple_open,
    428	.read =  xi2c_reg_addr_read,
    429	.write = xi2c_reg_addr_write,
    430};
    431
    432static const struct file_operations xi2c_reg_value_fops = {
    433	.owner = THIS_MODULE,
    434	.open = simple_open,
    435	.read =  xi2c_reg_value_read,
    436	.write = xi2c_reg_value_write,
    437};
    438
    439void xgbe_debugfs_init(struct xgbe_prv_data *pdata)
    440{
    441	char *buf;
    442
    443	/* Set defaults */
    444	pdata->debugfs_xgmac_reg = 0;
    445	pdata->debugfs_xpcs_mmd = 1;
    446	pdata->debugfs_xpcs_reg = 0;
    447
    448	buf = kasprintf(GFP_KERNEL, "amd-xgbe-%s", pdata->netdev->name);
    449	if (!buf)
    450		return;
    451
    452	pdata->xgbe_debugfs = debugfs_create_dir(buf, NULL);
    453
    454	debugfs_create_file("xgmac_register", 0600, pdata->xgbe_debugfs, pdata,
    455			    &xgmac_reg_addr_fops);
    456
    457	debugfs_create_file("xgmac_register_value", 0600, pdata->xgbe_debugfs,
    458			    pdata, &xgmac_reg_value_fops);
    459
    460	debugfs_create_file("xpcs_mmd", 0600, pdata->xgbe_debugfs, pdata,
    461			    &xpcs_mmd_fops);
    462
    463	debugfs_create_file("xpcs_register", 0600, pdata->xgbe_debugfs, pdata,
    464			    &xpcs_reg_addr_fops);
    465
    466	debugfs_create_file("xpcs_register_value", 0600, pdata->xgbe_debugfs,
    467			    pdata, &xpcs_reg_value_fops);
    468
    469	if (pdata->xprop_regs) {
    470		debugfs_create_file("xprop_register", 0600, pdata->xgbe_debugfs,
    471				    pdata, &xprop_reg_addr_fops);
    472
    473		debugfs_create_file("xprop_register_value", 0600,
    474				    pdata->xgbe_debugfs, pdata,
    475				    &xprop_reg_value_fops);
    476	}
    477
    478	if (pdata->xi2c_regs) {
    479		debugfs_create_file("xi2c_register", 0600, pdata->xgbe_debugfs,
    480				    pdata, &xi2c_reg_addr_fops);
    481
    482		debugfs_create_file("xi2c_register_value", 0600,
    483				    pdata->xgbe_debugfs, pdata,
    484				    &xi2c_reg_value_fops);
    485	}
    486
    487	if (pdata->vdata->an_cdr_workaround) {
    488		debugfs_create_bool("an_cdr_workaround", 0600,
    489				    pdata->xgbe_debugfs,
    490				    &pdata->debugfs_an_cdr_workaround);
    491
    492		debugfs_create_bool("an_cdr_track_early", 0600,
    493				    pdata->xgbe_debugfs,
    494				    &pdata->debugfs_an_cdr_track_early);
    495	}
    496
    497	kfree(buf);
    498}
    499
    500void xgbe_debugfs_exit(struct xgbe_prv_data *pdata)
    501{
    502	debugfs_remove_recursive(pdata->xgbe_debugfs);
    503	pdata->xgbe_debugfs = NULL;
    504}
    505
    506void xgbe_debugfs_rename(struct xgbe_prv_data *pdata)
    507{
    508	char *buf;
    509
    510	if (!pdata->xgbe_debugfs)
    511		return;
    512
    513	buf = kasprintf(GFP_KERNEL, "amd-xgbe-%s", pdata->netdev->name);
    514	if (!buf)
    515		return;
    516
    517	if (!strcmp(pdata->xgbe_debugfs->d_name.name, buf))
    518		goto out;
    519
    520	debugfs_rename(pdata->xgbe_debugfs->d_parent, pdata->xgbe_debugfs,
    521		       pdata->xgbe_debugfs->d_parent, buf);
    522
    523out:
    524	kfree(buf);
    525}