2 * SBE 2T3E3 synchronous serial card driver for Linux
4 * Copyright (C) 2009-2010 Krzysztof Halasa <khc@pm.waw.pl>
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.
10 * This code is based on a driver written by SBE Inc.
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>
24 static int t3e3_ioctl(struct net_device
*dev
, struct ifreq
*ifr
, int cmd
)
26 struct channel
*sc
= dev_to_priv(dev
);
27 int cmd_2t3e3
, len
, rlen
;
30 void __user
*data
= ifr
->ifr_data
+ sizeof(cmd_2t3e3
) + sizeof(len
);
32 if (cmd
== SIOCWANDEV
)
33 return hdlc_ioctl(dev
, ifr
, cmd
);
34 if (!capable(CAP_SYS_ADMIN
))
36 if (cmd
!= SIOCDEVPRIVATE
+ 15)
39 if (copy_from_user(&cmd_2t3e3
, ifr
->ifr_data
, sizeof(cmd_2t3e3
)))
41 if (copy_from_user(&len
, ifr
->ifr_data
+ sizeof(cmd_2t3e3
), sizeof(len
)))
44 if (len
> sizeof(param
))
48 if (copy_from_user(¶m
, data
, len
))
51 t3e3_if_config(sc
, cmd_2t3e3
, (char *)¶m
, &resp
, &rlen
);
54 if (copy_to_user(data
, &resp
, rlen
))
60 static struct net_device_stats
*t3e3_get_stats(struct net_device
*dev
)
62 struct net_device_stats
*nstats
= &dev
->stats
;
63 struct channel
*sc
= dev_to_priv(dev
);
64 t3e3_stats_t
*stats
= &sc
->s
;
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
;
72 nstats
->rx_errors
= stats
->in_errors
;
73 nstats
->tx_errors
= stats
->out_errors
;
74 nstats
->rx_crc_errors
= stats
->in_error_crc
;
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
;
85 static int t3e3_open(struct net_device
*dev
)
87 struct channel
*sc
= dev_to_priv(dev
);
88 int ret
= hdlc_open(dev
);
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
);
100 static int t3e3_close(struct net_device
*dev
)
102 struct channel
*sc
= dev_to_priv(dev
);
104 netif_stop_queue(dev
);
106 sc
->r
.flags
&= ~SBE_2T3E3_FLAG_NETWORK_UP
;
107 module_put(THIS_MODULE
);
111 static int t3e3_attach(struct net_device
*dev
, unsigned short foo1
,
117 static 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
,
126 int setup_device(struct net_device
*dev
, struct channel
*sc
)
128 hdlc_device
*hdlc
= dev_to_hdlc(dev
);
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
);
139 dev_err(&sc
->pdev
->dev
, "error registering HDLC device\n");