opnsense-src/sys/compat/linuxkpi/common/include/linux/netdevice.h
Bjoern A. Zeeb 75388b9ca5 LinuxKPI: add (skeleton) functions to make drivers compile
Add more functions to netdevice.h (netif_napi_add_tx() being the only
one implemented) and add platform_device.h and netlink.h in order to
make driver code compile.
The skeleton functions are used only in very limited scope and not at
all in our usage so far but add (invasive) #ifdef if removed.
Add pr_debug() calls to each of them in order to log a TODO (if DEBUG
compiled in) and someone should hit them in the future.

MFC after:	3 days
Commented on by: hselasky (earlier version)
Differential Revision: https://reviews.freebsd.org/D37599
2023-01-13 00:38:11 +00:00

467 lines
12 KiB
C

/*-
* Copyright (c) 2010 Isilon Systems, Inc.
* Copyright (c) 2010 iX Systems, Inc.
* Copyright (c) 2010 Panasas, Inc.
* Copyright (c) 2013-2019 Mellanox Technologies, Ltd.
* All rights reserved.
* Copyright (c) 2020-2021 The FreeBSD Foundation
* Copyright (c) 2020-2022 Bjoern A. Zeeb
*
* Portions of this software were developed by Björn Zeeb
* under sponsorship from the FreeBSD Foundation.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice unmodified, this list of conditions, and the following
* disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* $FreeBSD$
*/
#ifndef _LINUXKPI_LINUX_NETDEVICE_H
#define _LINUXKPI_LINUX_NETDEVICE_H
#include <linux/types.h>
#include <linux/netdev_features.h>
#include <sys/param.h>
#include <sys/kernel.h>
#include <sys/lock.h>
#include <sys/mutex.h>
#include <sys/malloc.h>
#include <sys/queue.h>
#include <sys/socket.h>
#include <sys/taskqueue.h>
#include <net/if_types.h>
#include <net/if.h>
#include <net/if_var.h>
#include <net/if_dl.h>
#include <linux/kernel.h>
#include <linux/bitops.h>
#include <linux/list.h>
#include <linux/device.h>
#include <linux/net.h>
#include <linux/if_ether.h>
#include <linux/notifier.h>
#include <linux/random.h>
#include <linux/rcupdate.h>
#ifdef VIMAGE
#define init_net *vnet0
#else
#define init_net *((struct vnet *)0)
#endif
struct sk_buff;
struct net_device;
struct wireless_dev; /* net/cfg80211.h */
#define MAX_ADDR_LEN 20
#define NET_NAME_UNKNOWN 0
enum netdev_tx {
NETDEV_TX_OK = 0,
};
typedef enum netdev_tx netdev_tx_t;
struct netdev_hw_addr {
struct list_head addr_list;
uint8_t addr[MAX_ADDR_LEN];
};
struct netdev_hw_addr_list {
struct list_head addr_list;
int count;
};
enum net_device_reg_state {
NETREG_DUMMY = 1,
NETREG_REGISTERED,
};
struct net_device_ops {
int (*ndo_open)(struct net_device *);
int (*ndo_stop)(struct net_device *);
int (*ndo_set_mac_address)(struct net_device *, void *);
netdev_tx_t (*ndo_start_xmit)(struct sk_buff *, struct net_device *);
void (*ndo_set_rx_mode)(struct net_device *);
};
struct net_device {
/* BSD specific for compat. */
struct ifnet bsdifp;
/* net_device fields seen publicly. */
/* XXX can we later make some aliases to ifnet? */
char name[IFNAMSIZ];
struct wireless_dev *ieee80211_ptr;
uint8_t dev_addr[ETH_ALEN];
struct netdev_hw_addr_list mc;
netdev_features_t features;
struct {
unsigned long multicast;
unsigned long rx_bytes;
unsigned long rx_errors;
unsigned long rx_packets;
unsigned long tx_bytes;
unsigned long tx_dropped;
unsigned long tx_errors;
unsigned long tx_packets;
} stats;
enum net_device_reg_state reg_state;
const struct ethtool_ops *ethtool_ops;
const struct net_device_ops *netdev_ops;
bool needs_free_netdev;
/* Not properly typed as-of now. */
int flags, type;
int name_assign_type, needed_headroom;
int threaded;
void (*priv_destructor)(struct net_device *);
/* net_device internal. */
struct device dev;
/*
* In case we delete the net_device we need to be able to clear all
* NAPI consumers.
*/
struct mtx napi_mtx;
TAILQ_HEAD(, napi_struct) napi_head;
struct taskqueue *napi_tq;
/* Must stay last. */
uint8_t drv_priv[0] __aligned(CACHE_LINE_SIZE);
};
#define SET_NETDEV_DEV(_ndev, _dev) (_ndev)->dev.parent = _dev;
/* -------------------------------------------------------------------------- */
/* According to linux::ipoib_main.c. */
struct netdev_notifier_info {
struct net_device *dev;
struct ifnet *ifp;
};
static inline struct net_device *
netdev_notifier_info_to_dev(struct netdev_notifier_info *ni)
{
return (ni->dev);
}
static inline struct ifnet *
netdev_notifier_info_to_ifp(struct netdev_notifier_info *ni)
{
return (ni->ifp);
}
int register_netdevice_notifier(struct notifier_block *);
int register_inetaddr_notifier(struct notifier_block *);
int unregister_netdevice_notifier(struct notifier_block *);
int unregister_inetaddr_notifier(struct notifier_block *);
/* -------------------------------------------------------------------------- */
#define NAPI_POLL_WEIGHT 64 /* budget */
/*
* There are drivers directly testing napi state bits, so we need to publicly
* expose them. If you ask me, those accesses should be hid behind an
* inline function and the bit flags not be directly exposed.
*/
enum napi_state_bits {
/*
* Official Linux flags encountered.
*/
NAPI_STATE_SCHED = 1,
/*
* Our internal versions (for now).
*/
/* Do not schedule new things while we are waiting to clear things. */
LKPI_NAPI_FLAG_DISABLE_PENDING = 0,
/* To synchronise that only one poll is ever running. */
LKPI_NAPI_FLAG_IS_SCHEDULED = 1,
/* If trying to schedule while poll is running. Need to re-schedule. */
LKPI_NAPI_FLAG_LOST_RACE_TRY_AGAIN = 2,
/* When shutting down forcefully prevent anything from running task/poll. */
LKPI_NAPI_FLAG_SHUTDOWN = 3,
};
struct napi_struct {
TAILQ_ENTRY(napi_struct) entry;
struct list_head rx_list;
struct net_device *dev;
int (*poll)(struct napi_struct *, int);
int budget;
int rx_count;
/*
* These flags mostly need to be checked/changed atomically
* (multiple together in some cases).
*/
volatile unsigned long state;
/* FreeBSD internal. */
/* Use task for now, so we can easily switch between direct and task. */
struct task napi_task;
};
void linuxkpi_init_dummy_netdev(struct net_device *);
void linuxkpi_netif_napi_add(struct net_device *, struct napi_struct *,
int(*napi_poll)(struct napi_struct *, int));
void linuxkpi_netif_napi_del(struct napi_struct *);
bool linuxkpi_napi_schedule_prep(struct napi_struct *);
void linuxkpi___napi_schedule(struct napi_struct *);
void linuxkpi_napi_schedule(struct napi_struct *);
void linuxkpi_napi_reschedule(struct napi_struct *);
bool linuxkpi_napi_complete_done(struct napi_struct *, int);
bool linuxkpi_napi_complete(struct napi_struct *);
void linuxkpi_napi_disable(struct napi_struct *);
void linuxkpi_napi_enable(struct napi_struct *);
void linuxkpi_napi_synchronize(struct napi_struct *);
#define init_dummy_netdev(_n) \
linuxkpi_init_dummy_netdev(_n)
#define netif_napi_add(_nd, _ns, _p) \
linuxkpi_netif_napi_add(_nd, _ns, _p)
#define netif_napi_del(_n) \
linuxkpi_netif_napi_del(_n)
#define napi_schedule_prep(_n) \
linuxkpi_napi_schedule_prep(_n)
#define __napi_schedule(_n) \
linuxkpi___napi_schedule(_n)
#define napi_schedule(_n) \
linuxkpi_napi_schedule(_n)
#define napi_reschedule(_n) \
linuxkpi_napi_reschedule(_n)
#define napi_complete_done(_n, _r) \
linuxkpi_napi_complete_done(_n, _r)
#define napi_complete(_n) \
linuxkpi_napi_complete(_n)
#define napi_disable(_n) \
linuxkpi_napi_disable(_n)
#define napi_enable(_n) \
linuxkpi_napi_enable(_n)
#define napi_synchronize(_n) \
linuxkpi_napi_synchronize(_n)
static inline void
netif_napi_add_tx(struct net_device *dev, struct napi_struct *napi,
int(*napi_poll)(struct napi_struct *, int))
{
netif_napi_add(dev, napi, napi_poll);
}
/* -------------------------------------------------------------------------- */
static inline void
netdev_rss_key_fill(uint32_t *buf, size_t len)
{
/*
* Remembering from a previous life there was discussions on what is
* a good RSS hash key. See end of rss_init() in net/rss_config.c.
* iwlwifi is looking for a 10byte "secret" so stay with random for now.
*/
get_random_bytes(buf, len);
}
static inline int
netdev_hw_addr_list_count(struct netdev_hw_addr_list *list)
{
return (list->count);
}
static inline int
netdev_mc_count(struct net_device *ndev)
{
return (netdev_hw_addr_list_count(&ndev->mc));
}
#define netdev_hw_addr_list_for_each(_addr, _list) \
list_for_each_entry((_addr), &(_list)->addr_list, addr_list)
#define netdev_for_each_mc_addr(na, ndev) \
netdev_hw_addr_list_for_each(na, &(ndev)->mc)
static __inline void
synchronize_net(void)
{
/* We probably cannot do that unconditionally at some point anymore. */
synchronize_rcu();
}
static __inline void
netif_receive_skb_list(struct list_head *head)
{
pr_debug("%s: TODO\n", __func__);
}
static __inline int
napi_gro_receive(struct napi_struct *napi, struct sk_buff *skb)
{
pr_debug("%s: TODO\n", __func__);
return (-1);
}
static __inline void
ether_setup(struct net_device *ndev)
{
pr_debug("%s: TODO\n", __func__);
}
static __inline void
dev_net_set(struct net_device *dev, void *p)
{
pr_debug("%s: TODO\n", __func__);
}
/* -------------------------------------------------------------------------- */
static __inline bool
netif_carrier_ok(struct net_device *ndev)
{
pr_debug("%s: TODO\n", __func__);
return (false);
}
static __inline void
netif_carrier_off(struct net_device *ndev)
{
pr_debug("%s: TODO\n", __func__);
}
static __inline void
netif_carrier_on(struct net_device *ndev)
{
pr_debug("%s: TODO\n", __func__);
}
/* -------------------------------------------------------------------------- */
static __inline bool
netif_queue_stopped(struct net_device *ndev)
{
pr_debug("%s: TODO\n", __func__);
return (false);
}
static __inline void
netif_stop_queue(struct net_device *ndev)
{
pr_debug("%s: TODO\n", __func__);
}
static __inline void
netif_wake_queue(struct net_device *ndev)
{
pr_debug("%s: TODO\n", __func__);
}
/* -------------------------------------------------------------------------- */
static __inline int
register_netdevice(struct net_device *ndev)
{
/* assert rtnl_locked? */
pr_debug("%s: TODO\n", __func__);
return (0);
}
static __inline int
register_netdev(struct net_device *ndev)
{
int error;
/* lock */
error = register_netdevice(ndev);
/* unlock */
pr_debug("%s: TODO\n", __func__);
return (error);
}
static __inline void
unregister_netdev(struct net_device *ndev)
{
pr_debug("%s: TODO\n", __func__);
}
static __inline void
unregister_netdevice(struct net_device *ndev)
{
pr_debug("%s: TODO\n", __func__);
}
/* -------------------------------------------------------------------------- */
static __inline void
netif_rx(struct sk_buff *skb)
{
pr_debug("%s: TODO\n", __func__);
}
static __inline void
netif_rx_ni(struct sk_buff *skb)
{
pr_debug("%s: TODO\n", __func__);
}
/* -------------------------------------------------------------------------- */
struct net_device *linuxkpi_alloc_netdev(size_t, const char *, uint32_t,
void(*)(struct net_device *));
void linuxkpi_free_netdev(struct net_device *);
#define alloc_netdev(_l, _n, _f, _func) \
linuxkpi_alloc_netdev(_l, _n, _f, _func)
#define free_netdev(_n) \
linuxkpi_free_netdev(_n)
static inline void *
netdev_priv(const struct net_device *ndev)
{
return (__DECONST(void *, ndev->drv_priv));
}
/* -------------------------------------------------------------------------- */
/* This is really rtnetlink and probably belongs elsewhere. */
#define rtnl_lock() do { } while(0)
#define rtnl_unlock() do { } while(0)
#define rcu_dereference_rtnl(x) READ_ONCE(x)
#endif /* _LINUXKPI_LINUX_NETDEVICE_H */