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) 156c5aa9e3bSLendacky, Thomas return 0; 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 319*47f164deSLendacky, Thomas static ssize_t xprop_reg_addr_read(struct file *filp, char __user *buffer, 320*47f164deSLendacky, Thomas size_t count, loff_t *ppos) 321*47f164deSLendacky, Thomas { 322*47f164deSLendacky, Thomas struct xgbe_prv_data *pdata = filp->private_data; 323*47f164deSLendacky, Thomas 324*47f164deSLendacky, Thomas return xgbe_common_read(buffer, count, ppos, pdata->debugfs_xprop_reg); 325*47f164deSLendacky, Thomas } 326*47f164deSLendacky, Thomas 327*47f164deSLendacky, Thomas static ssize_t xprop_reg_addr_write(struct file *filp, 328*47f164deSLendacky, Thomas const char __user *buffer, 329*47f164deSLendacky, Thomas size_t count, loff_t *ppos) 330*47f164deSLendacky, Thomas { 331*47f164deSLendacky, Thomas struct xgbe_prv_data *pdata = filp->private_data; 332*47f164deSLendacky, Thomas 333*47f164deSLendacky, Thomas return xgbe_common_write(buffer, count, ppos, 334*47f164deSLendacky, Thomas &pdata->debugfs_xprop_reg); 335*47f164deSLendacky, Thomas } 336*47f164deSLendacky, Thomas 337*47f164deSLendacky, Thomas static ssize_t xprop_reg_value_read(struct file *filp, char __user *buffer, 338*47f164deSLendacky, Thomas size_t count, loff_t *ppos) 339*47f164deSLendacky, Thomas { 340*47f164deSLendacky, Thomas struct xgbe_prv_data *pdata = filp->private_data; 341*47f164deSLendacky, Thomas unsigned int value; 342*47f164deSLendacky, Thomas 343*47f164deSLendacky, Thomas value = XP_IOREAD(pdata, pdata->debugfs_xprop_reg); 344*47f164deSLendacky, Thomas 345*47f164deSLendacky, Thomas return xgbe_common_read(buffer, count, ppos, value); 346*47f164deSLendacky, Thomas } 347*47f164deSLendacky, Thomas 348*47f164deSLendacky, Thomas static ssize_t xprop_reg_value_write(struct file *filp, 349*47f164deSLendacky, Thomas const char __user *buffer, 350*47f164deSLendacky, Thomas size_t count, loff_t *ppos) 351*47f164deSLendacky, Thomas { 352*47f164deSLendacky, Thomas struct xgbe_prv_data *pdata = filp->private_data; 353*47f164deSLendacky, Thomas unsigned int value; 354*47f164deSLendacky, Thomas ssize_t len; 355*47f164deSLendacky, Thomas 356*47f164deSLendacky, Thomas len = xgbe_common_write(buffer, count, ppos, &value); 357*47f164deSLendacky, Thomas if (len < 0) 358*47f164deSLendacky, Thomas return len; 359*47f164deSLendacky, Thomas 360*47f164deSLendacky, Thomas XP_IOWRITE(pdata, pdata->debugfs_xprop_reg, value); 361*47f164deSLendacky, Thomas 362*47f164deSLendacky, Thomas return len; 363*47f164deSLendacky, Thomas } 364*47f164deSLendacky, Thomas 365*47f164deSLendacky, Thomas static const struct file_operations xprop_reg_addr_fops = { 366*47f164deSLendacky, Thomas .owner = THIS_MODULE, 367*47f164deSLendacky, Thomas .open = simple_open, 368*47f164deSLendacky, Thomas .read = xprop_reg_addr_read, 369*47f164deSLendacky, Thomas .write = xprop_reg_addr_write, 370*47f164deSLendacky, Thomas }; 371*47f164deSLendacky, Thomas 372*47f164deSLendacky, Thomas static const struct file_operations xprop_reg_value_fops = { 373*47f164deSLendacky, Thomas .owner = THIS_MODULE, 374*47f164deSLendacky, Thomas .open = simple_open, 375*47f164deSLendacky, Thomas .read = xprop_reg_value_read, 376*47f164deSLendacky, Thomas .write = xprop_reg_value_write, 377*47f164deSLendacky, Thomas }; 378*47f164deSLendacky, Thomas 379c5aa9e3bSLendacky, Thomas void xgbe_debugfs_init(struct xgbe_prv_data *pdata) 380c5aa9e3bSLendacky, Thomas { 381c5aa9e3bSLendacky, Thomas struct dentry *pfile; 382c5aa9e3bSLendacky, Thomas char *buf; 383c5aa9e3bSLendacky, Thomas 384c5aa9e3bSLendacky, Thomas /* Set defaults */ 385c5aa9e3bSLendacky, Thomas pdata->debugfs_xgmac_reg = 0; 386c5aa9e3bSLendacky, Thomas pdata->debugfs_xpcs_mmd = 1; 387c5aa9e3bSLendacky, Thomas pdata->debugfs_xpcs_reg = 0; 388c5aa9e3bSLendacky, Thomas 389c5aa9e3bSLendacky, Thomas buf = kasprintf(GFP_KERNEL, "amd-xgbe-%s", pdata->netdev->name); 390855591d2STom Lendacky if (!buf) 391855591d2STom Lendacky return; 392855591d2STom Lendacky 393c5aa9e3bSLendacky, Thomas pdata->xgbe_debugfs = debugfs_create_dir(buf, NULL); 3941d67d7f6SLendacky, Thomas if (!pdata->xgbe_debugfs) { 395c5aa9e3bSLendacky, Thomas netdev_err(pdata->netdev, "debugfs_create_dir failed\n"); 3969dc80a74SGeliang Tang kfree(buf); 397c5aa9e3bSLendacky, Thomas return; 398c5aa9e3bSLendacky, Thomas } 399c5aa9e3bSLendacky, Thomas 400c5aa9e3bSLendacky, Thomas pfile = debugfs_create_file("xgmac_register", 0600, 401c5aa9e3bSLendacky, Thomas pdata->xgbe_debugfs, pdata, 402c5aa9e3bSLendacky, Thomas &xgmac_reg_addr_fops); 403c5aa9e3bSLendacky, Thomas if (!pfile) 404c5aa9e3bSLendacky, Thomas netdev_err(pdata->netdev, "debugfs_create_file failed\n"); 405c5aa9e3bSLendacky, Thomas 406c5aa9e3bSLendacky, Thomas pfile = debugfs_create_file("xgmac_register_value", 0600, 407c5aa9e3bSLendacky, Thomas pdata->xgbe_debugfs, pdata, 408c5aa9e3bSLendacky, Thomas &xgmac_reg_value_fops); 409c5aa9e3bSLendacky, Thomas if (!pfile) 410c5aa9e3bSLendacky, Thomas netdev_err(pdata->netdev, "debugfs_create_file failed\n"); 411c5aa9e3bSLendacky, Thomas 412c5aa9e3bSLendacky, Thomas pfile = debugfs_create_file("xpcs_mmd", 0600, 413c5aa9e3bSLendacky, Thomas pdata->xgbe_debugfs, pdata, 414c5aa9e3bSLendacky, Thomas &xpcs_mmd_fops); 415c5aa9e3bSLendacky, Thomas if (!pfile) 416c5aa9e3bSLendacky, Thomas netdev_err(pdata->netdev, "debugfs_create_file failed\n"); 417c5aa9e3bSLendacky, Thomas 418c5aa9e3bSLendacky, Thomas pfile = debugfs_create_file("xpcs_register", 0600, 419c5aa9e3bSLendacky, Thomas pdata->xgbe_debugfs, pdata, 420c5aa9e3bSLendacky, Thomas &xpcs_reg_addr_fops); 421c5aa9e3bSLendacky, Thomas if (!pfile) 422c5aa9e3bSLendacky, Thomas netdev_err(pdata->netdev, "debugfs_create_file failed\n"); 423c5aa9e3bSLendacky, Thomas 424c5aa9e3bSLendacky, Thomas pfile = debugfs_create_file("xpcs_register_value", 0600, 425c5aa9e3bSLendacky, Thomas pdata->xgbe_debugfs, pdata, 426c5aa9e3bSLendacky, Thomas &xpcs_reg_value_fops); 427c5aa9e3bSLendacky, Thomas if (!pfile) 428c5aa9e3bSLendacky, Thomas netdev_err(pdata->netdev, "debugfs_create_file failed\n"); 429c5aa9e3bSLendacky, Thomas 430*47f164deSLendacky, Thomas if (pdata->xprop_regs) { 431*47f164deSLendacky, Thomas pfile = debugfs_create_file("xprop_register", 0600, 432*47f164deSLendacky, Thomas pdata->xgbe_debugfs, pdata, 433*47f164deSLendacky, Thomas &xprop_reg_addr_fops); 434*47f164deSLendacky, Thomas if (!pfile) 435*47f164deSLendacky, Thomas netdev_err(pdata->netdev, 436*47f164deSLendacky, Thomas "debugfs_create_file failed\n"); 437*47f164deSLendacky, Thomas 438*47f164deSLendacky, Thomas pfile = debugfs_create_file("xprop_register_value", 0600, 439*47f164deSLendacky, Thomas pdata->xgbe_debugfs, pdata, 440*47f164deSLendacky, Thomas &xprop_reg_value_fops); 441*47f164deSLendacky, Thomas if (!pfile) 442*47f164deSLendacky, Thomas netdev_err(pdata->netdev, 443*47f164deSLendacky, Thomas "debugfs_create_file failed\n"); 444*47f164deSLendacky, Thomas } 445*47f164deSLendacky, Thomas 446c5aa9e3bSLendacky, Thomas kfree(buf); 447c5aa9e3bSLendacky, Thomas } 448c5aa9e3bSLendacky, Thomas 449c5aa9e3bSLendacky, Thomas void xgbe_debugfs_exit(struct xgbe_prv_data *pdata) 450c5aa9e3bSLendacky, Thomas { 451c5aa9e3bSLendacky, Thomas debugfs_remove_recursive(pdata->xgbe_debugfs); 452c5aa9e3bSLendacky, Thomas pdata->xgbe_debugfs = NULL; 453c5aa9e3bSLendacky, Thomas } 454