blob: a0525a1f4715d7cce2e1e883070b75a655b12359 [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/*
2 * Common code for low-level network console, dump, and debugger code
3 *
4 * Derived from netconsole, kgdb-over-ethernet, and netdump patches
5 */
6
7#ifndef _LINUX_NETPOLL_H
8#define _LINUX_NETPOLL_H
9
10#include <linux/netdevice.h>
11#include <linux/interrupt.h>
Matt Mackall53fb95d2005-08-11 19:27:43 -070012#include <linux/rcupdate.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070013#include <linux/list.h>
14
Linus Torvalds1da177e2005-04-16 15:20:36 -070015struct netpoll {
16 struct net_device *dev;
Stephen Hemmingerbf6bce72006-10-26 15:46:56 -070017 char dev_name[IFNAMSIZ];
18 const char *name;
Linus Torvalds1da177e2005-04-16 15:20:36 -070019 void (*rx_hook)(struct netpoll *, int, char *, int);
Stephen Hemminger5de4a472006-10-26 15:46:55 -070020
Linus Torvalds1da177e2005-04-16 15:20:36 -070021 u32 local_ip, remote_ip;
22 u16 local_port, remote_port;
Stephen Hemminger09538642007-11-19 19:23:29 -080023 u8 remote_mac[ETH_ALEN];
Jeff Moyer115c1d62005-06-22 22:05:31 -070024};
25
26struct netpoll_info {
Stephen Hemminger93ec2c72006-10-26 15:46:50 -070027 atomic_t refcnt;
Jeff Moyerfbeec2e2005-06-22 22:05:59 -070028 spinlock_t rx_lock;
29 struct netpoll *rx_np; /* netpoll that registered an rx_hook */
Neil Horman068c6e92006-06-26 00:04:27 -070030 struct sk_buff_head arp_tx; /* list of arp requests to reply to */
Stephen Hemmingerb6cd27e2006-10-26 15:46:51 -070031 struct sk_buff_head txq;
David Howells6d5aefb2006-12-05 19:36:26 +000032 struct delayed_work tx_work;
Linus Torvalds1da177e2005-04-16 15:20:36 -070033};
34
35void netpoll_poll(struct netpoll *np);
36void netpoll_send_udp(struct netpoll *np, const char *msg, int len);
Satyam Sharma0bcc1812007-08-10 15:35:05 -070037void netpoll_print_options(struct netpoll *np);
Linus Torvalds1da177e2005-04-16 15:20:36 -070038int netpoll_parse_options(struct netpoll *np, char *opt);
39int netpoll_setup(struct netpoll *np);
40int netpoll_trap(void);
41void netpoll_set_trap(int trap);
42void netpoll_cleanup(struct netpoll *np);
43int __netpoll_rx(struct sk_buff *skb);
Stephen Hemminger5de4a472006-10-26 15:46:55 -070044
Linus Torvalds1da177e2005-04-16 15:20:36 -070045
46#ifdef CONFIG_NETPOLL
47static inline int netpoll_rx(struct sk_buff *skb)
48{
Jeff Moyer115c1d62005-06-22 22:05:31 -070049 struct netpoll_info *npinfo = skb->dev->npinfo;
Jeff Moyerfbeec2e2005-06-22 22:05:59 -070050 unsigned long flags;
51 int ret = 0;
Jeff Moyer115c1d62005-06-22 22:05:31 -070052
Stephen Hemmingerc7b6ea22007-11-19 19:37:09 -080053 if (!npinfo || !npinfo->rx_np)
Jeff Moyer115c1d62005-06-22 22:05:31 -070054 return 0;
55
Jeff Moyerfbeec2e2005-06-22 22:05:59 -070056 spin_lock_irqsave(&npinfo->rx_lock, flags);
Stephen Hemmingerc7b6ea22007-11-19 19:37:09 -080057 /* check rx_np again with the lock held */
58 if (npinfo->rx_np && __netpoll_rx(skb))
Jeff Moyerfbeec2e2005-06-22 22:05:59 -070059 ret = 1;
60 spin_unlock_irqrestore(&npinfo->rx_lock, flags);
61
62 return ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -070063}
64
Stephen Hemmingerbea33482007-10-03 16:41:36 -070065static inline int netpoll_receive_skb(struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -070066{
Stephen Hemmingerbea33482007-10-03 16:41:36 -070067 if (!list_empty(&skb->dev->napi_list))
68 return netpoll_rx(skb);
69 return 0;
70}
71
72static inline void *netpoll_poll_lock(struct napi_struct *napi)
73{
74 struct net_device *dev = napi->dev;
75
Matt Mackall53fb95d2005-08-11 19:27:43 -070076 rcu_read_lock(); /* deal with race on ->npinfo */
Stephen Hemmingerbea33482007-10-03 16:41:36 -070077 if (dev && dev->npinfo) {
78 spin_lock(&napi->poll_lock);
79 napi->poll_owner = smp_processor_id();
80 return napi;
Linus Torvalds1da177e2005-04-16 15:20:36 -070081 }
Matt Mackall53fb95d2005-08-11 19:27:43 -070082 return NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -070083}
84
Matt Mackall53fb95d2005-08-11 19:27:43 -070085static inline void netpoll_poll_unlock(void *have)
Linus Torvalds1da177e2005-04-16 15:20:36 -070086{
Stephen Hemmingerbea33482007-10-03 16:41:36 -070087 struct napi_struct *napi = have;
Matt Mackall53fb95d2005-08-11 19:27:43 -070088
Stephen Hemmingerbea33482007-10-03 16:41:36 -070089 if (napi) {
90 napi->poll_owner = -1;
91 spin_unlock(&napi->poll_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -070092 }
Matt Mackall53fb95d2005-08-11 19:27:43 -070093 rcu_read_unlock();
Linus Torvalds1da177e2005-04-16 15:20:36 -070094}
95
Stephen Hemmingerbea33482007-10-03 16:41:36 -070096static inline void netpoll_netdev_init(struct net_device *dev)
97{
98 INIT_LIST_HEAD(&dev->napi_list);
99}
100
Linus Torvalds1da177e2005-04-16 15:20:36 -0700101#else
Stephen Hemmingerbea33482007-10-03 16:41:36 -0700102static inline int netpoll_rx(struct sk_buff *skb)
103{
104 return 0;
105}
106static inline int netpoll_receive_skb(struct sk_buff *skb)
107{
108 return 0;
109}
110static inline void *netpoll_poll_lock(struct napi_struct *napi)
111{
112 return NULL;
113}
114static inline void netpoll_poll_unlock(void *have)
115{
116}
117static inline void netpoll_netdev_init(struct net_device *dev)
118{
119}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700120#endif
121
122#endif