netdevice.h revision 289644
1219820Sjeff/*-
2219820Sjeff * Copyright (c) 2010 Isilon Systems, Inc.
3219820Sjeff * Copyright (c) 2010 iX Systems, Inc.
4219820Sjeff * Copyright (c) 2010 Panasas, Inc.
5270710Shselasky * Copyright (c) 2013, 2014 Mellanox Technologies, Ltd.
6219820Sjeff * All rights reserved.
7219820Sjeff *
8219820Sjeff * Redistribution and use in source and binary forms, with or without
9219820Sjeff * modification, are permitted provided that the following conditions
10219820Sjeff * are met:
11219820Sjeff * 1. Redistributions of source code must retain the above copyright
12219820Sjeff *    notice unmodified, this list of conditions, and the following
13219820Sjeff *    disclaimer.
14219820Sjeff * 2. Redistributions in binary form must reproduce the above copyright
15219820Sjeff *    notice, this list of conditions and the following disclaimer in the
16219820Sjeff *    documentation and/or other materials provided with the distribution.
17219820Sjeff *
18219820Sjeff * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19219820Sjeff * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20219820Sjeff * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21219820Sjeff * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22219820Sjeff * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23219820Sjeff * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24219820Sjeff * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25219820Sjeff * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26219820Sjeff * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27219820Sjeff * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28289644Shselasky *
29289644Shselasky * $FreeBSD: head/sys/ofed/include/linux/netdevice.h 289644 2015-10-20 19:08:26Z hselasky $
30219820Sjeff */
31219820Sjeff#ifndef	_LINUX_NETDEVICE_H_
32219820Sjeff#define	_LINUX_NETDEVICE_H_
33219820Sjeff
34219820Sjeff#include <linux/types.h>
35219820Sjeff
36219820Sjeff#include <sys/socket.h>
37219820Sjeff
38219820Sjeff#include <net/if_types.h>
39219820Sjeff#include <net/if.h>
40219820Sjeff#include <net/if_var.h>
41219820Sjeff#include <net/if_dl.h>
42219820Sjeff
43219820Sjeff#include <linux/completion.h>
44219820Sjeff#include <linux/device.h>
45219820Sjeff#include <linux/workqueue.h>
46219820Sjeff#include <linux/net.h>
47219820Sjeff#include <linux/notifier.h>
48219820Sjeff
49219820Sjeffstruct net {
50219820Sjeff};
51219820Sjeff
52219820Sjeffextern struct net init_net;
53219820Sjeff
54219820Sjeff#define	MAX_ADDR_LEN		20
55219820Sjeff
56219820Sjeff#define	net_device	ifnet
57219820Sjeff
58219820Sjeff#define	dev_get_by_index(n, idx)	ifnet_byindex_ref((idx))
59219820Sjeff#define	dev_hold(d)	if_ref((d))
60219820Sjeff#define	dev_put(d)	if_rele((d))
61219820Sjeff
62219820Sjeff#define	netif_running(dev)	!!((dev)->if_drv_flags & IFF_DRV_RUNNING)
63219820Sjeff#define	netif_oper_up(dev)	!!((dev)->if_flags & IFF_UP)
64219820Sjeff#define	netif_carrier_ok(dev)	netif_running(dev)
65219820Sjeff
66219820Sjeffstatic inline void *
67219820Sjeffnetdev_priv(const struct net_device *dev)
68219820Sjeff{
69219820Sjeff	return (dev->if_softc);
70219820Sjeff}
71219820Sjeff
72219820Sjeffstatic inline void
73219820Sjeff_handle_ifnet_link_event(void *arg, struct ifnet *ifp, int linkstate)
74219820Sjeff{
75219820Sjeff	struct notifier_block *nb;
76219820Sjeff
77219820Sjeff	nb = arg;
78219820Sjeff	if (linkstate == LINK_STATE_UP)
79219820Sjeff		nb->notifier_call(nb, NETDEV_UP, ifp);
80219820Sjeff	else
81219820Sjeff		nb->notifier_call(nb, NETDEV_DOWN, ifp);
82219820Sjeff}
83219820Sjeff
84219820Sjeffstatic inline void
85219820Sjeff_handle_ifnet_arrival_event(void *arg, struct ifnet *ifp)
86219820Sjeff{
87219820Sjeff	struct notifier_block *nb;
88219820Sjeff
89219820Sjeff	nb = arg;
90219820Sjeff	nb->notifier_call(nb, NETDEV_REGISTER, ifp);
91219820Sjeff}
92219820Sjeff
93219820Sjeffstatic inline void
94219820Sjeff_handle_ifnet_departure_event(void *arg, struct ifnet *ifp)
95219820Sjeff{
96219820Sjeff	struct notifier_block *nb;
97219820Sjeff
98219820Sjeff	nb = arg;
99219820Sjeff	nb->notifier_call(nb, NETDEV_UNREGISTER, ifp);
100219820Sjeff}
101219820Sjeff
102270710Shselaskystatic inline void
103270710Shselasky_handle_iflladdr_event(void *arg, struct ifnet *ifp)
104270710Shselasky{
105270710Shselasky	struct notifier_block *nb;
106270710Shselasky
107270710Shselasky	nb = arg;
108270710Shselasky	nb->notifier_call(nb, NETDEV_CHANGEADDR, ifp);
109270710Shselasky}
110270710Shselasky
111270710Shselaskystatic inline void
112270710Shselasky_handle_ifaddr_event(void *arg, struct ifnet *ifp)
113270710Shselasky{
114270710Shselasky	struct notifier_block *nb;
115270710Shselasky
116270710Shselasky	nb = arg;
117270710Shselasky	nb->notifier_call(nb, NETDEV_CHANGEIFADDR, ifp);
118270710Shselasky}
119270710Shselasky
120219820Sjeffstatic inline int
121219820Sjeffregister_netdevice_notifier(struct notifier_block *nb)
122219820Sjeff{
123219820Sjeff
124219820Sjeff	nb->tags[NETDEV_UP] = EVENTHANDLER_REGISTER(
125219820Sjeff	    ifnet_link_event, _handle_ifnet_link_event, nb, 0);
126219820Sjeff	nb->tags[NETDEV_REGISTER] = EVENTHANDLER_REGISTER(
127219820Sjeff	    ifnet_arrival_event, _handle_ifnet_arrival_event, nb, 0);
128219820Sjeff	nb->tags[NETDEV_UNREGISTER] = EVENTHANDLER_REGISTER(
129219820Sjeff	    ifnet_departure_event, _handle_ifnet_departure_event, nb, 0);
130270710Shselasky	nb->tags[NETDEV_CHANGEADDR] = EVENTHANDLER_REGISTER(
131270710Shselasky	    iflladdr_event, _handle_iflladdr_event, nb, 0);
132270710Shselasky
133219820Sjeff	return (0);
134219820Sjeff}
135219820Sjeff
136219820Sjeffstatic inline int
137270710Shselaskyregister_inetaddr_notifier(struct notifier_block *nb)
138270710Shselasky{
139270710Shselasky
140270710Shselasky        nb->tags[NETDEV_CHANGEIFADDR] = EVENTHANDLER_REGISTER(
141270710Shselasky            ifaddr_event, _handle_ifaddr_event, nb, 0);
142270710Shselasky        return (0);
143270710Shselasky}
144270710Shselasky
145270710Shselaskystatic inline int
146219820Sjeffunregister_netdevice_notifier(struct notifier_block *nb)
147219820Sjeff{
148219820Sjeff
149219820Sjeff        EVENTHANDLER_DEREGISTER(ifnet_link_event, nb->tags[NETDEV_UP]);
150219820Sjeff        EVENTHANDLER_DEREGISTER(ifnet_arrival_event, nb->tags[NETDEV_REGISTER]);
151219820Sjeff        EVENTHANDLER_DEREGISTER(ifnet_departure_event,
152219820Sjeff	    nb->tags[NETDEV_UNREGISTER]);
153270710Shselasky        EVENTHANDLER_DEREGISTER(iflladdr_event,
154270710Shselasky            nb->tags[NETDEV_CHANGEADDR]);
155270710Shselasky
156219820Sjeff	return (0);
157219820Sjeff}
158219820Sjeff
159270710Shselaskystatic inline int
160270710Shselaskyunregister_inetaddr_notifier(struct notifier_block *nb)
161270710Shselasky{
162270710Shselasky
163270710Shselasky        EVENTHANDLER_DEREGISTER(ifaddr_event,
164270710Shselasky            nb->tags[NETDEV_CHANGEIFADDR]);
165270710Shselasky
166270710Shselasky        return (0);
167270710Shselasky}
168270710Shselasky
169270710Shselasky
170219820Sjeff#define	rtnl_lock()
171219820Sjeff#define	rtnl_unlock()
172219820Sjeff
173219820Sjeffstatic inline int
174219820Sjeffdev_mc_delete(struct net_device *dev, void *addr, int alen, int all)
175219820Sjeff{
176219820Sjeff	struct sockaddr_dl sdl;
177219820Sjeff
178219820Sjeff	if (alen > sizeof(sdl.sdl_data))
179219820Sjeff		return (-EINVAL);
180219820Sjeff	memset(&sdl, 0, sizeof(sdl));
181219820Sjeff	sdl.sdl_len = sizeof(sdl);
182219820Sjeff	sdl.sdl_family = AF_LINK;
183219820Sjeff	sdl.sdl_alen = alen;
184219820Sjeff	memcpy(&sdl.sdl_data, addr, alen);
185219820Sjeff
186219820Sjeff	return -if_delmulti(dev, (struct sockaddr *)&sdl);
187219820Sjeff}
188219820Sjeff
189219820Sjeffstatic inline int
190219820Sjeffdev_mc_add(struct net_device *dev, void *addr, int alen, int newonly)
191219820Sjeff{
192219820Sjeff	struct sockaddr_dl sdl;
193219820Sjeff
194219820Sjeff	if (alen > sizeof(sdl.sdl_data))
195219820Sjeff		return (-EINVAL);
196219820Sjeff	memset(&sdl, 0, sizeof(sdl));
197219820Sjeff	sdl.sdl_len = sizeof(sdl);
198219820Sjeff	sdl.sdl_family = AF_LINK;
199219820Sjeff	sdl.sdl_alen = alen;
200219820Sjeff	memcpy(&sdl.sdl_data, addr, alen);
201219820Sjeff
202219820Sjeff	return -if_addmulti(dev, (struct sockaddr *)&sdl, NULL);
203219820Sjeff}
204219820Sjeff
205219820Sjeff#endif	/* _LINUX_NETDEVICE_H_ */
206