#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;
#define MAX_ADDR_LEN 20
#define NET_NAME_UNKNOWN 0
enum net_addr_assign_type {
NET_ADDR_RANDOM,
};
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,
};
enum tc_setup_type {
TC_SETUP_MAX_DUMMY,
};
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 {
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_addr_assign_type addr_assign_type;
enum net_device_reg_state reg_state;
const struct ethtool_ops *ethtool_ops;
const struct net_device_ops *netdev_ops;
bool needs_free_netdev;
int flags, type;
int name_assign_type, needed_headroom;
int threaded;
void (*priv_destructor)(struct net_device *);
struct device dev;
struct mtx napi_mtx;
TAILQ_HEAD(, napi_struct) napi_head;
struct taskqueue *napi_tq;
uint8_t drv_priv[0] __aligned(CACHE_LINE_SIZE);
};
#define SET_NETDEV_DEV(_ndev, _dev) (_ndev)->dev.parent = _dev;
enum net_device_path_type {
DEV_PATH_MTK_WDMA,
};
struct net_device_path {
enum net_device_path_type type;
const struct net_device *dev;
union {
struct {
uint16_t wcid;
uint8_t wdma_idx;
uint8_t queue;
uint8_t bss;
uint8_t amsdu;
} mtk_wdma;
};
};
struct net_device_path_ctx {
const struct net_device *dev;
};
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
enum napi_state_bits {
NAPI_STATE_SCHED = 1,
LKPI_NAPI_FLAG_DISABLE_PENDING = 0,
LKPI_NAPI_FLAG_IS_SCHEDULED = 1,
LKPI_NAPI_FLAG_LOST_RACE_TRY_AGAIN = 2,
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;
volatile unsigned long state;
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 *);
bool 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 bool
napi_is_scheduled(struct napi_struct *napi)
{
return (test_bit(LKPI_NAPI_FLAG_IS_SCHEDULED, &napi->state));
}
static inline void
netdev_rss_key_fill(uint32_t *buf, size_t len)
{
get_random_bytes(buf, len);
}
static inline void
__hw_addr_init(struct netdev_hw_addr_list *list)
{
list->count = 0;
INIT_LIST_HEAD(&list->addr_list);
}
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)
{
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 *ndev, void *p)
{
pr_debug("%s: TODO\n", __func__);
}
static __inline int
dev_set_threaded(struct net_device *ndev, bool threaded)
{
pr_debug("%s: TODO\n", __func__);
return (-ENODEV);
}
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)
{
pr_debug("%s: TODO\n", __func__);
return (0);
}
static __inline int
register_netdev(struct net_device *ndev)
{
int error;
error = register_netdevice(ndev);
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 alloc_netdev_dummy(_l) \
linuxkpi_alloc_netdev(_l, "dummy", NET_NAME_UNKNOWN, NULL)
#define free_netdev(_n) \
linuxkpi_free_netdev(_n)
static inline void *
netdev_priv(const struct net_device *ndev)
{
return (__DECONST(void *, ndev->drv_priv));
}
static __inline void
netif_device_attach(struct net_device *ndev)
{
pr_debug("%s: TODO\n", __func__);
}
static __inline void
netif_device_detach(struct net_device *ndev)
{
pr_debug("%s: TODO\n", __func__);
}
#define rtnl_lock() do { } while(0)
#define rtnl_unlock() do { } while(0)
#define rcu_dereference_rtnl(x) READ_ONCE(x)
#endif