Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
at v2.6.29-rc4 312 lines 8.1 kB view raw
1/* 2 * drivers/net/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 * 12 * Copyright (c) 2002-2005 Freescale Semiconductor, Inc. 13 * 14 * This program is free software; you can redistribute it and/or modify it 15 * under the terms of the GNU General Public License as published by the 16 * Free Software Foundation; either version 2 of the License, or (at your 17 * option) any later version. 18 * 19 * Sysfs file creation and management 20 */ 21 22#include <linux/kernel.h> 23#include <linux/string.h> 24#include <linux/errno.h> 25#include <linux/unistd.h> 26#include <linux/slab.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 int new_setting = 0; 53 u32 temp; 54 unsigned long flags; 55 56 /* Find out the new setting */ 57 if (!strncmp("on", buf, count - 1) || !strncmp("1", buf, count - 1)) 58 new_setting = 1; 59 else if (!strncmp("off", buf, count - 1) 60 || !strncmp("0", buf, count - 1)) 61 new_setting = 0; 62 else 63 return count; 64 65 spin_lock_irqsave(&priv->rxlock, flags); 66 67 /* Set the new stashing value */ 68 priv->bd_stash_en = new_setting; 69 70 temp = gfar_read(&priv->regs->attr); 71 72 if (new_setting) 73 temp |= ATTR_BDSTASH; 74 else 75 temp &= ~(ATTR_BDSTASH); 76 77 gfar_write(&priv->regs->attr, temp); 78 79 spin_unlock_irqrestore(&priv->rxlock, flags); 80 81 return count; 82} 83 84DEVICE_ATTR(bd_stash, 0644, gfar_show_bd_stash, gfar_set_bd_stash); 85 86static ssize_t gfar_show_rx_stash_size(struct device *dev, 87 struct device_attribute *attr, char *buf) 88{ 89 struct gfar_private *priv = netdev_priv(to_net_dev(dev)); 90 91 return sprintf(buf, "%d\n", priv->rx_stash_size); 92} 93 94static ssize_t gfar_set_rx_stash_size(struct device *dev, 95 struct device_attribute *attr, 96 const char *buf, size_t count) 97{ 98 struct gfar_private *priv = netdev_priv(to_net_dev(dev)); 99 unsigned int length = simple_strtoul(buf, NULL, 0); 100 u32 temp; 101 unsigned long flags; 102 103 spin_lock_irqsave(&priv->rxlock, flags); 104 if (length > priv->rx_buffer_size) 105 goto out; 106 107 if (length == priv->rx_stash_size) 108 goto out; 109 110 priv->rx_stash_size = length; 111 112 temp = gfar_read(&priv->regs->attreli); 113 temp &= ~ATTRELI_EL_MASK; 114 temp |= ATTRELI_EL(length); 115 gfar_write(&priv->regs->attreli, temp); 116 117 /* Turn stashing on/off as appropriate */ 118 temp = gfar_read(&priv->regs->attr); 119 120 if (length) 121 temp |= ATTR_BUFSTASH; 122 else 123 temp &= ~(ATTR_BUFSTASH); 124 125 gfar_write(&priv->regs->attr, temp); 126 127out: 128 spin_unlock_irqrestore(&priv->rxlock, flags); 129 130 return count; 131} 132 133DEVICE_ATTR(rx_stash_size, 0644, gfar_show_rx_stash_size, 134 gfar_set_rx_stash_size); 135 136/* Stashing will only be enabled when rx_stash_size != 0 */ 137static ssize_t gfar_show_rx_stash_index(struct device *dev, 138 struct device_attribute *attr, 139 char *buf) 140{ 141 struct gfar_private *priv = netdev_priv(to_net_dev(dev)); 142 143 return sprintf(buf, "%d\n", priv->rx_stash_index); 144} 145 146static ssize_t gfar_set_rx_stash_index(struct device *dev, 147 struct device_attribute *attr, 148 const char *buf, size_t count) 149{ 150 struct gfar_private *priv = netdev_priv(to_net_dev(dev)); 151 unsigned short index = simple_strtoul(buf, NULL, 0); 152 u32 temp; 153 unsigned long flags; 154 155 spin_lock_irqsave(&priv->rxlock, flags); 156 if (index > priv->rx_stash_size) 157 goto out; 158 159 if (index == priv->rx_stash_index) 160 goto out; 161 162 priv->rx_stash_index = index; 163 164 temp = gfar_read(&priv->regs->attreli); 165 temp &= ~ATTRELI_EI_MASK; 166 temp |= ATTRELI_EI(index); 167 gfar_write(&priv->regs->attreli, flags); 168 169out: 170 spin_unlock_irqrestore(&priv->rxlock, flags); 171 172 return count; 173} 174 175DEVICE_ATTR(rx_stash_index, 0644, gfar_show_rx_stash_index, 176 gfar_set_rx_stash_index); 177 178static ssize_t gfar_show_fifo_threshold(struct device *dev, 179 struct device_attribute *attr, 180 char *buf) 181{ 182 struct gfar_private *priv = netdev_priv(to_net_dev(dev)); 183 184 return sprintf(buf, "%d\n", priv->fifo_threshold); 185} 186 187static ssize_t gfar_set_fifo_threshold(struct device *dev, 188 struct device_attribute *attr, 189 const char *buf, size_t count) 190{ 191 struct gfar_private *priv = netdev_priv(to_net_dev(dev)); 192 unsigned int length = simple_strtoul(buf, NULL, 0); 193 u32 temp; 194 unsigned long flags; 195 196 if (length > GFAR_MAX_FIFO_THRESHOLD) 197 return count; 198 199 spin_lock_irqsave(&priv->txlock, flags); 200 201 priv->fifo_threshold = length; 202 203 temp = gfar_read(&priv->regs->fifo_tx_thr); 204 temp &= ~FIFO_TX_THR_MASK; 205 temp |= length; 206 gfar_write(&priv->regs->fifo_tx_thr, temp); 207 208 spin_unlock_irqrestore(&priv->txlock, flags); 209 210 return count; 211} 212 213DEVICE_ATTR(fifo_threshold, 0644, gfar_show_fifo_threshold, 214 gfar_set_fifo_threshold); 215 216static ssize_t gfar_show_fifo_starve(struct device *dev, 217 struct device_attribute *attr, char *buf) 218{ 219 struct gfar_private *priv = netdev_priv(to_net_dev(dev)); 220 221 return sprintf(buf, "%d\n", priv->fifo_starve); 222} 223 224static ssize_t gfar_set_fifo_starve(struct device *dev, 225 struct device_attribute *attr, 226 const char *buf, size_t count) 227{ 228 struct gfar_private *priv = netdev_priv(to_net_dev(dev)); 229 unsigned int num = simple_strtoul(buf, NULL, 0); 230 u32 temp; 231 unsigned long flags; 232 233 if (num > GFAR_MAX_FIFO_STARVE) 234 return count; 235 236 spin_lock_irqsave(&priv->txlock, flags); 237 238 priv->fifo_starve = num; 239 240 temp = gfar_read(&priv->regs->fifo_tx_starve); 241 temp &= ~FIFO_TX_STARVE_MASK; 242 temp |= num; 243 gfar_write(&priv->regs->fifo_tx_starve, temp); 244 245 spin_unlock_irqrestore(&priv->txlock, flags); 246 247 return count; 248} 249 250DEVICE_ATTR(fifo_starve, 0644, gfar_show_fifo_starve, gfar_set_fifo_starve); 251 252static ssize_t gfar_show_fifo_starve_off(struct device *dev, 253 struct device_attribute *attr, 254 char *buf) 255{ 256 struct gfar_private *priv = netdev_priv(to_net_dev(dev)); 257 258 return sprintf(buf, "%d\n", priv->fifo_starve_off); 259} 260 261static ssize_t gfar_set_fifo_starve_off(struct device *dev, 262 struct device_attribute *attr, 263 const char *buf, size_t count) 264{ 265 struct gfar_private *priv = netdev_priv(to_net_dev(dev)); 266 unsigned int num = simple_strtoul(buf, NULL, 0); 267 u32 temp; 268 unsigned long flags; 269 270 if (num > GFAR_MAX_FIFO_STARVE_OFF) 271 return count; 272 273 spin_lock_irqsave(&priv->txlock, flags); 274 275 priv->fifo_starve_off = num; 276 277 temp = gfar_read(&priv->regs->fifo_tx_starve_shutoff); 278 temp &= ~FIFO_TX_STARVE_OFF_MASK; 279 temp |= num; 280 gfar_write(&priv->regs->fifo_tx_starve_shutoff, temp); 281 282 spin_unlock_irqrestore(&priv->txlock, flags); 283 284 return count; 285} 286 287DEVICE_ATTR(fifo_starve_off, 0644, gfar_show_fifo_starve_off, 288 gfar_set_fifo_starve_off); 289 290void gfar_init_sysfs(struct net_device *dev) 291{ 292 struct gfar_private *priv = netdev_priv(dev); 293 int rc; 294 295 /* Initialize the default values */ 296 priv->rx_stash_size = DEFAULT_STASH_LENGTH; 297 priv->rx_stash_index = DEFAULT_STASH_INDEX; 298 priv->fifo_threshold = DEFAULT_FIFO_TX_THR; 299 priv->fifo_starve = DEFAULT_FIFO_TX_STARVE; 300 priv->fifo_starve_off = DEFAULT_FIFO_TX_STARVE_OFF; 301 priv->bd_stash_en = DEFAULT_BD_STASH; 302 303 /* Create our sysfs files */ 304 rc = device_create_file(&dev->dev, &dev_attr_bd_stash); 305 rc |= device_create_file(&dev->dev, &dev_attr_rx_stash_size); 306 rc |= device_create_file(&dev->dev, &dev_attr_rx_stash_index); 307 rc |= device_create_file(&dev->dev, &dev_attr_fifo_threshold); 308 rc |= device_create_file(&dev->dev, &dev_attr_fifo_starve); 309 rc |= device_create_file(&dev->dev, &dev_attr_fifo_starve_off); 310 if (rc) 311 dev_err(&dev->dev, "Error creating gianfar sysfs files.\n"); 312}