138494Sobrien/*-
2174294Sobrien * Copyright (c) 2010 Isilon Systems, Inc.
338494Sobrien * Copyright (c) 2010 iX Systems, Inc.
438494Sobrien * Copyright (c) 2010 Panasas, Inc.
538494Sobrien * All rights reserved.
638494Sobrien *
738494Sobrien * Redistribution and use in source and binary forms, with or without
838494Sobrien * modification, are permitted provided that the following conditions
938494Sobrien * are met:
1038494Sobrien * 1. Redistributions of source code must retain the above copyright
1138494Sobrien *    notice unmodified, this list of conditions, and the following
1238494Sobrien *    disclaimer.
1338494Sobrien * 2. Redistributions in binary form must reproduce the above copyright
1438494Sobrien *    notice, this list of conditions and the following disclaimer in the
1538494Sobrien *    documentation and/or other materials provided with the distribution.
1638494Sobrien *
1738494Sobrien * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
1838494Sobrien * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
1938494Sobrien * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
2042629Sobrien * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
2138494Sobrien * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
2238494Sobrien * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2338494Sobrien * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2438494Sobrien * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2538494Sobrien * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
2638494Sobrien * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2738494Sobrien */
2838494Sobrien#ifndef	_LINUX_NETDEVICE_H_
2938494Sobrien#define	_LINUX_NETDEVICE_H_
3038494Sobrien
3138494Sobrien#include <linux/types.h>
3238494Sobrien
3338494Sobrien#include <sys/socket.h>
3438494Sobrien
3538494Sobrien#include <net/if_types.h>
3638494Sobrien#include <net/if.h>
3738494Sobrien#include <net/if_var.h>
3838494Sobrien#include <net/if_dl.h>
3938494Sobrien
40174294Sobrien#include <linux/completion.h>
4138494Sobrien#include <linux/device.h>
4238494Sobrien#include <linux/ethtool.h>
4338494Sobrien#include <linux/workqueue.h>
4438494Sobrien#include <linux/net.h>
4538494Sobrien#include <linux/notifier.h>
4638494Sobrien
4738494Sobrienstruct net {
4838494Sobrien};
4938494Sobrien
5038494Sobrienextern struct net init_net;
5138494Sobrien
5238494Sobrien#define	MAX_ADDR_LEN		20
5338494Sobrien
5438494Sobrien#define	net_device	ifnet
5538494Sobrien
5638494Sobrien#define	dev_get_by_index(n, idx)	ifnet_byindex_ref((idx))
5738494Sobrien#define	dev_hold(d)	if_ref((d))
5838494Sobrien#define	dev_put(d)	if_rele((d))
5938494Sobrien
6038494Sobrien#define	netif_running(dev)	!!((dev)->if_drv_flags & IFF_DRV_RUNNING)
6138494Sobrien#define	netif_oper_up(dev)	!!((dev)->if_flags & IFF_UP)
6238494Sobrien#define	netif_carrier_ok(dev)	netif_running(dev)
6338494Sobrien
6438494Sobrienstatic inline void *
6538494Sobriennetdev_priv(const struct net_device *dev)
6638494Sobrien{
6738494Sobrien	return (dev->if_softc);
6838494Sobrien}
6938494Sobrien
7038494Sobrienstatic inline void
7138494Sobrien_handle_ifnet_link_event(void *arg, struct ifnet *ifp, int linkstate)
7238494Sobrien{
7338494Sobrien	struct notifier_block *nb;
7438494Sobrien
7538494Sobrien	nb = arg;
7638494Sobrien	if (linkstate == LINK_STATE_UP)
7738494Sobrien		nb->notifier_call(nb, NETDEV_UP, ifp);
7838494Sobrien	else
7938494Sobrien		nb->notifier_call(nb, NETDEV_DOWN, ifp);
8038494Sobrien}
8138494Sobrien
8238494Sobrienstatic inline void
8338494Sobrien_handle_ifnet_arrival_event(void *arg, struct ifnet *ifp)
8438494Sobrien{
8538494Sobrien	struct notifier_block *nb;
8638494Sobrien
8738494Sobrien	nb = arg;
8838494Sobrien	nb->notifier_call(nb, NETDEV_REGISTER, ifp);
8938494Sobrien}
9038494Sobrien
9138494Sobrienstatic inline void
9238494Sobrien_handle_ifnet_departure_event(void *arg, struct ifnet *ifp)
9338494Sobrien{
9438494Sobrien	struct notifier_block *nb;
9538494Sobrien
9638494Sobrien	nb = arg;
9738494Sobrien	nb->notifier_call(nb, NETDEV_UNREGISTER, ifp);
9838494Sobrien}
9938494Sobrien
10038494Sobrienstatic inline int
10138494Sobrienregister_netdevice_notifier(struct notifier_block *nb)
10238494Sobrien{
10338494Sobrien
10438494Sobrien	nb->tags[NETDEV_UP] = EVENTHANDLER_REGISTER(
10538494Sobrien	    ifnet_link_event, _handle_ifnet_link_event, nb, 0);
10638494Sobrien	nb->tags[NETDEV_REGISTER] = EVENTHANDLER_REGISTER(
10738494Sobrien	    ifnet_arrival_event, _handle_ifnet_arrival_event, nb, 0);
10838494Sobrien	nb->tags[NETDEV_UNREGISTER] = EVENTHANDLER_REGISTER(
10938494Sobrien	    ifnet_departure_event, _handle_ifnet_departure_event, nb, 0);
11038494Sobrien	return (0);
11138494Sobrien}
11238494Sobrien
11338494Sobrienstatic inline int
114174294Sobrienunregister_netdevice_notifier(struct notifier_block *nb)
11538494Sobrien{
11638494Sobrien
11738494Sobrien        EVENTHANDLER_DEREGISTER(ifnet_link_event, nb->tags[NETDEV_UP]);
118174294Sobrien        EVENTHANDLER_DEREGISTER(ifnet_arrival_event, nb->tags[NETDEV_REGISTER]);
11938494Sobrien        EVENTHANDLER_DEREGISTER(ifnet_departure_event,
12038494Sobrien	    nb->tags[NETDEV_UNREGISTER]);
12138494Sobrien	return (0);
12238494Sobrien}
12338494Sobrien
12438494Sobrien#define	rtnl_lock()
12538494Sobrien#define	rtnl_unlock()
126174294Sobrien
127174294Sobrienstatic inline int
12838494Sobriendev_mc_delete(struct net_device *dev, void *addr, int alen, int all)
129174294Sobrien{
13038494Sobrien	struct sockaddr_dl sdl;
13138494Sobrien
13238494Sobrien	if (alen > sizeof(sdl.sdl_data))
133119679Smbr		return (-EINVAL);
13438494Sobrien	memset(&sdl, 0, sizeof(sdl));
135174294Sobrien	sdl.sdl_len = sizeof(sdl);
13638494Sobrien	sdl.sdl_family = AF_LINK;
13738494Sobrien	sdl.sdl_alen = alen;
13838494Sobrien	memcpy(&sdl.sdl_data, addr, alen);
13938494Sobrien
14038494Sobrien	return -if_delmulti(dev, (struct sockaddr *)&sdl);
14138494Sobrien}
14238494Sobrien
14338494Sobrienstatic inline int
14438494Sobriendev_mc_add(struct net_device *dev, void *addr, int alen, int newonly)
14538494Sobrien{
14638494Sobrien	struct sockaddr_dl sdl;
14738494Sobrien
148119679Smbr	if (alen > sizeof(sdl.sdl_data))
14938494Sobrien		return (-EINVAL);
15038494Sobrien	memset(&sdl, 0, sizeof(sdl));
15138494Sobrien	sdl.sdl_len = sizeof(sdl);
15238494Sobrien	sdl.sdl_family = AF_LINK;
15338494Sobrien	sdl.sdl_alen = alen;
15438494Sobrien	memcpy(&sdl.sdl_data, addr, alen);
15538494Sobrien
15638494Sobrien	return -if_addmulti(dev, (struct sockaddr *)&sdl, NULL);
15738494Sobrien}
15838494Sobrien
15938494Sobrien#endif	/* _LINUX_NETDEVICE_H_ */
16038494Sobrien