linux/drivers/staging/sbe-2t3e3/netdev.c
<<
>>
Prefs
   1/*
   2 * SBE 2T3E3 synchronous serial card driver for Linux
   3 *
   4 * Copyright (C) 2009-2010 Krzysztof Halasa <khc@pm.waw.pl>
   5 *
   6 * This program is free software; you can redistribute it and/or modify it
   7 * under the terms of version 2 of the GNU General Public License
   8 * as published by the Free Software Foundation.
   9 *
  10 * This code is based on a driver written by SBE Inc.
  11 */
  12
  13#include <linux/capability.h>
  14#include <linux/module.h>
  15#include <linux/slab.h>
  16#include <linux/delay.h>
  17#include <linux/netdevice.h>
  18#include <linux/pci.h>
  19#include <linux/hdlc.h>
  20#include <linux/if_arp.h>
  21#include <linux/interrupt.h>
  22#include "2t3e3.h"
  23
  24static int t3e3_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
  25{
  26        struct channel *sc = dev_to_priv(dev);
  27        int cmd_2t3e3, len, rlen;
  28        t3e3_param_t param;
  29        t3e3_resp_t  resp;
  30        void __user *data = ifr->ifr_data + sizeof(cmd_2t3e3) + sizeof(len);
  31
  32        if (cmd == SIOCWANDEV)
  33                return hdlc_ioctl(dev, ifr, cmd);
  34        if (!capable(CAP_SYS_ADMIN))
  35                return -EPERM;
  36        if (cmd != SIOCDEVPRIVATE + 15)
  37                return -EINVAL;
  38
  39        if (copy_from_user(&cmd_2t3e3, ifr->ifr_data, sizeof(cmd_2t3e3)))
  40                return -EFAULT;
  41        if (copy_from_user(&len, ifr->ifr_data + sizeof(cmd_2t3e3), sizeof(len)))
  42                return -EFAULT;
  43
  44        if (len > sizeof(param))
  45                return -EFAULT;
  46
  47        if (len)
  48                if (copy_from_user(&param, data, len))
  49                        return -EFAULT;
  50
  51        t3e3_if_config(sc, cmd_2t3e3, (char *)&param, &resp, &rlen);
  52
  53        if (rlen)
  54                if (copy_to_user(data, &resp, rlen))
  55                        return -EFAULT;
  56
  57        return 0;
  58}
  59
  60static struct net_device_stats *t3e3_get_stats(struct net_device *dev)
  61{
  62        struct net_device_stats *nstats = &dev->stats;
  63        struct channel *sc = dev_to_priv(dev);
  64        t3e3_stats_t *stats = &sc->s;
  65
  66        memset(nstats, 0, sizeof(struct net_device_stats));
  67        nstats->rx_packets = stats->in_packets;
  68        nstats->tx_packets = stats->out_packets;
  69        nstats->rx_bytes = stats->in_bytes;
  70        nstats->tx_bytes = stats->out_bytes;
  71
  72        nstats->rx_errors = stats->in_errors;
  73        nstats->tx_errors = stats->out_errors;
  74        nstats->rx_crc_errors = stats->in_error_crc;
  75
  76
  77        nstats->rx_dropped = stats->in_dropped;
  78        nstats->tx_dropped = stats->out_dropped;
  79        nstats->tx_carrier_errors = stats->out_error_lost_carr +
  80                stats->out_error_no_carr;
  81
  82        return nstats;
  83}
  84
  85static int t3e3_open(struct net_device *dev)
  86{
  87        struct channel *sc = dev_to_priv(dev);
  88        int ret = hdlc_open(dev);
  89
  90        if (ret)
  91                return ret;
  92
  93        sc->r.flags |= SBE_2T3E3_FLAG_NETWORK_UP;
  94        dc_start(dev_to_priv(dev));
  95        netif_start_queue(dev);
  96        try_module_get(THIS_MODULE);
  97        return 0;
  98}
  99
 100static int t3e3_close(struct net_device *dev)
 101{
 102        struct channel *sc = dev_to_priv(dev);
 103        hdlc_close(dev);
 104        netif_stop_queue(dev);
 105        dc_stop(sc);
 106        sc->r.flags &= ~SBE_2T3E3_FLAG_NETWORK_UP;
 107        module_put(THIS_MODULE);
 108        return 0;
 109}
 110
 111static int t3e3_attach(struct net_device *dev, unsigned short foo1,
 112                       unsigned short foo2)
 113{
 114        return 0;
 115}
 116
 117static const struct net_device_ops t3e3_ops = {
 118        .ndo_open       = t3e3_open,
 119        .ndo_stop       = t3e3_close,
 120        .ndo_change_mtu = hdlc_change_mtu,
 121        .ndo_start_xmit = hdlc_start_xmit,
 122        .ndo_do_ioctl   = t3e3_ioctl,
 123        .ndo_get_stats  = t3e3_get_stats,
 124};
 125
 126int setup_device(struct net_device *dev, struct channel *sc)
 127{
 128        hdlc_device *hdlc = dev_to_hdlc(dev);
 129        int retval;
 130
 131        dev->base_addr = pci_resource_start(sc->pdev, 0);
 132        dev->irq = sc->pdev->irq;
 133        dev->netdev_ops = &t3e3_ops;
 134        dev->tx_queue_len = 100;
 135        hdlc->xmit = t3e3_if_start_xmit;
 136        hdlc->attach = t3e3_attach;
 137        retval = register_hdlc_device(dev);
 138        if (retval) {
 139                dev_err(&sc->pdev->dev, "error registering HDLC device\n");
 140                return retval;
 141        }
 142        return 0;
 143}
 144