1/* 2 * drivers/net/ethernet/freescale/gianfar_sysfs.c 3 * 4 * Gianfar Ethernet Driver 5 * This driver is designed for the non-CPM ethernet controllers 6 * on the 85xx and 83xx family of integrated processors 7 * Based on 8260_io/fcc_enet.c 8 * 9 * Author: Andy Fleming 10 * Maintainer: Kumar Gala (galak@kernel.crashing.org) 11 * Modifier: Sandeep Gopalpet <sandeep.kumar@freescale.com> 12 * 13 * Copyright 2002-2009 Freescale Semiconductor, Inc. 14 * 15 * This program is free software; you can redistribute it and/or modify it 16 * under the terms of the GNU General Public License as published by the 17 * Free Software Foundation; either version 2 of the License, or (at your 18 * option) any later version. 19 * 20 * Sysfs file creation and management 21 */ 22 23#include <linux/kernel.h> 24#include <linux/string.h> 25#include <linux/errno.h> 26#include <linux/unistd.h> 27#include <linux/init.h> 28#include <linux/delay.h> 29#include <linux/etherdevice.h> 30#include <linux/spinlock.h> 31#include <linux/mm.h> 32#include <linux/device.h> 33 34#include <asm/uaccess.h> 35#include <linux/module.h> 36 37#include "gianfar.h" 38 39static ssize_t gfar_show_bd_stash(struct device *dev, 40 struct device_attribute *attr, char *buf) 41{ 42 struct gfar_private *priv = netdev_priv(to_net_dev(dev)); 43 44 return sprintf(buf, "%s\n", priv->bd_stash_en ? "on" : "off"); 45} 46 47static ssize_t gfar_set_bd_stash(struct device *dev, 48 struct device_attribute *attr, 49 const char *buf, size_t count) 50{ 51 struct gfar_private *priv = netdev_priv(to_net_dev(dev)); 52 struct gfar __iomem *regs = priv->gfargrp[0].regs; 53 int new_setting = 0; 54 u32 temp; 55 unsigned long flags; 56 57 if (!(priv->device_flags & FSL_GIANFAR_DEV_HAS_BD_STASHING)) 58 return count; 59 60 61 /* Find out the new setting */ 62 if (!strncmp("on", buf, count - 1) || !strncmp("1", buf, count - 1)) 63 new_setting = 1; 64 else if (!strncmp("off", buf, count - 1) || 65 !strncmp("0", buf, count - 1)) 66 new_setting = 0; 67 else 68 return count; 69 70 71 local_irq_save(flags); 72 lock_rx_qs(priv); 73 74 /* Set the new stashing value */ 75 priv->bd_stash_en = new_setting; 76 77 temp = gfar_read(®s->attr); 78 79 if (new_setting) 80 temp |= ATTR_BDSTASH; 81 else 82 temp &= ~(ATTR_BDSTASH); 83 84 gfar_write(®s->attr, temp); 85 86 unlock_rx_qs(priv); 87 local_irq_restore(flags); 88 89 return count; 90} 91 92static DEVICE_ATTR(bd_stash, 0644, gfar_show_bd_stash, gfar_set_bd_stash); 93 94static ssize_t gfar_show_rx_stash_size(struct device *dev, 95 struct device_attribute *attr, char *buf) 96{ 97 struct gfar_private *priv = netdev_priv(to_net_dev(dev)); 98 99 return sprintf(buf, "%d\n", priv->rx_stash_size); 100} 101 102static ssize_t gfar_set_rx_stash_size(struct device *dev, 103 struct device_attribute *attr, 104 const char *buf, size_t count) 105{ 106 struct gfar_private *priv = netdev_priv(to_net_dev(dev)); 107 struct gfar __iomem *regs = priv->gfargrp[0].regs; 108 unsigned int length = simple_strtoul(buf, NULL, 0); 109 u32 temp; 110 unsigned long flags; 111 112 if (!(priv->device_flags & FSL_GIANFAR_DEV_HAS_BUF_STASHING)) 113 return count; 114 115 local_irq_save(flags); 116 lock_rx_qs(priv); 117 118 if (length > priv->rx_buffer_size) 119 goto out; 120 121 if (length == priv->rx_stash_size) 122 goto out; 123 124 priv->rx_stash_size = length; 125 126 temp = gfar_read(®s->attreli); 127 temp &= ~ATTRELI_EL_MASK; 128 temp |= ATTRELI_EL(length); 129 gfar_write(®s->attreli, temp); 130 131 /* Turn stashing on/off as appropriate */ 132 temp = gfar_read(®s->attr); 133 134 if (length) 135 temp |= ATTR_BUFSTASH; 136 else 137 temp &= ~(ATTR_BUFSTASH); 138 139 gfar_write(®s->attr, temp); 140 141out: 142 unlock_rx_qs(priv); 143 local_irq_restore(flags); 144 145 return count; 146} 147 148static DEVICE_ATTR(rx_stash_size, 0644, gfar_show_rx_stash_size, 149 gfar_set_rx_stash_size); 150 151/* Stashing will only be enabled when rx_stash_size != 0 */ 152static ssize_t gfar_show_rx_stash_index(struct device *dev, 153 struct device_attribute *attr, 154 char *buf) 155{ 156 struct gfar_private *priv = netdev_priv(to_net_dev(dev)); 157 158 return sprintf(buf, "%d\n", priv->rx_stash_index); 159} 160 161static ssize_t gfar_set_rx_stash_index(struct device *dev, 162 struct device_attribute *attr, 163 const char *buf, size_t count) 164{ 165 struct gfar_private *priv = netdev_priv(to_net_dev(dev)); 166 struct gfar __iomem *regs = priv->gfargrp[0].regs; 167 unsigned short index = simple_strtoul(buf, NULL, 0); 168 u32 temp; 169 unsigned long flags; 170 171 if (!(priv->device_flags & FSL_GIANFAR_DEV_HAS_BUF_STASHING)) 172 return count; 173 174 local_irq_save(flags); 175 lock_rx_qs(priv); 176 177 if (index > priv->rx_stash_size) 178 goto out; 179 180 if (index == priv->rx_stash_index) 181 goto out; 182 183 priv->rx_stash_index = index; 184 185 temp = gfar_read(®s->attreli); 186 temp &= ~ATTRELI_EI_MASK; 187 temp |= ATTRELI_EI(index); 188 gfar_write(®s->attreli, temp); 189 190out: 191 unlock_rx_qs(priv); 192 local_irq_restore(flags); 193 194 return count; 195} 196 197static DEVICE_ATTR(rx_stash_index, 0644, gfar_show_rx_stash_index, 198 gfar_set_rx_stash_index); 199 200static ssize_t gfar_show_fifo_threshold(struct device *dev, 201 struct device_attribute *attr, 202 char *buf) 203{ 204 struct gfar_private *priv = netdev_priv(to_net_dev(dev)); 205 206 return sprintf(buf, "%d\n", priv->fifo_threshold); 207} 208 209static ssize_t gfar_set_fifo_threshold(struct device *dev, 210 struct device_attribute *attr, 211 const char *buf, size_t count) 212{ 213 struct gfar_private *priv = netdev_priv(to_net_dev(dev)); 214 struct gfar __iomem *regs = priv->gfargrp[0].regs; 215 unsigned int length = simple_strtoul(buf, NULL, 0); 216 u32 temp; 217 unsigned long flags; 218 219 if (length > GFAR_MAX_FIFO_THRESHOLD) 220 return count; 221 222 local_irq_save(flags); 223 lock_tx_qs(priv); 224 225 priv->fifo_threshold = length; 226 227 temp = gfar_read(®s->fifo_tx_thr); 228 temp &= ~FIFO_TX_THR_MASK; 229 temp |= length; 230 gfar_write(®s->fifo_tx_thr, temp); 231 232 unlock_tx_qs(priv); 233 local_irq_restore(flags); 234 235 return count; 236} 237 238static DEVICE_ATTR(fifo_threshold, 0644, gfar_show_fifo_threshold, 239 gfar_set_fifo_threshold); 240 241static ssize_t gfar_show_fifo_starve(struct device *dev, 242 struct device_attribute *attr, char *buf) 243{ 244 struct gfar_private *priv = netdev_priv(to_net_dev(dev)); 245 246 return sprintf(buf, "%d\n", priv->fifo_starve); 247} 248 249static ssize_t gfar_set_fifo_starve(struct device *dev, 250 struct device_attribute *attr, 251 const char *buf, size_t count) 252{ 253 struct gfar_private *priv = netdev_priv(to_net_dev(dev)); 254 struct gfar __iomem *regs = priv->gfargrp[0].regs; 255 unsigned int num = simple_strtoul(buf, NULL, 0); 256 u32 temp; 257 unsigned long flags; 258 259 if (num > GFAR_MAX_FIFO_STARVE) 260 return count; 261 262 local_irq_save(flags); 263 lock_tx_qs(priv); 264 265 priv->fifo_starve = num; 266 267 temp = gfar_read(®s->fifo_tx_starve); 268 temp &= ~FIFO_TX_STARVE_MASK; 269 temp |= num; 270 gfar_write(®s->fifo_tx_starve, temp); 271 272 unlock_tx_qs(priv); 273 local_irq_restore(flags); 274 275 return count; 276} 277 278static DEVICE_ATTR(fifo_starve, 0644, gfar_show_fifo_starve, 279 gfar_set_fifo_starve); 280 281static ssize_t gfar_show_fifo_starve_off(struct device *dev, 282 struct device_attribute *attr, 283 char *buf) 284{ 285 struct gfar_private *priv = netdev_priv(to_net_dev(dev)); 286 287 return sprintf(buf, "%d\n", priv->fifo_starve_off); 288} 289 290static ssize_t gfar_set_fifo_starve_off(struct device *dev, 291 struct device_attribute *attr, 292 const char *buf, size_t count) 293{ 294 struct gfar_private *priv = netdev_priv(to_net_dev(dev)); 295 struct gfar __iomem *regs = priv->gfargrp[0].regs; 296 unsigned int num = simple_strtoul(buf, NULL, 0); 297 u32 temp; 298 unsigned long flags; 299 300 if (num > GFAR_MAX_FIFO_STARVE_OFF) 301 return count; 302 303 local_irq_save(flags); 304 lock_tx_qs(priv); 305 306 priv->fifo_starve_off = num; 307 308 temp = gfar_read(®s->fifo_tx_starve_shutoff); 309 temp &= ~FIFO_TX_STARVE_OFF_MASK; 310 temp |= num; 311 gfar_write(®s->fifo_tx_starve_shutoff, temp); 312 313 unlock_tx_qs(priv); 314 local_irq_restore(flags); 315 316 return count; 317} 318 319static DEVICE_ATTR(fifo_starve_off, 0644, gfar_show_fifo_starve_off, 320 gfar_set_fifo_starve_off); 321 322void gfar_init_sysfs(struct net_device *dev) 323{ 324 struct gfar_private *priv = netdev_priv(dev); 325 int rc; 326 327 /* Initialize the default values */ 328 priv->fifo_threshold = DEFAULT_FIFO_TX_THR; 329 priv->fifo_starve = DEFAULT_FIFO_TX_STARVE; 330 priv->fifo_starve_off = DEFAULT_FIFO_TX_STARVE_OFF; 331 332 /* Create our sysfs files */ 333 rc = device_create_file(&dev->dev, &dev_attr_bd_stash); 334 rc |= device_create_file(&dev->dev, &dev_attr_rx_stash_size); 335 rc |= device_create_file(&dev->dev, &dev_attr_rx_stash_index); 336 rc |= device_create_file(&dev->dev, &dev_attr_fifo_threshold); 337 rc |= device_create_file(&dev->dev, &dev_attr_fifo_starve); 338 rc |= device_create_file(&dev->dev, &dev_attr_fifo_starve_off); 339 if (rc) 340 dev_err(&dev->dev, "Error creating gianfar sysfs files.\n"); 341} 342