#define LL_RESERVED_SPACE_EXTRA(dev,extra) \
((((dev)->hard_header_len+extra)&~(HH_DATA_MOD - 1)) + HH_DATA_MOD)
+struct header_ops {
+ int (*create) (struct sk_buff *skb, struct net_device *dev,
+ unsigned short type, const void *daddr,
+ const void *saddr, unsigned len);
+ int (*parse)(const struct sk_buff *skb, unsigned char *haddr);
+ int (*rebuild)(struct sk_buff *skb);
+#define HAVE_HEADER_CACHE
+ int (*cache)(const struct neighbour *neigh, struct hh_cache *hh);
+ void (*cache_update)(struct hh_cache *hh,
+ const struct net_device *dev,
+ const unsigned char *haddr);
+};
+
/* These flag bits are private to the generic network queueing
* layer, they may not be explicitly referenced by any other
* code.
__napi_schedule(n);
}
+/* Try to reschedule poll. Called by dev->poll() after napi_complete(). */
+static inline int napi_reschedule(struct napi_struct *napi)
+{
+ if (napi_schedule_prep(napi)) {
+ __napi_schedule(napi);
+ return 1;
+ }
+ return 0;
+}
+
/**
* napi_complete - NAPI processing complete
* @n: napi context
#define NETIF_F_HW_VLAN_FILTER 512 /* Receive filtering on VLAN */
#define NETIF_F_VLAN_CHALLENGED 1024 /* Device cannot handle VLAN packets */
#define NETIF_F_GSO 2048 /* Enable software GSO. */
-#define NETIF_F_LLTX 4096 /* LockLess TX */
+#define NETIF_F_LLTX 4096 /* LockLess TX - deprecated. Please */
+ /* do not use LLTX in new drivers */
#define NETIF_F_NETNS_LOCAL 8192 /* Does not change network namespaces */
#define NETIF_F_MULTI_QUEUE 16384 /* Has multiple TX/RX queues */
#define NETIF_F_LRO 32768 /* large receive offload */
#endif
const struct ethtool_ops *ethtool_ops;
+ /* Hardware header description */
+ const struct header_ops *header_ops;
+
/*
* This marks the end of the "visible" part of the structure. All
* fields hereafter are internal to the system, and may change at
int (*open)(struct net_device *dev);
int (*stop)(struct net_device *dev);
#define HAVE_NETDEV_POLL
- int (*hard_header) (struct sk_buff *skb,
- struct net_device *dev,
- unsigned short type,
- void *daddr,
- void *saddr,
- unsigned len);
- int (*rebuild_header)(struct sk_buff *skb);
#define HAVE_CHANGE_RX_FLAGS
void (*change_rx_flags)(struct net_device *dev,
int flags);
#define HAVE_SET_CONFIG
int (*set_config)(struct net_device *dev,
struct ifmap *map);
-#define HAVE_HEADER_CACHE
- int (*hard_header_cache)(struct neighbour *neigh,
- struct hh_cache *hh);
- void (*header_cache_update)(struct hh_cache *hh,
- struct net_device *dev,
- unsigned char * haddr);
#define HAVE_CHANGE_MTU
int (*change_mtu)(struct net_device *dev, int new_mtu);
void (*vlan_rx_kill_vid)(struct net_device *dev,
unsigned short vid);
- int (*hard_header_parse)(struct sk_buff *skb,
- unsigned char *haddr);
int (*neigh_setup)(struct net_device *dev, struct neigh_parms *);
#ifdef CONFIG_NETPOLL
struct netpoll_info *npinfo;
return dev->priv;
}
-#define SET_MODULE_OWNER(dev) do { } while (0)
/* Set the sysfs physical device reference for the network logical device
* if set prior to registration will cause a symlink during initialization.
*/
#include <linux/interrupt.h>
#include <linux/notifier.h>
-extern struct net_device loopback_dev; /* The loopback */
extern rwlock_t dev_base_lock; /* Device list lock */
extern void synchronize_net(void);
extern int register_netdevice_notifier(struct notifier_block *nb);
extern int unregister_netdevice_notifier(struct notifier_block *nb);
-extern int call_netdevice_notifiers(unsigned long val, void *v);
+extern int call_netdevice_notifiers(unsigned long val, struct net_device *dev);
extern struct net_device *dev_get_by_index(struct net *net, int ifindex);
extern struct net_device *__dev_get_by_index(struct net *net, int ifindex);
extern int dev_restart(struct net_device *dev);
extern int netpoll_trap(void);
#endif
+static inline int dev_hard_header(struct sk_buff *skb, struct net_device *dev,
+ unsigned short type,
+ const void *daddr, const void *saddr,
+ unsigned len)
+{
+ if (!dev->header_ops)
+ return 0;
+
+ return dev->header_ops->create(skb, dev, type, daddr, saddr, len);
+}
+
+static inline int dev_parse_header(const struct sk_buff *skb,
+ unsigned char *haddr)
+{
+ const struct net_device *dev = skb->dev;
+
+ if (!dev->header_ops->parse)
+ return 0;
+ return dev->header_ops->parse(skb, haddr);
+}
+
typedef int gifconf_func_t(struct net_device * dev, char __user * bufptr, int len);
extern int register_gifconf(unsigned int family, gifconf_func_t * gifconf);
static inline int unregister_gifconf(unsigned int family)
* dev_put - release reference to device
* @dev: network device
*
- * Hold reference to device to keep it from being freed.
+ * Release reference to device to allow it to be freed.
*/
static inline void dev_put(struct net_device *dev)
{
* dev_hold - get reference to device
* @dev: network device
*
- * Release reference to device to allow it to be freed.
+ * Hold reference to device to keep it from being freed.
*/
static inline void dev_hold(struct net_device *dev)
{
*
* Get network device transmit lock
*/
-static inline void netif_tx_lock(struct net_device *dev)
+static inline void __netif_tx_lock(struct net_device *dev, int cpu)
{
spin_lock(&dev->_xmit_lock);
- dev->xmit_lock_owner = smp_processor_id();
+ dev->xmit_lock_owner = cpu;
+}
+
+static inline void netif_tx_lock(struct net_device *dev)
+{
+ __netif_tx_lock(dev, smp_processor_id());
}
static inline void netif_tx_lock_bh(struct net_device *dev)
spin_unlock_bh(&dev->_xmit_lock);
}
+#define HARD_TX_LOCK(dev, cpu) { \
+ if ((dev->features & NETIF_F_LLTX) == 0) { \
+ __netif_tx_lock(dev, cpu); \
+ } \
+}
+
+#define HARD_TX_UNLOCK(dev) { \
+ if ((dev->features & NETIF_F_LLTX) == 0) { \
+ netif_tx_unlock(dev); \
+ } \
+}
+
static inline void netif_tx_disable(struct net_device *dev)
{
netif_tx_lock_bh(dev);