Commit 150e4b7c authored by Jeff Garzik's avatar Jeff Garzik

Hand merge netpoll into latest upstream.

parents f4d86110 31784249
started by Ingo Molnar <mingo@redhat.com>, 2001.09.17
2.6 port and netpoll api by Matt Mackall <mpm@selenic.com>, Sep 9 2003
Please send bug reports to Matt Mackall <mpm@selenic.com>
This module logs kernel printk messages over UDP allowing debugging of
problem where disk logging fails and serial consoles are impractical.
It can be used either built-in or as a module. As a built-in,
netconsole initializes immediately after NIC cards and will bring up
the specified interface as soon as possible. While this doesn't allow
capture of early kernel panics, it does capture most of the boot
process.
It takes a string configuration parameter "netconsole" in the
following format:
netconsole=[src-port]@[src-ip]/[<dev>],[tgt-port]@<tgt-ip>/[tgt-macaddr]
where
src-port source for UDP packets (defaults to 6665)
src-ip source IP to use (interface address)
dev network interface (eth0)
tgt-port port for logging agent (6666)
tgt-ip IP address for logging agent
tgt-macaddr ethernet MAC address for logging agent (broadcast)
Examples:
linux netconsole=4444@10.0.0.1/eth1,9353@10.0.0.2/12:34:56:78:9a:bc
or
insmod netconsole netconsole=@/,@10.0.0.2/
Built-in netconsole starts immediately after the TCP stack is
initialized and attempts to bring up the supplied dev at the supplied
address.
The remote host can run either 'netcat -u -l -p <port>' or syslogd.
WARNING: the default target ethernet setting uses the broadcast
ethernet address to send packets, which can cause increased load on
other systems on the same ethernet segment.
NOTE: the network device (eth1 in the above case) can run any kind
of other network traffic, netconsole is not intrusive. Netconsole
might cause slight delays in other traffic if the volume of kernel
messages is high, but should have no other impact.
Netconsole was designed to be as instantaneous as possible, to
enable the logging of even the most critical kernel bugs. It works
from IRQ contexts as well, and does not enable interrupts while
sending packets. Due to these unique needs, configuration can not
be more automatic, and some fundamental limitations will remain:
only IP networks, UDP packets and ethernet devices are supported.
......@@ -337,6 +337,9 @@ el2_probe1(struct net_device *dev, int ioaddr)
dev->open = &el2_open;
dev->stop = &el2_close;
dev->ethtool_ops = &netdev_ethtool_ops;
#ifdef CONFIG_NET_POLL_CONTROLLER
dev->poll_controller = ei_poll;
#endif
if (dev->mem_start)
printk("%s: %s - %dkB RAM, 8kB shared mem window at %#6lx-%#6lx.\n",
......
......@@ -920,6 +920,18 @@ static struct net_device *compaq_net_device;
static int vortex_cards_found;
#ifdef CONFIG_NET_POLL_CONTROLLER
static void poll_vortex(struct net_device *dev)
{
struct vortex_private *vp = (struct vortex_private *)dev->priv;
unsigned long flags;
local_save_flags(flags);
local_irq_disable();
(vp->full_bus_master_rx ? boomerang_interrupt:vortex_interrupt)(dev->irq,dev,NULL);
local_irq_restore(flags);
}
#endif
#ifdef CONFIG_PM
static int vortex_suspend (struct pci_dev *pdev, u32 state)
......@@ -1450,6 +1462,9 @@ static int __devinit vortex_probe1(struct device *gendev,
dev->set_multicast_list = set_rx_mode;
dev->tx_timeout = vortex_tx_timeout;
dev->watchdog_timeo = (watchdog * HZ) / 1000;
#ifdef CONFIG_NET_POLL_CONTROLLER
dev->poll_controller = poll_vortex;
#endif
if (pdev) {
vp->pm_state_valid = 1;
pci_save_state(VORTEX_PCI(vp), vp->power_state);
......
......@@ -516,6 +516,15 @@ irqreturn_t ei_interrupt(int irq, void *dev_id, struct pt_regs * regs)
return IRQ_HANDLED;
}
#ifdef CONFIG_NET_POLL_CONTROLLER
void ei_poll(struct net_device *dev)
{
disable_irq(dev->irq);
ei_interrupt(dev->irq, dev, NULL);
enable_irq(dev->irq);
}
#endif
/**
* ei_tx_err - handle transmitter error
* @dev: network device which threw the exception
......@@ -1124,6 +1133,9 @@ static void NS8390_trigger_send(struct net_device *dev, unsigned int length,
EXPORT_SYMBOL(ei_open);
EXPORT_SYMBOL(ei_close);
EXPORT_SYMBOL(ei_interrupt);
#ifdef CONFIG_NET_POLL_CONTROLLER
EXPORT_SYMBOL(ei_poll);
#endif
EXPORT_SYMBOL(ei_tx_timeout);
EXPORT_SYMBOL(NS8390_init);
EXPORT_SYMBOL(__alloc_ei_netdev);
......
......@@ -39,6 +39,10 @@ extern int ei_debug;
#define ei_debug 1
#endif
#ifdef CONFIG_NET_POLL_CONTROLLER
extern void ei_poll(struct net_device *dev);
#endif
extern void NS8390_init(struct net_device *dev, int startp);
extern int ei_open(struct net_device *dev);
extern int ei_close(struct net_device *dev);
......
......@@ -2476,6 +2476,13 @@ config SHAPER
To compile this driver as a module, choose M here: the module
will be called shaper. If unsure, say N.
config NETCONSOLE
tristate "Network console logging support (EXPERIMENTAL)"
depends on NETDEVICES && EXPERIMENTAL
---help---
If you want to log kernel messages over the network, enable this.
See Documentation/networking/netconsole.txt for details.
source "drivers/net/wan/Kconfig"
source "drivers/net/pcmcia/Kconfig"
......
......@@ -188,3 +188,4 @@ obj-$(CONFIG_NET_TULIP) += tulip/
obj-$(CONFIG_HAMRADIO) += hamradio/
obj-$(CONFIG_IRDA) += irda/
obj-$(CONFIG_NETCONSOLE) += netconsole.o
......@@ -276,6 +276,9 @@ static int __init ac_probe1(int ioaddr, struct net_device *dev)
dev->open = &ac_open;
dev->stop = &ac_close_card;
#ifdef CONFIG_NET_POLL_CONTROLLER
dev->poll_controller = ei_poll;
#endif
NS8390_init(dev, 0);
return 0;
out1:
......
......@@ -1153,6 +1153,17 @@ static irqreturn_t amd8111e_interrupt(int irq, void *dev_id, struct pt_regs *reg
return IRQ_RETVAL(handled);
}
#ifdef CONFIG_NET_POLL_CONTROLLER
static void amd8111e_poll(struct net_device *dev)
{
unsigned long flags;
local_save_flags(flags);
local_irq_disable();
amd8111e_interrupt(0, dev, NULL);
local_irq_restore(flags);
}
#endif
/*
This function closes the network interface and updates the statistics so that most recent statistics will be available after the interface is down.
*/
......@@ -1884,6 +1895,9 @@ static int __devinit amd8111e_probe_one(struct pci_dev *pdev,
dev->irq =pdev->irq;
dev->tx_timeout = amd8111e_tx_timeout;
dev->watchdog_timeo = AMD8111E_TX_TIMEOUT;
#ifdef CONFIG_NET_POLL_CONTROLLER
dev->poll_controller = amd8111e_poll;
#endif
#if AMD8111E_VLAN_TAG_USED
dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX;
......
......@@ -333,6 +333,9 @@ static int __init apne_probe1(struct net_device *dev, int ioaddr)
ei_status.get_8390_hdr = &apne_get_8390_hdr;
dev->open = &apne_open;
dev->stop = &apne_close;
#ifdef CONFIG_NET_POLL_CONTROLLER
dev->poll_controller = ei_poll;
#endif
NS8390_init(dev, 0);
pcmcia_ack_int(pcmcia_get_intreq()); /* ack PCMCIA int req */
......
......@@ -269,6 +269,9 @@ static int __init e21_probe1(struct net_device *dev, int ioaddr)
ei_status.get_8390_hdr = &e21_get_8390_hdr;
dev->open = &e21_open;
dev->stop = &e21_close;
#ifdef CONFIG_NET_POLL_CONTROLLER
dev->poll_controller = ei_poll;
#endif
NS8390_init(dev, 0);
return 0;
......
......@@ -542,6 +542,7 @@ static int speedo_start_xmit(struct sk_buff *skb, struct net_device *dev);
static void speedo_refill_rx_buffers(struct net_device *dev, int force);
static int speedo_rx(struct net_device *dev);
static void speedo_tx_buffer_gc(struct net_device *dev);
static void poll_speedo (struct net_device *dev);
static irqreturn_t speedo_interrupt(int irq, void *dev_instance, struct pt_regs *regs);
static int speedo_close(struct net_device *dev);
static struct net_device_stats *speedo_get_stats(struct net_device *dev);
......@@ -885,6 +886,9 @@ static int __devinit speedo_found1(struct pci_dev *pdev,
dev->get_stats = &speedo_get_stats;
dev->set_multicast_list = &set_rx_mode;
dev->do_ioctl = &speedo_ioctl;
#ifdef CONFIG_NET_POLL_CONTROLLER
dev->poll_controller = &poll_speedo;
#endif
if (register_netdevice(dev))
goto err_free_unlock;
......@@ -1675,6 +1679,23 @@ static irqreturn_t speedo_interrupt(int irq, void *dev_instance, struct pt_regs
return IRQ_RETVAL(handled);
}
#ifdef CONFIG_NET_POLL_CONTROLLER
/*
* Polling 'interrupt' - used by things like netconsole to send skbs
* without having to re-enable interrupts. It's not called while
* the interrupt routine is executing.
*/
static void poll_speedo (struct net_device *dev)
{
/* disable_irq is not very nice, but with the funny lockless design
we have no other choice. */
disable_irq(dev->irq);
speedo_interrupt (dev->irq, dev, NULL);
enable_irq(dev->irq);
}
#endif
static inline struct RxFD *speedo_rx_alloc(struct net_device *dev, int entry)
{
struct speedo_private *sp = (struct speedo_private *)dev->priv;
......
......@@ -298,6 +298,9 @@ static int __init es_probe1(struct net_device *dev, int ioaddr)
dev->open = &es_open;
dev->stop = &es_close;
#ifdef CONFIG_NET_POLL_CONTROLLER
dev->poll_controller = ei_poll;
#endif
NS8390_init(dev, 0);
return 0;
out1:
......
......@@ -236,6 +236,9 @@ static int __init hpp_probe1(struct net_device *dev, int ioaddr)
dev->open = &hpp_open;
dev->stop = &hpp_close;
#ifdef CONFIG_NET_POLL_CONTROLLER
dev->poll_controller = ei_poll;
#endif
ei_status.name = name;
ei_status.word16 = 0; /* Agggghhhhh! Debug time: 2 days! */
......
......@@ -207,6 +207,9 @@ static int __init hp_probe1(struct net_device *dev, int ioaddr)
dev->base_addr = ioaddr + NIC_OFFSET;
dev->open = &hp_open;
dev->stop = &hp_close;
#ifdef CONFIG_NET_POLL_CONTROLLER
dev->poll_controller = ei_poll;
#endif
ei_status.name = name;
ei_status.word16 = wordmode;
......
......@@ -138,6 +138,9 @@ static int __init hydra_init(unsigned long board)
ei_status.reg_offset = hydra_offsets;
dev->open = &hydra_open;
dev->stop = &hydra_close;
#ifdef CONFIG_NET_POLL_CONTROLLER
dev->poll_controller = ei_poll;
#endif
#ifdef MODULE
ei_status.priv = (unsigned long)root_hydra_dev;
root_hydra_dev = dev;
......
......@@ -299,6 +299,9 @@ static int __init lne390_probe1(struct net_device *dev, int ioaddr)
dev->open = &lne390_open;
dev->stop = &lne390_close;
#ifdef CONFIG_NET_POLL_CONTROLLER
dev->poll_controller = ei_poll;
#endif
NS8390_init(dev, 0);
return 0;
cleanup:
......
......@@ -442,6 +442,9 @@ static int __init mac8390_initdev(struct net_device * dev, struct nubus_dev * nd
/* Now fill in our stuff */
dev->open = &mac8390_open;
dev->stop = &mac8390_close;
#ifdef CONFIG_NET_POLL_CONTROLLER
dev->poll_controller = ei_poll;
#endif
/* GAR, ei_status is actually a macro even though it looks global */
ei_status.name = cardname[type];
......
......@@ -496,6 +496,9 @@ static int __init ne_probe1(struct net_device *dev, int ioaddr)
ei_status.priv = 0;
dev->open = &ne_open;
dev->stop = &ne_close;
#ifdef CONFIG_NET_POLL_CONTROLLER
dev->poll_controller = ei_poll;
#endif
NS8390_init(dev, 0);
return 0;
......
......@@ -509,6 +509,9 @@ static int __init ne2_probe1(struct net_device *dev, int slot)
dev->open = &ne_open;
dev->stop = &ne_close;
#ifdef CONFIG_NET_POLL_CONTROLLER
dev->poll_controller = ei_poll;
#endif
NS8390_init(dev, 0);
return 0;
out:
......
......@@ -359,6 +359,9 @@ static int __devinit ne2k_pci_init_one (struct pci_dev *pdev,
dev->open = &ne2k_pci_open;
dev->stop = &ne2k_pci_close;
dev->ethtool_ops = &ne2k_pci_ethtool_ops;
#ifdef CONFIG_NET_POLL_CONTROLLER
dev->poll_controller = ei_poll;
#endif
NS8390_init(dev, 0);
i = register_netdev(dev);
......
......@@ -534,6 +534,9 @@ static int __init ne_probe1(struct net_device *dev, int ioaddr)
ei_status.priv = 0;
dev->open = &ne_open;
dev->stop = &ne_close;
#ifdef CONFIG_NET_POLL_CONTROLLER
dev->poll_controller = ei_poll;
#endif
NS8390_init(dev, 0);
return 0;
......
......@@ -205,6 +205,9 @@ static int __init ne3210_eisa_probe (struct device *device)
dev->open = &ne3210_open;
dev->stop = &ne3210_close;
#ifdef CONFIG_NET_POLL_CONTROLLER
dev->poll_controller = ei_poll;
#endif
dev->if_port = ifmap_val[port_index];
if ((retval = register_netdev (dev)))
......
/*
* linux/drivers/net/netconsole.c
*
* Copyright (C) 2001 Ingo Molnar <mingo@redhat.com>
*
* This file contains the implementation of an IRQ-safe, crash-safe
* kernel console implementation that outputs kernel messages to the
* network.
*
* Modification history:
*
* 2001-09-17 started by Ingo Molnar.
* 2003-08-11 2.6 port by Matt Mackall
* simplified options
* generic card hooks
* works non-modular
* 2003-09-07 rewritten with netpoll api
*/
/****************************************************************
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
****************************************************************/
#include <linux/mm.h>
#include <linux/tty.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/console.h>
#include <linux/tty_driver.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/string.h>
#include <linux/sysrq.h>
#include <linux/smp.h>
#include <linux/netpoll.h>
MODULE_AUTHOR("Maintainer: Matt Mackall <mpm@selenic.com>");
MODULE_DESCRIPTION("Console driver for network interfaces");
MODULE_LICENSE("GPL");
static char config[256];
module_param_string(netconsole, config, 256, 0);
MODULE_PARM_DESC(netconsole, " netconsole=[src-port]@[src-ip]/[dev],[tgt-port]@<tgt-ip>/[tgt-macaddr]\n");
static struct netpoll np = {
.name = "netconsole",
.dev_name = "eth0",
.local_port = 6665,
.remote_port = 6666,
.remote_mac = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff},
};
static int configured = 0;
#define MAX_PRINT_CHUNK 1000
static void write_msg(struct console *con, const char *msg, unsigned int len)
{
int frag, left;
unsigned long flags;
if (!np.dev)
return;
local_irq_save(flags);
for(left = len; left; ) {
frag = min(left, MAX_PRINT_CHUNK);
netpoll_send_udp(&np, msg, frag);
msg += frag;
left -= frag;
}
local_irq_restore(flags);
}
static struct console netconsole = {
.flags = CON_ENABLED | CON_PRINTBUFFER,
.write = write_msg
};
static int option_setup(char *opt)
{
configured = !netpoll_parse_options(&np, opt);
return 0;
}
__setup("netconsole=", option_setup);
static int init_netconsole(void)
{
if(strlen(config))
option_setup(config);
if(!configured) {
printk("netconsole: not configured, aborting\n");
return -EINVAL;
}
if(netpoll_setup(&np))
return -EINVAL;
register_console(&netconsole);
printk(KERN_INFO "netconsole: network logging started\n");
return 0;
}
static void cleanup_netconsole(void)
{
unregister_console(&netconsole);
netpoll_cleanup(&np);
}
module_init(init_netconsole);
module_exit(cleanup_netconsole);
......@@ -192,6 +192,9 @@ static int __init oaknet_init(void)
dev->open = oaknet_open;
dev->stop = oaknet_close;
#ifdef CONFIG_NET_POLL_CONTROLLER
dev->poll_controller = ei_poll;
#endif
NS8390_init(dev, FALSE);
ret = register_netdev(dev);
......
......@@ -456,6 +456,14 @@ static struct pcnet32_access pcnet32_dwio = {
.reset = pcnet32_dwio_reset
};
#ifdef CONFIG_NET_POLL_CONTROLLER
static void pcnet32_poll_controller(struct net_device *dev)
{
disable_irq(dev->irq);
pcnet32_interrupt(0, dev, NULL);
enable_irq(dev->irq);
}
#endif
/* only probes for non-PCI devices, the rest are handled by
......@@ -806,6 +814,10 @@ pcnet32_probe1(unsigned long ioaddr, unsigned int irq_line, int shared,
dev->tx_timeout = pcnet32_tx_timeout;
dev->watchdog_timeo = (5*HZ);
#ifdef CONFIG_NET_POLL_CONTROLLER
dev->poll_controller = pcnet32_poll_controller;
#endif
/* Fill in the generic fields of the device structure. */
if (register_netdev(dev))
goto err_free_consistent;
......
......@@ -324,6 +324,9 @@ int __init ultramca_probe(struct device *gen_dev)
dev->open = &ultramca_open;
dev->stop = &ultramca_close_card;
#ifdef CONFIG_NET_POLL_CONTROLLER
dev->poll_controller = ei_poll;
#endif
NS8390_init(dev, 0);
......
......@@ -121,6 +121,14 @@ MODULE_DEVICE_TABLE(isapnp, ultra_device_ids);
#define ULTRA_IO_EXTENT 32
#define EN0_ERWCNT 0x08 /* Early receive warning count. */
#ifdef CONFIG_NET_POLL_CONTROLLER
static void ultra_poll(struct net_device *dev)
{
disable_irq(dev->irq);
ei_interrupt(dev->irq, dev, NULL);
enable_irq(dev->irq);
}
#endif
/* Probe for the Ultra. This looks like a 8013 with the station
address PROM at I/O ports <base>+8 to <base>+13, with a checksum
following.
......@@ -134,6 +142,9 @@ static int __init do_ultra_probe(struct net_device *dev)
SET_MODULE_OWNER(dev);
#ifdef CONFIG_NET_POLL_CONTROLLER
dev->poll_controller = &ultra_poll;
#endif
if (base_addr > 0x1ff) /* Check a single specified location. */
return ultra_probe1(dev, base_addr);
else if (base_addr != 0) /* Don't probe at all. */
......@@ -301,6 +312,9 @@ static int __init ultra_probe1(struct net_device *dev, int ioaddr)
ei_status.reset_8390 = &ultra_reset_8390;
dev->open = &ultra_open;
dev->stop = &ultra_close_card;
#ifdef CONFIG_NET_POLL_CONTROLLER
dev->poll_controller = ei_poll;
#endif
NS8390_init(dev, 0);
return 0;
......
......@@ -268,6 +268,9 @@ static int __init ultra32_probe1(struct net_device *dev, int ioaddr)
ei_status.reset_8390 = &ultra32_reset_8390;
dev->open = &ultra32_open;
dev->stop = &ultra32_close;
#ifdef CONFIG_NET_POLL_CONTROLLER
dev->poll_controller = ei_poll;
#endif
NS8390_init(dev, 0);
return 0;
......
......@@ -124,6 +124,9 @@ static int __init stnic_probe(void)
dev->irq = IRQ_STNIC;
dev->open = &stnic_open;
dev->stop = &stnic_close;
#ifdef CONFIG_NET_POLL_CONTROLLER
dev->poll_controller = ei_poll;
#endif
/* Snarf the interrupt now. There's no point in waiting since we cannot
share and the board will usually be enabled. */
......
......@@ -2479,6 +2479,13 @@ static irqreturn_t tg3_interrupt(int irq, void *dev_id, struct pt_regs *regs)
static int tg3_init_hw(struct tg3 *);
static int tg3_halt(struct tg3 *);
#ifdef CONFIG_NET_POLL_CONTROLLER
static void tg3_poll_controller(struct net_device *dev)
{
tg3_interrupt(dev->irq, dev, NULL);
}
#endif
static void tg3_reset_task(void *_data)
{
struct tg3 *tp = _data;
......@@ -7696,6 +7703,9 @@ static int __devinit tg3_init_one(struct pci_dev *pdev,
dev->watchdog_timeo = TG3_TX_TIMEOUT;
dev->change_mtu = tg3_change_mtu;
dev->irq = pdev->irq;
#ifdef CONFIG_NET_POLL_CONTROLLER
dev->poll_controller = tg3_poll_controller;
#endif
err = tg3_get_invariants(tp);
if (err) {
......
......@@ -814,6 +814,14 @@ static void __init TLan_EisaProbe (void)
} /* TLan_EisaProbe */
#ifdef CONFIG_NET_POLL_CONTROLLER
static void TLan_Poll(struct net_device *dev)
{
disable_irq(dev->irq);
TLan_HandleInterrupt(dev->irq, dev, NULL);
enable_irq(dev->irq);
}
#endif
......@@ -893,6 +901,9 @@ static int TLan_Init( struct net_device *dev )
dev->get_stats = &TLan_GetStats;
dev->set_multicast_list = &TLan_SetMulticastList;
dev->do_ioctl = &TLan_ioctl;
#ifdef CONFIG_NET_POLL_CONTROLLER
dev->poll_controller = &TLan_Poll;
#endif
dev->tx_timeout = &TLan_tx_timeout;
dev->watchdog_timeo = TX_TIMEOUT;
......
......@@ -253,7 +253,7 @@ static void tulip_down(struct net_device *dev);
static struct net_device_stats *tulip_get_stats(struct net_device *dev);
static int private_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
static void set_rx_mode(struct net_device *dev);
static void poll_tulip(struct net_device *dev);
static void tulip_set_power_state (struct tulip_private *tp,
......@@ -1618,6 +1618,9 @@ static int __devinit tulip_init_one (struct pci_dev *pdev,
dev->get_stats = tulip_get_stats;
dev->do_ioctl = private_ioctl;
dev->set_multicast_list = set_rx_mode;
#ifdef CONFIG_NET_POLL_CONTROLLER
dev->poll_controller = &poll_tulip;
#endif
if (register_netdev(dev))
goto err_out_free_ring;
......@@ -1774,6 +1777,22 @@ static void __devexit tulip_remove_one (struct pci_dev *pdev)
/* pci_power_off (pdev, -1); */
}
#ifdef CONFIG_NET_POLL_CONTROLLER
/*
* Polling 'interrupt' - used by things like netconsole to send skbs
* without having to re-enable interrupts. It's not called while
* the interrupt routine is executing.
*/
static void poll_tulip (struct net_device *dev)
{
/* disable_irq here is not very nice, but with the lockless
interrupt handler we have no other choice. */
disable_irq(dev->irq);
tulip_interrupt (dev->irq, dev, NULL);
enable_irq(dev->irq);
}
#endif
static struct pci_driver tulip_driver = {
.name = DRV_NAME,
......
......@@ -615,6 +615,15 @@ static void __devinit reload_eeprom(long ioaddr)
break;
}
#ifdef CONFIG_NET_POLL_CONTROLLER
static void via_rhine_poll(struct net_device *dev)
{
disable_irq(dev->irq);
via_rhine_interrupt(dev->irq, (void *)dev, NULL);
enable_irq(dev->irq);
}
#endif
static int __devinit via_rhine_init_one (struct pci_dev *pdev,
const struct pci_device_id *ent)
{
......@@ -784,6 +793,9 @@ static int __devinit via_rhine_init_one (struct pci_dev *pdev,
dev->ethtool_ops = &netdev_ethtool_ops;
dev->tx_timeout = via_rhine_tx_timeout;
dev->watchdog_timeo = TX_TIMEOUT;
#ifdef CONFIG_NET_POLL_CONTROLLER
dev->poll_controller = via_rhine_poll;
#endif
if (np->drv_flags & ReqTxAlign)
dev->features |= NETIF_F_SG|NETIF_F_HW_CSUM;
......
......@@ -333,6 +333,9 @@ static int __init wd_probe1(struct net_device *dev, int ioaddr)
ei_status.get_8390_hdr = &wd_get_8390_hdr;
dev->open = &wd_open;
dev->stop = &wd_close;
#ifdef CONFIG_NET_POLL_CONTROLLER
dev->poll_controller = ei_poll;
#endif
NS8390_init(dev, 0);
#if 1
......
......@@ -222,6 +222,9 @@ static int __init zorro8390_init(struct net_device *dev, unsigned long board,
ei_status.reg_offset = zorro8390_offsets;
dev->open = &zorro8390_open;
dev->stop = &zorro8390_close;
#ifdef CONFIG_NET_POLL_CONTROLLER
dev->poll_controller = ei_poll;
#endif
#ifdef MODULE
ei_status.priv = (unsigned long)root_zorro8390_dev;
root_zorro8390_dev = dev;
......
......@@ -456,6 +456,12 @@ struct net_device
unsigned char *haddr);
int (*neigh_setup)(struct net_device *dev, struct neigh_parms *);
int (*accept_fastpath)(struct net_device *, struct dst_entry*);
#ifdef CONFIG_NETPOLL_RX
int netpoll_rx;
#endif
#ifdef CONFIG_NET_POLL_CONTROLLER
void (*poll_controller)(struct net_device *dev);
#endif
/* bridge stuff */
struct net_bridge_port *br_port;
......@@ -545,6 +551,9 @@ extern int dev_new_index(void);
extern struct net_device *dev_get_by_index(int ifindex);
extern struct net_device *__dev_get_by_index(int ifindex);
extern int dev_restart(struct net_device *dev);
#ifdef CONFIG_NETPOLL_TRAP
extern int netpoll_trap(void);
#endif
typedef int gifconf_func_t(struct net_device * dev, char * bufptr, int len);
extern int register_gifconf(unsigned int family, gifconf_func_t * gifconf);
......@@ -603,12 +612,20 @@ static inline void netif_start_queue(struct net_device *dev)
static inline void netif_wake_queue(struct net_device *dev)
{
#ifdef CONFIG_NETPOLL_TRAP
if (netpoll_trap())
return;
#endif
if (test_and_clear_bit(__LINK_STATE_XOFF, &dev->state))
__netif_schedule(dev);
}
static inline void netif_stop_queue(struct net_device *dev)
{
#ifdef CONFIG_NETPOLL_TRAP
if (netpoll_trap())
return;
#endif
set_bit(__LINK_STATE_XOFF, &dev->state);
}
......
/*
* Common code for low-level network console, dump, and debugger code
*
* Derived from netconsole, kgdb-over-ethernet, and netdump patches
*/
#ifndef _LINUX_NETPOLL_H
#define _LINUX_NETPOLL_H
#include <linux/netdevice.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/list.h>
struct netpoll;
struct netpoll {
struct net_device *dev;
char dev_name[16], *name;
void (*rx_hook)(struct netpoll *, int, char *, int);
u32 local_ip, remote_ip;
u16 local_port, remote_port;
unsigned char local_mac[6], remote_mac[6];
struct list_head rx_list;
};
void netpoll_poll(struct netpoll *np);
void netpoll_send_skb(struct netpoll *np, struct sk_buff *skb);
void netpoll_send_udp(struct netpoll *np, const char *msg, int len);
int netpoll_parse_options(struct netpoll *np, char *opt);
int netpoll_setup(struct netpoll *np);
int netpoll_trap(void);
void netpoll_set_trap(int trap);
void netpoll_cleanup(struct netpoll *np);
int netpoll_rx(struct sk_buff *skb);
#endif
......@@ -664,4 +664,20 @@ source "net/irda/Kconfig"
source "net/bluetooth/Kconfig"
config NETPOLL
def_bool NETCONSOLE
config NETPOLL_RX
bool "Netpoll support for trapping incoming packets"
default n
depends on NETPOLL
config NETPOLL_TRAP
bool "Netpoll traffic trapping"
default n
depends on NETPOLL
config NET_POLL_CONTROLLER
def_bool NETPOLL
endmenu
......@@ -13,3 +13,4 @@ obj-$(CONFIG_NETFILTER) += netfilter.o
obj-$(CONFIG_NET_DIVERT) += dv.o
obj-$(CONFIG_NET_PKTGEN) += pktgen.o
obj-$(CONFIG_NET_RADIO) += wireless.o
obj-$(CONFIG_NETPOLL) += netpoll.o
......@@ -105,6 +105,7 @@
#include <linux/kmod.h>
#include <linux/module.h>
#include <linux/kallsyms.h>
#include <linux/netpoll.h>
#ifdef CONFIG_NET_RADIO
#include <linux/wireless.h> /* Note : will define WIRELESS_EXT */
#include <net/iw_handler.h>
......@@ -1572,6 +1573,13 @@ int netif_rx(struct sk_buff *skb)
struct softnet_data *queue;
unsigned long flags;
#ifdef CONFIG_NETPOLL_RX
if (skb->dev->netpoll_rx && netpoll_rx(skb)) {
kfree_skb(skb);
return NET_RX_DROP;
}
#endif
if (!skb->stamp.tv_sec)
do_gettimeofday(&skb->stamp);
......@@ -1727,6 +1735,13 @@ int netif_receive_skb(struct sk_buff *skb)
int ret = NET_RX_DROP;
unsigned short type = skb->protocol;
#ifdef CONFIG_NETPOLL_RX
if (skb->dev->netpoll_rx && skb->dev->poll && netpoll_rx(skb)) {
kfree_skb(skb);
return NET_RX_DROP;
}
#endif
if (!skb->stamp.tv_sec)
do_gettimeofday(&skb->stamp);
......
This diff is collapsed.
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