linux/drivers/net/gianfar_sysfs.c
<<
>>
Prefs
   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 * 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(&regs->attr);
  78
  79        if (new_setting)
  80                temp |= ATTR_BDSTASH;
  81        else
  82                temp &= ~(ATTR_BDSTASH);
  83
  84        gfar_write(&regs->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(&regs->attreli);
 127        temp &= ~ATTRELI_EL_MASK;
 128        temp |= ATTRELI_EL(length);
 129        gfar_write(&regs->attreli, temp);
 130
 131        /* Turn stashing on/off as appropriate */
 132        temp = gfar_read(&regs->attr);
 133
 134        if (length)
 135                temp |= ATTR_BUFSTASH;
 136        else
 137                temp &= ~(ATTR_BUFSTASH);
 138
 139        gfar_write(&regs->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(&regs->attreli);
 186        temp &= ~ATTRELI_EI_MASK;
 187        temp |= ATTRELI_EI(index);
 188        gfar_write(&regs->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(&regs->fifo_tx_thr);
 228        temp &= ~FIFO_TX_THR_MASK;
 229        temp |= length;
 230        gfar_write(&regs->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(&regs->fifo_tx_starve);
 268        temp &= ~FIFO_TX_STARVE_MASK;
 269        temp |= num;
 270        gfar_write(&regs->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(&regs->fifo_tx_starve_shutoff);
 309        temp &= ~FIFO_TX_STARVE_OFF_MASK;
 310        temp |= num;
 311        gfar_write(&regs->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