Skip to contentSkip to conversation

Network Devices Ops (v0.3)

PATCH Applied Stephen Hemminger 7 participants 93 messages Nov 17, 2008 – Nov 20, 2008

Subsystems (9)
lore
Share & tools
lore
#0 lore raw

cover Network Devices Ops (v0.3)

This sequence of patches breaks the network device adminstration function table away from the network device data structure. It is a transitional API change (both keep working), and this set of patches hits a range of commonly used drivers. This should be enough to make sure both old and new interfaces get used and tested.

#1 lore raw

PATCH 1/33 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.

---

---
 include/linux/netdevice.h |  232 +++++++++++++++++++++++++++++++++-------------
 net/Kconfig               |    3 
 net/core/dev.c            |  107 ++++++++++++++-------
 net/core/netpoll.c        |    7 -
 net/core/rtnetlink.c      |    9 -
 net/sched/sch_generic.c   |    4 
 6 files changed, 257 insertions(+), 105 deletions(-)
include/linux/netdevice.h +168 -64
@@ -451,6 +451,131 @@ struct netdev_queue {
 	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 (*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 (*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 (*open)(struct net_device *dev);
+ *     This function is called when network device transistions to the up
+ *     state.
+ *
+ * int (*stop)(struct net_device *dev);
+ *     This function is called when network device transistions to the down
+ *     state.
+ *
+ * void (*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 (*set_rx_mode)(struct net_device *dev);
+ *	This function is called device changes address list filtering.
+ *
+ * void (*set_multicast_list)(struct net_device *dev);
+ *	This function is called when the multicast address list changes.
+ *
+ * int (*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 (*validate_addr)(struct net_device *dev);
+ *	Test if Media Access Control address is valid for the device.
+ *
+ * int (*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 (*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 (*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 (*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 (*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 (*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 (*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 (*poll_controller)(struct net_device *dev);
+ */
+struct net_device_ops {
+	int			(*init)(struct net_device *dev);
+	void			(*uninit)(struct net_device *dev);
+	int			(*open)(struct net_device *dev);
+	int			(*stop)(struct net_device *dev);
+#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);
+
+#define HAVE_TX_TIMEOUT
+	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
+#define HAVE_NETDEV_POLL
+	void                    (*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 @@ struct net_device
 #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 @@ struct net_device
 	 * 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 @@ struct net_device
 	/* 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 @@ struct net_device
 	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 @@ struct net_device
 	/* 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 @@ struct net_device
 	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 @@ struct net_device
 	       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);
-
-	/* 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);
-
-#define HAVE_TX_TIMEOUT
-	void			(*tx_timeout) (struct net_device *dev);
+	/* Called from unregister, can be used to call free_netdev */
+	void (*destructor)(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 *);
 
-	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 @@ struct net_device
 	/* 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)
 
net/Kconfig +3 -0
@@ -32,6 +32,9 @@ config NET_NS
 	  Allow user space to create what appear to be multiple instances
 	  of the network stack.
 
+config COMPAT_NET_DEV_OPS
+       def_bool y
+
 source "net/packet/Kconfig"
 source "net/unix/Kconfig"
 source "net/xfrm/Kconfig"
net/core/dev.c +75 -32

245 lines not on this page · raw message

net/core/netpoll.c +4 -3
@@ -172,12 +172,13 @@ static void service_arp_queue(struct net
 void netpoll_poll(struct netpoll *np)
 {
 	struct net_device *dev = np->dev;
+	const struct net_device_ops *ops = dev->netdev_ops;
 
-	if (!dev || !netif_running(dev) || !dev->poll_controller)
+	if (!dev || !netif_running(dev) || !ops->poll_controller)
 		return;
 
 	/* Process pending work on NIC */
-	dev->poll_controller(dev);
+	ops->poll_controller(dev);
 
 	poll_napi(dev);
 
@@ -694,7 +695,7 @@ int netpoll_setup(struct netpoll *np)
 		atomic_inc(&npinfo->refcnt);
 	}
 
-	if (!ndev->poll_controller) {
+	if (!ndev->netdev_ops->poll_controller) {
 		printk(KERN_ERR "%s: %s doesn't support polling, aborting.\n",
 		       np->name, np->dev_name);
 		err = -ENOTSUPP;
net/sched/sch_generic.c +2 -2
@@ -224,7 +224,7 @@ static void dev_watchdog(unsigned long a
 				char drivername[64];
 				WARN_ONCE(1, KERN_INFO "NETDEV WATCHDOG: %s (%s): transmit timed out\n",
 				       dev->name, netdev_drivername(dev, drivername, 64));
-				dev->tx_timeout(dev);
+				dev->netdev_ops->tx_timeout(dev);
 			}
 			if (!mod_timer(&dev->watchdog_timer,
 				       round_jiffies(jiffies +
@@ -239,7 +239,7 @@ static void dev_watchdog(unsigned long a
 
 void __netdev_watchdog_up(struct net_device *dev)
 {
-	if (dev->tx_timeout) {
+	if (dev->netdev_ops->tx_timeout) {
 		if (dev->watchdog_timeo <= 0)
 			dev->watchdog_timeo = 5*HZ;
 		if (!mod_timer(&dev->watchdog_timer,
net/core/rtnetlink.c +5 -4
@@ -762,6 +762,7 @@ static int validate_linkmsg(struct net_d
 static int do_setlink(struct net_device *dev, struct ifinfomsg *ifm,
 		      struct nlattr **tb, char *ifname, int modified)
 {
+	const struct net_device_ops *ops = dev->netdev_ops;
 	int send_addr_notify = 0;
 	int err;
 
@@ -783,7 +784,7 @@ static int do_setlink(struct net_device 
 		struct rtnl_link_ifmap *u_map;
 		struct ifmap k_map;
 
-		if (!dev->set_config) {
+		if (!ops->set_config) {
 			err = -EOPNOTSUPP;
 			goto errout;
 		}
@@ -801,7 +802,7 @@ static int do_setlink(struct net_device 
 		k_map.dma = (unsigned char) u_map->dma;
 		k_map.port = (unsigned char) u_map->port;
 
-		err = dev->set_config(dev, &k_map);
+		err = ops->set_config(dev, &k_map);
 		if (err < 0)
 			goto errout;
 
@@ -812,7 +813,7 @@ static int do_setlink(struct net_device 
 		struct sockaddr *sa;
 		int len;
 
-		if (!dev->set_mac_address) {
+		if (!ops->set_mac_address) {
 			err = -EOPNOTSUPP;
 			goto errout;
 		}
@@ -831,7 +832,7 @@ static int do_setlink(struct net_device 
 		sa->sa_family = dev->type;
 		memcpy(sa->sa_data, nla_data(tb[IFLA_ADDRESS]),
 		       dev->addr_len);
-		err = dev->set_mac_address(dev, sa);
+		err = ops->set_mac_address(dev, sa);
 		kfree(sa);
 		if (err)
 			goto errout;
maintainer
#2 lore raw

Re: [PATCH 01/33] netdev: network device operations infrastructure

From: Stephen Hemminger <[email protected]>
Date: Mon, 17 Nov 2008 15:42:08 -0800

Quoted 12 lines

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.

Quoted 8 lines

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.

Ok, I'm applying this but it needs the following interdiff to cure some build failures.

And I'm also going to add the "ndo_*" prefix to the netdev_ops member names as suggested by Eric.

I'll fix up the remaining patches as needed, so don't worry about that.

maintainer
#3 lore raw

Re: [PATCH 01/33] netdev: network device operations infrastructure

From: David Miller <[email protected]>
Date: Wed, 19 Nov 2008 21:26:50 -0800 (PST)

Quoted 2 lines

Ok, I'm applying this but it needs the following interdiff to cure some build failures.

Durrr! And here is that interdiff!

core/dev.c renamed from core/dev.c~ +2 -0
@@ -4037,7 +4037,9 @@ int register_netdevice(struct net_device
 		dev->vlan_rx_register = ops->vlan_rx_register;
 		dev->vlan_rx_add_vid = ops->vlan_rx_add_vid;
 		dev->vlan_rx_kill_vid = ops->vlan_rx_kill_vid;
+#ifdef CONFIG_NET_POLL_CONTROLLER
 		dev->poll_controller = ops->poll_controller;
+#endif
 	} else {
 		char drivername[64];
 		pr_info("%s (%s): not using net_device_ops yet\n",
#4 lore raw

PATCH 2/33 netdev: introduce dev_get_stats()

In reply to Stephen Hemminger

In order for the network device ops get_stats call to be immutable, the handling of the default internal network device stats block has to be changed. Add a new helper function which replaces the old use of internal_get_stats.

Note: change return code to make it clear that the caller should not go changing the returned statistics.

---
 arch/s390/appldata/appldata_net_sum.c |    4 ++--
 drivers/net/bonding/bond_main.c       |    5 +++--
 drivers/net/sfc/ethtool.c             |    2 +-
 drivers/parisc/led.c                  |    4 ++--
 include/linux/netdevice.h             |    4 +++-
 net/core/dev.c                        |   23 ++++++++++++++++++-----
 net/core/net-sysfs.c                  |    3 +--
 net/core/rtnetlink.c                  |    6 +++---
 8 files changed, 33 insertions(+), 18 deletions(-)
arch/s390/appldata/appldata_net_sum.c +2 -2
@@ -67,7 +67,6 @@ static void appldata_get_net_sum_data(vo
 	int i;
 	struct appldata_net_sum_data *net_data;
 	struct net_device *dev;
-	struct net_device_stats *stats;
 	unsigned long rx_packets, tx_packets, rx_bytes, tx_bytes, rx_errors,
 			tx_errors, rx_dropped, tx_dropped, collisions;
 
@@ -86,7 +85,8 @@ static void appldata_get_net_sum_data(vo
 	collisions = 0;
 	read_lock(&dev_base_lock);
 	for_each_netdev(&init_net, dev) {
-		stats = dev->get_stats(dev);
+		const struct net_device_stats *stats = dev_get_stats(dev);
+
 		rx_packets += stats->rx_packets;
 		tx_packets += stats->tx_packets;
 		rx_bytes   += stats->rx_bytes;
drivers/net/bonding/bond_main.c +3 -2
@@ -3899,7 +3899,7 @@ static int bond_close(struct net_device 
 static struct net_device_stats *bond_get_stats(struct net_device *bond_dev)
 {
 	struct bonding *bond = netdev_priv(bond_dev);
-	struct net_device_stats *stats = &(bond->stats), *sstats;
+	struct net_device_stats *stats = &bond->stats;
 	struct net_device_stats local_stats;
 	struct slave *slave;
 	int i;
@@ -3909,7 +3909,8 @@ static struct net_device_stats *bond_get
 	read_lock_bh(&bond->lock);
 
 	bond_for_each_slave(bond, slave, i) {
-		sstats = slave->dev->get_stats(slave->dev);
+		const struct net_device_stats *sstats = dev_get_stats(slave->dev);
+
 		local_stats.rx_packets += sstats->rx_packets;
 		local_stats.rx_bytes += sstats->rx_bytes;
 		local_stats.rx_errors += sstats->rx_errors;
drivers/net/sfc/ethtool.c +1 -1
@@ -426,7 +426,7 @@ static void efx_ethtool_get_stats(struct
 	EFX_BUG_ON_PARANOID(stats->n_stats != EFX_ETHTOOL_NUM_STATS);
 
 	/* Update MAC and NIC statistics */
-	net_dev->get_stats(net_dev);
+	dev_get_stats(net_dev);
 
 	/* Fill detailed statistics buffer */
 	for (i = 0; i < EFX_ETHTOOL_NUM_STATS; i++) {
drivers/parisc/led.c +2 -2
@@ -360,13 +360,13 @@ static __inline__ int led_get_net_activi
 	read_lock(&dev_base_lock);
 	rcu_read_lock();
 	for_each_netdev(&init_net, dev) {
-	    struct net_device_stats *stats;
+	    const struct net_device_stats *stats;
 	    struct in_device *in_dev = __in_dev_get_rcu(dev);
 	    if (!in_dev || !in_dev->ifa_list)
 		continue;
 	    if (ipv4_is_loopback(in_dev->ifa_list->ifa_local))
 		continue;
-	    stats = dev->get_stats(dev);
+	    stats = dev_get_stats(dev);
 	    rx_total += stats->rx_packets;
 	    tx_total += stats->tx_packets;
 	}
include/linux/netdevice.h +3 -1
@@ -865,8 +865,8 @@ struct net_device
 #ifdef CONFIG_NET_POLL_CONTROLLER
 		void                    (*poll_controller)(struct net_device *dev);
 #endif
-#endif
 	};
+#endif
 };
 #define to_net_dev(d) container_of(d, struct net_device, dev)
 
@@ -1780,6 +1780,8 @@ extern void		netdev_features_change(stru
 /* Load a device via the kmod */
 extern void		dev_load(struct net *net, const char *name);
 extern void		dev_mcast_init(void);
+extern const struct net_device_stats *dev_get_stats(struct net_device *dev);
+
 extern int		netdev_max_backlog;
 extern int		weight_p;
 extern int		netdev_set_master(struct net_device *dev, struct net_device *master);
net/core/dev.c +18 -5
@@ -2620,7 +2620,7 @@ void dev_seq_stop(struct seq_file *seq, 
 
 static void dev_seq_printf_stats(struct seq_file *seq, struct net_device *dev)
 {
-	struct net_device_stats *stats = dev->get_stats(dev);
+	const struct net_device_stats *stats = dev_get_stats(dev);
 
 	seq_printf(seq, "%6s:%8lu %7lu %4lu %4lu %4lu %5lu %10lu %9lu "
 		   "%8lu %7lu %4lu %4lu %4lu %5lu %7lu %10lu\n",
@@ -4286,10 +4286,24 @@ void netdev_run_todo(void)
 	}
 }
 
-static struct net_device_stats *internal_stats(struct net_device *dev)
-{
-	return &dev->stats;
+/**
+ *	dev_get_stats	- get network device statistics
+ *	@dev: device to get statistics from
+ *
+ *	Get network statistics from device. The device driver may provide
+ *	its own method by setting dev->netdev_ops->get_stats; otherwise
+ *	the internal statistics structure is used.
+ */
+const struct net_device_stats *dev_get_stats(struct net_device *dev)
+ {
+	const struct net_device_ops *ops = dev->netdev_ops;
+
+	if (ops->get_stats)
+		return ops->get_stats(dev);
+	else
+		return &dev->stats;
 }
+EXPORT_SYMBOL(dev_get_stats);
 
 static void netdev_init_one_queue(struct net_device *dev,
 				  struct netdev_queue *queue,
@@ -4368,7 +4382,6 @@ struct net_device *alloc_netdev_mq(int s
 
 	netdev_init_queues(dev);
 
-	dev->get_stats = internal_stats;
 	netpoll_netdev_init(dev);
 	setup(dev);
 	strcpy(dev->name, name);
net/core/net-sysfs.c +1 -2
@@ -270,7 +270,6 @@ static ssize_t netstat_show(const struct
 			    unsigned long offset)
 {
 	struct net_device *dev = to_net_dev(d);
-	struct net_device_stats *stats;
 	ssize_t ret = -EINVAL;
 
 	WARN_ON(offset > sizeof(struct net_device_stats) ||
@@ -278,7 +277,7 @@ static ssize_t netstat_show(const struct
 
 	read_lock(&dev_base_lock);
 	if (dev_isalive(dev)) {
-		stats = dev->get_stats(dev);
+		const struct net_device_stats *stats = dev_get_stats(dev);
 		ret = sprintf(buf, fmt_ulong,
 			      *(unsigned long *)(((u8 *) stats) + offset));
 	}
net/core/rtnetlink.c +3 -3
@@ -551,7 +551,7 @@ static void set_operstate(struct net_dev
 }
 
 static void copy_rtnl_link_stats(struct rtnl_link_stats *a,
-				 struct net_device_stats *b)
+				 const struct net_device_stats *b)
 {
 	a->rx_packets = b->rx_packets;
 	a->tx_packets = b->tx_packets;
@@ -609,7 +609,7 @@ static int rtnl_fill_ifinfo(struct sk_bu
 	struct netdev_queue *txq;
 	struct ifinfomsg *ifm;
 	struct nlmsghdr *nlh;
-	struct net_device_stats *stats;
+	const struct net_device_stats *stats;
 	struct nlattr *attr;
 
 	nlh = nlmsg_put(skb, pid, seq, type, sizeof(*ifm), flags);
@@ -666,7 +666,7 @@ static int rtnl_fill_ifinfo(struct sk_bu
 	if (attr == NULL)
 		goto nla_put_failure;
 
-	stats = dev->get_stats(dev);
+	stats = dev_get_stats(dev);
 	copy_rtnl_link_stats(nla_data(attr), stats);
 
 	if (dev->rtnl_link_ops) {
maintainer Applied
#5 lore raw

Re: [PATCH 02/33] netdev: introduce dev_get_stats()

From: Stephen Hemminger <[email protected]>
Date: Mon, 17 Nov 2008 15:42:09 -0800

Quoted 8 lines

In order for the network device ops get_stats call to be immutable, the handling of the default internal network device stats block has to be changed. Add a new helper function which replaces the old use of internal_get_stats.

Note: change return code to make it clear that the caller should not go changing the returned statistics.

Applied.

#6 lore raw

Re: [PATCH 02/33] netdev: introduce dev_get_stats()

Quoted 7 lines · David Miller

From: Stephen Hemminger <[email protected]>
Date: Mon, 17 Nov 2008 15:42:09 -0800

Quoted 4 lines

In order for the network device ops get_stats call to be immutable, the handling of the default internal network device stats block has to be changed. Add a new helper function which replaces the old use of internal_get_stats.

Quoted 6 lines
Quoted 4 lines

Note: change return code to make it clear that the caller should not go changing the returned statistics.

Applied.

I have one comment about netdev stats

on 32bit arches, SMP :

struct net_device = 0x480
offsetof(struct net_device, features)=0x44 offsetof(struct net_device, stats)=0x50 offsetof(struct net_device, stats.rx_packets)=0x50

So we trash features field, thats a problem...

I wonder if we could zap stats from netdev structure. Some drivers already use external stats handling (like loopback)

get_dev_stats() would accept a second parameter : a pointer to a struct net_device_stats provided by the reader, that the driver could use as a working zone, or not.

static struct net_device_stats *bond_get_stats(struct net_device *bond_dev,
struct net_device_stats *temp)

{
       struct bonding *bond = netdev_priv(bond_dev);
       struct net_device_stats wrk;
       struct slave *slave;
       int i;

	/* use the caller provided zone */
       memset(temp, 0, sizeof(struct net_device_stats));

       read_lock_bh(&bond->lock);

       bond_for_each_slave(bond, slave, i) {
               const struct net_device_stats *sstats = dev_get_stats(slave->dev, &wrk);

               temp->rx_packets += sstats->rx_packets;
               temp->rx_bytes += sstats->rx_bytes;
               temp->rx_errors += sstats->rx_errors;
		...
	}


       read_unlock_bh(&bond->lock);

       return temp;
}

....

static struct net_device_stats *loopback_get_stats(struct net_device *dev,
struct net_device_stats *temp)

{
       const struct pcpu_lstats *pcpu_lstats;
       unsigned long bytes = 0;
       unsigned long packets = 0;
       int i;

	memset(temp, 0, sizeof(*temp);
       pcpu_lstats = dev->ml_priv;
       for_each_possible_cpu(i) {
               const struct pcpu_lstats *lb_stats;

               lb_stats = per_cpu_ptr(pcpu_lstats, i);
               bytes   += lb_stats->bytes;
               packets += lb_stats->packets;
       }
       temp->rx_packets = packets;
       temp->tx_packets = packets;
       temp->rx_bytes = bytes;
       temp->tx_bytes = bytes;
       return temp;
}

...

maintainer
#7 lore raw

Re: [PATCH 02/33] netdev: introduce dev_get_stats()

From: Eric Dumazet <[email protected]>
Date: Thu, 20 Nov 2008 10:17:02 +0100

Quoted 9 lines

I have one comment about netdev stats

on 32bit arches, SMP :

struct net_device = 0x480
offsetof(struct net_device, features)=0x44 offsetof(struct net_device, stats)=0x50 offsetof(struct net_device, stats.rx_packets)=0x50

Quoted 4 lines

So we trash features field, thats a problem...

I wonder if we could zap stats from netdev structure. Some drivers already use external stats handling (like loopback)

Some... but most just want a single stats structure, and that's what this is for.

Let's just put the appropriate alignment tags in struct net_device after all of this dust settles, ok?

#8 lore raw

PATCH 3/33 netdev: expose ethernet address primitives

In reply to Stephen Hemminger

When ethernet devices are converted, the function pointer setup by eth_setup() need to be done during intialization.

---
 include/linux/etherdevice.h |    4 ++++
 net/ethernet/eth.c          |   13 ++++++++-----
 2 files changed, 12 insertions(+), 5 deletions(-)
include/linux/etherdevice.h +4 -0
@@ -41,6 +41,10 @@ extern int eth_header_cache(const struct
 extern void eth_header_cache_update(struct hh_cache *hh,
 				    const struct net_device *dev,
 				    const unsigned char *haddr);
+extern int eth_mac_addr(struct net_device *dev, void *p);
+extern int eth_change_mtu(struct net_device *dev, int new_mtu);
+extern int eth_validate_addr(struct net_device *dev);
+
 
 
 extern struct net_device *alloc_etherdev_mq(int sizeof_priv, unsigned int queue_count);
net/ethernet/eth.c +8 -5
@@ -282,7 +282,7 @@ EXPORT_SYMBOL(eth_header_cache_update);
  * This doesn't change hardware matching, so needs to be overridden
  * for most real devices.
  */
-static int eth_mac_addr(struct net_device *dev, void *p)
+int eth_mac_addr(struct net_device *dev, void *p)
 {
 	struct sockaddr *addr = p;
 
@@ -293,6 +293,7 @@ static int eth_mac_addr(struct net_devic
 	memcpy(dev->dev_addr, addr->sa_data, ETH_ALEN);
 	return 0;
 }
+EXPORT_SYMBOL(eth_mac_addr);
 
 /**
  * eth_change_mtu - set new MTU size
@@ -302,21 +303,23 @@ static int eth_mac_addr(struct net_devic
  * Allow changing MTU size. Needs to be overridden for devices
  * supporting jumbo frames.
  */
-static int eth_change_mtu(struct net_device *dev, int new_mtu)
+int eth_change_mtu(struct net_device *dev, int new_mtu)
 {
 	if (new_mtu < 68 || new_mtu > ETH_DATA_LEN)
 		return -EINVAL;
 	dev->mtu = new_mtu;
 	return 0;
 }
+EXPORT_SYMBOL(eth_change_mtu);
 
-static int eth_validate_addr(struct net_device *dev)
+int eth_validate_addr(struct net_device *dev)
 {
 	if (!is_valid_ether_addr(dev->dev_addr))
 		return -EADDRNOTAVAIL;
 
 	return 0;
 }
+EXPORT_SYMBOL(eth_validate_addr);
 
 const struct header_ops eth_header_ops ____cacheline_aligned = {
 	.create		= eth_header,
@@ -334,11 +337,11 @@ const struct header_ops eth_header_ops _
 void ether_setup(struct net_device *dev)
 {
 	dev->header_ops		= &eth_header_ops;
-
+#ifdef CONFIG_COMPAT_NET_DEV_OPS
 	dev->change_mtu		= eth_change_mtu;
 	dev->set_mac_address 	= eth_mac_addr;
 	dev->validate_addr	= eth_validate_addr;
-
+#endif
 	dev->type		= ARPHRD_ETHER;
 	dev->hard_header_len 	= ETH_HLEN;
 	dev->mtu		= ETH_DATA_LEN;
maintainer Applied
#9 lore raw

Re: [PATCH 03/33] netdev: expose ethernet address primitives

From: Stephen Hemminger <[email protected]>
Date: Mon, 17 Nov 2008 15:42:10 -0800

Quoted 4 lines

When ethernet devices are converted, the function pointer setup by eth_setup() need to be done during intialization.

Applied.

maintainer
#10 lore raw

Re: [PATCH 03/33] netdev: expose ethernet address primitives

From: David Miller <[email protected]>
Date: Wed, 19 Nov 2008 21:45:25 -0800 (PST)

Quoted 9 lines

From: Stephen Hemminger <[email protected]>
Date: Mon, 17 Nov 2008 15:42:10 -0800

Quoted 4 lines

When ethernet devices are converted, the function pointer setup by eth_setup() need to be done during intialization.

Applied.

Ok, I have to make a slight modification to this change.

Build testing showed that drivers/usb/gadget/u_ether.c has static functions with the same name, in particular eth_change_mtu().

I'll rename the function in the usb driver and respin everything before pushing out.

#11 lore raw

PATCH 4/33 netdev: convert loopback to net_device_ops

In reply to Stephen Hemminger

First device to convert over is the loopback device.

drivers/net/loopback.c +8 -4
@@ -87,7 +87,7 @@ static int loopback_xmit(struct sk_buff 
 	return 0;
 }
 
-static struct net_device_stats *get_stats(struct net_device *dev)
+static struct net_device_stats *loopback_get_stats(struct net_device *dev)
 {
 	const struct pcpu_lstats *pcpu_lstats;
 	struct net_device_stats *stats = &dev->stats;
@@ -143,13 +143,17 @@ static void loopback_dev_free(struct net
 	free_netdev(dev);
 }
 
+static const struct net_device_ops loopback_ops = {
+	.init      = loopback_dev_init,
+	.get_stats = loopback_get_stats,
+};
+
 /*
  * The loopback device is special. There is only one instance
  * per network namespace.
  */
 static void loopback_setup(struct net_device *dev)
 {
-	dev->get_stats		= &get_stats;
 	dev->mtu		= (16 * 1024) + 20 + 20 + 12;
 	dev->hard_start_xmit	= loopback_xmit;
 	dev->hard_header_len	= ETH_HLEN;	/* 14	*/
@@ -165,8 +169,8 @@ static void loopback_setup(struct net_de
 		| NETIF_F_NETNS_LOCAL;
 	dev->ethtool_ops	= &loopback_ethtool_ops;
 	dev->header_ops		= &eth_header_ops;
-	dev->init = loopback_dev_init;
-	dev->destructor = loopback_dev_free;
+	dev->netdev_ops		= &loopback_ops;
+	dev->destructor		= loopback_dev_free;
 }
 
 /* Setup and register the loopback device. */
#13 lore raw

PATCH 5/33 ifb: convert to net_device_ops

In reply to Stephen Hemminger

Convert to new network device ops interface.

drivers/net/ifb.c +8 -3
@@ -137,18 +137,23 @@ resched:
 
 }
 
+static const struct net_device_ops ifb_netdev_ops = {
+	.validate_addr = eth_validate_addr,
+	.open	= ifb_open,
+	.stop	= ifb_close,
+};
+
 static void ifb_setup(struct net_device *dev)
 {
 	/* Initialize the device structure. */
 	dev->hard_start_xmit = ifb_xmit;
-	dev->open = &ifb_open;
-	dev->stop = &ifb_close;
 	dev->destructor = free_netdev;
+	dev->netdev_ops = &ifb_netdev_ops;
 
 	/* Fill in device structure with ethernet-generic values. */
 	ether_setup(dev);
 	dev->tx_queue_len = TX_Q_LIMIT;
-	dev->change_mtu = NULL;
+
 	dev->flags |= IFF_NOARP;
 	dev->flags &= ~IFF_MULTICAST;
 	random_ether_addr(dev->dev_addr);
#15 lore raw

PATCH 6/33 dummy: convert to net_device_ops

In reply to Stephen Hemminger

Convert to new network device ops interface.

drivers/net/dummy.c +9 -4
@@ -57,18 +57,23 @@ static void set_multicast_list(struct ne
 {
 }
 
+static const struct net_device_ops dummy_netdev_ops = {
+	.validate_addr = eth_validate_addr,
+	.set_multicast_list = set_multicast_list,
+	.set_mac_address = dummy_set_address,
+};
+
 static void dummy_setup(struct net_device *dev)
 {
+	ether_setup(dev);
+
 	/* Initialize the device structure. */
+	dev->netdev_ops = &dummy_netdev_ops;
 	dev->hard_start_xmit = dummy_xmit;
-	dev->set_multicast_list = set_multicast_list;
-	dev->set_mac_address = dummy_set_address;
 	dev->destructor = free_netdev;
 
 	/* Fill in device structure with ethernet-generic values. */
-	ether_setup(dev);
 	dev->tx_queue_len = 0;
-	dev->change_mtu = NULL;
 	dev->flags |= IFF_NOARP;
 	dev->flags &= ~IFF_MULTICAST;
 	random_ether_addr(dev->dev_addr);
#17 lore raw

PATCH 7/33 bridge: convert to net_device_ops

In reply to Stephen Hemminger

Convert to net_device_ops function table.

net/bridge/br_device.c +11 -7
@@ -147,7 +147,7 @@ static int br_set_tx_csum(struct net_dev
 	return 0;
 }
 
-static struct ethtool_ops br_ethtool_ops = {
+static const struct ethtool_ops br_ethtool_ops = {
 	.get_drvinfo    = br_getinfo,
 	.get_link	= ethtool_op_get_link,
 	.get_tx_csum	= ethtool_op_get_tx_csum,
@@ -160,21 +160,25 @@ static struct ethtool_ops br_ethtool_ops
 	.get_flags	= ethtool_op_get_flags,
 };
 
+static const struct net_device_ops br_netdev_ops = {
+	.open		 = br_dev_open,
+	.stop		 = br_dev_stop,
+	.set_mac_address = br_set_mac_address,
+	.set_multicast_list = br_dev_set_multicast_list,
+	.change_mtu	 = br_change_mtu,
+	.do_ioctl	= br_dev_ioctl,
+};
+
 void br_dev_setup(struct net_device *dev)
 {
 	random_ether_addr(dev->dev_addr);
 	ether_setup(dev);
 
-	dev->do_ioctl = br_dev_ioctl;
+	dev->netdev_ops = &br_netdev_ops;
 	dev->hard_start_xmit = br_dev_xmit;
-	dev->open = br_dev_open;
-	dev->set_multicast_list = br_dev_set_multicast_list;
-	dev->change_mtu = br_change_mtu;
 	dev->destructor = free_netdev;
 	SET_ETHTOOL_OPS(dev, &br_ethtool_ops);
-	dev->stop = br_dev_stop;
 	dev->tx_queue_len = 0;
-	dev->set_mac_address = br_set_mac_address;
 	dev->priv_flags = IFF_EBRIDGE;
 
 	dev->features = NETIF_F_SG | NETIF_F_FRAGLIST | NETIF_F_HIGHDMA |
#19 lore raw

PATCH 8/33 veth: convert to net_device_ops

In reply to Stephen Hemminger

Convert to net_device_ops function tabl.e

drivers/net/veth.c +8 -4
@@ -262,16 +262,20 @@ static void veth_dev_free(struct net_dev
 	free_netdev(dev);
 }
 
+static const struct net_device_ops veth_netdev_ops = {
+	.init	   = veth_dev_init,
+	.open	   = veth_open,
+	.get_stats = veth_get_stats,
+};
+
 static void veth_setup(struct net_device *dev)
 {
 	ether_setup(dev);
 
+	dev->netdev_ops = &veth_netdev_ops;
 	dev->hard_start_xmit = veth_xmit;
-	dev->get_stats = veth_get_stats;
-	dev->open = veth_open;
 	dev->ethtool_ops = &veth_ethtool_ops;
 	dev->features |= NETIF_F_LLTX;
-	dev->init = veth_dev_init;
 	dev->destructor = veth_dev_free;
 }
 
@@ -297,7 +301,7 @@ static int veth_device_event(struct noti
 {
 	struct net_device *dev = ptr;
 
-	if (dev->open != veth_open)
+	if (dev->netdev_ops->open != veth_open)
 		goto out;
 
 	switch (event) {
#21 lore raw

PATCH 9/33 macvlan: convert to net_device_ops

In reply to Stephen Hemminger

Convert to net_device_ops function table.

drivers/net/macvlan.c +12 -7
@@ -361,17 +361,22 @@ static const struct ethtool_ops macvlan_
 	.get_flags		= macvlan_ethtool_get_flags,
 };
 
+static const struct net_device_ops macvlan_netdev_ops = {
+	.init		= macvlan_init,
+	.open		= macvlan_open,
+	.stop		= macvlan_stop,
+	.change_mtu	= macvlan_change_mtu,
+	.change_rx_flags= macvlan_change_rx_flags,
+	.set_mac_address= macvlan_set_mac_address,
+	.set_multicast_list= macvlan_set_multicast_list,
+	.validate_addr = eth_validate_addr,
+};
+
 static void macvlan_setup(struct net_device *dev)
 {
 	ether_setup(dev);
 
-	dev->init		= macvlan_init;
-	dev->open		= macvlan_open;
-	dev->stop		= macvlan_stop;
-	dev->change_mtu		= macvlan_change_mtu;
-	dev->change_rx_flags	= macvlan_change_rx_flags;
-	dev->set_mac_address	= macvlan_set_mac_address;
-	dev->set_multicast_list	= macvlan_set_multicast_list;
+	dev->netdev_ops		= &macvlan_netdev_ops;
 	dev->hard_start_xmit	= macvlan_hard_start_xmit;
 	dev->destructor		= free_netdev;
 	dev->header_ops		= &macvlan_hard_header_ops,
#23 lore raw

PATCH 10/33 ip: convert to net_device_ops for ioctl

In reply to Stephen Hemminger

Convert to net_device_ops function table pointer for ioctl.

net/ipv4/ipmr.c +17 -8
@@ -124,8 +124,8 @@ static void ipmr_del_tunnel(struct net_d
 
 	dev = __dev_get_by_name(&init_net, "tunl0");
 	if (dev) {
+		const struct net_device_ops *ops = dev->netdev_ops;
 		struct ifreq ifr;
-		mm_segment_t	oldfs;
 		struct ip_tunnel_parm p;
 
 		memset(&p, 0, sizeof(p));
@@ -137,9 +137,13 @@ static void ipmr_del_tunnel(struct net_d
 		sprintf(p.name, "dvmrp%d", v->vifc_vifi);
 		ifr.ifr_ifru.ifru_data = (__force void __user *)&p;
 
-		oldfs = get_fs(); set_fs(KERNEL_DS);
-		dev->do_ioctl(dev, &ifr, SIOCDELTUNNEL);
-		set_fs(oldfs);
+		if (ops->do_ioctl) {
+			mm_segment_t oldfs = get_fs();
+
+			set_fs(KERNEL_DS);
+			ops->do_ioctl(dev, &ifr, SIOCDELTUNNEL);
+			set_fs(oldfs);
+		}
 	}
 }
 
@@ -151,9 +155,9 @@ struct net_device *ipmr_new_tunnel(struc
 	dev = __dev_get_by_name(&init_net, "tunl0");
 
 	if (dev) {
+		const struct net_device_ops *ops = dev->netdev_ops;
 		int err;
 		struct ifreq ifr;
-		mm_segment_t	oldfs;
 		struct ip_tunnel_parm p;
 		struct in_device  *in_dev;
 
@@ -166,9 +170,14 @@ struct net_device *ipmr_new_tunnel(struc
 		sprintf(p.name, "dvmrp%d", v->vifc_vifi);
 		ifr.ifr_ifru.ifru_data = (__force void __user *)&p;
 
-		oldfs = get_fs(); set_fs(KERNEL_DS);
-		err = dev->do_ioctl(dev, &ifr, SIOCADDTUNNEL);
-		set_fs(oldfs);
+		if (ops->do_ioctl) {
+			mm_segment_t oldfs = get_fs();
+
+			set_fs(KERNEL_DS);
+			err = ops->do_ioctl(dev, &ifr, SIOCADDTUNNEL);
+			set_fs(oldfs);
+		} else
+			err = -EOPNOTSUPP;
 
 		dev = NULL;
 
net/ipv6/addrconf.c +9 -4
@@ -2031,8 +2031,8 @@ int addrconf_set_dstaddr(struct net *net
 
 #if defined(CONFIG_IPV6_SIT) || defined(CONFIG_IPV6_SIT_MODULE)
 	if (dev->type == ARPHRD_SIT) {
+		const struct net_device_ops *ops = dev->netdev_ops;
 		struct ifreq ifr;
-		mm_segment_t	oldfs;
 		struct ip_tunnel_parm p;
 
 		err = -EADDRNOTAVAIL;
@@ -2048,9 +2048,14 @@ int addrconf_set_dstaddr(struct net *net
 		p.iph.ttl = 64;
 		ifr.ifr_ifru.ifru_data = (__force void __user *)&p;
 
-		oldfs = get_fs(); set_fs(KERNEL_DS);
-		err = dev->do_ioctl(dev, &ifr, SIOCADDTUNNEL);
-		set_fs(oldfs);
+		if (ops->do_ioctl) {
+			mm_segment_t oldfs = get_fs();
+
+			set_fs(KERNEL_DS);
+			err = ops->do_ioctl(dev, &ifr, SIOCADDTUNNEL);
+			set_fs(oldfs);
+		} else
+			err = -EOPNOTSUPP;
 
 		if (err == 0) {
 			err = -ENOBUFS;
#25 lore raw

PATCH 11/33 vlan: convert to net_device_ops

In reply to Stephen Hemminger

Convert vlan devices and function pointers to net_device_ops.

net/8021q/vlan.c +10 -8
@@ -144,6 +144,7 @@ void unregister_vlan_dev(struct net_devi
 {
 	struct vlan_dev_info *vlan = vlan_dev_info(dev);
 	struct net_device *real_dev = vlan->real_dev;
+	const struct net_device_ops *ops = real_dev->netdev_ops;
 	struct vlan_group *grp;
 	u16 vlan_id = vlan->vlan_id;
 
@@ -156,7 +157,7 @@ void unregister_vlan_dev(struct net_devi
 	 * HW accelerating devices or SW vlan input packet processing.
 	 */
 	if (real_dev->features & NETIF_F_HW_VLAN_FILTER)
-		real_dev->vlan_rx_kill_vid(real_dev, vlan_id);
+		ops->vlan_rx_kill_vid(real_dev, vlan_id);
 
 	vlan_group_set_device(grp, vlan_id, NULL);
 	grp->nr_vlans--;
@@ -170,7 +171,7 @@ void unregister_vlan_dev(struct net_devi
 		vlan_gvrp_uninit_applicant(real_dev);
 
 		if (real_dev->features & NETIF_F_HW_VLAN_RX)
-			real_dev->vlan_rx_register(real_dev, NULL);
+			ops->vlan_rx_register(real_dev, NULL);
 
 		hlist_del_rcu(&grp->hlist);
 
@@ -205,21 +206,21 @@ static void vlan_transfer_operstate(cons
 
 int vlan_check_real_dev(struct net_device *real_dev, u16 vlan_id)
 {
-	char *name = real_dev->name;
+	const char *name = real_dev->name;
+	const struct net_device_ops *ops = real_dev->netdev_ops;
 
 	if (real_dev->features & NETIF_F_VLAN_CHALLENGED) {
 		pr_info("8021q: VLANs not supported on %s\n", name);
 		return -EOPNOTSUPP;
 	}
 
-	if ((real_dev->features & NETIF_F_HW_VLAN_RX) &&
-	    !real_dev->vlan_rx_register) {
+	if ((real_dev->features & NETIF_F_HW_VLAN_RX) && !ops->vlan_rx_register) {
 		pr_info("8021q: device %s has buggy VLAN hw accel\n", name);
 		return -EOPNOTSUPP;
 	}
 
 	if ((real_dev->features & NETIF_F_HW_VLAN_FILTER) &&
-	    (!real_dev->vlan_rx_add_vid || !real_dev->vlan_rx_kill_vid)) {
+	    (!ops->vlan_rx_add_vid || !ops->vlan_rx_kill_vid)) {
 		pr_info("8021q: Device %s has buggy VLAN hw accel\n", name);
 		return -EOPNOTSUPP;
 	}
@@ -240,6 +241,7 @@ int register_vlan_dev(struct net_device 
 {
 	struct vlan_dev_info *vlan = vlan_dev_info(dev);
 	struct net_device *real_dev = vlan->real_dev;
+	const struct net_device_ops *ops = real_dev->netdev_ops;
 	u16 vlan_id = vlan->vlan_id;
 	struct vlan_group *grp, *ngrp = NULL;
 	int err;
@@ -275,9 +277,9 @@ int register_vlan_dev(struct net_device 
 	grp->nr_vlans++;
 
 	if (ngrp && real_dev->features & NETIF_F_HW_VLAN_RX)
-		real_dev->vlan_rx_register(real_dev, ngrp);
+		ops->vlan_rx_register(real_dev, ngrp);
 	if (real_dev->features & NETIF_F_HW_VLAN_FILTER)
-		real_dev->vlan_rx_add_vid(real_dev, vlan_id);
+		ops->vlan_rx_add_vid(real_dev, vlan_id);
 
 	return 0;
 
net/8021q/vlan_dev.c +18 -12
@@ -524,6 +524,7 @@ out:
 static int vlan_dev_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
 {
 	struct net_device *real_dev = vlan_dev_info(dev)->real_dev;
+	const struct net_device_ops *ops = real_dev->netdev_ops;
 	struct ifreq ifrr;
 	int err = -EOPNOTSUPP;
 
@@ -534,8 +535,8 @@ static int vlan_dev_ioctl(struct net_dev
 	case SIOCGMIIPHY:
 	case SIOCGMIIREG:
 	case SIOCSMIIREG:
-		if (real_dev->do_ioctl && netif_device_present(real_dev))
-			err = real_dev->do_ioctl(real_dev, &ifrr, cmd);
+		if (netif_device_present(real_dev) && ops->do_ioctl)
+			err = ops->do_ioctl(real_dev, &ifrr, cmd);
 		break;
 	}
 
@@ -697,6 +698,20 @@ static const struct ethtool_ops vlan_eth
 	.get_flags		= vlan_ethtool_get_flags,
 };
 
+static const struct net_device_ops vlan_netdev_ops = {
+	.change_mtu		= vlan_dev_change_mtu,
+	.init			= vlan_dev_init,
+	.uninit			= vlan_dev_uninit,
+	.open			= vlan_dev_open,
+	.stop			= vlan_dev_stop,
+	.validate_addr		= eth_validate_addr,
+	.set_mac_address	= vlan_dev_set_mac_address,
+	.set_rx_mode		= vlan_dev_set_rx_mode,
+	.set_multicast_list	= vlan_dev_set_rx_mode,
+	.change_rx_flags	= vlan_dev_change_rx_flags,
+	.do_ioctl		= vlan_dev_ioctl,
+};
+
 void vlan_setup(struct net_device *dev)
 {
 	ether_setup(dev);
@@ -704,16 +719,7 @@ void vlan_setup(struct net_device *dev)
 	dev->priv_flags		|= IFF_802_1Q_VLAN;
 	dev->tx_queue_len	= 0;
 
-	dev->change_mtu		= vlan_dev_change_mtu;
-	dev->init		= vlan_dev_init;
-	dev->uninit		= vlan_dev_uninit;
-	dev->open		= vlan_dev_open;
-	dev->stop		= vlan_dev_stop;
-	dev->set_mac_address	= vlan_dev_set_mac_address;
-	dev->set_rx_mode	= vlan_dev_set_rx_mode;
-	dev->set_multicast_list	= vlan_dev_set_rx_mode;
-	dev->change_rx_flags	= vlan_dev_change_rx_flags;
-	dev->do_ioctl		= vlan_dev_ioctl;
+	dev->netdev_ops		= &vlan_netdev_ops;
 	dev->destructor		= free_netdev;
 	dev->ethtool_ops	= &vlan_ethtool_ops;
 
#27 lore raw

PATCH 12/33 bonding: convert to net_device_ops

In reply to Stephen Hemminger

Convert to net_device_ops table.
Note: for some operations move error checking into generic networking layer (rather than looking at pointers in bonding).

A couple of gratituous style cleanups to get rid of extra {}

drivers/net/bonding/bond_alb.c +1 -7
@@ -1218,11 +1218,6 @@ static int alb_set_mac_address(struct bo
 	}
 
 	bond_for_each_slave(bond, slave, i) {
-		if (slave->dev->set_mac_address == NULL) {
-			res = -EOPNOTSUPP;
-			goto unwind;
-		}
-
 		/* save net_device's current hw address */
 		memcpy(tmp_addr, slave->dev->dev_addr, ETH_ALEN);
 
@@ -1231,9 +1226,8 @@ static int alb_set_mac_address(struct bo
 		/* restore net_device's hw address */
 		memcpy(slave->dev->dev_addr, tmp_addr, ETH_ALEN);
 
-		if (res) {
+		if (res)
 			goto unwind;
-		}
 	}
 
 	return 0;
drivers/net/bonding/bond_main.c +49 -43

231 lines not on this page · raw message

drivers/net/bonding/bond_sysfs.c +6 -16
@@ -317,18 +317,12 @@ static ssize_t bonding_store_slaves(stru
 
 		/* Set the slave's MTU to match the bond */
 		original_mtu = dev->mtu;
-		if (dev->mtu != bond->dev->mtu) {
-			if (dev->change_mtu) {
-				res = dev->change_mtu(dev,
-						      bond->dev->mtu);
-				if (res) {
-					ret = res;
-					goto out;
-				}
-			} else {
-				dev->mtu = bond->dev->mtu;
-			}
+		res = dev_set_mtu(dev, bond->dev->mtu);
+		if (res) {
+			ret = res;
+			goto out;
 		}
+
 		res = bond_enslave(bond->dev, dev);
 		bond_for_each_slave(bond, slave, i)
 			if (strnicmp(slave->dev->name, ifname, IFNAMSIZ) == 0)
@@ -357,11 +351,7 @@ static ssize_t bonding_store_slaves(stru
 				goto out;
 			}
 			/* set the slave MTU to the default */
-			if (dev->change_mtu) {
-				dev->change_mtu(dev, original_mtu);
-			} else {
-				dev->mtu = original_mtu;
-			}
+			dev_set_mtu(dev, original_mtu);
 		}
 		else {
 			printk(KERN_ERR DRV_NAME ": unable to remove non-existent slave %s for bond %s.\n",
maintainer Applied
#28 lore raw

Re: [PATCH 12/33] bonding: convert to net_device_ops

From: Stephen Hemminger <[email protected]>
Date: Mon, 17 Nov 2008 15:42:19 -0800

Quoted 7 lines

Convert to net_device_ops table.
Note: for some operations move error checking into generic networking layer (rather than looking at pointers in bonding).

A couple of gratituous style cleanups to get rid of extra {}

Applied.

#29 lore raw

PATCH 13/33 e1000e: convert to net_device_ops

In reply to Stephen Hemminger

Convert e1000e to network device ops.

drivers/net/e1000e/netdev.c +20 -14
@@ -4686,6 +4686,25 @@ static void e1000_eeprom_checks(struct e
 	}
 }
 
+static const struct net_device_ops e1000e_netdev_ops = {
+	.open			= e1000_open,
+	.stop			= e1000_close,
+	.get_stats		= e1000_get_stats,
+	.set_multicast_list	= e1000_set_multi,
+	.set_mac_address	= e1000_set_mac,
+	.change_mtu		= e1000_change_mtu,
+	.do_ioctl		= e1000_ioctl,
+	.tx_timeout		= e1000_tx_timeout,
+	.validate_addr		= eth_validate_addr,
+
+	.vlan_rx_register	= e1000_vlan_rx_register,
+	.vlan_rx_add_vid	= e1000_vlan_rx_add_vid,
+	.vlan_rx_kill_vid	= e1000_vlan_rx_kill_vid,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+	.poll_controller	= e1000_netpoll,
+#endif
+};
+
 /**
  * e1000_probe - Device Initialization Routine
  * @pdev: PCI device information struct
@@ -4783,24 +4802,11 @@ static int __devinit e1000_probe(struct 
 	}
 
 	/* construct the net_device struct */
-	netdev->open			= &e1000_open;
-	netdev->stop			= &e1000_close;
+	netdev->netdev_ops		= &e1000e_netdev_ops;
 	netdev->hard_start_xmit		= &e1000_xmit_frame;
-	netdev->get_stats		= &e1000_get_stats;
-	netdev->set_multicast_list	= &e1000_set_multi;
-	netdev->set_mac_address		= &e1000_set_mac;
-	netdev->change_mtu		= &e1000_change_mtu;
-	netdev->do_ioctl		= &e1000_ioctl;
 	e1000e_set_ethtool_ops(netdev);
-	netdev->tx_timeout		= &e1000_tx_timeout;
 	netdev->watchdog_timeo		= 5 * HZ;
 	netif_napi_add(netdev, &adapter->napi, e1000_clean, 64);
-	netdev->vlan_rx_register	= e1000_vlan_rx_register;
-	netdev->vlan_rx_add_vid		= e1000_vlan_rx_add_vid;
-	netdev->vlan_rx_kill_vid	= e1000_vlan_rx_kill_vid;
-#ifdef CONFIG_NET_POLL_CONTROLLER
-	netdev->poll_controller		= e1000_netpoll;
-#endif
 	strncpy(netdev->name, pci_name(pdev), sizeof(netdev->name) - 1);
 
 	netdev->mem_start = mmio_start;
#31 lore raw

PATCH 14/33 sky2: convert to net_device_ops

In reply to Stephen Hemminger

Convert to new network device ops interface. Slight additional complexity here because the second port does not allow netpoll and therefore has different virtual function table.

drivers/net/sky2.c +31 -13
@@ -3979,7 +3979,7 @@ static int sky2_device_event(struct noti
 	struct net_device *dev = ptr;
 	struct sky2_port *sky2 = netdev_priv(dev);
 
-	if (dev->open != sky2_up || !sky2_debug)
+	if (dev->netdev_ops->open != sky2_up || !sky2_debug)
 		return NOTIFY_DONE;
 
 	switch(event) {
@@ -4041,6 +4041,35 @@ static __exit void sky2_debug_cleanup(vo
 #define sky2_debug_cleanup()
 #endif
 
+/* Two copies of network device operations to handle special case of
+   not allowing netpoll on second port */
+static const struct net_device_ops sky2_netdev_ops[2] = {
+  {
+	.open		= sky2_up,
+	.stop		= sky2_down,
+	.do_ioctl	= sky2_ioctl,
+	.validate_addr	= eth_validate_addr,
+	.set_mac_address = sky2_set_mac_address,
+	.set_multicast_list = sky2_set_multicast,
+	.change_mtu	= sky2_change_mtu,
+	.tx_timeout	= sky2_tx_timeout,
+	.vlan_rx_register = sky2_vlan_rx_register,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+	.poll_controller = sky2_netpoll,
+#endif
+  },
+  {
+	.open		= sky2_up,
+	.stop		= sky2_down,
+	.do_ioctl	= sky2_ioctl,
+	.validate_addr	= eth_validate_addr,
+	.set_mac_address = sky2_set_mac_address,
+	.set_multicast_list = sky2_set_multicast,
+	.change_mtu	= sky2_change_mtu,
+	.tx_timeout	= sky2_tx_timeout,
+	.vlan_rx_register = sky2_vlan_rx_register,
+  },
+};
 
 /* Initialize network device */
 static __devinit struct net_device *sky2_init_netdev(struct sky2_hw *hw,
@@ -4057,20 +4086,10 @@ static __devinit struct net_device *sky2
 
 	SET_NETDEV_DEV(dev, &hw->pdev->dev);
 	dev->irq = hw->pdev->irq;
-	dev->open = sky2_up;
-	dev->stop = sky2_down;
-	dev->do_ioctl = sky2_ioctl;
 	dev->hard_start_xmit = sky2_xmit_frame;
-	dev->set_multicast_list = sky2_set_multicast;
-	dev->set_mac_address = sky2_set_mac_address;
-	dev->change_mtu = sky2_change_mtu;
 	SET_ETHTOOL_OPS(dev, &sky2_ethtool_ops);
-	dev->tx_timeout = sky2_tx_timeout;
 	dev->watchdog_timeo = TX_WATCHDOG;
-#ifdef CONFIG_NET_POLL_CONTROLLER
-	if (port == 0)
-		dev->poll_controller = sky2_netpoll;
-#endif
+	dev->netdev_ops = &sky2_netdev_ops[port];
 
 	sky2 = netdev_priv(dev);
 	sky2->netdev = dev;
@@ -4104,7 +4123,6 @@ static __devinit struct net_device *sky2
 	if (!(sky2->hw->chip_id == CHIP_ID_YUKON_FE_P &&
 	      sky2->hw->chip_rev == CHIP_REV_YU_FE2_A0)) {
 		dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX;
-		dev->vlan_rx_register = sky2_vlan_rx_register;
 	}
 #endif
 
#32 lore raw

Re: [PATCH 14/33] sky2: convert to net_device_ops

Convert to new network device ops interface. Slight additional complexity here because the second port does not allow netpoll and therefore has different virtual function table.

---
Handle non-vlan build.

drivers/net/sky2.c +35 -13
@@ -3979,7 +3979,7 @@ static int sky2_device_event(struct noti
 	struct net_device *dev = ptr;
 	struct sky2_port *sky2 = netdev_priv(dev);
 
-	if (dev->open != sky2_up || !sky2_debug)
+	if (dev->netdev_ops->open != sky2_up || !sky2_debug)
 		return NOTIFY_DONE;
 
 	switch(event) {
@@ -4041,6 +4041,39 @@ static __exit void sky2_debug_cleanup(vo
 #define sky2_debug_cleanup()
 #endif
 
+/* Two copies of network device operations to handle special case of
+   not allowing netpoll on second port */
+static const struct net_device_ops sky2_netdev_ops[2] = {
+  {
+	.open		= sky2_up,
+	.stop		= sky2_down,
+	.do_ioctl	= sky2_ioctl,
+	.validate_addr	= eth_validate_addr,
+	.set_mac_address = sky2_set_mac_address,
+	.set_multicast_list = sky2_set_multicast,
+	.change_mtu	= sky2_change_mtu,
+	.tx_timeout	= sky2_tx_timeout,
+#ifdef SKY2_VLAN_TAG_USED
+	.vlan_rx_register = sky2_vlan_rx_register,
+#endif
+#ifdef CONFIG_NET_POLL_CONTROLLER
+	.poll_controller = sky2_netpoll,
+#endif
+  },
+  {
+	.open		= sky2_up,
+	.stop		= sky2_down,
+	.do_ioctl	= sky2_ioctl,
+	.validate_addr	= eth_validate_addr,
+	.set_mac_address = sky2_set_mac_address,
+	.set_multicast_list = sky2_set_multicast,
+	.change_mtu	= sky2_change_mtu,
+	.tx_timeout	= sky2_tx_timeout,
+#ifdef SKY2_VLAN_TAG_USED
+	.vlan_rx_register = sky2_vlan_rx_register,
+#endif
+  },
+};
 
 /* Initialize network device */
 static __devinit struct net_device *sky2_init_netdev(struct sky2_hw *hw,
@@ -4057,20 +4090,10 @@ static __devinit struct net_device *sky2
 
 	SET_NETDEV_DEV(dev, &hw->pdev->dev);
 	dev->irq = hw->pdev->irq;
-	dev->open = sky2_up;
-	dev->stop = sky2_down;
-	dev->do_ioctl = sky2_ioctl;
 	dev->hard_start_xmit = sky2_xmit_frame;
-	dev->set_multicast_list = sky2_set_multicast;
-	dev->set_mac_address = sky2_set_mac_address;
-	dev->change_mtu = sky2_change_mtu;
 	SET_ETHTOOL_OPS(dev, &sky2_ethtool_ops);
-	dev->tx_timeout = sky2_tx_timeout;
 	dev->watchdog_timeo = TX_WATCHDOG;
-#ifdef CONFIG_NET_POLL_CONTROLLER
-	if (port == 0)
-		dev->poll_controller = sky2_netpoll;
-#endif
+	dev->netdev_ops = &sky2_netdev_ops[port];
 
 	sky2 = netdev_priv(dev);
 	sky2->netdev = dev;
@@ -4104,7 +4127,6 @@ static __devinit struct net_device *sky2
 	if (!(sky2->hw->chip_id == CHIP_ID_YUKON_FE_P &&
 	      sky2->hw->chip_rev == CHIP_REV_YU_FE2_A0)) {
 		dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX;
-		dev->vlan_rx_register = sky2_vlan_rx_register;
 	}
 #endif
 
maintainer Applied
#33 lore raw

Re: [PATCH 14/33] sky2: convert to net_device_ops

From: Stephen Hemminger <[email protected]>
Date: Mon, 17 Nov 2008 17:37:52 -0800

Quoted 8 lines

Convert to new network device ops interface. Slight additional complexity here because the second port does not allow netpoll and therefore has different virtual function table.

---
Handle non-vlan build.

Applied.

#34 lore raw

PATCH 15/33 skge: convert to net_device_ops

In reply to Stephen Hemminger

Convert to new network device ops interface.

drivers/net/skge.c +33 -18
@@ -104,6 +104,7 @@ static void yukon_get_stats(struct skge_
 static void yukon_init(struct skge_hw *hw, int port);
 static void genesis_mac_init(struct skge_hw *hw, int port);
 static void genesis_link_up(struct skge_port *skge);
+static void skge_set_multicast(struct net_device *dev);
 
 /* Avoid conditionals by using array */
 static const int txqaddr[] = { Q_XA1, Q_XA2 };
@@ -2463,7 +2464,7 @@ static void skge_phy_reset(struct skge_p
 	}
 	spin_unlock_bh(&hw->phy_lock);
 
-	dev->set_multicast_list(dev);
+	skge_set_multicast(dev);
 }
 
 /* Basic MII support */
@@ -3031,6 +3032,18 @@ static inline int bad_phy_status(const s
 			(status & GMR_FS_RX_OK) == 0;
 }
 
+static void skge_set_multicast(struct net_device *dev)
+{
+	struct skge_port *skge = netdev_priv(dev);
+	struct skge_hw *hw = skge->hw;
+
+	if (hw->chip_id == CHIP_ID_GENESIS)
+		genesis_set_multicast(dev);
+	else
+		yukon_set_multicast(dev);
+
+}
+
 
 /* Get receive buffer from descriptor.
  * Handles copy of small buffers and reallocation failures
@@ -3715,7 +3728,7 @@ static int skge_device_event(struct noti
 	struct skge_port *skge;
 	struct dentry *d;
 
-	if (dev->open != &skge_up || !skge_debug)
+	if (dev->netdev_ops->open != &skge_up || !skge_debug)
 		goto done;
 
 	skge = netdev_priv(dev);
@@ -3789,6 +3802,22 @@ static __exit void skge_debug_cleanup(vo
 #define skge_debug_cleanup()
 #endif
 
+static const struct net_device_ops skge_netdev_ops = {
+	.open		= skge_up,
+	.stop		= skge_down,
+	.do_ioctl	= skge_ioctl,
+	.get_stats	= skge_get_stats,
+	.tx_timeout	= skge_tx_timeout,
+	.change_mtu	= skge_change_mtu,
+	.validate_addr	= eth_validate_addr,
+	.set_multicast_list = skge_set_multicast,
+	.set_mac_address = skge_set_mac_address,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+	.poll_controller = skge_netpoll,
+#endif
+};
+
+
 /* Initialize network device */
 static struct net_device *skge_devinit(struct skge_hw *hw, int port,
 				       int highmem)
@@ -3802,24 +3831,10 @@ static struct net_device *skge_devinit(s
 	}
 
 	SET_NETDEV_DEV(dev, &hw->pdev->dev);
-	dev->open = skge_up;
-	dev->stop = skge_down;
-	dev->do_ioctl = skge_ioctl;
 	dev->hard_start_xmit = skge_xmit_frame;
-	dev->get_stats = skge_get_stats;
-	if (hw->chip_id == CHIP_ID_GENESIS)
-		dev->set_multicast_list = genesis_set_multicast;
-	else
-		dev->set_multicast_list = yukon_set_multicast;
-
-	dev->set_mac_address = skge_set_mac_address;
-	dev->change_mtu = skge_change_mtu;
-	SET_ETHTOOL_OPS(dev, &skge_ethtool_ops);
-	dev->tx_timeout = skge_tx_timeout;
+	dev->netdev_ops = &skge_netdev_ops;
+	dev->ethtool_ops = &skge_ethtool_ops;
 	dev->watchdog_timeo = TX_WATCHDOG;
-#ifdef CONFIG_NET_POLL_CONTROLLER
-	dev->poll_controller = skge_netpoll;
-#endif
 	dev->irq = hw->pdev->irq;
 
 	if (highmem)
#36 lore raw

PATCH 16/33 r8169: convert to net_device_ops

In reply to Stephen Hemminger

Convert to new network device ops interface. In this case needed to match behaviour of old code which only allowed ioctl on some device types.

drivers/net/r8169.c +21 -14
@@ -1832,6 +1832,9 @@ static int rtl8169_ioctl(struct net_devi
 	if (!netif_running(dev))
 		return -ENODEV;
 
+	if (tp->get_settings != rtl8169_gset_xmii)
+		return -EOPNOTSUPP;
+
 	switch (cmd) {
 	case SIOCGMIIPHY:
 		data->phy_id = 32; /* Internal PHY */
@@ -1915,6 +1918,23 @@ static void rtl_disable_msi(struct pci_d
 	}
 }
 
+static const struct net_device_ops rtl8169_netdev_ops = {
+	.open			= rtl8169_open,
+	.stop			= rtl8169_close,
+	.get_stats		= rtl8169_get_stats,
+	.tx_timeout		= rtl8169_tx_timeout,
+	.validate_addr		= eth_validate_addr,
+	.change_mtu		= rtl8169_change_mtu,
+	.set_mac_address	= rtl_set_mac_address,
+	.do_ioctl		= rtl8169_ioctl,
+	.set_multicast_list	= rtl_set_rx_mode,
+	.vlan_rx_register	= rtl8169_vlan_rx_register,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+	.poll_controller	= rtl8169_netpoll,
+#endif
+
+};
+
 static int __devinit
 rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
 {
@@ -1941,6 +1961,7 @@ rtl8169_init_one(struct pci_dev *pdev, c
 	}
 
 	SET_NETDEV_DEV(dev, &pdev->dev);
+	dev->netdev_ops = &rtl8169_netdev_ops;
 	tp = netdev_priv(dev);
 	tp->dev = dev;
 	tp->pci_dev = pdev;
@@ -2084,8 +2105,6 @@ rtl8169_init_one(struct pci_dev *pdev, c
 		tp->phy_reset_enable = rtl8169_xmii_reset_enable;
 		tp->phy_reset_pending = rtl8169_xmii_reset_pending;
 		tp->link_ok = rtl8169_xmii_link_ok;
-
-		dev->do_ioctl = rtl8169_ioctl;
 	}
 
 	spin_lock_init(&tp->lock);
@@ -2097,28 +2116,16 @@ rtl8169_init_one(struct pci_dev *pdev, c
 		dev->dev_addr[i] = RTL_R8(MAC0 + i);
 	memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len);
 
-	dev->open = rtl8169_open;
 	dev->hard_start_xmit = rtl8169_start_xmit;
-	dev->get_stats = rtl8169_get_stats;
 	SET_ETHTOOL_OPS(dev, &rtl8169_ethtool_ops);
-	dev->stop = rtl8169_close;
-	dev->tx_timeout = rtl8169_tx_timeout;
-	dev->set_multicast_list = rtl_set_rx_mode;
 	dev->watchdog_timeo = RTL8169_TX_TIMEOUT;
 	dev->irq = pdev->irq;
 	dev->base_addr = (unsigned long) ioaddr;
-	dev->change_mtu = rtl8169_change_mtu;
-	dev->set_mac_address = rtl_set_mac_address;
 
 	netif_napi_add(dev, &tp->napi, rtl8169_poll, R8169_NAPI_WEIGHT);
 
 #ifdef CONFIG_R8169_VLAN
 	dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX;
-	dev->vlan_rx_register = rtl8169_vlan_rx_register;
-#endif
-
-#ifdef CONFIG_NET_POLL_CONTROLLER
-	dev->poll_controller = rtl8169_netpoll;
 #endif
 
 	tp->intr_mask = 0xffff;
#37 lore raw

Re: [PATCH 16/33] r8169: convert to net_device_ops

Convert to new network device ops interface. In this case needed to match behaviour of old code which only allowed ioctl on some device types.

---
Handle no vlan case as well.

drivers/net/r8169.c +23 -14
@@ -1832,6 +1832,9 @@ static int rtl8169_ioctl(struct net_devi
 	if (!netif_running(dev))
 		return -ENODEV;
 
+	if (tp->get_settings != rtl8169_gset_xmii)
+		return -EOPNOTSUPP;
+
 	switch (cmd) {
 	case SIOCGMIIPHY:
 		data->phy_id = 32; /* Internal PHY */
@@ -1915,6 +1918,25 @@ static void rtl_disable_msi(struct pci_d
 	}
 }
 
+static const struct net_device_ops rtl8169_netdev_ops = {
+	.open			= rtl8169_open,
+	.stop			= rtl8169_close,
+	.get_stats		= rtl8169_get_stats,
+	.tx_timeout		= rtl8169_tx_timeout,
+	.validate_addr		= eth_validate_addr,
+	.change_mtu		= rtl8169_change_mtu,
+	.set_mac_address	= rtl_set_mac_address,
+	.do_ioctl		= rtl8169_ioctl,
+	.set_multicast_list	= rtl_set_rx_mode,
+#ifdef CONFIG_R8169_VLAN
+	.vlan_rx_register	= rtl8169_vlan_rx_register,
+#endif
+#ifdef CONFIG_NET_POLL_CONTROLLER
+	.poll_controller	= rtl8169_netpoll,
+#endif
+
+};
+
 static int __devinit
 rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
 {
@@ -1941,6 +1963,7 @@ rtl8169_init_one(struct pci_dev *pdev, c
 	}
 
 	SET_NETDEV_DEV(dev, &pdev->dev);
+	dev->netdev_ops = &rtl8169_netdev_ops;
 	tp = netdev_priv(dev);
 	tp->dev = dev;
 	tp->pci_dev = pdev;
@@ -2084,8 +2107,6 @@ rtl8169_init_one(struct pci_dev *pdev, c
 		tp->phy_reset_enable = rtl8169_xmii_reset_enable;
 		tp->phy_reset_pending = rtl8169_xmii_reset_pending;
 		tp->link_ok = rtl8169_xmii_link_ok;
-
-		dev->do_ioctl = rtl8169_ioctl;
 	}
 
 	spin_lock_init(&tp->lock);
@@ -2097,28 +2118,16 @@ rtl8169_init_one(struct pci_dev *pdev, c
 		dev->dev_addr[i] = RTL_R8(MAC0 + i);
 	memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len);
 
-	dev->open = rtl8169_open;
 	dev->hard_start_xmit = rtl8169_start_xmit;
-	dev->get_stats = rtl8169_get_stats;
 	SET_ETHTOOL_OPS(dev, &rtl8169_ethtool_ops);
-	dev->stop = rtl8169_close;
-	dev->tx_timeout = rtl8169_tx_timeout;
-	dev->set_multicast_list = rtl_set_rx_mode;
 	dev->watchdog_timeo = RTL8169_TX_TIMEOUT;
 	dev->irq = pdev->irq;
 	dev->base_addr = (unsigned long) ioaddr;
-	dev->change_mtu = rtl8169_change_mtu;
-	dev->set_mac_address = rtl_set_mac_address;
 
 	netif_napi_add(dev, &tp->napi, rtl8169_poll, R8169_NAPI_WEIGHT);
 
 #ifdef CONFIG_R8169_VLAN
 	dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX;
-	dev->vlan_rx_register = rtl8169_vlan_rx_register;
-#endif
-
-#ifdef CONFIG_NET_POLL_CONTROLLER
-	dev->poll_controller = rtl8169_netpoll;
 #endif
 
 	tp->intr_mask = 0xffff;
#38 lore raw

Re: [PATCH 16/33] r8169: convert to net_device_ops

Stephen Hemminger <[email protected]> :

Quoted 11 lines

Convert to new network device ops interface. In this case needed to match behaviour of old code which only allowed ioctl on some device types.

---
Handle no vlan case as well.

drivers/net/r8169.c static int rtl8169_ioctl(struct net_devi · line 1837

Quoted 6 lines
drivers/net/r8169.c +3 -0
@@ -1832,6 +1832,9 @@ static int rtl8169_ioctl(struct net_devi
 	if (!netif_running(dev))
 		return -ENODEV;
 
+	if (tp->get_settings != rtl8169_gset_xmii)
+		return -EOPNOTSUPP;
+

It's a bit hackish. Would you raise an objection against the code below ?

drivers/net/r8169.c +32 -16
index 4b7cb38..983ec8b 100644
@@ -474,6 +474,7 @@ struct rtl8169_private {
 	void (*hw_start)(struct net_device *);
 	unsigned int (*phy_reset_pending)(void __iomem *);
 	unsigned int (*link_ok)(void __iomem *);
+	int do_ioctl(struct rtl8169_private *tp, struct mii_ioctl_data *data);
 	int pcie_cap;
 	struct delayed_work task;
 	unsigned features;
@@ -1829,9 +1830,11 @@ static int rtl8169_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
 	struct rtl8169_private *tp = netdev_priv(dev);
 	struct mii_ioctl_data *data = if_mii(ifr);
 
-	if (!netif_running(dev))
-		return -ENODEV;
+	return netif_running(dev) ? tp->do_ioctl(tp, data) : -ENODEV;
+}
 
+static int rtl_xmii_ioctl(struct rtl8169_private *tp, struct mii_ioctl_data *data)
+{
 	switch (cmd) {
 	case SIOCGMIIPHY:
 		data->phy_id = 32; /* Internal PHY */
@@ -1850,6 +1853,11 @@ static int rtl8169_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
 	return -EOPNOTSUPP;
 }
 
+static int rtl_tbi_ioctl(struct rtl8169_private *tp, struct mii_ioctl_data *data)
+{
+	return -EOPNOTSUPP;
+}
+
 static const struct rtl_cfg_info {
 	void (*hw_start)(struct net_device *);
 	unsigned int region;
@@ -1915,6 +1923,25 @@ static void rtl_disable_msi(struct pci_dev *pdev, struct rtl8169_private *tp)
 	}
 }
 
+static const struct net_device_ops rtl8169_netdev_ops = {
+	.open			= rtl8169_open,
+	.stop			= rtl8169_close,
+	.get_stats		= rtl8169_get_stats,
+	.tx_timeout		= rtl8169_tx_timeout,
+	.validate_addr		= eth_validate_addr,
+	.change_mtu		= rtl8169_change_mtu,
+	.set_mac_address	= rtl_set_mac_address,
+	.do_ioctl		= rtl8169_ioctl,
+	.set_multicast_list	= rtl_set_rx_mode,
+#ifdef CONFIG_R8169_VLAN
+	.vlan_rx_register	= rtl8169_vlan_rx_register,
+#endif
+#ifdef CONFIG_NET_POLL_CONTROLLER
+	.poll_controller	= rtl8169_netpoll,
+#endif
+
+};
+
 static int __devinit
 rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
 {
@@ -1941,6 +1968,7 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
 	}
 
 	SET_NETDEV_DEV(dev, &pdev->dev);
+	dev->netdev_ops = &rtl8169_netdev_ops;
 	tp = netdev_priv(dev);
 	tp->dev = dev;
 	tp->pci_dev = pdev;
@@ -2076,6 +2104,7 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
 		tp->phy_reset_enable = rtl8169_tbi_reset_enable;
 		tp->phy_reset_pending = rtl8169_tbi_reset_pending;
 		tp->link_ok = rtl8169_tbi_link_ok;
+		tp->do_ioctl = rtl_tbi_ioctl;
 
 		tp->phy_1000_ctrl_reg = ADVERTISE_1000FULL; /* Implied by TBI */
 	} else {
@@ -2084,8 +2113,7 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
 		tp->phy_reset_enable = rtl8169_xmii_reset_enable;
 		tp->phy_reset_pending = rtl8169_xmii_reset_pending;
 		tp->link_ok = rtl8169_xmii_link_ok;
-
-		dev->do_ioctl = rtl8169_ioctl;
+		tp->do_ioctl = rtl_xmii_ioctl;
 	}
 
 	spin_lock_init(&tp->lock);
@@ -2097,28 +2125,16 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
 		dev->dev_addr[i] = RTL_R8(MAC0 + i);
 	memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len);
 
-	dev->open = rtl8169_open;
 	dev->hard_start_xmit = rtl8169_start_xmit;
-	dev->get_stats = rtl8169_get_stats;
 	SET_ETHTOOL_OPS(dev, &rtl8169_ethtool_ops);
-	dev->stop = rtl8169_close;
-	dev->tx_timeout = rtl8169_tx_timeout;
-	dev->set_multicast_list = rtl_set_rx_mode;
 	dev->watchdog_timeo = RTL8169_TX_TIMEOUT;
 	dev->irq = pdev->irq;
 	dev->base_addr = (unsigned long) ioaddr;
-	dev->change_mtu = rtl8169_change_mtu;
-	dev->set_mac_address = rtl_set_mac_address;
 
 	netif_napi_add(dev, &tp->napi, rtl8169_poll, R8169_NAPI_WEIGHT);
 
 #ifdef CONFIG_R8169_VLAN
 	dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX;
-	dev->vlan_rx_register = rtl8169_vlan_rx_register;
-#endif
-
-#ifdef CONFIG_NET_POLL_CONTROLLER
-	dev->poll_controller = rtl8169_netpoll;
 #endif
 
 	tp->intr_mask = 0xffff;
Signature · 1 line
Ueimor
maintainer
#39 lore raw

Re: [PATCH 16/33] r8169: convert to net_device_ops

From: Francois Romieu <[email protected]>
Date: Tue, 18 Nov 2008 22:18:58 +0100

Quoted 15 lines

Stephen Hemminger <[email protected]> :

Quoted 14 lines

Convert to new network device ops interface. In this case needed to match behaviour of old code which only allowed ioctl on some device types.

---
Handle no vlan case as well.

drivers/net/r8169.c +0 -0
@@ -1832,6 +1832,9 @@ static int rtl8169_ioctl(struct net_devi
 	if (!netif_running(dev))
 		return -ENODEV;
 
Quoted 6 lines

drivers/net/r8169.c static int rtl8169_ioctl(struct net_devi · line 1837

Quoted 3 lines
drivers/net/r8169.c +3 -0
+	if (tp->get_settings != rtl8169_gset_xmii)
+		return -EOPNOTSUPP;
+

It's a bit hackish. Would you raise an objection against the code below ?

I applied this (actually build tested, sigh) version of your patch.

Please, if you are going to propose a real patch, at least do a minimal build test on it.

If you cannot be bothered to do that, either be happy with the original submission or make your suggestion using pseudo-code or plain english.

Otherwise what you post looks like something I can expect to apply and use.

r8169: convert to net_device_ops

From: Francois Romieu <[email protected]>

Based upon a patch by Stephen Hemminger.

---
 drivers/net/r8169.c |   48 ++++++++++++++++++++++++++++++++----------------
 1 files changed, 32 insertions(+), 16 deletions(-)
drivers/net/r8169.c +32 -16
index cb5042e..bac58ca 100644
@@ -474,6 +474,7 @@ struct rtl8169_private {
 	void (*hw_start)(struct net_device *);
 	unsigned int (*phy_reset_pending)(void __iomem *);
 	unsigned int (*link_ok)(void __iomem *);
+	int (*do_ioctl)(struct rtl8169_private *tp, struct mii_ioctl_data *data, int cmd);
 	int pcie_cap;
 	struct delayed_work task;
 	unsigned features;
@@ -1829,9 +1830,11 @@ static int rtl8169_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
 	struct rtl8169_private *tp = netdev_priv(dev);
 	struct mii_ioctl_data *data = if_mii(ifr);
 
-	if (!netif_running(dev))
-		return -ENODEV;
+	return netif_running(dev) ? tp->do_ioctl(tp, data, cmd) : -ENODEV;
+}
 
+static int rtl_xmii_ioctl(struct rtl8169_private *tp, struct mii_ioctl_data *data, int cmd)
+{
 	switch (cmd) {
 	case SIOCGMIIPHY:
 		data->phy_id = 32; /* Internal PHY */
@@ -1850,6 +1853,11 @@ static int rtl8169_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
 	return -EOPNOTSUPP;
 }
 
+static int rtl_tbi_ioctl(struct rtl8169_private *tp, struct mii_ioctl_data *data, int cmd)
+{
+	return -EOPNOTSUPP;
+}
+
 static const struct rtl_cfg_info {
 	void (*hw_start)(struct net_device *);
 	unsigned int region;
@@ -1915,6 +1923,25 @@ static void rtl_disable_msi(struct pci_dev *pdev, struct rtl8169_private *tp)
 	}
 }
 
+static const struct net_device_ops rtl8169_netdev_ops = {
+	.ndo_open		= rtl8169_open,
+	.ndo_stop		= rtl8169_close,
+	.ndo_get_stats		= rtl8169_get_stats,
+	.ndo_tx_timeout		= rtl8169_tx_timeout,
+	.ndo_validate_addr	= eth_validate_addr,
+	.ndo_change_mtu		= rtl8169_change_mtu,
+	.ndo_set_mac_address	= rtl_set_mac_address,
+	.ndo_do_ioctl		= rtl8169_ioctl,
+	.ndo_set_multicast_list	= rtl_set_rx_mode,
+#ifdef CONFIG_R8169_VLAN
+	.ndo_vlan_rx_register	= rtl8169_vlan_rx_register,
+#endif
+#ifdef CONFIG_NET_POLL_CONTROLLER
+	.ndo_poll_controller	= rtl8169_netpoll,
+#endif
+
+};
+
 static int __devinit
 rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
 {
@@ -1941,6 +1968,7 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
 	}
 
 	SET_NETDEV_DEV(dev, &pdev->dev);
+	dev->netdev_ops = &rtl8169_netdev_ops;
 	tp = netdev_priv(dev);
 	tp->dev = dev;
 	tp->pci_dev = pdev;
@@ -2076,6 +2104,7 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
 		tp->phy_reset_enable = rtl8169_tbi_reset_enable;
 		tp->phy_reset_pending = rtl8169_tbi_reset_pending;
 		tp->link_ok = rtl8169_tbi_link_ok;
+		tp->do_ioctl = rtl_tbi_ioctl;
 
 		tp->phy_1000_ctrl_reg = ADVERTISE_1000FULL; /* Implied by TBI */
 	} else {
@@ -2084,8 +2113,7 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
 		tp->phy_reset_enable = rtl8169_xmii_reset_enable;
 		tp->phy_reset_pending = rtl8169_xmii_reset_pending;
 		tp->link_ok = rtl8169_xmii_link_ok;
-
-		dev->do_ioctl = rtl8169_ioctl;
+		tp->do_ioctl = rtl_xmii_ioctl;
 	}
 
 	spin_lock_init(&tp->lock);
@@ -2097,28 +2125,16 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
 		dev->dev_addr[i] = RTL_R8(MAC0 + i);
 	memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len);
 
-	dev->open = rtl8169_open;
 	dev->hard_start_xmit = rtl8169_start_xmit;
-	dev->get_stats = rtl8169_get_stats;
 	SET_ETHTOOL_OPS(dev, &rtl8169_ethtool_ops);
-	dev->stop = rtl8169_close;
-	dev->tx_timeout = rtl8169_tx_timeout;
-	dev->set_multicast_list = rtl_set_rx_mode;
 	dev->watchdog_timeo = RTL8169_TX_TIMEOUT;
 	dev->irq = pdev->irq;
 	dev->base_addr = (unsigned long) ioaddr;
-	dev->change_mtu = rtl8169_change_mtu;
-	dev->set_mac_address = rtl_set_mac_address;
 
 	netif_napi_add(dev, &tp->napi, rtl8169_poll, R8169_NAPI_WEIGHT);
 
 #ifdef CONFIG_R8169_VLAN
 	dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX;
-	dev->vlan_rx_register = rtl8169_vlan_rx_register;
-#endif
-
-#ifdef CONFIG_NET_POLL_CONTROLLER
-	dev->poll_controller = rtl8169_netpoll;
 #endif
 
 	tp->intr_mask = 0xffff;
Signature · 1 line
1.5.6.5
#40 lore raw

Re: [PATCH 16/33] r8169: convert to net_device_ops

David Miller <[email protected]> :
[...]

Quoted 2 lines

Otherwise what you post looks like something I can expect to apply and use.

Sorry for wasting your time.

I'll add a clear "don't apply as is / proof of concept" disclaimer next time.

Signature · 1 line
Ueimor
#41 lore raw

PATCH 17/33 8139: convert to net_device_ops

In reply to Stephen Hemminger

Convert to new network device ops interface.

---
 drivers/net/8139cp.c  |   31 ++++++++++++++++++-------------
 drivers/net/8139too.c |   27 ++++++++++++++++-----------
 2 files changed, 34 insertions(+), 24 deletions(-)
drivers/net/8139cp.c +18 -13
@@ -1817,6 +1817,23 @@ static void cp_set_d3_state (struct cp_p
 	pci_set_power_state (cp->pdev, PCI_D3hot);
 }
 
+static const struct net_device_ops cp_netdev_ops = {
+	.open			= cp_open,
+	.stop			= cp_close,
+	.validate_addr		= eth_validate_addr,
+	.set_multicast_list	= cp_set_rx_mode,
+	.get_stats		= cp_get_stats,
+	.do_ioctl		= cp_ioctl,
+	.tx_timeout		= cp_tx_timeout,
+	.vlan_rx_register	= cp_vlan_rx_register,
+#ifdef BROKEN
+	.change_mtu		= cp_change_mtu,
+#endif
+#ifdef CONFIG_NET_POLL_CONTROLLER
+	.poll_controller	= cp_poll_controller,
+#endif
+};
+
 static int cp_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
 {
 	struct net_device *dev;
@@ -1929,26 +1946,14 @@ static int cp_init_one (struct pci_dev *
 		    cpu_to_le16(read_eeprom (regs, i + 7, addr_len));
 	memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len);
 
-	dev->open = cp_open;
-	dev->stop = cp_close;
-	dev->set_multicast_list = cp_set_rx_mode;
+	dev->netdev_ops = &cp_netdev_ops;
 	dev->hard_start_xmit = cp_start_xmit;
-	dev->get_stats = cp_get_stats;
-	dev->do_ioctl = cp_ioctl;
-#ifdef CONFIG_NET_POLL_CONTROLLER
-	dev->poll_controller = cp_poll_controller;
-#endif
 	netif_napi_add(dev, &cp->napi, cp_rx_poll, 16);
-#ifdef BROKEN
-	dev->change_mtu = cp_change_mtu;
-#endif
 	dev->ethtool_ops = &cp_ethtool_ops;
-	dev->tx_timeout = cp_tx_timeout;
 	dev->watchdog_timeo = TX_TIMEOUT;
 
 #if CP_VLAN_TAG_USED
 	dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX;
-	dev->vlan_rx_register = cp_vlan_rx_register;
 #endif
 
 	if (pci_using_dac)
drivers/net/8139too.c +16 -11
@@ -916,6 +916,19 @@ err_out:
 	return rc;
 }
 
+static const struct net_device_ops rtl8139_netdev_ops = {
+	.open			= rtl8139_open,
+	.stop			= rtl8139_close,
+	.get_stats		= rtl8139_get_stats,
+	.validate_addr		= eth_validate_addr,
+	.set_multicast_list	= rtl8139_set_rx_mode,
+	.do_ioctl		= netdev_ioctl,
+	.tx_timeout		= rtl8139_tx_timeout,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+	.poll_controller	= rtl8139_poll_controller,
+#endif
+
+};
 
 static int __devinit rtl8139_init_one (struct pci_dev *pdev,
 				       const struct pci_device_id *ent)
@@ -976,19 +989,11 @@ static int __devinit rtl8139_init_one (s
 	memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len);
 
 	/* The Rtl8139-specific entries in the device structure. */
-	dev->open = rtl8139_open;
-	dev->hard_start_xmit = rtl8139_start_xmit;
-	netif_napi_add(dev, &tp->napi, rtl8139_poll, 64);
-	dev->stop = rtl8139_close;
-	dev->get_stats = rtl8139_get_stats;
-	dev->set_multicast_list = rtl8139_set_rx_mode;
-	dev->do_ioctl = netdev_ioctl;
+	dev->netdev_ops = &rtl8139_netdev_ops;
 	dev->ethtool_ops = &rtl8139_ethtool_ops;
-	dev->tx_timeout = rtl8139_tx_timeout;
 	dev->watchdog_timeo = TX_TIMEOUT;
-#ifdef CONFIG_NET_POLL_CONTROLLER
-	dev->poll_controller = rtl8139_poll_controller;
-#endif
+	dev->hard_start_xmit = rtl8139_start_xmit;
+	netif_napi_add(dev, &tp->napi, rtl8139_poll, 64);
 
 	/* note: the hardware is not capable of sg/csum/highdma, however
 	 * through the use of skb_copy_and_csum_dev we enable these
#42 lore raw

Re: [PATCH 17/33] 8139: convert to net_device_ops

Convert to new network device ops interface.

---
Handle non-vlan tag support as well

 drivers/net/8139cp.c  |   31 ++++++++++++++++++-------------
 drivers/net/8139too.c |   27 ++++++++++++++++-----------
 2 files changed, 34 insertions(+), 24 deletions(-)
drivers/net/8139cp.c +20 -13
@@ -1817,6 +1817,25 @@ static void cp_set_d3_state (struct cp_p
 	pci_set_power_state (cp->pdev, PCI_D3hot);
 }
 
+static const struct net_device_ops cp_netdev_ops = {
+	.open			= cp_open,
+	.stop			= cp_close,
+	.validate_addr		= eth_validate_addr,
+	.set_multicast_list	= cp_set_rx_mode,
+	.get_stats		= cp_get_stats,
+	.do_ioctl		= cp_ioctl,
+	.tx_timeout		= cp_tx_timeout,
+#if CP_VLAN_TAG_USED
+	.vlan_rx_register	= cp_vlan_rx_register,
+#endif
+#ifdef BROKEN
+	.change_mtu		= cp_change_mtu,
+#endif
+#ifdef CONFIG_NET_POLL_CONTROLLER
+	.poll_controller	= cp_poll_controller,
+#endif
+};
+
 static int cp_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
 {
 	struct net_device *dev;
@@ -1929,26 +1948,14 @@ static int cp_init_one (struct pci_dev *
 		    cpu_to_le16(read_eeprom (regs, i + 7, addr_len));
 	memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len);
 
-	dev->open = cp_open;
-	dev->stop = cp_close;
-	dev->set_multicast_list = cp_set_rx_mode;
+	dev->netdev_ops = &cp_netdev_ops;
 	dev->hard_start_xmit = cp_start_xmit;
-	dev->get_stats = cp_get_stats;
-	dev->do_ioctl = cp_ioctl;
-#ifdef CONFIG_NET_POLL_CONTROLLER
-	dev->poll_controller = cp_poll_controller;
-#endif
 	netif_napi_add(dev, &cp->napi, cp_rx_poll, 16);
-#ifdef BROKEN
-	dev->change_mtu = cp_change_mtu;
-#endif
 	dev->ethtool_ops = &cp_ethtool_ops;
-	dev->tx_timeout = cp_tx_timeout;
 	dev->watchdog_timeo = TX_TIMEOUT;
 
 #if CP_VLAN_TAG_USED
 	dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX;
-	dev->vlan_rx_register = cp_vlan_rx_register;
 #endif
 
 	if (pci_using_dac)
drivers/net/8139too.c +16 -11
@@ -916,6 +916,19 @@ err_out:
 	return rc;
 }
 
+static const struct net_device_ops rtl8139_netdev_ops = {
+	.open			= rtl8139_open,
+	.stop			= rtl8139_close,
+	.get_stats		= rtl8139_get_stats,
+	.validate_addr		= eth_validate_addr,
+	.set_multicast_list	= rtl8139_set_rx_mode,
+	.do_ioctl		= netdev_ioctl,
+	.tx_timeout		= rtl8139_tx_timeout,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+	.poll_controller	= rtl8139_poll_controller,
+#endif
+
+};
 
 static int __devinit rtl8139_init_one (struct pci_dev *pdev,
 				       const struct pci_device_id *ent)
@@ -976,19 +989,11 @@ static int __devinit rtl8139_init_one (s
 	memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len);
 
 	/* The Rtl8139-specific entries in the device structure. */
-	dev->open = rtl8139_open;
-	dev->hard_start_xmit = rtl8139_start_xmit;
-	netif_napi_add(dev, &tp->napi, rtl8139_poll, 64);
-	dev->stop = rtl8139_close;
-	dev->get_stats = rtl8139_get_stats;
-	dev->set_multicast_list = rtl8139_set_rx_mode;
-	dev->do_ioctl = netdev_ioctl;
+	dev->netdev_ops = &rtl8139_netdev_ops;
 	dev->ethtool_ops = &rtl8139_ethtool_ops;
-	dev->tx_timeout = rtl8139_tx_timeout;
 	dev->watchdog_timeo = TX_TIMEOUT;
-#ifdef CONFIG_NET_POLL_CONTROLLER
-	dev->poll_controller = rtl8139_poll_controller;
-#endif
+	dev->hard_start_xmit = rtl8139_start_xmit;
+	netif_napi_add(dev, &tp->napi, rtl8139_poll, 64);
 
 	/* note: the hardware is not capable of sg/csum/highdma, however
 	 * through the use of skb_copy_and_csum_dev we enable these
#44 lore raw

PATCH 18/33 tun: convert to net_device_ops

In reply to Stephen Hemminger

Convert the TUN/TAP tunnel driver to net_device_ops. Split the ops in two, and retain compatability.

drivers/net/tun.c +20 -5
@@ -305,6 +305,22 @@ tun_net_change_mtu(struct net_device *de
 	return 0;
 }
 
+static const struct net_device_ops tun_netdev_ops = {
+	.open	            = tun_net_open,
+	.stop 	    	    = tun_net_close,
+	.change_mtu  	    = tun_net_change_mtu,
+
+};
+
+static const struct net_device_ops tap_netdev_ops = {
+	.open		    = tun_net_open,
+	.stop		    = tun_net_close,
+	.change_mtu	    = tun_net_change_mtu,
+	.set_multicast_list = tun_net_mclist,
+	.set_mac_address    = eth_mac_addr,
+	.validate_addr	    = eth_validate_addr,
+};
+
 /* Initialize net device. */
 static void tun_net_init(struct net_device *dev)
 {
@@ -312,11 +328,12 @@ static void tun_net_init(struct net_devi
 
 	switch (tun->flags & TUN_TYPE_MASK) {
 	case TUN_TUN_DEV:
+		dev->netdev_ops = &tun_netdev_ops;
+
 		/* Point-to-Point TUN Device */
 		dev->hard_header_len = 0;
 		dev->addr_len = 0;
 		dev->mtu = 1500;
-		dev->change_mtu = tun_net_change_mtu;
 
 		/* Zero header length */
 		dev->type = ARPHRD_NONE;
@@ -325,10 +342,9 @@ static void tun_net_init(struct net_devi
 		break;
 
 	case TUN_TAP_DEV:
+		dev->netdev_ops = &tun_netdev_ops;
 		/* Ethernet TAP Device */
 		ether_setup(dev);
-		dev->change_mtu         = tun_net_change_mtu;
-		dev->set_multicast_list = tun_net_mclist;
 
 		random_ether_addr(dev->dev_addr);
 
@@ -675,9 +691,7 @@ static void tun_setup(struct net_device 
 	tun->owner = -1;
 	tun->group = -1;
 
-	dev->open = tun_net_open;
 	dev->hard_start_xmit = tun_net_xmit;
-	dev->stop = tun_net_close;
 	dev->ethtool_ops = &tun_ethtool_ops;
 	dev->destructor = free_netdev;
 	dev->features |= NETIF_F_NETNS_LOCAL;
@@ -749,6 +763,7 @@ static int tun_set_iff(struct net *net, 
 			return -ENOMEM;
 
 		dev_net_set(dev, net);
+
 		tun = netdev_priv(dev);
 		tun->dev = dev;
 		tun->flags = flags;
#46 lore raw

PATCH 19/33 atl1e: convert to net_device_ops

In reply to Stephen Hemminger

Convert this driver to network device ops. Compile tested only.

drivers/net/atl1e/atl1e_main.c +19 -13
@@ -2253,26 +2253,32 @@ static void atl1e_shutdown(struct pci_de
 	atl1e_suspend(pdev, PMSG_SUSPEND);
 }
 
+static const struct net_device_ops atl1e_netdev_ops = {
+	.open 	 	    = atl1e_open,
+	.stop 	 	    = atl1e_close,
+	.get_stats 	    = atl1e_get_stats,
+	.set_multicast_list = atl1e_set_multi,
+	.validate_addr	    = eth_validate_addr,
+	.set_mac_address    = atl1e_set_mac_addr,
+	.change_mtu 	    = atl1e_change_mtu,
+	.do_ioctl 	    = atl1e_ioctl,
+	.tx_timeout 	    = atl1e_tx_timeout,
+	.vlan_rx_register   = atl1e_vlan_rx_register,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+	.poll_controller    = atl1e_netpoll,
+#endif
+
+};
+
 static int atl1e_init_netdev(struct net_device *netdev, struct pci_dev *pdev)
 {
 	SET_NETDEV_DEV(netdev, &pdev->dev);
 	pci_set_drvdata(pdev, netdev);
 
 	netdev->irq  = pdev->irq;
-	netdev->open = &atl1e_open;
-	netdev->stop = &atl1e_close;
-	netdev->hard_start_xmit = &atl1e_xmit_frame;
-	netdev->get_stats = &atl1e_get_stats;
-	netdev->set_multicast_list = &atl1e_set_multi;
-	netdev->set_mac_address = &atl1e_set_mac_addr;
-	netdev->change_mtu = &atl1e_change_mtu;
-	netdev->do_ioctl = &atl1e_ioctl;
-	netdev->tx_timeout = &atl1e_tx_timeout;
+	netdev->netdev_ops = &atl1e_netdev_ops;
+	netdev->hard_start_xmit = atl1e_xmit_frame,
 	netdev->watchdog_timeo = AT_TX_WATCHDOG;
-	netdev->vlan_rx_register = atl1e_vlan_rx_register;
-#ifdef CONFIG_NET_POLL_CONTROLLER
-	netdev->poll_controller = atl1e_netpoll;
-#endif
 	atl1e_set_ethtool_ops(netdev);
 
 	netdev->features = NETIF_F_SG | NETIF_F_HW_CSUM |
#48 lore raw

PATCH 20/33 atlx: convert to net_device_ops

In reply to Stephen Hemminger

Convert this driver to network device ops. Compile tested only.

drivers/net/atlx/atl1.c +16 -12
@@ -2880,6 +2880,21 @@ static void atl1_poll_controller(struct 
 }
 #endif
 
+static const struct net_device_ops atl1_netdev_ops = {
+	.open		    = atl1_open,
+	.stop		    = atl1_close,
+	.set_multicast_list = atlx_set_multi,
+	.validate_addr	    = eth_validate_addr,
+	.set_mac_address    = atl1_set_mac,
+	.change_mtu	    = atl1_change_mtu,
+	.do_ioctl	    = atlx_ioctl,
+	.tx_timeout	    = atlx_tx_timeout,
+	.vlan_rx_register   = atlx_vlan_rx_register,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+	.poll_controller    = atl1_poll_controller,
+#endif
+};
+
 /*
  * atl1_probe - Device Initialization Routine
  * @pdev: PCI device information struct
@@ -2967,20 +2982,9 @@ static int __devinit atl1_probe(struct p
 	adapter->mii.phy_id_mask = 0x1f;
 	adapter->mii.reg_num_mask = 0x1f;
 
-	netdev->open = &atl1_open;
-	netdev->stop = &atl1_close;
+	netdev->netdev_ops = &atl1_netdev_ops;
 	netdev->hard_start_xmit = &atl1_xmit_frame;
-
-	netdev->set_multicast_list = &atlx_set_multi;
-	netdev->set_mac_address = &atl1_set_mac;
-	netdev->change_mtu = &atl1_change_mtu;
-	netdev->do_ioctl = &atlx_ioctl;
-	netdev->tx_timeout = &atlx_tx_timeout;
 	netdev->watchdog_timeo = 5 * HZ;
-#ifdef CONFIG_NET_POLL_CONTROLLER
-	netdev->poll_controller = atl1_poll_controller;
-#endif
-	netdev->vlan_rx_register = atlx_vlan_rx_register;
 
 	netdev->ethtool_ops = &atl1_ethtool_ops;
 	adapter->bd_number = cards_found;
drivers/net/atlx/atl2.c +17 -16
@@ -1311,6 +1311,22 @@ static void atl2_poll_controller(struct 
 }
 #endif
 
+
+static const struct net_device_ops atl2_netdev_ops = {
+	.open		    = atl2_open,
+	.stop		    = atl2_close,
+	.set_multicast_list = atl2_set_multi,
+	.validate_addr	    = eth_validate_addr,
+	.set_mac_address    = atl2_set_mac,
+	.change_mtu	    = atl2_change_mtu,
+	.do_ioctl	    = atl2_ioctl,
+	.tx_timeout	    = atl2_tx_timeout,
+	.vlan_rx_register   = atl2_vlan_rx_register,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+	.poll_controller    = atl2_poll_controller,
+#endif
+};
+
 /*
  * atl2_probe - Device Initialization Routine
  * @pdev: PCI device information struct
@@ -1384,25 +1400,10 @@ static int __devinit atl2_probe(struct p
 
 	atl2_setup_pcicmd(pdev);
 
-	netdev->open = &atl2_open;
-	netdev->stop = &atl2_close;
 	netdev->hard_start_xmit = &atl2_xmit_frame;
-	netdev->set_multicast_list = &atl2_set_multi;
-	netdev->set_mac_address = &atl2_set_mac;
-	netdev->change_mtu = &atl2_change_mtu;
-	netdev->do_ioctl = &atl2_ioctl;
+	netdev->netdev_ops = &atl2_netdev_ops;
 	atl2_set_ethtool_ops(netdev);
-
-#ifdef CONFIG_NET_POLL_CONTROLLER
-	netdev->poll_controller = atl2_poll_controller;
-#endif
-#ifdef HAVE_TX_TIMEOUT
-	netdev->tx_timeout = &atl2_tx_timeout;
 	netdev->watchdog_timeo = 5 * HZ;
-#endif
-#ifdef NETIF_F_HW_VLAN_TX
-	netdev->vlan_rx_register = atl2_vlan_rx_register;
-#endif
 	strncpy(netdev->name, pci_name(pdev), sizeof(netdev->name) - 1);
 
 	netdev->mem_start = mmio_start;
#50 lore raw

PATCH 21/33 cxgb3: convert to net_device_ops

In reply to Stephen Hemminger

Convert this driver to network device ops. Compile tested only.

drivers/net/cxgb3/cxgb3_main.c +16 -13
@@ -2826,6 +2826,21 @@ static void __devinit print_port_info(st
 	}
 }
 
+static const struct net_device_ops cxgb_netdev_ops = {
+	.open = cxgb_open,
+	.stop = cxgb_close,
+	.get_stats = cxgb_get_stats,
+	.validate_addr	= eth_validate_addr,
+	.set_multicast_list = cxgb_set_rxmode,
+	.do_ioctl = cxgb_ioctl,
+	.change_mtu = cxgb_change_mtu,
+	.set_mac_address = cxgb_set_mac_addr,
+	.vlan_rx_register = vlan_rx_register,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+	.poll_controller = cxgb_netpoll,
+#endif
+};
+
 static int __devinit init_one(struct pci_dev *pdev,
 			      const struct pci_device_id *ent)
 {
@@ -2937,20 +2952,8 @@ static int __devinit init_one(struct pci
 			netdev->features |= NETIF_F_HIGHDMA;
 
 		netdev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX;
-		netdev->vlan_rx_register = vlan_rx_register;
-
-		netdev->open = cxgb_open;
-		netdev->stop = cxgb_close;
+		netdev->netdev_ops = &cxgb_netdev_ops;
 		netdev->hard_start_xmit = t3_eth_xmit;
-		netdev->get_stats = cxgb_get_stats;
-		netdev->set_multicast_list = cxgb_set_rxmode;
-		netdev->do_ioctl = cxgb_ioctl;
-		netdev->change_mtu = cxgb_change_mtu;
-		netdev->set_mac_address = cxgb_set_mac_addr;
-#ifdef CONFIG_NET_POLL_CONTROLLER
-		netdev->poll_controller = cxgb_netpoll;
-#endif
-
 		SET_ETHTOOL_OPS(netdev, &cxgb_ethtool_ops);
 	}
 
#52 lore raw

PATCH 22/33 cxgb2: convert to net_device_ops

In reply to Stephen Hemminger

Convert this driver to network device ops. Compile tested only.

drivers/net/chelsio/cxgb2.c +17 -11
@@ -1010,6 +1010,21 @@ void t1_fatal_err(struct adapter *adapte
 		 adapter->name);
 }
 
+static const struct net_device_ops cxgb_netdev_ops = {
+	.open = cxgb_open,
+	.stop = cxgb_close,
+	.get_stats = t1_get_stats,
+	.validate_addr	= eth_validate_addr,
+	.set_multicast_list = t1_set_rxmode,
+	.do_ioctl = t1_ioctl,
+	.change_mtu = t1_change_mtu,
+	.set_mac_address = t1_set_mac_addr,
+	.vlan_rx_register = vlan_rx_register,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+	.poll_controller = t1_netpoll,
+#endif
+};
+
 static int __devinit init_one(struct pci_dev *pdev,
 			      const struct pci_device_id *ent)
 {
@@ -1130,7 +1145,6 @@ static int __devinit init_one(struct pci
 			adapter->flags |= VLAN_ACCEL_CAPABLE;
 			netdev->features |=
 				NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX;
-			netdev->vlan_rx_register = vlan_rx_register;
 #endif
 
 			/* T204: disable TSO */
@@ -1140,19 +1154,11 @@ static int __devinit init_one(struct pci
 			}
 		}
 
-		netdev->open = cxgb_open;
-		netdev->stop = cxgb_close;
+		netdev->netdev_ops = &cxgb_netdev_ops;
 		netdev->hard_start_xmit = t1_start_xmit;
 		netdev->hard_header_len += (adapter->flags & TSO_CAPABLE) ?
 			sizeof(struct cpl_tx_pkt_lso) : sizeof(struct cpl_tx_pkt);
-		netdev->get_stats = t1_get_stats;
-		netdev->set_multicast_list = t1_set_rxmode;
-		netdev->do_ioctl = t1_ioctl;
-		netdev->change_mtu = t1_change_mtu;
-		netdev->set_mac_address = t1_set_mac_addr;
-#ifdef CONFIG_NET_POLL_CONTROLLER
-		netdev->poll_controller = t1_netpoll;
-#endif
+
 		netif_napi_add(netdev, &adapter->napi, t1_poll, 64);
 
 		SET_ETHTOOL_OPS(netdev, &t1_ethtool_ops);
#53 lore raw

Re: [PATCH 22/33] cxgb2: convert to net_device_ops

Convert this driver to network device ops. Compile teseted only.

---
Need to handle non-vlan cas as well.

drivers/net/chelsio/cxgb2.c +19 -11
@@ -1010,6 +1010,23 @@ void t1_fatal_err(struct adapter *adapte
 		 adapter->name);
 }
 
+static const struct net_device_ops cxgb_netdev_ops = {
+	.open = cxgb_open,
+	.stop = cxgb_close,
+	.get_stats = t1_get_stats,
+	.validate_addr	= eth_validate_addr,
+	.set_multicast_list = t1_set_rxmode,
+	.do_ioctl = t1_ioctl,
+	.change_mtu = t1_change_mtu,
+	.set_mac_address = t1_set_mac_addr,
+#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE)
+	.vlan_rx_register = vlan_rx_register,
+#endif
+#ifdef CONFIG_NET_POLL_CONTROLLER
+	.poll_controller = t1_netpoll,
+#endif
+};
+
 static int __devinit init_one(struct pci_dev *pdev,
 			      const struct pci_device_id *ent)
 {
@@ -1130,7 +1147,6 @@ static int __devinit init_one(struct pci
 			adapter->flags |= VLAN_ACCEL_CAPABLE;
 			netdev->features |=
 				NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX;
-			netdev->vlan_rx_register = vlan_rx_register;
 #endif
 
 			/* T204: disable TSO */
@@ -1140,19 +1156,11 @@ static int __devinit init_one(struct pci
 			}
 		}
 
-		netdev->open = cxgb_open;
-		netdev->stop = cxgb_close;
+		netdev->netdev_ops = &cxgb_netdev_ops;
 		netdev->hard_start_xmit = t1_start_xmit;
 		netdev->hard_header_len += (adapter->flags & TSO_CAPABLE) ?
 			sizeof(struct cpl_tx_pkt_lso) : sizeof(struct cpl_tx_pkt);
-		netdev->get_stats = t1_get_stats;
-		netdev->set_multicast_list = t1_set_rxmode;
-		netdev->do_ioctl = t1_ioctl;
-		netdev->change_mtu = t1_change_mtu;
-		netdev->set_mac_address = t1_set_mac_addr;
-#ifdef CONFIG_NET_POLL_CONTROLLER
-		netdev->poll_controller = t1_netpoll;
-#endif
+
 		netif_napi_add(netdev, &adapter->napi, t1_poll, 64);
 
 		SET_ETHTOOL_OPS(netdev, &t1_ethtool_ops);
#55 lore raw

PATCH 23/33 e1000: convert to net_device_ops

In reply to Stephen Hemminger

Convert to new network device ops interface.

drivers/net/e1000/e1000_main.c +21 -14
@@ -888,6 +888,25 @@ static int e1000_is_need_ioport(struct p
 	}
 }
 
+static const struct net_device_ops e1000_netdev_ops = {
+	.open		= e1000_open,
+	.stop		= e1000_close,
+	.get_stats	= e1000_get_stats,
+	.set_rx_mode	= e1000_set_rx_mode,
+	.set_mac_address = e1000_set_mac,
+	.tx_timeout 	= e1000_tx_timeout,
+	.change_mtu	= e1000_change_mtu,
+	.do_ioctl	= e1000_ioctl,
+	.validate_addr	= eth_validate_addr,
+
+	.vlan_rx_register = e1000_vlan_rx_register,
+	.vlan_rx_add_vid = e1000_vlan_rx_add_vid,
+	.vlan_rx_kill_vid = e1000_vlan_rx_kill_vid,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+	.poll_controller = e1000_netpoll,
+#endif
+};
+
 /**
  * e1000_probe - Device Initialization Routine
  * @pdev: PCI device information struct
@@ -981,24 +1000,12 @@ static int __devinit e1000_probe(struct 
 		}
 	}
 
-	netdev->open = &e1000_open;
-	netdev->stop = &e1000_close;
+	netdev->netdev_ops = &e1000_netdev_ops;
 	netdev->hard_start_xmit = &e1000_xmit_frame;
-	netdev->get_stats = &e1000_get_stats;
-	netdev->set_rx_mode = &e1000_set_rx_mode;
-	netdev->set_mac_address = &e1000_set_mac;
-	netdev->change_mtu = &e1000_change_mtu;
-	netdev->do_ioctl = &e1000_ioctl;
 	e1000_set_ethtool_ops(netdev);
-	netdev->tx_timeout = &e1000_tx_timeout;
 	netdev->watchdog_timeo = 5 * HZ;
 	netif_napi_add(netdev, &adapter->napi, e1000_clean, 64);
-	netdev->vlan_rx_register = e1000_vlan_rx_register;
-	netdev->vlan_rx_add_vid = e1000_vlan_rx_add_vid;
-	netdev->vlan_rx_kill_vid = e1000_vlan_rx_kill_vid;
-#ifdef CONFIG_NET_POLL_CONTROLLER
-	netdev->poll_controller = e1000_netpoll;
-#endif
+
 	strncpy(netdev->name, pci_name(pdev), sizeof(netdev->name) - 1);
 
 	adapter->bd_number = cards_found;
#57 lore raw

PATCH 24/33 via-velocity: convert to net_device_ops

In reply to Stephen Hemminger

Convert this driver to network device ops. Compile tested only.

drivers/net/via-velocity.c +14 -10
@@ -849,6 +849,19 @@ static int velocity_soft_reset(struct ve
 	return 0;
 }
 
+static const struct net_device_ops velocity_netdev_ops = {
+	.open = velocity_open,
+	.stop = velocity_close,
+	.get_stats = velocity_get_stats,
+	.validate_addr	= eth_validate_addr,
+	.set_multicast_list = velocity_set_multi,
+	.change_mtu = velocity_change_mtu,
+	.do_ioctl = velocity_ioctl,
+	.vlan_rx_add_vid = velocity_vlan_rx_add_vid,
+	.vlan_rx_kill_vid = velocity_vlan_rx_kill_vid,
+	.vlan_rx_register = velocity_vlan_rx_register,
+};
+
 /**
  *	velocity_found1		-	set up discovered velocity card
  *	@pdev: PCI device
@@ -958,18 +971,9 @@ static int __devinit velocity_found1(str
 	vptr->phy_id = MII_GET_PHY_ID(vptr->mac_regs);
 
 	dev->irq = pdev->irq;
-	dev->open = velocity_open;
 	dev->hard_start_xmit = velocity_xmit;
-	dev->stop = velocity_close;
-	dev->get_stats = velocity_get_stats;
-	dev->set_multicast_list = velocity_set_multi;
-	dev->do_ioctl = velocity_ioctl;
+	dev->netdev_ops = &velocity_netdev_ops;
 	dev->ethtool_ops = &velocity_ethtool_ops;
-	dev->change_mtu = velocity_change_mtu;
-
-	dev->vlan_rx_add_vid = velocity_vlan_rx_add_vid;
-	dev->vlan_rx_kill_vid = velocity_vlan_rx_kill_vid;
-	dev->vlan_rx_register = velocity_vlan_rx_register;
 
 #ifdef  VELOCITY_ZERO_COPY_SUPPORT
 	dev->features |= NETIF_F_SG;
#59 lore raw

PATCH 25/33 igb: convert to net_device_ops

In reply to Stephen Hemminger

Convert to new network device ops interface. Compile tested only.

drivers/net/igb/igb_main.c +19 -14
@@ -950,6 +950,24 @@ static int igb_is_need_ioport(struct pci
 	}
 }
 
+static const struct net_device_ops igb_netdev_ops = {
+	.open 		= igb_open,
+	.stop		= igb_close,
+	.get_stats	= igb_get_stats,
+	.set_multicast_list = igb_set_multi,
+	.set_mac_address = igb_set_mac,
+	.change_mtu	= igb_change_mtu,
+	.do_ioctl	= igb_ioctl,
+	.tx_timeout	= igb_tx_timeout,
+	.validate_addr	= eth_validate_addr,
+	.vlan_rx_register = igb_vlan_rx_register,
+	.vlan_rx_add_vid = igb_vlan_rx_add_vid,
+	.vlan_rx_kill_vid = igb_vlan_rx_kill_vid,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+	.poll_controller = igb_netpoll,
+#endif
+};
+
 /**
  * igb_probe - Device Initialization Routine
  * @pdev: PCI device information struct
@@ -1060,22 +1078,9 @@ static int __devinit igb_probe(struct pc
 	if (!adapter->hw.hw_addr)
 		goto err_ioremap;
 
-	netdev->open = &igb_open;
-	netdev->stop = &igb_close;
-	netdev->get_stats = &igb_get_stats;
-	netdev->set_multicast_list = &igb_set_multi;
-	netdev->set_mac_address = &igb_set_mac;
-	netdev->change_mtu = &igb_change_mtu;
-	netdev->do_ioctl = &igb_ioctl;
+	netdev->netdev_ops = &igb_netdev_ops;
 	igb_set_ethtool_ops(netdev);
-	netdev->tx_timeout = &igb_tx_timeout;
 	netdev->watchdog_timeo = 5 * HZ;
-	netdev->vlan_rx_register = igb_vlan_rx_register;
-	netdev->vlan_rx_add_vid = igb_vlan_rx_add_vid;
-	netdev->vlan_rx_kill_vid = igb_vlan_rx_kill_vid;
-#ifdef CONFIG_NET_POLL_CONTROLLER
-	netdev->poll_controller = igb_netpoll;
-#endif
 	netdev->hard_start_xmit = &igb_xmit_frame_adv;
 
 	strncpy(netdev->name, pci_name(pdev), sizeof(netdev->name) - 1);
#61 lore raw

PATCH 26/33 e100: convert to net_device_ops

In reply to Stephen Hemminger

Convert to new network device ops interface. Compile tested only.

drivers/net/e100.c +16 -11
@@ -2612,6 +2612,20 @@ static int e100_close(struct net_device 
 	return 0;
 }
 
+static const struct net_device_ops e100_netdev_ops = {
+	.open			= e100_open,
+	.stop			= e100_close,
+	.validate_addr		= eth_validate_addr,
+	.set_multicast_list	= e100_set_multicast_list,
+	.set_mac_address	= e100_set_mac_address,
+	.change_mtu		= e100_change_mtu,
+	.do_ioctl		= e100_do_ioctl,
+	.tx_timeout		= e100_tx_timeout,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+	.poll_controller	= e100_netpoll,
+#endif
+};
+
 static int __devinit e100_probe(struct pci_dev *pdev,
 	const struct pci_device_id *ent)
 {
@@ -2625,19 +2639,10 @@ static int __devinit e100_probe(struct p
 		return -ENOMEM;
 	}
 
-	netdev->open = e100_open;
-	netdev->stop = e100_close;
+	netdev->netdev_ops = &e100_netdev_ops;
 	netdev->hard_start_xmit = e100_xmit_frame;
-	netdev->set_multicast_list = e100_set_multicast_list;
-	netdev->set_mac_address = e100_set_mac_address;
-	netdev->change_mtu = e100_change_mtu;
-	netdev->do_ioctl = e100_do_ioctl;
 	SET_ETHTOOL_OPS(netdev, &e100_ethtool_ops);
-	netdev->tx_timeout = e100_tx_timeout;
 	netdev->watchdog_timeo = E100_WATCHDOG_PERIOD;
-#ifdef CONFIG_NET_POLL_CONTROLLER
-	netdev->poll_controller = e100_netpoll;
-#endif
 	strncpy(netdev->name, pci_name(pdev), sizeof(netdev->name) - 1);
 
 	nic = netdev_priv(netdev);
@@ -2845,7 +2850,7 @@ static pci_ers_result_t e100_io_error_de
 	struct nic *nic = netdev_priv(netdev);
 
 	/* Similar to calling e100_down(), but avoids adapter I/O. */
-	netdev->stop(netdev);
+	e100_close(netdev);
 
 	/* Detach; put netif into a state similar to hotplug unplug. */
 	napi_enable(&nic->napi);
#63 lore raw

PATCH 27/33 ppp: convert to net_device_ops

In reply to Stephen Hemminger

Convert this driver to network device ops. Compile tested only.

drivers/net/ppp_generic.c +5 -1
@@ -971,8 +971,13 @@ ppp_net_ioctl(struct net_device *dev, st
 	return err;
 }
 
+static const struct net_device_ops ppp_netdev_ops = {
+	.do_ioctl = ppp_net_ioctl,
+};
+
 static void ppp_setup(struct net_device *dev)
 {
+	dev->netdev_ops = &ppp_netdev_ops;
 	dev->hard_header_len = PPP_HDRLEN;
 	dev->mtu = PPP_MTU;
 	dev->addr_len = 0;
@@ -2436,7 +2441,6 @@ ppp_create_interface(int unit, int *retp
 	dev->priv = ppp;
 
 	dev->hard_start_xmit = ppp_start_xmit;
-	dev->do_ioctl = ppp_net_ioctl;
 
 	ret = -EEXIST;
 	mutex_lock(&all_ppp_mutex);
#65 lore raw

PATCH 28/33 enic: convert to net_device_ops

In reply to Stephen Hemminger

Convert this driver to network device ops. Compile tested only.

drivers/net/enic/enic_main.c +17 -12
@@ -1590,6 +1590,22 @@ static void enic_iounmap(struct enic *en
 		iounmap(enic->bar0.vaddr);
 }
 
+static const struct net_device_ops enic_netdev_ops = {
+	.open = enic_open,
+	.stop = enic_stop,
+	.get_stats = enic_get_stats,
+	.validate_addr = eth_validate_addr,
+	.set_multicast_list = enic_set_multicast_list,
+	.change_mtu = enic_change_mtu,
+	.vlan_rx_register = enic_vlan_rx_register,
+	.vlan_rx_add_vid = enic_vlan_rx_add_vid,
+	.vlan_rx_kill_vid = enic_vlan_rx_kill_vid,
+	.tx_timeout = enic_tx_timeout,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+	.poll_controller = enic_poll_controller,
+#endif
+};
+
 static int __devinit enic_probe(struct pci_dev *pdev,
 	const struct pci_device_id *ent)
 {
@@ -1813,21 +1829,10 @@ static int __devinit enic_probe(struct p
 		goto err_out_free_vnic_resources;
 	}
 
-	netdev->open = enic_open;
-	netdev->stop = enic_stop;
+	netdev->netdev_ops = &enic_netdev_ops;
 	netdev->hard_start_xmit = enic_hard_start_xmit;
-	netdev->get_stats = enic_get_stats;
-	netdev->set_multicast_list = enic_set_multicast_list;
-	netdev->change_mtu = enic_change_mtu;
-	netdev->vlan_rx_register = enic_vlan_rx_register;
-	netdev->vlan_rx_add_vid = enic_vlan_rx_add_vid;
-	netdev->vlan_rx_kill_vid = enic_vlan_rx_kill_vid;
-	netdev->tx_timeout = enic_tx_timeout;
 	netdev->watchdog_timeo = 2 * HZ;
 	netdev->ethtool_ops = &enic_ethtool_ops;
-#ifdef CONFIG_NET_POLL_CONTROLLER
-	netdev->poll_controller = enic_poll_controller;
-#endif
 
 	switch (vnic_dev_get_intr_mode(enic->vdev)) {
 	default:
#67 lore raw

PATCH 29/33 ixgb: convert to net_device_ops

In reply to Stephen Hemminger

Convert this driver to network device ops. Compile tested only.

drivers/net/ixgb/ixgb_main.c +18 -13
@@ -321,6 +321,23 @@ ixgb_reset(struct ixgb_adapter *adapter)
 	}
 }
 
+static const struct net_device_ops ixgb_netdev_ops = {
+	.open 			= ixgb_open,
+	.stop			= ixgb_close,
+	.get_stats		= ixgb_get_stats,
+	.set_multicast_list	= ixgb_set_multi,
+	.validate_addr		= eth_validate_addr,
+	.set_mac_address	= ixgb_set_mac,
+	.change_mtu		= ixgb_change_mtu,
+	.tx_timeout		= ixgb_tx_timeout,
+	.vlan_rx_register	= ixgb_vlan_rx_register,
+	.vlan_rx_add_vid	= ixgb_vlan_rx_add_vid,
+	.vlan_rx_kill_vid	= ixgb_vlan_rx_kill_vid,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+	.poll_controller	= ixgb_netpoll,
+#endif
+};
+
 /**
  * ixgb_probe - Device Initialization Routine
  * @pdev: PCI device information struct
@@ -396,23 +413,11 @@ ixgb_probe(struct pci_dev *pdev, const s
 		}
 	}
 
-	netdev->open = &ixgb_open;
-	netdev->stop = &ixgb_close;
+	netdev->netdev_ops = &ixgb_netdev_ops;
 	netdev->hard_start_xmit = &ixgb_xmit_frame;
-	netdev->get_stats = &ixgb_get_stats;
-	netdev->set_multicast_list = &ixgb_set_multi;
-	netdev->set_mac_address = &ixgb_set_mac;
-	netdev->change_mtu = &ixgb_change_mtu;
 	ixgb_set_ethtool_ops(netdev);
-	netdev->tx_timeout = &ixgb_tx_timeout;
 	netdev->watchdog_timeo = 5 * HZ;
 	netif_napi_add(netdev, &adapter->napi, ixgb_clean, 64);
-	netdev->vlan_rx_register = ixgb_vlan_rx_register;
-	netdev->vlan_rx_add_vid = ixgb_vlan_rx_add_vid;
-	netdev->vlan_rx_kill_vid = ixgb_vlan_rx_kill_vid;
-#ifdef CONFIG_NET_POLL_CONTROLLER
-	netdev->poll_controller = ixgb_netpoll;
-#endif
 
 	strncpy(netdev->name, pci_name(pdev), sizeof(netdev->name) - 1);
 
drivers/net/ixgbe/ixgbe_main.c +18 -14
@@ -3727,6 +3727,23 @@ static int ixgbe_link_config(struct ixgb
 	return hw->mac.ops.setup_link_speed(hw, autoneg, true, true);
 }
 
+static const struct net_device_ops ixgbe_netdev_ops = {
+	.open 			= ixgbe_open,
+	.stop			= ixgbe_close,
+	.get_stats		= ixgbe_get_stats,
+	.set_multicast_list	= ixgbe_set_rx_mode,
+	.validate_addr		= eth_validate_addr,
+	.set_mac_address	= ixgbe_set_mac,
+	.change_mtu		= ixgbe_change_mtu,
+	.tx_timeout		= ixgbe_tx_timeout,
+	.vlan_rx_register	= ixgbe_vlan_rx_register,
+	.vlan_rx_add_vid	= ixgbe_vlan_rx_add_vid,
+	.vlan_rx_kill_vid	= ixgbe_vlan_rx_kill_vid,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+	.poll_controller	= ixgbe_netpoll,
+#endif
+};
+
 /**
  * ixgbe_probe - Device Initialization Routine
  * @pdev: PCI device information struct
@@ -3808,23 +3825,10 @@ static int __devinit ixgbe_probe(struct 
 			continue;
 	}
 
-	netdev->open = &ixgbe_open;
-	netdev->stop = &ixgbe_close;
+	netdev->netdev_ops = &ixgbe_netdev_ops;
 	netdev->hard_start_xmit = &ixgbe_xmit_frame;
-	netdev->get_stats = &ixgbe_get_stats;
-	netdev->set_rx_mode = &ixgbe_set_rx_mode;
-	netdev->set_multicast_list = &ixgbe_set_rx_mode;
-	netdev->set_mac_address = &ixgbe_set_mac;
-	netdev->change_mtu = &ixgbe_change_mtu;
 	ixgbe_set_ethtool_ops(netdev);
-	netdev->tx_timeout = &ixgbe_tx_timeout;
 	netdev->watchdog_timeo = 5 * HZ;
-	netdev->vlan_rx_register = ixgbe_vlan_rx_register;
-	netdev->vlan_rx_add_vid = ixgbe_vlan_rx_add_vid;
-	netdev->vlan_rx_kill_vid = ixgbe_vlan_rx_kill_vid;
-#ifdef CONFIG_NET_POLL_CONTROLLER
-	netdev->poll_controller = ixgbe_netpoll;
-#endif
 	strcpy(netdev->name, pci_name(pdev));
 
 	adapter->bd_number = cards_found;
#69 lore raw

PATCH 30/33 tg3: convert to net_device_ops

In reply to Stephen Hemminger

Convert this driver to network device ops.

drivers/net/tg3.c +17 -12
@@ -13343,6 +13343,22 @@ static void __devinit tg3_init_coal(stru
 	}
 }
 
+static const struct net_device_ops tg3_netdev_ops = {
+	.open			= tg3_open,
+	.stop			= tg3_close,
+	.get_stats		= tg3_get_stats,
+	.validate_addr		= eth_validate_addr,
+	.set_multicast_list	= tg3_set_rx_mode,
+	.set_mac_address	= tg3_set_mac_addr,
+	.do_ioctl		= tg3_ioctl,
+	.tx_timeout		= tg3_tx_timeout,
+	.change_mtu		= tg3_change_mtu,
+	.vlan_rx_register	= tg3_vlan_rx_register,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+	.poll_controller	= tg3_poll_controller,
+#endif
+};
+
 static int __devinit tg3_init_one(struct pci_dev *pdev,
 				  const struct pci_device_id *ent)
 {
@@ -13400,7 +13416,6 @@ static int __devinit tg3_init_one(struct
 
 #if TG3_VLAN_TAG_USED
 	dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX;
-	dev->vlan_rx_register = tg3_vlan_rx_register;
 #endif
 
 	tp = netdev_priv(dev);
@@ -13458,21 +13473,11 @@ static int __devinit tg3_init_one(struct
 	tp->rx_jumbo_pending = TG3_DEF_RX_JUMBO_RING_PENDING;
 	tp->tx_pending = TG3_DEF_TX_RING_PENDING;
 
-	dev->open = tg3_open;
-	dev->stop = tg3_close;
-	dev->get_stats = tg3_get_stats;
-	dev->set_multicast_list = tg3_set_rx_mode;
-	dev->set_mac_address = tg3_set_mac_addr;
-	dev->do_ioctl = tg3_ioctl;
-	dev->tx_timeout = tg3_tx_timeout;
+	dev->netdev_ops = &tg3_netdev_ops;
 	netif_napi_add(dev, &tp->napi, tg3_poll, 64);
 	dev->ethtool_ops = &tg3_ethtool_ops;
 	dev->watchdog_timeo = TG3_TX_TIMEOUT;
-	dev->change_mtu = tg3_change_mtu;
 	dev->irq = pdev->irq;
-#ifdef CONFIG_NET_POLL_CONTROLLER
-	dev->poll_controller = tg3_poll_controller;
-#endif
 
 	err = tg3_get_invariants(tp);
 	if (err) {
#70 lore raw

Re: [PATCH 30/33] tg3: convert to net_device_ops

Quoted 30 lines · Stephen Hemminger

Convert this driver to network device ops.

drivers/net/tg3.c +16 -0
@@ -13343,6 +13343,22 @@ static void __devinit tg3_init_coal(stru
 	}
 }
 
+static const struct net_device_ops tg3_netdev_ops = {
+	.open			= tg3_open,
+	.stop			= tg3_close,
+	.get_stats		= tg3_get_stats,
+	.validate_addr		= eth_validate_addr,
+	.set_multicast_list	= tg3_set_rx_mode,
+	.set_mac_address	= tg3_set_mac_addr,
+	.do_ioctl		= tg3_ioctl,
+	.tx_timeout		= tg3_tx_timeout,
+	.change_mtu		= tg3_change_mtu,
+	.vlan_rx_register	= tg3_vlan_rx_register,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+	.poll_controller	= tg3_poll_controller,
+#endif
+};
+
 static int __devinit tg3_init_one(struct pci_dev *pdev,
 				  const struct pci_device_id *ent)
 {

drivers/net/tg3.c static int __devinit tg3_init_one(struct · line 13419

Quoted 5 lines
drivers/net/tg3.c +0 -1
@@ -13400,7 +13416,6 @@ static int __devinit tg3_init_one(struct
 
 #if TG3_VLAN_TAG_USED
 	dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX;
-	dev->vlan_rx_register = tg3_vlan_rx_register;
 #endif

The tg3_vlan_rx_register() function is only defined if CONFIG_VLAN_8021Q or CONFIG_VLAN_8021Q_MODULE is defined. You will need to either surround the .vlan_rx_register declaration with TG3_VLAN_TAG_USED or move the TG3_VLAN_TAG_USED preprocessor guards inside the body of tg3_vlan_rx_register().

Quoted 32 lines
drivers/net/tg3.c +1 -11
 	tp = netdev_priv(dev);
@@ -13458,21 +13473,11 @@ static int __devinit tg3_init_one(struct
 	tp->rx_jumbo_pending = TG3_DEF_RX_JUMBO_RING_PENDING;
 	tp->tx_pending = TG3_DEF_TX_RING_PENDING;
 
-	dev->open = tg3_open;
-	dev->stop = tg3_close;
-	dev->get_stats = tg3_get_stats;
-	dev->set_multicast_list = tg3_set_rx_mode;
-	dev->set_mac_address = tg3_set_mac_addr;
-	dev->do_ioctl = tg3_ioctl;
-	dev->tx_timeout = tg3_tx_timeout;
+	dev->netdev_ops = &tg3_netdev_ops;
 	netif_napi_add(dev, &tp->napi, tg3_poll, 64);
 	dev->ethtool_ops = &tg3_ethtool_ops;
 	dev->watchdog_timeo = TG3_TX_TIMEOUT;
-	dev->change_mtu = tg3_change_mtu;
 	dev->irq = pdev->irq;
-#ifdef CONFIG_NET_POLL_CONTROLLER
-	dev->poll_controller = tg3_poll_controller;
-#endif
 
 	err = tg3_get_invariants(tp);
 	if (err) {
Signature · 6 lines
-- 

--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
#71 lore raw

Re: [PATCH 30/33] tg3: convert to net_device_ops

In reply to Stephen Hemminger

Convert this driver to network device ops.

---
Handle non-vlan build.

drivers/net/tg3.c +19 -12
@@ -13343,6 +13343,24 @@ static void __devinit tg3_init_coal(stru
 	}
 }
 
+static const struct net_device_ops tg3_netdev_ops = {
+	.open			= tg3_open,
+	.stop			= tg3_close,
+	.get_stats		= tg3_get_stats,
+	.validate_addr		= eth_validate_addr,
+	.set_multicast_list	= tg3_set_rx_mode,
+	.set_mac_address	= tg3_set_mac_addr,
+	.do_ioctl		= tg3_ioctl,
+	.tx_timeout		= tg3_tx_timeout,
+	.change_mtu		= tg3_change_mtu,
+#if TG3_VLAN_TAG_USED
+	.vlan_rx_register	= tg3_vlan_rx_register,
+#endif
+#ifdef CONFIG_NET_POLL_CONTROLLER
+	.poll_controller	= tg3_poll_controller,
+#endif
+};
+
 static int __devinit tg3_init_one(struct pci_dev *pdev,
 				  const struct pci_device_id *ent)
 {
@@ -13400,7 +13418,6 @@ static int __devinit tg3_init_one(struct
 
 #if TG3_VLAN_TAG_USED
 	dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX;
-	dev->vlan_rx_register = tg3_vlan_rx_register;
 #endif
 
 	tp = netdev_priv(dev);
@@ -13458,21 +13475,11 @@ static int __devinit tg3_init_one(struct
 	tp->rx_jumbo_pending = TG3_DEF_RX_JUMBO_RING_PENDING;
 	tp->tx_pending = TG3_DEF_TX_RING_PENDING;
 
-	dev->open = tg3_open;
-	dev->stop = tg3_close;
-	dev->get_stats = tg3_get_stats;
-	dev->set_multicast_list = tg3_set_rx_mode;
-	dev->set_mac_address = tg3_set_mac_addr;
-	dev->do_ioctl = tg3_ioctl;
-	dev->tx_timeout = tg3_tx_timeout;
+	dev->netdev_ops = &tg3_netdev_ops;
 	netif_napi_add(dev, &tp->napi, tg3_poll, 64);
 	dev->ethtool_ops = &tg3_ethtool_ops;
 	dev->watchdog_timeo = TG3_TX_TIMEOUT;
-	dev->change_mtu = tg3_change_mtu;
 	dev->irq = pdev->irq;
-#ifdef CONFIG_NET_POLL_CONTROLLER
-	dev->poll_controller = tg3_poll_controller;
-#endif
 
 	err = tg3_get_invariants(tp);
 	if (err) {
#72 lore raw

Re: [PATCH 30/33] tg3: convert to net_device_ops

Quoted 10 lines · Stephen Hemminger

Convert this driver to network device ops.

---
Handle non-vlan build.

drivers/net/tg3.c static void __devinit tg3_init_coal(stru · line 13348

Quoted 6 lines
drivers/net/tg3.c +3 -0
@@ -13343,6 +13343,24 @@ static void __devinit tg3_init_coal(stru
 	}
 }
 
+static const struct net_device_ops tg3_netdev_ops = {
+	.open			= tg3_open,
+	.stop			= tg3_close,

One more completely trivial nit. Is there a reason why you chose the verbs to be "open" and "stop" rather than "open" and "close" or "start" and "stop"?

Quoted 54 lines
drivers/net/tg3.c +16 -13
+	.get_stats		= tg3_get_stats,
+	.validate_addr		= eth_validate_addr,
+	.set_multicast_list	= tg3_set_rx_mode,
+	.set_mac_address	= tg3_set_mac_addr,
+	.do_ioctl		= tg3_ioctl,
+	.tx_timeout		= tg3_tx_timeout,
+	.change_mtu		= tg3_change_mtu,
+#if TG3_VLAN_TAG_USED
+	.vlan_rx_register	= tg3_vlan_rx_register,
+#endif
+#ifdef CONFIG_NET_POLL_CONTROLLER
+	.poll_controller	= tg3_poll_controller,
+#endif
+};
+
 static int __devinit tg3_init_one(struct pci_dev *pdev,
 				  const struct pci_device_id *ent)
 {
@@ -13400,7 +13418,6 @@ static int __devinit tg3_init_one(struct
 
 #if TG3_VLAN_TAG_USED
 	dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX;
-	dev->vlan_rx_register = tg3_vlan_rx_register;
 #endif
 
 	tp = netdev_priv(dev);
@@ -13458,21 +13475,11 @@ static int __devinit tg3_init_one(struct
 	tp->rx_jumbo_pending = TG3_DEF_RX_JUMBO_RING_PENDING;
 	tp->tx_pending = TG3_DEF_TX_RING_PENDING;
 
-	dev->open = tg3_open;
-	dev->stop = tg3_close;
-	dev->get_stats = tg3_get_stats;
-	dev->set_multicast_list = tg3_set_rx_mode;
-	dev->set_mac_address = tg3_set_mac_addr;
-	dev->do_ioctl = tg3_ioctl;
-	dev->tx_timeout = tg3_tx_timeout;
+	dev->netdev_ops = &tg3_netdev_ops;
 	netif_napi_add(dev, &tp->napi, tg3_poll, 64);
 	dev->ethtool_ops = &tg3_ethtool_ops;
 	dev->watchdog_timeo = TG3_TX_TIMEOUT;
-	dev->change_mtu = tg3_change_mtu;
 	dev->irq = pdev->irq;
-#ifdef CONFIG_NET_POLL_CONTROLLER
-	dev->poll_controller = tg3_poll_controller;
-#endif
 
 	err = tg3_get_invariants(tp);
 	if (err) {
--

To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html

#73 lore raw

Re: [PATCH 30/33] tg3: convert to net_device_ops

Quoted 14 lines · On Wed, 19 Nov 2008 13:04:47 -0800 "Matt Carlson" <[email protected]> wrote:
Quoted 13 lines · Stephen Hemminger

Convert this driver to network device ops.

---
Handle non-vlan build.

drivers/net/tg3.c +0 -0
@@ -13343,6 +13343,24 @@ static void __devinit tg3_init_coal(stru
 	}
 }
 
Quoted 7 lines

drivers/net/tg3.c static void __devinit tg3_init_coal(stru · line 13348

Quoted 3 lines
drivers/net/tg3.c +3 -0
+static const struct net_device_ops tg3_netdev_ops = {
+	.open			= tg3_open,
+	.stop			= tg3_close,

One more completely trivial nit. Is there a reason why you chose the verbs to be "open" and "stop" rather than "open" and "close" or "start" and "stop"?

Because that is what they were before (but in a different place).

maintainer
#74 lore raw

Re: [PATCH 30/33] tg3: convert to net_device_ops

From: Stephen Hemminger <[email protected]>
Date: Wed, 19 Nov 2008 13:07:27 -0800

Quoted 25 lines
Quoted 14 lines · On Wed, 19 Nov 2008 13:04:47 -0800 "Matt Carlson" <[email protected]> wrote:
Quoted 13 lines · Stephen Hemminger

Convert this driver to network device ops.

---
Handle non-vlan build.

drivers/net/tg3.c +0 -0
@@ -13343,6 +13343,24 @@ static void __devinit tg3_init_coal(stru
 	}
 }
 
Quoted 7 lines

drivers/net/tg3.c static void __devinit tg3_init_coal(stru · line 13348

Quoted 3 lines
drivers/net/tg3.c +3 -0
+static const struct net_device_ops tg3_netdev_ops = {
+	.open			= tg3_open,
+	.stop			= tg3_close,

One more completely trivial nit. Is there a reason why you chose the verbs to be "open" and "stop" rather than "open" and "close" or "start" and "stop"?

Quoted 1 line

Because that is what they were before (but in a different place).

Right.

#76 lore raw

PATCH 31/33 forcedeth: convert to net_device_ops

In reply to Stephen Hemminger

Convert this driver to network device ops. Compile tested only.

drivers/net/forcedeth.c +17 -12
@@ -5408,6 +5408,21 @@ static int nv_close(struct net_device *d
 	return 0;
 }
 
+static const struct net_device_ops nv_netdev_ops = {
+	.open = nv_open,
+	.stop = nv_close,
+	.get_stats = nv_get_stats,
+	.tx_timeout = nv_tx_timeout,
+	.change_mtu = nv_change_mtu,
+	.validate_addr= eth_validate_addr,
+	.set_mac_address = nv_set_mac_address,
+	.set_multicast_list = nv_set_multicast,
+	.vlan_rx_register = nv_vlan_rx_register,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+	.poll_controller = nv_poll_controller,
+#endif
+};
+
 static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_id *id)
 {
 	struct net_device *dev;
@@ -5527,7 +5542,6 @@ static int __devinit nv_probe(struct pci
 	if (id->driver_data & DEV_HAS_VLAN) {
 		np->vlanctl_bits = NVREG_VLANCONTROL_ENABLE;
 		dev->features |= NETIF_F_HW_VLAN_RX | NETIF_F_HW_VLAN_TX;
-		dev->vlan_rx_register = nv_vlan_rx_register;
 	}
 
 	np->msi_flags = 0;
@@ -5577,25 +5591,16 @@ static int __devinit nv_probe(struct pci
 	if (!np->rx_skb || !np->tx_skb)
 		goto out_freering;
 
-	dev->open = nv_open;
-	dev->stop = nv_close;
-
 	if (!nv_optimized(np))
 		dev->hard_start_xmit = nv_start_xmit;
 	else
 		dev->hard_start_xmit = nv_start_xmit_optimized;
-	dev->get_stats = nv_get_stats;
-	dev->change_mtu = nv_change_mtu;
-	dev->set_mac_address = nv_set_mac_address;
-	dev->set_multicast_list = nv_set_multicast;
-#ifdef CONFIG_NET_POLL_CONTROLLER
-	dev->poll_controller = nv_poll_controller;
-#endif
+
+	dev->netdev_ops = &nv_netdev_ops;
 #ifdef CONFIG_FORCEDETH_NAPI
 	netif_napi_add(dev, &np->napi, nv_napi_poll, RX_WORK_PER_LOOP);
 #endif
 	SET_ETHTOOL_OPS(dev, &ops);
-	dev->tx_timeout = nv_tx_timeout;
 	dev->watchdog_timeo = NV_WATCHDOG_TIMEO;
 
 	pci_set_drvdata(pci_dev, dev);
#78 lore raw

PATCH 32/33 niu: convert to net_device_ops

In reply to Stephen Hemminger

Convert this driver to network device ops. Compile tested only (give me hw!)

drivers/net/niu.c +13 -8
@@ -8618,19 +8618,24 @@ static struct net_device * __devinit niu
 	return dev;
 }
 
+static const struct net_device_ops niu_netdev_ops = {
+	.open			= niu_open,
+	.stop			= niu_close,
+	.get_stats		= niu_get_stats,
+	.set_multicast_list	= niu_set_rx_mode,
+	.validate_addr		= eth_validate_addr,
+	.set_mac_address	= niu_set_mac_addr,
+	.do_ioctl		= niu_ioctl,
+	.tx_timeout		= niu_tx_timeout,
+	.change_mtu		= niu_change_mtu,
+};
+
 static void __devinit niu_assign_netdev_ops(struct net_device *dev)
 {
-	dev->open = niu_open;
-	dev->stop = niu_close;
-	dev->get_stats = niu_get_stats;
-	dev->set_multicast_list = niu_set_rx_mode;
-	dev->set_mac_address = niu_set_mac_addr;
-	dev->do_ioctl = niu_ioctl;
-	dev->tx_timeout = niu_tx_timeout;
+	dev->netdev_ops = &niu_netdev_ops;
 	dev->hard_start_xmit = niu_start_xmit;
 	dev->ethtool_ops = &niu_ethtool_ops;
 	dev->watchdog_timeo = NIU_TX_TIMEOUT;
-	dev->change_mtu = niu_change_mtu;
 }
 
 static void __devinit niu_device_announce(struct niu *np)
#80 lore raw

PATCH 33/33 acenic: convert to net_device_ops

In reply to Stephen Hemminger

Convert this driver to network device ops. Compile tested only.

drivers/net/acenic.c +12 -8
@@ -450,6 +450,17 @@ static const struct ethtool_ops ace_etht
 
 static void ace_watchdog(struct net_device *dev);
 
+static const struct net_device_ops ace_netdev_ops = {
+	.open = ace_open,
+	.stop = ace_close,
+	.tx_timeout = ace_watchdog,
+	.get_stats = ace_get_stats,
+	.set_multicast_list = ace_set_multicast_list,
+	.set_mac_address = ace_set_mac_addr,
+	.change_mtu = ace_change_mtu,
+	.vlan_rx_register = ace_vlan_rx_register,
+};
+
 static int __devinit acenic_probe_one(struct pci_dev *pdev,
 		const struct pci_device_id *id)
 {
@@ -473,20 +484,13 @@ static int __devinit acenic_probe_one(st
 	dev->features |= NETIF_F_SG | NETIF_F_IP_CSUM;
 #if ACENIC_DO_VLAN
 	dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX;
-	dev->vlan_rx_register = ace_vlan_rx_register;
 #endif
 
-	dev->tx_timeout = &ace_watchdog;
 	dev->watchdog_timeo = 5*HZ;
 
-	dev->open = &ace_open;
-	dev->stop = &ace_close;
+	dev->netdev_ops = &ace_netdev_ops;
 	dev->hard_start_xmit = &ace_start_xmit;
-	dev->get_stats = &ace_get_stats;
-	dev->set_multicast_list = &ace_set_multicast_list;
 	SET_ETHTOOL_OPS(dev, &ace_ethtool_ops);
-	dev->set_mac_address = &ace_set_mac_addr;
-	dev->change_mtu = &ace_change_mtu;
 
 	/* we only display this string ONCE */
 	if (!boards_found)
Acked-by on the v1 series
#82 lore raw
In reply to Stephen Hemminger
Quoted 6 lines · Stephen Hemminger

This sequence of patches breaks the network device adminstration function table away from the network device data structure. It is a transitional API change (both keep working), and this set of patches hits a range of commonly used drivers. This should be enough to make sure both old and new interfaces get used and tested.

Quoted 7 lines

--

--
To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html

Did I miss a patch, or did you intentionally not convert ixgbe?

The following patches look find...
Patch 13/33 - e1000e
Patch 23/33 - e1000
Patch 25/33 - igb
Patch 26/33 - e100
Patch 29/33 - ixgb

Signature · 2 lines
Cheers,
Jeff
#83 lore raw
Quoted 10 lines · On Mon, 17 Nov 2008 17:27:05 -0800 "Jeff Kirsher"…
Quoted 8 lines · Stephen Hemminger

This sequence of patches breaks the network device adminstration function table away from the network device data structure. It is a transitional API change (both keep working), and this set of patches hits a range of commonly used drivers. This should be enough to make sure both old and new interfaces get used and tested.

--

Quoted 7 lines
Quoted 5 lines

--
To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html

Did I miss a patch, or did you intentionally not convert ixgbe?

Since it was so similar to ixgb, both files are patched in same patch bundle.

#84 lore raw
Quoted 19 lines · Stephen Hemminger
Quoted 16 lines · On Mon, 17 Nov 2008 17:27:05 -0800 "Jeff Kirsher"…
Quoted 13 lines · Stephen Hemminger

This sequence of patches breaks the network device adminstration function table away from the network device data structure. It is a transitional API change (both keep working), and this set of patches hits a range of commonly used drivers. This should be enough to make sure both old and new interfaces get used and tested.

--

--
To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html

Quoted 3 lines
Quoted 1 line

Did I miss a patch, or did you intentionally not convert ixgbe?

Since it was so similar to ixgb, both files are patched in same patch bundle.

Got it, thanks.

Signature · 2 lines
Cheers,
Jeff
#85 lore raw
In reply to Stephen Hemminger
Quoted 13 lines · Stephen Hemminger
Quoted 10 lines · On Mon, 17 Nov 2008 17:27:05 -0800 "Jeff Kirsher"…
Quoted 7 lines · Stephen Hemminger

This sequence of patches breaks the network device adminstration function table away from the network device data structure. It is a transitional API change (both keep working), and this set of patches hits a range of commonly used drivers. This should be enough to make sure both old and new interfaces get used and tested.

Quoted 5 lines
Quoted 1 line

Did I miss a patch, or did you intentionally not convert ixgbe?

Since it was so similar to ixgb, both files are patched in same patch bundle. --

Looking at this further, what is the benefit of this change? For this massive of a change, I would expect some sort of significant benefit.

What is the driving force behind this change?

Signature · 2 lines
Cheers,
Jeff
maintainer
#86 lore raw

From: "Jeff Kirsher" <[email protected]>
Date: Wed, 19 Nov 2008 13:55:12 -0800

Quoted 17 lines
Quoted 15 lines · Stephen Hemminger
Quoted 11 lines · On Mon, 17 Nov 2008 17:27:05 -0800 "Jeff Kirsher"…
Quoted 7 lines · Stephen Hemminger

This sequence of patches breaks the network device adminstration function table away from the network device data structure. It is a transitional API change (both keep working), and this set of patches hits a range of commonly used drivers. This should be enough to make sure both old and new interfaces get used and tested.

Did I miss a patch, or did you intentionally not convert ixgbe?

Quoted 8 lines
Quoted 3 lines

Since it was so similar to ixgb, both files are patched in same patch bundle. --

Looking at this further, what is the benefit of this change? For this massive of a change, I would expect some sort of significant benefit.

What is the driving force behind this change?

If you have 1,000 virtual MAC vlan devices, you have 1,000 copies of these ops pointers being accessed by the CPU, that's stupid.

It's just one of many examples.

maintainer
#87 lore raw
In reply to Stephen Hemminger

From: Stephen Hemminger <[email protected]>
Date: Mon, 17 Nov 2008 15:42:07 -0800

Quoted 5 lines

This sequence of patches breaks the network device adminstration function table away from the network device data structure. It is a transitional API change (both keep working), and this set of patches hits a range of commonly used drivers. This should be enough to make sure both old and new interfaces get used and tested.

I'm starting to apply these patches, thanks Stephen.

I really think we should move even fast-path function pointers here. When we have tons of virtual devices configured, it doesn't make sense for us to touch tons of ->hard_start_xmit pointer values which all evaluate to the same thing.

ops are ops

#88 lore raw
Quoted 9 lines · On Wed, 19 Nov 2008 17:33:53 -0800 (PST) David Miller <[email protected]>…

From: Stephen Hemminger <[email protected]>
Date: Mon, 17 Nov 2008 15:42:07 -0800

Quoted 5 lines

This sequence of patches breaks the network device adminstration function table away from the network device data structure. It is a transitional API change (both keep working), and this set of patches hits a range of commonly used drivers. This should be enough to make sure both old and new interfaces get used and tested.

Quoted 8 lines

I'm starting to apply these patches, thanks Stephen.

I really think we should move even fast-path function pointers here. When we have tons of virtual devices configured, it doesn't make sense for us to touch tons of ->hard_start_xmit pointer values which all evaluate to the same thing.

ops are ops

I have some more pending. I'll add neigh_setup and xmit stuff.

#89 lore raw
Quoted 12 lines · Stephen Hemminger
Quoted 9 lines · On Wed, 19 Nov 2008 17:33:53 -0800 (PST) David Miller <[email protected]>…

From: Stephen Hemminger <[email protected]>
Date: Mon, 17 Nov 2008 15:42:07 -0800

Quoted 4 lines

This sequence of patches breaks the network device adminstration function table away from the network device data structure. It is a transitional API change (both keep working), and this set of patches
hits a range of commonly used drivers. This should be enough to make sure
both old and new interfaces get used and tested.

I'm starting to apply these patches, thanks Stephen.

Quoted 8 lines
Quoted 6 lines

I really think we should move even fast-path function pointers here. When we have tons of virtual devices configured, it doesn't make sense for us to touch tons of ->hard_start_xmit pointer values which all evaluate to the same thing.

ops are ops

I have some more pending. I'll add neigh_setup and xmit stuff.

So if you plan to release a new release of Network Device Ops...

I would have one suggestion about these ops, that would be to prefix method names (open, close, ...) by a ndo_ or something that ease greping...

Thanks

maintainer
#90 lore raw

From: Eric Dumazet <[email protected]>
Date: Thu, 20 Nov 2008 06:21:29 +0100

Quoted 4 lines

So if you plan to release a new release of Network Device Ops...

I would have one suggestion about these ops, that would be to prefix method names (open, close, ...) by a ndo_ or something that ease greping...

Since I'm in the process of integrating this work, I'll take care of doing this. It definitely sounds like a good idea to me.

#91 lore raw
Quoted 10 lines · David Miller

From: Eric Dumazet <[email protected]>
Date: Thu, 20 Nov 2008 06:21:29 +0100

Quoted 4 lines

So if you plan to release a new release of Network Device Ops...

I would have one suggestion about these ops, that would be to prefix method names (open, close, ...) by a ndo_ or something that ease greping...

Since I'm in the process of integrating this work, I'll take care of doing this. It definitely sounds like a good idea to me.

Can use just "nd_".

maintainer
#92 lore raw

From: Alexey Dobriyan <[email protected]>
Date: Thu, 20 Nov 2008 09:15:40 +0300

Quoted 6 lines · David Miller
Quoted 5 lines

From: Eric Dumazet <[email protected]>
Date: Thu, 20 Nov 2008 06:21:29 +0100

Quoted 2 lines

So if you plan to release a new release of Network Device Ops...

Quoted 7 lines
Quoted 5 lines
Quoted 2 lines

I would have one suggestion about these ops, that would be to prefix method names (open, close, ...) by a ndo_ or something that ease greping...

Since I'm in the process of integrating this work, I'll take care of doing this. It definitely sounds like a good idea to me.

Can use just "nd_".

Already used by ocfs and others.