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#include <linux/version.h> 37 38#include "gianfar.h" 39 40#define GFAR_ATTR(_name) \ 41static ssize_t gfar_show_##_name(struct device *dev, \ 42 struct device_attribute *attr, char *buf); \ 43static ssize_t gfar_set_##_name(struct device *dev, \ 44 struct device_attribute *attr, \ 45 const char *buf, size_t count); \ 46static DEVICE_ATTR(_name, 0644, gfar_show_##_name, gfar_set_##_name) 47 48#define GFAR_CREATE_FILE(_dev, _name) \ 49 device_create_file(&_dev->dev, &dev_attr_##_name) 50 51GFAR_ATTR(bd_stash); 52GFAR_ATTR(rx_stash_size); 53GFAR_ATTR(rx_stash_index); 54GFAR_ATTR(fifo_threshold); 55GFAR_ATTR(fifo_starve); 56GFAR_ATTR(fifo_starve_off); 57 58static ssize_t gfar_show_bd_stash(struct device *dev, 59 struct device_attribute *attr, char *buf) 60{ 61 struct gfar_private *priv = netdev_priv(to_net_dev(dev)); 62 63 return sprintf(buf, "%s\n", priv->bd_stash_en ? "on" : "off"); 64} 65 66static ssize_t gfar_set_bd_stash(struct device *dev, 67 struct device_attribute *attr, 68 const char *buf, size_t count) 69{ 70 struct gfar_private *priv = netdev_priv(to_net_dev(dev)); 71 int new_setting = 0; 72 u32 temp; 73 unsigned long flags; 74 75 /* Find out the new setting */ 76 if (!strncmp("on", buf, count - 1) || !strncmp("1", buf, count - 1)) 77 new_setting = 1; 78 else if (!strncmp("off", buf, count - 1) 79 || !strncmp("0", buf, count - 1)) 80 new_setting = 0; 81 else 82 return count; 83 84 spin_lock_irqsave(&priv->rxlock, flags); 85 86 /* Set the new stashing value */ 87 priv->bd_stash_en = new_setting; 88 89 temp = gfar_read(&priv->regs->attr); 90 91 if (new_setting) 92 temp |= ATTR_BDSTASH; 93 else 94 temp &= ~(ATTR_BDSTASH); 95 96 gfar_write(&priv->regs->attr, temp); 97 98 spin_unlock_irqrestore(&priv->rxlock, flags); 99 100 return count; 101} 102 103static ssize_t gfar_show_rx_stash_size(struct device *dev, 104 struct device_attribute *attr, char *buf) 105{ 106 struct gfar_private *priv = netdev_priv(to_net_dev(dev)); 107 108 return sprintf(buf, "%d\n", priv->rx_stash_size); 109} 110 111static ssize_t gfar_set_rx_stash_size(struct device *dev, 112 struct device_attribute *attr, 113 const char *buf, size_t count) 114{ 115 struct gfar_private *priv = netdev_priv(to_net_dev(dev)); 116 unsigned int length = simple_strtoul(buf, NULL, 0); 117 u32 temp; 118 unsigned long flags; 119 120 spin_lock_irqsave(&priv->rxlock, flags); 121 if (length > priv->rx_buffer_size) 122 return count; 123 124 if (length == priv->rx_stash_size) 125 return count; 126 127 priv->rx_stash_size = length; 128 129 temp = gfar_read(&priv->regs->attreli); 130 temp &= ~ATTRELI_EL_MASK; 131 temp |= ATTRELI_EL(length); 132 gfar_write(&priv->regs->attreli, temp); 133 134 /* Turn stashing on/off as appropriate */ 135 temp = gfar_read(&priv->regs->attr); 136 137 if (length) 138 temp |= ATTR_BUFSTASH; 139 else 140 temp &= ~(ATTR_BUFSTASH); 141 142 gfar_write(&priv->regs->attr, temp); 143 144 spin_unlock_irqrestore(&priv->rxlock, flags); 145 146 return count; 147} 148 149/* Stashing will only be enabled when rx_stash_size != 0 */ 150static ssize_t gfar_show_rx_stash_index(struct device *dev, 151 struct device_attribute *attr, 152 char *buf) 153{ 154 struct gfar_private *priv = netdev_priv(to_net_dev(dev)); 155 156 return sprintf(buf, "%d\n", priv->rx_stash_index); 157} 158 159static ssize_t gfar_set_rx_stash_index(struct device *dev, 160 struct device_attribute *attr, 161 const char *buf, size_t count) 162{ 163 struct gfar_private *priv = netdev_priv(to_net_dev(dev)); 164 unsigned short index = simple_strtoul(buf, NULL, 0); 165 u32 temp; 166 unsigned long flags; 167 168 spin_lock_irqsave(&priv->rxlock, flags); 169 if (index > priv->rx_stash_size) 170 return count; 171 172 if (index == priv->rx_stash_index) 173 return count; 174 175 priv->rx_stash_index = index; 176 177 temp = gfar_read(&priv->regs->attreli); 178 temp &= ~ATTRELI_EI_MASK; 179 temp |= ATTRELI_EI(index); 180 gfar_write(&priv->regs->attreli, flags); 181 182 spin_unlock_irqrestore(&priv->rxlock, flags); 183 184 return count; 185} 186 187static ssize_t gfar_show_fifo_threshold(struct device *dev, 188 struct device_attribute *attr, 189 char *buf) 190{ 191 struct gfar_private *priv = netdev_priv(to_net_dev(dev)); 192 193 return sprintf(buf, "%d\n", priv->fifo_threshold); 194} 195 196static ssize_t gfar_set_fifo_threshold(struct device *dev, 197 struct device_attribute *attr, 198 const char *buf, size_t count) 199{ 200 struct gfar_private *priv = netdev_priv(to_net_dev(dev)); 201 unsigned int length = simple_strtoul(buf, NULL, 0); 202 u32 temp; 203 unsigned long flags; 204 205 if (length > GFAR_MAX_FIFO_THRESHOLD) 206 return count; 207 208 spin_lock_irqsave(&priv->txlock, flags); 209 210 priv->fifo_threshold = length; 211 212 temp = gfar_read(&priv->regs->fifo_tx_thr); 213 temp &= ~FIFO_TX_THR_MASK; 214 temp |= length; 215 gfar_write(&priv->regs->fifo_tx_thr, temp); 216 217 spin_unlock_irqrestore(&priv->txlock, flags); 218 219 return count; 220} 221 222static ssize_t gfar_show_fifo_starve(struct device *dev, 223 struct device_attribute *attr, char *buf) 224{ 225 struct gfar_private *priv = netdev_priv(to_net_dev(dev)); 226 227 return sprintf(buf, "%d\n", priv->fifo_starve); 228} 229 230static ssize_t gfar_set_fifo_starve(struct device *dev, 231 struct device_attribute *attr, 232 const char *buf, size_t count) 233{ 234 struct gfar_private *priv = netdev_priv(to_net_dev(dev)); 235 unsigned int num = simple_strtoul(buf, NULL, 0); 236 u32 temp; 237 unsigned long flags; 238 239 if (num > GFAR_MAX_FIFO_STARVE) 240 return count; 241 242 spin_lock_irqsave(&priv->txlock, flags); 243 244 priv->fifo_starve = num; 245 246 temp = gfar_read(&priv->regs->fifo_tx_starve); 247 temp &= ~FIFO_TX_STARVE_MASK; 248 temp |= num; 249 gfar_write(&priv->regs->fifo_tx_starve, temp); 250 251 spin_unlock_irqrestore(&priv->txlock, flags); 252 253 return count; 254} 255 256static ssize_t gfar_show_fifo_starve_off(struct device *dev, 257 struct device_attribute *attr, 258 char *buf) 259{ 260 struct gfar_private *priv = netdev_priv(to_net_dev(dev)); 261 262 return sprintf(buf, "%d\n", priv->fifo_starve_off); 263} 264 265static ssize_t gfar_set_fifo_starve_off(struct device *dev, 266 struct device_attribute *attr, 267 const char *buf, size_t count) 268{ 269 struct gfar_private *priv = netdev_priv(to_net_dev(dev)); 270 unsigned int num = simple_strtoul(buf, NULL, 0); 271 u32 temp; 272 unsigned long flags; 273 274 if (num > GFAR_MAX_FIFO_STARVE_OFF) 275 return count; 276 277 spin_lock_irqsave(&priv->txlock, flags); 278 279 priv->fifo_starve_off = num; 280 281 temp = gfar_read(&priv->regs->fifo_tx_starve_shutoff); 282 temp &= ~FIFO_TX_STARVE_OFF_MASK; 283 temp |= num; 284 gfar_write(&priv->regs->fifo_tx_starve_shutoff, temp); 285 286 spin_unlock_irqrestore(&priv->txlock, flags); 287 288 return count; 289} 290 291void gfar_init_sysfs(struct net_device *dev) 292{ 293 struct gfar_private *priv = netdev_priv(dev); 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 GFAR_CREATE_FILE(dev, bd_stash); 305 GFAR_CREATE_FILE(dev, rx_stash_size); 306 GFAR_CREATE_FILE(dev, rx_stash_index); 307 GFAR_CREATE_FILE(dev, fifo_threshold); 308 GFAR_CREATE_FILE(dev, fifo_starve); 309 GFAR_CREATE_FILE(dev, fifo_starve_off); 310 311} 312