Commit c8f6c77d authored by David S. Miller's avatar David S. Miller

Merge branch 'Space-cleanup'

Arnd Bergmann says:

====================
drivers/net/Space.c cleanup

I discovered that there are still a couple of drivers that rely on
beiong statically initialized from drivers/net/Space.c the way
we did in the last century. As it turns out, there are a couple
of simplifications that can be made here, as well as some minor
bugfixes.

There are four classes of drivers that use this:

- most 10mbit ISA bus ethernet drivers (and one 100mbit one)
- both ISA localtalk drivers
- several m68k ethernet drivers
- one obsolete WAN driver

I found that the drivers using in arch/m68k/ don't actually benefit
from being probed this way as they do not rely on the netdev= command
line arguments, they have simply never been changed to work like a
modern driver.

I had previously sent a patch to remove the sbni/granch driver, and
there were no objections to this patch but forgot to resend it after
some discussion about another patch in the same series.

For the ISA drivers, there is usually no way to probe multiple devices
at boot time other than the netdev= arguments, so all that logic is left
in place for the moment, but centralized in a single file that only gets
included in the kernel build if one or more of the drivers are built-in.

I'm also changing the old-style init_module() functions in these drivers
to static functions with a module_init() annotation, to more closely
resemble modern drivers. These are the last drivers in the kernel to
still use init_module/cleanup_module, removing those may enable future
cleanups to the module loading process.

       Arnd

Changes in v2:

