/* netip_subsystem_sysfs.c: * GPL LICENSE SUMMARY * * Copyright(c) 2015-2016 Intel Corporation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of version 2 of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. * The full GNU General Public License is included in this distribution * in the file called LICENSE.GPL. * * Contact Information: * Intel Corporation * 2200 Mission College Blvd. * Santa Clara, CA 97052 * */ #include #include #include #include #include #include #include #include "netip_subsystem_sysfs.h" static int netssdev_dummy_init(struct net_device *dev) { return 0; } static void netssdev_dummy_uninit(struct net_device *dev) { return; } static const struct net_device_ops dummy_netdev_ops = { .ndo_init = netssdev_dummy_init, .ndo_uninit = netssdev_dummy_uninit, }; static void dummy_setup(struct net_device *dev) { /* Initialize the device structure. */ dev->netdev_ops = &dummy_netdev_ops; dev->priv_destructor = free_netdev; } struct net_device *g_netss_netdev = NULL; static ssize_t service_show(struct device *dev, struct device_attribute *attr, char *buf) { uint32_t attribute_value = 0; ssize_t ret = 0; if (strncmp(attr->attr.name, "service_level", 13) == 0) { attribute_value = netss_get_attribute( NETSS_SERVICE_LEVEL_ATTR, NETSS_SERVICE_ID_MAX); } else if (strncmp(attr->attr.name, "service_status", 14) == 0) { attribute_value = netss_get_attribute( NETSS_SERVICE_STATE_ATTR, NETSS_SERVICE_ID_MAX); } else if (strncmp(attr->attr.name, "service_available", 17) == 0) { attribute_value = netss_get_attribute( NETSS_SERVICE_AVAILABLE_ATTR, NETSS_SERVICE_ID_MAX); } else if (strncmp(attr->attr.name, "netip_soft_off", 14) == 0) { attribute_value = netss_get_attribute( NETSS_NETIP_SOFT_OFF_ATTR, 0); } else if (strncmp(attr->attr.name, "enable_debug", 12) == 0) { attribute_value = netss_get_attribute( NETSS_ENABLE_DEBUG_ATTR, 0); } else if (strncmp(attr->attr.name, "service_ready", 13) == 0) { attribute_value = netss_get_attribute( NETSS_SERVICE_READY_ATTR, NETSS_SERVICE_ID_MAX); } else if (strncmp(attr->attr.name, "boot_handshake_done", 19) == 0) { attribute_value = netss_get_attribute( NETSS_BOOT_HANDSHAKE_DONE_ATTR, 0); } else if (strncmp(attr->attr.name, "port_mapping", 12) == 0) { attribute_value = netss_get_attribute( NETSS_PORT_MAPPING_ATTR, 0); } else { ret = -EIO; } if (!ret) ret = sprintf(buf, "0x%08X\n", (unsigned int)attribute_value); return ret; } static ssize_t service_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { unsigned long attribute_value; ssize_t ret; ret = kstrtoul(buf, 0, &attribute_value); if (ret != 0) return ret; if (strncmp(attr->attr.name, "service_level", 13) == 0) { ret = netss_set_attribute(NETSS_SERVICE_LEVEL_ATTR, attribute_value, NETSS_SERVICE_ID_MAX); } else if (strncmp(attr->attr.name, "netip_soft_off", 14) == 0) { ret = netss_set_attribute(NETSS_NETIP_SOFT_OFF_ATTR, attribute_value, 0); } else if (strncmp(attr->attr.name, "enable_debug", 12) == 0) { ret = netss_set_attribute(NETSS_ENABLE_DEBUG_ATTR, attribute_value, 0); } else { ret = -EIO; } if (!ret) ret = count; return ret; } static DEVICE_ATTR(service_level, S_IWUSR, NULL, service_store); static DEVICE_ATTR(service_status, S_IRUGO, service_show, NULL); static DEVICE_ATTR(service_available, S_IRUGO, service_show, NULL); static DEVICE_ATTR(service_ready, S_IRUGO, service_show, NULL); static DEVICE_ATTR(boot_handshake_done, S_IRUGO, service_show, NULL); static DEVICE_ATTR(enable_debug, S_IRUGO|S_IWUSR, service_show, service_store); static DEVICE_ATTR(netip_soft_off, S_IRUGO|S_IWUSR, service_show, service_store); static DEVICE_ATTR(port_mapping, S_IRUGO, service_show, NULL); char *get_netss_service_name(int i) { switch (i) { case NETIP_SUBSYSTEM: return "netip_subsystem"; case NETSS_SERVICE_ID_DOCSIS: return "docsis"; case NETSS_SERVICE_ID_SPECTRAL_ANALYSIS: return "spectraAnalysis"; case NETSS_SERVICE_ID_VIDEO: return "video"; case NETSS_SERVICE_ID_VOICE: return "voice"; case NETSS_SERVICE_ID_MOCA: return "moca"; case NETSS_SERVICE_ID_BBU: return "bbu"; case NETSS_SERVICE_ID_WIFI: return "wifi"; case NETSS_SERVICE_ID_EXSW: return "exSw"; case NETSS_SERVICE_ID_SFP: return "sfp"; case NETSS_SERVICE_ID_SGMII1_BARE: return "sgmii1_bare"; case NETSS_SERVICE_ID_ETHPHY: return "ethphy"; case NETSS_SERVICE_ID_RGMII3_BARE: return "rgmii3_bare"; case NETSS_SERVICE_ID_SGMII0_BARE: return "sgmii0_bare"; case NETSS_SERVICE_ID_RGMII2_BARE: return "rgmii2_bare"; default: return ""; } } static int __init netss_sysfs_create_netip_attributes(void) { int ret; g_netss_netdev = alloc_netdev(0, get_netss_service_name(0), NET_NAME_PREDICTABLE, dummy_setup); if (!g_netss_netdev) { return -ENOMEM; } else { ret = register_netdevice(g_netss_netdev); if (ret < 0) { free_netdev(g_netss_netdev); return ret; } ret = device_create_file(&g_netss_netdev->dev, &dev_attr_service_level); if (ret < 0) return ret; ret = device_create_file(&g_netss_netdev->dev, &dev_attr_service_status); if (ret < 0) return ret; ret = device_create_file(&g_netss_netdev->dev, &dev_attr_service_available); if (ret < 0) return ret; ret = device_create_file(&g_netss_netdev->dev, &dev_attr_netip_soft_off); if (ret < 0) return ret; ret = device_create_file(&g_netss_netdev->dev, &dev_attr_enable_debug); if (ret < 0) return ret; ret = device_create_file(&g_netss_netdev->dev, &dev_attr_service_ready); if (ret < 0) return ret; ret = device_create_file(&g_netss_netdev->dev, &dev_attr_boot_handshake_done); if (ret < 0) return ret; ret = device_create_file(&g_netss_netdev->dev, &dev_attr_port_mapping); } return ret; } static int __init netss_sysfs_init_module(void) { int err = 0; rtnl_lock(); g_netss_netdev = NULL; err = netss_sysfs_create_netip_attributes(); rtnl_unlock(); return err; } static void __exit netss_sysfs_cleanup_module(void) { if (g_netss_netdev != NULL) { unregister_netdevice(g_netss_netdev); free_netdev(g_netss_netdev); g_netss_netdev = NULL; } } module_init(netss_sysfs_init_module); module_exit(netss_sysfs_cleanup_module); MODULE_DESCRIPTION("Intel(R) NET SUBSYSTEM sysfs Driver"); MODULE_AUTHOR("Intel Corporation"); MODULE_LICENSE("GPL");