#ifdef __KERNEL__
#include <linux/timer.h>
#include <linux/delay.h>
+#include <linux/mm.h>
#include <asm/atomic.h>
#include <asm/cache.h>
#include <asm/byteorder.h>
* Compute the worst case header length according to the protocols
* used.
*/
-
+
#if defined(CONFIG_WLAN_80211) || defined(CONFIG_AX25) || defined(CONFIG_AX25_MODULE)
# if defined(CONFIG_MAC80211_MESH)
# define LL_MAX_HEADER 128
# else
# define LL_MAX_HEADER 96
# endif
-#elif defined(CONFIG_TR)
+#elif defined(CONFIG_TR) || defined(CONFIG_TR_MODULE)
# define LL_MAX_HEADER 48
#else
# define LL_MAX_HEADER 32
* Network device statistics. Akin to the 2.0 ether stats but
* with byte counters.
*/
-
+
struct net_device_stats
{
unsigned long rx_packets; /* total packets received */
/*
* This structure holds at boot time configured netdevice settings. They
- * are then used in the device probing.
+ * are then used in the device probing.
*/
struct netdev_boot_setup {
char name[IFNAMSIZ];
#ifdef CONFIG_NETPOLL
spinlock_t poll_lock;
int poll_owner;
+#endif
+
+ unsigned int gro_count;
+
struct net_device *dev;
struct list_head dev_list;
-#endif
+ struct sk_buff *gro_list;
+ struct sk_buff *skb;
};
enum
{
NAPI_STATE_SCHED, /* Poll is scheduled */
NAPI_STATE_DISABLE, /* Disable pending */
+ NAPI_STATE_NPSVC, /* Netpoll - don't dequeue from poll_list */
+};
+
+enum {
+ GRO_MERGED,
+ GRO_MERGED_FREE,
+ GRO_HELD,
+ GRO_NORMAL,
+ GRO_DROP,
};
extern void __napi_schedule(struct napi_struct *n);
*
* Mark NAPI processing as complete.
*/
-static inline void __napi_complete(struct napi_struct *n)
-{
- BUG_ON(!test_bit(NAPI_STATE_SCHED, &n->state));
- list_del(&n->poll_list);
- smp_mb__before_clear_bit();
- clear_bit(NAPI_STATE_SCHED, &n->state);
-}
-
-static inline void napi_complete(struct napi_struct *n)
-{
- unsigned long flags;
-
- local_irq_save(flags);
- __napi_complete(n);
- local_irq_restore(flags);
-}
+extern void __napi_complete(struct napi_struct *n);
+extern void napi_complete(struct napi_struct *n);
/**
* napi_disable - prevent NAPI from scheduling
* This function is called when network device transistions to the down
* state.
*
- * int (*ndo_hard_start_xmit)(struct sk_buff *skb, struct net_device *dev);
+ * int (*ndo_start_xmit)(struct sk_buff *skb, struct net_device *dev);
* Called when a packet needs to be transmitted.
* Must return NETDEV_TX_OK , NETDEV_TX_BUSY, or NETDEV_TX_LOCKED,
* Required can not be NULL.
*
* int (*ndo_set_mac_address)(struct net_device *dev, void *addr);
* This function is called when the Media Access Control address
- * needs to be changed. If not this interface is not defined, the
+ * needs to be changed. If this interface is not defined, the
* mac address can not be changed.
*
* int (*ndo_validate_addr)(struct net_device *dev);
#define HAVE_NETDEV_POLL
void (*ndo_poll_controller)(struct net_device *dev);
#endif
+#if defined(CONFIG_FCOE) || defined(CONFIG_FCOE_MODULE)
+ int (*ndo_fcoe_ddp_setup)(struct net_device *dev,
+ u16 xid,
+ struct scatterlist *sgl,
+ unsigned int sgc);
+ int (*ndo_fcoe_ddp_done)(struct net_device *dev,
+ u16 xid);
+#endif
};
/*
unsigned long state;
struct list_head dev_list;
-#ifdef CONFIG_NETPOLL
struct list_head napi_list;
-#endif
/* Net device features */
unsigned long features;
#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_GRO 16384 /* Generic receive offload */
#define NETIF_F_LRO 32768 /* large receive offload */
+#define NETIF_F_FCOE_CRC (1 << 24) /* FCoE CRC32 */
+
/* Segmentation offload features */
#define NETIF_F_GSO_SHIFT 16
-#define NETIF_F_GSO_MASK 0xffff0000
+#define NETIF_F_GSO_MASK 0x00ff0000
#define NETIF_F_TSO (SKB_GSO_TCPV4 << NETIF_F_GSO_SHIFT)
#define NETIF_F_UFO (SKB_GSO_UDP << NETIF_F_GSO_SHIFT)
#define NETIF_F_GSO_ROBUST (SKB_GSO_DODGY << NETIF_F_GSO_SHIFT)
#define NETIF_F_TSO_ECN (SKB_GSO_TCP_ECN << NETIF_F_GSO_SHIFT)
#define NETIF_F_TSO6 (SKB_GSO_TCPV6 << NETIF_F_GSO_SHIFT)
+#define NETIF_F_FSO (SKB_GSO_FCOE << NETIF_F_GSO_SHIFT)
/* List of features with software fallbacks. */
#define NETIF_F_GSO_SOFTWARE (NETIF_F_TSO | NETIF_F_TSO_ECN | NETIF_F_TSO6)
void *dsa_ptr; /* dsa specific data */
#endif
void *atalk_ptr; /* AppleTalk link */
- void *ip_ptr; /* IPv4 specific data */
+ void *ip_ptr; /* IPv4 specific data */
void *dn_ptr; /* DECnet specific data */
void *ip6_ptr; /* IPv6 specific data */
void *ec_ptr; /* Econet specific data */
*/
unsigned long last_rx; /* Time of last Rx */
/* Interface address info used in eth_type_trans() */
- unsigned char dev_addr[MAX_ADDR_LEN]; /* hw address, (before bcast
+ unsigned char dev_addr[MAX_ADDR_LEN]; /* hw address, (before bcast
because most packets are unicast) */
unsigned char broadcast[MAX_ADDR_LEN]; /* hw bcast add */
NETREG_UNREGISTERING, /* called unregister_netdevice */
NETREG_UNREGISTERED, /* completed unregister todo */
NETREG_RELEASED, /* called free_netdev */
+ NETREG_DUMMY, /* dummy device for NAPI poll */
} reg_state;
/* Called from unregister, can be used to call free_netdev */
struct dcbnl_rtnl_ops *dcbnl_ops;
#endif
+#if defined(CONFIG_FCOE) || defined(CONFIG_FCOE_MODULE)
+ /* max exchange id for FCoE LRO by ddp */
+ unsigned int fcoe_ddp_xid;
+#endif
+
#ifdef CONFIG_COMPAT_NET_DEV_OPS
struct {
int (*init)(struct net_device *dev);
* netif_napi_add() must be used to initialize a napi context prior to calling
* *any* of the other napi related functions.
*/
-static inline void netif_napi_add(struct net_device *dev,
- struct napi_struct *napi,
- int (*poll)(struct napi_struct *, int),
- int weight)
-{
- INIT_LIST_HEAD(&napi->poll_list);
- napi->poll = poll;
- napi->weight = weight;
-#ifdef CONFIG_NETPOLL
- napi->dev = dev;
- list_add(&napi->dev_list, &dev->napi_list);
- spin_lock_init(&napi->poll_lock);
- napi->poll_owner = -1;
-#endif
- set_bit(NAPI_STATE_SCHED, &napi->state);
-}
+void netif_napi_add(struct net_device *dev, struct napi_struct *napi,
+ int (*poll)(struct napi_struct *, int), int weight);
/**
* netif_napi_del - remove a napi context
*
* netif_napi_del() removes a napi context from the network device napi list
*/
-static inline void netif_napi_del(struct napi_struct *napi)
-{
-#ifdef CONFIG_NETPOLL
- list_del(&napi->dev_list);
-#endif
-}
+void netif_napi_del(struct napi_struct *napi);
+
+struct napi_gro_cb {
+ /* This indicates where we are processing relative to skb->data. */
+ int data_offset;
+
+ /* This is non-zero if the packet may be of the same flow. */
+ int same_flow;
+
+ /* This is non-zero if the packet cannot be merged with the new skb. */
+ int flush;
+
+ /* Number of segments aggregated. */
+ int count;
+
+ /* Free the skb? */
+ int free;
+};
+
+#define NAPI_GRO_CB(skb) ((struct napi_gro_cb *)(skb)->cb)
struct packet_type {
__be16 type; /* This is really htons(ether_type). */
struct sk_buff *(*gso_segment)(struct sk_buff *skb,
int features);
int (*gso_send_check)(struct sk_buff *skb);
+ struct sk_buff **(*gro_receive)(struct sk_buff **head,
+ struct sk_buff *skb);
+ int (*gro_complete)(struct sk_buff *skb);
void *af_packet_priv;
struct list_head list;
};
+struct napi_gro_fraginfo {
+ skb_frag_t frags[MAX_SKB_FRAGS];
+ unsigned int nr_frags;
+ unsigned int ip_summed;
+ unsigned int len;
+ __wsum csum;
+};
+
#include <linux/interrupt.h>
#include <linux/notifier.h>
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 init_dummy_netdev(struct net_device *dev);
+extern void netdev_resync_ops(struct net_device *dev);
+
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);
#ifdef CONFIG_NETPOLL_TRAP
extern int netpoll_trap(void);
#endif
+extern void *skb_gro_header(struct sk_buff *skb, unsigned int hlen);
+extern int skb_gro_receive(struct sk_buff **head,
+ struct sk_buff *skb);
+
+static inline unsigned int skb_gro_offset(const struct sk_buff *skb)
+{
+ return NAPI_GRO_CB(skb)->data_offset;
+}
+
+static inline unsigned int skb_gro_len(const struct sk_buff *skb)
+{
+ return skb->len - NAPI_GRO_CB(skb)->data_offset;
+}
+
+static inline void skb_gro_pull(struct sk_buff *skb, unsigned int len)
+{
+ NAPI_GRO_CB(skb)->data_offset += len;
+}
+
+static inline void skb_gro_reset_offset(struct sk_buff *skb)
+{
+ NAPI_GRO_CB(skb)->data_offset = 0;
+}
+
+static inline void *skb_gro_mac_header(struct sk_buff *skb)
+{
+ return skb_mac_header(skb) < skb->data ? skb_mac_header(skb) :
+ page_address(skb_shinfo(skb)->frags[0].page) +
+ skb_shinfo(skb)->frags[0].page_offset;
+}
static inline int dev_hard_header(struct sk_buff *skb, struct net_device *dev,
unsigned short type,
struct sk_buff *completion_queue;
struct napi_struct backlog;
-#ifdef CONFIG_NET_DMA
- struct dma_chan *net_dma;
-#endif
};
DECLARE_PER_CPU(struct softnet_data,softnet_data);
extern int netif_rx_ni(struct sk_buff *skb);
#define HAVE_NETIF_RECEIVE_SKB 1
extern int netif_receive_skb(struct sk_buff *skb);
+extern void napi_gro_flush(struct napi_struct *napi);
+extern int dev_gro_receive(struct napi_struct *napi,
+ struct sk_buff *skb);
+extern int napi_skb_finish(int ret, struct sk_buff *skb);
+extern int napi_gro_receive(struct napi_struct *napi,
+ struct sk_buff *skb);
+extern void napi_reuse_skb(struct napi_struct *napi,
+ struct sk_buff *skb);
+extern struct sk_buff * napi_fraginfo_skb(struct napi_struct *napi,
+ struct napi_gro_fraginfo *info);
+extern int napi_frags_finish(struct napi_struct *napi,
+ struct sk_buff *skb, int ret);
+extern int napi_gro_frags(struct napi_struct *napi,
+ struct napi_gro_fraginfo *info);
extern void netif_nit_deliver(struct sk_buff *skb);
extern int dev_valid_name(const char *name);
extern int dev_ioctl(struct net *net, unsigned int cmd, void __user *);
return (1 << debug_value) - 1;
}
-/* Test if receive needs to be scheduled but only if up */
-static inline int netif_rx_schedule_prep(struct net_device *dev,
- struct napi_struct *napi)
-{
- return napi_schedule_prep(napi);
-}
-
-/* Add interface to tail of rx poll list. This assumes that _prep has
- * already been called and returned 1.
- */
-static inline void __netif_rx_schedule(struct net_device *dev,
- struct napi_struct *napi)
-{
- __napi_schedule(napi);
-}
-
-/* Try to reschedule poll. Called by irq handler. */
-
-static inline void netif_rx_schedule(struct net_device *dev,
- struct napi_struct *napi)
-{
- if (netif_rx_schedule_prep(dev, napi))
- __netif_rx_schedule(dev, napi);
-}
-
-/* Try to reschedule poll. Called by dev->poll() after netif_rx_complete(). */
-static inline int netif_rx_reschedule(struct net_device *dev,
- struct napi_struct *napi)
-{
- if (napi_schedule_prep(napi)) {
- __netif_rx_schedule(dev, napi);
- return 1;
- }
- return 0;
-}
-
-/* same as netif_rx_complete, except that local_irq_save(flags)
- * has already been issued
- */
-static inline void __netif_rx_complete(struct net_device *dev,
- struct napi_struct *napi)
-{
- __napi_complete(napi);
-}
-
-/* Remove interface from poll list: it must be in the poll list
- * on current cpu. This primitive is called by dev->poll(), when
- * it completes the work. The device cannot be out of poll list at this
- * moment, it is BUG().
- */
-static inline void netif_rx_complete(struct net_device *dev,
- struct napi_struct *napi)
-{
- unsigned long flags;
-
- local_irq_save(flags);
- __netif_rx_complete(dev, napi);
- local_irq_restore(flags);
-}
-
static inline void __netif_tx_lock(struct netdev_queue *txq, int cpu)
{
spin_lock(&txq->_xmit_lock);
{
return skb_is_gso(skb) &&
(!skb_gso_ok(skb, dev->features) ||
+ (skb_shinfo(skb)->frag_list &&
+ !(dev->features & NETIF_F_FRAGLIST)) ||
unlikely(skb->ip_summed != CHECKSUM_PARTIAL));
}
if (dev->priv_flags & IFF_SLAVE_INACTIVE) {
if ((dev->priv_flags & IFF_SLAVE_NEEDARP) &&
- skb->protocol == __constant_htons(ETH_P_ARP))
+ skb->protocol == __cpu_to_be16(ETH_P_ARP))
return 0;
if (master->priv_flags & IFF_MASTER_ALB) {
return 0;
}
if (master->priv_flags & IFF_MASTER_8023AD &&
- skb->protocol == __constant_htons(ETH_P_SLOW))
+ skb->protocol == __cpu_to_be16(ETH_P_SLOW))
return 0;
return 1;