netdevice.h revision 219820
1219820Sjeff/*-
2219820Sjeff * Copyright (c) 2010 Isilon Systems, Inc.
3219820Sjeff * Copyright (c) 2010 iX Systems, Inc.
4219820Sjeff * Copyright (c) 2010 Panasas, Inc.
5219820Sjeff * All rights reserved.
6219820Sjeff *
7219820Sjeff * Redistribution and use in source and binary forms, with or without
8219820Sjeff * modification, are permitted provided that the following conditions
9219820Sjeff * are met:
10219820Sjeff * 1. Redistributions of source code must retain the above copyright
11219820Sjeff *    notice unmodified, this list of conditions, and the following
12219820Sjeff *    disclaimer.
13219820Sjeff * 2. Redistributions in binary form must reproduce the above copyright
14219820Sjeff *    notice, this list of conditions and the following disclaimer in the
15219820Sjeff *    documentation and/or other materials provided with the distribution.
16219820Sjeff *
17219820Sjeff * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18219820Sjeff * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19219820Sjeff * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20219820Sjeff * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21219820Sjeff * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22219820Sjeff * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23219820Sjeff * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24219820Sjeff * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25219820Sjeff * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26219820Sjeff * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27219820Sjeff */
28219820Sjeff#ifndef	_LINUX_NETDEVICE_H_
29219820Sjeff#define	_LINUX_NETDEVICE_H_
30219820Sjeff
31219820Sjeff#include <linux/types.h>
32219820Sjeff
33219820Sjeff#include <sys/socket.h>
34219820Sjeff
35219820Sjeff#include <net/if_types.h>
36219820Sjeff#include <net/if.h>
37219820Sjeff#include <net/if_var.h>
38219820Sjeff#include <net/if_dl.h>
39219820Sjeff
40219820Sjeff#include <linux/completion.h>
41219820Sjeff#include <linux/device.h>
42219820Sjeff#include <linux/ethtool.h>
43219820Sjeff#include <linux/workqueue.h>
44219820Sjeff#include <linux/net.h>
45219820Sjeff#include <linux/notifier.h>
46219820Sjeff
47219820Sjeffstruct net {
48219820Sjeff};
49219820Sjeff
50219820Sjeffextern struct net init_net;
51219820Sjeff
52219820Sjeff#define	MAX_ADDR_LEN		20
53219820Sjeff
54219820Sjeff#define	net_device	ifnet
55219820Sjeff
56219820Sjeff#define	dev_get_by_index(n, idx)	ifnet_byindex_ref((idx))
57219820Sjeff#define	dev_hold(d)	if_ref((d))
58219820Sjeff#define	dev_put(d)	if_rele((d))
59219820Sjeff
60219820Sjeff#define	netif_running(dev)	!!((dev)->if_drv_flags & IFF_DRV_RUNNING)
61219820Sjeff#define	netif_oper_up(dev)	!!((dev)->if_flags & IFF_UP)
62219820Sjeff#define	netif_carrier_ok(dev)	netif_running(dev)
63219820Sjeff
64219820Sjeffstatic inline void *
65219820Sjeffnetdev_priv(const struct net_device *dev)
66219820Sjeff{
67219820Sjeff	return (dev->if_softc);
68219820Sjeff}
69219820Sjeff
70219820Sjeffstatic inline void
71219820Sjeff_handle_ifnet_link_event(void *arg, struct ifnet *ifp, int linkstate)
72219820Sjeff{
73219820Sjeff	struct notifier_block *nb;
74219820Sjeff
75219820Sjeff	nb = arg;
76219820Sjeff	if (linkstate == LINK_STATE_UP)
77219820Sjeff		nb->notifier_call(nb, NETDEV_UP, ifp);
78219820Sjeff	else
79219820Sjeff		nb->notifier_call(nb, NETDEV_DOWN, ifp);
80219820Sjeff}
81219820Sjeff
82219820Sjeffstatic inline void
83219820Sjeff_handle_ifnet_arrival_event(void *arg, struct ifnet *ifp)
84219820Sjeff{
85219820Sjeff	struct notifier_block *nb;
86219820Sjeff
87219820Sjeff	nb = arg;
88219820Sjeff	nb->notifier_call(nb, NETDEV_REGISTER, ifp);
89219820Sjeff}
90219820Sjeff
91219820Sjeffstatic inline void
92219820Sjeff_handle_ifnet_departure_event(void *arg, struct ifnet *ifp)
93219820Sjeff{
94219820Sjeff	struct notifier_block *nb;
95219820Sjeff
96219820Sjeff	nb = arg;
97219820Sjeff	nb->notifier_call(nb, NETDEV_UNREGISTER, ifp);
98219820Sjeff}
99219820Sjeff
100219820Sjeffstatic inline int
101219820Sjeffregister_netdevice_notifier(struct notifier_block *nb)
102219820Sjeff{
103219820Sjeff
104219820Sjeff	nb->tags[NETDEV_UP] = EVENTHANDLER_REGISTER(
105219820Sjeff	    ifnet_link_event, _handle_ifnet_link_event, nb, 0);
106219820Sjeff	nb->tags[NETDEV_REGISTER] = EVENTHANDLER_REGISTER(
107219820Sjeff	    ifnet_arrival_event, _handle_ifnet_arrival_event, nb, 0);
108219820Sjeff	nb->tags[NETDEV_UNREGISTER] = EVENTHANDLER_REGISTER(
109219820Sjeff	    ifnet_departure_event, _handle_ifnet_departure_event, nb, 0);
110219820Sjeff	return (0);
111219820Sjeff}
112219820Sjeff
113219820Sjeffstatic inline int
114219820Sjeffunregister_netdevice_notifier(struct notifier_block *nb)
115219820Sjeff{
116219820Sjeff
117219820Sjeff        EVENTHANDLER_DEREGISTER(ifnet_link_event, nb->tags[NETDEV_UP]);
118219820Sjeff        EVENTHANDLER_DEREGISTER(ifnet_arrival_event, nb->tags[NETDEV_REGISTER]);
119219820Sjeff        EVENTHANDLER_DEREGISTER(ifnet_departure_event,
120219820Sjeff	    nb->tags[NETDEV_UNREGISTER]);
121219820Sjeff	return (0);
122219820Sjeff}
123219820Sjeff
124219820Sjeff#define	rtnl_lock()
125219820Sjeff#define	rtnl_unlock()
126219820Sjeff
127219820Sjeffstatic inline int
128219820Sjeffdev_mc_delete(struct net_device *dev, void *addr, int alen, int all)
129219820Sjeff{
130219820Sjeff	struct sockaddr_dl sdl;
131219820Sjeff
132219820Sjeff	if (alen > sizeof(sdl.sdl_data))
133219820Sjeff		return (-EINVAL);
134219820Sjeff	memset(&sdl, 0, sizeof(sdl));
135219820Sjeff	sdl.sdl_len = sizeof(sdl);
136219820Sjeff	sdl.sdl_family = AF_LINK;
137219820Sjeff	sdl.sdl_alen = alen;
138219820Sjeff	memcpy(&sdl.sdl_data, addr, alen);
139219820Sjeff
140219820Sjeff	return -if_delmulti(dev, (struct sockaddr *)&sdl);
141219820Sjeff}
142219820Sjeff
143219820Sjeffstatic inline int
144219820Sjeffdev_mc_add(struct net_device *dev, void *addr, int alen, int newonly)
145219820Sjeff{
146219820Sjeff	struct sockaddr_dl sdl;
147219820Sjeff
148219820Sjeff	if (alen > sizeof(sdl.sdl_data))
149219820Sjeff		return (-EINVAL);
150219820Sjeff	memset(&sdl, 0, sizeof(sdl));
151219820Sjeff	sdl.sdl_len = sizeof(sdl);
152219820Sjeff	sdl.sdl_family = AF_LINK;
153219820Sjeff	sdl.sdl_alen = alen;
154219820Sjeff	memcpy(&sdl.sdl_data, addr, alen);
155219820Sjeff
156219820Sjeff	return -if_addmulti(dev, (struct sockaddr *)&sdl, NULL);
157219820Sjeff}
158219820Sjeff
159219820Sjeff#endif	/* _LINUX_NETDEVICE_H_ */
160