Blame view
include/linux/netpoll.h
3.34 KB
1da177e4c
|
1 2 3 4 5 6 7 8 9 10 11 |
/* * 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> |
53fb95d3c
|
12 |
#include <linux/rcupdate.h> |
1da177e4c
|
13 |
#include <linux/list.h> |
1da177e4c
|
14 15 |
struct netpoll { struct net_device *dev; |
bf6bce71e
|
16 17 |
char dev_name[IFNAMSIZ]; const char *name; |
1da177e4c
|
18 |
void (*rx_hook)(struct netpoll *, int, char *, int); |
5de4a473b
|
19 |
|
e7557af56
|
20 |
__be32 local_ip, remote_ip; |
1da177e4c
|
21 |
u16 local_port, remote_port; |
095386416
|
22 |
u8 remote_mac[ETH_ALEN]; |
508e14b4a
|
23 24 |
struct list_head rx; /* rx_np list element */ |
115c1d6e6
|
25 26 27 |
}; struct netpoll_info { |
93ec2c723
|
28 |
atomic_t refcnt; |
508e14b4a
|
29 |
|
d9452e9f8
|
30 |
int rx_flags; |
fbeec2e15
|
31 |
spinlock_t rx_lock; |
508e14b4a
|
32 |
struct list_head rx_np; /* netpolls that registered an rx_hook */ |
068c6e98b
|
33 |
struct sk_buff_head arp_tx; /* list of arp requests to reply to */ |
b6cd27ed3
|
34 |
struct sk_buff_head txq; |
508e14b4a
|
35 |
|
6d5aefb8e
|
36 |
struct delayed_work tx_work; |
0e34e9317
|
37 38 |
struct netpoll *netpoll; |
1da177e4c
|
39 |
}; |
1da177e4c
|
40 |
void netpoll_send_udp(struct netpoll *np, const char *msg, int len); |
0bcc18161
|
41 |
void netpoll_print_options(struct netpoll *np); |
1da177e4c
|
42 |
int netpoll_parse_options(struct netpoll *np, char *opt); |
8fdd95ec1
|
43 |
int __netpoll_setup(struct netpoll *np); |
1da177e4c
|
44 45 46 |
int netpoll_setup(struct netpoll *np); int netpoll_trap(void); void netpoll_set_trap(int trap); |
8fdd95ec1
|
47 |
void __netpoll_cleanup(struct netpoll *np); |
1da177e4c
|
48 49 |
void netpoll_cleanup(struct netpoll *np); int __netpoll_rx(struct sk_buff *skb); |
c2355e1ab
|
50 51 52 53 54 55 |
void netpoll_send_skb_on_dev(struct netpoll *np, struct sk_buff *skb, struct net_device *dev); static inline void netpoll_send_skb(struct netpoll *np, struct sk_buff *skb) { netpoll_send_skb_on_dev(np, skb, np->dev); } |
5de4a473b
|
56 |
|
1da177e4c
|
57 58 |
#ifdef CONFIG_NETPOLL |
ffb273623
|
59 |
static inline bool netpoll_rx(struct sk_buff *skb) |
1da177e4c
|
60 |
{ |
de85d99eb
|
61 |
struct netpoll_info *npinfo; |
fbeec2e15
|
62 |
unsigned long flags; |
ffb273623
|
63 |
bool ret = false; |
115c1d6e6
|
64 |
|
f0f9deae9
|
65 |
local_irq_save(flags); |
d5f31fbfd
|
66 |
npinfo = rcu_dereference_bh(skb->dev->npinfo); |
de85d99eb
|
67 |
|
508e14b4a
|
68 |
if (!npinfo || (list_empty(&npinfo->rx_np) && !npinfo->rx_flags)) |
de85d99eb
|
69 |
goto out; |
115c1d6e6
|
70 |
|
f0f9deae9
|
71 |
spin_lock(&npinfo->rx_lock); |
d9452e9f8
|
72 73 |
/* check rx_flags again with the lock held */ if (npinfo->rx_flags && __netpoll_rx(skb)) |
ffb273623
|
74 |
ret = true; |
f0f9deae9
|
75 |
spin_unlock(&npinfo->rx_lock); |
fbeec2e15
|
76 |
|
de85d99eb
|
77 |
out: |
f0f9deae9
|
78 |
local_irq_restore(flags); |
fbeec2e15
|
79 |
return ret; |
1da177e4c
|
80 |
} |
d1c76af9e
|
81 82 |
static inline int netpoll_rx_on(struct sk_buff *skb) { |
d5f31fbfd
|
83 |
struct netpoll_info *npinfo = rcu_dereference_bh(skb->dev->npinfo); |
d1c76af9e
|
84 |
|
508e14b4a
|
85 |
return npinfo && (!list_empty(&npinfo->rx_np) || npinfo->rx_flags); |
d1c76af9e
|
86 |
} |
bea3348ee
|
87 |
static inline int netpoll_receive_skb(struct sk_buff *skb) |
1da177e4c
|
88 |
{ |
bea3348ee
|
89 90 91 92 93 94 95 96 |
if (!list_empty(&skb->dev->napi_list)) return netpoll_rx(skb); return 0; } static inline void *netpoll_poll_lock(struct napi_struct *napi) { struct net_device *dev = napi->dev; |
bea3348ee
|
97 98 99 100 |
if (dev && dev->npinfo) { spin_lock(&napi->poll_lock); napi->poll_owner = smp_processor_id(); return napi; |
1da177e4c
|
101 |
} |
53fb95d3c
|
102 |
return NULL; |
1da177e4c
|
103 |
} |
53fb95d3c
|
104 |
static inline void netpoll_poll_unlock(void *have) |
1da177e4c
|
105 |
{ |
bea3348ee
|
106 |
struct napi_struct *napi = have; |
53fb95d3c
|
107 |
|
bea3348ee
|
108 109 110 |
if (napi) { napi->poll_owner = -1; spin_unlock(&napi->poll_lock); |
1da177e4c
|
111 112 |
} } |
c18370f5b
|
113 114 115 116 |
static inline int netpoll_tx_running(struct net_device *dev) { return irqs_disabled(); } |
1da177e4c
|
117 |
#else |
969a6e521
|
118 |
static inline bool netpoll_rx(struct sk_buff *skb) |
bea3348ee
|
119 120 121 |
{ return 0; } |
d1c76af9e
|
122 123 124 125 |
static inline int netpoll_rx_on(struct sk_buff *skb) { return 0; } |
bea3348ee
|
126 127 128 129 130 131 132 133 134 135 136 137 138 139 |
static inline int netpoll_receive_skb(struct sk_buff *skb) { return 0; } static inline void *netpoll_poll_lock(struct napi_struct *napi) { return NULL; } static inline void netpoll_poll_unlock(void *have) { } static inline void netpoll_netdev_init(struct net_device *dev) { } |
c18370f5b
|
140 141 142 143 |
static inline int netpoll_tx_running(struct net_device *dev) { return 0; } |
1da177e4c
|
144 145 146 |
#endif #endif |