xref: /linux/include/linux/netpoll.h (revision c18370f5)
11da177e4SLinus Torvalds /*
21da177e4SLinus Torvalds  * Common code for low-level network console, dump, and debugger code
31da177e4SLinus Torvalds  *
41da177e4SLinus Torvalds  * Derived from netconsole, kgdb-over-ethernet, and netdump patches
51da177e4SLinus Torvalds  */
61da177e4SLinus Torvalds 
71da177e4SLinus Torvalds #ifndef _LINUX_NETPOLL_H
81da177e4SLinus Torvalds #define _LINUX_NETPOLL_H
91da177e4SLinus Torvalds 
101da177e4SLinus Torvalds #include <linux/netdevice.h>
111da177e4SLinus Torvalds #include <linux/interrupt.h>
1253fb95d3SMatt Mackall #include <linux/rcupdate.h>
131da177e4SLinus Torvalds #include <linux/list.h>
141da177e4SLinus Torvalds 
151da177e4SLinus Torvalds struct netpoll {
161da177e4SLinus Torvalds 	struct net_device *dev;
170e34e931SWANG Cong 	struct net_device *real_dev;
18bf6bce71SStephen Hemminger 	char dev_name[IFNAMSIZ];
19bf6bce71SStephen Hemminger 	const char *name;
201da177e4SLinus Torvalds 	void (*rx_hook)(struct netpoll *, int, char *, int);
215de4a473SStephen Hemminger 
22e7557af5SHarvey Harrison 	__be32 local_ip, remote_ip;
231da177e4SLinus Torvalds 	u16 local_port, remote_port;
2409538641SStephen Hemminger 	u8 remote_mac[ETH_ALEN];
25508e14b4SDaniel Borkmann 
26508e14b4SDaniel Borkmann 	struct list_head rx; /* rx_np list element */
27115c1d6eSJeff Moyer };
28115c1d6eSJeff Moyer 
29115c1d6eSJeff Moyer struct netpoll_info {
3093ec2c72SStephen Hemminger 	atomic_t refcnt;
31508e14b4SDaniel Borkmann 
32d9452e9fSDavid S. Miller 	int rx_flags;
33fbeec2e1SJeff Moyer 	spinlock_t rx_lock;
34508e14b4SDaniel Borkmann 	struct list_head rx_np; /* netpolls that registered an rx_hook */
35508e14b4SDaniel Borkmann 
36068c6e98SNeil Horman 	struct sk_buff_head arp_tx; /* list of arp requests to reply to */
37b6cd27edSStephen Hemminger 	struct sk_buff_head txq;
38508e14b4SDaniel Borkmann 
396d5aefb8SDavid Howells 	struct delayed_work tx_work;
400e34e931SWANG Cong 
410e34e931SWANG Cong 	struct netpoll *netpoll;
421da177e4SLinus Torvalds };
431da177e4SLinus Torvalds 
440e34e931SWANG Cong void netpoll_poll_dev(struct net_device *dev);
451da177e4SLinus Torvalds void netpoll_poll(struct netpoll *np);
461da177e4SLinus Torvalds void netpoll_send_udp(struct netpoll *np, const char *msg, int len);
470bcc1816SSatyam Sharma void netpoll_print_options(struct netpoll *np);
481da177e4SLinus Torvalds int netpoll_parse_options(struct netpoll *np, char *opt);
498fdd95ecSHerbert Xu int __netpoll_setup(struct netpoll *np);
501da177e4SLinus Torvalds int netpoll_setup(struct netpoll *np);
511da177e4SLinus Torvalds int netpoll_trap(void);
521da177e4SLinus Torvalds void netpoll_set_trap(int trap);
538fdd95ecSHerbert Xu void __netpoll_cleanup(struct netpoll *np);
541da177e4SLinus Torvalds void netpoll_cleanup(struct netpoll *np);
551da177e4SLinus Torvalds int __netpoll_rx(struct sk_buff *skb);
560e34e931SWANG Cong void netpoll_send_skb(struct netpoll *np, struct sk_buff *skb);
575de4a473SStephen Hemminger 
581da177e4SLinus Torvalds 
591da177e4SLinus Torvalds #ifdef CONFIG_NETPOLL
60ffb27362SDavid S. Miller static inline bool netpoll_rx(struct sk_buff *skb)
611da177e4SLinus Torvalds {
62de85d99eSHerbert Xu 	struct netpoll_info *npinfo;
63fbeec2e1SJeff Moyer 	unsigned long flags;
64ffb27362SDavid S. Miller 	bool ret = false;
65115c1d6eSJeff Moyer 
66de85d99eSHerbert Xu 	rcu_read_lock_bh();
67de85d99eSHerbert Xu 	npinfo = rcu_dereference(skb->dev->npinfo);
68de85d99eSHerbert Xu 
69508e14b4SDaniel Borkmann 	if (!npinfo || (list_empty(&npinfo->rx_np) && !npinfo->rx_flags))
70de85d99eSHerbert Xu 		goto out;
71115c1d6eSJeff Moyer 
72fbeec2e1SJeff Moyer 	spin_lock_irqsave(&npinfo->rx_lock, flags);
73d9452e9fSDavid S. Miller 	/* check rx_flags again with the lock held */
74d9452e9fSDavid S. Miller 	if (npinfo->rx_flags && __netpoll_rx(skb))
75ffb27362SDavid S. Miller 		ret = true;
76fbeec2e1SJeff Moyer 	spin_unlock_irqrestore(&npinfo->rx_lock, flags);
77fbeec2e1SJeff Moyer 
78de85d99eSHerbert Xu out:
79de85d99eSHerbert Xu 	rcu_read_unlock_bh();
80fbeec2e1SJeff Moyer 	return ret;
811da177e4SLinus Torvalds }
821da177e4SLinus Torvalds 
83d1c76af9SHerbert Xu static inline int netpoll_rx_on(struct sk_buff *skb)
84d1c76af9SHerbert Xu {
85de85d99eSHerbert Xu 	struct netpoll_info *npinfo = rcu_dereference(skb->dev->npinfo);
86d1c76af9SHerbert Xu 
87508e14b4SDaniel Borkmann 	return npinfo && (!list_empty(&npinfo->rx_np) || npinfo->rx_flags);
88d1c76af9SHerbert Xu }
89d1c76af9SHerbert Xu 
90bea3348eSStephen Hemminger static inline int netpoll_receive_skb(struct sk_buff *skb)
911da177e4SLinus Torvalds {
92bea3348eSStephen Hemminger 	if (!list_empty(&skb->dev->napi_list))
93bea3348eSStephen Hemminger 		return netpoll_rx(skb);
94bea3348eSStephen Hemminger 	return 0;
95bea3348eSStephen Hemminger }
96bea3348eSStephen Hemminger 
97bea3348eSStephen Hemminger static inline void *netpoll_poll_lock(struct napi_struct *napi)
98bea3348eSStephen Hemminger {
99bea3348eSStephen Hemminger 	struct net_device *dev = napi->dev;
100bea3348eSStephen Hemminger 
101bea3348eSStephen Hemminger 	if (dev && dev->npinfo) {
102bea3348eSStephen Hemminger 		spin_lock(&napi->poll_lock);
103bea3348eSStephen Hemminger 		napi->poll_owner = smp_processor_id();
104bea3348eSStephen Hemminger 		return napi;
1051da177e4SLinus Torvalds 	}
10653fb95d3SMatt Mackall 	return NULL;
1071da177e4SLinus Torvalds }
1081da177e4SLinus Torvalds 
10953fb95d3SMatt Mackall static inline void netpoll_poll_unlock(void *have)
1101da177e4SLinus Torvalds {
111bea3348eSStephen Hemminger 	struct napi_struct *napi = have;
11253fb95d3SMatt Mackall 
113bea3348eSStephen Hemminger 	if (napi) {
114bea3348eSStephen Hemminger 		napi->poll_owner = -1;
115bea3348eSStephen Hemminger 		spin_unlock(&napi->poll_lock);
1161da177e4SLinus Torvalds 	}
1171da177e4SLinus Torvalds }
1181da177e4SLinus Torvalds 
119*c18370f5SHerbert Xu static inline int netpoll_tx_running(struct net_device *dev)
120*c18370f5SHerbert Xu {
121*c18370f5SHerbert Xu 	return irqs_disabled();
122*c18370f5SHerbert Xu }
123*c18370f5SHerbert Xu 
1241da177e4SLinus Torvalds #else
125bea3348eSStephen Hemminger static inline int netpoll_rx(struct sk_buff *skb)
126bea3348eSStephen Hemminger {
127bea3348eSStephen Hemminger 	return 0;
128bea3348eSStephen Hemminger }
129d1c76af9SHerbert Xu static inline int netpoll_rx_on(struct sk_buff *skb)
130d1c76af9SHerbert Xu {
131d1c76af9SHerbert Xu 	return 0;
132d1c76af9SHerbert Xu }
133bea3348eSStephen Hemminger static inline int netpoll_receive_skb(struct sk_buff *skb)
134bea3348eSStephen Hemminger {
135bea3348eSStephen Hemminger 	return 0;
136bea3348eSStephen Hemminger }
137bea3348eSStephen Hemminger static inline void *netpoll_poll_lock(struct napi_struct *napi)
138bea3348eSStephen Hemminger {
139bea3348eSStephen Hemminger 	return NULL;
140bea3348eSStephen Hemminger }
141bea3348eSStephen Hemminger static inline void netpoll_poll_unlock(void *have)
142bea3348eSStephen Hemminger {
143bea3348eSStephen Hemminger }
144bea3348eSStephen Hemminger static inline void netpoll_netdev_init(struct net_device *dev)
145bea3348eSStephen Hemminger {
146bea3348eSStephen Hemminger }
147*c18370f5SHerbert Xu static inline int netpoll_tx_running(struct net_device *dev)
148*c18370f5SHerbert Xu {
149*c18370f5SHerbert Xu 	return 0;
150*c18370f5SHerbert Xu }
1511da177e4SLinus Torvalds #endif
1521da177e4SLinus Torvalds 
1531da177e4SLinus Torvalds #endif
154