/* sbni.c: Granch SBNI12 leased line adapters driver for linux
*
* Written 2001 by Denis I.Timofeev (timofeev@granch.ru)
*
* Previous versions were written by Yaroslav Polyakov,
* Alexey Zverev and Max Khon.
*
* Driver supports SBNI12-02,-04,-05,-10,-11 cards, single and
* double-channel, PCI and ISA modifications.
* More info and useful utilities to work with SBNI12 cards you can find
* at http://www.granch.com (English) or http://www.granch.ru (Russian)
*
* This software may be used and distributed according to the terms
* of the GNU General Public License.
*
*
* 5.0.1 Jun 22 2001
* - Fixed bug in probe
* 5.0.0 Jun 06 2001
* - Driver was completely redesigned by Denis I.Timofeev,
* - now PCI/Dual, ISA/Dual (with single interrupt line) models are
* - supported
* 3.3.0 Thu Feb 24 21:30:28 NOVT 2000
* - PCI cards support
* 3.2.0 Mon Dec 13 22:26:53 NOVT 1999
* - Completely rebuilt all the packet storage system
* - to work in Ethernet-like style.
* 3.1.1 just fixed some bugs (5 aug 1999)
* 3.1.0 added balancing feature (26 apr 1999)
* 3.0.1 just fixed some bugs (14 apr 1999).
* 3.0.0 Initial Revision, Yaroslav Polyakov (24 Feb 1999)
* - added pre-calculation for CRC, fixed bug with "len-2" frames,
* - removed outbound fragmentation (MTU=1000), written CRC-calculation
* - on asm, added work with hard_headers and now we have our own cache
* - for them, optionally supported word-interchange on some chipsets,
*
* Known problem: this driver wasn't tested on multiprocessor machine.
*/
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/ptrace.h>
#include <linux/fcntl.h>
#include <linux/ioport.h>
#include <linux/interrupt.h>
#include <linux/string.h>
#include <linux/errno.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/pci.h>
#include <linux/skbuff.h>
#include <linux/timer.h>
#include <linux/init.h>
#include <linux/delay.h>
#include <net/net_namespace.h>
#include <net/arp.h>
#include <net/Space.h>
#include <asm/io.h>
#include <asm/types.h>
#include <asm/byteorder.h>
#include <asm/irq.h>
#include <linux/uaccess.h>
#include "sbni.h"
/* device private data */
struct net_local {
struct timer_list watchdog;
struct net_device *watchdog_dev;
spinlock_t lock;
struct sk_buff *rx_buf_p; /* receive buffer ptr */
struct sk_buff *tx_buf_p; /* transmit buffer ptr */
unsigned int framelen; /* current frame length */
unsigned int maxframe; /* maximum valid frame length */
unsigned int state;
unsigned int inppos, outpos; /* positions in rx/tx buffers */
/* transmitting frame number - from frames qty to 1 */
unsigned int tx_frameno;
/* expected number of next receiving frame */
unsigned int wait_frameno;
/* count of failed attempts to frame send - 32 attempts do before
error - while receiver tunes on opposite side of wire */
unsigned int trans_errors;
/* idle time; send pong when limit exceeded */
unsigned int timer_ticks;
/* fields used for receive level autoselection */
int delta_rxl;
unsigned int cur_rxl_index, timeout_rxl;
unsigned long cur_rxl_rcvd, prev_rxl_rcvd;
struct sbni_csr1 csr1; /* current value of CSR1 */
struct sbni_in_stats in_stats; /* internal statistics */
struct net_device *second; /* for ISA/dual cards */
#ifdef CONFIG_SBNI_MULTILINE
struct net_device *master;
struct net_device *link;
#endif
};
static int sbni_card_probe( unsigned long );
static int sbni_pci_probe( struct net_device * );
static struct net_device *sbni_probe1(struct net_device *, unsigned long, int);
static int sbni_open( struct net_device * );
static int sbni_close( struct net_device * );
static netdev_tx_t sbni_start_xmit(struct sk_buff *,
struct net_device * );
static int sbni_ioctl( struct net_device *, struct ifreq *, int );
static void set_multicast_list( struct
|