main.c revision c2b13452b283f9c4a5b02a6b53ed6416ebf4c03c
1f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc/*
2f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc * Copyright 2002-2005, Instant802 Networks, Inc.
3f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc * Copyright 2005-2006, Devicescape Software, Inc.
4f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc * Copyright 2006-2007	Jiri Benc <jbenc@suse.cz>
5f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc *
6f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc * This program is free software; you can redistribute it and/or modify
7f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc * it under the terms of the GNU General Public License version 2 as
8f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc * published by the Free Software Foundation.
9f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc */
10f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc
11f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc#include <net/mac80211.h>
12f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc#include <net/ieee80211_radiotap.h>
13f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc#include <linux/module.h>
14f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc#include <linux/init.h>
15f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc#include <linux/netdevice.h>
16f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc#include <linux/types.h>
17f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc#include <linux/slab.h>
18f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc#include <linux/skbuff.h>
19f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc#include <linux/etherdevice.h>
20f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc#include <linux/if_arp.h>
21f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc#include <linux/wireless.h>
22f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc#include <linux/rtnetlink.h>
23f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc#include <linux/bitmap.h>
24881d966b48b035ab3f3aeaae0f3d3f9b584f45b2Eric W. Biederman#include <net/net_namespace.h>
25f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc#include <net/cfg80211.h>
26f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc
27f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc#include "ieee80211_i.h"
282c8dccc77420fb7433da5674818959d3499d35beJohannes Berg#include "rate.h"
29f7a921443740d7dafc65b17aa32531730d358f50Luis Carlos Cobo#include "mesh.h"
30f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc#include "wep.h"
31f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc#include "wme.h"
32f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc#include "aes_ccm.h"
332c8dccc77420fb7433da5674818959d3499d35beJohannes Berg#include "led.h"
34e0eb68596232788bc352368f2fbc3cb088e42e41Michael Wu#include "cfg.h"
35e9f207f0ff90bf60b825800d7450e6f2ff2eab88Jiri Benc#include "debugfs.h"
36e9f207f0ff90bf60b825800d7450e6f2ff2eab88Jiri Benc#include "debugfs_netdev.h"
37f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc
38b306f45300866adc01b84f7aa083bfcd9cbb89c4Johannes Berg/*
39b306f45300866adc01b84f7aa083bfcd9cbb89c4Johannes Berg * For seeing transmitted packets on monitor interfaces
40b306f45300866adc01b84f7aa083bfcd9cbb89c4Johannes Berg * we have a radiotap header too.
41b306f45300866adc01b84f7aa083bfcd9cbb89c4Johannes Berg */
42b306f45300866adc01b84f7aa083bfcd9cbb89c4Johannes Bergstruct ieee80211_tx_status_rtap_hdr {
43b306f45300866adc01b84f7aa083bfcd9cbb89c4Johannes Berg	struct ieee80211_radiotap_header hdr;
44b306f45300866adc01b84f7aa083bfcd9cbb89c4Johannes Berg	__le16 tx_flags;
45b306f45300866adc01b84f7aa083bfcd9cbb89c4Johannes Berg	u8 data_retries;
46b306f45300866adc01b84f7aa083bfcd9cbb89c4Johannes Berg} __attribute__ ((packed));
47b306f45300866adc01b84f7aa083bfcd9cbb89c4Johannes Berg
48b2c258fb11b3fc77a73f8b0453ff1256de812bc6Johannes Berg/* common interface routines */
49b306f45300866adc01b84f7aa083bfcd9cbb89c4Johannes Berg
50b95cce3576813ac3f86bafa6b5daaaaf7574b0feStephen Hemmingerstatic int header_parse_80211(const struct sk_buff *skb, unsigned char *haddr)
51b2c258fb11b3fc77a73f8b0453ff1256de812bc6Johannes Berg{
52b2c258fb11b3fc77a73f8b0453ff1256de812bc6Johannes Berg	memcpy(haddr, skb_mac_header(skb) + 10, ETH_ALEN); /* addr2 */
53b2c258fb11b3fc77a73f8b0453ff1256de812bc6Johannes Berg	return ETH_ALEN;
54b2c258fb11b3fc77a73f8b0453ff1256de812bc6Johannes Berg}
55f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc
564150c57212ad134765dd78c654a4b9906252b66dJohannes Berg/* must be called under mdev tx lock */
574150c57212ad134765dd78c654a4b9906252b66dJohannes Bergstatic void ieee80211_configure_filter(struct ieee80211_local *local)
584150c57212ad134765dd78c654a4b9906252b66dJohannes Berg{
594150c57212ad134765dd78c654a4b9906252b66dJohannes Berg	unsigned int changed_flags;
604150c57212ad134765dd78c654a4b9906252b66dJohannes Berg	unsigned int new_flags = 0;
614150c57212ad134765dd78c654a4b9906252b66dJohannes Berg
6253918994b7c8c3bf0af5f641e1f299856799d883Johannes Berg	if (atomic_read(&local->iff_promiscs))
634150c57212ad134765dd78c654a4b9906252b66dJohannes Berg		new_flags |= FIF_PROMISC_IN_BSS;
644150c57212ad134765dd78c654a4b9906252b66dJohannes Berg
6553918994b7c8c3bf0af5f641e1f299856799d883Johannes Berg	if (atomic_read(&local->iff_allmultis))
664150c57212ad134765dd78c654a4b9906252b66dJohannes Berg		new_flags |= FIF_ALLMULTI;
674150c57212ad134765dd78c654a4b9906252b66dJohannes Berg
684150c57212ad134765dd78c654a4b9906252b66dJohannes Berg	if (local->monitors)
698cc9a73914b07b5908d8a59320f4557fc9639f2eMichael Wu		new_flags |= FIF_BCN_PRBRESP_PROMISC;
708cc9a73914b07b5908d8a59320f4557fc9639f2eMichael Wu
718cc9a73914b07b5908d8a59320f4557fc9639f2eMichael Wu	if (local->fif_fcsfail)
728cc9a73914b07b5908d8a59320f4557fc9639f2eMichael Wu		new_flags |= FIF_FCSFAIL;
738cc9a73914b07b5908d8a59320f4557fc9639f2eMichael Wu
748cc9a73914b07b5908d8a59320f4557fc9639f2eMichael Wu	if (local->fif_plcpfail)
758cc9a73914b07b5908d8a59320f4557fc9639f2eMichael Wu		new_flags |= FIF_PLCPFAIL;
768cc9a73914b07b5908d8a59320f4557fc9639f2eMichael Wu
778cc9a73914b07b5908d8a59320f4557fc9639f2eMichael Wu	if (local->fif_control)
788cc9a73914b07b5908d8a59320f4557fc9639f2eMichael Wu		new_flags |= FIF_CONTROL;
798cc9a73914b07b5908d8a59320f4557fc9639f2eMichael Wu
808cc9a73914b07b5908d8a59320f4557fc9639f2eMichael Wu	if (local->fif_other_bss)
818cc9a73914b07b5908d8a59320f4557fc9639f2eMichael Wu		new_flags |= FIF_OTHER_BSS;
824150c57212ad134765dd78c654a4b9906252b66dJohannes Berg
834150c57212ad134765dd78c654a4b9906252b66dJohannes Berg	changed_flags = local->filter_flags ^ new_flags;
844150c57212ad134765dd78c654a4b9906252b66dJohannes Berg
854150c57212ad134765dd78c654a4b9906252b66dJohannes Berg	/* be a bit nasty */
864150c57212ad134765dd78c654a4b9906252b66dJohannes Berg	new_flags |= (1<<31);
874150c57212ad134765dd78c654a4b9906252b66dJohannes Berg
884150c57212ad134765dd78c654a4b9906252b66dJohannes Berg	local->ops->configure_filter(local_to_hw(local),
894150c57212ad134765dd78c654a4b9906252b66dJohannes Berg				     changed_flags, &new_flags,
904150c57212ad134765dd78c654a4b9906252b66dJohannes Berg				     local->mdev->mc_count,
914150c57212ad134765dd78c654a4b9906252b66dJohannes Berg				     local->mdev->mc_list);
924150c57212ad134765dd78c654a4b9906252b66dJohannes Berg
934150c57212ad134765dd78c654a4b9906252b66dJohannes Berg	WARN_ON(new_flags & (1<<31));
944150c57212ad134765dd78c654a4b9906252b66dJohannes Berg
954150c57212ad134765dd78c654a4b9906252b66dJohannes Berg	local->filter_flags = new_flags & ~(1<<31);
964150c57212ad134765dd78c654a4b9906252b66dJohannes Berg}
974150c57212ad134765dd78c654a4b9906252b66dJohannes Berg
98b2c258fb11b3fc77a73f8b0453ff1256de812bc6Johannes Berg/* master interface */
99f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc
100b2c258fb11b3fc77a73f8b0453ff1256de812bc6Johannes Bergstatic int ieee80211_master_open(struct net_device *dev)
101b2c258fb11b3fc77a73f8b0453ff1256de812bc6Johannes Berg{
102b2c258fb11b3fc77a73f8b0453ff1256de812bc6Johannes Berg	struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
103b2c258fb11b3fc77a73f8b0453ff1256de812bc6Johannes Berg	struct ieee80211_sub_if_data *sdata;
104b2c258fb11b3fc77a73f8b0453ff1256de812bc6Johannes Berg	int res = -EOPNOTSUPP;
105f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc
10679010420cc3f78eab911598bfdd29c4b06a83e1fJohannes Berg	/* we hold the RTNL here so can safely walk the list */
10779010420cc3f78eab911598bfdd29c4b06a83e1fJohannes Berg	list_for_each_entry(sdata, &local->interfaces, list) {
1083e122be089e6fb8d3f322416da4cdbb80ce12927Johannes Berg		if (netif_running(sdata->dev)) {
109b2c258fb11b3fc77a73f8b0453ff1256de812bc6Johannes Berg			res = 0;
110b2c258fb11b3fc77a73f8b0453ff1256de812bc6Johannes Berg			break;
111b2c258fb11b3fc77a73f8b0453ff1256de812bc6Johannes Berg		}
112b2c258fb11b3fc77a73f8b0453ff1256de812bc6Johannes Berg	}
11336d6825b91bc492b65b6333c369cd96a2fc8c903Johannes Berg
11436d6825b91bc492b65b6333c369cd96a2fc8c903Johannes Berg	if (res)
11536d6825b91bc492b65b6333c369cd96a2fc8c903Johannes Berg		return res;
11636d6825b91bc492b65b6333c369cd96a2fc8c903Johannes Berg
11751cb6db0f5654f08a4a6bfa3888dc36a51c2df3eDavid S. Miller	netif_tx_start_all_queues(local->mdev);
11836d6825b91bc492b65b6333c369cd96a2fc8c903Johannes Berg
11936d6825b91bc492b65b6333c369cd96a2fc8c903Johannes Berg	return 0;
120b2c258fb11b3fc77a73f8b0453ff1256de812bc6Johannes Berg}
121f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc
122b2c258fb11b3fc77a73f8b0453ff1256de812bc6Johannes Bergstatic int ieee80211_master_stop(struct net_device *dev)
123f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc{
124b2c258fb11b3fc77a73f8b0453ff1256de812bc6Johannes Berg	struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
125b2c258fb11b3fc77a73f8b0453ff1256de812bc6Johannes Berg	struct ieee80211_sub_if_data *sdata;
126f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc
12779010420cc3f78eab911598bfdd29c4b06a83e1fJohannes Berg	/* we hold the RTNL here so can safely walk the list */
12879010420cc3f78eab911598bfdd29c4b06a83e1fJohannes Berg	list_for_each_entry(sdata, &local->interfaces, list)
1293e122be089e6fb8d3f322416da4cdbb80ce12927Johannes Berg		if (netif_running(sdata->dev))
130b2c258fb11b3fc77a73f8b0453ff1256de812bc6Johannes Berg			dev_close(sdata->dev);
131f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc
132b2c258fb11b3fc77a73f8b0453ff1256de812bc6Johannes Berg	return 0;
133b2c258fb11b3fc77a73f8b0453ff1256de812bc6Johannes Berg}
134f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc
1354150c57212ad134765dd78c654a4b9906252b66dJohannes Bergstatic void ieee80211_master_set_multicast_list(struct net_device *dev)
1364150c57212ad134765dd78c654a4b9906252b66dJohannes Berg{
1374150c57212ad134765dd78c654a4b9906252b66dJohannes Berg	struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
1384150c57212ad134765dd78c654a4b9906252b66dJohannes Berg
1394150c57212ad134765dd78c654a4b9906252b66dJohannes Berg	ieee80211_configure_filter(local);
1404150c57212ad134765dd78c654a4b9906252b66dJohannes Berg}
1414150c57212ad134765dd78c654a4b9906252b66dJohannes Berg
142b2c258fb11b3fc77a73f8b0453ff1256de812bc6Johannes Berg/* regular interfaces */
143f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc
144b2c258fb11b3fc77a73f8b0453ff1256de812bc6Johannes Bergstatic int ieee80211_change_mtu(struct net_device *dev, int new_mtu)
145f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc{
146f7a921443740d7dafc65b17aa32531730d358f50Luis Carlos Cobo	int meshhdrlen;
147f7a921443740d7dafc65b17aa32531730d358f50Luis Carlos Cobo	struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
148f7a921443740d7dafc65b17aa32531730d358f50Luis Carlos Cobo
149f7a921443740d7dafc65b17aa32531730d358f50Luis Carlos Cobo	meshhdrlen = (sdata->vif.type == IEEE80211_IF_TYPE_MESH_POINT) ? 5 : 0;
150f7a921443740d7dafc65b17aa32531730d358f50Luis Carlos Cobo
151b2c258fb11b3fc77a73f8b0453ff1256de812bc6Johannes Berg	/* FIX: what would be proper limits for MTU?
152b2c258fb11b3fc77a73f8b0453ff1256de812bc6Johannes Berg	 * This interface uses 802.3 frames. */
153f7a921443740d7dafc65b17aa32531730d358f50Luis Carlos Cobo	if (new_mtu < 256 ||
154f4ea83dd743d3e1bec8fdf954ac911c6b12ae87aJohannes Berg	    new_mtu > IEEE80211_MAX_DATA_LEN - 24 - 6 - meshhdrlen) {
155b2c258fb11b3fc77a73f8b0453ff1256de812bc6Johannes Berg		return -EINVAL;
156b2c258fb11b3fc77a73f8b0453ff1256de812bc6Johannes Berg	}
157f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc
158b2c258fb11b3fc77a73f8b0453ff1256de812bc6Johannes Berg#ifdef CONFIG_MAC80211_VERBOSE_DEBUG
159b2c258fb11b3fc77a73f8b0453ff1256de812bc6Johannes Berg	printk(KERN_DEBUG "%s: setting MTU %d\n", dev->name, new_mtu);
160b2c258fb11b3fc77a73f8b0453ff1256de812bc6Johannes Berg#endif /* CONFIG_MAC80211_VERBOSE_DEBUG */
161b2c258fb11b3fc77a73f8b0453ff1256de812bc6Johannes Berg	dev->mtu = new_mtu;
162f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc	return 0;
163f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc}
164f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc
165b2c258fb11b3fc77a73f8b0453ff1256de812bc6Johannes Bergstatic inline int identical_mac_addr_allowed(int type1, int type2)
166b2c258fb11b3fc77a73f8b0453ff1256de812bc6Johannes Berg{
167b2c258fb11b3fc77a73f8b0453ff1256de812bc6Johannes Berg	return (type1 == IEEE80211_IF_TYPE_MNTR ||
168b2c258fb11b3fc77a73f8b0453ff1256de812bc6Johannes Berg		type2 == IEEE80211_IF_TYPE_MNTR ||
169b2c258fb11b3fc77a73f8b0453ff1256de812bc6Johannes Berg		(type1 == IEEE80211_IF_TYPE_AP &&
170b2c258fb11b3fc77a73f8b0453ff1256de812bc6Johannes Berg		 type2 == IEEE80211_IF_TYPE_WDS) ||
171b2c258fb11b3fc77a73f8b0453ff1256de812bc6Johannes Berg		(type1 == IEEE80211_IF_TYPE_WDS &&
172b2c258fb11b3fc77a73f8b0453ff1256de812bc6Johannes Berg		 (type2 == IEEE80211_IF_TYPE_WDS ||
173b2c258fb11b3fc77a73f8b0453ff1256de812bc6Johannes Berg		  type2 == IEEE80211_IF_TYPE_AP)) ||
174b2c258fb11b3fc77a73f8b0453ff1256de812bc6Johannes Berg		(type1 == IEEE80211_IF_TYPE_AP &&
175b2c258fb11b3fc77a73f8b0453ff1256de812bc6Johannes Berg		 type2 == IEEE80211_IF_TYPE_VLAN) ||
176b2c258fb11b3fc77a73f8b0453ff1256de812bc6Johannes Berg		(type1 == IEEE80211_IF_TYPE_VLAN &&
177b2c258fb11b3fc77a73f8b0453ff1256de812bc6Johannes Berg		 (type2 == IEEE80211_IF_TYPE_AP ||
178b2c258fb11b3fc77a73f8b0453ff1256de812bc6Johannes Berg		  type2 == IEEE80211_IF_TYPE_VLAN)));
179b2c258fb11b3fc77a73f8b0453ff1256de812bc6Johannes Berg}
180f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc
181b2c258fb11b3fc77a73f8b0453ff1256de812bc6Johannes Bergstatic int ieee80211_open(struct net_device *dev)
182e2ebc74d7e3d71600640db6fbb28cc2f362184c1Johannes Berg{
183b2c258fb11b3fc77a73f8b0453ff1256de812bc6Johannes Berg	struct ieee80211_sub_if_data *sdata, *nsdata;
184b2c258fb11b3fc77a73f8b0453ff1256de812bc6Johannes Berg	struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
185fc32f9243dc93e75f81457e95d9cb90ee6136d94Tomas Winkler	struct sta_info *sta;
186b2c258fb11b3fc77a73f8b0453ff1256de812bc6Johannes Berg	struct ieee80211_if_init_conf conf;
187fc32f9243dc93e75f81457e95d9cb90ee6136d94Tomas Winkler	u32 changed = 0;
188b2c258fb11b3fc77a73f8b0453ff1256de812bc6Johannes Berg	int res;
189ceffefd15aac78841432230627308b8a382dbcfcMichael Buesch	bool need_hw_reconfig = 0;
190bdbe819540f3365249095692118dbfeee308140dLuis Carlos Cobo	u8 null_addr[ETH_ALEN] = {0};
191f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc
192b2c258fb11b3fc77a73f8b0453ff1256de812bc6Johannes Berg	sdata = IEEE80211_DEV_TO_SUB_IF(dev);
1930ec3ca445931ff0e7ad6ac61d6c5d2aaafe7a9f5Johannes Berg
194bdbe819540f3365249095692118dbfeee308140dLuis Carlos Cobo	/* fail early if user set an invalid address */
195bdbe819540f3365249095692118dbfeee308140dLuis Carlos Cobo	if (compare_ether_addr(dev->dev_addr, null_addr) &&
196bdbe819540f3365249095692118dbfeee308140dLuis Carlos Cobo	    !is_valid_ether_addr(dev->dev_addr))
197bdbe819540f3365249095692118dbfeee308140dLuis Carlos Cobo		return -EADDRNOTAVAIL;
198bdbe819540f3365249095692118dbfeee308140dLuis Carlos Cobo
19979010420cc3f78eab911598bfdd29c4b06a83e1fJohannes Berg	/* we hold the RTNL here so can safely walk the list */
20079010420cc3f78eab911598bfdd29c4b06a83e1fJohannes Berg	list_for_each_entry(nsdata, &local->interfaces, list) {
201b2c258fb11b3fc77a73f8b0453ff1256de812bc6Johannes Berg		struct net_device *ndev = nsdata->dev;
202e2ebc74d7e3d71600640db6fbb28cc2f362184c1Johannes Berg
2033e122be089e6fb8d3f322416da4cdbb80ce12927Johannes Berg		if (ndev != dev && netif_running(ndev)) {
204665e8aafb4e0826caec9db25617b186ea3f3ec91Johannes Berg			/*
205665e8aafb4e0826caec9db25617b186ea3f3ec91Johannes Berg			 * Allow only a single IBSS interface to be up at any
206665e8aafb4e0826caec9db25617b186ea3f3ec91Johannes Berg			 * time. This is restricted because beacon distribution
207665e8aafb4e0826caec9db25617b186ea3f3ec91Johannes Berg			 * cannot work properly if both are in the same IBSS.
208665e8aafb4e0826caec9db25617b186ea3f3ec91Johannes Berg			 *
209665e8aafb4e0826caec9db25617b186ea3f3ec91Johannes Berg			 * To remove this restriction we'd have to disallow them
210665e8aafb4e0826caec9db25617b186ea3f3ec91Johannes Berg			 * from setting the same SSID on different IBSS interfaces
211665e8aafb4e0826caec9db25617b186ea3f3ec91Johannes Berg			 * belonging to the same hardware. Then, however, we're
212665e8aafb4e0826caec9db25617b186ea3f3ec91Johannes Berg			 * faced with having to adopt two different TSF timers...
213665e8aafb4e0826caec9db25617b186ea3f3ec91Johannes Berg			 */
214665e8aafb4e0826caec9db25617b186ea3f3ec91Johannes Berg			if (sdata->vif.type == IEEE80211_IF_TYPE_IBSS &&
215665e8aafb4e0826caec9db25617b186ea3f3ec91Johannes Berg			    nsdata->vif.type == IEEE80211_IF_TYPE_IBSS)
216665e8aafb4e0826caec9db25617b186ea3f3ec91Johannes Berg				return -EBUSY;
217665e8aafb4e0826caec9db25617b186ea3f3ec91Johannes Berg
218665e8aafb4e0826caec9db25617b186ea3f3ec91Johannes Berg			/*
219665e8aafb4e0826caec9db25617b186ea3f3ec91Johannes Berg			 * The remaining checks are only performed for interfaces
220665e8aafb4e0826caec9db25617b186ea3f3ec91Johannes Berg			 * with the same MAC address.
221665e8aafb4e0826caec9db25617b186ea3f3ec91Johannes Berg			 */
222665e8aafb4e0826caec9db25617b186ea3f3ec91Johannes Berg			if (compare_ether_addr(dev->dev_addr, ndev->dev_addr))
223665e8aafb4e0826caec9db25617b186ea3f3ec91Johannes Berg				continue;
224665e8aafb4e0826caec9db25617b186ea3f3ec91Johannes Berg
2250ec3ca445931ff0e7ad6ac61d6c5d2aaafe7a9f5Johannes Berg			/*
2260ec3ca445931ff0e7ad6ac61d6c5d2aaafe7a9f5Johannes Berg			 * check whether it may have the same address
2270ec3ca445931ff0e7ad6ac61d6c5d2aaafe7a9f5Johannes Berg			 */
22851fb61e76d952e6bc2fbdd9f0d38425fbab1cf31Johannes Berg			if (!identical_mac_addr_allowed(sdata->vif.type,
22951fb61e76d952e6bc2fbdd9f0d38425fbab1cf31Johannes Berg							nsdata->vif.type))
2300ec3ca445931ff0e7ad6ac61d6c5d2aaafe7a9f5Johannes Berg				return -ENOTUNIQ;
2310ec3ca445931ff0e7ad6ac61d6c5d2aaafe7a9f5Johannes Berg
2320ec3ca445931ff0e7ad6ac61d6c5d2aaafe7a9f5Johannes Berg			/*
2330ec3ca445931ff0e7ad6ac61d6c5d2aaafe7a9f5Johannes Berg			 * can only add VLANs to enabled APs
2340ec3ca445931ff0e7ad6ac61d6c5d2aaafe7a9f5Johannes Berg			 */
23551fb61e76d952e6bc2fbdd9f0d38425fbab1cf31Johannes Berg			if (sdata->vif.type == IEEE80211_IF_TYPE_VLAN &&
236665e8aafb4e0826caec9db25617b186ea3f3ec91Johannes Berg			    nsdata->vif.type == IEEE80211_IF_TYPE_AP)
2373e122be089e6fb8d3f322416da4cdbb80ce12927Johannes Berg				sdata->bss = &nsdata->u.ap;
238b2c258fb11b3fc77a73f8b0453ff1256de812bc6Johannes Berg		}
239b2c258fb11b3fc77a73f8b0453ff1256de812bc6Johannes Berg	}
240f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc
24151fb61e76d952e6bc2fbdd9f0d38425fbab1cf31Johannes Berg	switch (sdata->vif.type) {
2420ec3ca445931ff0e7ad6ac61d6c5d2aaafe7a9f5Johannes Berg	case IEEE80211_IF_TYPE_WDS:
243e94e106831403d5028e7bb73c3163951134de1baJohannes Berg		if (!is_valid_ether_addr(sdata->u.wds.remote_addr))
2440ec3ca445931ff0e7ad6ac61d6c5d2aaafe7a9f5Johannes Berg			return -ENOLINK;
2450ec3ca445931ff0e7ad6ac61d6c5d2aaafe7a9f5Johannes Berg		break;
2460ec3ca445931ff0e7ad6ac61d6c5d2aaafe7a9f5Johannes Berg	case IEEE80211_IF_TYPE_VLAN:
2473e122be089e6fb8d3f322416da4cdbb80ce12927Johannes Berg		if (!sdata->bss)
2480ec3ca445931ff0e7ad6ac61d6c5d2aaafe7a9f5Johannes Berg			return -ENOLINK;
2493e122be089e6fb8d3f322416da4cdbb80ce12927Johannes Berg		list_add(&sdata->u.vlan.list, &sdata->bss->vlans);
2500ec3ca445931ff0e7ad6ac61d6c5d2aaafe7a9f5Johannes Berg		break;
251fb1c1cd6c5a8988b14c5c6c0dfe55542df3a34c6Johannes Berg	case IEEE80211_IF_TYPE_AP:
2523e122be089e6fb8d3f322416da4cdbb80ce12927Johannes Berg		sdata->bss = &sdata->u.ap;
2533e122be089e6fb8d3f322416da4cdbb80ce12927Johannes Berg		break;
2548dbc1722a78343eb80f0ce1a3ef1965a9774ad5bLuis Carlos Cobo	case IEEE80211_IF_TYPE_MESH_POINT:
255472dbc45dc1966284de72d7de15690c17ed2cf33Johannes Berg		if (!ieee80211_vif_is_mesh(&sdata->vif))
256472dbc45dc1966284de72d7de15690c17ed2cf33Johannes Berg			break;
2578dbc1722a78343eb80f0ce1a3ef1965a9774ad5bLuis Carlos Cobo		/* mesh ifaces must set allmulti to forward mcast traffic */
2588dbc1722a78343eb80f0ce1a3ef1965a9774ad5bLuis Carlos Cobo		atomic_inc(&local->iff_allmultis);
2598dbc1722a78343eb80f0ce1a3ef1965a9774ad5bLuis Carlos Cobo		break;
260fb1c1cd6c5a8988b14c5c6c0dfe55542df3a34c6Johannes Berg	case IEEE80211_IF_TYPE_STA:
261fb1c1cd6c5a8988b14c5c6c0dfe55542df3a34c6Johannes Berg	case IEEE80211_IF_TYPE_MNTR:
262fb1c1cd6c5a8988b14c5c6c0dfe55542df3a34c6Johannes Berg	case IEEE80211_IF_TYPE_IBSS:
263fb1c1cd6c5a8988b14c5c6c0dfe55542df3a34c6Johannes Berg		/* no special treatment */
264fb1c1cd6c5a8988b14c5c6c0dfe55542df3a34c6Johannes Berg		break;
265a28975525016ddcbdaab8225666df1cf2dc9cb2dJohannes Berg	case IEEE80211_IF_TYPE_INVALID:
266a28975525016ddcbdaab8225666df1cf2dc9cb2dJohannes Berg		/* cannot happen */
267a28975525016ddcbdaab8225666df1cf2dc9cb2dJohannes Berg		WARN_ON(1);
268a28975525016ddcbdaab8225666df1cf2dc9cb2dJohannes Berg		break;
2690ec3ca445931ff0e7ad6ac61d6c5d2aaafe7a9f5Johannes Berg	}
270f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc
271b2c258fb11b3fc77a73f8b0453ff1256de812bc6Johannes Berg	if (local->open_count == 0) {
272b2c258fb11b3fc77a73f8b0453ff1256de812bc6Johannes Berg		res = 0;
2734150c57212ad134765dd78c654a4b9906252b66dJohannes Berg		if (local->ops->start)
2744150c57212ad134765dd78c654a4b9906252b66dJohannes Berg			res = local->ops->start(local_to_hw(local));
2754150c57212ad134765dd78c654a4b9906252b66dJohannes Berg		if (res)
2763e122be089e6fb8d3f322416da4cdbb80ce12927Johannes Berg			goto err_del_bss;
277ceffefd15aac78841432230627308b8a382dbcfcMichael Buesch		need_hw_reconfig = 1;
278cdcb006fbe7a74b5f7827f5c5c27e11399a2fab7Ivo van Doorn		ieee80211_led_radio(local, local->hw.conf.radio_enabled);
279b2c258fb11b3fc77a73f8b0453ff1256de812bc6Johannes Berg	}
280f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc
281bdbe819540f3365249095692118dbfeee308140dLuis Carlos Cobo	/*
282bdbe819540f3365249095692118dbfeee308140dLuis Carlos Cobo	 * Check all interfaces and copy the hopefully now-present
283bdbe819540f3365249095692118dbfeee308140dLuis Carlos Cobo	 * MAC address to those that have the special null one.
284bdbe819540f3365249095692118dbfeee308140dLuis Carlos Cobo	 */
285bdbe819540f3365249095692118dbfeee308140dLuis Carlos Cobo	list_for_each_entry(nsdata, &local->interfaces, list) {
286bdbe819540f3365249095692118dbfeee308140dLuis Carlos Cobo		struct net_device *ndev = nsdata->dev;
287bdbe819540f3365249095692118dbfeee308140dLuis Carlos Cobo
288bdbe819540f3365249095692118dbfeee308140dLuis Carlos Cobo		/*
289bdbe819540f3365249095692118dbfeee308140dLuis Carlos Cobo		 * No need to check netif_running since we do not allow
290bdbe819540f3365249095692118dbfeee308140dLuis Carlos Cobo		 * it to start up with this invalid address.
291bdbe819540f3365249095692118dbfeee308140dLuis Carlos Cobo		 */
292bdbe819540f3365249095692118dbfeee308140dLuis Carlos Cobo		if (compare_ether_addr(null_addr, ndev->dev_addr) == 0)
293bdbe819540f3365249095692118dbfeee308140dLuis Carlos Cobo			memcpy(ndev->dev_addr,
294bdbe819540f3365249095692118dbfeee308140dLuis Carlos Cobo			       local->hw.wiphy->perm_addr,
295bdbe819540f3365249095692118dbfeee308140dLuis Carlos Cobo			       ETH_ALEN);
296bdbe819540f3365249095692118dbfeee308140dLuis Carlos Cobo	}
297bdbe819540f3365249095692118dbfeee308140dLuis Carlos Cobo
298bdbe819540f3365249095692118dbfeee308140dLuis Carlos Cobo	if (compare_ether_addr(null_addr, local->mdev->dev_addr) == 0)
299bdbe819540f3365249095692118dbfeee308140dLuis Carlos Cobo		memcpy(local->mdev->dev_addr, local->hw.wiphy->perm_addr,
300bdbe819540f3365249095692118dbfeee308140dLuis Carlos Cobo		       ETH_ALEN);
301bdbe819540f3365249095692118dbfeee308140dLuis Carlos Cobo
302bdbe819540f3365249095692118dbfeee308140dLuis Carlos Cobo	/*
303bdbe819540f3365249095692118dbfeee308140dLuis Carlos Cobo	 * Validate the MAC address for this device.
304bdbe819540f3365249095692118dbfeee308140dLuis Carlos Cobo	 */
305bdbe819540f3365249095692118dbfeee308140dLuis Carlos Cobo	if (!is_valid_ether_addr(dev->dev_addr)) {
306bdbe819540f3365249095692118dbfeee308140dLuis Carlos Cobo		if (!local->open_count && local->ops->stop)
307bdbe819540f3365249095692118dbfeee308140dLuis Carlos Cobo			local->ops->stop(local_to_hw(local));
308bdbe819540f3365249095692118dbfeee308140dLuis Carlos Cobo		return -EADDRNOTAVAIL;
309bdbe819540f3365249095692118dbfeee308140dLuis Carlos Cobo	}
310bdbe819540f3365249095692118dbfeee308140dLuis Carlos Cobo
31151fb61e76d952e6bc2fbdd9f0d38425fbab1cf31Johannes Berg	switch (sdata->vif.type) {
3120ec3ca445931ff0e7ad6ac61d6c5d2aaafe7a9f5Johannes Berg	case IEEE80211_IF_TYPE_VLAN:
3130ec3ca445931ff0e7ad6ac61d6c5d2aaafe7a9f5Johannes Berg		/* no need to tell driver */
3140ec3ca445931ff0e7ad6ac61d6c5d2aaafe7a9f5Johannes Berg		break;
3154150c57212ad134765dd78c654a4b9906252b66dJohannes Berg	case IEEE80211_IF_TYPE_MNTR:
3163d30d949cf3f9763393f3457721bca3ac2426e42Michael Wu		if (sdata->u.mntr_flags & MONITOR_FLAG_COOK_FRAMES) {
3173d30d949cf3f9763393f3457721bca3ac2426e42Michael Wu			local->cooked_mntrs++;
3183d30d949cf3f9763393f3457721bca3ac2426e42Michael Wu			break;
3193d30d949cf3f9763393f3457721bca3ac2426e42Michael Wu		}
3203d30d949cf3f9763393f3457721bca3ac2426e42Michael Wu
3214150c57212ad134765dd78c654a4b9906252b66dJohannes Berg		/* must be before the call to ieee80211_configure_filter */
322b2c258fb11b3fc77a73f8b0453ff1256de812bc6Johannes Berg		local->monitors++;
3238cc9a73914b07b5908d8a59320f4557fc9639f2eMichael Wu		if (local->monitors == 1)
3244150c57212ad134765dd78c654a4b9906252b66dJohannes Berg			local->hw.conf.flags |= IEEE80211_CONF_RADIOTAP;
3258cc9a73914b07b5908d8a59320f4557fc9639f2eMichael Wu
3268cc9a73914b07b5908d8a59320f4557fc9639f2eMichael Wu		if (sdata->u.mntr_flags & MONITOR_FLAG_FCSFAIL)
3278cc9a73914b07b5908d8a59320f4557fc9639f2eMichael Wu			local->fif_fcsfail++;
3288cc9a73914b07b5908d8a59320f4557fc9639f2eMichael Wu		if (sdata->u.mntr_flags & MONITOR_FLAG_PLCPFAIL)
3298cc9a73914b07b5908d8a59320f4557fc9639f2eMichael Wu			local->fif_plcpfail++;
3308cc9a73914b07b5908d8a59320f4557fc9639f2eMichael Wu		if (sdata->u.mntr_flags & MONITOR_FLAG_CONTROL)
3318cc9a73914b07b5908d8a59320f4557fc9639f2eMichael Wu			local->fif_control++;
3328cc9a73914b07b5908d8a59320f4557fc9639f2eMichael Wu		if (sdata->u.mntr_flags & MONITOR_FLAG_OTHER_BSS)
3338cc9a73914b07b5908d8a59320f4557fc9639f2eMichael Wu			local->fif_other_bss++;
3348cc9a73914b07b5908d8a59320f4557fc9639f2eMichael Wu
335b9e40857682ecfc5bcd0356a23ff409883ffb982David S. Miller		netif_addr_lock_bh(local->mdev);
3368cc9a73914b07b5908d8a59320f4557fc9639f2eMichael Wu		ieee80211_configure_filter(local);
337b9e40857682ecfc5bcd0356a23ff409883ffb982David S. Miller		netif_addr_unlock_bh(local->mdev);
3384150c57212ad134765dd78c654a4b9906252b66dJohannes Berg		break;
3394150c57212ad134765dd78c654a4b9906252b66dJohannes Berg	case IEEE80211_IF_TYPE_STA:
3404150c57212ad134765dd78c654a4b9906252b66dJohannes Berg	case IEEE80211_IF_TYPE_IBSS:
3414150c57212ad134765dd78c654a4b9906252b66dJohannes Berg		sdata->u.sta.flags &= ~IEEE80211_STA_PREV_BSSID_SET;
3424150c57212ad134765dd78c654a4b9906252b66dJohannes Berg		/* fall through */
3434150c57212ad134765dd78c654a4b9906252b66dJohannes Berg	default:
34432bfd35d4b63bd63de4bb0d791ef049c3c868726Johannes Berg		conf.vif = &sdata->vif;
34551fb61e76d952e6bc2fbdd9f0d38425fbab1cf31Johannes Berg		conf.type = sdata->vif.type;
3464150c57212ad134765dd78c654a4b9906252b66dJohannes Berg		conf.mac_addr = dev->dev_addr;
3474150c57212ad134765dd78c654a4b9906252b66dJohannes Berg		res = local->ops->add_interface(local_to_hw(local), &conf);
3484150c57212ad134765dd78c654a4b9906252b66dJohannes Berg		if (res)
349636c5d488bc0b349e01cf5bfbf85588134af70a0Johannes Berg			goto err_stop;
3504150c57212ad134765dd78c654a4b9906252b66dJohannes Berg
3519d139c810a2aa17365cc548d0cd2a189d8433c65Johannes Berg		if (ieee80211_vif_is_mesh(&sdata->vif))
352f698d856f65c3fea091cc303a135967965c5b880Jasper Bryant-Greene			ieee80211_start_mesh(sdata);
353f698d856f65c3fea091cc303a135967965c5b880Jasper Bryant-Greene		changed |= ieee80211_reset_erp_info(sdata);
354fc32f9243dc93e75f81457e95d9cb90ee6136d94Tomas Winkler		ieee80211_bss_info_change_notify(sdata, changed);
35511a843b7e16062389c53ba393c7913956e034eb2Johannes Berg		ieee80211_enable_keys(sdata);
3564150c57212ad134765dd78c654a4b9906252b66dJohannes Berg
35751fb61e76d952e6bc2fbdd9f0d38425fbab1cf31Johannes Berg		if (sdata->vif.type == IEEE80211_IF_TYPE_STA &&
358ddd3d2be85e3207c47f2b3c431723e6c758b4b0dJohannes Berg		    !(sdata->flags & IEEE80211_SDATA_USERSPACE_MLME))
3594150c57212ad134765dd78c654a4b9906252b66dJohannes Berg			netif_carrier_off(dev);
3604150c57212ad134765dd78c654a4b9906252b66dJohannes Berg		else
3614150c57212ad134765dd78c654a4b9906252b66dJohannes Berg			netif_carrier_on(dev);
362d9430a32886f70c0c16d67c525f6cda2df7906eeDaniel Drake	}
363f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc
364636c5d488bc0b349e01cf5bfbf85588134af70a0Johannes Berg	if (sdata->vif.type == IEEE80211_IF_TYPE_WDS) {
365636c5d488bc0b349e01cf5bfbf85588134af70a0Johannes Berg		/* Create STA entry for the WDS peer */
366636c5d488bc0b349e01cf5bfbf85588134af70a0Johannes Berg		sta = sta_info_alloc(sdata, sdata->u.wds.remote_addr,
367636c5d488bc0b349e01cf5bfbf85588134af70a0Johannes Berg				     GFP_KERNEL);
368636c5d488bc0b349e01cf5bfbf85588134af70a0Johannes Berg		if (!sta) {
369636c5d488bc0b349e01cf5bfbf85588134af70a0Johannes Berg			res = -ENOMEM;
370636c5d488bc0b349e01cf5bfbf85588134af70a0Johannes Berg			goto err_del_interface;
371636c5d488bc0b349e01cf5bfbf85588134af70a0Johannes Berg		}
372636c5d488bc0b349e01cf5bfbf85588134af70a0Johannes Berg
37307346f81e87d6e4cca7ae9adfa711d0c61c87b56Johannes Berg		/* no locking required since STA is not live yet */
374636c5d488bc0b349e01cf5bfbf85588134af70a0Johannes Berg		sta->flags |= WLAN_STA_AUTHORIZED;
375636c5d488bc0b349e01cf5bfbf85588134af70a0Johannes Berg
376636c5d488bc0b349e01cf5bfbf85588134af70a0Johannes Berg		res = sta_info_insert(sta);
377636c5d488bc0b349e01cf5bfbf85588134af70a0Johannes Berg		if (res) {
378636c5d488bc0b349e01cf5bfbf85588134af70a0Johannes Berg			/* STA has been freed */
379636c5d488bc0b349e01cf5bfbf85588134af70a0Johannes Berg			goto err_del_interface;
380636c5d488bc0b349e01cf5bfbf85588134af70a0Johannes Berg		}
381636c5d488bc0b349e01cf5bfbf85588134af70a0Johannes Berg	}
382636c5d488bc0b349e01cf5bfbf85588134af70a0Johannes Berg
3834150c57212ad134765dd78c654a4b9906252b66dJohannes Berg	if (local->open_count == 0) {
3844150c57212ad134765dd78c654a4b9906252b66dJohannes Berg		res = dev_open(local->mdev);
3854150c57212ad134765dd78c654a4b9906252b66dJohannes Berg		WARN_ON(res);
386636c5d488bc0b349e01cf5bfbf85588134af70a0Johannes Berg		if (res)
387636c5d488bc0b349e01cf5bfbf85588134af70a0Johannes Berg			goto err_del_interface;
3884150c57212ad134765dd78c654a4b9906252b66dJohannes Berg		tasklet_enable(&local->tx_pending_tasklet);
3894150c57212ad134765dd78c654a4b9906252b66dJohannes Berg		tasklet_enable(&local->tasklet);
3904150c57212ad134765dd78c654a4b9906252b66dJohannes Berg	}
3914150c57212ad134765dd78c654a4b9906252b66dJohannes Berg
392c1428b3f45d152a300e4f18638ebf30ceafda6c3Johannes Berg	/*
393c1428b3f45d152a300e4f18638ebf30ceafda6c3Johannes Berg	 * set_multicast_list will be invoked by the networking core
394c1428b3f45d152a300e4f18638ebf30ceafda6c3Johannes Berg	 * which will check whether any increments here were done in
395c1428b3f45d152a300e4f18638ebf30ceafda6c3Johannes Berg	 * error and sync them down to the hardware as filter flags.
396c1428b3f45d152a300e4f18638ebf30ceafda6c3Johannes Berg	 */
397c1428b3f45d152a300e4f18638ebf30ceafda6c3Johannes Berg	if (sdata->flags & IEEE80211_SDATA_ALLMULTI)
398c1428b3f45d152a300e4f18638ebf30ceafda6c3Johannes Berg		atomic_inc(&local->iff_allmultis);
399c1428b3f45d152a300e4f18638ebf30ceafda6c3Johannes Berg
400c1428b3f45d152a300e4f18638ebf30ceafda6c3Johannes Berg	if (sdata->flags & IEEE80211_SDATA_PROMISC)
401c1428b3f45d152a300e4f18638ebf30ceafda6c3Johannes Berg		atomic_inc(&local->iff_promiscs);
402c1428b3f45d152a300e4f18638ebf30ceafda6c3Johannes Berg
4034150c57212ad134765dd78c654a4b9906252b66dJohannes Berg	local->open_count++;
4045825fe100d654fff89aa67a1e202af1f8a7f0ad0Johannes Berg	if (need_hw_reconfig) {
405ceffefd15aac78841432230627308b8a382dbcfcMichael Buesch		ieee80211_hw_config(local);
4065825fe100d654fff89aa67a1e202af1f8a7f0ad0Johannes Berg		/*
4075825fe100d654fff89aa67a1e202af1f8a7f0ad0Johannes Berg		 * set default queue parameters so drivers don't
4085825fe100d654fff89aa67a1e202af1f8a7f0ad0Johannes Berg		 * need to initialise the hardware if the hardware
4095825fe100d654fff89aa67a1e202af1f8a7f0ad0Johannes Berg		 * doesn't start up with sane defaults
4105825fe100d654fff89aa67a1e202af1f8a7f0ad0Johannes Berg		 */
4115825fe100d654fff89aa67a1e202af1f8a7f0ad0Johannes Berg		ieee80211_set_wmm_default(sdata);
4125825fe100d654fff89aa67a1e202af1f8a7f0ad0Johannes Berg	}
413f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc
41464f851e410ae37a0990212ae34f0c96b641478f7Jan Niehusmann	/*
41564f851e410ae37a0990212ae34f0c96b641478f7Jan Niehusmann	 * ieee80211_sta_work is disabled while network interface
41664f851e410ae37a0990212ae34f0c96b641478f7Jan Niehusmann	 * is down. Therefore, some configuration changes may not
41764f851e410ae37a0990212ae34f0c96b641478f7Jan Niehusmann	 * yet be effective. Trigger execution of ieee80211_sta_work
41864f851e410ae37a0990212ae34f0c96b641478f7Jan Niehusmann	 * to fix this.
41964f851e410ae37a0990212ae34f0c96b641478f7Jan Niehusmann	 */
420988c0f723d0b1abb399e6e71d8bf3f8bf1949a70Johannes Berg	if (sdata->vif.type == IEEE80211_IF_TYPE_STA ||
421988c0f723d0b1abb399e6e71d8bf3f8bf1949a70Johannes Berg	    sdata->vif.type == IEEE80211_IF_TYPE_IBSS) {
42264f851e410ae37a0990212ae34f0c96b641478f7Jan Niehusmann		struct ieee80211_if_sta *ifsta = &sdata->u.sta;
42364f851e410ae37a0990212ae34f0c96b641478f7Jan Niehusmann		queue_work(local->hw.workqueue, &ifsta->work);
42464f851e410ae37a0990212ae34f0c96b641478f7Jan Niehusmann	}
42564f851e410ae37a0990212ae34f0c96b641478f7Jan Niehusmann
42651cb6db0f5654f08a4a6bfa3888dc36a51c2df3eDavid S. Miller	netif_tx_start_all_queues(dev);
4274150c57212ad134765dd78c654a4b9906252b66dJohannes Berg
428b2c258fb11b3fc77a73f8b0453ff1256de812bc6Johannes Berg	return 0;
429636c5d488bc0b349e01cf5bfbf85588134af70a0Johannes Berg err_del_interface:
430636c5d488bc0b349e01cf5bfbf85588134af70a0Johannes Berg	local->ops->remove_interface(local_to_hw(local), &conf);
431636c5d488bc0b349e01cf5bfbf85588134af70a0Johannes Berg err_stop:
432636c5d488bc0b349e01cf5bfbf85588134af70a0Johannes Berg	if (!local->open_count && local->ops->stop)
433636c5d488bc0b349e01cf5bfbf85588134af70a0Johannes Berg		local->ops->stop(local_to_hw(local));
4343e122be089e6fb8d3f322416da4cdbb80ce12927Johannes Berg err_del_bss:
4353e122be089e6fb8d3f322416da4cdbb80ce12927Johannes Berg	sdata->bss = NULL;
4363e122be089e6fb8d3f322416da4cdbb80ce12927Johannes Berg	if (sdata->vif.type == IEEE80211_IF_TYPE_VLAN)
4373e122be089e6fb8d3f322416da4cdbb80ce12927Johannes Berg		list_del(&sdata->u.vlan.list);
438636c5d488bc0b349e01cf5bfbf85588134af70a0Johannes Berg	return res;
439f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc}
440f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc
4414150c57212ad134765dd78c654a4b9906252b66dJohannes Bergstatic int ieee80211_stop(struct net_device *dev)
442f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc{
44344213b5e13c907bf4aa2e73941944f90184c8772Johannes Berg	struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
44444213b5e13c907bf4aa2e73941944f90184c8772Johannes Berg	struct ieee80211_local *local = sdata->local;
4454150c57212ad134765dd78c654a4b9906252b66dJohannes Berg	struct ieee80211_if_init_conf conf;
44607db218396650933abff3c5c1ad1e2a6e0cfedebRon Rindjunsky	struct sta_info *sta;
4474150c57212ad134765dd78c654a4b9906252b66dJohannes Berg
44844213b5e13c907bf4aa2e73941944f90184c8772Johannes Berg	/*
44944213b5e13c907bf4aa2e73941944f90184c8772Johannes Berg	 * Stop TX on this interface first.
45044213b5e13c907bf4aa2e73941944f90184c8772Johannes Berg	 */
45151cb6db0f5654f08a4a6bfa3888dc36a51c2df3eDavid S. Miller	netif_tx_stop_all_queues(dev);
4524150c57212ad134765dd78c654a4b9906252b66dJohannes Berg
45344213b5e13c907bf4aa2e73941944f90184c8772Johannes Berg	/*
45444213b5e13c907bf4aa2e73941944f90184c8772Johannes Berg	 * Now delete all active aggregation sessions.
45544213b5e13c907bf4aa2e73941944f90184c8772Johannes Berg	 */
456d0709a65181beb787ef3f58cfe45536a2bb254c8Johannes Berg	rcu_read_lock();
457d0709a65181beb787ef3f58cfe45536a2bb254c8Johannes Berg
458d0709a65181beb787ef3f58cfe45536a2bb254c8Johannes Berg	list_for_each_entry_rcu(sta, &local->sta_list, list) {
459d0709a65181beb787ef3f58cfe45536a2bb254c8Johannes Berg		if (sta->sdata == sdata)
460f698d856f65c3fea091cc303a135967965c5b880Jasper Bryant-Greene			ieee80211_sta_tear_down_BA_sessions(sdata, sta->addr);
46107db218396650933abff3c5c1ad1e2a6e0cfedebRon Rindjunsky	}
46207db218396650933abff3c5c1ad1e2a6e0cfedebRon Rindjunsky
463d0709a65181beb787ef3f58cfe45536a2bb254c8Johannes Berg	rcu_read_unlock();
464d0709a65181beb787ef3f58cfe45536a2bb254c8Johannes Berg
46544213b5e13c907bf4aa2e73941944f90184c8772Johannes Berg	/*
46644213b5e13c907bf4aa2e73941944f90184c8772Johannes Berg	 * Remove all stations associated with this interface.
46744213b5e13c907bf4aa2e73941944f90184c8772Johannes Berg	 *
46844213b5e13c907bf4aa2e73941944f90184c8772Johannes Berg	 * This must be done before calling ops->remove_interface()
46944213b5e13c907bf4aa2e73941944f90184c8772Johannes Berg	 * because otherwise we can later invoke ops->sta_notify()
47044213b5e13c907bf4aa2e73941944f90184c8772Johannes Berg	 * whenever the STAs are removed, and that invalidates driver
47144213b5e13c907bf4aa2e73941944f90184c8772Johannes Berg	 * assumptions about always getting a vif pointer that is valid
47244213b5e13c907bf4aa2e73941944f90184c8772Johannes Berg	 * (because if we remove a STA after ops->remove_interface()
47344213b5e13c907bf4aa2e73941944f90184c8772Johannes Berg	 * the driver will have removed the vif info already!)
47444213b5e13c907bf4aa2e73941944f90184c8772Johannes Berg	 *
47544213b5e13c907bf4aa2e73941944f90184c8772Johannes Berg	 * We could relax this and only unlink the stations from the
47644213b5e13c907bf4aa2e73941944f90184c8772Johannes Berg	 * hash table and list but keep them on a per-sdata list that
47744213b5e13c907bf4aa2e73941944f90184c8772Johannes Berg	 * will be inserted back again when the interface is brought
47844213b5e13c907bf4aa2e73941944f90184c8772Johannes Berg	 * up again, but I don't currently see a use case for that,
47944213b5e13c907bf4aa2e73941944f90184c8772Johannes Berg	 * except with WDS which gets a STA entry created when it is
48044213b5e13c907bf4aa2e73941944f90184c8772Johannes Berg	 * brought up.
48144213b5e13c907bf4aa2e73941944f90184c8772Johannes Berg	 */
48244213b5e13c907bf4aa2e73941944f90184c8772Johannes Berg	sta_info_flush(local, sdata);
4834150c57212ad134765dd78c654a4b9906252b66dJohannes Berg
484c1428b3f45d152a300e4f18638ebf30ceafda6c3Johannes Berg	/*
485c1428b3f45d152a300e4f18638ebf30ceafda6c3Johannes Berg	 * Don't count this interface for promisc/allmulti while it
486c1428b3f45d152a300e4f18638ebf30ceafda6c3Johannes Berg	 * is down. dev_mc_unsync() will invoke set_multicast_list
487c1428b3f45d152a300e4f18638ebf30ceafda6c3Johannes Berg	 * on the master interface which will sync these down to the
488c1428b3f45d152a300e4f18638ebf30ceafda6c3Johannes Berg	 * hardware as filter flags.
489c1428b3f45d152a300e4f18638ebf30ceafda6c3Johannes Berg	 */
490c1428b3f45d152a300e4f18638ebf30ceafda6c3Johannes Berg	if (sdata->flags & IEEE80211_SDATA_ALLMULTI)
491c1428b3f45d152a300e4f18638ebf30ceafda6c3Johannes Berg		atomic_dec(&local->iff_allmultis);
492c1428b3f45d152a300e4f18638ebf30ceafda6c3Johannes Berg
493c1428b3f45d152a300e4f18638ebf30ceafda6c3Johannes Berg	if (sdata->flags & IEEE80211_SDATA_PROMISC)
494c1428b3f45d152a300e4f18638ebf30ceafda6c3Johannes Berg		atomic_dec(&local->iff_promiscs);
495c1428b3f45d152a300e4f18638ebf30ceafda6c3Johannes Berg
4964150c57212ad134765dd78c654a4b9906252b66dJohannes Berg	dev_mc_unsync(local->mdev, dev);
4974150c57212ad134765dd78c654a4b9906252b66dJohannes Berg
4985dfdaf58d61f06a458529430c24b1191ea4d1a27Johannes Berg	/* APs need special treatment */
49951fb61e76d952e6bc2fbdd9f0d38425fbab1cf31Johannes Berg	if (sdata->vif.type == IEEE80211_IF_TYPE_AP) {
5000ec3ca445931ff0e7ad6ac61d6c5d2aaafe7a9f5Johannes Berg		struct ieee80211_sub_if_data *vlan, *tmp;
5015dfdaf58d61f06a458529430c24b1191ea4d1a27Johannes Berg		struct beacon_data *old_beacon = sdata->u.ap.beacon;
5020ec3ca445931ff0e7ad6ac61d6c5d2aaafe7a9f5Johannes Berg
5035dfdaf58d61f06a458529430c24b1191ea4d1a27Johannes Berg		/* remove beacon */
5045dfdaf58d61f06a458529430c24b1191ea4d1a27Johannes Berg		rcu_assign_pointer(sdata->u.ap.beacon, NULL);
5055dfdaf58d61f06a458529430c24b1191ea4d1a27Johannes Berg		synchronize_rcu();
5065dfdaf58d61f06a458529430c24b1191ea4d1a27Johannes Berg		kfree(old_beacon);
5075dfdaf58d61f06a458529430c24b1191ea4d1a27Johannes Berg
5085dfdaf58d61f06a458529430c24b1191ea4d1a27Johannes Berg		/* down all dependent devices, that is VLANs */
5090ec3ca445931ff0e7ad6ac61d6c5d2aaafe7a9f5Johannes Berg		list_for_each_entry_safe(vlan, tmp, &sdata->u.ap.vlans,
5100ec3ca445931ff0e7ad6ac61d6c5d2aaafe7a9f5Johannes Berg					 u.vlan.list)
5110ec3ca445931ff0e7ad6ac61d6c5d2aaafe7a9f5Johannes Berg			dev_close(vlan->dev);
5120ec3ca445931ff0e7ad6ac61d6c5d2aaafe7a9f5Johannes Berg		WARN_ON(!list_empty(&sdata->u.ap.vlans));
5130ec3ca445931ff0e7ad6ac61d6c5d2aaafe7a9f5Johannes Berg	}
5140ec3ca445931ff0e7ad6ac61d6c5d2aaafe7a9f5Johannes Berg
5154150c57212ad134765dd78c654a4b9906252b66dJohannes Berg	local->open_count--;
516f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc
51751fb61e76d952e6bc2fbdd9f0d38425fbab1cf31Johannes Berg	switch (sdata->vif.type) {
5180ec3ca445931ff0e7ad6ac61d6c5d2aaafe7a9f5Johannes Berg	case IEEE80211_IF_TYPE_VLAN:
5190ec3ca445931ff0e7ad6ac61d6c5d2aaafe7a9f5Johannes Berg		list_del(&sdata->u.vlan.list);
5200ec3ca445931ff0e7ad6ac61d6c5d2aaafe7a9f5Johannes Berg		/* no need to tell driver */
5210ec3ca445931ff0e7ad6ac61d6c5d2aaafe7a9f5Johannes Berg		break;
5224150c57212ad134765dd78c654a4b9906252b66dJohannes Berg	case IEEE80211_IF_TYPE_MNTR:
5233d30d949cf3f9763393f3457721bca3ac2426e42Michael Wu		if (sdata->u.mntr_flags & MONITOR_FLAG_COOK_FRAMES) {
5243d30d949cf3f9763393f3457721bca3ac2426e42Michael Wu			local->cooked_mntrs--;
5253d30d949cf3f9763393f3457721bca3ac2426e42Michael Wu			break;
5263d30d949cf3f9763393f3457721bca3ac2426e42Michael Wu		}
5273d30d949cf3f9763393f3457721bca3ac2426e42Michael Wu
5284150c57212ad134765dd78c654a4b9906252b66dJohannes Berg		local->monitors--;
5298cc9a73914b07b5908d8a59320f4557fc9639f2eMichael Wu		if (local->monitors == 0)
5308b393f1dc76acbe65a97a4e51f8144f4a65fa1c9Michael Wu			local->hw.conf.flags &= ~IEEE80211_CONF_RADIOTAP;
5318cc9a73914b07b5908d8a59320f4557fc9639f2eMichael Wu
5328cc9a73914b07b5908d8a59320f4557fc9639f2eMichael Wu		if (sdata->u.mntr_flags & MONITOR_FLAG_FCSFAIL)
5338cc9a73914b07b5908d8a59320f4557fc9639f2eMichael Wu			local->fif_fcsfail--;
5348cc9a73914b07b5908d8a59320f4557fc9639f2eMichael Wu		if (sdata->u.mntr_flags & MONITOR_FLAG_PLCPFAIL)
5358cc9a73914b07b5908d8a59320f4557fc9639f2eMichael Wu			local->fif_plcpfail--;
5368cc9a73914b07b5908d8a59320f4557fc9639f2eMichael Wu		if (sdata->u.mntr_flags & MONITOR_FLAG_CONTROL)
5378cc9a73914b07b5908d8a59320f4557fc9639f2eMichael Wu			local->fif_control--;
5388cc9a73914b07b5908d8a59320f4557fc9639f2eMichael Wu		if (sdata->u.mntr_flags & MONITOR_FLAG_OTHER_BSS)
5398cc9a73914b07b5908d8a59320f4557fc9639f2eMichael Wu			local->fif_other_bss--;
5408cc9a73914b07b5908d8a59320f4557fc9639f2eMichael Wu
541b9e40857682ecfc5bcd0356a23ff409883ffb982David S. Miller		netif_addr_lock_bh(local->mdev);
5428cc9a73914b07b5908d8a59320f4557fc9639f2eMichael Wu		ieee80211_configure_filter(local);
543b9e40857682ecfc5bcd0356a23ff409883ffb982David S. Miller		netif_addr_unlock_bh(local->mdev);
5444150c57212ad134765dd78c654a4b9906252b66dJohannes Berg		break;
545b2c258fb11b3fc77a73f8b0453ff1256de812bc6Johannes Berg	case IEEE80211_IF_TYPE_STA:
546b2c258fb11b3fc77a73f8b0453ff1256de812bc6Johannes Berg	case IEEE80211_IF_TYPE_IBSS:
54748c2fc59aa415ba92be0ad3a7e741c46883e3944Tomas Winkler		sdata->u.sta.state = IEEE80211_STA_MLME_DISABLED;
548ad81b2f97d42e13ef78bb3798e046cd5f0492980Assaf Krauss		memset(sdata->u.sta.bssid, 0, ETH_ALEN);
549b2c258fb11b3fc77a73f8b0453ff1256de812bc6Johannes Berg		del_timer_sync(&sdata->u.sta.timer);
5502a8a9a88fc1b18f5c45244d0ef8a5352f6cf761fJohannes Berg		/*
551b7413430d4d2a6168e68231d9f93763047b6d60cJohannes Berg		 * If the timer fired while we waited for it, it will have
552b7413430d4d2a6168e68231d9f93763047b6d60cJohannes Berg		 * requeued the work. Now the work will be running again
553b7413430d4d2a6168e68231d9f93763047b6d60cJohannes Berg		 * but will not rearm the timer again because it checks
554b7413430d4d2a6168e68231d9f93763047b6d60cJohannes Berg		 * whether the interface is running, which, at this point,
555b7413430d4d2a6168e68231d9f93763047b6d60cJohannes Berg		 * it no longer is.
556b7413430d4d2a6168e68231d9f93763047b6d60cJohannes Berg		 */
557b7413430d4d2a6168e68231d9f93763047b6d60cJohannes Berg		cancel_work_sync(&sdata->u.sta.work);
558b7413430d4d2a6168e68231d9f93763047b6d60cJohannes Berg		/*
55979010420cc3f78eab911598bfdd29c4b06a83e1fJohannes Berg		 * When we get here, the interface is marked down.
56079010420cc3f78eab911598bfdd29c4b06a83e1fJohannes Berg		 * Call synchronize_rcu() to wait for the RX path
56179010420cc3f78eab911598bfdd29c4b06a83e1fJohannes Berg		 * should it be using the interface and enqueuing
56279010420cc3f78eab911598bfdd29c4b06a83e1fJohannes Berg		 * frames at this very time on another CPU.
5632a8a9a88fc1b18f5c45244d0ef8a5352f6cf761fJohannes Berg		 */
56479010420cc3f78eab911598bfdd29c4b06a83e1fJohannes Berg		synchronize_rcu();
565b2c258fb11b3fc77a73f8b0453ff1256de812bc6Johannes Berg		skb_queue_purge(&sdata->u.sta.skb_queue);
5662a8a9a88fc1b18f5c45244d0ef8a5352f6cf761fJohannes Berg
567a10605e599a7873417043fe2bb559abe719f8a1aZhu Yi		sdata->u.sta.flags &= ~IEEE80211_STA_PRIVACY_INVOKED;
568a10605e599a7873417043fe2bb559abe719f8a1aZhu Yi		kfree(sdata->u.sta.extra_ie);
569a10605e599a7873417043fe2bb559abe719f8a1aZhu Yi		sdata->u.sta.extra_ie = NULL;
570a10605e599a7873417043fe2bb559abe719f8a1aZhu Yi		sdata->u.sta.extra_ie_len = 0;
5714150c57212ad134765dd78c654a4b9906252b66dJohannes Berg		/* fall through */
572472dbc45dc1966284de72d7de15690c17ed2cf33Johannes Berg	case IEEE80211_IF_TYPE_MESH_POINT:
573472dbc45dc1966284de72d7de15690c17ed2cf33Johannes Berg		if (ieee80211_vif_is_mesh(&sdata->vif)) {
574472dbc45dc1966284de72d7de15690c17ed2cf33Johannes Berg			/* allmulti is always set on mesh ifaces */
575472dbc45dc1966284de72d7de15690c17ed2cf33Johannes Berg			atomic_dec(&local->iff_allmultis);
576472dbc45dc1966284de72d7de15690c17ed2cf33Johannes Berg			ieee80211_stop_mesh(sdata);
577472dbc45dc1966284de72d7de15690c17ed2cf33Johannes Berg		}
578472dbc45dc1966284de72d7de15690c17ed2cf33Johannes Berg		/* fall through */
5794150c57212ad134765dd78c654a4b9906252b66dJohannes Berg	default:
5805bc75728fd43bb15b46f16ef465bcf9d487393cfJohannes Berg		if (local->scan_sdata == sdata) {
5815bc75728fd43bb15b46f16ef465bcf9d487393cfJohannes Berg			if (!local->ops->hw_scan)
5825bc75728fd43bb15b46f16ef465bcf9d487393cfJohannes Berg				cancel_delayed_work_sync(&local->scan_work);
5835bc75728fd43bb15b46f16ef465bcf9d487393cfJohannes Berg			/*
5845bc75728fd43bb15b46f16ef465bcf9d487393cfJohannes Berg			 * The software scan can no longer run now, so we can
5855bc75728fd43bb15b46f16ef465bcf9d487393cfJohannes Berg			 * clear out the scan_sdata reference. However, the
5865bc75728fd43bb15b46f16ef465bcf9d487393cfJohannes Berg			 * hardware scan may still be running. The complete
5875bc75728fd43bb15b46f16ef465bcf9d487393cfJohannes Berg			 * function must be prepared to handle a NULL value.
5885bc75728fd43bb15b46f16ef465bcf9d487393cfJohannes Berg			 */
5895bc75728fd43bb15b46f16ef465bcf9d487393cfJohannes Berg			local->scan_sdata = NULL;
5905bc75728fd43bb15b46f16ef465bcf9d487393cfJohannes Berg			/*
5915bc75728fd43bb15b46f16ef465bcf9d487393cfJohannes Berg			 * The memory barrier guarantees that another CPU
5925bc75728fd43bb15b46f16ef465bcf9d487393cfJohannes Berg			 * that is hardware-scanning will now see the fact
5935bc75728fd43bb15b46f16ef465bcf9d487393cfJohannes Berg			 * that this interface is gone.
5945bc75728fd43bb15b46f16ef465bcf9d487393cfJohannes Berg			 */
5955bc75728fd43bb15b46f16ef465bcf9d487393cfJohannes Berg			smp_mb();
5965bc75728fd43bb15b46f16ef465bcf9d487393cfJohannes Berg			/*
5975bc75728fd43bb15b46f16ef465bcf9d487393cfJohannes Berg			 * If software scanning, complete the scan but since
5985bc75728fd43bb15b46f16ef465bcf9d487393cfJohannes Berg			 * the scan_sdata is NULL already don't send out a
5995bc75728fd43bb15b46f16ef465bcf9d487393cfJohannes Berg			 * scan event to userspace -- the scan is incomplete.
6005bc75728fd43bb15b46f16ef465bcf9d487393cfJohannes Berg			 */
601c2b13452b283f9c4a5b02a6b53ed6416ebf4c03cJohannes Berg			if (local->sw_scanning)
6025bc75728fd43bb15b46f16ef465bcf9d487393cfJohannes Berg				ieee80211_scan_completed(&local->hw);
6035bc75728fd43bb15b46f16ef465bcf9d487393cfJohannes Berg		}
6045bc75728fd43bb15b46f16ef465bcf9d487393cfJohannes Berg
60532bfd35d4b63bd63de4bb0d791ef049c3c868726Johannes Berg		conf.vif = &sdata->vif;
60651fb61e76d952e6bc2fbdd9f0d38425fbab1cf31Johannes Berg		conf.type = sdata->vif.type;
6074150c57212ad134765dd78c654a4b9906252b66dJohannes Berg		conf.mac_addr = dev->dev_addr;
60811a843b7e16062389c53ba393c7913956e034eb2Johannes Berg		/* disable all keys for as long as this netdev is down */
60911a843b7e16062389c53ba393c7913956e034eb2Johannes Berg		ieee80211_disable_keys(sdata);
6104150c57212ad134765dd78c654a4b9906252b66dJohannes Berg		local->ops->remove_interface(local_to_hw(local), &conf);
611f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc	}
612f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc
6133e122be089e6fb8d3f322416da4cdbb80ce12927Johannes Berg	sdata->bss = NULL;
6143e122be089e6fb8d3f322416da4cdbb80ce12927Johannes Berg
615b2c258fb11b3fc77a73f8b0453ff1256de812bc6Johannes Berg	if (local->open_count == 0) {
616b2c258fb11b3fc77a73f8b0453ff1256de812bc6Johannes Berg		if (netif_running(local->mdev))
617b2c258fb11b3fc77a73f8b0453ff1256de812bc6Johannes Berg			dev_close(local->mdev);
6184150c57212ad134765dd78c654a4b9906252b66dJohannes Berg
619b2c258fb11b3fc77a73f8b0453ff1256de812bc6Johannes Berg		if (local->ops->stop)
620b2c258fb11b3fc77a73f8b0453ff1256de812bc6Johannes Berg			local->ops->stop(local_to_hw(local));
6214150c57212ad134765dd78c654a4b9906252b66dJohannes Berg
622cdcb006fbe7a74b5f7827f5c5c27e11399a2fab7Ivo van Doorn		ieee80211_led_radio(local, 0);
623cdcb006fbe7a74b5f7827f5c5c27e11399a2fab7Ivo van Doorn
624ea0c925370b33baf168bb33782c613468c1aa119Ivo van Doorn		flush_workqueue(local->hw.workqueue);
625ea0c925370b33baf168bb33782c613468c1aa119Ivo van Doorn
626b2c258fb11b3fc77a73f8b0453ff1256de812bc6Johannes Berg		tasklet_disable(&local->tx_pending_tasklet);
627b2c258fb11b3fc77a73f8b0453ff1256de812bc6Johannes Berg		tasklet_disable(&local->tasklet);
628b2c258fb11b3fc77a73f8b0453ff1256de812bc6Johannes Berg	}
629b2c258fb11b3fc77a73f8b0453ff1256de812bc6Johannes Berg
630f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc	return 0;
631f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc}
632f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc
633f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Bencstatic void ieee80211_set_multicast_list(struct net_device *dev)
634f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc{
635f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc	struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
636f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc	struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
6374150c57212ad134765dd78c654a4b9906252b66dJohannes Berg	int allmulti, promisc, sdata_allmulti, sdata_promisc;
638f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc
6394150c57212ad134765dd78c654a4b9906252b66dJohannes Berg	allmulti = !!(dev->flags & IFF_ALLMULTI);
6404150c57212ad134765dd78c654a4b9906252b66dJohannes Berg	promisc = !!(dev->flags & IFF_PROMISC);
641b52f2198ac889561d341c6990d669a671f93f450Johannes Berg	sdata_allmulti = !!(sdata->flags & IEEE80211_SDATA_ALLMULTI);
642b52f2198ac889561d341c6990d669a671f93f450Johannes Berg	sdata_promisc = !!(sdata->flags & IEEE80211_SDATA_PROMISC);
6434150c57212ad134765dd78c654a4b9906252b66dJohannes Berg
6444150c57212ad134765dd78c654a4b9906252b66dJohannes Berg	if (allmulti != sdata_allmulti) {
6454150c57212ad134765dd78c654a4b9906252b66dJohannes Berg		if (dev->flags & IFF_ALLMULTI)
64653918994b7c8c3bf0af5f641e1f299856799d883Johannes Berg			atomic_inc(&local->iff_allmultis);
6474150c57212ad134765dd78c654a4b9906252b66dJohannes Berg		else
64853918994b7c8c3bf0af5f641e1f299856799d883Johannes Berg			atomic_dec(&local->iff_allmultis);
64913262ffd4902805acad2618c12b41fcaa6c50791Jiri Slaby		sdata->flags ^= IEEE80211_SDATA_ALLMULTI;
650f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc	}
6514150c57212ad134765dd78c654a4b9906252b66dJohannes Berg
6524150c57212ad134765dd78c654a4b9906252b66dJohannes Berg	if (promisc != sdata_promisc) {
6534150c57212ad134765dd78c654a4b9906252b66dJohannes Berg		if (dev->flags & IFF_PROMISC)
65453918994b7c8c3bf0af5f641e1f299856799d883Johannes Berg			atomic_inc(&local->iff_promiscs);
6554150c57212ad134765dd78c654a4b9906252b66dJohannes Berg		else
65653918994b7c8c3bf0af5f641e1f299856799d883Johannes Berg			atomic_dec(&local->iff_promiscs);
65713262ffd4902805acad2618c12b41fcaa6c50791Jiri Slaby		sdata->flags ^= IEEE80211_SDATA_PROMISC;
658f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc	}
6594150c57212ad134765dd78c654a4b9906252b66dJohannes Berg
6604150c57212ad134765dd78c654a4b9906252b66dJohannes Berg	dev_mc_sync(local->mdev, dev);
661f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc}
662f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc
6633b04ddde02cf1b6f14f2697da5c20eca5715017fStephen Hemmingerstatic const struct header_ops ieee80211_header_ops = {
6643b04ddde02cf1b6f14f2697da5c20eca5715017fStephen Hemminger	.create		= eth_header,
6653b04ddde02cf1b6f14f2697da5c20eca5715017fStephen Hemminger	.parse		= header_parse_80211,
6663b04ddde02cf1b6f14f2697da5c20eca5715017fStephen Hemminger	.rebuild	= eth_rebuild_header,
6673b04ddde02cf1b6f14f2697da5c20eca5715017fStephen Hemminger	.cache		= eth_header_cache,
6683b04ddde02cf1b6f14f2697da5c20eca5715017fStephen Hemminger	.cache_update	= eth_header_cache_update,
6693b04ddde02cf1b6f14f2697da5c20eca5715017fStephen Hemminger};
6703b04ddde02cf1b6f14f2697da5c20eca5715017fStephen Hemminger
671b2c258fb11b3fc77a73f8b0453ff1256de812bc6Johannes Bergvoid ieee80211_if_setup(struct net_device *dev)
672f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc{
673b2c258fb11b3fc77a73f8b0453ff1256de812bc6Johannes Berg	ether_setup(dev);
674b2c258fb11b3fc77a73f8b0453ff1256de812bc6Johannes Berg	dev->hard_start_xmit = ieee80211_subif_start_xmit;
675b2c258fb11b3fc77a73f8b0453ff1256de812bc6Johannes Berg	dev->wireless_handlers = &ieee80211_iw_handler_def;
676b2c258fb11b3fc77a73f8b0453ff1256de812bc6Johannes Berg	dev->set_multicast_list = ieee80211_set_multicast_list;
677b2c258fb11b3fc77a73f8b0453ff1256de812bc6Johannes Berg	dev->change_mtu = ieee80211_change_mtu;
678b2c258fb11b3fc77a73f8b0453ff1256de812bc6Johannes Berg	dev->open = ieee80211_open;
679b2c258fb11b3fc77a73f8b0453ff1256de812bc6Johannes Berg	dev->stop = ieee80211_stop;
68075636525fbfa78fa33fd754c89785cfde750acd3Johannes Berg	dev->destructor = free_netdev;
681bdbe819540f3365249095692118dbfeee308140dLuis Carlos Cobo	/* we will validate the address ourselves in ->open */
682bdbe819540f3365249095692118dbfeee308140dLuis Carlos Cobo	dev->validate_addr = NULL;
683b2c258fb11b3fc77a73f8b0453ff1256de812bc6Johannes Berg}
684f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc
685b2c258fb11b3fc77a73f8b0453ff1256de812bc6Johannes Berg/* everything else */
686b2c258fb11b3fc77a73f8b0453ff1256de812bc6Johannes Berg
6879d139c810a2aa17365cc548d0cd2a189d8433c65Johannes Bergint ieee80211_if_config(struct ieee80211_sub_if_data *sdata, u32 changed)
688b2c258fb11b3fc77a73f8b0453ff1256de812bc6Johannes Berg{
6899d139c810a2aa17365cc548d0cd2a189d8433c65Johannes Berg	struct ieee80211_local *local = sdata->local;
690b2c258fb11b3fc77a73f8b0453ff1256de812bc6Johannes Berg	struct ieee80211_if_conf conf;
691b2c258fb11b3fc77a73f8b0453ff1256de812bc6Johannes Berg
6929d139c810a2aa17365cc548d0cd2a189d8433c65Johannes Berg	if (WARN_ON(!netif_running(sdata->dev)))
6939d139c810a2aa17365cc548d0cd2a189d8433c65Johannes Berg		return 0;
6949d139c810a2aa17365cc548d0cd2a189d8433c65Johannes Berg
6959d139c810a2aa17365cc548d0cd2a189d8433c65Johannes Berg	if (!local->ops->config_interface)
696f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc		return 0;
697f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc
698b2c258fb11b3fc77a73f8b0453ff1256de812bc6Johannes Berg	memset(&conf, 0, sizeof(conf));
6999d139c810a2aa17365cc548d0cd2a189d8433c65Johannes Berg	conf.changed = changed;
7009d139c810a2aa17365cc548d0cd2a189d8433c65Johannes Berg
70151fb61e76d952e6bc2fbdd9f0d38425fbab1cf31Johannes Berg	if (sdata->vif.type == IEEE80211_IF_TYPE_STA ||
70251fb61e76d952e6bc2fbdd9f0d38425fbab1cf31Johannes Berg	    sdata->vif.type == IEEE80211_IF_TYPE_IBSS) {
7034150c57212ad134765dd78c654a4b9906252b66dJohannes Berg		conf.bssid = sdata->u.sta.bssid;
704b2c258fb11b3fc77a73f8b0453ff1256de812bc6Johannes Berg		conf.ssid = sdata->u.sta.ssid;
705b2c258fb11b3fc77a73f8b0453ff1256de812bc6Johannes Berg		conf.ssid_len = sdata->u.sta.ssid_len;
70651fb61e76d952e6bc2fbdd9f0d38425fbab1cf31Johannes Berg	} else if (sdata->vif.type == IEEE80211_IF_TYPE_AP) {
7079d139c810a2aa17365cc548d0cd2a189d8433c65Johannes Berg		conf.bssid = sdata->dev->dev_addr;
708b2c258fb11b3fc77a73f8b0453ff1256de812bc6Johannes Berg		conf.ssid = sdata->u.ap.ssid;
709b2c258fb11b3fc77a73f8b0453ff1256de812bc6Johannes Berg		conf.ssid_len = sdata->u.ap.ssid_len;
7109d139c810a2aa17365cc548d0cd2a189d8433c65Johannes Berg	} else if (ieee80211_vif_is_mesh(&sdata->vif)) {
7119d139c810a2aa17365cc548d0cd2a189d8433c65Johannes Berg		u8 zero[ETH_ALEN] = { 0 };
7129d139c810a2aa17365cc548d0cd2a189d8433c65Johannes Berg		conf.bssid = zero;
7139d139c810a2aa17365cc548d0cd2a189d8433c65Johannes Berg		conf.ssid = zero;
7149d139c810a2aa17365cc548d0cd2a189d8433c65Johannes Berg		conf.ssid_len = 0;
7159d139c810a2aa17365cc548d0cd2a189d8433c65Johannes Berg	} else {
7169d139c810a2aa17365cc548d0cd2a189d8433c65Johannes Berg		WARN_ON(1);
7179d139c810a2aa17365cc548d0cd2a189d8433c65Johannes Berg		return -EINVAL;
718f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc	}
719f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc
7209d139c810a2aa17365cc548d0cd2a189d8433c65Johannes Berg	if (WARN_ON(!conf.bssid && (changed & IEEE80211_IFCC_BSSID)))
7219d139c810a2aa17365cc548d0cd2a189d8433c65Johannes Berg		return -EINVAL;
722f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc
7239d139c810a2aa17365cc548d0cd2a189d8433c65Johannes Berg	if (WARN_ON(!conf.ssid && (changed & IEEE80211_IFCC_SSID)))
7249d139c810a2aa17365cc548d0cd2a189d8433c65Johannes Berg		return -EINVAL;
725f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc
7269d139c810a2aa17365cc548d0cd2a189d8433c65Johannes Berg	return local->ops->config_interface(local_to_hw(local),
7279d139c810a2aa17365cc548d0cd2a189d8433c65Johannes Berg					    &sdata->vif, &conf);
728b2c258fb11b3fc77a73f8b0453ff1256de812bc6Johannes Berg}
729f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc
730b2c258fb11b3fc77a73f8b0453ff1256de812bc6Johannes Bergint ieee80211_hw_config(struct ieee80211_local *local)
731b2c258fb11b3fc77a73f8b0453ff1256de812bc6Johannes Berg{
732b2c258fb11b3fc77a73f8b0453ff1256de812bc6Johannes Berg	struct ieee80211_channel *chan;
733b2c258fb11b3fc77a73f8b0453ff1256de812bc6Johannes Berg	int ret = 0;
734f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc
735c2b13452b283f9c4a5b02a6b53ed6416ebf4c03cJohannes Berg	if (local->sw_scanning)
736b2c258fb11b3fc77a73f8b0453ff1256de812bc6Johannes Berg		chan = local->scan_channel;
7378318d78a44d49ac1edf2bdec7299de3617c4232eJohannes Berg	else
738b2c258fb11b3fc77a73f8b0453ff1256de812bc6Johannes Berg		chan = local->oper_channel;
739f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc
7408318d78a44d49ac1edf2bdec7299de3617c4232eJohannes Berg	local->hw.conf.channel = chan;
7418318d78a44d49ac1edf2bdec7299de3617c4232eJohannes Berg
7428318d78a44d49ac1edf2bdec7299de3617c4232eJohannes Berg	if (!local->hw.conf.power_level)
7438318d78a44d49ac1edf2bdec7299de3617c4232eJohannes Berg		local->hw.conf.power_level = chan->max_power;
7448318d78a44d49ac1edf2bdec7299de3617c4232eJohannes Berg	else
7458318d78a44d49ac1edf2bdec7299de3617c4232eJohannes Berg		local->hw.conf.power_level = min(chan->max_power,
7468318d78a44d49ac1edf2bdec7299de3617c4232eJohannes Berg					       local->hw.conf.power_level);
7478318d78a44d49ac1edf2bdec7299de3617c4232eJohannes Berg
7488318d78a44d49ac1edf2bdec7299de3617c4232eJohannes Berg	local->hw.conf.max_antenna_gain = chan->max_antenna_gain;
749f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc
750b2c258fb11b3fc77a73f8b0453ff1256de812bc6Johannes Berg#ifdef CONFIG_MAC80211_VERBOSE_DEBUG
7518318d78a44d49ac1edf2bdec7299de3617c4232eJohannes Berg	printk(KERN_DEBUG "%s: HW CONFIG: freq=%d\n",
7528318d78a44d49ac1edf2bdec7299de3617c4232eJohannes Berg	       wiphy_name(local->hw.wiphy), chan->center_freq);
7538318d78a44d49ac1edf2bdec7299de3617c4232eJohannes Berg#endif
754b2c258fb11b3fc77a73f8b0453ff1256de812bc6Johannes Berg
755f7c4daed99fba15e4e48df464031f4ac7c32e4c9Michael Buesch	if (local->open_count)
756b2c258fb11b3fc77a73f8b0453ff1256de812bc6Johannes Berg		ret = local->ops->config(local_to_hw(local), &local->hw.conf);
757f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc
758b2c258fb11b3fc77a73f8b0453ff1256de812bc6Johannes Berg	return ret;
759b2c258fb11b3fc77a73f8b0453ff1256de812bc6Johannes Berg}
760f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc
761d3c990fb26b78f60614885d9ecaf7b7686b7b098Ron Rindjunsky/**
76238668c059f5202f5fd9612391f9aa1b38a97241bTomas Winkler * ieee80211_handle_ht should be used only after legacy configuration
76338668c059f5202f5fd9612391f9aa1b38a97241bTomas Winkler * has been determined namely band, as ht configuration depends upon
76438668c059f5202f5fd9612391f9aa1b38a97241bTomas Winkler * the hardware's HT abilities for a _specific_ band.
765d3c990fb26b78f60614885d9ecaf7b7686b7b098Ron Rindjunsky */
76638668c059f5202f5fd9612391f9aa1b38a97241bTomas Winkleru32 ieee80211_handle_ht(struct ieee80211_local *local, int enable_ht,
767d3c990fb26b78f60614885d9ecaf7b7686b7b098Ron Rindjunsky			   struct ieee80211_ht_info *req_ht_cap,
768d3c990fb26b78f60614885d9ecaf7b7686b7b098Ron Rindjunsky			   struct ieee80211_ht_bss_info *req_bss_cap)
769d3c990fb26b78f60614885d9ecaf7b7686b7b098Ron Rindjunsky{
770d3c990fb26b78f60614885d9ecaf7b7686b7b098Ron Rindjunsky	struct ieee80211_conf *conf = &local->hw.conf;
7718318d78a44d49ac1edf2bdec7299de3617c4232eJohannes Berg	struct ieee80211_supported_band *sband;
77238668c059f5202f5fd9612391f9aa1b38a97241bTomas Winkler	struct ieee80211_ht_info ht_conf;
77338668c059f5202f5fd9612391f9aa1b38a97241bTomas Winkler	struct ieee80211_ht_bss_info ht_bss_conf;
77438668c059f5202f5fd9612391f9aa1b38a97241bTomas Winkler	u32 changed = 0;
775edcdf8b21ac920e06b4180246123fe43b022e020Ron Rindjunsky	int i;
776edcdf8b21ac920e06b4180246123fe43b022e020Ron Rindjunsky	u8 max_tx_streams = IEEE80211_HT_CAP_MAX_STREAMS;
777edcdf8b21ac920e06b4180246123fe43b022e020Ron Rindjunsky	u8 tx_mcs_set_cap;
778d3c990fb26b78f60614885d9ecaf7b7686b7b098Ron Rindjunsky
7798318d78a44d49ac1edf2bdec7299de3617c4232eJohannes Berg	sband = local->hw.wiphy->bands[conf->channel->band];
7808318d78a44d49ac1edf2bdec7299de3617c4232eJohannes Berg
781edcdf8b21ac920e06b4180246123fe43b022e020Ron Rindjunsky	memset(&ht_conf, 0, sizeof(struct ieee80211_ht_info));
782edcdf8b21ac920e06b4180246123fe43b022e020Ron Rindjunsky	memset(&ht_bss_conf, 0, sizeof(struct ieee80211_ht_bss_info));
783edcdf8b21ac920e06b4180246123fe43b022e020Ron Rindjunsky
784d3c990fb26b78f60614885d9ecaf7b7686b7b098Ron Rindjunsky	/* HT is not supported */
7858318d78a44d49ac1edf2bdec7299de3617c4232eJohannes Berg	if (!sband->ht_info.ht_supported) {
786d3c990fb26b78f60614885d9ecaf7b7686b7b098Ron Rindjunsky		conf->flags &= ~IEEE80211_CONF_SUPPORT_HT_MODE;
787edcdf8b21ac920e06b4180246123fe43b022e020Ron Rindjunsky		goto out;
788d3c990fb26b78f60614885d9ecaf7b7686b7b098Ron Rindjunsky	}
789d3c990fb26b78f60614885d9ecaf7b7686b7b098Ron Rindjunsky
790edcdf8b21ac920e06b4180246123fe43b022e020Ron Rindjunsky	/* disable HT */
791edcdf8b21ac920e06b4180246123fe43b022e020Ron Rindjunsky	if (!enable_ht) {
792edcdf8b21ac920e06b4180246123fe43b022e020Ron Rindjunsky		if (conf->flags & IEEE80211_CONF_SUPPORT_HT_MODE)
79338668c059f5202f5fd9612391f9aa1b38a97241bTomas Winkler			changed |= BSS_CHANGED_HT;
794edcdf8b21ac920e06b4180246123fe43b022e020Ron Rindjunsky		conf->flags &= ~IEEE80211_CONF_SUPPORT_HT_MODE;
795edcdf8b21ac920e06b4180246123fe43b022e020Ron Rindjunsky		conf->ht_conf.ht_supported = 0;
796edcdf8b21ac920e06b4180246123fe43b022e020Ron Rindjunsky		goto out;
797edcdf8b21ac920e06b4180246123fe43b022e020Ron Rindjunsky	}
79838668c059f5202f5fd9612391f9aa1b38a97241bTomas Winkler
79938668c059f5202f5fd9612391f9aa1b38a97241bTomas Winkler
800edcdf8b21ac920e06b4180246123fe43b022e020Ron Rindjunsky	if (!(conf->flags & IEEE80211_CONF_SUPPORT_HT_MODE))
801edcdf8b21ac920e06b4180246123fe43b022e020Ron Rindjunsky		changed |= BSS_CHANGED_HT;
80238668c059f5202f5fd9612391f9aa1b38a97241bTomas Winkler
803edcdf8b21ac920e06b4180246123fe43b022e020Ron Rindjunsky	conf->flags |= IEEE80211_CONF_SUPPORT_HT_MODE;
804edcdf8b21ac920e06b4180246123fe43b022e020Ron Rindjunsky	ht_conf.ht_supported = 1;
80538668c059f5202f5fd9612391f9aa1b38a97241bTomas Winkler
806edcdf8b21ac920e06b4180246123fe43b022e020Ron Rindjunsky	ht_conf.cap = req_ht_cap->cap & sband->ht_info.cap;
80700c5ae2fa0f8191a1b204e71f0ee11359e3b2c06Tomas Winkler	ht_conf.cap &= ~(IEEE80211_HT_CAP_SM_PS);
80800c5ae2fa0f8191a1b204e71f0ee11359e3b2c06Tomas Winkler	ht_conf.cap |= sband->ht_info.cap & IEEE80211_HT_CAP_SM_PS;
809edcdf8b21ac920e06b4180246123fe43b022e020Ron Rindjunsky	ht_bss_conf.primary_channel = req_bss_cap->primary_channel;
810edcdf8b21ac920e06b4180246123fe43b022e020Ron Rindjunsky	ht_bss_conf.bss_cap = req_bss_cap->bss_cap;
811edcdf8b21ac920e06b4180246123fe43b022e020Ron Rindjunsky	ht_bss_conf.bss_op_mode = req_bss_cap->bss_op_mode;
81238668c059f5202f5fd9612391f9aa1b38a97241bTomas Winkler
813edcdf8b21ac920e06b4180246123fe43b022e020Ron Rindjunsky	ht_conf.ampdu_factor = req_ht_cap->ampdu_factor;
814edcdf8b21ac920e06b4180246123fe43b022e020Ron Rindjunsky	ht_conf.ampdu_density = req_ht_cap->ampdu_density;
81538668c059f5202f5fd9612391f9aa1b38a97241bTomas Winkler
816edcdf8b21ac920e06b4180246123fe43b022e020Ron Rindjunsky	/* Bits 96-100 */
817edcdf8b21ac920e06b4180246123fe43b022e020Ron Rindjunsky	tx_mcs_set_cap = sband->ht_info.supp_mcs_set[12];
818edcdf8b21ac920e06b4180246123fe43b022e020Ron Rindjunsky
819edcdf8b21ac920e06b4180246123fe43b022e020Ron Rindjunsky	/* configure suppoerted Tx MCS according to requested MCS
820edcdf8b21ac920e06b4180246123fe43b022e020Ron Rindjunsky	 * (based in most cases on Rx capabilities of peer) and self
821edcdf8b21ac920e06b4180246123fe43b022e020Ron Rindjunsky	 * Tx MCS capabilities (as defined by low level driver HW
822edcdf8b21ac920e06b4180246123fe43b022e020Ron Rindjunsky	 * Tx capabilities) */
823edcdf8b21ac920e06b4180246123fe43b022e020Ron Rindjunsky	if (!(tx_mcs_set_cap & IEEE80211_HT_CAP_MCS_TX_DEFINED))
824edcdf8b21ac920e06b4180246123fe43b022e020Ron Rindjunsky		goto check_changed;
825d3c990fb26b78f60614885d9ecaf7b7686b7b098Ron Rindjunsky
826edcdf8b21ac920e06b4180246123fe43b022e020Ron Rindjunsky	/* Counting from 0 therfore + 1 */
827edcdf8b21ac920e06b4180246123fe43b022e020Ron Rindjunsky	if (tx_mcs_set_cap & IEEE80211_HT_CAP_MCS_TX_RX_DIFF)
828edcdf8b21ac920e06b4180246123fe43b022e020Ron Rindjunsky		max_tx_streams = ((tx_mcs_set_cap &
829edcdf8b21ac920e06b4180246123fe43b022e020Ron Rindjunsky				IEEE80211_HT_CAP_MCS_TX_STREAMS) >> 2) + 1;
830edcdf8b21ac920e06b4180246123fe43b022e020Ron Rindjunsky
831edcdf8b21ac920e06b4180246123fe43b022e020Ron Rindjunsky	for (i = 0; i < max_tx_streams; i++)
832edcdf8b21ac920e06b4180246123fe43b022e020Ron Rindjunsky		ht_conf.supp_mcs_set[i] =
833edcdf8b21ac920e06b4180246123fe43b022e020Ron Rindjunsky			sband->ht_info.supp_mcs_set[i] &
834edcdf8b21ac920e06b4180246123fe43b022e020Ron Rindjunsky					req_ht_cap->supp_mcs_set[i];
835edcdf8b21ac920e06b4180246123fe43b022e020Ron Rindjunsky
836edcdf8b21ac920e06b4180246123fe43b022e020Ron Rindjunsky	if (tx_mcs_set_cap & IEEE80211_HT_CAP_MCS_TX_UEQM)
837edcdf8b21ac920e06b4180246123fe43b022e020Ron Rindjunsky		for (i = IEEE80211_SUPP_MCS_SET_UEQM;
838edcdf8b21ac920e06b4180246123fe43b022e020Ron Rindjunsky		     i < IEEE80211_SUPP_MCS_SET_LEN; i++)
839edcdf8b21ac920e06b4180246123fe43b022e020Ron Rindjunsky			ht_conf.supp_mcs_set[i] =
840edcdf8b21ac920e06b4180246123fe43b022e020Ron Rindjunsky				sband->ht_info.supp_mcs_set[i] &
841edcdf8b21ac920e06b4180246123fe43b022e020Ron Rindjunsky					req_ht_cap->supp_mcs_set[i];
842edcdf8b21ac920e06b4180246123fe43b022e020Ron Rindjunsky
843edcdf8b21ac920e06b4180246123fe43b022e020Ron Rindjunskycheck_changed:
844edcdf8b21ac920e06b4180246123fe43b022e020Ron Rindjunsky	/* if bss configuration changed store the new one */
845edcdf8b21ac920e06b4180246123fe43b022e020Ron Rindjunsky	if (memcmp(&conf->ht_conf, &ht_conf, sizeof(ht_conf)) ||
846edcdf8b21ac920e06b4180246123fe43b022e020Ron Rindjunsky	    memcmp(&conf->ht_bss_conf, &ht_bss_conf, sizeof(ht_bss_conf))) {
847edcdf8b21ac920e06b4180246123fe43b022e020Ron Rindjunsky		changed |= BSS_CHANGED_HT;
848edcdf8b21ac920e06b4180246123fe43b022e020Ron Rindjunsky		memcpy(&conf->ht_conf, &ht_conf, sizeof(ht_conf));
849edcdf8b21ac920e06b4180246123fe43b022e020Ron Rindjunsky		memcpy(&conf->ht_bss_conf, &ht_bss_conf, sizeof(ht_bss_conf));
850edcdf8b21ac920e06b4180246123fe43b022e020Ron Rindjunsky	}
851edcdf8b21ac920e06b4180246123fe43b022e020Ron Rindjunskyout:
85238668c059f5202f5fd9612391f9aa1b38a97241bTomas Winkler	return changed;
853d3c990fb26b78f60614885d9ecaf7b7686b7b098Ron Rindjunsky}
854d3c990fb26b78f60614885d9ecaf7b7686b7b098Ron Rindjunsky
855471b3efdfccc257591331724145f8ccf8b3217e1Johannes Bergvoid ieee80211_bss_info_change_notify(struct ieee80211_sub_if_data *sdata,
856471b3efdfccc257591331724145f8ccf8b3217e1Johannes Berg				      u32 changed)
857d9430a32886f70c0c16d67c525f6cda2df7906eeDaniel Drake{
858471b3efdfccc257591331724145f8ccf8b3217e1Johannes Berg	struct ieee80211_local *local = sdata->local;
859471b3efdfccc257591331724145f8ccf8b3217e1Johannes Berg
860471b3efdfccc257591331724145f8ccf8b3217e1Johannes Berg	if (!changed)
861471b3efdfccc257591331724145f8ccf8b3217e1Johannes Berg		return;
862471b3efdfccc257591331724145f8ccf8b3217e1Johannes Berg
863471b3efdfccc257591331724145f8ccf8b3217e1Johannes Berg	if (local->ops->bss_info_changed)
864471b3efdfccc257591331724145f8ccf8b3217e1Johannes Berg		local->ops->bss_info_changed(local_to_hw(local),
865471b3efdfccc257591331724145f8ccf8b3217e1Johannes Berg					     &sdata->vif,
866471b3efdfccc257591331724145f8ccf8b3217e1Johannes Berg					     &sdata->bss_conf,
867471b3efdfccc257591331724145f8ccf8b3217e1Johannes Berg					     changed);
868d9430a32886f70c0c16d67c525f6cda2df7906eeDaniel Drake}
869d9430a32886f70c0c16d67c525f6cda2df7906eeDaniel Drake
870f698d856f65c3fea091cc303a135967965c5b880Jasper Bryant-Greeneu32 ieee80211_reset_erp_info(struct ieee80211_sub_if_data *sdata)
871d9430a32886f70c0c16d67c525f6cda2df7906eeDaniel Drake{
872471b3efdfccc257591331724145f8ccf8b3217e1Johannes Berg	sdata->bss_conf.use_cts_prot = 0;
873471b3efdfccc257591331724145f8ccf8b3217e1Johannes Berg	sdata->bss_conf.use_short_preamble = 0;
874fc32f9243dc93e75f81457e95d9cb90ee6136d94Tomas Winkler	return BSS_CHANGED_ERP_CTS_PROT | BSS_CHANGED_ERP_PREAMBLE;
875d9430a32886f70c0c16d67c525f6cda2df7906eeDaniel Drake}
876d9430a32886f70c0c16d67c525f6cda2df7906eeDaniel Drake
877f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Bencvoid ieee80211_tx_status_irqsafe(struct ieee80211_hw *hw,
878e039fa4a4195ac4ee895e6f3d1334beed63256feJohannes Berg				 struct sk_buff *skb)
879f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc{
880f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc	struct ieee80211_local *local = hw_to_local(hw);
881e039fa4a4195ac4ee895e6f3d1334beed63256feJohannes Berg	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
882f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc	int tmp;
883f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc
884f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc	skb->dev = local->mdev;
885f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc	skb->pkt_type = IEEE80211_TX_STATUS_MSG;
886e039fa4a4195ac4ee895e6f3d1334beed63256feJohannes Berg	skb_queue_tail(info->flags & IEEE80211_TX_CTL_REQ_TX_STATUS ?
887f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc		       &local->skb_queue : &local->skb_queue_unreliable, skb);
888f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc	tmp = skb_queue_len(&local->skb_queue) +
889f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc		skb_queue_len(&local->skb_queue_unreliable);
890f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc	while (tmp > IEEE80211_IRQSAFE_QUEUE_LIMIT &&
891f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc	       (skb = skb_dequeue(&local->skb_queue_unreliable))) {
892f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc		dev_kfree_skb_irq(skb);
893f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc		tmp--;
894f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc		I802_DEBUG_INC(local->tx_status_drop);
895f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc	}
896f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc	tasklet_schedule(&local->tasklet);
897f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc}
898f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri BencEXPORT_SYMBOL(ieee80211_tx_status_irqsafe);
899f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc
900f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Bencstatic void ieee80211_tasklet_handler(unsigned long data)
901f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc{
902f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc	struct ieee80211_local *local = (struct ieee80211_local *) data;
903f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc	struct sk_buff *skb;
904f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc	struct ieee80211_rx_status rx_status;
905eadc8d9e9047266a8914eb2ed4d36e797ce540d1Ron Rindjunsky	struct ieee80211_ra_tid *ra_tid;
906f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc
907f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc	while ((skb = skb_dequeue(&local->skb_queue)) ||
908f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc	       (skb = skb_dequeue(&local->skb_queue_unreliable))) {
909f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc		switch (skb->pkt_type) {
910f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc		case IEEE80211_RX_MSG:
911f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc			/* status is in skb->cb */
912f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc			memcpy(&rx_status, skb->cb, sizeof(rx_status));
91351fb61e76d952e6bc2fbdd9f0d38425fbab1cf31Johannes Berg			/* Clear skb->pkt_type in order to not confuse kernel
914f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc			 * netstack. */
915f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc			skb->pkt_type = 0;
916f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc			__ieee80211_rx(local_to_hw(local), skb, &rx_status);
917f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc			break;
918f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc		case IEEE80211_TX_STATUS_MSG:
919f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc			skb->pkt_type = 0;
920e039fa4a4195ac4ee895e6f3d1334beed63256feJohannes Berg			ieee80211_tx_status(local_to_hw(local), skb);
921f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc			break;
922eadc8d9e9047266a8914eb2ed4d36e797ce540d1Ron Rindjunsky		case IEEE80211_DELBA_MSG:
923eadc8d9e9047266a8914eb2ed4d36e797ce540d1Ron Rindjunsky			ra_tid = (struct ieee80211_ra_tid *) &skb->cb;
924eadc8d9e9047266a8914eb2ed4d36e797ce540d1Ron Rindjunsky			ieee80211_stop_tx_ba_cb(local_to_hw(local),
925eadc8d9e9047266a8914eb2ed4d36e797ce540d1Ron Rindjunsky						ra_tid->ra, ra_tid->tid);
926eadc8d9e9047266a8914eb2ed4d36e797ce540d1Ron Rindjunsky			dev_kfree_skb(skb);
927eadc8d9e9047266a8914eb2ed4d36e797ce540d1Ron Rindjunsky			break;
928eadc8d9e9047266a8914eb2ed4d36e797ce540d1Ron Rindjunsky		case IEEE80211_ADDBA_MSG:
929eadc8d9e9047266a8914eb2ed4d36e797ce540d1Ron Rindjunsky			ra_tid = (struct ieee80211_ra_tid *) &skb->cb;
930eadc8d9e9047266a8914eb2ed4d36e797ce540d1Ron Rindjunsky			ieee80211_start_tx_ba_cb(local_to_hw(local),
931eadc8d9e9047266a8914eb2ed4d36e797ce540d1Ron Rindjunsky						 ra_tid->ra, ra_tid->tid);
932eadc8d9e9047266a8914eb2ed4d36e797ce540d1Ron Rindjunsky			dev_kfree_skb(skb);
933eadc8d9e9047266a8914eb2ed4d36e797ce540d1Ron Rindjunsky			break ;
934f4ea83dd743d3e1bec8fdf954ac911c6b12ae87aJohannes Berg		default:
935f4ea83dd743d3e1bec8fdf954ac911c6b12ae87aJohannes Berg			WARN_ON(1);
936f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc			dev_kfree_skb(skb);
937f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc			break;
938f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc		}
939f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc	}
940f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc}
941f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc
942f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc/* Remove added headers (e.g., QoS control), encryption header/MIC, etc. to
943f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc * make a prepared TX frame (one that has been given to hw) to look like brand
944f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc * new IEEE 802.11 frame that is ready to go through TX processing again.
945d0f09804144fd9471a13cf4d80e66842c7fa114fJohannes Berg */
946f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Bencstatic void ieee80211_remove_tx_extra(struct ieee80211_local *local,
947f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc				      struct ieee80211_key *key,
948e039fa4a4195ac4ee895e6f3d1334beed63256feJohannes Berg				      struct sk_buff *skb)
949f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc{
95062bf1d762e24006fa9b6c8d56a22cf47a2310af3Harvey Harrison	unsigned int hdrlen, iv_len, mic_len;
95162bf1d762e24006fa9b6c8d56a22cf47a2310af3Harvey Harrison	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
952f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc
95362bf1d762e24006fa9b6c8d56a22cf47a2310af3Harvey Harrison	hdrlen = ieee80211_hdrlen(hdr->frame_control);
954f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc
955f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc	if (!key)
956f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc		goto no_key;
957f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc
9588f20fc24986a083228823d9b68adca20714b254eJohannes Berg	switch (key->conf.alg) {
959f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc	case ALG_WEP:
960f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc		iv_len = WEP_IV_LEN;
961f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc		mic_len = WEP_ICV_LEN;
962f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc		break;
963f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc	case ALG_TKIP:
964f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc		iv_len = TKIP_IV_LEN;
965f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc		mic_len = TKIP_ICV_LEN;
966f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc		break;
967f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc	case ALG_CCMP:
968f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc		iv_len = CCMP_HDR_LEN;
969f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc		mic_len = CCMP_MIC_LEN;
970f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc		break;
971f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc	default:
972f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc		goto no_key;
973f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc	}
974f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc
97562bf1d762e24006fa9b6c8d56a22cf47a2310af3Harvey Harrison	if (skb->len >= hdrlen + mic_len &&
97611a843b7e16062389c53ba393c7913956e034eb2Johannes Berg	    !(key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE))
977f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc		skb_trim(skb, skb->len - mic_len);
97862bf1d762e24006fa9b6c8d56a22cf47a2310af3Harvey Harrison	if (skb->len >= hdrlen + iv_len) {
979f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc		memmove(skb->data + iv_len, skb->data, hdrlen);
98062bf1d762e24006fa9b6c8d56a22cf47a2310af3Harvey Harrison		hdr = (struct ieee80211_hdr *)skb_pull(skb, iv_len);
981f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc	}
982f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc
983f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Bencno_key:
98462bf1d762e24006fa9b6c8d56a22cf47a2310af3Harvey Harrison	if (ieee80211_is_data_qos(hdr->frame_control)) {
98562bf1d762e24006fa9b6c8d56a22cf47a2310af3Harvey Harrison		hdr->frame_control &= ~cpu_to_le16(IEEE80211_STYPE_QOS_DATA);
98662bf1d762e24006fa9b6c8d56a22cf47a2310af3Harvey Harrison		memmove(skb->data + IEEE80211_QOS_CTL_LEN, skb->data,
98762bf1d762e24006fa9b6c8d56a22cf47a2310af3Harvey Harrison			hdrlen - IEEE80211_QOS_CTL_LEN);
98862bf1d762e24006fa9b6c8d56a22cf47a2310af3Harvey Harrison		skb_pull(skb, IEEE80211_QOS_CTL_LEN);
989f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc	}
990f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc}
991f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc
992d46e144b65bf053b25d134ec9f52a38e63e04bb4Johannes Bergstatic void ieee80211_handle_filtered_frame(struct ieee80211_local *local,
993d46e144b65bf053b25d134ec9f52a38e63e04bb4Johannes Berg					    struct sta_info *sta,
994e039fa4a4195ac4ee895e6f3d1334beed63256feJohannes Berg					    struct sk_buff *skb)
995d46e144b65bf053b25d134ec9f52a38e63e04bb4Johannes Berg{
996e039fa4a4195ac4ee895e6f3d1334beed63256feJohannes Berg	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
997e039fa4a4195ac4ee895e6f3d1334beed63256feJohannes Berg
998d46e144b65bf053b25d134ec9f52a38e63e04bb4Johannes Berg	sta->tx_filtered_count++;
999d46e144b65bf053b25d134ec9f52a38e63e04bb4Johannes Berg
1000d46e144b65bf053b25d134ec9f52a38e63e04bb4Johannes Berg	/*
1001d46e144b65bf053b25d134ec9f52a38e63e04bb4Johannes Berg	 * Clear the TX filter mask for this STA when sending the next
1002d46e144b65bf053b25d134ec9f52a38e63e04bb4Johannes Berg	 * packet. If the STA went to power save mode, this will happen
1003f6d97104890203ba9c2cf8e34894c4c8e64cb880Yi Zhu	 * when it wakes up for the next time.
1004d46e144b65bf053b25d134ec9f52a38e63e04bb4Johannes Berg	 */
100507346f81e87d6e4cca7ae9adfa711d0c61c87b56Johannes Berg	set_sta_flags(sta, WLAN_STA_CLEAR_PS_FILT);
1006d46e144b65bf053b25d134ec9f52a38e63e04bb4Johannes Berg
1007d46e144b65bf053b25d134ec9f52a38e63e04bb4Johannes Berg	/*
1008d46e144b65bf053b25d134ec9f52a38e63e04bb4Johannes Berg	 * This code races in the following way:
1009d46e144b65bf053b25d134ec9f52a38e63e04bb4Johannes Berg	 *
1010d46e144b65bf053b25d134ec9f52a38e63e04bb4Johannes Berg	 *  (1) STA sends frame indicating it will go to sleep and does so
1011d46e144b65bf053b25d134ec9f52a38e63e04bb4Johannes Berg	 *  (2) hardware/firmware adds STA to filter list, passes frame up
1012d46e144b65bf053b25d134ec9f52a38e63e04bb4Johannes Berg	 *  (3) hardware/firmware processes TX fifo and suppresses a frame
1013d46e144b65bf053b25d134ec9f52a38e63e04bb4Johannes Berg	 *  (4) we get TX status before having processed the frame and
1014d46e144b65bf053b25d134ec9f52a38e63e04bb4Johannes Berg	 *	knowing that the STA has gone to sleep.
1015d46e144b65bf053b25d134ec9f52a38e63e04bb4Johannes Berg	 *
1016d46e144b65bf053b25d134ec9f52a38e63e04bb4Johannes Berg	 * This is actually quite unlikely even when both those events are
1017d46e144b65bf053b25d134ec9f52a38e63e04bb4Johannes Berg	 * processed from interrupts coming in quickly after one another or
1018d46e144b65bf053b25d134ec9f52a38e63e04bb4Johannes Berg	 * even at the same time because we queue both TX status events and
1019d46e144b65bf053b25d134ec9f52a38e63e04bb4Johannes Berg	 * RX frames to be processed by a tasklet and process them in the
1020d46e144b65bf053b25d134ec9f52a38e63e04bb4Johannes Berg	 * same order that they were received or TX status last. Hence, there
1021d46e144b65bf053b25d134ec9f52a38e63e04bb4Johannes Berg	 * is no race as long as the frame RX is processed before the next TX
1022d46e144b65bf053b25d134ec9f52a38e63e04bb4Johannes Berg	 * status, which drivers can ensure, see below.
1023d46e144b65bf053b25d134ec9f52a38e63e04bb4Johannes Berg	 *
1024d46e144b65bf053b25d134ec9f52a38e63e04bb4Johannes Berg	 * Note that this can only happen if the hardware or firmware can
1025d46e144b65bf053b25d134ec9f52a38e63e04bb4Johannes Berg	 * actually add STAs to the filter list, if this is done by the
1026d46e144b65bf053b25d134ec9f52a38e63e04bb4Johannes Berg	 * driver in response to set_tim() (which will only reduce the race
1027d46e144b65bf053b25d134ec9f52a38e63e04bb4Johannes Berg	 * this whole filtering tries to solve, not completely solve it)
1028d46e144b65bf053b25d134ec9f52a38e63e04bb4Johannes Berg	 * this situation cannot happen.
1029d46e144b65bf053b25d134ec9f52a38e63e04bb4Johannes Berg	 *
1030d46e144b65bf053b25d134ec9f52a38e63e04bb4Johannes Berg	 * To completely solve this race drivers need to make sure that they
1031d46e144b65bf053b25d134ec9f52a38e63e04bb4Johannes Berg	 *  (a) don't mix the irq-safe/not irq-safe TX status/RX processing
1032d46e144b65bf053b25d134ec9f52a38e63e04bb4Johannes Berg	 *	functions and
1033d46e144b65bf053b25d134ec9f52a38e63e04bb4Johannes Berg	 *  (b) always process RX events before TX status events if ordering
1034d46e144b65bf053b25d134ec9f52a38e63e04bb4Johannes Berg	 *      can be unknown, for example with different interrupt status
1035d46e144b65bf053b25d134ec9f52a38e63e04bb4Johannes Berg	 *	bits.
1036d46e144b65bf053b25d134ec9f52a38e63e04bb4Johannes Berg	 */
103707346f81e87d6e4cca7ae9adfa711d0c61c87b56Johannes Berg	if (test_sta_flags(sta, WLAN_STA_PS) &&
1038d46e144b65bf053b25d134ec9f52a38e63e04bb4Johannes Berg	    skb_queue_len(&sta->tx_filtered) < STA_MAX_TX_BUFFER) {
1039e039fa4a4195ac4ee895e6f3d1334beed63256feJohannes Berg		ieee80211_remove_tx_extra(local, sta->key, skb);
1040d46e144b65bf053b25d134ec9f52a38e63e04bb4Johannes Berg		skb_queue_tail(&sta->tx_filtered, skb);
1041d46e144b65bf053b25d134ec9f52a38e63e04bb4Johannes Berg		return;
1042d46e144b65bf053b25d134ec9f52a38e63e04bb4Johannes Berg	}
1043d46e144b65bf053b25d134ec9f52a38e63e04bb4Johannes Berg
104407346f81e87d6e4cca7ae9adfa711d0c61c87b56Johannes Berg	if (!test_sta_flags(sta, WLAN_STA_PS) &&
1045e039fa4a4195ac4ee895e6f3d1334beed63256feJohannes Berg	    !(info->flags & IEEE80211_TX_CTL_REQUEUE)) {
1046d46e144b65bf053b25d134ec9f52a38e63e04bb4Johannes Berg		/* Software retry the packet once */
1047e039fa4a4195ac4ee895e6f3d1334beed63256feJohannes Berg		info->flags |= IEEE80211_TX_CTL_REQUEUE;
1048e039fa4a4195ac4ee895e6f3d1334beed63256feJohannes Berg		ieee80211_remove_tx_extra(local, sta->key, skb);
1049d46e144b65bf053b25d134ec9f52a38e63e04bb4Johannes Berg		dev_queue_xmit(skb);
1050d46e144b65bf053b25d134ec9f52a38e63e04bb4Johannes Berg		return;
1051d46e144b65bf053b25d134ec9f52a38e63e04bb4Johannes Berg	}
1052d46e144b65bf053b25d134ec9f52a38e63e04bb4Johannes Berg
1053f4ea83dd743d3e1bec8fdf954ac911c6b12ae87aJohannes Berg#ifdef CONFIG_MAC80211_VERBOSE_DEBUG
1054d46e144b65bf053b25d134ec9f52a38e63e04bb4Johannes Berg	if (net_ratelimit())
1055d46e144b65bf053b25d134ec9f52a38e63e04bb4Johannes Berg		printk(KERN_DEBUG "%s: dropped TX filtered frame, "
1056d46e144b65bf053b25d134ec9f52a38e63e04bb4Johannes Berg		       "queue_len=%d PS=%d @%lu\n",
1057d46e144b65bf053b25d134ec9f52a38e63e04bb4Johannes Berg		       wiphy_name(local->hw.wiphy),
1058d46e144b65bf053b25d134ec9f52a38e63e04bb4Johannes Berg		       skb_queue_len(&sta->tx_filtered),
105907346f81e87d6e4cca7ae9adfa711d0c61c87b56Johannes Berg		       !!test_sta_flags(sta, WLAN_STA_PS), jiffies);
1060f4ea83dd743d3e1bec8fdf954ac911c6b12ae87aJohannes Berg#endif
1061d46e144b65bf053b25d134ec9f52a38e63e04bb4Johannes Berg	dev_kfree_skb(skb);
1062d46e144b65bf053b25d134ec9f52a38e63e04bb4Johannes Berg}
1063d46e144b65bf053b25d134ec9f52a38e63e04bb4Johannes Berg
1064e039fa4a4195ac4ee895e6f3d1334beed63256feJohannes Bergvoid ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb)
1065f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc{
1066f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc	struct sk_buff *skb2;
1067f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
1068f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc	struct ieee80211_local *local = hw_to_local(hw);
1069e039fa4a4195ac4ee895e6f3d1334beed63256feJohannes Berg	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
1070f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc	u16 frag, type;
1071429a380571a6e6b8525b93161544eafc9b227e44Ron Rindjunsky	__le16 fc;
1072b306f45300866adc01b84f7aa083bfcd9cbb89c4Johannes Berg	struct ieee80211_tx_status_rtap_hdr *rthdr;
1073b306f45300866adc01b84f7aa083bfcd9cbb89c4Johannes Berg	struct ieee80211_sub_if_data *sdata;
10743d30d949cf3f9763393f3457721bca3ac2426e42Michael Wu	struct net_device *prev_dev = NULL;
1075429a380571a6e6b8525b93161544eafc9b227e44Ron Rindjunsky	struct sta_info *sta;
1076f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc
1077d0709a65181beb787ef3f58cfe45536a2bb254c8Johannes Berg	rcu_read_lock();
1078d0709a65181beb787ef3f58cfe45536a2bb254c8Johannes Berg
1079e039fa4a4195ac4ee895e6f3d1334beed63256feJohannes Berg	if (info->status.excessive_retries) {
1080f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc		sta = sta_info_get(local, hdr->addr1);
1081f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc		if (sta) {
108207346f81e87d6e4cca7ae9adfa711d0c61c87b56Johannes Berg			if (test_sta_flags(sta, WLAN_STA_PS)) {
1083d46e144b65bf053b25d134ec9f52a38e63e04bb4Johannes Berg				/*
1084d46e144b65bf053b25d134ec9f52a38e63e04bb4Johannes Berg				 * The STA is in power save mode, so assume
1085f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc				 * that this TX packet failed because of that.
1086f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc				 */
1087e039fa4a4195ac4ee895e6f3d1334beed63256feJohannes Berg				ieee80211_handle_filtered_frame(local, sta, skb);
1088d0709a65181beb787ef3f58cfe45536a2bb254c8Johannes Berg				rcu_read_unlock();
1089d46e144b65bf053b25d134ec9f52a38e63e04bb4Johannes Berg				return;
1090f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc			}
1091f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc		}
1092f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc	}
1093f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc
1094429a380571a6e6b8525b93161544eafc9b227e44Ron Rindjunsky	fc = hdr->frame_control;
1095429a380571a6e6b8525b93161544eafc9b227e44Ron Rindjunsky
1096429a380571a6e6b8525b93161544eafc9b227e44Ron Rindjunsky	if ((info->flags & IEEE80211_TX_STAT_AMPDU_NO_BACK) &&
1097429a380571a6e6b8525b93161544eafc9b227e44Ron Rindjunsky	    (ieee80211_is_data_qos(fc))) {
1098429a380571a6e6b8525b93161544eafc9b227e44Ron Rindjunsky		u16 tid, ssn;
1099429a380571a6e6b8525b93161544eafc9b227e44Ron Rindjunsky		u8 *qc;
1100429a380571a6e6b8525b93161544eafc9b227e44Ron Rindjunsky		sta = sta_info_get(local, hdr->addr1);
1101429a380571a6e6b8525b93161544eafc9b227e44Ron Rindjunsky		if (sta) {
1102429a380571a6e6b8525b93161544eafc9b227e44Ron Rindjunsky			qc = ieee80211_get_qos_ctl(hdr);
1103429a380571a6e6b8525b93161544eafc9b227e44Ron Rindjunsky			tid = qc[0] & 0xf;
1104429a380571a6e6b8525b93161544eafc9b227e44Ron Rindjunsky			ssn = ((le16_to_cpu(hdr->seq_ctrl) + 0x10)
1105429a380571a6e6b8525b93161544eafc9b227e44Ron Rindjunsky						& IEEE80211_SCTL_SEQ);
1106f698d856f65c3fea091cc303a135967965c5b880Jasper Bryant-Greene			ieee80211_send_bar(sta->sdata, hdr->addr1,
1107429a380571a6e6b8525b93161544eafc9b227e44Ron Rindjunsky					   tid, ssn);
1108429a380571a6e6b8525b93161544eafc9b227e44Ron Rindjunsky		}
1109429a380571a6e6b8525b93161544eafc9b227e44Ron Rindjunsky	}
1110429a380571a6e6b8525b93161544eafc9b227e44Ron Rindjunsky
1111e039fa4a4195ac4ee895e6f3d1334beed63256feJohannes Berg	if (info->flags & IEEE80211_TX_STAT_TX_FILTERED) {
1112f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc		sta = sta_info_get(local, hdr->addr1);
1113f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc		if (sta) {
1114e039fa4a4195ac4ee895e6f3d1334beed63256feJohannes Berg			ieee80211_handle_filtered_frame(local, sta, skb);
1115d0709a65181beb787ef3f58cfe45536a2bb254c8Johannes Berg			rcu_read_unlock();
1116f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc			return;
1117f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc		}
11181abbe498e4b5e4f2000dfc30a0fa25be9553530eMattias Nissler	} else
1119e039fa4a4195ac4ee895e6f3d1334beed63256feJohannes Berg		rate_control_tx_status(local->mdev, skb);
1120f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc
1121d0709a65181beb787ef3f58cfe45536a2bb254c8Johannes Berg	rcu_read_unlock();
1122d0709a65181beb787ef3f58cfe45536a2bb254c8Johannes Berg
1123f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc	ieee80211_led_tx(local, 0);
1124f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc
1125f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc	/* SNMP counters
1126f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc	 * Fragments are passed to low-level drivers as separate skbs, so these
1127f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc	 * are actually fragments, not frames. Update frame counters only for
1128f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc	 * the first fragment of the frame. */
1129f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc
1130f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc	frag = le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_FRAG;
1131f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc	type = le16_to_cpu(hdr->frame_control) & IEEE80211_FCTL_FTYPE;
1132f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc
1133e039fa4a4195ac4ee895e6f3d1334beed63256feJohannes Berg	if (info->flags & IEEE80211_TX_STAT_ACK) {
1134f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc		if (frag == 0) {
1135f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc			local->dot11TransmittedFrameCount++;
1136f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc			if (is_multicast_ether_addr(hdr->addr1))
1137f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc				local->dot11MulticastTransmittedFrameCount++;
1138e039fa4a4195ac4ee895e6f3d1334beed63256feJohannes Berg			if (info->status.retry_count > 0)
1139f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc				local->dot11RetryCount++;
1140e039fa4a4195ac4ee895e6f3d1334beed63256feJohannes Berg			if (info->status.retry_count > 1)
1141f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc				local->dot11MultipleRetryCount++;
1142f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc		}
1143f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc
1144f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc		/* This counter shall be incremented for an acknowledged MPDU
1145f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc		 * with an individual address in the address 1 field or an MPDU
1146f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc		 * with a multicast address in the address 1 field of type Data
1147f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc		 * or Management. */
1148f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc		if (!is_multicast_ether_addr(hdr->addr1) ||
1149f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc		    type == IEEE80211_FTYPE_DATA ||
1150f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc		    type == IEEE80211_FTYPE_MGMT)
1151f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc			local->dot11TransmittedFragmentCount++;
1152f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc	} else {
1153f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc		if (frag == 0)
1154f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc			local->dot11FailedCount++;
1155f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc	}
1156f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc
1157b306f45300866adc01b84f7aa083bfcd9cbb89c4Johannes Berg	/* this was a transmitted frame, but now we want to reuse it */
1158b306f45300866adc01b84f7aa083bfcd9cbb89c4Johannes Berg	skb_orphan(skb);
1159b306f45300866adc01b84f7aa083bfcd9cbb89c4Johannes Berg
11603d30d949cf3f9763393f3457721bca3ac2426e42Michael Wu	/*
11613d30d949cf3f9763393f3457721bca3ac2426e42Michael Wu	 * This is a bit racy but we can avoid a lot of work
11623d30d949cf3f9763393f3457721bca3ac2426e42Michael Wu	 * with this test...
11633d30d949cf3f9763393f3457721bca3ac2426e42Michael Wu	 */
11643d30d949cf3f9763393f3457721bca3ac2426e42Michael Wu	if (!local->monitors && !local->cooked_mntrs) {
1165f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc		dev_kfree_skb(skb);
1166f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc		return;
1167f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc	}
1168f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc
1169b306f45300866adc01b84f7aa083bfcd9cbb89c4Johannes Berg	/* send frame to monitor interfaces now */
1170f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc
1171b306f45300866adc01b84f7aa083bfcd9cbb89c4Johannes Berg	if (skb_headroom(skb) < sizeof(*rthdr)) {
1172b306f45300866adc01b84f7aa083bfcd9cbb89c4Johannes Berg		printk(KERN_ERR "ieee80211_tx_status: headroom too small\n");
1173f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc		dev_kfree_skb(skb);
1174f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc		return;
1175f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc	}
1176f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc
1177988c0f723d0b1abb399e6e71d8bf3f8bf1949a70Johannes Berg	rthdr = (struct ieee80211_tx_status_rtap_hdr *)
1178b306f45300866adc01b84f7aa083bfcd9cbb89c4Johannes Berg				skb_push(skb, sizeof(*rthdr));
1179b306f45300866adc01b84f7aa083bfcd9cbb89c4Johannes Berg
1180b306f45300866adc01b84f7aa083bfcd9cbb89c4Johannes Berg	memset(rthdr, 0, sizeof(*rthdr));
1181b306f45300866adc01b84f7aa083bfcd9cbb89c4Johannes Berg	rthdr->hdr.it_len = cpu_to_le16(sizeof(*rthdr));
1182b306f45300866adc01b84f7aa083bfcd9cbb89c4Johannes Berg	rthdr->hdr.it_present =
1183b306f45300866adc01b84f7aa083bfcd9cbb89c4Johannes Berg		cpu_to_le32((1 << IEEE80211_RADIOTAP_TX_FLAGS) |
1184b306f45300866adc01b84f7aa083bfcd9cbb89c4Johannes Berg			    (1 << IEEE80211_RADIOTAP_DATA_RETRIES));
1185b306f45300866adc01b84f7aa083bfcd9cbb89c4Johannes Berg
1186e039fa4a4195ac4ee895e6f3d1334beed63256feJohannes Berg	if (!(info->flags & IEEE80211_TX_STAT_ACK) &&
1187b306f45300866adc01b84f7aa083bfcd9cbb89c4Johannes Berg	    !is_multicast_ether_addr(hdr->addr1))
1188b306f45300866adc01b84f7aa083bfcd9cbb89c4Johannes Berg		rthdr->tx_flags |= cpu_to_le16(IEEE80211_RADIOTAP_F_TX_FAIL);
1189b306f45300866adc01b84f7aa083bfcd9cbb89c4Johannes Berg
1190e039fa4a4195ac4ee895e6f3d1334beed63256feJohannes Berg	if ((info->flags & IEEE80211_TX_CTL_USE_RTS_CTS) &&
1191e039fa4a4195ac4ee895e6f3d1334beed63256feJohannes Berg	    (info->flags & IEEE80211_TX_CTL_USE_CTS_PROTECT))
1192b306f45300866adc01b84f7aa083bfcd9cbb89c4Johannes Berg		rthdr->tx_flags |= cpu_to_le16(IEEE80211_RADIOTAP_F_TX_CTS);
1193e039fa4a4195ac4ee895e6f3d1334beed63256feJohannes Berg	else if (info->flags & IEEE80211_TX_CTL_USE_RTS_CTS)
1194b306f45300866adc01b84f7aa083bfcd9cbb89c4Johannes Berg		rthdr->tx_flags |= cpu_to_le16(IEEE80211_RADIOTAP_F_TX_RTS);
1195b306f45300866adc01b84f7aa083bfcd9cbb89c4Johannes Berg
1196e039fa4a4195ac4ee895e6f3d1334beed63256feJohannes Berg	rthdr->data_retries = info->status.retry_count;
1197b306f45300866adc01b84f7aa083bfcd9cbb89c4Johannes Berg
11983d30d949cf3f9763393f3457721bca3ac2426e42Michael Wu	/* XXX: is this sufficient for BPF? */
11993d30d949cf3f9763393f3457721bca3ac2426e42Michael Wu	skb_set_mac_header(skb, 0);
12003d30d949cf3f9763393f3457721bca3ac2426e42Michael Wu	skb->ip_summed = CHECKSUM_UNNECESSARY;
12013d30d949cf3f9763393f3457721bca3ac2426e42Michael Wu	skb->pkt_type = PACKET_OTHERHOST;
12023d30d949cf3f9763393f3457721bca3ac2426e42Michael Wu	skb->protocol = htons(ETH_P_802_2);
12033d30d949cf3f9763393f3457721bca3ac2426e42Michael Wu	memset(skb->cb, 0, sizeof(skb->cb));
12043d30d949cf3f9763393f3457721bca3ac2426e42Michael Wu
120579010420cc3f78eab911598bfdd29c4b06a83e1fJohannes Berg	rcu_read_lock();
120679010420cc3f78eab911598bfdd29c4b06a83e1fJohannes Berg	list_for_each_entry_rcu(sdata, &local->interfaces, list) {
120751fb61e76d952e6bc2fbdd9f0d38425fbab1cf31Johannes Berg		if (sdata->vif.type == IEEE80211_IF_TYPE_MNTR) {
1208b306f45300866adc01b84f7aa083bfcd9cbb89c4Johannes Berg			if (!netif_running(sdata->dev))
1209b306f45300866adc01b84f7aa083bfcd9cbb89c4Johannes Berg				continue;
12103d30d949cf3f9763393f3457721bca3ac2426e42Michael Wu
12113d30d949cf3f9763393f3457721bca3ac2426e42Michael Wu			if (prev_dev) {
121279010420cc3f78eab911598bfdd29c4b06a83e1fJohannes Berg				skb2 = skb_clone(skb, GFP_ATOMIC);
12133d30d949cf3f9763393f3457721bca3ac2426e42Michael Wu				if (skb2) {
12143d30d949cf3f9763393f3457721bca3ac2426e42Michael Wu					skb2->dev = prev_dev;
12153d30d949cf3f9763393f3457721bca3ac2426e42Michael Wu					netif_rx(skb2);
12163d30d949cf3f9763393f3457721bca3ac2426e42Michael Wu				}
12173d30d949cf3f9763393f3457721bca3ac2426e42Michael Wu			}
12183d30d949cf3f9763393f3457721bca3ac2426e42Michael Wu
12193d30d949cf3f9763393f3457721bca3ac2426e42Michael Wu			prev_dev = sdata->dev;
1220b306f45300866adc01b84f7aa083bfcd9cbb89c4Johannes Berg		}
1221b306f45300866adc01b84f7aa083bfcd9cbb89c4Johannes Berg	}
12223d30d949cf3f9763393f3457721bca3ac2426e42Michael Wu	if (prev_dev) {
12233d30d949cf3f9763393f3457721bca3ac2426e42Michael Wu		skb->dev = prev_dev;
12243d30d949cf3f9763393f3457721bca3ac2426e42Michael Wu		netif_rx(skb);
12253d30d949cf3f9763393f3457721bca3ac2426e42Michael Wu		skb = NULL;
12263d30d949cf3f9763393f3457721bca3ac2426e42Michael Wu	}
122779010420cc3f78eab911598bfdd29c4b06a83e1fJohannes Berg	rcu_read_unlock();
12283d30d949cf3f9763393f3457721bca3ac2426e42Michael Wu	dev_kfree_skb(skb);
1229f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc}
1230f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri BencEXPORT_SYMBOL(ieee80211_tx_status);
1231f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc
1232f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Bencstruct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len,
1233f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc					const struct ieee80211_ops *ops)
1234f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc{
1235f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc	struct ieee80211_local *local;
1236f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc	int priv_size;
1237f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc	struct wiphy *wiphy;
1238f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc
1239f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc	/* Ensure 32-byte alignment of our private data and hw private data.
1240f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc	 * We use the wiphy priv data for both our ieee80211_local and for
1241f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc	 * the driver's private data
1242f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc	 *
1243f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc	 * In memory it'll be like this:
1244f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc	 *
1245f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc	 * +-------------------------+
1246f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc	 * | struct wiphy	    |
1247f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc	 * +-------------------------+
1248f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc	 * | struct ieee80211_local  |
1249f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc	 * +-------------------------+
1250f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc	 * | driver's private data   |
1251f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc	 * +-------------------------+
1252f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc	 *
1253f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc	 */
1254f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc	priv_size = ((sizeof(struct ieee80211_local) +
1255f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc		      NETDEV_ALIGN_CONST) & ~NETDEV_ALIGN_CONST) +
1256f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc		    priv_data_len;
1257f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc
1258f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc	wiphy = wiphy_new(&mac80211_config_ops, priv_size);
1259f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc
1260f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc	if (!wiphy)
1261f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc		return NULL;
1262f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc
1263f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc	wiphy->privid = mac80211_wiphy_privid;
1264f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc
1265f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc	local = wiphy_priv(wiphy);
1266f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc	local->hw.wiphy = wiphy;
1267f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc
1268f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc	local->hw.priv = (char *)local +
1269f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc			 ((sizeof(struct ieee80211_local) +
1270f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc			   NETDEV_ALIGN_CONST) & ~NETDEV_ALIGN_CONST);
1271f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc
12724480f15ca62a595248d6d8e2b3e75052113cde59Johannes Berg	BUG_ON(!ops->tx);
12734150c57212ad134765dd78c654a4b9906252b66dJohannes Berg	BUG_ON(!ops->start);
12744150c57212ad134765dd78c654a4b9906252b66dJohannes Berg	BUG_ON(!ops->stop);
12754480f15ca62a595248d6d8e2b3e75052113cde59Johannes Berg	BUG_ON(!ops->config);
12764480f15ca62a595248d6d8e2b3e75052113cde59Johannes Berg	BUG_ON(!ops->add_interface);
12774150c57212ad134765dd78c654a4b9906252b66dJohannes Berg	BUG_ON(!ops->remove_interface);
12784150c57212ad134765dd78c654a4b9906252b66dJohannes Berg	BUG_ON(!ops->configure_filter);
1279f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc	local->ops = ops;
1280f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc
1281f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc	local->hw.queues = 1; /* default */
1282f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc
1283f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc	local->rts_threshold = IEEE80211_MAX_RTS_THRESHOLD;
1284f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc	local->fragmentation_threshold = IEEE80211_MAX_FRAG_THRESHOLD;
1285f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc	local->short_retry_limit = 7;
1286f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc	local->long_retry_limit = 4;
1287f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc	local->hw.conf.radio_enabled = 1;
1288f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc
128979010420cc3f78eab911598bfdd29c4b06a83e1fJohannes Berg	INIT_LIST_HEAD(&local->interfaces);
1290f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc
1291b16bd15c379410f2aa47837aa4a0de5712856ad5Johannes Berg	spin_lock_init(&local->key_lock);
1292b16bd15c379410f2aa47837aa4a0de5712856ad5Johannes Berg
1293c2b13452b283f9c4a5b02a6b53ed6416ebf4c03cJohannes Berg	INIT_DELAYED_WORK(&local->scan_work, ieee80211_scan_work);
1294f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc
1295f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc	sta_info_init(local);
1296f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc
1297f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc	tasklet_init(&local->tx_pending_tasklet, ieee80211_tx_pending,
1298f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc		     (unsigned long)local);
1299f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc	tasklet_disable(&local->tx_pending_tasklet);
1300f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc
1301f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc	tasklet_init(&local->tasklet,
1302f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc		     ieee80211_tasklet_handler,
1303f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc		     (unsigned long) local);
1304f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc	tasklet_disable(&local->tasklet);
1305f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc
1306f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc	skb_queue_head_init(&local->skb_queue);
1307f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc	skb_queue_head_init(&local->skb_queue_unreliable);
1308f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc
1309f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc	return local_to_hw(local);
1310f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc}
1311f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri BencEXPORT_SYMBOL(ieee80211_alloc_hw);
1312f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc
1313f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Bencint ieee80211_register_hw(struct ieee80211_hw *hw)
1314f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc{
1315f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc	struct ieee80211_local *local = hw_to_local(hw);
1316f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc	const char *name;
1317f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc	int result;
13188318d78a44d49ac1edf2bdec7299de3617c4232eJohannes Berg	enum ieee80211_band band;
131996d510566e4908f77f03ff1436c78ae7162a17d0Johannes Berg	struct net_device *mdev;
13203e122be089e6fb8d3f322416da4cdbb80ce12927Johannes Berg	struct wireless_dev *mwdev;
13218318d78a44d49ac1edf2bdec7299de3617c4232eJohannes Berg
13228318d78a44d49ac1edf2bdec7299de3617c4232eJohannes Berg	/*
13238318d78a44d49ac1edf2bdec7299de3617c4232eJohannes Berg	 * generic code guarantees at least one band,
13248318d78a44d49ac1edf2bdec7299de3617c4232eJohannes Berg	 * set this very early because much code assumes
13258318d78a44d49ac1edf2bdec7299de3617c4232eJohannes Berg	 * that hw.conf.channel is assigned
13268318d78a44d49ac1edf2bdec7299de3617c4232eJohannes Berg	 */
13278318d78a44d49ac1edf2bdec7299de3617c4232eJohannes Berg	for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
13288318d78a44d49ac1edf2bdec7299de3617c4232eJohannes Berg		struct ieee80211_supported_band *sband;
13298318d78a44d49ac1edf2bdec7299de3617c4232eJohannes Berg
13308318d78a44d49ac1edf2bdec7299de3617c4232eJohannes Berg		sband = local->hw.wiphy->bands[band];
13318318d78a44d49ac1edf2bdec7299de3617c4232eJohannes Berg		if (sband) {
13328318d78a44d49ac1edf2bdec7299de3617c4232eJohannes Berg			/* init channel we're on */
13338318d78a44d49ac1edf2bdec7299de3617c4232eJohannes Berg			local->hw.conf.channel =
13348318d78a44d49ac1edf2bdec7299de3617c4232eJohannes Berg			local->oper_channel =
13358318d78a44d49ac1edf2bdec7299de3617c4232eJohannes Berg			local->scan_channel = &sband->channels[0];
13368318d78a44d49ac1edf2bdec7299de3617c4232eJohannes Berg			break;
13378318d78a44d49ac1edf2bdec7299de3617c4232eJohannes Berg		}
13388318d78a44d49ac1edf2bdec7299de3617c4232eJohannes Berg	}
1339f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc
1340f59ac0481660e66cec67f1d6b024e78b9dc715feLuis R. Rodriguez	/* if low-level driver supports AP, we also support VLAN */
1341f59ac0481660e66cec67f1d6b024e78b9dc715feLuis R. Rodriguez	if (local->hw.wiphy->interface_modes & BIT(NL80211_IFTYPE_AP))
1342f59ac0481660e66cec67f1d6b024e78b9dc715feLuis R. Rodriguez		local->hw.wiphy->interface_modes |= BIT(NL80211_IFTYPE_AP_VLAN);
1343f59ac0481660e66cec67f1d6b024e78b9dc715feLuis R. Rodriguez
1344f59ac0481660e66cec67f1d6b024e78b9dc715feLuis R. Rodriguez	/* mac80211 always supports monitor */
1345f59ac0481660e66cec67f1d6b024e78b9dc715feLuis R. Rodriguez	local->hw.wiphy->interface_modes |= BIT(NL80211_IFTYPE_MONITOR);
1346f59ac0481660e66cec67f1d6b024e78b9dc715feLuis R. Rodriguez
1347f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc	result = wiphy_register(local->hw.wiphy);
1348f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc	if (result < 0)
1349f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc		return result;
1350f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc
1351e2530083609148a7835b54c431f6b8956407c1f6Johannes Berg	/*
1352e2530083609148a7835b54c431f6b8956407c1f6Johannes Berg	 * We use the number of queues for feature tests (QoS, HT) internally
1353e2530083609148a7835b54c431f6b8956407c1f6Johannes Berg	 * so restrict them appropriately.
1354e2530083609148a7835b54c431f6b8956407c1f6Johannes Berg	 */
1355e2530083609148a7835b54c431f6b8956407c1f6Johannes Berg	if (hw->queues > IEEE80211_MAX_QUEUES)
1356e2530083609148a7835b54c431f6b8956407c1f6Johannes Berg		hw->queues = IEEE80211_MAX_QUEUES;
1357e2530083609148a7835b54c431f6b8956407c1f6Johannes Berg	if (hw->ampdu_queues > IEEE80211_MAX_AMPDU_QUEUES)
1358e2530083609148a7835b54c431f6b8956407c1f6Johannes Berg		hw->ampdu_queues = IEEE80211_MAX_AMPDU_QUEUES;
1359e2530083609148a7835b54c431f6b8956407c1f6Johannes Berg	if (hw->queues < 4)
1360e2530083609148a7835b54c431f6b8956407c1f6Johannes Berg		hw->ampdu_queues = 0;
1361e2530083609148a7835b54c431f6b8956407c1f6Johannes Berg
13623e122be089e6fb8d3f322416da4cdbb80ce12927Johannes Berg	mdev = alloc_netdev_mq(sizeof(struct wireless_dev),
1363e2530083609148a7835b54c431f6b8956407c1f6Johannes Berg			       "wmaster%d", ether_setup,
1364e2530083609148a7835b54c431f6b8956407c1f6Johannes Berg			       ieee80211_num_queues(hw));
136596d510566e4908f77f03ff1436c78ae7162a17d0Johannes Berg	if (!mdev)
136696d510566e4908f77f03ff1436c78ae7162a17d0Johannes Berg		goto fail_mdev_alloc;
136796d510566e4908f77f03ff1436c78ae7162a17d0Johannes Berg
13683e122be089e6fb8d3f322416da4cdbb80ce12927Johannes Berg	mwdev = netdev_priv(mdev);
13693e122be089e6fb8d3f322416da4cdbb80ce12927Johannes Berg	mdev->ieee80211_ptr = mwdev;
13703e122be089e6fb8d3f322416da4cdbb80ce12927Johannes Berg	mwdev->wiphy = local->hw.wiphy;
137196d510566e4908f77f03ff1436c78ae7162a17d0Johannes Berg
137296d510566e4908f77f03ff1436c78ae7162a17d0Johannes Berg	local->mdev = mdev;
137396d510566e4908f77f03ff1436c78ae7162a17d0Johannes Berg
13743e122be089e6fb8d3f322416da4cdbb80ce12927Johannes Berg	ieee80211_rx_bss_list_init(local);
137596d510566e4908f77f03ff1436c78ae7162a17d0Johannes Berg
137696d510566e4908f77f03ff1436c78ae7162a17d0Johannes Berg	mdev->hard_start_xmit = ieee80211_master_start_xmit;
137796d510566e4908f77f03ff1436c78ae7162a17d0Johannes Berg	mdev->open = ieee80211_master_open;
137896d510566e4908f77f03ff1436c78ae7162a17d0Johannes Berg	mdev->stop = ieee80211_master_stop;
137996d510566e4908f77f03ff1436c78ae7162a17d0Johannes Berg	mdev->type = ARPHRD_IEEE80211;
138096d510566e4908f77f03ff1436c78ae7162a17d0Johannes Berg	mdev->header_ops = &ieee80211_header_ops;
138196d510566e4908f77f03ff1436c78ae7162a17d0Johannes Berg	mdev->set_multicast_list = ieee80211_master_set_multicast_list;
138296d510566e4908f77f03ff1436c78ae7162a17d0Johannes Berg
1383f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc	name = wiphy_dev(local->hw.wiphy)->driver->name;
138459959a6150c8af737898e83f727e824dbed7b0faJohannes Berg	local->hw.workqueue = create_freezeable_workqueue(name);
1385f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc	if (!local->hw.workqueue) {
1386f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc		result = -ENOMEM;
1387f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc		goto fail_workqueue;
1388f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc	}
1389f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc
1390b306f45300866adc01b84f7aa083bfcd9cbb89c4Johannes Berg	/*
1391b306f45300866adc01b84f7aa083bfcd9cbb89c4Johannes Berg	 * The hardware needs headroom for sending the frame,
1392b306f45300866adc01b84f7aa083bfcd9cbb89c4Johannes Berg	 * and we need some headroom for passing the frame to monitor
1393b306f45300866adc01b84f7aa083bfcd9cbb89c4Johannes Berg	 * interfaces, but never both at the same time.
1394b306f45300866adc01b84f7aa083bfcd9cbb89c4Johannes Berg	 */
139533ccad35a21df51c0d23f3e3e88688524e7b51edJiri Benc	local->tx_headroom = max_t(unsigned int , local->hw.extra_tx_headroom,
139633ccad35a21df51c0d23f3e3e88688524e7b51edJiri Benc				   sizeof(struct ieee80211_tx_status_rtap_hdr));
1397b306f45300866adc01b84f7aa083bfcd9cbb89c4Johannes Berg
1398e9f207f0ff90bf60b825800d7450e6f2ff2eab88Jiri Benc	debugfs_hw_add(local);
1399e9f207f0ff90bf60b825800d7450e6f2ff2eab88Jiri Benc
1400dc0ae30c31ee6ef83992bb692f37dfbba08a2ef6Tomas Winkler	if (local->hw.conf.beacon_int < 10)
1401dc0ae30c31ee6ef83992bb692f37dfbba08a2ef6Tomas Winkler		local->hw.conf.beacon_int = 100;
1402f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc
1403ea95bba41e69c616bb1512cf59d22f33266b8568Tomas Winkler	if (local->hw.max_listen_interval == 0)
1404ea95bba41e69c616bb1512cf59d22f33266b8568Tomas Winkler		local->hw.max_listen_interval = 1;
1405ea95bba41e69c616bb1512cf59d22f33266b8568Tomas Winkler
1406ea95bba41e69c616bb1512cf59d22f33266b8568Tomas Winkler	local->hw.conf.listen_interval = local->hw.max_listen_interval;
1407ea95bba41e69c616bb1512cf59d22f33266b8568Tomas Winkler
1408566bfe5a8bcde13188a356f77666f8115813cf31Bruno Randolf	local->wstats_flags |= local->hw.flags & (IEEE80211_HW_SIGNAL_UNSPEC |
1409566bfe5a8bcde13188a356f77666f8115813cf31Bruno Randolf						  IEEE80211_HW_SIGNAL_DB |
1410566bfe5a8bcde13188a356f77666f8115813cf31Bruno Randolf						  IEEE80211_HW_SIGNAL_DBM) ?
1411f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc			       IW_QUAL_QUAL_UPDATED : IW_QUAL_QUAL_INVALID;
1412566bfe5a8bcde13188a356f77666f8115813cf31Bruno Randolf	local->wstats_flags |= local->hw.flags & IEEE80211_HW_NOISE_DBM ?
1413f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc			       IW_QUAL_NOISE_UPDATED : IW_QUAL_NOISE_INVALID;
1414566bfe5a8bcde13188a356f77666f8115813cf31Bruno Randolf	if (local->hw.flags & IEEE80211_HW_SIGNAL_DBM)
1415f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc		local->wstats_flags |= IW_QUAL_DBM;
1416f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc
1417f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc	result = sta_info_start(local);
1418f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc	if (result < 0)
1419f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc		goto fail_sta_info;
1420f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc
1421f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc	rtnl_lock();
1422f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc	result = dev_alloc_name(local->mdev, local->mdev->name);
1423f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc	if (result < 0)
1424f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc		goto fail_dev;
1425f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc
1426f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc	memcpy(local->mdev->dev_addr, local->hw.wiphy->perm_addr, ETH_ALEN);
1427f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc	SET_NETDEV_DEV(local->mdev, wiphy_dev(local->hw.wiphy));
1428f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc
1429f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc	result = register_netdevice(local->mdev);
1430f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc	if (result < 0)
1431f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc		goto fail_dev;
1432f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc
1433830f903866a1611e9ce53f3e35202302bb938946Johannes Berg	result = ieee80211_init_rate_ctrl_alg(local,
1434830f903866a1611e9ce53f3e35202302bb938946Johannes Berg					      hw->rate_control_algorithm);
1435f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc	if (result < 0) {
1436f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc		printk(KERN_DEBUG "%s: Failed to initialize rate control "
1437dd1cd4c620c174ebbdf78dc01b924115a06de5d3Johannes Berg		       "algorithm\n", wiphy_name(local->hw.wiphy));
1438f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc		goto fail_rate;
1439f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc	}
1440f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc
1441f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc	result = ieee80211_wep_init(local);
1442f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc
1443f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc	if (result < 0) {
1444023a04bebe7030c1e6d5347bd3f27a3e49a1f222Jeremy Fitzhardinge		printk(KERN_DEBUG "%s: Failed to initialize wep: %d\n",
1445023a04bebe7030c1e6d5347bd3f27a3e49a1f222Jeremy Fitzhardinge		       wiphy_name(local->hw.wiphy), result);
1446f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc		goto fail_wep;
1447f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc	}
1448f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc
144951cb6db0f5654f08a4a6bfa3888dc36a51c2df3eDavid S. Miller	local->mdev->select_queue = ieee80211_select_queue;
1450f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc
1451f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc	/* add one default STA interface */
14523e122be089e6fb8d3f322416da4cdbb80ce12927Johannes Berg	result = ieee80211_if_add(local, "wlan%d", NULL,
1453ee3858551ae6d044578f598f8001db5f1a9fd52eLuis Carlos Cobo				  IEEE80211_IF_TYPE_STA, NULL);
1454f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc	if (result)
1455f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc		printk(KERN_WARNING "%s: Failed to add default virtual iface\n",
1456dd1cd4c620c174ebbdf78dc01b924115a06de5d3Johannes Berg		       wiphy_name(local->hw.wiphy));
1457f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc
1458f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc	rtnl_unlock();
1459f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc
1460f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc	ieee80211_led_init(local);
1461f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc
1462f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc	return 0;
1463f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc
1464f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Bencfail_wep:
1465f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc	rate_control_deinitialize(local);
1466f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Bencfail_rate:
1467f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc	unregister_netdevice(local->mdev);
1468339a7c41c913035bf58579f6e47b4ba29da83795Pavel Emelyanov	local->mdev = NULL;
1469f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Bencfail_dev:
1470f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc	rtnl_unlock();
1471f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc	sta_info_stop(local);
1472f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Bencfail_sta_info:
1473e9f207f0ff90bf60b825800d7450e6f2ff2eab88Jiri Benc	debugfs_hw_del(local);
1474f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc	destroy_workqueue(local->hw.workqueue);
1475f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Bencfail_workqueue:
14763e122be089e6fb8d3f322416da4cdbb80ce12927Johannes Berg	if (local->mdev)
14773e122be089e6fb8d3f322416da4cdbb80ce12927Johannes Berg		free_netdev(local->mdev);
147896d510566e4908f77f03ff1436c78ae7162a17d0Johannes Bergfail_mdev_alloc:
1479f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc	wiphy_unregister(local->hw.wiphy);
1480f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc	return result;
1481f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc}
1482f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri BencEXPORT_SYMBOL(ieee80211_register_hw);
1483f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc
1484f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Bencvoid ieee80211_unregister_hw(struct ieee80211_hw *hw)
1485f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc{
1486f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc	struct ieee80211_local *local = hw_to_local(hw);
1487f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc
1488f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc	tasklet_kill(&local->tx_pending_tasklet);
1489f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc	tasklet_kill(&local->tasklet);
1490f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc
1491f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc	rtnl_lock();
1492f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc
149379010420cc3f78eab911598bfdd29c4b06a83e1fJohannes Berg	/*
149479010420cc3f78eab911598bfdd29c4b06a83e1fJohannes Berg	 * At this point, interface list manipulations are fine
149579010420cc3f78eab911598bfdd29c4b06a83e1fJohannes Berg	 * because the driver cannot be handing us frames any
149679010420cc3f78eab911598bfdd29c4b06a83e1fJohannes Berg	 * more and the tasklet is killed.
149779010420cc3f78eab911598bfdd29c4b06a83e1fJohannes Berg	 */
14985b2812e925c8e976852867f8d760637c5926d817Johannes Berg
149975636525fbfa78fa33fd754c89785cfde750acd3Johannes Berg	/* First, we remove all virtual interfaces. */
150075636525fbfa78fa33fd754c89785cfde750acd3Johannes Berg	ieee80211_remove_interfaces(local);
15015b2812e925c8e976852867f8d760637c5926d817Johannes Berg
15025b2812e925c8e976852867f8d760637c5926d817Johannes Berg	/* then, finally, remove the master interface */
15033e122be089e6fb8d3f322416da4cdbb80ce12927Johannes Berg	unregister_netdevice(local->mdev);
1504f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc
1505f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc	rtnl_unlock();
1506f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc
15073e122be089e6fb8d3f322416da4cdbb80ce12927Johannes Berg	ieee80211_rx_bss_list_deinit(local);
1508f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc	ieee80211_clear_tx_pending(local);
1509f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc	sta_info_stop(local);
1510f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc	rate_control_deinitialize(local);
1511e9f207f0ff90bf60b825800d7450e6f2ff2eab88Jiri Benc	debugfs_hw_del(local);
1512f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc
1513f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc	if (skb_queue_len(&local->skb_queue)
1514f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc			|| skb_queue_len(&local->skb_queue_unreliable))
1515f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc		printk(KERN_WARNING "%s: skb_queue not empty\n",
1516dd1cd4c620c174ebbdf78dc01b924115a06de5d3Johannes Berg		       wiphy_name(local->hw.wiphy));
1517f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc	skb_queue_purge(&local->skb_queue);
1518f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc	skb_queue_purge(&local->skb_queue_unreliable);
1519f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc
1520f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc	destroy_workqueue(local->hw.workqueue);
1521f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc	wiphy_unregister(local->hw.wiphy);
1522f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc	ieee80211_wep_free(local);
1523f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc	ieee80211_led_exit(local);
15243e122be089e6fb8d3f322416da4cdbb80ce12927Johannes Berg	free_netdev(local->mdev);
1525f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc}
1526f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri BencEXPORT_SYMBOL(ieee80211_unregister_hw);
1527f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc
1528f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Bencvoid ieee80211_free_hw(struct ieee80211_hw *hw)
1529f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc{
1530f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc	struct ieee80211_local *local = hw_to_local(hw);
1531f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc
1532f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc	wiphy_free(local->hw.wiphy);
1533f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc}
1534f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri BencEXPORT_SYMBOL(ieee80211_free_hw);
1535f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc
1536f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Bencstatic int __init ieee80211_init(void)
1537f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc{
1538f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc	struct sk_buff *skb;
1539f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc	int ret;
1540f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc
1541e039fa4a4195ac4ee895e6f3d1334beed63256feJohannes Berg	BUILD_BUG_ON(sizeof(struct ieee80211_tx_info) > sizeof(skb->cb));
1542e039fa4a4195ac4ee895e6f3d1334beed63256feJohannes Berg	BUILD_BUG_ON(offsetof(struct ieee80211_tx_info, driver_data) +
1543e039fa4a4195ac4ee895e6f3d1334beed63256feJohannes Berg	             IEEE80211_TX_INFO_DRIVER_DATA_SIZE > sizeof(skb->cb));
1544f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc
15454b475898ec9dc6e62cebcb8fc0b3495c986a4590Johannes Berg	ret = rc80211_pid_init();
1546ad01837593338f13508463fa11c8dbf8109a1e5dMattias Nissler	if (ret)
154751cb6db0f5654f08a4a6bfa3888dc36a51c2df3eDavid S. Miller		return ret;
1548f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc
1549e9f207f0ff90bf60b825800d7450e6f2ff2eab88Jiri Benc	ieee80211_debugfs_netdev_init();
1550e9f207f0ff90bf60b825800d7450e6f2ff2eab88Jiri Benc
1551f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc	return 0;
1552f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc}
1553f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc
1554f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Bencstatic void __exit ieee80211_exit(void)
1555f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc{
15564b475898ec9dc6e62cebcb8fc0b3495c986a4590Johannes Berg	rc80211_pid_exit();
1557ac71c691e6a5ce991fe221d3bdb0c972f617aa37Johannes Berg
15583b96766f0e643f52ae19e134664df6730c737e87Johannes Berg	/*
15593b96766f0e643f52ae19e134664df6730c737e87Johannes Berg	 * For key todo, it'll be empty by now but the work
15603b96766f0e643f52ae19e134664df6730c737e87Johannes Berg	 * might still be scheduled.
15613b96766f0e643f52ae19e134664df6730c737e87Johannes Berg	 */
15623b96766f0e643f52ae19e134664df6730c737e87Johannes Berg	flush_scheduled_work();
15633b96766f0e643f52ae19e134664df6730c737e87Johannes Berg
1564f7a921443740d7dafc65b17aa32531730d358f50Luis Carlos Cobo	if (mesh_allocated)
1565f7a921443740d7dafc65b17aa32531730d358f50Luis Carlos Cobo		ieee80211s_stop();
1566902acc7896d7649fb30e4b22bd4e643c7f34b02cJohannes Berg
1567e9f207f0ff90bf60b825800d7450e6f2ff2eab88Jiri Benc	ieee80211_debugfs_netdev_exit();
1568f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc}
1569f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc
1570f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc
1571ca9938fea576ebbb8d8c4fbe8a5bcc937e49e1caJohannes Bergsubsys_initcall(ieee80211_init);
1572f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Bencmodule_exit(ieee80211_exit);
1573f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri Benc
1574f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri BencMODULE_DESCRIPTION("IEEE 802.11 subsystem");
1575f0706e828e96d0fa4e80c0d25aa98523f6d589a0Jiri BencMODULE_LICENSE("GPL");
1576