18c2ecf20Sopenharmony_ci/* 28c2ecf20Sopenharmony_ci * AMD 10Gb Ethernet driver 38c2ecf20Sopenharmony_ci * 48c2ecf20Sopenharmony_ci * This file is available to you under your choice of the following two 58c2ecf20Sopenharmony_ci * licenses: 68c2ecf20Sopenharmony_ci * 78c2ecf20Sopenharmony_ci * License 1: GPLv2 88c2ecf20Sopenharmony_ci * 98c2ecf20Sopenharmony_ci * Copyright (c) 2014 Advanced Micro Devices, Inc. 108c2ecf20Sopenharmony_ci * 118c2ecf20Sopenharmony_ci * This file is free software; you may copy, redistribute and/or modify 128c2ecf20Sopenharmony_ci * it under the terms of the GNU General Public License as published by 138c2ecf20Sopenharmony_ci * the Free Software Foundation, either version 2 of the License, or (at 148c2ecf20Sopenharmony_ci * your option) any later version. 158c2ecf20Sopenharmony_ci * 168c2ecf20Sopenharmony_ci * This file is distributed in the hope that it will be useful, but 178c2ecf20Sopenharmony_ci * WITHOUT ANY WARRANTY; without even the implied warranty of 188c2ecf20Sopenharmony_ci * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 198c2ecf20Sopenharmony_ci * General Public License for more details. 208c2ecf20Sopenharmony_ci * 218c2ecf20Sopenharmony_ci * You should have received a copy of the GNU General Public License 228c2ecf20Sopenharmony_ci * along with this program. If not, see <http://www.gnu.org/licenses/>. 238c2ecf20Sopenharmony_ci * 248c2ecf20Sopenharmony_ci * This file incorporates work covered by the following copyright and 258c2ecf20Sopenharmony_ci * permission notice: 268c2ecf20Sopenharmony_ci * The Synopsys DWC ETHER XGMAC Software Driver and documentation 278c2ecf20Sopenharmony_ci * (hereinafter "Software") is an unsupported proprietary work of Synopsys, 288c2ecf20Sopenharmony_ci * Inc. unless otherwise expressly agreed to in writing between Synopsys 298c2ecf20Sopenharmony_ci * and you. 308c2ecf20Sopenharmony_ci * 318c2ecf20Sopenharmony_ci * The Software IS NOT an item of Licensed Software or Licensed Product 328c2ecf20Sopenharmony_ci * under any End User Software License Agreement or Agreement for Licensed 338c2ecf20Sopenharmony_ci * Product with Synopsys or any supplement thereto. Permission is hereby 348c2ecf20Sopenharmony_ci * granted, free of charge, to any person obtaining a copy of this software 358c2ecf20Sopenharmony_ci * annotated with this license and the Software, to deal in the Software 368c2ecf20Sopenharmony_ci * without restriction, including without limitation the rights to use, 378c2ecf20Sopenharmony_ci * copy, modify, merge, publish, distribute, sublicense, and/or sell copies 388c2ecf20Sopenharmony_ci * of the Software, and to permit persons to whom the Software is furnished 398c2ecf20Sopenharmony_ci * to do so, subject to the following conditions: 408c2ecf20Sopenharmony_ci * 418c2ecf20Sopenharmony_ci * The above copyright notice and this permission notice shall be included 428c2ecf20Sopenharmony_ci * in all copies or substantial portions of the Software. 438c2ecf20Sopenharmony_ci * 448c2ecf20Sopenharmony_ci * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" 458c2ecf20Sopenharmony_ci * BASIS AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 468c2ecf20Sopenharmony_ci * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 478c2ecf20Sopenharmony_ci * PARTICULAR PURPOSE ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS 488c2ecf20Sopenharmony_ci * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 498c2ecf20Sopenharmony_ci * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 508c2ecf20Sopenharmony_ci * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 518c2ecf20Sopenharmony_ci * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 528c2ecf20Sopenharmony_ci * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 538c2ecf20Sopenharmony_ci * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 548c2ecf20Sopenharmony_ci * THE POSSIBILITY OF SUCH DAMAGE. 558c2ecf20Sopenharmony_ci * 568c2ecf20Sopenharmony_ci * 578c2ecf20Sopenharmony_ci * License 2: Modified BSD 588c2ecf20Sopenharmony_ci * 598c2ecf20Sopenharmony_ci * Copyright (c) 2014 Advanced Micro Devices, Inc. 608c2ecf20Sopenharmony_ci * All rights reserved. 618c2ecf20Sopenharmony_ci * 628c2ecf20Sopenharmony_ci * Redistribution and use in source and binary forms, with or without 638c2ecf20Sopenharmony_ci * modification, are permitted provided that the following conditions are met: 648c2ecf20Sopenharmony_ci * * Redistributions of source code must retain the above copyright 658c2ecf20Sopenharmony_ci * notice, this list of conditions and the following disclaimer. 668c2ecf20Sopenharmony_ci * * Redistributions in binary form must reproduce the above copyright 678c2ecf20Sopenharmony_ci * notice, this list of conditions and the following disclaimer in the 688c2ecf20Sopenharmony_ci * documentation and/or other materials provided with the distribution. 698c2ecf20Sopenharmony_ci * * Neither the name of Advanced Micro Devices, Inc. nor the 708c2ecf20Sopenharmony_ci * names of its contributors may be used to endorse or promote products 718c2ecf20Sopenharmony_ci * derived from this software without specific prior written permission. 728c2ecf20Sopenharmony_ci * 738c2ecf20Sopenharmony_ci * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 748c2ecf20Sopenharmony_ci * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 758c2ecf20Sopenharmony_ci * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 768c2ecf20Sopenharmony_ci * ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY 778c2ecf20Sopenharmony_ci * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 788c2ecf20Sopenharmony_ci * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 798c2ecf20Sopenharmony_ci * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 808c2ecf20Sopenharmony_ci * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 818c2ecf20Sopenharmony_ci * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 828c2ecf20Sopenharmony_ci * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 838c2ecf20Sopenharmony_ci * 848c2ecf20Sopenharmony_ci * This file incorporates work covered by the following copyright and 858c2ecf20Sopenharmony_ci * permission notice: 868c2ecf20Sopenharmony_ci * The Synopsys DWC ETHER XGMAC Software Driver and documentation 878c2ecf20Sopenharmony_ci * (hereinafter "Software") is an unsupported proprietary work of Synopsys, 888c2ecf20Sopenharmony_ci * Inc. unless otherwise expressly agreed to in writing between Synopsys 898c2ecf20Sopenharmony_ci * and you. 908c2ecf20Sopenharmony_ci * 918c2ecf20Sopenharmony_ci * The Software IS NOT an item of Licensed Software or Licensed Product 928c2ecf20Sopenharmony_ci * under any End User Software License Agreement or Agreement for Licensed 938c2ecf20Sopenharmony_ci * Product with Synopsys or any supplement thereto. Permission is hereby 948c2ecf20Sopenharmony_ci * granted, free of charge, to any person obtaining a copy of this software 958c2ecf20Sopenharmony_ci * annotated with this license and the Software, to deal in the Software 968c2ecf20Sopenharmony_ci * without restriction, including without limitation the rights to use, 978c2ecf20Sopenharmony_ci * copy, modify, merge, publish, distribute, sublicense, and/or sell copies 988c2ecf20Sopenharmony_ci * of the Software, and to permit persons to whom the Software is furnished 998c2ecf20Sopenharmony_ci * to do so, subject to the following conditions: 1008c2ecf20Sopenharmony_ci * 1018c2ecf20Sopenharmony_ci * The above copyright notice and this permission notice shall be included 1028c2ecf20Sopenharmony_ci * in all copies or substantial portions of the Software. 1038c2ecf20Sopenharmony_ci * 1048c2ecf20Sopenharmony_ci * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" 1058c2ecf20Sopenharmony_ci * BASIS AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 1068c2ecf20Sopenharmony_ci * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 1078c2ecf20Sopenharmony_ci * PARTICULAR PURPOSE ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS 1088c2ecf20Sopenharmony_ci * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 1098c2ecf20Sopenharmony_ci * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 1108c2ecf20Sopenharmony_ci * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 1118c2ecf20Sopenharmony_ci * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 1128c2ecf20Sopenharmony_ci * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 1138c2ecf20Sopenharmony_ci * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 1148c2ecf20Sopenharmony_ci * THE POSSIBILITY OF SUCH DAMAGE. 1158c2ecf20Sopenharmony_ci */ 1168c2ecf20Sopenharmony_ci 1178c2ecf20Sopenharmony_ci#include <linux/debugfs.h> 1188c2ecf20Sopenharmony_ci#include <linux/module.h> 1198c2ecf20Sopenharmony_ci#include <linux/slab.h> 1208c2ecf20Sopenharmony_ci 1218c2ecf20Sopenharmony_ci#include "xgbe.h" 1228c2ecf20Sopenharmony_ci#include "xgbe-common.h" 1238c2ecf20Sopenharmony_ci 1248c2ecf20Sopenharmony_cistatic ssize_t xgbe_common_read(char __user *buffer, size_t count, 1258c2ecf20Sopenharmony_ci loff_t *ppos, unsigned int value) 1268c2ecf20Sopenharmony_ci{ 1278c2ecf20Sopenharmony_ci char *buf; 1288c2ecf20Sopenharmony_ci ssize_t len; 1298c2ecf20Sopenharmony_ci 1308c2ecf20Sopenharmony_ci if (*ppos != 0) 1318c2ecf20Sopenharmony_ci return 0; 1328c2ecf20Sopenharmony_ci 1338c2ecf20Sopenharmony_ci buf = kasprintf(GFP_KERNEL, "0x%08x\n", value); 1348c2ecf20Sopenharmony_ci if (!buf) 1358c2ecf20Sopenharmony_ci return -ENOMEM; 1368c2ecf20Sopenharmony_ci 1378c2ecf20Sopenharmony_ci if (count < strlen(buf)) { 1388c2ecf20Sopenharmony_ci kfree(buf); 1398c2ecf20Sopenharmony_ci return -ENOSPC; 1408c2ecf20Sopenharmony_ci } 1418c2ecf20Sopenharmony_ci 1428c2ecf20Sopenharmony_ci len = simple_read_from_buffer(buffer, count, ppos, buf, strlen(buf)); 1438c2ecf20Sopenharmony_ci kfree(buf); 1448c2ecf20Sopenharmony_ci 1458c2ecf20Sopenharmony_ci return len; 1468c2ecf20Sopenharmony_ci} 1478c2ecf20Sopenharmony_ci 1488c2ecf20Sopenharmony_cistatic ssize_t xgbe_common_write(const char __user *buffer, size_t count, 1498c2ecf20Sopenharmony_ci loff_t *ppos, unsigned int *value) 1508c2ecf20Sopenharmony_ci{ 1518c2ecf20Sopenharmony_ci char workarea[32]; 1528c2ecf20Sopenharmony_ci ssize_t len; 1538c2ecf20Sopenharmony_ci int ret; 1548c2ecf20Sopenharmony_ci 1558c2ecf20Sopenharmony_ci if (*ppos != 0) 1568c2ecf20Sopenharmony_ci return -EINVAL; 1578c2ecf20Sopenharmony_ci 1588c2ecf20Sopenharmony_ci if (count >= sizeof(workarea)) 1598c2ecf20Sopenharmony_ci return -ENOSPC; 1608c2ecf20Sopenharmony_ci 1618c2ecf20Sopenharmony_ci len = simple_write_to_buffer(workarea, sizeof(workarea) - 1, ppos, 1628c2ecf20Sopenharmony_ci buffer, count); 1638c2ecf20Sopenharmony_ci if (len < 0) 1648c2ecf20Sopenharmony_ci return len; 1658c2ecf20Sopenharmony_ci 1668c2ecf20Sopenharmony_ci workarea[len] = '\0'; 1678c2ecf20Sopenharmony_ci ret = kstrtouint(workarea, 16, value); 1688c2ecf20Sopenharmony_ci if (ret) 1698c2ecf20Sopenharmony_ci return -EIO; 1708c2ecf20Sopenharmony_ci 1718c2ecf20Sopenharmony_ci return len; 1728c2ecf20Sopenharmony_ci} 1738c2ecf20Sopenharmony_ci 1748c2ecf20Sopenharmony_cistatic ssize_t xgmac_reg_addr_read(struct file *filp, char __user *buffer, 1758c2ecf20Sopenharmony_ci size_t count, loff_t *ppos) 1768c2ecf20Sopenharmony_ci{ 1778c2ecf20Sopenharmony_ci struct xgbe_prv_data *pdata = filp->private_data; 1788c2ecf20Sopenharmony_ci 1798c2ecf20Sopenharmony_ci return xgbe_common_read(buffer, count, ppos, pdata->debugfs_xgmac_reg); 1808c2ecf20Sopenharmony_ci} 1818c2ecf20Sopenharmony_ci 1828c2ecf20Sopenharmony_cistatic ssize_t xgmac_reg_addr_write(struct file *filp, 1838c2ecf20Sopenharmony_ci const char __user *buffer, 1848c2ecf20Sopenharmony_ci size_t count, loff_t *ppos) 1858c2ecf20Sopenharmony_ci{ 1868c2ecf20Sopenharmony_ci struct xgbe_prv_data *pdata = filp->private_data; 1878c2ecf20Sopenharmony_ci 1888c2ecf20Sopenharmony_ci return xgbe_common_write(buffer, count, ppos, 1898c2ecf20Sopenharmony_ci &pdata->debugfs_xgmac_reg); 1908c2ecf20Sopenharmony_ci} 1918c2ecf20Sopenharmony_ci 1928c2ecf20Sopenharmony_cistatic ssize_t xgmac_reg_value_read(struct file *filp, char __user *buffer, 1938c2ecf20Sopenharmony_ci size_t count, loff_t *ppos) 1948c2ecf20Sopenharmony_ci{ 1958c2ecf20Sopenharmony_ci struct xgbe_prv_data *pdata = filp->private_data; 1968c2ecf20Sopenharmony_ci unsigned int value; 1978c2ecf20Sopenharmony_ci 1988c2ecf20Sopenharmony_ci value = XGMAC_IOREAD(pdata, pdata->debugfs_xgmac_reg); 1998c2ecf20Sopenharmony_ci 2008c2ecf20Sopenharmony_ci return xgbe_common_read(buffer, count, ppos, value); 2018c2ecf20Sopenharmony_ci} 2028c2ecf20Sopenharmony_ci 2038c2ecf20Sopenharmony_cistatic ssize_t xgmac_reg_value_write(struct file *filp, 2048c2ecf20Sopenharmony_ci const char __user *buffer, 2058c2ecf20Sopenharmony_ci size_t count, loff_t *ppos) 2068c2ecf20Sopenharmony_ci{ 2078c2ecf20Sopenharmony_ci struct xgbe_prv_data *pdata = filp->private_data; 2088c2ecf20Sopenharmony_ci unsigned int value; 2098c2ecf20Sopenharmony_ci ssize_t len; 2108c2ecf20Sopenharmony_ci 2118c2ecf20Sopenharmony_ci len = xgbe_common_write(buffer, count, ppos, &value); 2128c2ecf20Sopenharmony_ci if (len < 0) 2138c2ecf20Sopenharmony_ci return len; 2148c2ecf20Sopenharmony_ci 2158c2ecf20Sopenharmony_ci XGMAC_IOWRITE(pdata, pdata->debugfs_xgmac_reg, value); 2168c2ecf20Sopenharmony_ci 2178c2ecf20Sopenharmony_ci return len; 2188c2ecf20Sopenharmony_ci} 2198c2ecf20Sopenharmony_ci 2208c2ecf20Sopenharmony_cistatic const struct file_operations xgmac_reg_addr_fops = { 2218c2ecf20Sopenharmony_ci .owner = THIS_MODULE, 2228c2ecf20Sopenharmony_ci .open = simple_open, 2238c2ecf20Sopenharmony_ci .read = xgmac_reg_addr_read, 2248c2ecf20Sopenharmony_ci .write = xgmac_reg_addr_write, 2258c2ecf20Sopenharmony_ci}; 2268c2ecf20Sopenharmony_ci 2278c2ecf20Sopenharmony_cistatic const struct file_operations xgmac_reg_value_fops = { 2288c2ecf20Sopenharmony_ci .owner = THIS_MODULE, 2298c2ecf20Sopenharmony_ci .open = simple_open, 2308c2ecf20Sopenharmony_ci .read = xgmac_reg_value_read, 2318c2ecf20Sopenharmony_ci .write = xgmac_reg_value_write, 2328c2ecf20Sopenharmony_ci}; 2338c2ecf20Sopenharmony_ci 2348c2ecf20Sopenharmony_cistatic ssize_t xpcs_mmd_read(struct file *filp, char __user *buffer, 2358c2ecf20Sopenharmony_ci size_t count, loff_t *ppos) 2368c2ecf20Sopenharmony_ci{ 2378c2ecf20Sopenharmony_ci struct xgbe_prv_data *pdata = filp->private_data; 2388c2ecf20Sopenharmony_ci 2398c2ecf20Sopenharmony_ci return xgbe_common_read(buffer, count, ppos, pdata->debugfs_xpcs_mmd); 2408c2ecf20Sopenharmony_ci} 2418c2ecf20Sopenharmony_ci 2428c2ecf20Sopenharmony_cistatic ssize_t xpcs_mmd_write(struct file *filp, const char __user *buffer, 2438c2ecf20Sopenharmony_ci size_t count, loff_t *ppos) 2448c2ecf20Sopenharmony_ci{ 2458c2ecf20Sopenharmony_ci struct xgbe_prv_data *pdata = filp->private_data; 2468c2ecf20Sopenharmony_ci 2478c2ecf20Sopenharmony_ci return xgbe_common_write(buffer, count, ppos, 2488c2ecf20Sopenharmony_ci &pdata->debugfs_xpcs_mmd); 2498c2ecf20Sopenharmony_ci} 2508c2ecf20Sopenharmony_ci 2518c2ecf20Sopenharmony_cistatic ssize_t xpcs_reg_addr_read(struct file *filp, char __user *buffer, 2528c2ecf20Sopenharmony_ci size_t count, loff_t *ppos) 2538c2ecf20Sopenharmony_ci{ 2548c2ecf20Sopenharmony_ci struct xgbe_prv_data *pdata = filp->private_data; 2558c2ecf20Sopenharmony_ci 2568c2ecf20Sopenharmony_ci return xgbe_common_read(buffer, count, ppos, pdata->debugfs_xpcs_reg); 2578c2ecf20Sopenharmony_ci} 2588c2ecf20Sopenharmony_ci 2598c2ecf20Sopenharmony_cistatic ssize_t xpcs_reg_addr_write(struct file *filp, const char __user *buffer, 2608c2ecf20Sopenharmony_ci size_t count, loff_t *ppos) 2618c2ecf20Sopenharmony_ci{ 2628c2ecf20Sopenharmony_ci struct xgbe_prv_data *pdata = filp->private_data; 2638c2ecf20Sopenharmony_ci 2648c2ecf20Sopenharmony_ci return xgbe_common_write(buffer, count, ppos, 2658c2ecf20Sopenharmony_ci &pdata->debugfs_xpcs_reg); 2668c2ecf20Sopenharmony_ci} 2678c2ecf20Sopenharmony_ci 2688c2ecf20Sopenharmony_cistatic ssize_t xpcs_reg_value_read(struct file *filp, char __user *buffer, 2698c2ecf20Sopenharmony_ci size_t count, loff_t *ppos) 2708c2ecf20Sopenharmony_ci{ 2718c2ecf20Sopenharmony_ci struct xgbe_prv_data *pdata = filp->private_data; 2728c2ecf20Sopenharmony_ci unsigned int value; 2738c2ecf20Sopenharmony_ci 2748c2ecf20Sopenharmony_ci value = XMDIO_READ(pdata, pdata->debugfs_xpcs_mmd, 2758c2ecf20Sopenharmony_ci pdata->debugfs_xpcs_reg); 2768c2ecf20Sopenharmony_ci 2778c2ecf20Sopenharmony_ci return xgbe_common_read(buffer, count, ppos, value); 2788c2ecf20Sopenharmony_ci} 2798c2ecf20Sopenharmony_ci 2808c2ecf20Sopenharmony_cistatic ssize_t xpcs_reg_value_write(struct file *filp, 2818c2ecf20Sopenharmony_ci const char __user *buffer, 2828c2ecf20Sopenharmony_ci size_t count, loff_t *ppos) 2838c2ecf20Sopenharmony_ci{ 2848c2ecf20Sopenharmony_ci struct xgbe_prv_data *pdata = filp->private_data; 2858c2ecf20Sopenharmony_ci unsigned int value; 2868c2ecf20Sopenharmony_ci ssize_t len; 2878c2ecf20Sopenharmony_ci 2888c2ecf20Sopenharmony_ci len = xgbe_common_write(buffer, count, ppos, &value); 2898c2ecf20Sopenharmony_ci if (len < 0) 2908c2ecf20Sopenharmony_ci return len; 2918c2ecf20Sopenharmony_ci 2928c2ecf20Sopenharmony_ci XMDIO_WRITE(pdata, pdata->debugfs_xpcs_mmd, pdata->debugfs_xpcs_reg, 2938c2ecf20Sopenharmony_ci value); 2948c2ecf20Sopenharmony_ci 2958c2ecf20Sopenharmony_ci return len; 2968c2ecf20Sopenharmony_ci} 2978c2ecf20Sopenharmony_ci 2988c2ecf20Sopenharmony_cistatic const struct file_operations xpcs_mmd_fops = { 2998c2ecf20Sopenharmony_ci .owner = THIS_MODULE, 3008c2ecf20Sopenharmony_ci .open = simple_open, 3018c2ecf20Sopenharmony_ci .read = xpcs_mmd_read, 3028c2ecf20Sopenharmony_ci .write = xpcs_mmd_write, 3038c2ecf20Sopenharmony_ci}; 3048c2ecf20Sopenharmony_ci 3058c2ecf20Sopenharmony_cistatic const struct file_operations xpcs_reg_addr_fops = { 3068c2ecf20Sopenharmony_ci .owner = THIS_MODULE, 3078c2ecf20Sopenharmony_ci .open = simple_open, 3088c2ecf20Sopenharmony_ci .read = xpcs_reg_addr_read, 3098c2ecf20Sopenharmony_ci .write = xpcs_reg_addr_write, 3108c2ecf20Sopenharmony_ci}; 3118c2ecf20Sopenharmony_ci 3128c2ecf20Sopenharmony_cistatic const struct file_operations xpcs_reg_value_fops = { 3138c2ecf20Sopenharmony_ci .owner = THIS_MODULE, 3148c2ecf20Sopenharmony_ci .open = simple_open, 3158c2ecf20Sopenharmony_ci .read = xpcs_reg_value_read, 3168c2ecf20Sopenharmony_ci .write = xpcs_reg_value_write, 3178c2ecf20Sopenharmony_ci}; 3188c2ecf20Sopenharmony_ci 3198c2ecf20Sopenharmony_cistatic ssize_t xprop_reg_addr_read(struct file *filp, char __user *buffer, 3208c2ecf20Sopenharmony_ci size_t count, loff_t *ppos) 3218c2ecf20Sopenharmony_ci{ 3228c2ecf20Sopenharmony_ci struct xgbe_prv_data *pdata = filp->private_data; 3238c2ecf20Sopenharmony_ci 3248c2ecf20Sopenharmony_ci return xgbe_common_read(buffer, count, ppos, pdata->debugfs_xprop_reg); 3258c2ecf20Sopenharmony_ci} 3268c2ecf20Sopenharmony_ci 3278c2ecf20Sopenharmony_cistatic ssize_t xprop_reg_addr_write(struct file *filp, 3288c2ecf20Sopenharmony_ci const char __user *buffer, 3298c2ecf20Sopenharmony_ci size_t count, loff_t *ppos) 3308c2ecf20Sopenharmony_ci{ 3318c2ecf20Sopenharmony_ci struct xgbe_prv_data *pdata = filp->private_data; 3328c2ecf20Sopenharmony_ci 3338c2ecf20Sopenharmony_ci return xgbe_common_write(buffer, count, ppos, 3348c2ecf20Sopenharmony_ci &pdata->debugfs_xprop_reg); 3358c2ecf20Sopenharmony_ci} 3368c2ecf20Sopenharmony_ci 3378c2ecf20Sopenharmony_cistatic ssize_t xprop_reg_value_read(struct file *filp, char __user *buffer, 3388c2ecf20Sopenharmony_ci size_t count, loff_t *ppos) 3398c2ecf20Sopenharmony_ci{ 3408c2ecf20Sopenharmony_ci struct xgbe_prv_data *pdata = filp->private_data; 3418c2ecf20Sopenharmony_ci unsigned int value; 3428c2ecf20Sopenharmony_ci 3438c2ecf20Sopenharmony_ci value = XP_IOREAD(pdata, pdata->debugfs_xprop_reg); 3448c2ecf20Sopenharmony_ci 3458c2ecf20Sopenharmony_ci return xgbe_common_read(buffer, count, ppos, value); 3468c2ecf20Sopenharmony_ci} 3478c2ecf20Sopenharmony_ci 3488c2ecf20Sopenharmony_cistatic ssize_t xprop_reg_value_write(struct file *filp, 3498c2ecf20Sopenharmony_ci const char __user *buffer, 3508c2ecf20Sopenharmony_ci size_t count, loff_t *ppos) 3518c2ecf20Sopenharmony_ci{ 3528c2ecf20Sopenharmony_ci struct xgbe_prv_data *pdata = filp->private_data; 3538c2ecf20Sopenharmony_ci unsigned int value; 3548c2ecf20Sopenharmony_ci ssize_t len; 3558c2ecf20Sopenharmony_ci 3568c2ecf20Sopenharmony_ci len = xgbe_common_write(buffer, count, ppos, &value); 3578c2ecf20Sopenharmony_ci if (len < 0) 3588c2ecf20Sopenharmony_ci return len; 3598c2ecf20Sopenharmony_ci 3608c2ecf20Sopenharmony_ci XP_IOWRITE(pdata, pdata->debugfs_xprop_reg, value); 3618c2ecf20Sopenharmony_ci 3628c2ecf20Sopenharmony_ci return len; 3638c2ecf20Sopenharmony_ci} 3648c2ecf20Sopenharmony_ci 3658c2ecf20Sopenharmony_cistatic const struct file_operations xprop_reg_addr_fops = { 3668c2ecf20Sopenharmony_ci .owner = THIS_MODULE, 3678c2ecf20Sopenharmony_ci .open = simple_open, 3688c2ecf20Sopenharmony_ci .read = xprop_reg_addr_read, 3698c2ecf20Sopenharmony_ci .write = xprop_reg_addr_write, 3708c2ecf20Sopenharmony_ci}; 3718c2ecf20Sopenharmony_ci 3728c2ecf20Sopenharmony_cistatic const struct file_operations xprop_reg_value_fops = { 3738c2ecf20Sopenharmony_ci .owner = THIS_MODULE, 3748c2ecf20Sopenharmony_ci .open = simple_open, 3758c2ecf20Sopenharmony_ci .read = xprop_reg_value_read, 3768c2ecf20Sopenharmony_ci .write = xprop_reg_value_write, 3778c2ecf20Sopenharmony_ci}; 3788c2ecf20Sopenharmony_ci 3798c2ecf20Sopenharmony_cistatic ssize_t xi2c_reg_addr_read(struct file *filp, char __user *buffer, 3808c2ecf20Sopenharmony_ci size_t count, loff_t *ppos) 3818c2ecf20Sopenharmony_ci{ 3828c2ecf20Sopenharmony_ci struct xgbe_prv_data *pdata = filp->private_data; 3838c2ecf20Sopenharmony_ci 3848c2ecf20Sopenharmony_ci return xgbe_common_read(buffer, count, ppos, pdata->debugfs_xi2c_reg); 3858c2ecf20Sopenharmony_ci} 3868c2ecf20Sopenharmony_ci 3878c2ecf20Sopenharmony_cistatic ssize_t xi2c_reg_addr_write(struct file *filp, 3888c2ecf20Sopenharmony_ci const char __user *buffer, 3898c2ecf20Sopenharmony_ci size_t count, loff_t *ppos) 3908c2ecf20Sopenharmony_ci{ 3918c2ecf20Sopenharmony_ci struct xgbe_prv_data *pdata = filp->private_data; 3928c2ecf20Sopenharmony_ci 3938c2ecf20Sopenharmony_ci return xgbe_common_write(buffer, count, ppos, 3948c2ecf20Sopenharmony_ci &pdata->debugfs_xi2c_reg); 3958c2ecf20Sopenharmony_ci} 3968c2ecf20Sopenharmony_ci 3978c2ecf20Sopenharmony_cistatic ssize_t xi2c_reg_value_read(struct file *filp, char __user *buffer, 3988c2ecf20Sopenharmony_ci size_t count, loff_t *ppos) 3998c2ecf20Sopenharmony_ci{ 4008c2ecf20Sopenharmony_ci struct xgbe_prv_data *pdata = filp->private_data; 4018c2ecf20Sopenharmony_ci unsigned int value; 4028c2ecf20Sopenharmony_ci 4038c2ecf20Sopenharmony_ci value = XI2C_IOREAD(pdata, pdata->debugfs_xi2c_reg); 4048c2ecf20Sopenharmony_ci 4058c2ecf20Sopenharmony_ci return xgbe_common_read(buffer, count, ppos, value); 4068c2ecf20Sopenharmony_ci} 4078c2ecf20Sopenharmony_ci 4088c2ecf20Sopenharmony_cistatic ssize_t xi2c_reg_value_write(struct file *filp, 4098c2ecf20Sopenharmony_ci const char __user *buffer, 4108c2ecf20Sopenharmony_ci size_t count, loff_t *ppos) 4118c2ecf20Sopenharmony_ci{ 4128c2ecf20Sopenharmony_ci struct xgbe_prv_data *pdata = filp->private_data; 4138c2ecf20Sopenharmony_ci unsigned int value; 4148c2ecf20Sopenharmony_ci ssize_t len; 4158c2ecf20Sopenharmony_ci 4168c2ecf20Sopenharmony_ci len = xgbe_common_write(buffer, count, ppos, &value); 4178c2ecf20Sopenharmony_ci if (len < 0) 4188c2ecf20Sopenharmony_ci return len; 4198c2ecf20Sopenharmony_ci 4208c2ecf20Sopenharmony_ci XI2C_IOWRITE(pdata, pdata->debugfs_xi2c_reg, value); 4218c2ecf20Sopenharmony_ci 4228c2ecf20Sopenharmony_ci return len; 4238c2ecf20Sopenharmony_ci} 4248c2ecf20Sopenharmony_ci 4258c2ecf20Sopenharmony_cistatic const struct file_operations xi2c_reg_addr_fops = { 4268c2ecf20Sopenharmony_ci .owner = THIS_MODULE, 4278c2ecf20Sopenharmony_ci .open = simple_open, 4288c2ecf20Sopenharmony_ci .read = xi2c_reg_addr_read, 4298c2ecf20Sopenharmony_ci .write = xi2c_reg_addr_write, 4308c2ecf20Sopenharmony_ci}; 4318c2ecf20Sopenharmony_ci 4328c2ecf20Sopenharmony_cistatic const struct file_operations xi2c_reg_value_fops = { 4338c2ecf20Sopenharmony_ci .owner = THIS_MODULE, 4348c2ecf20Sopenharmony_ci .open = simple_open, 4358c2ecf20Sopenharmony_ci .read = xi2c_reg_value_read, 4368c2ecf20Sopenharmony_ci .write = xi2c_reg_value_write, 4378c2ecf20Sopenharmony_ci}; 4388c2ecf20Sopenharmony_ci 4398c2ecf20Sopenharmony_civoid xgbe_debugfs_init(struct xgbe_prv_data *pdata) 4408c2ecf20Sopenharmony_ci{ 4418c2ecf20Sopenharmony_ci char *buf; 4428c2ecf20Sopenharmony_ci 4438c2ecf20Sopenharmony_ci /* Set defaults */ 4448c2ecf20Sopenharmony_ci pdata->debugfs_xgmac_reg = 0; 4458c2ecf20Sopenharmony_ci pdata->debugfs_xpcs_mmd = 1; 4468c2ecf20Sopenharmony_ci pdata->debugfs_xpcs_reg = 0; 4478c2ecf20Sopenharmony_ci 4488c2ecf20Sopenharmony_ci buf = kasprintf(GFP_KERNEL, "amd-xgbe-%s", pdata->netdev->name); 4498c2ecf20Sopenharmony_ci if (!buf) 4508c2ecf20Sopenharmony_ci return; 4518c2ecf20Sopenharmony_ci 4528c2ecf20Sopenharmony_ci pdata->xgbe_debugfs = debugfs_create_dir(buf, NULL); 4538c2ecf20Sopenharmony_ci 4548c2ecf20Sopenharmony_ci debugfs_create_file("xgmac_register", 0600, pdata->xgbe_debugfs, pdata, 4558c2ecf20Sopenharmony_ci &xgmac_reg_addr_fops); 4568c2ecf20Sopenharmony_ci 4578c2ecf20Sopenharmony_ci debugfs_create_file("xgmac_register_value", 0600, pdata->xgbe_debugfs, 4588c2ecf20Sopenharmony_ci pdata, &xgmac_reg_value_fops); 4598c2ecf20Sopenharmony_ci 4608c2ecf20Sopenharmony_ci debugfs_create_file("xpcs_mmd", 0600, pdata->xgbe_debugfs, pdata, 4618c2ecf20Sopenharmony_ci &xpcs_mmd_fops); 4628c2ecf20Sopenharmony_ci 4638c2ecf20Sopenharmony_ci debugfs_create_file("xpcs_register", 0600, pdata->xgbe_debugfs, pdata, 4648c2ecf20Sopenharmony_ci &xpcs_reg_addr_fops); 4658c2ecf20Sopenharmony_ci 4668c2ecf20Sopenharmony_ci debugfs_create_file("xpcs_register_value", 0600, pdata->xgbe_debugfs, 4678c2ecf20Sopenharmony_ci pdata, &xpcs_reg_value_fops); 4688c2ecf20Sopenharmony_ci 4698c2ecf20Sopenharmony_ci if (pdata->xprop_regs) { 4708c2ecf20Sopenharmony_ci debugfs_create_file("xprop_register", 0600, pdata->xgbe_debugfs, 4718c2ecf20Sopenharmony_ci pdata, &xprop_reg_addr_fops); 4728c2ecf20Sopenharmony_ci 4738c2ecf20Sopenharmony_ci debugfs_create_file("xprop_register_value", 0600, 4748c2ecf20Sopenharmony_ci pdata->xgbe_debugfs, pdata, 4758c2ecf20Sopenharmony_ci &xprop_reg_value_fops); 4768c2ecf20Sopenharmony_ci } 4778c2ecf20Sopenharmony_ci 4788c2ecf20Sopenharmony_ci if (pdata->xi2c_regs) { 4798c2ecf20Sopenharmony_ci debugfs_create_file("xi2c_register", 0600, pdata->xgbe_debugfs, 4808c2ecf20Sopenharmony_ci pdata, &xi2c_reg_addr_fops); 4818c2ecf20Sopenharmony_ci 4828c2ecf20Sopenharmony_ci debugfs_create_file("xi2c_register_value", 0600, 4838c2ecf20Sopenharmony_ci pdata->xgbe_debugfs, pdata, 4848c2ecf20Sopenharmony_ci &xi2c_reg_value_fops); 4858c2ecf20Sopenharmony_ci } 4868c2ecf20Sopenharmony_ci 4878c2ecf20Sopenharmony_ci if (pdata->vdata->an_cdr_workaround) { 4888c2ecf20Sopenharmony_ci debugfs_create_bool("an_cdr_workaround", 0600, 4898c2ecf20Sopenharmony_ci pdata->xgbe_debugfs, 4908c2ecf20Sopenharmony_ci &pdata->debugfs_an_cdr_workaround); 4918c2ecf20Sopenharmony_ci 4928c2ecf20Sopenharmony_ci debugfs_create_bool("an_cdr_track_early", 0600, 4938c2ecf20Sopenharmony_ci pdata->xgbe_debugfs, 4948c2ecf20Sopenharmony_ci &pdata->debugfs_an_cdr_track_early); 4958c2ecf20Sopenharmony_ci } 4968c2ecf20Sopenharmony_ci 4978c2ecf20Sopenharmony_ci kfree(buf); 4988c2ecf20Sopenharmony_ci} 4998c2ecf20Sopenharmony_ci 5008c2ecf20Sopenharmony_civoid xgbe_debugfs_exit(struct xgbe_prv_data *pdata) 5018c2ecf20Sopenharmony_ci{ 5028c2ecf20Sopenharmony_ci debugfs_remove_recursive(pdata->xgbe_debugfs); 5038c2ecf20Sopenharmony_ci pdata->xgbe_debugfs = NULL; 5048c2ecf20Sopenharmony_ci} 5058c2ecf20Sopenharmony_ci 5068c2ecf20Sopenharmony_civoid xgbe_debugfs_rename(struct xgbe_prv_data *pdata) 5078c2ecf20Sopenharmony_ci{ 5088c2ecf20Sopenharmony_ci char *buf; 5098c2ecf20Sopenharmony_ci 5108c2ecf20Sopenharmony_ci if (!pdata->xgbe_debugfs) 5118c2ecf20Sopenharmony_ci return; 5128c2ecf20Sopenharmony_ci 5138c2ecf20Sopenharmony_ci buf = kasprintf(GFP_KERNEL, "amd-xgbe-%s", pdata->netdev->name); 5148c2ecf20Sopenharmony_ci if (!buf) 5158c2ecf20Sopenharmony_ci return; 5168c2ecf20Sopenharmony_ci 5178c2ecf20Sopenharmony_ci if (!strcmp(pdata->xgbe_debugfs->d_name.name, buf)) 5188c2ecf20Sopenharmony_ci goto out; 5198c2ecf20Sopenharmony_ci 5208c2ecf20Sopenharmony_ci debugfs_rename(pdata->xgbe_debugfs->d_parent, pdata->xgbe_debugfs, 5218c2ecf20Sopenharmony_ci pdata->xgbe_debugfs->d_parent, buf); 5228c2ecf20Sopenharmony_ci 5238c2ecf20Sopenharmony_ciout: 5248c2ecf20Sopenharmony_ci kfree(buf); 5258c2ecf20Sopenharmony_ci} 526