blob: 6e2166a7601a267f892f8d5d2039af1f1630df94 [file] [log] [blame]
Andy Fleming7f7f5312005-11-11 12:38:59 -06001/*
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
Adrian Bunkb56d55b2006-01-11 02:00:10 +010010 * Maintainer: Kumar Gala (galak@kernel.crashing.org)
Andy Fleming7f7f5312005-11-11 12:38:59 -060011 *
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
Andy Fleming7f7f5312005-11-11 12:38:59 -060022#include <linux/kernel.h>
23#include <linux/sched.h>
24#include <linux/string.h>
25#include <linux/errno.h>
26#include <linux/unistd.h>
27#include <linux/slab.h>
28#include <linux/init.h>
29#include <linux/delay.h>
30#include <linux/etherdevice.h>
31#include <linux/spinlock.h>
32#include <linux/mm.h>
33#include <linux/device.h>
34
35#include <asm/uaccess.h>
36#include <linux/module.h>
37#include <linux/version.h>
38
39#include "gianfar.h"
40
41#define GFAR_ATTR(_name) \
Kumar Gala4409d282007-02-12 23:40:06 -060042static ssize_t gfar_show_##_name(struct device *dev, \
43 struct device_attribute *attr, char *buf); \
44static ssize_t gfar_set_##_name(struct device *dev, \
45 struct device_attribute *attr, \
Andy Fleming7f7f5312005-11-11 12:38:59 -060046 const char *buf, size_t count); \
Kumar Gala4409d282007-02-12 23:40:06 -060047static DEVICE_ATTR(_name, 0644, gfar_show_##_name, gfar_set_##_name)
Andy Fleming7f7f5312005-11-11 12:38:59 -060048
49#define GFAR_CREATE_FILE(_dev, _name) \
Kumar Gala4409d282007-02-12 23:40:06 -060050 device_create_file(&_dev->dev, &dev_attr_##_name)
Andy Fleming7f7f5312005-11-11 12:38:59 -060051
52GFAR_ATTR(bd_stash);
53GFAR_ATTR(rx_stash_size);
54GFAR_ATTR(rx_stash_index);
55GFAR_ATTR(fifo_threshold);
56GFAR_ATTR(fifo_starve);
57GFAR_ATTR(fifo_starve_off);
58
Kumar Gala4409d282007-02-12 23:40:06 -060059static ssize_t gfar_show_bd_stash(struct device *dev,
60 struct device_attribute *attr, char *buf)
Andy Fleming7f7f5312005-11-11 12:38:59 -060061{
Kumar Gala4409d282007-02-12 23:40:06 -060062 struct gfar_private *priv = netdev_priv(to_net_dev(dev));
Andy Fleming7f7f5312005-11-11 12:38:59 -060063
Kumar Gala4409d282007-02-12 23:40:06 -060064 return sprintf(buf, "%s\n", priv->bd_stash_en ? "on" : "off");
Andy Fleming7f7f5312005-11-11 12:38:59 -060065}
66
Kumar Gala4409d282007-02-12 23:40:06 -060067static ssize_t gfar_set_bd_stash(struct device *dev,
68 struct device_attribute *attr,
69 const char *buf, size_t count)
Andy Fleming7f7f5312005-11-11 12:38:59 -060070{
Kumar Gala4409d282007-02-12 23:40:06 -060071 struct gfar_private *priv = netdev_priv(to_net_dev(dev));
Andy Fleming7f7f5312005-11-11 12:38:59 -060072 int new_setting = 0;
73 u32 temp;
74 unsigned long flags;
75
76 /* Find out the new setting */
Kumar Gala4409d282007-02-12 23:40:06 -060077 if (!strncmp("on", buf, count - 1) || !strncmp("1", buf, count - 1))
Andy Fleming7f7f5312005-11-11 12:38:59 -060078 new_setting = 1;
Kumar Gala4409d282007-02-12 23:40:06 -060079 else if (!strncmp("off", buf, count - 1)
80 || !strncmp("0", buf, count - 1))
Andy Fleming7f7f5312005-11-11 12:38:59 -060081 new_setting = 0;
82 else
83 return count;
84
Andy Flemingfef61082006-04-20 16:44:29 -050085 spin_lock_irqsave(&priv->rxlock, flags);
Andy Fleming7f7f5312005-11-11 12:38:59 -060086
87 /* Set the new stashing value */
88 priv->bd_stash_en = new_setting;
89
90 temp = gfar_read(&priv->regs->attr);
Jeff Garzik6aa20a22006-09-13 13:24:59 -040091
Andy Fleming7f7f5312005-11-11 12:38:59 -060092 if (new_setting)
93 temp |= ATTR_BDSTASH;
94 else
95 temp &= ~(ATTR_BDSTASH);
96
97 gfar_write(&priv->regs->attr, temp);
98
Andy Flemingfef61082006-04-20 16:44:29 -050099 spin_unlock_irqrestore(&priv->rxlock, flags);
Andy Fleming7f7f5312005-11-11 12:38:59 -0600100
101 return count;
102}
103
Kumar Gala4409d282007-02-12 23:40:06 -0600104static ssize_t gfar_show_rx_stash_size(struct device *dev,
105 struct device_attribute *attr, char *buf)
Andy Fleming7f7f5312005-11-11 12:38:59 -0600106{
Kumar Gala4409d282007-02-12 23:40:06 -0600107 struct gfar_private *priv = netdev_priv(to_net_dev(dev));
Andy Fleming7f7f5312005-11-11 12:38:59 -0600108
109 return sprintf(buf, "%d\n", priv->rx_stash_size);
110}
111
Kumar Gala4409d282007-02-12 23:40:06 -0600112static ssize_t gfar_set_rx_stash_size(struct device *dev,
113 struct device_attribute *attr,
114 const char *buf, size_t count)
Andy Fleming7f7f5312005-11-11 12:38:59 -0600115{
Kumar Gala4409d282007-02-12 23:40:06 -0600116 struct gfar_private *priv = netdev_priv(to_net_dev(dev));
Andy Fleming7f7f5312005-11-11 12:38:59 -0600117 unsigned int length = simple_strtoul(buf, NULL, 0);
118 u32 temp;
119 unsigned long flags;
120
Andy Flemingfef61082006-04-20 16:44:29 -0500121 spin_lock_irqsave(&priv->rxlock, flags);
Andy Fleming7f7f5312005-11-11 12:38:59 -0600122 if (length > priv->rx_buffer_size)
123 return count;
124
125 if (length == priv->rx_stash_size)
126 return count;
127
128 priv->rx_stash_size = length;
129
130 temp = gfar_read(&priv->regs->attreli);
131 temp &= ~ATTRELI_EL_MASK;
132 temp |= ATTRELI_EL(length);
133 gfar_write(&priv->regs->attreli, temp);
134
135 /* Turn stashing on/off as appropriate */
136 temp = gfar_read(&priv->regs->attr);
137
138 if (length)
139 temp |= ATTR_BUFSTASH;
140 else
141 temp &= ~(ATTR_BUFSTASH);
142
143 gfar_write(&priv->regs->attr, temp);
144
Andy Flemingfef61082006-04-20 16:44:29 -0500145 spin_unlock_irqrestore(&priv->rxlock, flags);
Andy Fleming7f7f5312005-11-11 12:38:59 -0600146
147 return count;
148}
149
Andy Fleming7f7f5312005-11-11 12:38:59 -0600150/* Stashing will only be enabled when rx_stash_size != 0 */
Kumar Gala4409d282007-02-12 23:40:06 -0600151static ssize_t gfar_show_rx_stash_index(struct device *dev,
152 struct device_attribute *attr,
153 char *buf)
Andy Fleming7f7f5312005-11-11 12:38:59 -0600154{
Kumar Gala4409d282007-02-12 23:40:06 -0600155 struct gfar_private *priv = netdev_priv(to_net_dev(dev));
Andy Fleming7f7f5312005-11-11 12:38:59 -0600156
157 return sprintf(buf, "%d\n", priv->rx_stash_index);
158}
159
Kumar Gala4409d282007-02-12 23:40:06 -0600160static ssize_t gfar_set_rx_stash_index(struct device *dev,
161 struct device_attribute *attr,
162 const char *buf, size_t count)
Andy Fleming7f7f5312005-11-11 12:38:59 -0600163{
Kumar Gala4409d282007-02-12 23:40:06 -0600164 struct gfar_private *priv = netdev_priv(to_net_dev(dev));
Andy Fleming7f7f5312005-11-11 12:38:59 -0600165 unsigned short index = simple_strtoul(buf, NULL, 0);
166 u32 temp;
167 unsigned long flags;
168
Andy Flemingfef61082006-04-20 16:44:29 -0500169 spin_lock_irqsave(&priv->rxlock, flags);
Andy Fleming7f7f5312005-11-11 12:38:59 -0600170 if (index > priv->rx_stash_size)
171 return count;
172
173 if (index == priv->rx_stash_index)
174 return count;
175
176 priv->rx_stash_index = index;
177
178 temp = gfar_read(&priv->regs->attreli);
179 temp &= ~ATTRELI_EI_MASK;
180 temp |= ATTRELI_EI(index);
181 gfar_write(&priv->regs->attreli, flags);
182
Andy Flemingfef61082006-04-20 16:44:29 -0500183 spin_unlock_irqrestore(&priv->rxlock, flags);
Andy Fleming7f7f5312005-11-11 12:38:59 -0600184
185 return count;
186}
187
Kumar Gala4409d282007-02-12 23:40:06 -0600188static ssize_t gfar_show_fifo_threshold(struct device *dev,
189 struct device_attribute *attr,
190 char *buf)
Andy Fleming7f7f5312005-11-11 12:38:59 -0600191{
Kumar Gala4409d282007-02-12 23:40:06 -0600192 struct gfar_private *priv = netdev_priv(to_net_dev(dev));
Andy Fleming7f7f5312005-11-11 12:38:59 -0600193
194 return sprintf(buf, "%d\n", priv->fifo_threshold);
195}
196
Kumar Gala4409d282007-02-12 23:40:06 -0600197static ssize_t gfar_set_fifo_threshold(struct device *dev,
198 struct device_attribute *attr,
199 const char *buf, size_t count)
Andy Fleming7f7f5312005-11-11 12:38:59 -0600200{
Kumar Gala4409d282007-02-12 23:40:06 -0600201 struct gfar_private *priv = netdev_priv(to_net_dev(dev));
Andy Fleming7f7f5312005-11-11 12:38:59 -0600202 unsigned int length = simple_strtoul(buf, NULL, 0);
203 u32 temp;
204 unsigned long flags;
205
206 if (length > GFAR_MAX_FIFO_THRESHOLD)
207 return count;
208
Andy Flemingfef61082006-04-20 16:44:29 -0500209 spin_lock_irqsave(&priv->txlock, flags);
Andy Fleming7f7f5312005-11-11 12:38:59 -0600210
211 priv->fifo_threshold = length;
212
213 temp = gfar_read(&priv->regs->fifo_tx_thr);
214 temp &= ~FIFO_TX_THR_MASK;
215 temp |= length;
216 gfar_write(&priv->regs->fifo_tx_thr, temp);
217
Andy Flemingfef61082006-04-20 16:44:29 -0500218 spin_unlock_irqrestore(&priv->txlock, flags);
Andy Fleming7f7f5312005-11-11 12:38:59 -0600219
220 return count;
221}
222
Kumar Gala4409d282007-02-12 23:40:06 -0600223static ssize_t gfar_show_fifo_starve(struct device *dev,
224 struct device_attribute *attr, char *buf)
Andy Fleming7f7f5312005-11-11 12:38:59 -0600225{
Kumar Gala4409d282007-02-12 23:40:06 -0600226 struct gfar_private *priv = netdev_priv(to_net_dev(dev));
Andy Fleming7f7f5312005-11-11 12:38:59 -0600227
228 return sprintf(buf, "%d\n", priv->fifo_starve);
229}
230
Kumar Gala4409d282007-02-12 23:40:06 -0600231static ssize_t gfar_set_fifo_starve(struct device *dev,
232 struct device_attribute *attr,
233 const char *buf, size_t count)
Andy Fleming7f7f5312005-11-11 12:38:59 -0600234{
Kumar Gala4409d282007-02-12 23:40:06 -0600235 struct gfar_private *priv = netdev_priv(to_net_dev(dev));
Andy Fleming7f7f5312005-11-11 12:38:59 -0600236 unsigned int num = simple_strtoul(buf, NULL, 0);
237 u32 temp;
238 unsigned long flags;
239
240 if (num > GFAR_MAX_FIFO_STARVE)
241 return count;
242
Andy Flemingfef61082006-04-20 16:44:29 -0500243 spin_lock_irqsave(&priv->txlock, flags);
Andy Fleming7f7f5312005-11-11 12:38:59 -0600244
245 priv->fifo_starve = num;
246
247 temp = gfar_read(&priv->regs->fifo_tx_starve);
248 temp &= ~FIFO_TX_STARVE_MASK;
249 temp |= num;
250 gfar_write(&priv->regs->fifo_tx_starve, temp);
251
Andy Flemingfef61082006-04-20 16:44:29 -0500252 spin_unlock_irqrestore(&priv->txlock, flags);
Andy Fleming7f7f5312005-11-11 12:38:59 -0600253
254 return count;
255}
256
Kumar Gala4409d282007-02-12 23:40:06 -0600257static ssize_t gfar_show_fifo_starve_off(struct device *dev,
258 struct device_attribute *attr,
259 char *buf)
Andy Fleming7f7f5312005-11-11 12:38:59 -0600260{
Kumar Gala4409d282007-02-12 23:40:06 -0600261 struct gfar_private *priv = netdev_priv(to_net_dev(dev));
Andy Fleming7f7f5312005-11-11 12:38:59 -0600262
263 return sprintf(buf, "%d\n", priv->fifo_starve_off);
264}
265
Kumar Gala4409d282007-02-12 23:40:06 -0600266static ssize_t gfar_set_fifo_starve_off(struct device *dev,
267 struct device_attribute *attr,
268 const char *buf, size_t count)
Andy Fleming7f7f5312005-11-11 12:38:59 -0600269{
Kumar Gala4409d282007-02-12 23:40:06 -0600270 struct gfar_private *priv = netdev_priv(to_net_dev(dev));
Andy Fleming7f7f5312005-11-11 12:38:59 -0600271 unsigned int num = simple_strtoul(buf, NULL, 0);
272 u32 temp;
273 unsigned long flags;
274
275 if (num > GFAR_MAX_FIFO_STARVE_OFF)
276 return count;
277
Andy Flemingfef61082006-04-20 16:44:29 -0500278 spin_lock_irqsave(&priv->txlock, flags);
Andy Fleming7f7f5312005-11-11 12:38:59 -0600279
280 priv->fifo_starve_off = num;
281
282 temp = gfar_read(&priv->regs->fifo_tx_starve_shutoff);
283 temp &= ~FIFO_TX_STARVE_OFF_MASK;
284 temp |= num;
285 gfar_write(&priv->regs->fifo_tx_starve_shutoff, temp);
286
Andy Flemingfef61082006-04-20 16:44:29 -0500287 spin_unlock_irqrestore(&priv->txlock, flags);
Andy Fleming7f7f5312005-11-11 12:38:59 -0600288
289 return count;
290}
291
292void gfar_init_sysfs(struct net_device *dev)
293{
294 struct gfar_private *priv = netdev_priv(dev);
295
296 /* Initialize the default values */
297 priv->rx_stash_size = DEFAULT_STASH_LENGTH;
298 priv->rx_stash_index = DEFAULT_STASH_INDEX;
299 priv->fifo_threshold = DEFAULT_FIFO_TX_THR;
300 priv->fifo_starve = DEFAULT_FIFO_TX_STARVE;
301 priv->fifo_starve_off = DEFAULT_FIFO_TX_STARVE_OFF;
302 priv->bd_stash_en = DEFAULT_BD_STASH;
303
304 /* Create our sysfs files */
305 GFAR_CREATE_FILE(dev, bd_stash);
306 GFAR_CREATE_FILE(dev, rx_stash_size);
307 GFAR_CREATE_FILE(dev, rx_stash_index);
308 GFAR_CREATE_FILE(dev, fifo_threshold);
309 GFAR_CREATE_FILE(dev, fifo_starve);
310 GFAR_CREATE_FILE(dev, fifo_starve_off);
311
312}