wext: remove atomic requirement for wireless stats

The requirement for wireless stats to be atomic is now mostly
artificial since we hold the rtnl _and_ the dev_base_lock for
iterating the device list. Doing that is not required, just the
rtnl is sufficient (and the rtnl is required for other reasons
outlined in commit "wext: fix get_wireless_stats locking").

This will fix http://bugzilla.kernel.org/show_bug.cgi?id=13344
and make things easier for drivers.

Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
diff --git a/net/wireless/wext.c b/net/wireless/wext.c
index d3bbef7..22378da 100644
--- a/net/wireless/wext.c
+++ b/net/wireless/wext.c
@@ -636,8 +636,10 @@
 /*
  * Print info for /proc/net/wireless (print all entries)
  */
-static int wireless_seq_show(struct seq_file *seq, void *v)
+static int wireless_dev_seq_show(struct seq_file *seq, void *v)
 {
+	might_sleep();
+
 	if (v == SEQ_START_TOKEN)
 		seq_printf(seq, "Inter-| sta-|   Quality        |   Discarded "
 				"packets               | Missed | WE\n"
@@ -651,21 +653,41 @@
 
 static void *wireless_dev_seq_start(struct seq_file *seq, loff_t *pos)
 {
+	struct net *net = seq_file_net(seq);
+	loff_t off;
+	struct net_device *dev;
+
 	rtnl_lock();
-	return dev_seq_start(seq, pos);
+	if (!*pos)
+		return SEQ_START_TOKEN;
+
+	off = 1;
+	for_each_netdev(net, dev)
+		if (off++ == *pos)
+			return dev;
+	return NULL;
+}
+
+static void *wireless_dev_seq_next(struct seq_file *seq, void *v, loff_t *pos)
+{
+	struct net *net = seq_file_net(seq);
+
+	++*pos;
+
+	return v == SEQ_START_TOKEN ?
+		first_net_device(net) : next_net_device(v);
 }
 
 static void wireless_dev_seq_stop(struct seq_file *seq, void *v)
 {
-	dev_seq_stop(seq, v);
 	rtnl_unlock();
 }
 
 static const struct seq_operations wireless_seq_ops = {
 	.start = wireless_dev_seq_start,
-	.next  = dev_seq_next,
+	.next  = wireless_dev_seq_next,
 	.stop  = wireless_dev_seq_stop,
-	.show  = wireless_seq_show,
+	.show  = wireless_dev_seq_show,
 };
 
 static int seq_open_wireless(struct inode *inode, struct file *file)