1c5aa9e3bSLendacky, Thomas /* 2c5aa9e3bSLendacky, Thomas * AMD 10Gb Ethernet driver 3c5aa9e3bSLendacky, Thomas * 4c5aa9e3bSLendacky, Thomas * This file is available to you under your choice of the following two 5c5aa9e3bSLendacky, Thomas * licenses: 6c5aa9e3bSLendacky, Thomas * 7c5aa9e3bSLendacky, Thomas * License 1: GPLv2 8c5aa9e3bSLendacky, Thomas * 9c5aa9e3bSLendacky, Thomas * Copyright (c) 2014 Advanced Micro Devices, Inc. 10c5aa9e3bSLendacky, Thomas * 11c5aa9e3bSLendacky, Thomas * This file is free software; you may copy, redistribute and/or modify 12c5aa9e3bSLendacky, Thomas * it under the terms of the GNU General Public License as published by 13c5aa9e3bSLendacky, Thomas * the Free Software Foundation, either version 2 of the License, or (at 14c5aa9e3bSLendacky, Thomas * your option) any later version. 15c5aa9e3bSLendacky, Thomas * 16c5aa9e3bSLendacky, Thomas * This file is distributed in the hope that it will be useful, but 17c5aa9e3bSLendacky, Thomas * WITHOUT ANY WARRANTY; without even the implied warranty of 18c5aa9e3bSLendacky, Thomas * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 19c5aa9e3bSLendacky, Thomas * General Public License for more details. 20c5aa9e3bSLendacky, Thomas * 21c5aa9e3bSLendacky, Thomas * You should have received a copy of the GNU General Public License 22c5aa9e3bSLendacky, Thomas * along with this program. If not, see <http://www.gnu.org/licenses/>. 23c5aa9e3bSLendacky, Thomas * 24c5aa9e3bSLendacky, Thomas * This file incorporates work covered by the following copyright and 25c5aa9e3bSLendacky, Thomas * permission notice: 26c5aa9e3bSLendacky, Thomas * The Synopsys DWC ETHER XGMAC Software Driver and documentation 27c5aa9e3bSLendacky, Thomas * (hereinafter "Software") is an unsupported proprietary work of Synopsys, 28c5aa9e3bSLendacky, Thomas * Inc. unless otherwise expressly agreed to in writing between Synopsys 29c5aa9e3bSLendacky, Thomas * and you. 30c5aa9e3bSLendacky, Thomas * 31c5aa9e3bSLendacky, Thomas * The Software IS NOT an item of Licensed Software or Licensed Product 32c5aa9e3bSLendacky, Thomas * under any End User Software License Agreement or Agreement for Licensed 33c5aa9e3bSLendacky, Thomas * Product with Synopsys or any supplement thereto. Permission is hereby 34c5aa9e3bSLendacky, Thomas * granted, free of charge, to any person obtaining a copy of this software 35c5aa9e3bSLendacky, Thomas * annotated with this license and the Software, to deal in the Software 36c5aa9e3bSLendacky, Thomas * without restriction, including without limitation the rights to use, 37c5aa9e3bSLendacky, Thomas * copy, modify, merge, publish, distribute, sublicense, and/or sell copies 38c5aa9e3bSLendacky, Thomas * of the Software, and to permit persons to whom the Software is furnished 39c5aa9e3bSLendacky, Thomas * to do so, subject to the following conditions: 40c5aa9e3bSLendacky, Thomas * 41c5aa9e3bSLendacky, Thomas * The above copyright notice and this permission notice shall be included 42c5aa9e3bSLendacky, Thomas * in all copies or substantial portions of the Software. 43c5aa9e3bSLendacky, Thomas * 44c5aa9e3bSLendacky, Thomas * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" 45c5aa9e3bSLendacky, Thomas * BASIS AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 46c5aa9e3bSLendacky, Thomas * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 47c5aa9e3bSLendacky, Thomas * PARTICULAR PURPOSE ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS 48c5aa9e3bSLendacky, Thomas * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 49c5aa9e3bSLendacky, Thomas * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 50c5aa9e3bSLendacky, Thomas * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 51c5aa9e3bSLendacky, Thomas * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 52c5aa9e3bSLendacky, Thomas * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 53c5aa9e3bSLendacky, Thomas * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 54c5aa9e3bSLendacky, Thomas * THE POSSIBILITY OF SUCH DAMAGE. 55c5aa9e3bSLendacky, Thomas * 56c5aa9e3bSLendacky, Thomas * 57c5aa9e3bSLendacky, Thomas * License 2: Modified BSD 58c5aa9e3bSLendacky, Thomas * 59c5aa9e3bSLendacky, Thomas * Copyright (c) 2014 Advanced Micro Devices, Inc. 60c5aa9e3bSLendacky, Thomas * All rights reserved. 61c5aa9e3bSLendacky, Thomas * 62c5aa9e3bSLendacky, Thomas * Redistribution and use in source and binary forms, with or without 63c5aa9e3bSLendacky, Thomas * modification, are permitted provided that the following conditions are met: 64c5aa9e3bSLendacky, Thomas * * Redistributions of source code must retain the above copyright 65c5aa9e3bSLendacky, Thomas * notice, this list of conditions and the following disclaimer. 66c5aa9e3bSLendacky, Thomas * * Redistributions in binary form must reproduce the above copyright 67c5aa9e3bSLendacky, Thomas * notice, this list of conditions and the following disclaimer in the 68c5aa9e3bSLendacky, Thomas * documentation and/or other materials provided with the distribution. 69c5aa9e3bSLendacky, Thomas * * Neither the name of Advanced Micro Devices, Inc. nor the 70c5aa9e3bSLendacky, Thomas * names of its contributors may be used to endorse or promote products 71c5aa9e3bSLendacky, Thomas * derived from this software without specific prior written permission. 72c5aa9e3bSLendacky, Thomas * 73c5aa9e3bSLendacky, Thomas * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 74c5aa9e3bSLendacky, Thomas * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 75c5aa9e3bSLendacky, Thomas * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 76c5aa9e3bSLendacky, Thomas * ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY 77c5aa9e3bSLendacky, Thomas * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 78c5aa9e3bSLendacky, Thomas * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 79c5aa9e3bSLendacky, Thomas * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 80c5aa9e3bSLendacky, Thomas * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 81c5aa9e3bSLendacky, Thomas * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 82c5aa9e3bSLendacky, Thomas * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 83c5aa9e3bSLendacky, Thomas * 84c5aa9e3bSLendacky, Thomas * This file incorporates work covered by the following copyright and 85c5aa9e3bSLendacky, Thomas * permission notice: 86c5aa9e3bSLendacky, Thomas * The Synopsys DWC ETHER XGMAC Software Driver and documentation 87c5aa9e3bSLendacky, Thomas * (hereinafter "Software") is an unsupported proprietary work of Synopsys, 88c5aa9e3bSLendacky, Thomas * Inc. unless otherwise expressly agreed to in writing between Synopsys 89c5aa9e3bSLendacky, Thomas * and you. 90c5aa9e3bSLendacky, Thomas * 91c5aa9e3bSLendacky, Thomas * The Software IS NOT an item of Licensed Software or Licensed Product 92c5aa9e3bSLendacky, Thomas * under any End User Software License Agreement or Agreement for Licensed 93c5aa9e3bSLendacky, Thomas * Product with Synopsys or any supplement thereto. Permission is hereby 94c5aa9e3bSLendacky, Thomas * granted, free of charge, to any person obtaining a copy of this software 95c5aa9e3bSLendacky, Thomas * annotated with this license and the Software, to deal in the Software 96c5aa9e3bSLendacky, Thomas * without restriction, including without limitation the rights to use, 97c5aa9e3bSLendacky, Thomas * copy, modify, merge, publish, distribute, sublicense, and/or sell copies 98c5aa9e3bSLendacky, Thomas * of the Software, and to permit persons to whom the Software is furnished 99c5aa9e3bSLendacky, Thomas * to do so, subject to the following conditions: 100c5aa9e3bSLendacky, Thomas * 101c5aa9e3bSLendacky, Thomas * The above copyright notice and this permission notice shall be included 102c5aa9e3bSLendacky, Thomas * in all copies or substantial portions of the Software. 103c5aa9e3bSLendacky, Thomas * 104c5aa9e3bSLendacky, Thomas * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" 105c5aa9e3bSLendacky, Thomas * BASIS AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 106c5aa9e3bSLendacky, Thomas * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 107c5aa9e3bSLendacky, Thomas * PARTICULAR PURPOSE ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS 108c5aa9e3bSLendacky, Thomas * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 109c5aa9e3bSLendacky, Thomas * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 110c5aa9e3bSLendacky, Thomas * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 111c5aa9e3bSLendacky, Thomas * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 112c5aa9e3bSLendacky, Thomas * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 113c5aa9e3bSLendacky, Thomas * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 114c5aa9e3bSLendacky, Thomas * THE POSSIBILITY OF SUCH DAMAGE. 115c5aa9e3bSLendacky, Thomas */ 116c5aa9e3bSLendacky, Thomas 117c5aa9e3bSLendacky, Thomas #include <linux/debugfs.h> 118c5aa9e3bSLendacky, Thomas #include <linux/module.h> 119c5aa9e3bSLendacky, Thomas #include <linux/slab.h> 120c5aa9e3bSLendacky, Thomas 121c5aa9e3bSLendacky, Thomas #include "xgbe.h" 122c5aa9e3bSLendacky, Thomas #include "xgbe-common.h" 123c5aa9e3bSLendacky, Thomas 124c5aa9e3bSLendacky, Thomas static ssize_t xgbe_common_read(char __user *buffer, size_t count, 125c5aa9e3bSLendacky, Thomas loff_t *ppos, unsigned int value) 126c5aa9e3bSLendacky, Thomas { 127c5aa9e3bSLendacky, Thomas char *buf; 128c5aa9e3bSLendacky, Thomas ssize_t len; 129c5aa9e3bSLendacky, Thomas 130c5aa9e3bSLendacky, Thomas if (*ppos != 0) 131c5aa9e3bSLendacky, Thomas return 0; 132c5aa9e3bSLendacky, Thomas 133c5aa9e3bSLendacky, Thomas buf = kasprintf(GFP_KERNEL, "0x%08x\n", value); 134c5aa9e3bSLendacky, Thomas if (!buf) 135c5aa9e3bSLendacky, Thomas return -ENOMEM; 136c5aa9e3bSLendacky, Thomas 137c5aa9e3bSLendacky, Thomas if (count < strlen(buf)) { 138c5aa9e3bSLendacky, Thomas kfree(buf); 139c5aa9e3bSLendacky, Thomas return -ENOSPC; 140c5aa9e3bSLendacky, Thomas } 141c5aa9e3bSLendacky, Thomas 142c5aa9e3bSLendacky, Thomas len = simple_read_from_buffer(buffer, count, ppos, buf, strlen(buf)); 143c5aa9e3bSLendacky, Thomas kfree(buf); 144c5aa9e3bSLendacky, Thomas 145c5aa9e3bSLendacky, Thomas return len; 146c5aa9e3bSLendacky, Thomas } 147c5aa9e3bSLendacky, Thomas 148c5aa9e3bSLendacky, Thomas static ssize_t xgbe_common_write(const char __user *buffer, size_t count, 149c5aa9e3bSLendacky, Thomas loff_t *ppos, unsigned int *value) 150c5aa9e3bSLendacky, Thomas { 151c5aa9e3bSLendacky, Thomas char workarea[32]; 152c5aa9e3bSLendacky, Thomas ssize_t len; 15366f95c35SLendacky, Thomas int ret; 154c5aa9e3bSLendacky, Thomas 155c5aa9e3bSLendacky, Thomas if (*ppos != 0) 156*5e4cbaa7SLendacky, Thomas return -EINVAL; 157c5aa9e3bSLendacky, Thomas 158c5aa9e3bSLendacky, Thomas if (count >= sizeof(workarea)) 159c5aa9e3bSLendacky, Thomas return -ENOSPC; 160c5aa9e3bSLendacky, Thomas 161c5aa9e3bSLendacky, Thomas len = simple_write_to_buffer(workarea, sizeof(workarea) - 1, ppos, 162c5aa9e3bSLendacky, Thomas buffer, count); 163c5aa9e3bSLendacky, Thomas if (len < 0) 164c5aa9e3bSLendacky, Thomas return len; 165c5aa9e3bSLendacky, Thomas 166c5aa9e3bSLendacky, Thomas workarea[len] = '\0'; 167f3f128d4SLendacky, Thomas ret = kstrtouint(workarea, 16, value); 16866f95c35SLendacky, Thomas if (ret) 169f3f128d4SLendacky, Thomas return -EIO; 170c5aa9e3bSLendacky, Thomas 171c5aa9e3bSLendacky, Thomas return len; 172c5aa9e3bSLendacky, Thomas } 173c5aa9e3bSLendacky, Thomas 174c5aa9e3bSLendacky, Thomas static ssize_t xgmac_reg_addr_read(struct file *filp, char __user *buffer, 175c5aa9e3bSLendacky, Thomas size_t count, loff_t *ppos) 176c5aa9e3bSLendacky, Thomas { 177c5aa9e3bSLendacky, Thomas struct xgbe_prv_data *pdata = filp->private_data; 178c5aa9e3bSLendacky, Thomas 179c5aa9e3bSLendacky, Thomas return xgbe_common_read(buffer, count, ppos, pdata->debugfs_xgmac_reg); 180c5aa9e3bSLendacky, Thomas } 181c5aa9e3bSLendacky, Thomas 182c5aa9e3bSLendacky, Thomas static ssize_t xgmac_reg_addr_write(struct file *filp, 183c5aa9e3bSLendacky, Thomas const char __user *buffer, 184c5aa9e3bSLendacky, Thomas size_t count, loff_t *ppos) 185c5aa9e3bSLendacky, Thomas { 186c5aa9e3bSLendacky, Thomas struct xgbe_prv_data *pdata = filp->private_data; 187c5aa9e3bSLendacky, Thomas 188c5aa9e3bSLendacky, Thomas return xgbe_common_write(buffer, count, ppos, 189c5aa9e3bSLendacky, Thomas &pdata->debugfs_xgmac_reg); 190c5aa9e3bSLendacky, Thomas } 191c5aa9e3bSLendacky, Thomas 192c5aa9e3bSLendacky, Thomas static ssize_t xgmac_reg_value_read(struct file *filp, char __user *buffer, 193c5aa9e3bSLendacky, Thomas size_t count, loff_t *ppos) 194c5aa9e3bSLendacky, Thomas { 195c5aa9e3bSLendacky, Thomas struct xgbe_prv_data *pdata = filp->private_data; 196c5aa9e3bSLendacky, Thomas unsigned int value; 197c5aa9e3bSLendacky, Thomas 198c5aa9e3bSLendacky, Thomas value = XGMAC_IOREAD(pdata, pdata->debugfs_xgmac_reg); 199c5aa9e3bSLendacky, Thomas 200c5aa9e3bSLendacky, Thomas return xgbe_common_read(buffer, count, ppos, value); 201c5aa9e3bSLendacky, Thomas } 202c5aa9e3bSLendacky, Thomas 203c5aa9e3bSLendacky, Thomas static ssize_t xgmac_reg_value_write(struct file *filp, 204c5aa9e3bSLendacky, Thomas const char __user *buffer, 205c5aa9e3bSLendacky, Thomas size_t count, loff_t *ppos) 206c5aa9e3bSLendacky, Thomas { 207c5aa9e3bSLendacky, Thomas struct xgbe_prv_data *pdata = filp->private_data; 208c5aa9e3bSLendacky, Thomas unsigned int value; 209c5aa9e3bSLendacky, Thomas ssize_t len; 210c5aa9e3bSLendacky, Thomas 211c5aa9e3bSLendacky, Thomas len = xgbe_common_write(buffer, count, ppos, &value); 212c5aa9e3bSLendacky, Thomas if (len < 0) 213c5aa9e3bSLendacky, Thomas return len; 214c5aa9e3bSLendacky, Thomas 215c5aa9e3bSLendacky, Thomas XGMAC_IOWRITE(pdata, pdata->debugfs_xgmac_reg, value); 216c5aa9e3bSLendacky, Thomas 217c5aa9e3bSLendacky, Thomas return len; 218c5aa9e3bSLendacky, Thomas } 219c5aa9e3bSLendacky, Thomas 220c5aa9e3bSLendacky, Thomas static const struct file_operations xgmac_reg_addr_fops = { 221c5aa9e3bSLendacky, Thomas .owner = THIS_MODULE, 222c5aa9e3bSLendacky, Thomas .open = simple_open, 223c5aa9e3bSLendacky, Thomas .read = xgmac_reg_addr_read, 224c5aa9e3bSLendacky, Thomas .write = xgmac_reg_addr_write, 225c5aa9e3bSLendacky, Thomas }; 226c5aa9e3bSLendacky, Thomas 227c5aa9e3bSLendacky, Thomas static const struct file_operations xgmac_reg_value_fops = { 228c5aa9e3bSLendacky, Thomas .owner = THIS_MODULE, 229c5aa9e3bSLendacky, Thomas .open = simple_open, 230c5aa9e3bSLendacky, Thomas .read = xgmac_reg_value_read, 231c5aa9e3bSLendacky, Thomas .write = xgmac_reg_value_write, 232c5aa9e3bSLendacky, Thomas }; 233c5aa9e3bSLendacky, Thomas 234c5aa9e3bSLendacky, Thomas static ssize_t xpcs_mmd_read(struct file *filp, char __user *buffer, 235c5aa9e3bSLendacky, Thomas size_t count, loff_t *ppos) 236c5aa9e3bSLendacky, Thomas { 237c5aa9e3bSLendacky, Thomas struct xgbe_prv_data *pdata = filp->private_data; 238c5aa9e3bSLendacky, Thomas 239c5aa9e3bSLendacky, Thomas return xgbe_common_read(buffer, count, ppos, pdata->debugfs_xpcs_mmd); 240c5aa9e3bSLendacky, Thomas } 241c5aa9e3bSLendacky, Thomas 242c5aa9e3bSLendacky, Thomas static ssize_t xpcs_mmd_write(struct file *filp, const char __user *buffer, 243c5aa9e3bSLendacky, Thomas size_t count, loff_t *ppos) 244c5aa9e3bSLendacky, Thomas { 245c5aa9e3bSLendacky, Thomas struct xgbe_prv_data *pdata = filp->private_data; 246c5aa9e3bSLendacky, Thomas 247c5aa9e3bSLendacky, Thomas return xgbe_common_write(buffer, count, ppos, 248c5aa9e3bSLendacky, Thomas &pdata->debugfs_xpcs_mmd); 249c5aa9e3bSLendacky, Thomas } 250c5aa9e3bSLendacky, Thomas 251c5aa9e3bSLendacky, Thomas static ssize_t xpcs_reg_addr_read(struct file *filp, char __user *buffer, 252c5aa9e3bSLendacky, Thomas size_t count, loff_t *ppos) 253c5aa9e3bSLendacky, Thomas { 254c5aa9e3bSLendacky, Thomas struct xgbe_prv_data *pdata = filp->private_data; 255c5aa9e3bSLendacky, Thomas 256c5aa9e3bSLendacky, Thomas return xgbe_common_read(buffer, count, ppos, pdata->debugfs_xpcs_reg); 257c5aa9e3bSLendacky, Thomas } 258c5aa9e3bSLendacky, Thomas 259c5aa9e3bSLendacky, Thomas static ssize_t xpcs_reg_addr_write(struct file *filp, const char __user *buffer, 260c5aa9e3bSLendacky, Thomas size_t count, loff_t *ppos) 261c5aa9e3bSLendacky, Thomas { 262c5aa9e3bSLendacky, Thomas struct xgbe_prv_data *pdata = filp->private_data; 263c5aa9e3bSLendacky, Thomas 264c5aa9e3bSLendacky, Thomas return xgbe_common_write(buffer, count, ppos, 265c5aa9e3bSLendacky, Thomas &pdata->debugfs_xpcs_reg); 266c5aa9e3bSLendacky, Thomas } 267c5aa9e3bSLendacky, Thomas 268c5aa9e3bSLendacky, Thomas static ssize_t xpcs_reg_value_read(struct file *filp, char __user *buffer, 269c5aa9e3bSLendacky, Thomas size_t count, loff_t *ppos) 270c5aa9e3bSLendacky, Thomas { 271c5aa9e3bSLendacky, Thomas struct xgbe_prv_data *pdata = filp->private_data; 272c5aa9e3bSLendacky, Thomas unsigned int value; 273c5aa9e3bSLendacky, Thomas 274625c8e4aSLendacky, Thomas value = XMDIO_READ(pdata, pdata->debugfs_xpcs_mmd, 275c5aa9e3bSLendacky, Thomas pdata->debugfs_xpcs_reg); 276c5aa9e3bSLendacky, Thomas 277c5aa9e3bSLendacky, Thomas return xgbe_common_read(buffer, count, ppos, value); 278c5aa9e3bSLendacky, Thomas } 279c5aa9e3bSLendacky, Thomas 280c5aa9e3bSLendacky, Thomas static ssize_t xpcs_reg_value_write(struct file *filp, 281c5aa9e3bSLendacky, Thomas const char __user *buffer, 282c5aa9e3bSLendacky, Thomas size_t count, loff_t *ppos) 283c5aa9e3bSLendacky, Thomas { 284c5aa9e3bSLendacky, Thomas struct xgbe_prv_data *pdata = filp->private_data; 285c5aa9e3bSLendacky, Thomas unsigned int value; 286c5aa9e3bSLendacky, Thomas ssize_t len; 287c5aa9e3bSLendacky, Thomas 288c5aa9e3bSLendacky, Thomas len = xgbe_common_write(buffer, count, ppos, &value); 289c5aa9e3bSLendacky, Thomas if (len < 0) 290c5aa9e3bSLendacky, Thomas return len; 291c5aa9e3bSLendacky, Thomas 292625c8e4aSLendacky, Thomas XMDIO_WRITE(pdata, pdata->debugfs_xpcs_mmd, pdata->debugfs_xpcs_reg, 293625c8e4aSLendacky, Thomas value); 294c5aa9e3bSLendacky, Thomas 295c5aa9e3bSLendacky, Thomas return len; 296c5aa9e3bSLendacky, Thomas } 297c5aa9e3bSLendacky, Thomas 298c5aa9e3bSLendacky, Thomas static const struct file_operations xpcs_mmd_fops = { 299c5aa9e3bSLendacky, Thomas .owner = THIS_MODULE, 300c5aa9e3bSLendacky, Thomas .open = simple_open, 301c5aa9e3bSLendacky, Thomas .read = xpcs_mmd_read, 302c5aa9e3bSLendacky, Thomas .write = xpcs_mmd_write, 303c5aa9e3bSLendacky, Thomas }; 304c5aa9e3bSLendacky, Thomas 305c5aa9e3bSLendacky, Thomas static const struct file_operations xpcs_reg_addr_fops = { 306c5aa9e3bSLendacky, Thomas .owner = THIS_MODULE, 307c5aa9e3bSLendacky, Thomas .open = simple_open, 308c5aa9e3bSLendacky, Thomas .read = xpcs_reg_addr_read, 309c5aa9e3bSLendacky, Thomas .write = xpcs_reg_addr_write, 310c5aa9e3bSLendacky, Thomas }; 311c5aa9e3bSLendacky, Thomas 312c5aa9e3bSLendacky, Thomas static const struct file_operations xpcs_reg_value_fops = { 313c5aa9e3bSLendacky, Thomas .owner = THIS_MODULE, 314c5aa9e3bSLendacky, Thomas .open = simple_open, 315c5aa9e3bSLendacky, Thomas .read = xpcs_reg_value_read, 316c5aa9e3bSLendacky, Thomas .write = xpcs_reg_value_write, 317c5aa9e3bSLendacky, Thomas }; 318c5aa9e3bSLendacky, Thomas 31947f164deSLendacky, Thomas static ssize_t xprop_reg_addr_read(struct file *filp, char __user *buffer, 32047f164deSLendacky, Thomas size_t count, loff_t *ppos) 32147f164deSLendacky, Thomas { 32247f164deSLendacky, Thomas struct xgbe_prv_data *pdata = filp->private_data; 32347f164deSLendacky, Thomas 32447f164deSLendacky, Thomas return xgbe_common_read(buffer, count, ppos, pdata->debugfs_xprop_reg); 32547f164deSLendacky, Thomas } 32647f164deSLendacky, Thomas 32747f164deSLendacky, Thomas static ssize_t xprop_reg_addr_write(struct file *filp, 32847f164deSLendacky, Thomas const char __user *buffer, 32947f164deSLendacky, Thomas size_t count, loff_t *ppos) 33047f164deSLendacky, Thomas { 33147f164deSLendacky, Thomas struct xgbe_prv_data *pdata = filp->private_data; 33247f164deSLendacky, Thomas 33347f164deSLendacky, Thomas return xgbe_common_write(buffer, count, ppos, 33447f164deSLendacky, Thomas &pdata->debugfs_xprop_reg); 33547f164deSLendacky, Thomas } 33647f164deSLendacky, Thomas 33747f164deSLendacky, Thomas static ssize_t xprop_reg_value_read(struct file *filp, char __user *buffer, 33847f164deSLendacky, Thomas size_t count, loff_t *ppos) 33947f164deSLendacky, Thomas { 34047f164deSLendacky, Thomas struct xgbe_prv_data *pdata = filp->private_data; 34147f164deSLendacky, Thomas unsigned int value; 34247f164deSLendacky, Thomas 34347f164deSLendacky, Thomas value = XP_IOREAD(pdata, pdata->debugfs_xprop_reg); 34447f164deSLendacky, Thomas 34547f164deSLendacky, Thomas return xgbe_common_read(buffer, count, ppos, value); 34647f164deSLendacky, Thomas } 34747f164deSLendacky, Thomas 34847f164deSLendacky, Thomas static ssize_t xprop_reg_value_write(struct file *filp, 34947f164deSLendacky, Thomas const char __user *buffer, 35047f164deSLendacky, Thomas size_t count, loff_t *ppos) 35147f164deSLendacky, Thomas { 35247f164deSLendacky, Thomas struct xgbe_prv_data *pdata = filp->private_data; 35347f164deSLendacky, Thomas unsigned int value; 35447f164deSLendacky, Thomas ssize_t len; 35547f164deSLendacky, Thomas 35647f164deSLendacky, Thomas len = xgbe_common_write(buffer, count, ppos, &value); 35747f164deSLendacky, Thomas if (len < 0) 35847f164deSLendacky, Thomas return len; 35947f164deSLendacky, Thomas 36047f164deSLendacky, Thomas XP_IOWRITE(pdata, pdata->debugfs_xprop_reg, value); 36147f164deSLendacky, Thomas 36247f164deSLendacky, Thomas return len; 36347f164deSLendacky, Thomas } 36447f164deSLendacky, Thomas 36547f164deSLendacky, Thomas static const struct file_operations xprop_reg_addr_fops = { 36647f164deSLendacky, Thomas .owner = THIS_MODULE, 36747f164deSLendacky, Thomas .open = simple_open, 36847f164deSLendacky, Thomas .read = xprop_reg_addr_read, 36947f164deSLendacky, Thomas .write = xprop_reg_addr_write, 37047f164deSLendacky, Thomas }; 37147f164deSLendacky, Thomas 37247f164deSLendacky, Thomas static const struct file_operations xprop_reg_value_fops = { 37347f164deSLendacky, Thomas .owner = THIS_MODULE, 37447f164deSLendacky, Thomas .open = simple_open, 37547f164deSLendacky, Thomas .read = xprop_reg_value_read, 37647f164deSLendacky, Thomas .write = xprop_reg_value_write, 37747f164deSLendacky, Thomas }; 37847f164deSLendacky, Thomas 3795ab1dcd5SLendacky, Thomas static ssize_t xi2c_reg_addr_read(struct file *filp, char __user *buffer, 3805ab1dcd5SLendacky, Thomas size_t count, loff_t *ppos) 3815ab1dcd5SLendacky, Thomas { 3825ab1dcd5SLendacky, Thomas struct xgbe_prv_data *pdata = filp->private_data; 3835ab1dcd5SLendacky, Thomas 3845ab1dcd5SLendacky, Thomas return xgbe_common_read(buffer, count, ppos, pdata->debugfs_xi2c_reg); 3855ab1dcd5SLendacky, Thomas } 3865ab1dcd5SLendacky, Thomas 3875ab1dcd5SLendacky, Thomas static ssize_t xi2c_reg_addr_write(struct file *filp, 3885ab1dcd5SLendacky, Thomas const char __user *buffer, 3895ab1dcd5SLendacky, Thomas size_t count, loff_t *ppos) 3905ab1dcd5SLendacky, Thomas { 3915ab1dcd5SLendacky, Thomas struct xgbe_prv_data *pdata = filp->private_data; 3925ab1dcd5SLendacky, Thomas 3935ab1dcd5SLendacky, Thomas return xgbe_common_write(buffer, count, ppos, 3945ab1dcd5SLendacky, Thomas &pdata->debugfs_xi2c_reg); 3955ab1dcd5SLendacky, Thomas } 3965ab1dcd5SLendacky, Thomas 3975ab1dcd5SLendacky, Thomas static ssize_t xi2c_reg_value_read(struct file *filp, char __user *buffer, 3985ab1dcd5SLendacky, Thomas size_t count, loff_t *ppos) 3995ab1dcd5SLendacky, Thomas { 4005ab1dcd5SLendacky, Thomas struct xgbe_prv_data *pdata = filp->private_data; 4015ab1dcd5SLendacky, Thomas unsigned int value; 4025ab1dcd5SLendacky, Thomas 4035ab1dcd5SLendacky, Thomas value = XI2C_IOREAD(pdata, pdata->debugfs_xi2c_reg); 4045ab1dcd5SLendacky, Thomas 4055ab1dcd5SLendacky, Thomas return xgbe_common_read(buffer, count, ppos, value); 4065ab1dcd5SLendacky, Thomas } 4075ab1dcd5SLendacky, Thomas 4085ab1dcd5SLendacky, Thomas static ssize_t xi2c_reg_value_write(struct file *filp, 4095ab1dcd5SLendacky, Thomas const char __user *buffer, 4105ab1dcd5SLendacky, Thomas size_t count, loff_t *ppos) 4115ab1dcd5SLendacky, Thomas { 4125ab1dcd5SLendacky, Thomas struct xgbe_prv_data *pdata = filp->private_data; 4135ab1dcd5SLendacky, Thomas unsigned int value; 4145ab1dcd5SLendacky, Thomas ssize_t len; 4155ab1dcd5SLendacky, Thomas 4165ab1dcd5SLendacky, Thomas len = xgbe_common_write(buffer, count, ppos, &value); 4175ab1dcd5SLendacky, Thomas if (len < 0) 4185ab1dcd5SLendacky, Thomas return len; 4195ab1dcd5SLendacky, Thomas 4205ab1dcd5SLendacky, Thomas XI2C_IOWRITE(pdata, pdata->debugfs_xi2c_reg, value); 4215ab1dcd5SLendacky, Thomas 4225ab1dcd5SLendacky, Thomas return len; 4235ab1dcd5SLendacky, Thomas } 4245ab1dcd5SLendacky, Thomas 4255ab1dcd5SLendacky, Thomas static const struct file_operations xi2c_reg_addr_fops = { 4265ab1dcd5SLendacky, Thomas .owner = THIS_MODULE, 4275ab1dcd5SLendacky, Thomas .open = simple_open, 4285ab1dcd5SLendacky, Thomas .read = xi2c_reg_addr_read, 4295ab1dcd5SLendacky, Thomas .write = xi2c_reg_addr_write, 4305ab1dcd5SLendacky, Thomas }; 4315ab1dcd5SLendacky, Thomas 4325ab1dcd5SLendacky, Thomas static const struct file_operations xi2c_reg_value_fops = { 4335ab1dcd5SLendacky, Thomas .owner = THIS_MODULE, 4345ab1dcd5SLendacky, Thomas .open = simple_open, 4355ab1dcd5SLendacky, Thomas .read = xi2c_reg_value_read, 4365ab1dcd5SLendacky, Thomas .write = xi2c_reg_value_write, 4375ab1dcd5SLendacky, Thomas }; 4385ab1dcd5SLendacky, Thomas 439c5aa9e3bSLendacky, Thomas void xgbe_debugfs_init(struct xgbe_prv_data *pdata) 440c5aa9e3bSLendacky, Thomas { 441c5aa9e3bSLendacky, Thomas struct dentry *pfile; 442c5aa9e3bSLendacky, Thomas char *buf; 443c5aa9e3bSLendacky, Thomas 444c5aa9e3bSLendacky, Thomas /* Set defaults */ 445c5aa9e3bSLendacky, Thomas pdata->debugfs_xgmac_reg = 0; 446c5aa9e3bSLendacky, Thomas pdata->debugfs_xpcs_mmd = 1; 447c5aa9e3bSLendacky, Thomas pdata->debugfs_xpcs_reg = 0; 448c5aa9e3bSLendacky, Thomas 449c5aa9e3bSLendacky, Thomas buf = kasprintf(GFP_KERNEL, "amd-xgbe-%s", pdata->netdev->name); 450855591d2STom Lendacky if (!buf) 451855591d2STom Lendacky return; 452855591d2STom Lendacky 453c5aa9e3bSLendacky, Thomas pdata->xgbe_debugfs = debugfs_create_dir(buf, NULL); 4541d67d7f6SLendacky, Thomas if (!pdata->xgbe_debugfs) { 455c5aa9e3bSLendacky, Thomas netdev_err(pdata->netdev, "debugfs_create_dir failed\n"); 4569dc80a74SGeliang Tang kfree(buf); 457c5aa9e3bSLendacky, Thomas return; 458c5aa9e3bSLendacky, Thomas } 459c5aa9e3bSLendacky, Thomas 460c5aa9e3bSLendacky, Thomas pfile = debugfs_create_file("xgmac_register", 0600, 461c5aa9e3bSLendacky, Thomas pdata->xgbe_debugfs, pdata, 462c5aa9e3bSLendacky, Thomas &xgmac_reg_addr_fops); 463c5aa9e3bSLendacky, Thomas if (!pfile) 464c5aa9e3bSLendacky, Thomas netdev_err(pdata->netdev, "debugfs_create_file failed\n"); 465c5aa9e3bSLendacky, Thomas 466c5aa9e3bSLendacky, Thomas pfile = debugfs_create_file("xgmac_register_value", 0600, 467c5aa9e3bSLendacky, Thomas pdata->xgbe_debugfs, pdata, 468c5aa9e3bSLendacky, Thomas &xgmac_reg_value_fops); 469c5aa9e3bSLendacky, Thomas if (!pfile) 470c5aa9e3bSLendacky, Thomas netdev_err(pdata->netdev, "debugfs_create_file failed\n"); 471c5aa9e3bSLendacky, Thomas 472c5aa9e3bSLendacky, Thomas pfile = debugfs_create_file("xpcs_mmd", 0600, 473c5aa9e3bSLendacky, Thomas pdata->xgbe_debugfs, pdata, 474c5aa9e3bSLendacky, Thomas &xpcs_mmd_fops); 475c5aa9e3bSLendacky, Thomas if (!pfile) 476c5aa9e3bSLendacky, Thomas netdev_err(pdata->netdev, "debugfs_create_file failed\n"); 477c5aa9e3bSLendacky, Thomas 478c5aa9e3bSLendacky, Thomas pfile = debugfs_create_file("xpcs_register", 0600, 479c5aa9e3bSLendacky, Thomas pdata->xgbe_debugfs, pdata, 480c5aa9e3bSLendacky, Thomas &xpcs_reg_addr_fops); 481c5aa9e3bSLendacky, Thomas if (!pfile) 482c5aa9e3bSLendacky, Thomas netdev_err(pdata->netdev, "debugfs_create_file failed\n"); 483c5aa9e3bSLendacky, Thomas 484c5aa9e3bSLendacky, Thomas pfile = debugfs_create_file("xpcs_register_value", 0600, 485c5aa9e3bSLendacky, Thomas pdata->xgbe_debugfs, pdata, 486c5aa9e3bSLendacky, Thomas &xpcs_reg_value_fops); 487c5aa9e3bSLendacky, Thomas if (!pfile) 488c5aa9e3bSLendacky, Thomas netdev_err(pdata->netdev, "debugfs_create_file failed\n"); 489c5aa9e3bSLendacky, Thomas 49047f164deSLendacky, Thomas if (pdata->xprop_regs) { 49147f164deSLendacky, Thomas pfile = debugfs_create_file("xprop_register", 0600, 49247f164deSLendacky, Thomas pdata->xgbe_debugfs, pdata, 49347f164deSLendacky, Thomas &xprop_reg_addr_fops); 49447f164deSLendacky, Thomas if (!pfile) 49547f164deSLendacky, Thomas netdev_err(pdata->netdev, 49647f164deSLendacky, Thomas "debugfs_create_file failed\n"); 49747f164deSLendacky, Thomas 49847f164deSLendacky, Thomas pfile = debugfs_create_file("xprop_register_value", 0600, 49947f164deSLendacky, Thomas pdata->xgbe_debugfs, pdata, 50047f164deSLendacky, Thomas &xprop_reg_value_fops); 50147f164deSLendacky, Thomas if (!pfile) 50247f164deSLendacky, Thomas netdev_err(pdata->netdev, 50347f164deSLendacky, Thomas "debugfs_create_file failed\n"); 50447f164deSLendacky, Thomas } 50547f164deSLendacky, Thomas 5065ab1dcd5SLendacky, Thomas if (pdata->xi2c_regs) { 5075ab1dcd5SLendacky, Thomas pfile = debugfs_create_file("xi2c_register", 0600, 5085ab1dcd5SLendacky, Thomas pdata->xgbe_debugfs, pdata, 5095ab1dcd5SLendacky, Thomas &xi2c_reg_addr_fops); 5105ab1dcd5SLendacky, Thomas if (!pfile) 5115ab1dcd5SLendacky, Thomas netdev_err(pdata->netdev, 5125ab1dcd5SLendacky, Thomas "debugfs_create_file failed\n"); 5135ab1dcd5SLendacky, Thomas 5145ab1dcd5SLendacky, Thomas pfile = debugfs_create_file("xi2c_register_value", 0600, 5155ab1dcd5SLendacky, Thomas pdata->xgbe_debugfs, pdata, 5165ab1dcd5SLendacky, Thomas &xi2c_reg_value_fops); 5175ab1dcd5SLendacky, Thomas if (!pfile) 5185ab1dcd5SLendacky, Thomas netdev_err(pdata->netdev, 5195ab1dcd5SLendacky, Thomas "debugfs_create_file failed\n"); 5205ab1dcd5SLendacky, Thomas } 5215ab1dcd5SLendacky, Thomas 522c5aa9e3bSLendacky, Thomas kfree(buf); 523c5aa9e3bSLendacky, Thomas } 524c5aa9e3bSLendacky, Thomas 525c5aa9e3bSLendacky, Thomas void xgbe_debugfs_exit(struct xgbe_prv_data *pdata) 526c5aa9e3bSLendacky, Thomas { 527c5aa9e3bSLendacky, Thomas debugfs_remove_recursive(pdata->xgbe_debugfs); 528c5aa9e3bSLendacky, Thomas pdata->xgbe_debugfs = NULL; 529c5aa9e3bSLendacky, Thomas } 530