blob: 3ef82d3a78db51d958858470f8158f72cfd74fb3 [file] [log] [blame]
Greg Kroah-Hartmanb2441312017-11-01 15:07:57 +01001/* SPDX-License-Identifier: GPL-2.0 */
Linus Torvalds1da177e2005-04-16 15:20:36 -07002/*
3 * Common code for low-level network console, dump, and debugger code
4 *
5 * Derived from netconsole, kgdb-over-ethernet, and netdump patches
6 */
7
8#ifndef _LINUX_NETPOLL_H
9#define _LINUX_NETPOLL_H
10
11#include <linux/netdevice.h>
12#include <linux/interrupt.h>
Matt Mackall53fb95d2005-08-11 19:27:43 -070013#include <linux/rcupdate.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070014#include <linux/list.h>
Reshetova, Elena433cea42017-06-30 13:08:04 +030015#include <linux/refcount.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070016
Cong Wangb7394d22013-01-07 20:52:39 +000017union inet_addr {
18 __u32 all[4];
19 __be32 ip;
20 __be32 ip6[4];
21 struct in_addr in;
22 struct in6_addr in6;
23};
24
Linus Torvalds1da177e2005-04-16 15:20:36 -070025struct netpoll {
26 struct net_device *dev;
Stephen Hemmingerbf6bce72006-10-26 15:46:56 -070027 char dev_name[IFNAMSIZ];
28 const char *name;
Stephen Hemminger5de4a472006-10-26 15:46:55 -070029
Cong Wangb7394d22013-01-07 20:52:39 +000030 union inet_addr local_ip, remote_ip;
31 bool ipv6;
Linus Torvalds1da177e2005-04-16 15:20:36 -070032 u16 local_port, remote_port;
Stephen Hemminger09538642007-11-19 19:23:29 -080033 u8 remote_mac[ETH_ALEN];
Daniel Borkmann508e14b2010-01-12 14:27:30 +000034
Neil Horman2cde6ac2013-02-11 10:25:30 +000035 struct work_struct cleanup_work;
Jeff Moyer115c1d62005-06-22 22:05:31 -070036};
37
38struct netpoll_info {
Reshetova, Elena433cea42017-06-30 13:08:04 +030039 refcount_t refcnt;
Daniel Borkmann508e14b2010-01-12 14:27:30 +000040
Neil Hormanbd7c4b62013-04-30 05:35:05 +000041 struct semaphore dev_lock;
Daniel Borkmann508e14b2010-01-12 14:27:30 +000042
Stephen Hemmingerb6cd27e2006-10-26 15:46:51 -070043 struct sk_buff_head txq;
Daniel Borkmann508e14b2010-01-12 14:27:30 +000044
David Howells6d5aefb2006-12-05 19:36:26 +000045 struct delayed_work tx_work;
WANG Cong0e34e932010-05-06 00:47:21 -070046
47 struct netpoll *netpoll;
Amerigo Wang38e6bc12012-08-10 01:24:38 +000048 struct rcu_head rcu;
Linus Torvalds1da177e2005-04-16 15:20:36 -070049};
50
Neil Hormanca99ca12013-02-05 08:05:43 +000051#ifdef CONFIG_NETPOLL
Eric Dumazetac3d9dd2018-09-21 15:27:38 -070052void netpoll_poll_dev(struct net_device *dev);
53void netpoll_poll_disable(struct net_device *dev);
54void netpoll_poll_enable(struct net_device *dev);
Neil Hormanca99ca12013-02-05 08:05:43 +000055#else
Eric W. Biederman66b55522014-03-27 15:39:03 -070056static inline void netpoll_poll_disable(struct net_device *dev) { return; }
57static inline void netpoll_poll_enable(struct net_device *dev) { return; }
Neil Hormanca99ca12013-02-05 08:05:43 +000058#endif
59
Linus Torvalds1da177e2005-04-16 15:20:36 -070060void netpoll_send_udp(struct netpoll *np, const char *msg, int len);
Satyam Sharma0bcc1812007-08-10 15:35:05 -070061void netpoll_print_options(struct netpoll *np);
Linus Torvalds1da177e2005-04-16 15:20:36 -070062int netpoll_parse_options(struct netpoll *np, char *opt);
Eric W. Biedermana8779ec2014-03-27 15:36:38 -070063int __netpoll_setup(struct netpoll *np, struct net_device *ndev);
Linus Torvalds1da177e2005-04-16 15:20:36 -070064int netpoll_setup(struct netpoll *np);
Herbert Xu8fdd95e2010-06-10 16:12:48 +000065void __netpoll_cleanup(struct netpoll *np);
Neil Horman2cde6ac2013-02-11 10:25:30 +000066void __netpoll_free_async(struct netpoll *np);
Linus Torvalds1da177e2005-04-16 15:20:36 -070067void netpoll_cleanup(struct netpoll *np);
Neil Hormanc2355e12010-10-13 16:01:49 +000068void netpoll_send_skb_on_dev(struct netpoll *np, struct sk_buff *skb,
69 struct net_device *dev);
70static inline void netpoll_send_skb(struct netpoll *np, struct sk_buff *skb)
71{
Amerigo Wang28996562012-08-10 01:24:42 +000072 unsigned long flags;
73 local_irq_save(flags);
Neil Hormanc2355e12010-10-13 16:01:49 +000074 netpoll_send_skb_on_dev(np, skb, np->dev);
Amerigo Wang28996562012-08-10 01:24:42 +000075 local_irq_restore(flags);
Neil Hormanc2355e12010-10-13 16:01:49 +000076}
77
Eric W. Biedermane1bd4d32014-03-14 20:50:58 -070078#ifdef CONFIG_NETPOLL
Stephen Hemmingerbea33482007-10-03 16:41:36 -070079static inline void *netpoll_poll_lock(struct napi_struct *napi)
80{
81 struct net_device *dev = napi->dev;
82
Stephen Hemmingerbea33482007-10-03 16:41:36 -070083 if (dev && dev->npinfo) {
Eric Dumazet89c4b442016-11-16 14:54:50 -080084 int owner = smp_processor_id();
85
86 while (cmpxchg(&napi->poll_owner, -1, owner) != -1)
87 cpu_relax();
88
Stephen Hemmingerbea33482007-10-03 16:41:36 -070089 return napi;
Linus Torvalds1da177e2005-04-16 15:20:36 -070090 }
Matt Mackall53fb95d2005-08-11 19:27:43 -070091 return NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -070092}
93
Matt Mackall53fb95d2005-08-11 19:27:43 -070094static inline void netpoll_poll_unlock(void *have)
Linus Torvalds1da177e2005-04-16 15:20:36 -070095{
Stephen Hemmingerbea33482007-10-03 16:41:36 -070096 struct napi_struct *napi = have;
Matt Mackall53fb95d2005-08-11 19:27:43 -070097
Eric Dumazet89c4b442016-11-16 14:54:50 -080098 if (napi)
99 smp_store_release(&napi->poll_owner, -1);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700100}
101
Amerigo Wang77ab8a52012-08-10 01:24:46 +0000102static inline bool netpoll_tx_running(struct net_device *dev)
Herbert Xuc18370f2010-06-10 16:12:49 +0000103{
104 return irqs_disabled();
105}
106
Linus Torvalds1da177e2005-04-16 15:20:36 -0700107#else
Stephen Hemmingerbea33482007-10-03 16:41:36 -0700108static inline void *netpoll_poll_lock(struct napi_struct *napi)
109{
110 return NULL;
111}
112static inline void netpoll_poll_unlock(void *have)
113{
114}
115static inline void netpoll_netdev_init(struct net_device *dev)
116{
117}
Amerigo Wang77ab8a52012-08-10 01:24:46 +0000118static inline bool netpoll_tx_running(struct net_device *dev)
Herbert Xuc18370f2010-06-10 16:12:49 +0000119{
Amerigo Wang77ab8a52012-08-10 01:24:46 +0000120 return false;
Herbert Xuc18370f2010-06-10 16:12:49 +0000121}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700122#endif
123
124#endif