- replace xsurf100 change with Michael's version
- make it PATCH instead of RFC
- rebase to net-next as of August 3
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 2dbf4c2e a07d8ecf
......@@ -4945,8 +4945,6 @@
sa1100ir [NET]
See drivers/net/irda/sa1100_ir.c.
sbni= [NET] Granch SBNI12 leased line adapter
sched_verbose [KNL] Enables verbose scheduler debug messages.
schedstats= [KNL,X86] Enable or disable scheduled statistics.
......
......@@ -606,4 +606,11 @@ config NET_FAILOVER
a VM with direct attached VF by failing over to the paravirtual
datapath when the VF is unplugged.
config NETDEV_LEGACY_INIT
bool
depends on ISA
help
Drivers that call netdev_boot_setup_check() should select this
symbol, everything else no longer needs it.
endif # NETDEVICES
......@@ -18,7 +18,8 @@ obj-$(CONFIG_MACVLAN) += macvlan.o
obj-$(CONFIG_MACVTAP) += macvtap.o
obj-$(CONFIG_MII) += mii.o
obj-$(CONFIG_MDIO) += mdio.o
obj-$(CONFIG_NET) += Space.o loopback.o
obj-$(CONFIG_NET) += loopback.o
obj-$(CONFIG_NETDEV_LEGACY_INIT) += Space.o
obj-$(CONFIG_NETCONSOLE) += netconsole.o
obj-y += phy/
obj-y += mdio/
......
......@@ -30,6 +30,148 @@
#include <linux/netlink.h>
#include <net/Space.h>
/*
* This structure holds boot-time configured netdevice settings. They
* are then used in the device probing.
*/
struct netdev_boot_setup {
char name[IFNAMSIZ];
struct ifmap map;
};
#define NETDEV_BOOT_SETUP_MAX 8
/******************************************************************************
*
* Device Boot-time Settings Routines
*
******************************************************************************/
/* Boot time configuration table */
static struct netdev_boot_setup dev_boot_setup[NETDEV_BOOT_SETUP_MAX];
/**
* netdev_boot_setup_add - add new setup entry
* @name: name of the device
* @map: configured settings for the device
*
* Adds new setup entry to the dev_boot_setup list. The function
* returns 0 on error and 1 on success. This is a generic routine to
* all netdevices.
*/
static int netdev_boot_setup_add(char *name, struct ifmap *map)
{
struct netdev_boot_setup *s;
int i;
s = dev_boot_setup;
for (i = 0; i < NETDEV_BOOT_SETUP_MAX; i++) {
if (s[i].name[0] == '\0' || s[i].name[0] == ' ') {
memset(s[i].name, 0, sizeof(s[i].name));
strlcpy(s[i].name, name, IFNAMSIZ);
memcpy(&s[i].map, map, sizeof(s[i].map));
break;
}
}
return i >= NETDEV_BOOT_SETUP_MAX ? 0 : 1;
}
/**
* netdev_boot_setup_check - check boot time settings
* @dev: the netdevice
*
* Check boot time settings for the device.
* The found settings are set for the device to be used
* later in the device probing.
* Returns 0 if no settings found, 1 if they are.
*/
int netdev_boot_setup_check(struct net_device *dev)
{
struct netdev_boot_setup *s = dev_boot_setup;
int i;
for (i = 0; i < NETDEV_BOOT_SETUP_MAX; i++) {
if (s[i].name[0] != '\0' && s[i].name[0] != ' ' &&
!strcmp(dev->name, s[i].name)) {
dev->irq = s[i].map.irq;
dev->base_addr = s[i].map.base_addr;
dev->mem_start = s[i].map.mem_start;
dev->mem_end = s[i].map.mem_end;
return 1;
}
}
return 0;
}
EXPORT_SYMBOL(netdev_boot_setup_check);
/**
* netdev_boot_base - get address from boot time settings
* @prefix: prefix for network device
* @unit: id for network device
*
* Check boot time settings for the base address of device.
* The found settings are set for the device to be used
* later in the device probing.
* Returns 0 if no settings found.
*/
static unsigned long netdev_boot_base(const char *prefix, int unit)
{
const struct netdev_boot_setup *s = dev_boot_setup;
char name[IFNAMSIZ];
int i;
sprintf(name, "%s%d", prefix, unit);
/*
* If device already registered then return base of 1
* to indicate not to probe for this interface
*/
if (__dev_get_by_name(&init_net, name))
return 1;
for (i = 0; i < NETDEV_BOOT_SETUP_MAX; i++)
if (!strcmp(name, s[i].name))
return s[i].map.base_addr;
return 0;
}
/*
* Saves at boot time configured settings for any netdevice.
*/
static int __init netdev_boot_setup(char *str)
{
int ints[5];
struct ifmap map;
str = get_options(str, ARRAY_SIZE(ints), ints);
if (!str || !*str)
return 0;
/* Save settings */
memset(&map, 0, sizeof(map));
if (ints[0] > 0)
map.irq = ints[1];
if (ints[0] > 1)
map.base_addr = ints[2];
if (ints[0] > 2)
map.mem_start = ints[3];
if (ints[0] > 3)
map.mem_end = ints[4];
/* Add new entry to the list */
return netdev_boot_setup_add(str, &map);
}
__setup("netdev=", netdev_boot_setup);
static int __init ether_boot_setup(char *str)
{
return netdev_boot_setup(str);
}
__setup("ether=", ether_boot_setup);
/* A unified ethernet device probe. This is the easiest way to have every
* ethernet adaptor have the name "eth[0123...]".
*/
......@@ -77,39 +219,15 @@ static struct devprobe2 isa_probes[] __initdata = {
#ifdef CONFIG_SMC9194
{smc_init, 0},
#endif
#ifdef CONFIG_CS89x0
#ifndef CONFIG_CS89x0_PLATFORM
#ifdef CONFIG_CS89x0_ISA
{cs89x0_probe, 0},
#endif
#endif
#if defined(CONFIG_MVME16x_NET) || defined(CONFIG_BVME6000_NET) /* Intel */
{i82596_probe, 0}, /* I82596 */
#endif
#ifdef CONFIG_NI65
{ni65_probe, 0},
#endif
{NULL, 0},
};
static struct devprobe2 m68k_probes[] __initdata = {
#ifdef CONFIG_ATARILANCE /* Lance-based Atari ethernet boards */
{atarilance_probe, 0},
#endif
#ifdef CONFIG_SUN3LANCE /* sun3 onboard Lance chip */
{sun3lance_probe, 0},
#endif
#ifdef CONFIG_SUN3_82586 /* sun3 onboard Intel 82586 chip */
{sun3_82586_probe, 0},
#endif
#ifdef CONFIG_APNE /* A1200 PCMCIA NE2000 */
{apne_probe, 0},
#endif
#ifdef CONFIG_MVME147_NET /* MVME147 internal Ethernet */
{mvme147lance_probe, 0},
#endif
{NULL, 0},
};
/* Unified ethernet device probe, segmented per architecture and
* per bus interface. This drives the legacy devices only for now.
*/
......@@ -121,8 +239,7 @@ static void __init ethif_probe2(int unit)
if (base_addr == 1)
return;
(void)(probe_list2(unit, m68k_probes, base_addr == 0) &&
probe_list2(unit, isa_probes, base_addr == 0));
probe_list2(unit, isa_probes, base_addr == 0);
}
/* Statically configured drivers -- order matters here. */
......@@ -130,10 +247,6 @@ static int __init net_olddevs_init(void)
{
int num;
#ifdef CONFIG_SBNI
for (num = 0; num < 8; ++num)
sbni_probe(num);
#endif
for (num = 0; num < 8; ++num)
ethif_probe2(num);
......@@ -142,9 +255,6 @@ static int __init net_olddevs_init(void)
cops_probe(1);
cops_probe(2);
#endif
#ifdef CONFIG_LTPC
ltpc_probe();
#endif
return 0;
}
......
......@@ -52,7 +52,9 @@ config LTPC
config COPS
tristate "COPS LocalTalk PC support"
depends on DEV_APPLETALK && (ISA || EISA)
depends on DEV_APPLETALK && ISA
depends on NETDEVICES
select NETDEV_LEGACY_INIT
help
This allows you to use COPS AppleTalk cards to connect to LocalTalk
networks. You also need version 1.3.3 or later of the netatalk
......
......@@ -1015,7 +1015,7 @@ static const struct net_device_ops ltpc_netdev = {
.ndo_set_rx_mode = set_multicast_list,
};
struct net_device * __init ltpc_probe(void)
static struct net_device * __init ltpc_probe(void)
{
struct net_device *dev;
int err = -ENOMEM;
......@@ -1221,12 +1221,10 @@ static int __init ltpc_setup(char *str)
}
__setup("ltpc=", ltpc_setup);
#endif /* MODULE */
#endif
static struct net_device *dev_ltpc;
#ifdef MODULE
MODULE_LICENSE("GPL");
module_param(debug, int, 0);
module_param_hw(io, int, ioport, 0);
......@@ -1244,7 +1242,6 @@ static int __init ltpc_module_init(void)
return PTR_ERR_OR_ZERO(dev_ltpc);
}
module_init(ltpc_module_init);
#endif
static void __exit ltpc_cleanup(void)
{
......
......@@ -302,7 +302,6 @@ static int el3_isa_match(struct device *pdev, unsigned int ndev)
return -ENOMEM;
SET_NETDEV_DEV(dev, pdev);
netdev_boot_setup_check(dev);
if (!request_region(ioaddr, EL3_IO_EXTENT, "3c509-isa")) {
free_netdev(dev);
......@@ -421,7 +420,6 @@ static int el3_pnp_probe(struct pnp_dev *pdev, const struct pnp_device_id *id)
return -ENOMEM;
}
SET_NETDEV_DEV(dev, &pdev->dev);
netdev_boot_setup_check(dev);
el3_dev_fill(dev, phys_addr, ioaddr, irq, if_port, EL3_PNP);
pnp_set_drvdata(pdev, dev);
......@@ -590,7 +588,6 @@ static int el3_eisa_probe(struct device *device)
}
SET_NETDEV_DEV(dev, device);
netdev_boot_setup_check(dev);
el3_dev_fill(dev, phys_addr, ioaddr, irq, if_port, EL3_EISA);
eisa_set_drvdata (edev, dev);
......
......@@ -407,7 +407,7 @@ MODULE_PARM_DESC(max_interrupt_work, "3c515 maximum events handled per interrupt
/* we will need locking (and refcounting) if we ever use it for more */
static LIST_HEAD(root_corkscrew_dev);
int init_module(void)
static int corkscrew_init_module(void)
{
int found = 0;
if (debug >= 0)
......@@ -416,6 +416,7 @@ int init_module(void)
found++;
return found ? 0 : -ENODEV;
}
module_init(corkscrew_init_module);
#else
struct net_device *tc515_probe(int unit)
......
......@@ -34,6 +34,7 @@ config EL3
config 3C515
tristate "3c515 ISA \"Fast EtherLink\""
depends on ISA && ISA_DMA_API && !PPC32
select NETDEV_LEGACY_INIT
help
If you have a 3Com ISA EtherLink XL "Corkscrew" 3c515 Fast Ethernet
network card, say Y here.
......
......@@ -102,6 +102,7 @@ config MCF8390
config NE2000
tristate "NE2000/NE1000 support"
depends on (ISA || (Q40 && m) || MACH_TX49XX || ATARI_ETHERNEC)
select NETDEV_LEGACY_INIT if ISA
select CRC32
help
If you have a network (Ethernet) card of this type, say Y here.
......@@ -169,6 +170,7 @@ config STNIC
config ULTRA
tristate "SMC Ultra support"
depends on ISA
select NETDEV_LEGACY_INIT
select CRC32
help
If you have a network (Ethernet) card of this type, say Y here.
......@@ -186,6 +188,7 @@ config ULTRA
config WD80x3
tristate "WD80*3 support"
depends on ISA
select NETDEV_LEGACY_INIT
select CRC32
help
If you have a network (Ethernet) card of this type, say Y here.
......
......@@ -75,7 +75,6 @@
#define NESM_STOP_PG 0x80 /* Last page +1 of RX ring */
struct net_device * __init apne_probe(int unit);
static int apne_probe1(struct net_device *dev, int ioaddr);
static void apne_reset_8390(struct net_device *dev);
......@@ -120,7 +119,7 @@ static u32 apne_msg_enable;
module_param_named(msg_enable, apne_msg_enable, uint, 0444);
MODULE_PARM_DESC(msg_enable, "Debug message level (see linux/netdevice.h for bitmap)");
struct net_device * __init apne_probe(int unit)
static struct net_device * __init apne_probe(void)
{
struct net_device *dev;
struct ei_device *ei_local;
......@@ -150,10 +149,6 @@ struct net_device * __init apne_probe(int unit)
dev = alloc_ei_netdev();
if (!dev)
return ERR_PTR(-ENOMEM);
if (unit >= 0) {
sprintf(dev->name, "eth%d", unit);
netdev_boot_setup_check(dev);
}
ei_local = netdev_priv(dev);
ei_local->msg_enable = apne_msg_enable;
......@@ -554,12 +549,11 @@ static irqreturn_t apne_interrupt(int irq, void *dev_id)
return IRQ_HANDLED;
}
#ifdef MODULE
static struct net_device *apne_dev;
static int __init apne_module_init(void)
{
apne_dev = apne_probe(-1);
apne_dev = apne_probe();
return PTR_ERR_OR_ZERO(apne_dev);
}
......@@ -579,7 +573,6 @@ static void __exit apne_module_exit(void)
}
module_init(apne_module_init);
module_exit(apne_module_exit);
#endif
static int init_pcmcia(void)
{
......
......@@ -101,6 +101,13 @@ static inline struct ax_device *to_ax_dev(struct net_device *dev)
return (struct ax_device *)(ei_local + 1);
}
void ax_NS8390_reinit(struct net_device *dev)
{
ax_NS8390_init(dev, 1);
}
EXPORT_SYMBOL_GPL(ax_NS8390_reinit);
/*
* ax_initial_check
*
......
......@@ -923,7 +923,7 @@ static void __init ne_add_devices(void)
}
#ifdef MODULE
int __init init_module(void)
static int __init ne_init(void)
{
int retval;
ne_add_devices();
......@@ -940,6 +940,7 @@ int __init init_module(void)
ne_loop_rm_unreg(0);
return retval;
}
module_init(ne_init);
#else /* MODULE */
static int __init ne_init(void)
{
......@@ -951,6 +952,7 @@ static int __init ne_init(void)
}
module_init(ne_init);
#ifdef CONFIG_NETDEV_LEGACY_INIT
struct net_device * __init ne_probe(int unit)
{
int this_dev;
......@@ -991,6 +993,7 @@ struct net_device * __init ne_probe(int unit)
return ERR_PTR(-ENODEV);
}
#endif
#endif /* MODULE */
static void __exit ne_exit(void)
......
......@@ -522,7 +522,6 @@ static void ultra_pio_input(struct net_device *dev, int count,
/* We know skbuffs are padded to at least word alignment. */
insw(ioaddr + IOPD, buf, (count+1)>>1);
}
static void ultra_pio_output(struct net_device *dev, int count,
const unsigned char *buf, const int start_page)
{
......@@ -572,8 +571,7 @@ MODULE_LICENSE("GPL");
/* This is set up so that only a single autoprobe takes place per call.
ISA device autoprobes on a running machine are not recommended. */
int __init
init_module(void)
static int __init ultra_init_module(void)
{
struct net_device *dev;
int this_dev, found = 0;
......@@ -600,6 +598,7 @@ init_module(void)
return 0;
return -ENXIO;
}
module_init(ultra_init_module);
static void cleanup_card(struct net_device *dev)
{
......@@ -613,8 +612,7 @@ static void cleanup_card(struct net_device *dev)
iounmap(ei_status.mem);
}
void __exit
cleanup_module(void)
static void __exit ultra_cleanup_module(void)
{
int this_dev;
......@@ -627,4 +625,5 @@ cleanup_module(void)
}
}
}
module_exit(ultra_cleanup_module);
#endif /* MODULE */
......@@ -519,7 +519,7 @@ MODULE_LICENSE("GPL");
/* This is set up so that only a single autoprobe takes place per call.
ISA device autoprobes on a running machine are not recommended. */
int __init init_module(void)
static int __init wd_init_module(void)
{
struct net_device *dev;
int this_dev, found = 0;
......@@ -548,6 +548,7 @@ int __init init_module(void)
return 0;
return -ENXIO;
}
module_init(wd_init_module);
static void cleanup_card(struct net_device *dev)
{
......@@ -556,8 +557,7 @@ static void cleanup_card(struct net_device *dev)
iounmap(ei_status.mem);
}
void __exit
cleanup_module(void)
static void __exit wd_cleanup_module(void)
{
int this_dev;
......@@ -570,4 +570,5 @@ cleanup_module(void)
}
}
}
module_exit(wd_cleanup_module);
#endif /* MODULE */
......@@ -22,8 +22,6 @@
#define XS100_8390_DATA_WRITE32_BASE 0x0C80
#define XS100_8390_DATA_AREA_SIZE 0x80
#define __NS8390_init ax_NS8390_init
/* force unsigned long back to 'void __iomem *' */
#define ax_convert_addr(_a) ((void __force __iomem *)(_a))
......@@ -42,10 +40,7 @@
/* Ensure we have our RCR base value */
#define AX88796_PLATFORM
static unsigned char version[] =
"ax88796.c: Copyright 2005,2007 Simtec Electronics\n";
#include "lib8390.c"
#include "8390.h"
/* from ne.c */
#define NE_CMD EI_SHIFT(0x00)
......@@ -232,7 +227,7 @@ static void xs100_block_output(struct net_device *dev, int count,
if (jiffies - dma_start > 2 * HZ / 100) { /* 20ms */
netdev_warn(dev, "timeout waiting for Tx RDC.\n");
ei_local->reset_8390(dev);
ax_NS8390_init(dev, 1);
ax_NS8390_reinit(dev);
break;
}
}
......
......@@ -46,6 +46,7 @@ config AMD8111_ETH
config LANCE
tristate "AMD LANCE and PCnet (AT1500 and NE2100) support"
depends on ISA && ISA_DMA_API && !ARM && !PPC32
select NETDEV_LEGACY_INIT
help
If you have a network (Ethernet) card of this type, say Y here.
Some LinkSys cards are of this type.
......@@ -132,6 +133,7 @@ config PCMCIA_NMCLAN
config NI65
tristate "NI6510 support"
depends on ISA && ISA_DMA_API && !ARM && !PPC32
select NETDEV_LEGACY_INIT
help
If you have a network (Ethernet) card of this type, say Y here.
......
......@@ -367,7 +367,7 @@ static void *slow_memcpy( void *dst, const void *src, size_t len )
}
struct net_device * __init atarilance_probe(int unit)
struct net_device * __init atarilance_probe(void)
{
int i;
static int found;
......@@ -382,10 +382,6 @@ struct net_device * __init atarilance_probe(int unit)
dev = alloc_etherdev(sizeof(struct lance_private));
if (!dev)
return ERR_PTR(-ENOMEM);
if (unit >= 0) {
sprintf(dev->name, "eth%d", unit);
netdev_boot_setup_check(dev);
}
for( i = 0; i < N_LANCE_ADDR; ++i ) {
if (lance_probe1( dev, &lance_addr_list[i] )) {
......@@ -1137,13 +1133,11 @@ static int lance_set_mac_address( struct net_device *dev, void *addr )
return 0;
}
#ifdef MODULE
static struct net_device *atarilance_dev;
static int __init atarilance_module_init(void)
{
atarilance_dev = atarilance_probe(-1);
atarilance_dev = atarilance_probe();
return PTR_ERR_OR_ZERO(atarilance_dev);
}
......@@ -1155,4 +1149,3 @@ static void __exit atarilance_module_exit(void)
}
module_init(atarilance_module_init);
module_exit(atarilance_module_exit);
#endif /* MODULE */
......@@ -327,7 +327,7 @@ MODULE_PARM_DESC(dma, "LANCE/PCnet ISA DMA channel (ignored for some devices)");
MODULE_PARM_DESC(irq, "LANCE/PCnet IRQ number (ignored for some devices)");
MODULE_PARM_DESC(lance_debug, "LANCE/PCnet debug level (0-7)");
int __init init_module(void)
static int __init lance_init_module(void)
{
struct net_device *dev;
int this_dev, found = 0;
......@@ -356,6 +356,7 @@ int __init init_module(void)
return 0;
return -ENXIO;
}
module_init(lance_init_module);
static void cleanup_card(struct net_device *dev)
{
......@@ -368,7 +369,7 @@ static void cleanup_card(struct net_device *dev)
kfree(lp);
}
void __exit cleanup_module(void)
static void __exit lance_cleanup_module(void)
{
int this_dev;
......@@ -381,6 +382,7 @@ void __exit cleanup_module(void)
}
}
}
module_exit(lance_cleanup_module);
#endif /* MODULE */
MODULE_LICENSE("GPL");
......
......@@ -68,7 +68,7 @@ static const struct net_device_ops lance_netdev_ops = {
};
/* Initialise the one and only on-board 7990 */
struct net_device * __init mvme147lance_probe(int unit)
static struct net_device * __init mvme147lance_probe(void)
{
struct net_device *dev;
static int called;
......@@ -86,9 +86,6 @@ struct net_device * __init mvme147lance_probe(int unit)
if (!dev)
return ERR_PTR(-ENOMEM);
if (unit >= 0)
sprintf(dev->name, "eth%d", unit);
/* Fill the dev fields */
dev->base_addr = (unsigned long)MVME147_LANCE_BASE;
dev->netdev_ops = &lance_netdev_ops;
......@@ -179,22 +176,21 @@ static int m147lance_close(struct net_device *dev)
return 0;
}
#ifdef MODULE
MODULE_LICENSE("GPL");
static struct net_device *dev_mvme147_lance;
int __init init_module(void)
static int __init m147lance_init(void)
{
dev_mvme147_lance = mvme147lance_probe(-1);
dev_mvme147_lance = mvme147lance_probe();
return PTR_ERR_OR_ZERO(dev_mvme147_lance);
}
module_init(m147lance_init);
void __exit cleanup_module(void)
static void __exit m147lance_exit(void)
{
struct m147lance_private *lp = netdev_priv(dev_mvme147_lance);
unregister_netdev(dev_mvme147_lance);
free_pages(lp->ram, 3);
free_netdev(dev_mvme147_lance);
}
#endif /* MODULE */
module_exit(m147lance_exit);
......@@ -1230,18 +1230,20 @@ MODULE_PARM_DESC(irq, "ni6510 IRQ number (ignored for some cards)");
MODULE_PARM_DESC(io, "ni6510 I/O base address");
MODULE_PARM_DESC(dma, "ni6510 ISA DMA channel (ignored for some cards)");
int __init init_module(void)
static int __init ni65_init_module(void)
{
dev_ni65 = ni65_probe(-1);
return PTR_ERR_OR_ZERO(dev_ni65);
}
module_init(ni65_init_module);
void __exit cleanup_module(void)
static void __exit ni65_cleanup_module(void)
{
unregister_netdev(dev_ni65);
cleanup_card(dev_ni65);
free_netdev(dev_ni65);
}
module_exit(ni65_cleanup_module);
#endif /* MODULE */
MODULE_LICENSE("GPL");
......@@ -245,7 +245,7 @@ static void set_multicast_list( struct net_device *dev );
/************************* End of Prototypes **************************/
struct net_device * __init sun3lance_probe(int unit)
static struct net_device * __init sun3lance_probe(void)
{
struct net_device *dev;
static int found;
......@@ -272,10 +272,6 @@ struct net_device * __init sun3lance_probe(int unit)
dev = alloc_etherdev(sizeof(struct lance_private));
if (!dev)
return ERR_PTR(-ENOMEM);
if (unit >= 0) {
sprintf(dev->name, "eth%d", unit);
netdev_boot_setup_check(dev);
}
if (!lance_probe(dev))
goto out;
......@@ -924,17 +920,16 @@ static void set_multicast_list( struct net_device *dev )
}
#ifdef MODULE
static struct net_device *sun3lance_dev;
int __init init_module(void)
static int __init sun3lance_init(void)
{
sun3lance_dev = sun3lance_probe(-1);
sun3lance_dev = sun3lance_probe();
return PTR_ERR_OR_ZERO(sun3lance_dev);
}
module_init(sun3lance_init);
void __exit cleanup_module(void)
static void __exit sun3lance_cleanup(void)
{
unregister_netdev(sun3lance_dev);
#ifdef CONFIG_SUN3
......@@ -942,6 +937,4 @@ void __exit cleanup_module(void)
#endif
free_netdev(sun3lance_dev);
}
#endif /* MODULE */
module_exit(sun3lance_cleanup);
......@@ -3972,8 +3972,6 @@ static int bcmgenet_probe(struct platform_device *pdev)
*/
dev->needed_headroom += 64;
netdev_boot_setup_check(dev);
priv->dev = dev;
priv->pdev = pdev;
......
......@@ -6,7 +6,7 @@
config NET_VENDOR_CIRRUS
bool "Cirrus devices"
default y
depends on ISA || EISA || ARM || MAC
depends on ISA || EISA || ARM || MAC || COMPILE_TEST
help
If you have a network (Ethernet) card belonging to this class, say Y.
......@@ -18,9 +18,16 @@ config NET_VENDOR_CIRRUS
if NET_VENDOR_CIRRUS
config CS89x0
tristate "CS89x0 support"
depends on ISA || EISA || ARM
tristate
config CS89x0_ISA
tristate "CS89x0 ISA driver support"
depends on HAS_IOPORT_MAP
depends on ISA
depends on !PPC32
depends on CS89x0_PLATFORM=n
select NETDEV_LEGACY_INIT
select CS89x0
help
Support for CS89x0 chipset based Ethernet cards. If you have a
network (Ethernet) card of this type, say Y and read the file
......@@ -30,15 +37,15 @@ config CS89x0
will be called cs89x0.
config CS89x0_PLATFORM
bool "CS89x0 platform driver support" if HAS_IOPORT_MAP
default !HAS_IOPORT_MAP
depends on CS89x0
tristate "CS89x0 platform driver support"
depends on ARM || COMPILE_TEST
select CS89x0
help
Say Y to compile the cs89x0 driver as a platform driver. This
makes this driver suitable for use on certain evaluation boards
such as the iMX21ADS.
Say Y to compile the cs89x0 platform driver. This makes this driver
suitable for use on certain evaluation boards such as the iMX21ADS.
If you are unsure, say N.
To compile this driver as a module, choose M here. The module
will be called cs89x0.
config EP93XX_ETH
tristate "EP93xx Ethernet support"
......
......@@ -104,7 +104,7 @@ static char version[] __initdata =
* them to system IRQ numbers. This mapping is card specific and is set to
* the configuration of the Cirrus Eval board for this chip.
*/
#ifndef CONFIG_CS89x0_PLATFORM
#if IS_ENABLED(CONFIG_CS89x0_ISA)
static unsigned int netcard_portlist[] __used __initdata = {
0x300, 0x320, 0x340, 0x360, 0x200, 0x220, 0x240,
0x260, 0x280, 0x2a0, 0x2c0, 0x2e0, 0
......@@ -292,7 +292,7 @@ write_irq(struct net_device *dev, int chip_type, int irq)
int i;
if (chip_type == CS8900) {
#ifndef CONFIG_CS89x0_PLATFORM
#if IS_ENABLED(CONFIG_CS89x0_ISA)
/* Search the mapping table for the corresponding IRQ pin. */
for (i = 0; i != ARRAY_SIZE(cs8900_irq_map); i++)
if (cs8900_irq_map[i] == irq)
......@@ -859,7 +859,7 @@ net_open(struct net_device *dev)
goto bad_out;
}
} else {
#if !defined(CONFIG_CS89x0_PLATFORM)
#if IS_ENABLED(CONFIG_CS89x0_ISA)
if (((1 << dev->irq) & lp->irq_map) == 0) {
pr_err("%s: IRQ %d is not in our map of allowable IRQs, which is %x\n",
dev->name, dev->irq, lp->irq_map);
......@@ -1523,7 +1523,7 @@ cs89x0_probe1(struct net_device *dev, void __iomem *ioaddr, int modular)
dev->irq = i;
} else {
i = lp->isa_config & INT_NO_MASK;
#ifndef CONFIG_CS89x0_PLATFORM
#if IS_ENABLED(CONFIG_CS89x0_ISA)
if (lp->chip_type == CS8900) {
/* Translate the IRQ using the IRQ mapping table. */
if (i >= ARRAY_SIZE(cs8900_irq_map))
......@@ -1576,7 +1576,7 @@ cs89x0_probe1(struct net_device *dev, void __iomem *ioaddr, int modular)
return retval;
}
#ifndef CONFIG_CS89x0_PLATFORM
#if IS_ENABLED(CONFIG_CS89x0_ISA)
/*
* This function converts the I/O port address used by the cs89x0_probe() and
* init_module() functions to the I/O memory address used by the
......@@ -1682,11 +1682,7 @@ struct net_device * __init cs89x0_probe(int unit)
pr_warn("no cs8900 or cs8920 detected. Be sure to disable PnP with SETUP\n");
return ERR_PTR(err);
}
#endif
#endif
#if defined(MODULE) && !defined(CONFIG_CS89x0_PLATFORM)
#else
static struct net_device *dev_cs89x0;
/* Support the 'debug' module parm even if we're compiled for non-debug to
......@@ -1757,9 +1753,9 @@ MODULE_LICENSE("GPL");
* (hw or software util)
*/
int __init init_module(void)
static int __init cs89x0_isa_init_module(void)
{
struct net_device *dev = alloc_etherdev(sizeof(struct net_local));
struct net_device *dev;
struct net_local *lp;
int ret = 0;
......@@ -1768,6 +1764,7 @@ int __init init_module(void)
#else
debug = 0;
#endif
dev = alloc_etherdev(sizeof(struct net_local));
if (!dev)
return -ENOMEM;
......@@ -1826,9 +1823,9 @@ int __init init_module(void)
free_netdev(dev);
return ret;
}
module_init(cs89x0_isa_init_module);
void __exit
cleanup_module(void)
static void __exit cs89x0_isa_cleanup_module(void)
{
struct net_local *lp = netdev_priv(dev_cs89x0);
......@@ -1838,9 +1835,11 @@ cleanup_module(void)
release_region(dev_cs89x0->base_addr, NETCARD_IO_EXTENT);
free_netdev(dev_cs89x0);
}
#endif /* MODULE && !CONFIG_CS89x0_PLATFORM */
module_exit(cs89x0_isa_cleanup_module);
#endif /* MODULE */
#endif /* CONFIG_CS89x0_ISA */
#ifdef CONFIG_CS89x0_PLATFORM
#if IS_ENABLED(CONFIG_CS89x0_PLATFORM)
static int __init cs89x0_platform_probe(struct platform_device *pdev)
{
struct net_device *dev = alloc_etherdev(sizeof(struct net_local));
......
......@@ -1110,9 +1110,6 @@ static void print_eth(unsigned char *add, char *str)
add, add + 6, add, add[12], add[13], str);
}
static int io = 0x300;
static int irq = 10;
static const struct net_device_ops i596_netdev_ops = {
.ndo_open = i596_open,
.ndo_stop = i596_close,
......@@ -1123,7 +1120,7 @@ static const struct net_device_ops i596_netdev_ops = {
.ndo_validate_addr = eth_validate_addr,
};
struct net_device * __init i82596_probe(int unit)
static struct net_device * __init i82596_probe(void)
{
struct net_device *dev;
int i;
......@@ -1140,14 +1137,6 @@ struct net_device * __init i82596_probe(int unit)
if (!dev)
return ERR_PTR(-ENOMEM);
if (unit >= 0) {
sprintf(dev->name, "eth%d", unit);
netdev_boot_setup_check(dev);
} else {
dev->base_addr = io;
dev->irq = irq;
}
#ifdef ENABLE_MVME16x_NET
if (MACH_IS_MVME16x) {
if (mvme16x_config & MVME16x_CONFIG_NO_ETHERNET) {
......@@ -1515,22 +1504,22 @@ static void set_multicast_list(struct net_device *dev)
}
}
#ifdef MODULE
static struct net_device *dev_82596;
static int debug = -1;
module_param(debug, int, 0);
MODULE_PARM_DESC(debug, "i82596 debug mask");
int __init init_module(void)
static int __init i82596_init(void)
{
if (debug >= 0)
i596_debug = debug;
dev_82596 = i82596_probe(-1);
dev_82596 = i82596_probe();
return PTR_ERR_OR_ZERO(dev_82596);
}
module_init(i82596_init);
void __exit cleanup_module(void)
static void __exit i82596_cleanup(void)
{
unregister_netdev(dev_82596);
#ifdef __mc68000__
......@@ -1544,5 +1533,4 @@ void __exit cleanup_module(void)
free_page ((u32)(dev_82596->mem_start));
free_netdev(dev_82596);
}
#endif /* MODULE */
module_exit(i82596_cleanup);
......@@ -29,6 +29,7 @@ static int rfdadd = 0; /* rfdadd=1 may be better for 8K MEM cards */
static int fifo=0x8; /* don't change */
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/string.h>
#include <linux/errno.h>
#include <linux/ioport.h>
......@@ -276,7 +277,7 @@ static void alloc586(struct net_device *dev)
memset((char *)p->scb,0,sizeof(struct scb_struct));
}
struct net_device * __init sun3_82586_probe(int unit)
static int __init sun3_82586_probe(void)
{
struct net_device *dev;
unsigned long ioaddr;
......@@ -291,25 +292,20 @@ struct net_device * __init sun3_82586_probe(int unit)
break;
default:
return ERR_PTR(-ENODEV);
return -ENODEV;
}
if (found)
return ERR_PTR(-ENODEV);
return -ENODEV;
ioaddr = (unsigned long)ioremap(IE_OBIO, SUN3_82586_TOTAL_SIZE);
if (!ioaddr)
return ERR_PTR(-ENOMEM);
return -ENOMEM;
found = 1;
dev = alloc_etherdev(sizeof(struct priv));
if (!dev)
goto out;
if (unit >= 0) {
sprintf(dev->name, "eth%d", unit);
netdev_boot_setup_check(dev);
}
dev->irq = IE_IRQ;
dev->base_addr = ioaddr;
err = sun3_82586_probe1(dev, ioaddr);
......@@ -326,8 +322,9 @@ struct net_device * __init sun3_82586_probe(int unit)
free_netdev(dev);
out:
iounmap((void __iomem *)ioaddr);
return ERR_PTR(err);
return err;
}
module_init(sun3_82586_probe);
static const struct net_device_ops sun3_82586_netdev_ops = {
.ndo_open = sun3_82586_open,
......
......@@ -193,8 +193,6 @@ static int jazz_sonic_probe(struct platform_device *pdev)
SET_NETDEV_DEV(dev, &pdev->dev);
platform_set_drvdata(pdev, dev);
netdev_boot_setup_check(dev);
dev->base_addr = res->start;
dev->irq = platform_get_irq(pdev, 0);
err = sonic_probe1(dev);
......
......@@ -215,7 +215,6 @@ int xtsonic_probe(struct platform_device *pdev)
lp->device = &pdev->dev;
platform_set_drvdata(pdev, dev);
SET_NETDEV_DEV(dev, &pdev->dev);
netdev_boot_setup_check(dev);
dev->base_addr = resmem->start;
dev->irq = resirq->start;
......
......@@ -23,6 +23,7 @@ config SMC9194
tristate "SMC 9194 support"
depends on ISA
select CRC32
select NETDEV_LEGACY_INIT
help
This is support for the SMC9xxx based Ethernet cards. Choose this
option if you have a DELL laptop with the docking station, or
......
......@@ -1508,7 +1508,7 @@ MODULE_PARM_DESC(io, "SMC 99194 I/O base address");
MODULE_PARM_DESC(irq, "SMC 99194 IRQ number");
MODULE_PARM_DESC(ifport, "SMC 99194 interface port (0-default, 1-TP, 2-AUI)");
int __init init_module(void)
static int __init smc_init_module(void)
{
if (io == 0)
printk(KERN_WARNING
......@@ -1518,13 +1518,15 @@ int __init init_module(void)
devSMC9194 = smc_init(-1);
return PTR_ERR_OR_ZERO(devSMC9194);
}
module_init(smc_init_module);
void __exit cleanup_module(void)
static void __exit smc_cleanup_module(void)
{
unregister_netdev(devSMC9194);
free_irq(devSMC9194->irq, devSMC9194);
release_region(devSMC9194->base_addr, SMC_IO_EXTENT);
free_netdev(devSMC9194);
}
module_exit(smc_cleanup_module);
#endif /* MODULE */
......@@ -290,30 +290,6 @@ config SLIC_DS26522
To compile this driver as a module, choose M here: the
module will be called slic_ds26522.
config DSCC4_PCISYNC
bool "Etinc PCISYNC features"
depends on DSCC4
help
Due to Etinc's design choice for its PCISYNC cards, some operations
are only allowed on specific ports of the DSCC4. This option is the
only way for the driver to know that it shouldn't return a success
code for these operations.
Please say Y if your card is an Etinc's PCISYNC.
config DSCC4_PCI_RST
bool "Hard reset support"
depends on DSCC4
help
Various DSCC4 bugs forbid any reliable software reset of the ASIC.
As a replacement, some vendors provide a way to assert the PCI #RST
pin of DSCC4 through the GPIO port of the card. If you choose Y,
the driver will make use of this feature before module removal
(i.e. rmmod). The feature is known to be available on Commtech's
cards. Contact your manufacturer for details.
Say Y if your card supports this feature.
config IXP4XX_HSS
tristate "Intel IXP4xx HSS (synchronous serial port) support"
depends on HDLC && IXP4XX_NPE && IXP4XX_QMGR
......@@ -337,33 +313,6 @@ config LAPBETHER
To compile this driver as a module, choose M here: the
module will be called lapbether.
If unsure, say N.
config SBNI
tristate "Granch SBNI12 Leased Line adapter support"
depends on X86
help
Driver for ISA SBNI12-xx cards which are low cost alternatives to
leased line modems.
You can find more information and last versions of drivers and
utilities at <http://www.granch.ru/>. If you have any question you
can send email to <sbni@granch.ru>.
To compile this driver as a module, choose M here: the
module will be called sbni.
If unsure, say N.
config SBNI_MULTILINE
bool "Multiple line feature support"
depends on SBNI
help
Schedule traffic for some parallel lines, via SBNI12 adapters.
If you have two computers connected with two parallel lines it's
possible to increase transfer rate nearly twice. You should have
a program named 'sbniconfig' to configure adapters.
If unsure, say N.
......
......@@ -22,7 +22,6 @@ obj-$(CONFIG_FARSYNC) += farsync.o
obj-$(CONFIG_LANMEDIA) += lmc/
obj-$(CONFIG_LAPBETHER) += lapbether.o
obj-$(CONFIG_SBNI) += sbni.o
obj-$(CONFIG_N2) += n2.o
obj-$(CONFIG_C101) += c101.o
obj-$(CONFIG_WANXL) += wanxl.o
......
......@@ -319,16 +319,18 @@ MODULE_DESCRIPTION("Modular driver for the Comtrol Hostess SV11");
static struct z8530_dev *sv11_unit;
int init_module(void)
static int sv11_module_init(void)
{
sv11_unit = sv11_init(io, irq);
if (!sv11_unit)
return -ENODEV;
return 0;
}
module_init(sv11_module_init);
void cleanup_module(void)
static void sv11_module_cleanup(void)
{
if (sv11_unit)
sv11_shutdown(sv11_unit);
}
module_exit(sv11_module_cleanup);
/* 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_siocdevprivate(struct net_device *, struct ifreq *,
void __user *, int);
static void set_multicast_list( struct net_device * );
static irqreturn_t sbni_interrupt( int, void * );
static void handle_channel( struct net_device * );
static int recv_frame( struct net_device * );
static void send_frame( struct net_device * );
static int upload_data( struct net_device *,
unsigned, unsigned, unsigned, u32 );
static void download_data( struct net_device *, u32 * );
static void sbni_watchdog(struct timer_list *);
static void interpret_ack( struct net_device *, unsigned );
static int append_frame_to_pkt( struct net_device *, unsigned, u32 );
static void indicate_pkt( struct net_device * );
static void card_start( struct net_device * );
static void prepare_to_send( struct sk_buff *, struct net_device * );
static void drop_xmit_queue( struct net_device * );
static void send_frame_header( struct net_device *, u32 * );
static int skip_tail( unsigned int, unsigned int, u32 );
static int check_fhdr( u32, u32 *, u32 *, u32 *, u32 *, u32 * );
static void change_level( struct net_device * );
static void timeout_change_level( struct net_device * );
static u32 calc_crc32( u32, u8 *, u32 );
static struct sk_buff * get_rx_buf( struct net_device * );
static int sbni_init( struct net_device * );
#ifdef CONFIG_SBNI_MULTILINE
static int enslave( struct net_device *, struct net_device * );
static int emancipate( struct net_device * );
#endif
static const char version[] =
"Granch SBNI12 driver ver 5.0.1 Jun 22 2001 Denis I.Timofeev.\n";
static bool skip_pci_probe __initdata = false;
static int scandone __initdata = 0;
static int num __initdata = 0;
static unsigned char rxl_tab[];
static u32 crc32tab[];
/* A list of all installed devices, for removing the driver module. */
static struct net_device *sbni_cards[ SBNI_MAX_NUM_CARDS ];
/* Lists of device's parameters */
static u32 io[ SBNI_MAX_NUM_CARDS ] __initdata =
{ [0 ... SBNI_MAX_NUM_CARDS-1] = -1 };
static u32 irq[ SBNI_MAX_NUM_CARDS ] __initdata;
static u32 baud[ SBNI_MAX_NUM_CARDS ] __initdata;
static u32 rxl[ SBNI_MAX_NUM_CARDS ] __initdata =
{ [0 ... SBNI_MAX_NUM_CARDS-1] = -1 };
static u32 mac[ SBNI_MAX_NUM_CARDS ] __initdata;
#ifndef MODULE
typedef u32 iarr[];
static iarr *dest[5] __initdata = { &io, &irq, &baud, &rxl, &mac };
#endif
/* A zero-terminated list of I/O addresses to be probed on ISA bus */
static unsigned int netcard_portlist[ ] __initdata = {
0x210, 0x214, 0x220, 0x224, 0x230, 0x234, 0x240, 0x244, 0x250, 0x254,
0x260, 0x264, 0x270, 0x274, 0x280, 0x284, 0x290, 0x294, 0x2a0, 0x2a4,
0x2b0, 0x2b4, 0x2c0, 0x2c4, 0x2d0, 0x2d4, 0x2e0, 0x2e4, 0x2f0, 0x2f4,
0 };
#define NET_LOCAL_LOCK(dev) (((struct net_local *)netdev_priv(dev))->lock)
/*
* Look for SBNI card which addr stored in dev->base_addr, if nonzero.
* Otherwise, look through PCI bus. If none PCI-card was found, scan ISA.
*/
static inline int __init
sbni_isa_probe( struct net_device *dev )
{
if( dev->base_addr > 0x1ff &&
request_region( dev->base_addr, SBNI_IO_EXTENT, dev->name ) &&
sbni_probe1( dev, dev->base_addr, dev->irq ) )
return 0;
else {
pr_err("base address 0x%lx is busy, or adapter is malfunctional!\n",
dev->base_addr);
return -ENODEV;
}
}
static const struct net_device_ops sbni_netdev_ops = {
.ndo_open = sbni_open,
.ndo_stop = sbni_close,
.ndo_start_xmit = sbni_start_xmit,
.ndo_set_rx_mode = set_multicast_list,
.ndo_siocdevprivate = sbni_siocdevprivate,
.ndo_set_mac_address = eth_mac_addr,
.ndo_validate_addr = eth_validate_addr,
};
static void __init sbni_devsetup(struct net_device *dev)
{
ether_setup( dev );
dev->netdev_ops = &sbni_netdev_ops;
}
int __init sbni_probe(int unit)
{
struct net_device *dev;
int err;
dev = alloc_netdev(sizeof(struct net_local), "sbni",
NET_NAME_UNKNOWN, sbni_devsetup);
if (!dev)
return -ENOMEM;
dev->netdev_ops = &sbni_netdev_ops;
sprintf(dev->name, "sbni%d", unit);
netdev_boot_setup_check(dev);
err = sbni_init(dev);
if (err) {
free_netdev(dev);
return err;
}
err = register_netdev(dev);
if (err) {
release_region( dev->base_addr, SBNI_IO_EXTENT );
free_netdev(dev);
return err;
}
pr_info_once("%s", version);
return 0;
}
static int __init sbni_init(struct net_device *dev)
{
int i;
if( dev->base_addr )
return sbni_isa_probe( dev );
/* otherwise we have to perform search our adapter */
if( io[ num ] != -1 ) {
dev->base_addr = io[ num ];
dev->irq = irq[ num ];
} else if( scandone || io[ 0 ] != -1 ) {
return -ENODEV;
}
/* if io[ num ] contains non-zero address, then that is on ISA bus */
if( dev->base_addr )
return sbni_isa_probe( dev );
/* ...otherwise - scan PCI first */
if( !skip_pci_probe && !sbni_pci_probe( dev ) )
return 0;
if( io[ num ] == -1 ) {
/* Auto-scan will be stopped when first ISA card were found */
scandone = 1;
if( num > 0 )
return -ENODEV;
}
for( i = 0; netcard_portlist[ i ]; ++i ) {
int ioaddr = netcard_portlist[ i ];
if( request_region( ioaddr, SBNI_IO_EXTENT, dev->name ) &&
sbni_probe1( dev, ioaddr, 0 ))
return 0;
}
return -ENODEV;
}
static int __init
sbni_pci_probe( struct net_device *dev )
{
struct pci_dev *pdev = NULL;
while( (pdev = pci_get_class( PCI_CLASS_NETWORK_OTHER << 8, pdev ))
!= NULL ) {
int pci_irq_line;
unsigned long pci_ioaddr;
if( pdev->vendor != SBNI_PCI_VENDOR &&
pdev->device != SBNI_PCI_DEVICE )
continue;
pci_ioaddr = pci_resource_start( pdev, 0 );
pci_irq_line = pdev->irq;
/* Avoid already found cards from previous calls */
if( !request_region( pci_ioaddr, SBNI_IO_EXTENT, dev->name ) ) {
if (pdev->subsystem_device != 2)
continue;
/* Dual adapter is present */
if (!request_region(pci_ioaddr += 4, SBNI_IO_EXTENT,
dev->name ) )
continue;
}
if (pci_irq_line <= 0 || pci_irq_line >= nr_irqs)
pr_warn(
"WARNING: The PCI BIOS assigned this PCI card to IRQ %d, which is unlikely to work!.\n"
"You should use the PCI BIOS setup to assign a valid IRQ line.\n",
pci_irq_line );
/* avoiding re-enable dual adapters */
if( (pci_ioaddr & 7) == 0 && pci_enable_device( pdev ) ) {
release_region( pci_ioaddr, SBNI_IO_EXTENT );
pci_dev_put( pdev );
return -EIO;
}
if( sbni_probe1( dev, pci_ioaddr, pci_irq_line ) ) {
SET_NETDEV_DEV(dev, &pdev->dev);
/* not the best thing to do, but this is all messed up
for hotplug systems anyway... */
pci_dev_put( pdev );
return 0;
}
}
return -ENODEV;
}
static struct net_device * __init
sbni_probe1( struct net_device *dev, unsigned long ioaddr, int irq )
{
struct net_local *nl;
if( sbni_card_probe( ioaddr ) ) {
release_region( ioaddr, SBNI_IO_EXTENT );
return NULL;
}
outb( 0, ioaddr + CSR0 );
if( irq < 2 ) {
unsigned long irq_mask;
irq_mask = probe_irq_on();
outb( EN_INT | TR_REQ, ioaddr + CSR0 );
outb( PR_RES, ioaddr + CSR1 );
mdelay(50);
irq = probe_irq_off(irq_mask);
outb( 0, ioaddr + CSR0 );
if( !irq ) {
pr_err("%s: can't detect device irq!\n", dev->name);
release_region( ioaddr, SBNI_IO_EXTENT );
return NULL;
}
} else if( irq == 2 )
irq = 9;
dev->irq = irq;
dev->base_addr = ioaddr;
/* Fill in sbni-specific dev fields. */
nl = netdev_priv(dev);
if( !nl ) {
pr_err("%s: unable to get memory!\n", dev->name);
release_region( ioaddr, SBNI_IO_EXTENT );
return NULL;
}
memset( nl, 0, sizeof(struct net_local) );
spin_lock_init( &nl->lock );
/* store MAC address (generate if that isn't known) */
*(__be16 *)dev->dev_addr = htons( 0x00ff );
*(__be32 *)(dev->dev_addr + 2) = htonl( 0x01000000 |
((mac[num] ?
mac[num] :
(u32)((long)netdev_priv(dev))) & 0x00ffffff));
/* store link settings (speed, receive level ) */
nl->maxframe = DEFAULT_FRAME_LEN;
nl->csr1.rate = baud[ num ];
if( (nl->cur_rxl_index = rxl[ num ]) == -1 ) {
/* autotune rxl */
nl->cur_rxl_index = DEF_RXL;
nl->delta_rxl = DEF_RXL_DELTA;
} else {
nl->delta_rxl = 0;
}
nl->csr1.rxl = rxl_tab[ nl->cur_rxl_index ];
if( inb( ioaddr + CSR0 ) & 0x01 )
nl->state |= FL_SLOW_MODE;
pr_notice("%s: ioaddr %#lx, irq %d, MAC: 00:ff:01:%02x:%02x:%02x\n",
dev->name, dev->base_addr, dev->irq,
((u8 *)dev->dev_addr)[3],
((u8 *)dev->dev_addr)[4],
((u8 *)dev->dev_addr)[5]);
pr_notice("%s: speed %d",
dev->name,
((nl->state & FL_SLOW_MODE) ? 500000 : 2000000)
/ (1 << nl->csr1.rate));
if( nl->delta_rxl == 0 )
pr_cont(", receive level 0x%x (fixed)\n", nl->cur_rxl_index);
else
pr_cont(", receive level (auto)\n");
#ifdef CONFIG_SBNI_MULTILINE
nl->master = dev;
nl->link = NULL;
#endif
sbni_cards[ num++ ] = dev;
return dev;
}
/* -------------------------------------------------------------------------- */
#ifdef CONFIG_SBNI_MULTILINE
static netdev_tx_t
sbni_start_xmit( struct sk_buff *skb, struct net_device *dev )
{
struct net_device *p;
netif_stop_queue( dev );
/* Looking for idle device in the list */
for( p = dev; p; ) {
struct net_local *nl = netdev_priv(p);
spin_lock( &nl->lock );
if( nl->tx_buf_p || (nl->state & FL_LINE_DOWN) ) {
p = nl->link;
spin_unlock( &nl->lock );
} else {
/* Idle dev is found */
prepare_to_send( skb, p );
spin_unlock( &nl->lock );
netif_start_queue( dev );
return NETDEV_TX_OK;
}
}
return NETDEV_TX_BUSY;
}
#else /* CONFIG_SBNI_MULTILINE */
static netdev_tx_t
sbni_start_xmit( struct sk_buff *skb, struct net_device *dev )
{
struct net_local *nl = netdev_priv(dev);
netif_stop_queue( dev );
spin_lock( &nl->lock );
prepare_to_send( skb, dev );
spin_unlock( &nl->lock );
return NETDEV_TX_OK;
}
#endif /* CONFIG_SBNI_MULTILINE */
/* -------------------------------------------------------------------------- */
/* interrupt handler */
/*
* SBNI12D-10, -11/ISA boards within "common interrupt" mode could not
* be looked as two independent single-channel devices. Every channel seems
* as Ethernet interface but interrupt handler must be common. Really, first
* channel ("master") driver only registers the handler. In its struct net_local
* it has got pointer to "slave" channel's struct net_local and handles that's
* interrupts too.
* dev of successfully attached ISA SBNI boards is linked to list.
* While next board driver is initialized, it scans this list. If one
* has found dev with same irq and ioaddr different by 4 then it assumes
* this board to be "master".
*/
static irqreturn_t
sbni_interrupt( int irq, void *dev_id )
{
struct net_device *dev = dev_id;
struct net_local *nl = netdev_priv(dev);
int repeat;
spin_lock( &nl->lock );
if( nl->second )
spin_lock(&NET_LOCAL_LOCK(nl->second));
do {
repeat = 0;
if( inb( dev->base_addr + CSR0 ) & (RC_RDY | TR_RDY) ) {
handle_channel( dev );
repeat = 1;
}
if( nl->second && /* second channel present */
(inb( nl->second->base_addr+CSR0 ) & (RC_RDY | TR_RDY)) ) {
handle_channel( nl->second );
repeat = 1;
}
} while( repeat );
if( nl->second )
spin_unlock(&NET_LOCAL_LOCK(nl->second));
spin_unlock( &nl->lock );
return IRQ_HANDLED;
}
static void
handle_channel( struct net_device *dev )
{
struct net_local *nl = netdev_priv(dev);
unsigned long ioaddr = dev->base_addr;
int req_ans;
unsigned char csr0;
#ifdef CONFIG_SBNI_MULTILINE
/* Lock the master device because we going to change its local data */
if( nl->state & FL_SLAVE )
spin_lock(&NET_LOCAL_LOCK(nl->master));
#endif
outb( (inb( ioaddr + CSR0 ) & ~EN_INT) | TR_REQ, ioaddr + CSR0 );
nl->timer_ticks = CHANGE_LEVEL_START_TICKS;
for(;;) {
csr0 = inb( ioaddr + CSR0 );
if( ( csr0 & (RC_RDY | TR_RDY) ) == 0 )
break;
req_ans = !(nl->state & FL_PREV_OK);
if( csr0 & RC_RDY )
req_ans = recv_frame( dev );
/*
* TR_RDY always equals 1 here because we have owned the marker,
* and we set TR_REQ when disabled interrupts
*/
csr0 = inb( ioaddr + CSR0 );
if( !(csr0 & TR_RDY) || (csr0 & RC_RDY) )
netdev_err(dev, "internal error!\n");
/* if state & FL_NEED_RESEND != 0 then tx_frameno != 0 */
if( req_ans || nl->tx_frameno != 0 )
send_frame( dev );
else
/* send marker without any data */
outb( inb( ioaddr + CSR0 ) & ~TR_REQ, ioaddr + CSR0 );
}
outb( inb( ioaddr + CSR0 ) | EN_INT, ioaddr + CSR0 );
#ifdef CONFIG_SBNI_MULTILINE
if( nl->state & FL_SLAVE )
spin_unlock(&NET_LOCAL_LOCK(nl->master));
#endif
}
/*
* Routine returns 1 if it needs to acknowledge received frame.
* Empty frame received without errors won't be acknowledged.
*/
static int
recv_frame( struct net_device *dev )
{
struct net_local *nl = netdev_priv(dev);
unsigned long ioaddr = dev->base_addr;
u32 crc = CRC32_INITIAL;
unsigned framelen = 0, frameno, ack;
unsigned is_first, frame_ok = 0;
if( check_fhdr( ioaddr, &framelen, &frameno, &ack, &is_first, &crc ) ) {
frame_ok = framelen > 4
? upload_data( dev, framelen, frameno, is_first, crc )
: skip_tail( ioaddr, framelen, crc );
if( frame_ok )
interpret_ack( dev, ack );
}
outb( inb( ioaddr + CSR0 ) ^ CT_ZER, ioaddr + CSR0 );
if( frame_ok ) {
nl->state |= FL_PREV_OK;
if( framelen > 4 )
nl->in_stats.all_rx_number++;
} else {
nl->state &= ~FL_PREV_OK;
change_level( dev );
nl->in_stats.all_rx_number++;
nl->in_stats.bad_rx_number++;
}
return !frame_ok || framelen > 4;
}
static void
send_frame( struct net_device *dev )
{
struct net_local *nl = netdev_priv(dev);
u32 crc = CRC32_INITIAL;
if( nl->state & FL_NEED_RESEND ) {
/* if frame was sended but not ACK'ed - resend it */
if( nl->trans_errors ) {
--nl->trans_errors;
if( nl->framelen != 0 )
nl->in_stats.resend_tx_number++;
} else {
/* cannot xmit with many attempts */
#ifdef CONFIG_SBNI_MULTILINE
if( (nl->state & FL_SLAVE) || nl->link )
#endif
nl->state |= FL_LINE_DOWN;
drop_xmit_queue( dev );
goto do_send;
}
} else
nl->trans_errors = TR_ERROR_COUNT;
send_frame_header( dev, &crc );
nl->state |= FL_NEED_RESEND;
/*
* FL_NEED_RESEND will be cleared after ACK, but if empty
* frame sended then in prepare_to_send next frame
*/
if( nl->framelen ) {
download_data( dev, &crc );
nl->in_stats.all_tx_number++;
nl->state |= FL_WAIT_ACK;
}
outsb( dev->base_addr + DAT, (u8 *)&crc, sizeof crc );
do_send:
outb( inb( dev->base_addr + CSR0 ) & ~TR_REQ, dev->base_addr + CSR0 );
if( nl->tx_frameno )
/* next frame exists - we request card to send it */
outb( inb( dev->base_addr + CSR0 ) | TR_REQ,
dev->base_addr + CSR0 );
}
/*
* Write the frame data into adapter's buffer memory, and calculate CRC.
* Do padding if necessary.
*/
static void
download_data( struct net_device *dev, u32 *crc_p )
{
struct net_local *nl = netdev_priv(dev);
struct sk_buff *skb = nl->tx_buf_p;
unsigned len = min_t(unsigned int, skb->len - nl->outpos, nl->framelen);
outsb( dev->base_addr + DAT, skb->data + nl->outpos, len );
*crc_p = calc_crc32( *crc_p, skb->data + nl->outpos, len );
/* if packet too short we should write some more bytes to pad */
for( len = nl->framelen - len; len--; ) {
outb( 0, dev->base_addr + DAT );
*crc_p = CRC32( 0, *crc_p );
}
}
static int
upload_data( struct net_device *dev, unsigned framelen, unsigned frameno,
unsigned is_first, u32 crc )
{
struct net_local *nl = netdev_priv(dev);
int frame_ok;
if( is_first ) {
nl->wait_frameno = frameno;
nl->inppos = 0;
}
if( nl->wait_frameno == frameno ) {
if( nl->inppos + framelen <= ETHER_MAX_LEN )
frame_ok = append_frame_to_pkt( dev, framelen, crc );
/*
* if CRC is right but framelen incorrect then transmitter
* error was occurred... drop entire packet
*/
else if( (frame_ok = skip_tail( dev->base_addr, framelen, crc ))
!= 0 ) {
nl->wait_frameno = 0;
nl->inppos = 0;
#ifdef CONFIG_SBNI_MULTILINE
nl->master->stats.rx_errors++;
nl->master->stats.rx_missed_errors++;
#else
dev->stats.rx_errors++;
dev->stats.rx_missed_errors++;
#endif
}
/* now skip all frames until is_first != 0 */
} else
frame_ok = skip_tail( dev->base_addr, framelen, crc );
if( is_first && !frame_ok ) {
/*
* Frame has been broken, but we had already stored
* is_first... Drop entire packet.
*/
nl->wait_frameno = 0;
#ifdef CONFIG_SBNI_MULTILINE
nl->master->stats.rx_errors++;
nl->master->stats.rx_crc_errors++;
#else
dev->stats.rx_errors++;
dev->stats.rx_crc_errors++;
#endif
}
return frame_ok;
}
static inline void
send_complete( struct net_device *dev )
{
struct net_local *nl = netdev_priv(dev);
#ifdef CONFIG_SBNI_MULTILINE
nl->master->stats.tx_packets++;
nl->master->stats.tx_bytes += nl->tx_buf_p->len;
#else
dev->stats.tx_packets++;
dev->stats.tx_bytes += nl->tx_buf_p->len;
#endif
dev_consume_skb_irq(nl->tx_buf_p);
nl->tx_buf_p = NULL;
nl->outpos = 0;
nl->state &= ~(FL_WAIT_ACK | FL_NEED_RESEND);
nl->framelen = 0;
}
static void
interpret_ack( struct net_device *dev, unsigned ack )
{
struct net_local *nl = netdev_priv(dev);
if( ack == FRAME_SENT_OK ) {
nl->state &= ~FL_NEED_RESEND;
if( nl->state & FL_WAIT_ACK ) {
nl->outpos += nl->framelen;
if( --nl->tx_frameno ) {
nl->framelen = min_t(unsigned int,
nl->maxframe,
nl->tx_buf_p->len - nl->outpos);
} else {
send_complete( dev );
#ifdef CONFIG_SBNI_MULTILINE
netif_wake_queue( nl->master );
#else
netif_wake_queue( dev );
#endif
}
}
}
nl->state &= ~FL_WAIT_ACK;
}
/*
* Glue received frame with previous fragments of packet.
* Indicate packet when last frame would be accepted.
*/
static int
append_frame_to_pkt( struct net_device *dev, unsigned framelen, u32 crc )
{
struct net_local *nl = netdev_priv(dev);
u8 *p;
if( nl->inppos + framelen > ETHER_MAX_LEN )
return 0;
if( !nl->rx_buf_p && !(nl->rx_buf_p = get_rx_buf( dev )) )
return 0;
p = nl->rx_buf_p->data + nl->inppos;
insb( dev->base_addr + DAT, p, framelen );
if( calc_crc32( crc, p, framelen ) != CRC32_REMAINDER )
return 0;
nl->inppos += framelen - 4;
if( --nl->wait_frameno == 0 ) /* last frame received */
indicate_pkt( dev );
return 1;
}
/*
* Prepare to start output on adapter.
* Transmitter will be actually activated when marker is accepted.
*/
static void
prepare_to_send( struct sk_buff *skb, struct net_device *dev )
{
struct net_local *nl = netdev_priv(dev);
unsigned int len;
/* nl->tx_buf_p == NULL here! */
if( nl->tx_buf_p )
netdev_err(dev, "memory leak!\n");
nl->outpos = 0;
nl->state &= ~(FL_WAIT_ACK | FL_NEED_RESEND);
len = skb->len;
if( len < SBNI_MIN_LEN )
len = SBNI_MIN_LEN;
nl->tx_buf_p = skb;
nl->tx_frameno = DIV_ROUND_UP(len, nl->maxframe);
nl->framelen = len < nl->maxframe ? len : nl->maxframe;
outb( inb( dev->base_addr + CSR0 ) | TR_REQ, dev->base_addr + CSR0 );
#ifdef CONFIG_SBNI_MULTILINE
netif_trans_update(nl->master);
#else
netif_trans_update(dev);
#endif
}
static void
drop_xmit_queue( struct net_device *dev )
{
struct net_local *nl = netdev_priv(dev);
if( nl->tx_buf_p ) {
dev_kfree_skb_any( nl->tx_buf_p );
nl->tx_buf_p = NULL;
#ifdef CONFIG_SBNI_MULTILINE
nl->master->stats.tx_errors++;
nl->master->stats.tx_carrier_errors++;
#else
dev->stats.tx_errors++;
dev->stats.tx_carrier_errors++;
#endif
}
nl->tx_frameno = 0;
nl->framelen = 0;
nl->outpos = 0;
nl->state &= ~(FL_WAIT_ACK | FL_NEED_RESEND);
#ifdef CONFIG_SBNI_MULTILINE
netif_start_queue( nl->master );
netif_trans_update(nl->master);
#else
netif_start_queue( dev );
netif_trans_update(dev);
#endif
}
static void
send_frame_header( struct net_device *dev, u32 *crc_p )
{
struct net_local *nl = netdev_priv(dev);
u32 crc = *crc_p;
u32 len_field = nl->framelen + 6; /* CRC + frameno + reserved */
u8 value;
if( nl->state & FL_NEED_RESEND )
len_field |= FRAME_RETRY; /* non-first attempt... */
if( nl->outpos == 0 )
len_field |= FRAME_FIRST;
len_field |= (nl->state & FL_PREV_OK) ? FRAME_SENT_OK : FRAME_SENT_BAD;
outb( SBNI_SIG, dev->base_addr + DAT );
value = (u8) len_field;
outb( value, dev->base_addr + DAT );
crc = CRC32( value, crc );
value = (u8) (len_field >> 8);
outb( value, dev->base_addr + DAT );
crc = CRC32( value, crc );
outb( nl->tx_frameno, dev->base_addr + DAT );
crc = CRC32( nl->tx_frameno, crc );
outb( 0, dev->base_addr + DAT );
crc = CRC32( 0, crc );
*crc_p = crc;
}
/*
* if frame tail not needed (incorrect number or received twice),
* it won't store, but CRC will be calculated
*/
static int
skip_tail( unsigned int ioaddr, unsigned int tail_len, u32 crc )
{
while( tail_len-- )
crc = CRC32( inb( ioaddr + DAT ), crc );
return crc == CRC32_REMAINDER;
}
/*
* Preliminary checks if frame header is correct, calculates its CRC
* and split it to simple fields
*/
static int
check_fhdr( u32 ioaddr, u32 *framelen, u32 *frameno, u32 *ack,
u32 *is_first, u32 *crc_p )
{
u32 crc = *crc_p;
u8 value;
if( inb( ioaddr + DAT ) != SBNI_SIG )
return 0;
value = inb( ioaddr + DAT );
*framelen = (u32)value;
crc = CRC32( value, crc );
value = inb( ioaddr + DAT );
*framelen |= ((u32)value) << 8;
crc = CRC32( value, crc );
*ack = *framelen & FRAME_ACK_MASK;
*is_first = (*framelen & FRAME_FIRST) != 0;
if( (*framelen &= FRAME_LEN_MASK) < 6 ||
*framelen > SBNI_MAX_FRAME - 3 )
return 0;
value = inb( ioaddr + DAT );
*frameno = (u32)value;
crc = CRC32( value, crc );
crc = CRC32( inb( ioaddr + DAT ), crc ); /* reserved byte */
*framelen -= 2;
*crc_p = crc;
return 1;
}
static struct sk_buff *
get_rx_buf( struct net_device *dev )
{
/* +2 is to compensate for the alignment fixup below */
struct sk_buff *skb = dev_alloc_skb( ETHER_MAX_LEN + 2 );
if( !skb )
return NULL;
skb_reserve( skb, 2 ); /* Align IP on longword boundaries */
return skb;
}
static void
indicate_pkt( struct net_device *dev )
{
struct net_local *nl = netdev_priv(dev);
struct sk_buff *skb = nl->rx_buf_p;
skb_put( skb, nl->inppos );
#ifdef CONFIG_SBNI_MULTILINE
skb->protocol = eth_type_trans( skb, nl->master );
netif_rx( skb );
++nl->master->stats.rx_packets;
nl->master->stats.rx_bytes += nl->inppos;
#else
skb->protocol = eth_type_trans( skb, dev );
netif_rx( skb );
++dev->stats.rx_packets;
dev->stats.rx_bytes += nl->inppos;
#endif
nl->rx_buf_p = NULL; /* protocol driver will clear this sk_buff */
}
/* -------------------------------------------------------------------------- */
/*
* Routine checks periodically wire activity and regenerates marker if
* connect was inactive for a long time.
*/
static void
sbni_watchdog(struct timer_list *t)
{
struct net_local *nl = from_timer(nl, t, watchdog);
struct net_device *dev = nl->watchdog_dev;
unsigned long flags;
unsigned char csr0;
spin_lock_irqsave( &nl->lock, flags );
csr0 = inb( dev->base_addr + CSR0 );
if( csr0 & RC_CHK ) {
if( nl->timer_ticks ) {
if( csr0 & (RC_RDY | BU_EMP) )
/* receiving not active */
nl->timer_ticks--;
} else {
nl->in_stats.timeout_number++;
if( nl->delta_rxl )
timeout_change_level( dev );
outb( *(u_char *)&nl->csr1 | PR_RES,
dev->base_addr + CSR1 );
csr0 = inb( dev->base_addr + CSR0 );
}
} else
nl->state &= ~FL_LINE_DOWN;
outb( csr0 | RC_CHK, dev->base_addr + CSR0 );
mod_timer(t, jiffies + SBNI_TIMEOUT);
spin_unlock_irqrestore( &nl->lock, flags );
}
static unsigned char rxl_tab[] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x08,
0x0a, 0x0c, 0x0f, 0x16, 0x18, 0x1a, 0x1c, 0x1f
};
#define SIZE_OF_TIMEOUT_RXL_TAB 4
static unsigned char timeout_rxl_tab[] = {
0x03, 0x05, 0x08, 0x0b
};
/* -------------------------------------------------------------------------- */
static void
card_start( struct net_device *dev )
{
struct net_local *nl = netdev_priv(dev);
nl->timer_ticks = CHANGE_LEVEL_START_TICKS;
nl->state &= ~(FL_WAIT_ACK | FL_NEED_RESEND);
nl->state |= FL_PREV_OK;
nl->inppos = nl->outpos = 0;
nl->wait_frameno = 0;
nl->tx_frameno = 0;
nl->framelen = 0;
outb( *(u_char *)&nl->csr1 | PR_RES, dev->base_addr + CSR1 );
outb( EN_INT, dev->base_addr + CSR0 );
}
/* -------------------------------------------------------------------------- */
/* Receive level auto-selection */
static void
change_level( struct net_device *dev )
{
struct net_local *nl = netdev_priv(dev);
if( nl->delta_rxl == 0 ) /* do not auto-negotiate RxL */
return;
if( nl->cur_rxl_index == 0 )
nl->delta_rxl = 1;
else if( nl->cur_rxl_index == 15 )
nl->delta_rxl = -1;
else if( nl->cur_rxl_rcvd < nl->prev_rxl_rcvd )
nl->delta_rxl = -nl->delta_rxl;
nl->csr1.rxl = rxl_tab[ nl->cur_rxl_index += nl->delta_rxl ];
inb( dev->base_addr + CSR0 ); /* needs for PCI cards */
outb( *(u8 *)&nl->csr1, dev->base_addr + CSR1 );
nl->prev_rxl_rcvd = nl->cur_rxl_rcvd;
nl->cur_rxl_rcvd = 0;
}
static void
timeout_change_level( struct net_device *dev )
{
struct net_local *nl = netdev_priv(dev);
nl->cur_rxl_index = timeout_rxl_tab[ nl->timeout_rxl ];
if( ++nl->timeout_rxl >= 4 )
nl->timeout_rxl = 0;
nl->csr1.rxl = rxl_tab[ nl->cur_rxl_index ];
inb( dev->base_addr + CSR0 );
outb( *(unsigned char *)&nl->csr1, dev->base_addr + CSR1 );
nl->prev_rxl_rcvd = nl->cur_rxl_rcvd;
nl->cur_rxl_rcvd = 0;
}
/* -------------------------------------------------------------------------- */
/*
* Open/initialize the board.
*/
static int
sbni_open( struct net_device *dev )
{
struct net_local *nl = netdev_priv(dev);
struct timer_list *w = &nl->watchdog;
/*
* For double ISA adapters within "common irq" mode, we have to
* determine whether primary or secondary channel is initialized,
* and set the irq handler only in first case.
*/
if( dev->base_addr < 0x400 ) { /* ISA only */
struct net_device **p = sbni_cards;
for( ; *p && p < sbni_cards + SBNI_MAX_NUM_CARDS; ++p )
if( (*p)->irq == dev->irq &&
((*p)->base_addr == dev->base_addr + 4 ||
(*p)->base_addr == dev->base_addr - 4) &&
(*p)->flags & IFF_UP ) {
((struct net_local *) (netdev_priv(*p)))
->second = dev;
netdev_notice(dev, "using shared irq with %s\n",
(*p)->name);
nl->state |= FL_SECONDARY;
goto handler_attached;
}
}
if( request_irq(dev->irq, sbni_interrupt, IRQF_SHARED, dev->name, dev) ) {
netdev_err(dev, "unable to get IRQ %d\n", dev->irq);
return -EAGAIN;
}
handler_attached:
spin_lock( &nl->lock );
memset( &dev->stats, 0, sizeof(struct net_device_stats) );
memset( &nl->in_stats, 0, sizeof(struct sbni_in_stats) );
card_start( dev );
netif_start_queue( dev );
/* set timer watchdog */
nl->watchdog_dev = dev;
timer_setup(w, sbni_watchdog, 0);
w->expires = jiffies + SBNI_TIMEOUT;
add_timer( w );
spin_unlock( &nl->lock );
return 0;
}
static int
sbni_close( struct net_device *dev )
{
struct net_local *nl = netdev_priv(dev);
if( nl->second && nl->second->flags & IFF_UP ) {
netdev_notice(dev, "Secondary channel (%s) is active!\n",
nl->second->name);
return -EBUSY;
}
#ifdef CONFIG_SBNI_MULTILINE
if( nl->state & FL_SLAVE )
emancipate( dev );
else
while( nl->link ) /* it's master device! */
emancipate( nl->link );
#endif
spin_lock( &nl->lock );
nl->second = NULL;
drop_xmit_queue( dev );
netif_stop_queue( dev );
del_timer( &nl->watchdog );
outb( 0, dev->base_addr + CSR0 );
if( !(nl->state & FL_SECONDARY) )
free_irq( dev->irq, dev );
nl->state &= FL_SECONDARY;
spin_unlock( &nl->lock );
return 0;
}
/*
Valid combinations in CSR0 (for probing):
VALID_DECODER 0000,0011,1011,1010
; 0 ; -
TR_REQ ; 1 ; +
TR_RDY ; 2 ; -
TR_RDY TR_REQ ; 3 ; +
BU_EMP ; 4 ; +
BU_EMP TR_REQ ; 5 ; +
BU_EMP TR_RDY ; 6 ; -
BU_EMP TR_RDY TR_REQ ; 7 ; +
RC_RDY ; 8 ; +
RC_RDY TR_REQ ; 9 ; +
RC_RDY TR_RDY ; 10 ; -
RC_RDY TR_RDY TR_REQ ; 11 ; -
RC_RDY BU_EMP ; 12 ; -
RC_RDY BU_EMP TR_REQ ; 13 ; -
RC_RDY BU_EMP TR_RDY ; 14 ; -
RC_RDY BU_EMP TR_RDY TR_REQ ; 15 ; -
*/
#define VALID_DECODER (2 + 8 + 0x10 + 0x20 + 0x80 + 0x100 + 0x200)
static int
sbni_card_probe( unsigned long ioaddr )
{
unsigned char csr0;
csr0 = inb( ioaddr + CSR0 );
if( csr0 != 0xff && csr0 != 0x00 ) {
csr0 &= ~EN_INT;
if( csr0 & BU_EMP )
csr0 |= EN_INT;
if( VALID_DECODER & (1 << (csr0 >> 4)) )
return 0;
}
return -ENODEV;
}
/* -------------------------------------------------------------------------- */
static int
sbni_siocdevprivate(struct net_device *dev, struct ifreq *ifr, void __user *data, int cmd)
{
struct net_local *nl = netdev_priv(dev);
struct sbni_flags flags;
int error = 0;
#ifdef CONFIG_SBNI_MULTILINE
struct net_device *slave_dev;
char slave_name[ 8 ];
#endif
switch( cmd ) {
case SIOCDEVGETINSTATS :
if (copy_to_user(data, &nl->in_stats,
sizeof(struct sbni_in_stats)))
error = -EFAULT;
break;
case SIOCDEVRESINSTATS :
if (!capable(CAP_NET_ADMIN))
return -EPERM;
memset( &nl->in_stats, 0, sizeof(struct sbni_in_stats) );
break;
case SIOCDEVGHWSTATE :
flags.mac_addr = *(u32 *)(dev->dev_addr + 3);
flags.rate = nl->csr1.rate;
flags.slow_mode = (nl->state & FL_SLOW_MODE) != 0;
flags.rxl = nl->cur_rxl_index;
flags.fixed_rxl = nl->delta_rxl == 0;
if (copy_to_user(data, &flags, sizeof(flags)))
error = -EFAULT;
break;
case SIOCDEVSHWSTATE :
if (!capable(CAP_NET_ADMIN))
return -EPERM;
spin_lock( &nl->lock );
flags = *(struct sbni_flags*) &ifr->ifr_ifru;
if( flags.fixed_rxl ) {
nl->delta_rxl = 0;
nl->cur_rxl_index = flags.rxl;
} else {
nl->delta_rxl = DEF_RXL_DELTA;
nl->cur_rxl_index = DEF_RXL;
}
nl->csr1.rxl = rxl_tab[ nl->cur_rxl_index ];
nl->csr1.rate = flags.rate;
outb( *(u8 *)&nl->csr1 | PR_RES, dev->base_addr + CSR1 );
spin_unlock( &nl->lock );
break;
#ifdef CONFIG_SBNI_MULTILINE
case SIOCDEVENSLAVE :
if (!capable(CAP_NET_ADMIN))
return -EPERM;
if (copy_from_user(slave_name, data, sizeof(slave_name)))
return -EFAULT;
slave_dev = dev_get_by_name(&init_net, slave_name );
if( !slave_dev || !(slave_dev->flags & IFF_UP) ) {
netdev_err(dev, "trying to enslave non-active device %s\n",
slave_name);
if (slave_dev)
dev_put(slave_dev);
return -EPERM;
}
return enslave( dev, slave_dev );
case SIOCDEVEMANSIPATE :
if (!capable(CAP_NET_ADMIN))
return -EPERM;
return emancipate( dev );
#endif /* CONFIG_SBNI_MULTILINE */
default :
return -EOPNOTSUPP;
}
return error;
}
#ifdef CONFIG_SBNI_MULTILINE
static int
enslave( struct net_device *dev, struct net_device *slave_dev )
{
struct net_local *nl = netdev_priv(dev);
struct net_local *snl = netdev_priv(slave_dev);
if( nl->state & FL_SLAVE ) /* This isn't master or free device */
return -EBUSY;
if( snl->state & FL_SLAVE ) /* That was already enslaved */
return -EBUSY;
spin_lock( &nl->lock );
spin_lock( &snl->lock );
/* append to list */
snl->link = nl->link;
nl->link = slave_dev;
snl->master = dev;
snl->state |= FL_SLAVE;
/* Summary statistics of MultiLine operation will be stored
in master's counters */
memset( &slave_dev->stats, 0, sizeof(struct net_device_stats) );
netif_stop_queue( slave_dev );
netif_wake_queue( dev ); /* Now we are able to transmit */
spin_unlock( &snl->lock );
spin_unlock( &nl->lock );
netdev_notice(dev, "slave device (%s) attached\n", slave_dev->name);
return 0;
}
static int
emancipate( struct net_device *dev )
{
struct net_local *snl = netdev_priv(dev);
struct net_device *p = snl->master;
struct net_local *nl = netdev_priv(p);
if( !(snl->state & FL_SLAVE) )
return -EINVAL;
spin_lock( &nl->lock );
spin_lock( &snl->lock );
drop_xmit_queue( dev );
/* exclude from list */
for(;;) { /* must be in list */
struct net_local *t = netdev_priv(p);
if( t->link == dev ) {
t->link = snl->link;
break;
}
p = t->link;
}
snl->link = NULL;
snl->master = dev;
snl->state &= ~FL_SLAVE;
netif_start_queue( dev );
spin_unlock( &snl->lock );
spin_unlock( &nl->lock );
dev_put( dev );
return 0;
}
#endif
static void
set_multicast_list( struct net_device *dev )
{
return; /* sbni always operate in promiscuos mode */
}
#ifdef MODULE
module_param_hw_array(io, int, ioport, NULL, 0);
module_param_hw_array(irq, int, irq, NULL, 0);
module_param_array(baud, int, NULL, 0);
module_param_array(rxl, int, NULL, 0);
module_param_array(mac, int, NULL, 0);
module_param(skip_pci_probe, bool, 0);
MODULE_LICENSE("GPL");
int __init init_module( void )
{
struct net_device *dev;
int err;
while( num < SBNI_MAX_NUM_CARDS ) {
dev = alloc_netdev(sizeof(struct net_local), "sbni%d",
NET_NAME_UNKNOWN, sbni_devsetup);
if( !dev)
break;
sprintf( dev->name, "sbni%d", num );
err = sbni_init(dev);
if (err) {
free_netdev(dev);
break;
}
if( register_netdev( dev ) ) {
release_region( dev->base_addr, SBNI_IO_EXTENT );
free_netdev( dev );
break;
}
}
return *sbni_cards ? 0 : -ENODEV;
}
void
cleanup_module(void)
{
int i;
for (i = 0; i < SBNI_MAX_NUM_CARDS; ++i) {
struct net_device *dev = sbni_cards[i];
if (dev != NULL) {
unregister_netdev(dev);
release_region(dev->base_addr, SBNI_IO_EXTENT);
free_netdev(dev);
}
}
}
#else /* MODULE */
static int __init
sbni_setup( char *p )
{
int n, parm;
if( *p++ != '(' )
goto bad_param;
for( n = 0, parm = 0; *p && n < 8; ) {
(*dest[ parm ])[ n ] = simple_strtoul( p, &p, 0 );
if( !*p || *p == ')' )
return 1;
if( *p == ';' ) {
++p;
++n;
parm = 0;
} else if( *p++ != ',' ) {
break;
} else {
if( ++parm >= 5 )
break;
}
}
bad_param:
pr_err("Error in sbni kernel parameter!\n");
return 0;
}
__setup( "sbni=", sbni_setup );
#endif /* MODULE */
/* -------------------------------------------------------------------------- */
static u32
calc_crc32( u32 crc, u8 *p, u32 len )
{
while( len-- )
crc = CRC32( *p++, crc );
return crc;
}
static u32 crc32tab[] __attribute__ ((aligned(8))) = {
0xD202EF8D, 0xA505DF1B, 0x3C0C8EA1, 0x4B0BBE37,
0xD56F2B94, 0xA2681B02, 0x3B614AB8, 0x4C667A2E,
0xDCD967BF, 0xABDE5729, 0x32D70693, 0x45D03605,
0xDBB4A3A6, 0xACB39330, 0x35BAC28A, 0x42BDF21C,
0xCFB5FFE9, 0xB8B2CF7F, 0x21BB9EC5, 0x56BCAE53,
0xC8D83BF0, 0xBFDF0B66, 0x26D65ADC, 0x51D16A4A,
0xC16E77DB, 0xB669474D, 0x2F6016F7, 0x58672661,
0xC603B3C2, 0xB1048354, 0x280DD2EE, 0x5F0AE278,
0xE96CCF45, 0x9E6BFFD3, 0x0762AE69, 0x70659EFF,
0xEE010B5C, 0x99063BCA, 0x000F6A70, 0x77085AE6,
0xE7B74777, 0x90B077E1, 0x09B9265B, 0x7EBE16CD,
0xE0DA836E, 0x97DDB3F8, 0x0ED4E242, 0x79D3D2D4,
0xF4DBDF21, 0x83DCEFB7, 0x1AD5BE0D, 0x6DD28E9B,
0xF3B61B38, 0x84B12BAE, 0x1DB87A14, 0x6ABF4A82,
0xFA005713, 0x8D076785, 0x140E363F, 0x630906A9,
0xFD6D930A, 0x8A6AA39C, 0x1363F226, 0x6464C2B0,
0xA4DEAE1D, 0xD3D99E8B, 0x4AD0CF31, 0x3DD7FFA7,
0xA3B36A04, 0xD4B45A92, 0x4DBD0B28, 0x3ABA3BBE,
0xAA05262F, 0xDD0216B9, 0x440B4703, 0x330C7795,
0xAD68E236, 0xDA6FD2A0, 0x4366831A, 0x3461B38C,
0xB969BE79, 0xCE6E8EEF, 0x5767DF55, 0x2060EFC3,
0xBE047A60, 0xC9034AF6, 0x500A1B4C, 0x270D2BDA,
0xB7B2364B, 0xC0B506DD, 0x59BC5767, 0x2EBB67F1,
0xB0DFF252, 0xC7D8C2C4, 0x5ED1937E, 0x29D6A3E8,
0x9FB08ED5, 0xE8B7BE43, 0x71BEEFF9, 0x06B9DF6F,
0x98DD4ACC, 0xEFDA7A5A, 0x76D32BE0, 0x01D41B76,
0x916B06E7, 0xE66C3671, 0x7F6567CB, 0x0862575D,
0x9606C2FE, 0xE101F268, 0x7808A3D2, 0x0F0F9344,
0x82079EB1, 0xF500AE27, 0x6C09FF9D, 0x1B0ECF0B,
0x856A5AA8, 0xF26D6A3E, 0x6B643B84, 0x1C630B12,
0x8CDC1683, 0xFBDB2615, 0x62D277AF, 0x15D54739,
0x8BB1D29A, 0xFCB6E20C, 0x65BFB3B6, 0x12B88320,
0x3FBA6CAD, 0x48BD5C3B, 0xD1B40D81, 0xA6B33D17,
0x38D7A8B4, 0x4FD09822, 0xD6D9C998, 0xA1DEF90E,
0x3161E49F, 0x4666D409, 0xDF6F85B3, 0xA868B525,
0x360C2086, 0x410B1010, 0xD80241AA, 0xAF05713C,
0x220D7CC9, 0x550A4C5F, 0xCC031DE5, 0xBB042D73,
0x2560B8D0, 0x52678846, 0xCB6ED9FC, 0xBC69E96A,
0x2CD6F4FB, 0x5BD1C46D, 0xC2D895D7, 0xB5DFA541,
0x2BBB30E2, 0x5CBC0074, 0xC5B551CE, 0xB2B26158,
0x04D44C65, 0x73D37CF3, 0xEADA2D49, 0x9DDD1DDF,
0x03B9887C, 0x74BEB8EA, 0xEDB7E950, 0x9AB0D9C6,
0x0A0FC457, 0x7D08F4C1, 0xE401A57B, 0x930695ED,
0x0D62004E, 0x7A6530D8, 0xE36C6162, 0x946B51F4,
0x19635C01, 0x6E646C97, 0xF76D3D2D, 0x806A0DBB,
0x1E0E9818, 0x6909A88E, 0xF000F934, 0x8707C9A2,
0x17B8D433, 0x60BFE4A5, 0xF9B6B51F, 0x8EB18589,
0x10D5102A, 0x67D220BC, 0xFEDB7106, 0x89DC4190,
0x49662D3D, 0x3E611DAB, 0xA7684C11, 0xD06F7C87,
0x4E0BE924, 0x390CD9B2, 0xA0058808, 0xD702B89E,
0x47BDA50F, 0x30BA9599, 0xA9B3C423, 0xDEB4F4B5,
0x40D06116, 0x37D75180, 0xAEDE003A, 0xD9D930AC,
0x54D13D59, 0x23D60DCF, 0xBADF5C75, 0xCDD86CE3,
0x53BCF940, 0x24BBC9D6, 0xBDB2986C, 0xCAB5A8FA,
0x5A0AB56B, 0x2D0D85FD, 0xB404D447, 0xC303E4D1,
0x5D677172, 0x2A6041E4, 0xB369105E, 0xC46E20C8,
0x72080DF5, 0x050F3D63, 0x9C066CD9, 0xEB015C4F,
0x7565C9EC, 0x0262F97A, 0x9B6BA8C0, 0xEC6C9856,
0x7CD385C7, 0x0BD4B551, 0x92DDE4EB, 0xE5DAD47D,
0x7BBE41DE, 0x0CB97148, 0x95B020F2, 0xE2B71064,
0x6FBF1D91, 0x18B82D07, 0x81B17CBD, 0xF6B64C2B,
0x68D2D988, 0x1FD5E91E, 0x86DCB8A4, 0xF1DB8832,
0x616495A3, 0x1663A535, 0x8F6AF48F, 0xF86DC419,
0x660951BA, 0x110E612C, 0x88073096, 0xFF000000
};
/* sbni.h: definitions for a Granch SBNI12 driver, version 5.0.0
* Written 2001 Denis I.Timofeev (timofeev@granch.ru)
* This file is distributed under the GNU GPL
*/
#ifndef SBNI_H
#define SBNI_H
#ifdef SBNI_DEBUG
#define DP( A ) A
#else
#define DP( A )
#endif
/* We don't have official vendor id yet... */
#define SBNI_PCI_VENDOR 0x55
#define SBNI_PCI_DEVICE 0x9f
#define ISA_MODE 0x00
#define PCI_MODE 0x01
#define SBNI_IO_EXTENT 4
enum sbni_reg {
CSR0 = 0,
CSR1 = 1,
DAT = 2
};
/* CSR0 mapping */
enum {
BU_EMP = 0x02,
RC_CHK = 0x04,
CT_ZER = 0x08,
TR_REQ = 0x10,
TR_RDY = 0x20,
EN_INT = 0x40,
RC_RDY = 0x80
};
/* CSR1 mapping */
#define PR_RES 0x80
struct sbni_csr1 {
#ifdef __LITTLE_ENDIAN_BITFIELD
u8 rxl : 5;
u8 rate : 2;
u8 : 1;
#else
u8 : 1;
u8 rate : 2;
u8 rxl : 5;
#endif
};
/* fields in frame header */
#define FRAME_ACK_MASK (unsigned short)0x7000
#define FRAME_LEN_MASK (unsigned short)0x03FF
#define FRAME_FIRST (unsigned short)0x8000
#define FRAME_RETRY (unsigned short)0x0800
#define FRAME_SENT_BAD (unsigned short)0x4000
#define FRAME_SENT_OK (unsigned short)0x3000
/* state flags */
enum {
FL_WAIT_ACK = 0x01,
FL_NEED_RESEND = 0x02,
FL_PREV_OK = 0x04,
FL_SLOW_MODE = 0x08,
FL_SECONDARY = 0x10,
#ifdef CONFIG_SBNI_MULTILINE
FL_SLAVE = 0x20,
#endif
FL_LINE_DOWN = 0x40
};
enum {
DEFAULT_IOBASEADDR = 0x210,
DEFAULT_INTERRUPTNUMBER = 5,
DEFAULT_RATE = 0,
DEFAULT_FRAME_LEN = 1012
};
#define DEF_RXL_DELTA -1
#define DEF_RXL 0xf
#define SBNI_SIG 0x5a
#define SBNI_MIN_LEN 60 /* Shortest Ethernet frame without FCS */
#define SBNI_MAX_FRAME 1023
#define ETHER_MAX_LEN 1518
#define SBNI_TIMEOUT (HZ/10)
#define TR_ERROR_COUNT 32
#define CHANGE_LEVEL_START_TICKS 4
#define SBNI_MAX_NUM_CARDS 16
/* internal SBNI-specific statistics */
struct sbni_in_stats {
u32 all_rx_number;
u32 bad_rx_number;
u32 timeout_number;
u32 all_tx_number;
u32 resend_tx_number;
};
/* SBNI ioctl params */
#define SIOCDEVGETINSTATS SIOCDEVPRIVATE
#define SIOCDEVRESINSTATS SIOCDEVPRIVATE+1
#define SIOCDEVGHWSTATE SIOCDEVPRIVATE+2
#define SIOCDEVSHWSTATE SIOCDEVPRIVATE+3
#define SIOCDEVENSLAVE SIOCDEVPRIVATE+4
#define SIOCDEVEMANSIPATE SIOCDEVPRIVATE+5
/* data packet for SIOCDEVGHWSTATE/SIOCDEVSHWSTATE ioctl requests */
struct sbni_flags {
u32 rxl : 4;
u32 rate : 2;
u32 fixed_rxl : 1;
u32 slow_mode : 1;
u32 mac_addr : 24;
};
/*
* CRC-32 stuff
*/
#define CRC32(c,crc) (crc32tab[((size_t)(crc) ^ (c)) & 0xff] ^ (((crc) >> 8) & 0x00FFFFFF))
/* CRC generator 0xEDB88320 */
/* CRC remainder 0x2144DF1C */
/* CRC initial value 0x00000000 */
#define CRC32_REMAINDER 0x2144DF1C
#define CRC32_INITIAL 0x00000000
#ifndef __initdata
#define __initdata
#endif
#endif
......@@ -295,18 +295,6 @@ enum netdev_state_t {
};
/*
* This structure holds boot-time configured netdevice settings. They
* are then used in the device probing.
*/
struct netdev_boot_setup {
char name[IFNAMSIZ];
struct ifmap map;
};
#define NETDEV_BOOT_SETUP_MAX 8
int __init netdev_boot_setup(char *str);
struct gro_list {
struct list_head list;
int count;
......@@ -2939,7 +2927,6 @@ static inline struct net_device *first_net_device_rcu(struct net *net)
}
int netdev_boot_setup_check(struct net_device *dev);
unsigned long netdev_boot_base(const char *prefix, int unit);
struct net_device *dev_getbyhwaddr_rcu(struct net *net, unsigned short type,
const char *hwaddr);
struct net_device *dev_getfirstbyhwtype(struct net *net, unsigned short type);
......
......@@ -8,23 +8,13 @@ struct net_device *ultra_probe(int unit);
struct net_device *wd_probe(int unit);
struct net_device *ne_probe(int unit);
struct net_device *fmv18x_probe(int unit);
struct net_device *i82596_probe(int unit);
struct net_device *ni65_probe(int unit);
struct net_device *sonic_probe(int unit);
struct net_device *smc_init(int unit);
struct net_device *atarilance_probe(int unit);
struct net_device *sun3lance_probe(int unit);
struct net_device *sun3_82586_probe(int unit);
struct net_device *apne_probe(int unit);
struct net_device *cs89x0_probe(int unit);
struct net_device *mvme147lance_probe(int unit);
struct net_device *tc515_probe(int unit);
struct net_device *lance_probe(int unit);
struct net_device *cops_probe(int unit);
struct net_device *ltpc_probe(void);
/* Fibre Channel adapters */
int iph5526_probe(struct net_device *dev);
/* SBNI adapters */
int sbni_probe(int unit);
......@@ -38,4 +38,7 @@ struct ax_plat_data {
int (*check_irq)(struct platform_device *pdev);
};
/* exported from ax88796.c for xsurf100.c */
extern void ax_NS8390_reinit(struct net_device *dev);
#endif /* __NET_AX88796_PLAT_H */
......@@ -1221,7 +1221,7 @@ trace_initcall_start_cb(void *data, initcall_t fn)
{
ktime_t *calltime = (ktime_t *)data;
printk(KERN_DEBUG "calling %pS @ %i\n", fn, task_pid_nr(current));
printk(KERN_DEBUG "calling %pS @ %i irqs_disabled() %d\n", fn, task_pid_nr(current), irqs_disabled());
*calltime = ktime_get();
}
......@@ -1235,8 +1235,8 @@ trace_initcall_finish_cb(void *data, initcall_t fn, int ret)
rettime = ktime_get();
delta = ktime_sub(rettime, *calltime);
duration = (unsigned long long) ktime_to_ns(delta) >> 10;
printk(KERN_DEBUG "initcall %pS returned %d after %lld usecs\n",
fn, ret, duration);
printk(KERN_DEBUG "initcall %pS returned %d after %lld usecs, irqs_disabled() %d\n",
fn, ret, duration, irqs_disabled());
}
static ktime_t initcall_calltime;
......
......@@ -676,131 +676,6 @@ void dev_remove_offload(struct packet_offload *po)
}
EXPORT_SYMBOL(dev_remove_offload);
/******************************************************************************
*
* Device Boot-time Settings Routines
*
******************************************************************************/
/* Boot time configuration table */
static struct netdev_boot_setup dev_boot_setup[NETDEV_BOOT_SETUP_MAX];
/**
* netdev_boot_setup_add - add new setup entry
* @name: name of the device
* @map: configured settings for the device
*
* Adds new setup entry to the dev_boot_setup list. The function
* returns 0 on error and 1 on success. This is a generic routine to
* all netdevices.
*/
static int netdev_boot_setup_add(char *name, struct ifmap *map)
{
struct netdev_boot_setup *s;
int i;
s = dev_boot_setup;
for (i = 0; i < NETDEV_BOOT_SETUP_MAX; i++) {
if (s[i].name[0] == '\0' || s[i].name[0] == ' ') {
memset(s[i].name, 0, sizeof(s[i].name));
strlcpy(s[i].name, name, IFNAMSIZ);
memcpy(&s[i].map, map, sizeof(s[i].map));
break;
}
}
return i >= NETDEV_BOOT_SETUP_MAX ? 0 : 1;
}
/**
* netdev_boot_setup_check - check boot time settings
* @dev: the netdevice
*
* Check boot time settings for the device.
* The found settings are set for the device to be used
* later in the device probing.
* Returns 0 if no settings found, 1 if they are.
*/
int netdev_boot_setup_check(struct net_device *dev)
{
struct netdev_boot_setup *s = dev_boot_setup;
int i;
for (i = 0; i < NETDEV_BOOT_SETUP_MAX; i++) {
if (s[i].name[0] != '\0' && s[i].name[0] != ' ' &&
!strcmp(dev->name, s[i].name)) {
dev->irq = s[i].map.irq;
dev->base_addr = s[i].map.base_addr;
dev->mem_start = s[i].map.mem_start;
dev->mem_end = s[i].map.mem_end;
return 1;
}
}
return 0;
}
EXPORT_SYMBOL(netdev_boot_setup_check);
/**
* netdev_boot_base - get address from boot time settings
* @prefix: prefix for network device
* @unit: id for network device
*
* Check boot time settings for the base address of device.
* The found settings are set for the device to be used
* later in the device probing.
* Returns 0 if no settings found.
*/
unsigned long netdev_boot_base(const char *prefix, int unit)
{
const struct netdev_boot_setup *s = dev_boot_setup;
char name[IFNAMSIZ];
int i;
sprintf(name, "%s%d", prefix, unit);
/*
* If device already registered then return base of 1
* to indicate not to probe for this interface
*/
if (__dev_get_by_name(&init_net, name))
return 1;
for (i = 0; i < NETDEV_BOOT_SETUP_MAX; i++)
if (!strcmp(name, s[i].name))
return s[i].map.base_addr;
return 0;
}
/*
* Saves at boot time configured settings for any netdevice.
*/
int __init netdev_boot_setup(char *str)
{
int ints[5];
struct ifmap map;
str = get_options(str, ARRAY_SIZE(ints), ints);
if (!str || !*str)
return 0;
/* Save settings */
memset(&map, 0, sizeof(map));
if (ints[0] > 0)
map.irq = ints[1];
if (ints[0] > 1)
map.base_addr = ints[2];
if (ints[0] > 2)
map.mem_start = ints[3];
if (ints[0] > 3)
map.mem_end = ints[4];
/* Add new entry to the list */
return netdev_boot_setup_add(str, &map);
}
__setup("netdev=", netdev_boot_setup);
/*******************************************************************************
*
* Device Interface Subroutines
......
......@@ -62,8 +62,6 @@
#include <linux/uaccess.h>
#include <net/pkt_sched.h>
__setup("ether=", netdev_boot_setup);
/**
* eth_header - create the Ethernet header
* @skb: buffer to alter
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment