netdev: network device operations infrastructure
This patch changes the network device internal API to move adminstrative
operations out of the network device structure and into a separate structure.
This patch involves some hackery to maintain compatablity between the
new and old model, so all 300+ drivers don't have to be changed at once.
For drivers that aren't converted yet, the netdevice_ops virt function list
still resides in the net_device structure. For old protocols, the new
net_device_ops are copied out to the old net_device pointers.
After the transistion is completed the nag message can be changed to
an WARN_ON, and the compatiablity code can be made configurable.
Some function pointers aren't moved:
* destructor can't be in net_device_ops because
it may need to be referenced after the module is unloaded.
* neighbor setup is manipulated in a couple of places that need special
consideration
* hard_start_xmit is in the fast path for transmit.
Signed-off-by: Stephen Hemminger <shemminger@vyatta.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index 12d7f44..9060f5f 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -451,6 +451,131 @@
struct Qdisc *qdisc_sleeping;
} ____cacheline_aligned_in_smp;
+
+/*
+ * This structure defines the management hooks for network devices.
+ * The following hooks can bed defined and are optonal (can be null)
+ * unless otherwise noted.
+ *
+ * int (*ndo_init)(struct net_device *dev);
+ * This function is called once when network device is registered.
+ * The network device can use this to any late stage initializaton
+ * or semantic validattion. It can fail with an error code which will
+ * be propogated back to register_netdev
+ *
+ * void (*ndo_uninit)(struct net_device *dev);
+ * This function is called when device is unregistered or when registration
+ * fails. It is not called if init fails.
+ *
+ * int (*ndo_open)(struct net_device *dev);
+ * This function is called when network device transistions to the up
+ * state.
+ *
+ * int (*ndo_stop)(struct net_device *dev);
+ * This function is called when network device transistions to the down
+ * state.
+ *
+ * void (*ndo_change_rx_flags)(struct net_device *dev, int flags);
+ * This function is called to allow device receiver to make
+ * changes to configuration when multicast or promiscious is enabled.
+ *
+ * void (*ndo_set_rx_mode)(struct net_device *dev);
+ * This function is called device changes address list filtering.
+ *
+ * void (*ndo_set_multicast_list)(struct net_device *dev);
+ * This function is called when the multicast address list changes.
+ *
+ * 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
+ * mac address can not be changed.
+ *
+ * int (*ndo_validate_addr)(struct net_device *dev);
+ * Test if Media Access Control address is valid for the device.
+ *
+ * int (*ndo_do_ioctl)(struct net_device *dev, struct ifreq *ifr, int cmd);
+ * Called when a user request an ioctl which can't be handled by
+ * the generic interface code. If not defined ioctl's return
+ * not supported error code.
+ *
+ * int (*ndo_set_config)(struct net_device *dev, struct ifmap *map);
+ * Used to set network devices bus interface parameters. This interface
+ * is retained for legacy reason, new devices should use the bus
+ * interface (PCI) for low level management.
+ *
+ * int (*ndo_change_mtu)(struct net_device *dev, int new_mtu);
+ * Called when a user wants to change the Maximum Transfer Unit
+ * of a device. If not defined, any request to change MTU will
+ * will return an error.
+ *
+ * void (*ndo_tx_timeout) (struct net_device *dev);
+ * Callback uses when the transmitter has not made any progress
+ * for dev->watchdog ticks.
+ *
+ * struct net_device_stats* (*get_stats)(struct net_device *dev);
+ * Called when a user wants to get the network device usage
+ * statistics. If not defined, the counters in dev->stats will
+ * be used.
+ *
+ * void (*ndo_vlan_rx_register)(struct net_device *dev, struct vlan_group *grp);
+ * If device support VLAN receive accleration
+ * (ie. dev->features & NETIF_F_HW_VLAN_RX), then this function is called
+ * when vlan groups for the device changes. Note: grp is NULL
+ * if no vlan's groups are being used.
+ *
+ * void (*ndo_vlan_rx_add_vid)(struct net_device *dev, unsigned short vid);
+ * If device support VLAN filtering (dev->features & NETIF_F_HW_VLAN_FILTER)
+ * this function is called when a VLAN id is registered.
+ *
+ * void (*ndo_vlan_rx_kill_vid)(struct net_device *dev, unsigned short vid);
+ * If device support VLAN filtering (dev->features & NETIF_F_HW_VLAN_FILTER)
+ * this function is called when a VLAN id is unregistered.
+ *
+ * void (*ndo_poll_controller)(struct net_device *dev);
+ */
+struct net_device_ops {
+ int (*ndo_init)(struct net_device *dev);
+ void (*ndo_uninit)(struct net_device *dev);
+ int (*ndo_open)(struct net_device *dev);
+ int (*ndo_stop)(struct net_device *dev);
+#define HAVE_CHANGE_RX_FLAGS
+ void (*ndo_change_rx_flags)(struct net_device *dev,
+ int flags);
+#define HAVE_SET_RX_MODE
+ void (*ndo_set_rx_mode)(struct net_device *dev);
+#define HAVE_MULTICAST
+ void (*ndo_set_multicast_list)(struct net_device *dev);
+#define HAVE_SET_MAC_ADDR
+ int (*ndo_set_mac_address)(struct net_device *dev,
+ void *addr);
+#define HAVE_VALIDATE_ADDR
+ int (*ndo_validate_addr)(struct net_device *dev);
+#define HAVE_PRIVATE_IOCTL
+ int (*ndo_do_ioctl)(struct net_device *dev,
+ struct ifreq *ifr, int cmd);
+#define HAVE_SET_CONFIG
+ int (*ndo_set_config)(struct net_device *dev,
+ struct ifmap *map);
+#define HAVE_CHANGE_MTU
+ int (*ndo_change_mtu)(struct net_device *dev, int new_mtu);
+
+#define HAVE_TX_TIMEOUT
+ void (*ndo_tx_timeout) (struct net_device *dev);
+
+ struct net_device_stats* (*ndo_get_stats)(struct net_device *dev);
+
+ void (*ndo_vlan_rx_register)(struct net_device *dev,
+ struct vlan_group *grp);
+ void (*ndo_vlan_rx_add_vid)(struct net_device *dev,
+ unsigned short vid);
+ void (*ndo_vlan_rx_kill_vid)(struct net_device *dev,
+ unsigned short vid);
+#ifdef CONFIG_NET_POLL_CONTROLLER
+#define HAVE_NETDEV_POLL
+ void (*ndo_poll_controller)(struct net_device *dev);
+#endif
+};
+
/*
* The DEVICE structure.
* Actually, this whole structure is a big mistake. It mixes I/O
@@ -498,11 +623,6 @@
#ifdef CONFIG_NETPOLL
struct list_head napi_list;
#endif
-
- /* The device initialization function. Called only once. */
- int (*init)(struct net_device *dev);
-
- /* ------- Fields preinitialized in Space.c finish here ------- */
/* Net device features */
unsigned long features;
@@ -546,15 +666,13 @@
* for all in netdev_increment_features.
*/
#define NETIF_F_ONE_FOR_ALL (NETIF_F_GSO_SOFTWARE | NETIF_F_GSO_ROBUST | \
- NETIF_F_SG | NETIF_F_HIGHDMA | \
+ NETIF_F_SG | NETIF_F_HIGHDMA | \
NETIF_F_FRAGLIST)
/* Interface index. Unique device identifier */
int ifindex;
int iflink;
-
- struct net_device_stats* (*get_stats)(struct net_device *dev);
struct net_device_stats stats;
#ifdef CONFIG_WIRELESS_EXT
@@ -564,18 +682,13 @@
/* Instance data managed by the core of Wireless Extensions. */
struct iw_public_data * wireless_data;
#endif
+ /* Management operations */
+ const struct net_device_ops *netdev_ops;
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
- * will (read: may be cleaned up at will).
- */
-
-
unsigned int flags; /* interface flags (a la BSD) */
unsigned short gflags;
unsigned short priv_flags; /* Like 'flags' but invisible to userspace. */
@@ -634,7 +747,7 @@
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
- because most packets are unicast) */
+ because most packets are unicast) */
unsigned char broadcast[MAX_ADDR_LEN]; /* hw bcast add */
@@ -648,6 +761,10 @@
/* Number of TX queues currently active in device */
unsigned int real_num_tx_queues;
+ /* Map buffer to appropriate transmit queue */
+ u16 (*select_queue)(struct net_device *dev,
+ struct sk_buff *skb);
+
unsigned long tx_queue_len; /* Max frames per queue allowed */
spinlock_t tx_global_lock;
/*
@@ -662,9 +779,6 @@
int watchdog_timeo; /* used by dev_watchdog() */
struct timer_list watchdog_timer;
-/*
- * refcnt is a very hot point, so align it on SMP
- */
/* Number of references to this device */
atomic_t refcnt ____cacheline_aligned_in_smp;
@@ -683,56 +797,14 @@
NETREG_RELEASED, /* called free_netdev */
} reg_state;
- /* Called after device is detached from network. */
- void (*uninit)(struct net_device *dev);
- /* Called after last user reference disappears. */
- void (*destructor)(struct net_device *dev);
+ /* Called from unregister, can be used to call free_netdev */
+ void (*destructor)(struct net_device *dev);
- /* Pointers to interface service routines. */
- int (*open)(struct net_device *dev);
- int (*stop)(struct net_device *dev);
-#define HAVE_NETDEV_POLL
-#define HAVE_CHANGE_RX_FLAGS
- void (*change_rx_flags)(struct net_device *dev,
- int flags);
-#define HAVE_SET_RX_MODE
- void (*set_rx_mode)(struct net_device *dev);
-#define HAVE_MULTICAST
- void (*set_multicast_list)(struct net_device *dev);
-#define HAVE_SET_MAC_ADDR
- int (*set_mac_address)(struct net_device *dev,
- void *addr);
-#define HAVE_VALIDATE_ADDR
- int (*validate_addr)(struct net_device *dev);
-#define HAVE_PRIVATE_IOCTL
- int (*do_ioctl)(struct net_device *dev,
- struct ifreq *ifr, int cmd);
-#define HAVE_SET_CONFIG
- int (*set_config)(struct net_device *dev,
- struct ifmap *map);
-#define HAVE_CHANGE_MTU
- int (*change_mtu)(struct net_device *dev, int new_mtu);
+ int (*neigh_setup)(struct net_device *dev, struct neigh_parms *);
-#define HAVE_TX_TIMEOUT
- void (*tx_timeout) (struct net_device *dev);
-
- void (*vlan_rx_register)(struct net_device *dev,
- struct vlan_group *grp);
- void (*vlan_rx_add_vid)(struct net_device *dev,
- unsigned short vid);
- void (*vlan_rx_kill_vid)(struct net_device *dev,
- unsigned short vid);
-
- int (*neigh_setup)(struct net_device *dev, struct neigh_parms *);
#ifdef CONFIG_NETPOLL
struct netpoll_info *npinfo;
#endif
-#ifdef CONFIG_NET_POLL_CONTROLLER
- void (*poll_controller)(struct net_device *dev);
-#endif
-
- u16 (*select_queue)(struct net_device *dev,
- struct sk_buff *skb);
#ifdef CONFIG_NET_NS
/* Network namespace this network device is inside */
@@ -763,6 +835,38 @@
/* for setting kernel sock attribute on TCP connection setup */
#define GSO_MAX_SIZE 65536
unsigned int gso_max_size;
+
+#ifdef CONFIG_COMPAT_NET_DEV_OPS
+ struct {
+ int (*init)(struct net_device *dev);
+ void (*uninit)(struct net_device *dev);
+ int (*open)(struct net_device *dev);
+ int (*stop)(struct net_device *dev);
+ void (*change_rx_flags)(struct net_device *dev,
+ int flags);
+ void (*set_rx_mode)(struct net_device *dev);
+ void (*set_multicast_list)(struct net_device *dev);
+ int (*set_mac_address)(struct net_device *dev,
+ void *addr);
+ int (*validate_addr)(struct net_device *dev);
+ int (*do_ioctl)(struct net_device *dev,
+ struct ifreq *ifr, int cmd);
+ int (*set_config)(struct net_device *dev,
+ struct ifmap *map);
+ int (*change_mtu)(struct net_device *dev, int new_mtu);
+ void (*tx_timeout) (struct net_device *dev);
+ struct net_device_stats* (*get_stats)(struct net_device *dev);
+ void (*vlan_rx_register)(struct net_device *dev,
+ struct vlan_group *grp);
+ void (*vlan_rx_add_vid)(struct net_device *dev,
+ unsigned short vid);
+ void (*vlan_rx_kill_vid)(struct net_device *dev,
+ unsigned short vid);
+#ifdef CONFIG_NET_POLL_CONTROLLER
+ void (*poll_controller)(struct net_device *dev);
+#endif
+#endif
+ };
};
#define to_net_dev(d) container_of(d, struct net_device, dev)