diff options
Diffstat (limited to 'drivers/net/wireless/rt2x00/rt2x00dev.c')
| -rw-r--r-- | drivers/net/wireless/rt2x00/rt2x00dev.c | 611 | 
1 files changed, 499 insertions, 112 deletions
diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c index c879f9a7037..4fa43a2eeb7 100644 --- a/drivers/net/wireless/rt2x00/rt2x00dev.c +++ b/drivers/net/wireless/rt2x00/rt2x00dev.c @@ -14,9 +14,7 @@  	GNU General Public License for more details.  	You should have received a copy of the GNU General Public License -	along with this program; if not, write to the -	Free Software Foundation, Inc., -	59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +	along with this program; if not, see <http://www.gnu.org/licenses/>.   */  /* @@ -27,11 +25,28 @@  #include <linux/kernel.h>  #include <linux/module.h>  #include <linux/slab.h> +#include <linux/log2.h>  #include "rt2x00.h"  #include "rt2x00lib.h"  /* + * Utility functions. + */ +u32 rt2x00lib_get_bssidx(struct rt2x00_dev *rt2x00dev, +			 struct ieee80211_vif *vif) +{ +	/* +	 * When in STA mode, bssidx is always 0 otherwise local_address[5] +	 * contains the bss number, see BSS_ID_MASK comments for details. +	 */ +	if (rt2x00dev->intf_sta_count) +		return 0; +	return vif->addr[5] & (rt2x00dev->ops->max_ap_intf - 1); +} +EXPORT_SYMBOL_GPL(rt2x00lib_get_bssidx); + +/*   * Radio control handlers.   */  int rt2x00lib_enable_radio(struct rt2x00_dev *rt2x00dev) @@ -66,21 +81,19 @@ int rt2x00lib_enable_radio(struct rt2x00_dev *rt2x00dev)  	set_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags);  	/* -	 * Enable RX. +	 * Enable queues.  	 */ -	rt2x00dev->ops->lib->set_device_state(rt2x00dev, STATE_RADIO_RX_ON); +	rt2x00queue_start_queues(rt2x00dev);  	rt2x00link_start_tuner(rt2x00dev); +	rt2x00link_start_agc(rt2x00dev); +	if (rt2x00_has_cap_vco_recalibration(rt2x00dev)) +		rt2x00link_start_vcocal(rt2x00dev);  	/*  	 * Start watchdog monitoring.  	 */  	rt2x00link_start_watchdog(rt2x00dev); -	/* -	 * Start the TX queues. -	 */ -	ieee80211_wake_queues(rt2x00dev->hw); -  	return 0;  } @@ -90,21 +103,19 @@ void rt2x00lib_disable_radio(struct rt2x00_dev *rt2x00dev)  		return;  	/* -	 * Stop the TX queues in mac80211. -	 */ -	ieee80211_stop_queues(rt2x00dev->hw); -	rt2x00queue_stop_queues(rt2x00dev); - -	/*  	 * Stop watchdog monitoring.  	 */  	rt2x00link_stop_watchdog(rt2x00dev);  	/* -	 * Disable RX. +	 * Stop all queues  	 */ +	rt2x00link_stop_agc(rt2x00dev); +	if (rt2x00_has_cap_vco_recalibration(rt2x00dev)) +		rt2x00link_stop_vcocal(rt2x00dev);  	rt2x00link_stop_tuner(rt2x00dev); -	rt2x00dev->ops->lib->set_device_state(rt2x00dev, STATE_RADIO_RX_OFF); +	rt2x00queue_stop_queues(rt2x00dev); +	rt2x00queue_flush_queues(rt2x00dev, true);  	/*  	 * Disable radio. @@ -120,19 +131,6 @@ static void rt2x00lib_intf_scheduled_iter(void *data, u8 *mac,  {  	struct rt2x00_dev *rt2x00dev = data;  	struct rt2x00_intf *intf = vif_to_intf(vif); -	int delayed_flags; - -	/* -	 * Copy all data we need during this action under the protection -	 * of a spinlock. Otherwise race conditions might occur which results -	 * into an invalid configuration. -	 */ -	spin_lock(&intf->lock); - -	delayed_flags = intf->delayed_flags; -	intf->delayed_flags = 0; - -	spin_unlock(&intf->lock);  	/*  	 * It is possible the radio was disabled while the work had been @@ -143,8 +141,8 @@ static void rt2x00lib_intf_scheduled_iter(void *data, u8 *mac,  	if (!test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags))  		return; -	if (delayed_flags & DELAYED_UPDATE_BEACON) -		rt2x00queue_update_beacon(rt2x00dev, vif, true); +	if (test_and_clear_bit(DELAYED_UPDATE_BEACON, &intf->delayed_flags)) +		rt2x00queue_update_beacon(rt2x00dev, vif);  }  static void rt2x00lib_intf_scheduled(struct work_struct *work) @@ -157,16 +155,31 @@ static void rt2x00lib_intf_scheduled(struct work_struct *work)  	 * requested configurations.  	 */  	ieee80211_iterate_active_interfaces(rt2x00dev->hw, +					    IEEE80211_IFACE_ITER_RESUME_ALL,  					    rt2x00lib_intf_scheduled_iter,  					    rt2x00dev);  } +static void rt2x00lib_autowakeup(struct work_struct *work) +{ +	struct rt2x00_dev *rt2x00dev = +	    container_of(work, struct rt2x00_dev, autowakeup_work.work); + +	if (!test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags)) +		return; + +	if (rt2x00dev->ops->lib->set_device_state(rt2x00dev, STATE_AWAKE)) +		rt2x00_err(rt2x00dev, "Device failed to wakeup\n"); +	clear_bit(CONFIG_POWERSAVING, &rt2x00dev->flags); +} +  /*   * Interrupt context handlers.   */  static void rt2x00lib_bc_buffer_iter(void *data, u8 *mac,  				     struct ieee80211_vif *vif)  { +	struct ieee80211_tx_control control = {};  	struct rt2x00_dev *rt2x00dev = data;  	struct sk_buff *skb; @@ -181,7 +194,7 @@ static void rt2x00lib_bc_buffer_iter(void *data, u8 *mac,  	 */  	skb = ieee80211_get_buffered_bc(rt2x00dev->hw, vif);  	while (skb) { -		rt2x00mac_tx(rt2x00dev->hw, skb); +		rt2x00mac_tx(rt2x00dev->hw, &control, skb);  		skb = ieee80211_get_buffered_bc(rt2x00dev->hw, vif);  	}  } @@ -197,7 +210,13 @@ static void rt2x00lib_beaconupdate_iter(void *data, u8 *mac,  	    vif->type != NL80211_IFTYPE_WDS)  		return; -	rt2x00queue_update_beacon(rt2x00dev, vif, true); +	/* +	 * Update the beacon without locking. This is safe on PCI devices +	 * as they only update the beacon periodically here. This should +	 * never be called for USB devices. +	 */ +	WARN_ON(rt2x00_is_usb(rt2x00dev)); +	rt2x00queue_update_beacon_locked(rt2x00dev, vif);  }  void rt2x00lib_beacondone(struct rt2x00_dev *rt2x00dev) @@ -206,21 +225,21 @@ void rt2x00lib_beacondone(struct rt2x00_dev *rt2x00dev)  		return;  	/* send buffered bc/mc frames out for every bssid */ -	ieee80211_iterate_active_interfaces(rt2x00dev->hw, -					    rt2x00lib_bc_buffer_iter, -					    rt2x00dev); +	ieee80211_iterate_active_interfaces_atomic( +		rt2x00dev->hw, IEEE80211_IFACE_ITER_RESUME_ALL, +		rt2x00lib_bc_buffer_iter, rt2x00dev);  	/*  	 * Devices with pre tbtt interrupt don't need to update the beacon  	 * here as they will fetch the next beacon directly prior to  	 * transmission.  	 */ -	if (test_bit(DRIVER_SUPPORT_PRE_TBTT_INTERRUPT, &rt2x00dev->flags)) +	if (rt2x00_has_cap_pre_tbtt_interrupt(rt2x00dev))  		return;  	/* fetch next beacon */ -	ieee80211_iterate_active_interfaces(rt2x00dev->hw, -					    rt2x00lib_beaconupdate_iter, -					    rt2x00dev); +	ieee80211_iterate_active_interfaces_atomic( +		rt2x00dev->hw, IEEE80211_IFACE_ITER_RESUME_ALL, +		rt2x00lib_beaconupdate_iter, rt2x00dev);  }  EXPORT_SYMBOL_GPL(rt2x00lib_beacondone); @@ -230,26 +249,77 @@ void rt2x00lib_pretbtt(struct rt2x00_dev *rt2x00dev)  		return;  	/* fetch next beacon */ -	ieee80211_iterate_active_interfaces(rt2x00dev->hw, -					    rt2x00lib_beaconupdate_iter, -					    rt2x00dev); +	ieee80211_iterate_active_interfaces_atomic( +		rt2x00dev->hw, IEEE80211_IFACE_ITER_RESUME_ALL, +		rt2x00lib_beaconupdate_iter, rt2x00dev);  }  EXPORT_SYMBOL_GPL(rt2x00lib_pretbtt); +void rt2x00lib_dmastart(struct queue_entry *entry) +{ +	set_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags); +	rt2x00queue_index_inc(entry, Q_INDEX); +} +EXPORT_SYMBOL_GPL(rt2x00lib_dmastart); +  void rt2x00lib_dmadone(struct queue_entry *entry)  { +	set_bit(ENTRY_DATA_STATUS_PENDING, &entry->flags);  	clear_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags); -	rt2x00queue_index_inc(entry->queue, Q_INDEX_DMA_DONE); +	rt2x00queue_index_inc(entry, Q_INDEX_DMA_DONE);  }  EXPORT_SYMBOL_GPL(rt2x00lib_dmadone); +static inline int rt2x00lib_txdone_bar_status(struct queue_entry *entry) +{ +	struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; +	struct ieee80211_bar *bar = (void *) entry->skb->data; +	struct rt2x00_bar_list_entry *bar_entry; +	int ret; + +	if (likely(!ieee80211_is_back_req(bar->frame_control))) +		return 0; + +	/* +	 * Unlike all other frames, the status report for BARs does +	 * not directly come from the hardware as it is incapable of +	 * matching a BA to a previously send BAR. The hardware will +	 * report all BARs as if they weren't acked at all. +	 * +	 * Instead the RX-path will scan for incoming BAs and set the +	 * block_acked flag if it sees one that was likely caused by +	 * a BAR from us. +	 * +	 * Remove remaining BARs here and return their status for +	 * TX done processing. +	 */ +	ret = 0; +	rcu_read_lock(); +	list_for_each_entry_rcu(bar_entry, &rt2x00dev->bar_list, list) { +		if (bar_entry->entry != entry) +			continue; + +		spin_lock_bh(&rt2x00dev->bar_list_lock); +		/* Return whether this BAR was blockacked or not */ +		ret = bar_entry->block_acked; +		/* Remove the BAR from our checklist */ +		list_del_rcu(&bar_entry->list); +		spin_unlock_bh(&rt2x00dev->bar_list_lock); +		kfree_rcu(bar_entry, head); + +		break; +	} +	rcu_read_unlock(); + +	return ret; +} +  void rt2x00lib_txdone(struct queue_entry *entry,  		      struct txdone_entry_desc *txdesc)  {  	struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;  	struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(entry->skb);  	struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb); -	enum data_queue_qid qid = skb_get_queue_mapping(entry->skb);  	unsigned int header_length, i;  	u8 rate_idx, rate_flags, retry_rates;  	u8 skbdesc_flags = skbdesc->flags; @@ -263,7 +333,7 @@ void rt2x00lib_txdone(struct queue_entry *entry,  	/*  	 * Remove the extra tx headroom from the skb.  	 */ -	skb_pull(entry->skb, rt2x00dev->ops->extra_tx_headroom); +	skb_pull(entry->skb, rt2x00dev->extra_tx_headroom);  	/*  	 * Signal that the TX descriptor is no longer in the skb. @@ -278,7 +348,7 @@ void rt2x00lib_txdone(struct queue_entry *entry,  	/*  	 * Remove L2 padding which was added during  	 */ -	if (test_bit(DRIVER_REQUIRE_L2PAD, &rt2x00dev->flags)) +	if (test_bit(REQUIRE_L2PAD, &rt2x00dev->cap_flags))  		rt2x00queue_remove_l2pad(entry->skb, header_length);  	/* @@ -287,7 +357,7 @@ void rt2x00lib_txdone(struct queue_entry *entry,  	 * mac80211 will expect the same data to be present it the  	 * frame as it was passed to us.  	 */ -	if (test_bit(CONFIG_SUPPORT_HW_CRYPTO, &rt2x00dev->flags)) +	if (rt2x00_has_cap_hw_crypto(rt2x00dev))  		rt2x00crypto_tx_insert_iv(entry->skb, header_length);  	/* @@ -297,9 +367,12 @@ void rt2x00lib_txdone(struct queue_entry *entry,  	rt2x00debug_dump_frame(rt2x00dev, DUMP_FRAME_TXDONE, entry->skb);  	/* -	 * Determine if the frame has been successfully transmitted. +	 * Determine if the frame has been successfully transmitted and +	 * remove BARs from our check list while checking for their +	 * TX status.  	 */  	success = +	    rt2x00lib_txdone_bar_status(entry) ||  	    test_bit(TXDONE_SUCCESS, &txdesc->flags) ||  	    test_bit(TXDONE_UNKNOWN, &txdesc->flags); @@ -360,10 +433,14 @@ void rt2x00lib_txdone(struct queue_entry *entry,  	 * which would allow the rc algorithm to better decide on  	 * which rates are suitable.  	 */ -	if (tx_info->flags & IEEE80211_TX_CTL_AMPDU) { +	if (test_bit(TXDONE_AMPDU, &txdesc->flags) || +	    tx_info->flags & IEEE80211_TX_CTL_AMPDU) {  		tx_info->flags |= IEEE80211_TX_STAT_AMPDU;  		tx_info->status.ampdu_len = 1;  		tx_info->status.ampdu_ack_len = success ? 1 : 0; + +		if (!success) +			tx_info->flags |= IEEE80211_TX_STAT_AMPDU_NO_BACK;  	}  	if (rate_flags & IEEE80211_TX_RC_USE_RTS_CTS) { @@ -379,9 +456,12 @@ void rt2x00lib_txdone(struct queue_entry *entry,  	 * through a mac80211 library call (RTS/CTS) then we should not  	 * send the status report back.  	 */ -	if (!(skbdesc_flags & SKBDESC_NOT_MAC80211)) -		ieee80211_tx_status(rt2x00dev->hw, entry->skb); -	else +	if (!(skbdesc_flags & SKBDESC_NOT_MAC80211)) { +		if (test_bit(REQUIRE_TASKLET_CONTEXT, &rt2x00dev->cap_flags)) +			ieee80211_tx_status(rt2x00dev->hw, entry->skb); +		else +			ieee80211_tx_status_ni(rt2x00dev->hw, entry->skb); +	} else  		dev_kfree_skb_any(entry->skb);  	/* @@ -392,15 +472,19 @@ void rt2x00lib_txdone(struct queue_entry *entry,  	rt2x00dev->ops->lib->clear_entry(entry); -	rt2x00queue_index_inc(entry->queue, Q_INDEX_DONE); +	rt2x00queue_index_inc(entry, Q_INDEX_DONE);  	/*  	 * If the data queue was below the threshold before the txdone  	 * handler we must make sure the packet queue in the mac80211 stack -	 * is reenabled when the txdone handler has finished. +	 * is reenabled when the txdone handler has finished. This has to be +	 * serialized with rt2x00mac_tx(), otherwise we can wake up queue +	 * before it was stopped.  	 */ +	spin_lock_bh(&entry->queue->tx_lock);  	if (!rt2x00queue_threshold(entry->queue)) -		ieee80211_wake_queue(rt2x00dev->hw, qid); +		rt2x00queue_unpause_queue(entry->queue); +	spin_unlock_bh(&entry->queue->tx_lock);  }  EXPORT_SYMBOL_GPL(rt2x00lib_txdone); @@ -416,6 +500,137 @@ void rt2x00lib_txdone_noinfo(struct queue_entry *entry, u32 status)  }  EXPORT_SYMBOL_GPL(rt2x00lib_txdone_noinfo); +static u8 *rt2x00lib_find_ie(u8 *data, unsigned int len, u8 ie) +{ +	struct ieee80211_mgmt *mgmt = (void *)data; +	u8 *pos, *end; + +	pos = (u8 *)mgmt->u.beacon.variable; +	end = data + len; +	while (pos < end) { +		if (pos + 2 + pos[1] > end) +			return NULL; + +		if (pos[0] == ie) +			return pos; + +		pos += 2 + pos[1]; +	} + +	return NULL; +} + +static void rt2x00lib_sleep(struct work_struct *work) +{ +	struct rt2x00_dev *rt2x00dev = +	    container_of(work, struct rt2x00_dev, sleep_work); + +	if (!test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags)) +		return; + +	/* +	 * Check again is powersaving is enabled, to prevent races from delayed +	 * work execution. +	 */ +	if (!test_bit(CONFIG_POWERSAVING, &rt2x00dev->flags)) +		rt2x00lib_config(rt2x00dev, &rt2x00dev->hw->conf, +				 IEEE80211_CONF_CHANGE_PS); +} + +static void rt2x00lib_rxdone_check_ba(struct rt2x00_dev *rt2x00dev, +				      struct sk_buff *skb, +				      struct rxdone_entry_desc *rxdesc) +{ +	struct rt2x00_bar_list_entry *entry; +	struct ieee80211_bar *ba = (void *)skb->data; + +	if (likely(!ieee80211_is_back(ba->frame_control))) +		return; + +	if (rxdesc->size < sizeof(*ba) + FCS_LEN) +		return; + +	rcu_read_lock(); +	list_for_each_entry_rcu(entry, &rt2x00dev->bar_list, list) { + +		if (ba->start_seq_num != entry->start_seq_num) +			continue; + +#define TID_CHECK(a, b) (						\ +	((a) & cpu_to_le16(IEEE80211_BAR_CTRL_TID_INFO_MASK)) ==	\ +	((b) & cpu_to_le16(IEEE80211_BAR_CTRL_TID_INFO_MASK)))		\ + +		if (!TID_CHECK(ba->control, entry->control)) +			continue; + +#undef TID_CHECK + +		if (!ether_addr_equal_64bits(ba->ra, entry->ta)) +			continue; + +		if (!ether_addr_equal_64bits(ba->ta, entry->ra)) +			continue; + +		/* Mark BAR since we received the according BA */ +		spin_lock_bh(&rt2x00dev->bar_list_lock); +		entry->block_acked = 1; +		spin_unlock_bh(&rt2x00dev->bar_list_lock); +		break; +	} +	rcu_read_unlock(); + +} + +static void rt2x00lib_rxdone_check_ps(struct rt2x00_dev *rt2x00dev, +				      struct sk_buff *skb, +				      struct rxdone_entry_desc *rxdesc) +{ +	struct ieee80211_hdr *hdr = (void *) skb->data; +	struct ieee80211_tim_ie *tim_ie; +	u8 *tim; +	u8 tim_len; +	bool cam; + +	/* If this is not a beacon, or if mac80211 has no powersaving +	 * configured, or if the device is already in powersaving mode +	 * we can exit now. */ +	if (likely(!ieee80211_is_beacon(hdr->frame_control) || +		   !(rt2x00dev->hw->conf.flags & IEEE80211_CONF_PS))) +		return; + +	/* min. beacon length + FCS_LEN */ +	if (skb->len <= 40 + FCS_LEN) +		return; + +	/* and only beacons from the associated BSSID, please */ +	if (!(rxdesc->dev_flags & RXDONE_MY_BSS) || +	    !rt2x00dev->aid) +		return; + +	rt2x00dev->last_beacon = jiffies; + +	tim = rt2x00lib_find_ie(skb->data, skb->len - FCS_LEN, WLAN_EID_TIM); +	if (!tim) +		return; + +	if (tim[1] < sizeof(*tim_ie)) +		return; + +	tim_len = tim[1]; +	tim_ie = (struct ieee80211_tim_ie *) &tim[2]; + +	/* Check whenever the PHY can be turned off again. */ + +	/* 1. What about buffered unicast traffic for our AID? */ +	cam = ieee80211_check_tim(tim_ie, tim_len, rt2x00dev->aid); + +	/* 2. Maybe the AP wants to send multicast/broadcast data? */ +	cam |= (tim_ie->bitmap_ctrl & 0x01); + +	if (!cam && !test_bit(CONFIG_POWERSAVING, &rt2x00dev->flags)) +		queue_work(rt2x00dev->workqueue, &rt2x00dev->sleep_work); +} +  static int rt2x00lib_rxdone_read_signal(struct rt2x00_dev *rt2x00dev,  					struct rxdone_entry_desc *rxdesc)  { @@ -457,13 +672,12 @@ static int rt2x00lib_rxdone_read_signal(struct rt2x00_dev *rt2x00dev,  		break;  	} -	WARNING(rt2x00dev, "Frame received with unrecognized signal, " -		"mode=0x%.4x, signal=0x%.4x, type=%d.\n", -		rxdesc->rate_mode, signal, type); +	rt2x00_warn(rt2x00dev, "Frame received with unrecognized signal, mode=0x%.4x, signal=0x%.4x, type=%d\n", +		    rxdesc->rate_mode, signal, type);  	return 0;  } -void rt2x00lib_rxdone(struct queue_entry *entry) +void rt2x00lib_rxdone(struct queue_entry *entry, gfp_t gfp)  {  	struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;  	struct rxdone_entry_desc rxdesc; @@ -483,7 +697,7 @@ void rt2x00lib_rxdone(struct queue_entry *entry)  	 * Allocate a new sk_buffer. If no new buffer available, drop the  	 * received frame and reuse the existing buffer.  	 */ -	skb = rt2x00queue_alloc_rxskb(entry); +	skb = rt2x00queue_alloc_rxskb(entry, gfp);  	if (!skb)  		goto submit_entry; @@ -499,6 +713,18 @@ void rt2x00lib_rxdone(struct queue_entry *entry)  	rt2x00dev->ops->lib->fill_rxdone(entry, &rxdesc);  	/* +	 * Check for valid size in case we get corrupted descriptor from +	 * hardware. +	 */ +	if (unlikely(rxdesc.size == 0 || +		     rxdesc.size > entry->queue->data_size)) { +		rt2x00_err(rt2x00dev, "Wrong frame size %d max %d\n", +			   rxdesc.size, entry->queue->data_size); +		dev_kfree_skb(entry->skb); +		goto renew_skb; +	} + +	/*  	 * The data behind the ieee80211 header must be  	 * aligned on a 4 byte boundary.  	 */ @@ -518,8 +744,6 @@ void rt2x00lib_rxdone(struct queue_entry *entry)  		 (rxdesc.size > header_length) &&  		 (rxdesc.dev_flags & RXDONE_L2PAD))  		rt2x00queue_remove_l2pad(entry->skb, header_length); -	else -		rt2x00queue_align_payload(entry->skb, header_length);  	/* Trim buffer to correct size */  	skb_trim(entry->skb, rxdesc.size); @@ -533,6 +757,18 @@ void rt2x00lib_rxdone(struct queue_entry *entry)  		rxdesc.flags |= RX_FLAG_HT;  	/* +	 * Check if this is a beacon, and more frames have been +	 * buffered while we were in powersaving mode. +	 */ +	rt2x00lib_rxdone_check_ps(rt2x00dev, entry->skb, &rxdesc); + +	/* +	 * Check for incoming BlockAcks to match to the BlockAckReqs +	 * we've send out. +	 */ +	rt2x00lib_rxdone_check_ba(rt2x00dev, entry->skb, &rxdesc); + +	/*  	 * Update extra components  	 */  	rt2x00link_update_stats(rt2x00dev, entry->skb, &rxdesc); @@ -544,6 +780,14 @@ void rt2x00lib_rxdone(struct queue_entry *entry)  	 * to mac80211.  	 */  	rx_status = IEEE80211_SKB_RXCB(entry->skb); + +	/* Ensure that all fields of rx_status are initialized +	 * properly. The skb->cb array was used for driver +	 * specific informations, so rx_status might contain +	 * garbage. +	 */ +	memset(rx_status, 0, sizeof(*rx_status)); +  	rx_status->mactime = rxdesc.timestamp;  	rx_status->band = rt2x00dev->curr_band;  	rx_status->freq = rt2x00dev->curr_freq; @@ -554,6 +798,7 @@ void rt2x00lib_rxdone(struct queue_entry *entry)  	ieee80211_rx_ni(rt2x00dev->hw, entry->skb); +renew_skb:  	/*  	 * Replace the skb with the freshly allocated one.  	 */ @@ -561,12 +806,10 @@ void rt2x00lib_rxdone(struct queue_entry *entry)  submit_entry:  	entry->flags = 0; -	rt2x00queue_index_inc(entry->queue, Q_INDEX_DONE); +	rt2x00queue_index_inc(entry, Q_INDEX_DONE);  	if (test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags) && -	    test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags)) { +	    test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags))  		rt2x00dev->ops->lib->clear_entry(entry); -		rt2x00queue_index_inc(entry->queue, Q_INDEX); -	}  }  EXPORT_SYMBOL_GPL(rt2x00lib_rxdone); @@ -664,7 +907,10 @@ static void rt2x00lib_channel(struct ieee80211_channel *entry,  			      const int channel, const int tx_power,  			      const int value)  { -	entry->center_freq = ieee80211_channel_to_frequency(channel); +	/* XXX: this assumption about the band is wrong for 802.11j */ +	entry->band = channel <= 14 ? IEEE80211_BAND_2GHZ : IEEE80211_BAND_5GHZ; +	entry->center_freq = ieee80211_channel_to_frequency(channel, +							    entry->band);  	entry->hw_value = value;  	entry->max_power = tx_power;  	entry->max_antenna_gain = 0xff; @@ -697,11 +943,11 @@ static int rt2x00lib_probe_hw_modes(struct rt2x00_dev *rt2x00dev,  	if (spec->supported_rates & SUPPORT_RATE_OFDM)  		num_rates += 8; -	channels = kzalloc(sizeof(*channels) * spec->num_channels, GFP_KERNEL); +	channels = kcalloc(spec->num_channels, sizeof(*channels), GFP_KERNEL);  	if (!channels)  		return -ENOMEM; -	rates = kzalloc(sizeof(*rates) * num_rates, GFP_KERNEL); +	rates = kcalloc(num_rates, sizeof(*rates), GFP_KERNEL);  	if (!rates)  		goto exit_free_channels; @@ -758,7 +1004,7 @@ static int rt2x00lib_probe_hw_modes(struct rt2x00_dev *rt2x00dev,   exit_free_channels:  	kfree(channels); -	ERROR(rt2x00dev, "Allocation ieee80211 modes failed.\n"); +	rt2x00_err(rt2x00dev, "Allocation ieee80211 modes failed\n");  	return -ENOMEM;  } @@ -802,40 +1048,63 @@ static int rt2x00lib_probe_hw(struct rt2x00_dev *rt2x00dev)  	 */  	rt2x00dev->hw->extra_tx_headroom =  		max_t(unsigned int, IEEE80211_TX_STATUS_HEADROOM, -		      rt2x00dev->ops->extra_tx_headroom); +		      rt2x00dev->extra_tx_headroom);  	/*  	 * Take TX headroom required for alignment into account.  	 */ -	if (test_bit(DRIVER_REQUIRE_L2PAD, &rt2x00dev->flags)) +	if (test_bit(REQUIRE_L2PAD, &rt2x00dev->cap_flags))  		rt2x00dev->hw->extra_tx_headroom += RT2X00_L2PAD_SIZE; -	else if (test_bit(DRIVER_REQUIRE_DMA, &rt2x00dev->flags)) +	else if (test_bit(REQUIRE_DMA, &rt2x00dev->cap_flags))  		rt2x00dev->hw->extra_tx_headroom += RT2X00_ALIGN_SIZE;  	/* +	 * Tell mac80211 about the size of our private STA structure. +	 */ +	rt2x00dev->hw->sta_data_size = sizeof(struct rt2x00_sta); + +	/*  	 * Allocate tx status FIFO for driver use.  	 */ -	if (test_bit(DRIVER_REQUIRE_TXSTATUS_FIFO, &rt2x00dev->flags) && -	    rt2x00dev->ops->lib->txstatus_tasklet) { +	if (test_bit(REQUIRE_TXSTATUS_FIFO, &rt2x00dev->cap_flags)) {  		/* -		 * Allocate txstatus fifo and tasklet, we use a size of 512 -		 * for the kfifo which is big enough to store 512/4=128 tx -		 * status reports. In the worst case (tx status for all tx -		 * queues gets reported before we've got a chance to handle -		 * them) 24*4=384 tx status reports need to be cached. +		 * Allocate the txstatus fifo. In the worst case the tx +		 * status fifo has to hold the tx status of all entries +		 * in all tx queues. Hence, calculate the kfifo size as +		 * tx_queues * entry_num and round up to the nearest +		 * power of 2.  		 */ -		status = kfifo_alloc(&rt2x00dev->txstatus_fifo, 512, +		int kfifo_size = +			roundup_pow_of_two(rt2x00dev->ops->tx_queues * +					   rt2x00dev->tx->limit * +					   sizeof(u32)); + +		status = kfifo_alloc(&rt2x00dev->txstatus_fifo, kfifo_size,  				     GFP_KERNEL);  		if (status)  			return status; +	} -		/* tasklet for processing the tx status reports. */ -		tasklet_init(&rt2x00dev->txstatus_tasklet, -			     rt2x00dev->ops->lib->txstatus_tasklet, -			     (unsigned long)rt2x00dev); - +	/* +	 * Initialize tasklets if used by the driver. Tasklets are +	 * disabled until the interrupts are turned on. The driver +	 * has to handle that. +	 */ +#define RT2X00_TASKLET_INIT(taskletname) \ +	if (rt2x00dev->ops->lib->taskletname) { \ +		tasklet_init(&rt2x00dev->taskletname, \ +			     rt2x00dev->ops->lib->taskletname, \ +			     (unsigned long)rt2x00dev); \  	} +	RT2X00_TASKLET_INIT(txstatus_tasklet); +	RT2X00_TASKLET_INIT(pretbtt_tasklet); +	RT2X00_TASKLET_INIT(tbtt_tasklet); +	RT2X00_TASKLET_INIT(rxdone_tasklet); +	RT2X00_TASKLET_INIT(autowake_tasklet); + +#undef RT2X00_TASKLET_INIT +  	/*  	 * Register HW.  	 */ @@ -857,9 +1126,10 @@ static void rt2x00lib_uninitialize(struct rt2x00_dev *rt2x00dev)  		return;  	/* -	 * Unregister extra components. +	 * Stop rfkill polling.  	 */ -	rt2x00rfkill_unregister(rt2x00dev); +	if (test_bit(REQUIRE_DELAYED_RFKILL, &rt2x00dev->cap_flags)) +		rt2x00rfkill_unregister(rt2x00dev);  	/*  	 * Allow the HW to uninitialize. @@ -898,9 +1168,10 @@ static int rt2x00lib_initialize(struct rt2x00_dev *rt2x00dev)  	set_bit(DEVICE_STATE_INITIALIZED, &rt2x00dev->flags);  	/* -	 * Register the extra components. +	 * Start rfkill polling.  	 */ -	rt2x00rfkill_register(rt2x00dev); +	if (test_bit(REQUIRE_DELAYED_RFKILL, &rt2x00dev->cap_flags)) +		rt2x00rfkill_register(rt2x00dev);  	return 0;  } @@ -957,6 +1228,51 @@ void rt2x00lib_stop(struct rt2x00_dev *rt2x00dev)  	rt2x00dev->intf_associated = 0;  } +static inline void rt2x00lib_set_if_combinations(struct rt2x00_dev *rt2x00dev) +{ +	struct ieee80211_iface_limit *if_limit; +	struct ieee80211_iface_combination *if_combination; + +	if (rt2x00dev->ops->max_ap_intf < 2) +		return; + +	/* +	 * Build up AP interface limits structure. +	 */ +	if_limit = &rt2x00dev->if_limits_ap; +	if_limit->max = rt2x00dev->ops->max_ap_intf; +	if_limit->types = BIT(NL80211_IFTYPE_AP); +#ifdef CONFIG_MAC80211_MESH +	if_limit->types |= BIT(NL80211_IFTYPE_MESH_POINT); +#endif + +	/* +	 * Build up AP interface combinations structure. +	 */ +	if_combination = &rt2x00dev->if_combinations[IF_COMB_AP]; +	if_combination->limits = if_limit; +	if_combination->n_limits = 1; +	if_combination->max_interfaces = if_limit->max; +	if_combination->num_different_channels = 1; + +	/* +	 * Finally, specify the possible combinations to mac80211. +	 */ +	rt2x00dev->hw->wiphy->iface_combinations = rt2x00dev->if_combinations; +	rt2x00dev->hw->wiphy->n_iface_combinations = 1; +} + +static unsigned int rt2x00dev_extra_tx_headroom(struct rt2x00_dev *rt2x00dev) +{ +	if (WARN_ON(!rt2x00dev->tx)) +		return 0; + +	if (rt2x00_is_usb(rt2x00dev)) +		return rt2x00dev->tx[0].winfo_size + rt2x00dev->tx[0].desc_size; + +	return rt2x00dev->tx[0].winfo_size; +} +  /*   * driver allocation handlers.   */ @@ -964,7 +1280,27 @@ int rt2x00lib_probe_dev(struct rt2x00_dev *rt2x00dev)  {  	int retval = -ENOMEM; +	/* +	 * Set possible interface combinations. +	 */ +	rt2x00lib_set_if_combinations(rt2x00dev); + +	/* +	 * Allocate the driver data memory, if necessary. +	 */ +	if (rt2x00dev->ops->drv_data_size > 0) { +		rt2x00dev->drv_data = kzalloc(rt2x00dev->ops->drv_data_size, +			                      GFP_KERNEL); +		if (!rt2x00dev->drv_data) { +			retval = -ENOMEM; +			goto exit; +		} +	} + +	spin_lock_init(&rt2x00dev->irqmask_lock);  	mutex_init(&rt2x00dev->csr_mutex); +	INIT_LIST_HEAD(&rt2x00dev->bar_list); +	spin_lock_init(&rt2x00dev->bar_list_lock);  	set_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags); @@ -975,29 +1311,32 @@ int rt2x00lib_probe_dev(struct rt2x00_dev *rt2x00dev)  	rt2x00dev->hw->vif_data_size = sizeof(struct rt2x00_intf);  	/* -	 * Determine which operating modes are supported, all modes -	 * which require beaconing, depend on the availability of -	 * beacon entries. +	 * rt2x00 devices can only use the last n bits of the MAC address +	 * for virtual interfaces.  	 */ -	rt2x00dev->hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION); -	if (rt2x00dev->ops->bcn->entry_num > 0) -		rt2x00dev->hw->wiphy->interface_modes |= -		    BIT(NL80211_IFTYPE_ADHOC) | -		    BIT(NL80211_IFTYPE_AP) | -		    BIT(NL80211_IFTYPE_MESH_POINT) | -		    BIT(NL80211_IFTYPE_WDS); +	rt2x00dev->hw->wiphy->addr_mask[ETH_ALEN - 1] = +		(rt2x00dev->ops->max_ap_intf - 1);  	/* -	 * Initialize configuration work. +	 * Initialize work.  	 */ +	rt2x00dev->workqueue = +	    alloc_ordered_workqueue("%s", 0, wiphy_name(rt2x00dev->hw->wiphy)); +	if (!rt2x00dev->workqueue) { +		retval = -ENOMEM; +		goto exit; +	} +  	INIT_WORK(&rt2x00dev->intf_work, rt2x00lib_intf_scheduled); +	INIT_DELAYED_WORK(&rt2x00dev->autowakeup_work, rt2x00lib_autowakeup); +	INIT_WORK(&rt2x00dev->sleep_work, rt2x00lib_sleep);  	/*  	 * Let the driver probe the device to detect the capabilities.  	 */  	retval = rt2x00dev->ops->lib->probe_hw(rt2x00dev);  	if (retval) { -		ERROR(rt2x00dev, "Failed to allocate device.\n"); +		rt2x00_err(rt2x00dev, "Failed to allocate device\n");  		goto exit;  	} @@ -1008,12 +1347,32 @@ int rt2x00lib_probe_dev(struct rt2x00_dev *rt2x00dev)  	if (retval)  		goto exit; +	/* Cache TX headroom value */ +	rt2x00dev->extra_tx_headroom = rt2x00dev_extra_tx_headroom(rt2x00dev); + +	/* +	 * Determine which operating modes are supported, all modes +	 * which require beaconing, depend on the availability of +	 * beacon entries. +	 */ +	rt2x00dev->hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION); +	if (rt2x00dev->bcn->limit > 0) +		rt2x00dev->hw->wiphy->interface_modes |= +		    BIT(NL80211_IFTYPE_ADHOC) | +		    BIT(NL80211_IFTYPE_AP) | +#ifdef CONFIG_MAC80211_MESH +		    BIT(NL80211_IFTYPE_MESH_POINT) | +#endif +		    BIT(NL80211_IFTYPE_WDS); + +	rt2x00dev->hw->wiphy->flags |= WIPHY_FLAG_IBSS_RSN; +  	/*  	 * Initialize ieee80211 structure.  	 */  	retval = rt2x00lib_probe_hw(rt2x00dev);  	if (retval) { -		ERROR(rt2x00dev, "Failed to initialize hw.\n"); +		rt2x00_err(rt2x00dev, "Failed to initialize hw\n");  		goto exit;  	} @@ -1024,6 +1383,12 @@ int rt2x00lib_probe_dev(struct rt2x00_dev *rt2x00dev)  	rt2x00leds_register(rt2x00dev);  	rt2x00debug_register(rt2x00dev); +	/* +	 * Start rfkill polling. +	 */ +	if (!test_bit(REQUIRE_DELAYED_RFKILL, &rt2x00dev->cap_flags)) +		rt2x00rfkill_register(rt2x00dev); +  	return 0;  exit: @@ -1038,6 +1403,12 @@ void rt2x00lib_remove_dev(struct rt2x00_dev *rt2x00dev)  	clear_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags);  	/* +	 * Stop rfkill polling. +	 */ +	if (!test_bit(REQUIRE_DELAYED_RFKILL, &rt2x00dev->cap_flags)) +		rt2x00rfkill_unregister(rt2x00dev); + +	/*  	 * Disable radio.  	 */  	rt2x00lib_disable_radio(rt2x00dev); @@ -1046,8 +1417,15 @@ void rt2x00lib_remove_dev(struct rt2x00_dev *rt2x00dev)  	 * Stop all work.  	 */  	cancel_work_sync(&rt2x00dev->intf_work); -	cancel_work_sync(&rt2x00dev->rxdone_work); -	cancel_work_sync(&rt2x00dev->txdone_work); +	cancel_delayed_work_sync(&rt2x00dev->autowakeup_work); +	cancel_work_sync(&rt2x00dev->sleep_work); +	if (rt2x00_is_usb(rt2x00dev)) { +		hrtimer_cancel(&rt2x00dev->txstatus_timer); +		cancel_work_sync(&rt2x00dev->rxdone_work); +		cancel_work_sync(&rt2x00dev->txdone_work); +	} +	if (rt2x00dev->workqueue) +		destroy_workqueue(rt2x00dev->workqueue);  	/*  	 * Free the tx status fifo. @@ -1058,6 +1436,10 @@ void rt2x00lib_remove_dev(struct rt2x00_dev *rt2x00dev)  	 * Kill the tx status tasklet.  	 */  	tasklet_kill(&rt2x00dev->txstatus_tasklet); +	tasklet_kill(&rt2x00dev->pretbtt_tasklet); +	tasklet_kill(&rt2x00dev->tbtt_tasklet); +	tasklet_kill(&rt2x00dev->rxdone_tasklet); +	tasklet_kill(&rt2x00dev->autowake_tasklet);  	/*  	 * Uninitialize device. @@ -1084,6 +1466,12 @@ void rt2x00lib_remove_dev(struct rt2x00_dev *rt2x00dev)  	 * Free queue structures.  	 */  	rt2x00queue_free(rt2x00dev); + +	/* +	 * Free the driver data. +	 */ +	if (rt2x00dev->drv_data) +		kfree(rt2x00dev->drv_data);  }  EXPORT_SYMBOL_GPL(rt2x00lib_remove_dev); @@ -1093,7 +1481,7 @@ EXPORT_SYMBOL_GPL(rt2x00lib_remove_dev);  #ifdef CONFIG_PM  int rt2x00lib_suspend(struct rt2x00_dev *rt2x00dev, pm_message_t state)  { -	NOTICE(rt2x00dev, "Going to sleep.\n"); +	rt2x00_dbg(rt2x00dev, "Going to sleep\n");  	/*  	 * Prevent mac80211 from accessing driver while suspended. @@ -1124,8 +1512,7 @@ int rt2x00lib_suspend(struct rt2x00_dev *rt2x00dev, pm_message_t state)  	 * device is as good as disabled.  	 */  	if (rt2x00dev->ops->lib->set_device_state(rt2x00dev, STATE_SLEEP)) -		WARNING(rt2x00dev, "Device failed to enter sleep state, " -			"continue suspending.\n"); +		rt2x00_warn(rt2x00dev, "Device failed to enter sleep state, continue suspending\n");  	return 0;  } @@ -1133,7 +1520,7 @@ EXPORT_SYMBOL_GPL(rt2x00lib_suspend);  int rt2x00lib_resume(struct rt2x00_dev *rt2x00dev)  { -	NOTICE(rt2x00dev, "Waking up.\n"); +	rt2x00_dbg(rt2x00dev, "Waking up\n");  	/*  	 * Restore/enable extra components.  | 
