diff options
Diffstat (limited to 'drivers/net/wireless')
43 files changed, 215 insertions, 112 deletions
diff --git a/drivers/net/wireless/airo.c b/drivers/net/wireless/airo.c index c70604f0329..8ce5e4cee16 100644 --- a/drivers/net/wireless/airo.c +++ b/drivers/net/wireless/airo.c @@ -5918,20 +5918,19 @@ static int airo_set_essid(struct net_device *dev,  	readSsidRid(local, &SSID_rid);  	/* Check if we asked for `any' */ -	if(dwrq->flags == 0) { +	if (dwrq->flags == 0) {  		/* Just send an empty SSID list */  		memset(&SSID_rid, 0, sizeof(SSID_rid));  	} else { -		int	index = (dwrq->flags & IW_ENCODE_INDEX) - 1; +		unsigned index = (dwrq->flags & IW_ENCODE_INDEX) - 1;  		/* Check the size of the string */ -		if(dwrq->length > IW_ESSID_MAX_SIZE) { +		if (dwrq->length > IW_ESSID_MAX_SIZE)  			return -E2BIG ; -		} +  		/* Check if index is valid */ -		if((index < 0) || (index >= 4)) { +		if (index >= ARRAY_SIZE(SSID_rid.ssids))  			return -EINVAL; -		}  		/* Set the SSID */  		memset(SSID_rid.ssids[index].ssid, 0, @@ -6819,7 +6818,7 @@ static int airo_set_txpow(struct net_device *dev,  		return -EINVAL;  	}  	clear_bit (FLAG_RADIO_OFF, &local->flags); -	for (i = 0; cap_rid.txPowerLevels[i] && (i < 8); i++) +	for (i = 0; i < 8 && cap_rid.txPowerLevels[i]; i++)  		if (v == cap_rid.txPowerLevels[i]) {  			readConfigRid(local, 1);  			local->config.txPower = v; diff --git a/drivers/net/wireless/ath/Kconfig b/drivers/net/wireless/ath/Kconfig index d26e7b48531..eb0337c4954 100644 --- a/drivers/net/wireless/ath/Kconfig +++ b/drivers/net/wireless/ath/Kconfig @@ -1,5 +1,6 @@  config ATH_COMMON  	tristate "Atheros Wireless Cards" +	depends on WLAN_80211  	depends on ATH5K || ATH9K || AR9170_USB  source "drivers/net/wireless/ath/ath5k/Kconfig" diff --git a/drivers/net/wireless/ath/ar9170/main.c b/drivers/net/wireless/ath/ar9170/main.c index 9d38cf60a0d..88c3d857386 100644 --- a/drivers/net/wireless/ath/ar9170/main.c +++ b/drivers/net/wireless/ath/ar9170/main.c @@ -1967,13 +1967,14 @@ static int ar9170_conf_tx(struct ieee80211_hw *hw, u16 queue,  	int ret;  	mutex_lock(&ar->mutex); -	if ((param) && !(queue > __AR9170_NUM_TXQ)) { +	if (queue < __AR9170_NUM_TXQ) {  		memcpy(&ar->edcf[ar9170_qos_hwmap[queue]],  		       param, sizeof(*param));  		ret = ar9170_set_qos(ar); -	} else +	} else {  		ret = -EINVAL; +	}  	mutex_unlock(&ar->mutex);  	return ret; diff --git a/drivers/net/wireless/ath/ar9170/usb.c b/drivers/net/wireless/ath/ar9170/usb.c index 754b1f8d8da..007eb85fc67 100644 --- a/drivers/net/wireless/ath/ar9170/usb.c +++ b/drivers/net/wireless/ath/ar9170/usb.c @@ -598,11 +598,15 @@ static int ar9170_usb_request_firmware(struct ar9170_usb *aru)  	err = request_firmware(&aru->init_values, "ar9170-1.fw",  			       &aru->udev->dev); +	if (err) { +		dev_err(&aru->udev->dev, "file with init values not found.\n"); +		return err; +	}  	err = request_firmware(&aru->firmware, "ar9170-2.fw", &aru->udev->dev);  	if (err) {  		release_firmware(aru->init_values); -		dev_err(&aru->udev->dev, "file with init values not found.\n"); +		dev_err(&aru->udev->dev, "firmware file not found.\n");  		return err;  	} diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c index ea045151f95..029c1bc7468 100644 --- a/drivers/net/wireless/ath/ath5k/base.c +++ b/drivers/net/wireless/ath/ath5k/base.c @@ -2970,6 +2970,9 @@ ath5k_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,  	if (modparam_nohwcrypt)  		return -EOPNOTSUPP; +	if (sc->opmode == NL80211_IFTYPE_AP) +		return -EOPNOTSUPP; +  	switch (key->alg) {  	case ALG_WEP:  	case ALG_TKIP: diff --git a/drivers/net/wireless/ath/ath9k/ani.c b/drivers/net/wireless/ath/ath9k/ani.c index 1aeafb511dd..aad259b4c19 100644 --- a/drivers/net/wireless/ath/ath9k/ani.c +++ b/drivers/net/wireless/ath/ath9k/ani.c @@ -478,6 +478,18 @@ void ath9k_ani_reset(struct ath_hw *ah)  			"Reset ANI state opmode %u\n", ah->opmode);  		ah->stats.ast_ani_reset++; +		if (ah->opmode == NL80211_IFTYPE_AP) { +			/* +			 * ath9k_hw_ani_control() will only process items set on +			 * ah->ani_function +			 */ +			if (IS_CHAN_2GHZ(chan)) +				ah->ani_function = (ATH9K_ANI_SPUR_IMMUNITY_LEVEL | +						    ATH9K_ANI_FIRSTEP_LEVEL); +			else +				ah->ani_function = 0; +		} +  		ath9k_hw_ani_control(ah, ATH9K_ANI_NOISE_IMMUNITY_LEVEL, 0);  		ath9k_hw_ani_control(ah, ATH9K_ANI_SPUR_IMMUNITY_LEVEL, 0);  		ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL, 0); diff --git a/drivers/net/wireless/ath/ath9k/eeprom.c b/drivers/net/wireless/ath/ath9k/eeprom.c index a2fda702b62..ce0e86c36a8 100644 --- a/drivers/net/wireless/ath/ath9k/eeprom.c +++ b/drivers/net/wireless/ath/ath9k/eeprom.c @@ -460,7 +460,7 @@ static int ath9k_hw_4k_check_eeprom(struct ath_hw *ah)  		integer = swab32(eep->modalHeader.antCtrlCommon);  		eep->modalHeader.antCtrlCommon = integer; -		for (i = 0; i < AR5416_MAX_CHAINS; i++) { +		for (i = 0; i < AR5416_EEP4K_MAX_CHAINS; i++) {  			integer = swab32(eep->modalHeader.antCtrlChain[i]);  			eep->modalHeader.antCtrlChain[i] = integer;  		} @@ -914,7 +914,7 @@ static void ath9k_hw_set_4k_power_per_rate_table(struct ath_hw *ah,  			ctlMode, numCtlModes, isHt40CtlMode,  			(pCtlMode[ctlMode] & EXT_ADDITIVE)); -		for (i = 0; (i < AR5416_NUM_CTLS) && +		for (i = 0; (i < AR5416_EEP4K_NUM_CTLS) &&  				pEepData->ctlIndex[i]; i++) {  			DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,  				"  LOOP-Ctlidx %d: cfgCtl 0x%2.2x " diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index b61a071788a..4ccf48e396d 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c @@ -355,7 +355,14 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,  		}  		if (bf_next == NULL) { -			INIT_LIST_HEAD(&bf_head); +			/* +			 * Make sure the last desc is reclaimed if it +			 * not a holding desc. +			 */ +			if (!bf_last->bf_stale) +				list_move_tail(&bf->list, &bf_head); +			else +				INIT_LIST_HEAD(&bf_head);  		} else {  			ASSERT(!list_empty(bf_q));  			list_move_tail(&bf->list, &bf_head); diff --git a/drivers/net/wireless/ath/regd.c b/drivers/net/wireless/ath/regd.c index eef370bd121..bf3d25ba7be 100644 --- a/drivers/net/wireless/ath/regd.c +++ b/drivers/net/wireless/ath/regd.c @@ -474,6 +474,21 @@ ath_regd_init_wiphy(struct ath_regulatory *reg,  	return 0;  } +/* + * Some users have reported their EEPROM programmed with + * 0x8000 set, this is not a supported regulatory domain + * but since we have more than one user with it we need + * a solution for them. We default to 0x64, which is the + * default Atheros world regulatory domain. + */ +static void ath_regd_sanitize(struct ath_regulatory *reg) +{ +	if (reg->current_rd != COUNTRY_ERD_FLAG) +		return; +	printk(KERN_DEBUG "ath: EEPROM regdomain sanitized\n"); +	reg->current_rd = 0x64; +} +  int  ath_regd_init(struct ath_regulatory *reg,  	      struct wiphy *wiphy, @@ -486,6 +501,8 @@ ath_regd_init(struct ath_regulatory *reg,  	if (!reg)  		return -EINVAL; +	ath_regd_sanitize(reg); +  	printk(KERN_DEBUG "ath: EEPROM regdomain: 0x%0x\n", reg->current_rd);  	if (!ath_regd_is_eeprom_valid(reg)) { diff --git a/drivers/net/wireless/b43/b43.h b/drivers/net/wireless/b43/b43.h index f580c2812d9..40448067e4c 100644 --- a/drivers/net/wireless/b43/b43.h +++ b/drivers/net/wireless/b43/b43.h @@ -648,6 +648,7 @@ struct b43_wl {  	u8 nr_devs;  	bool radiotap_enabled; +	bool radio_enabled;  	/* The beacon we are currently using (AP or IBSS mode).  	 * This beacon stuff is protected by the irq_lock. */ diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c index 6456afebdba..e71c8d9cd70 100644 --- a/drivers/net/wireless/b43/main.c +++ b/drivers/net/wireless/b43/main.c @@ -3497,8 +3497,8 @@ static int b43_op_config(struct ieee80211_hw *hw, u32 changed)  	if (phy->ops->set_rx_antenna)  		phy->ops->set_rx_antenna(dev, antenna); -	if (!!conf->radio_enabled != phy->radio_on) { -		if (conf->radio_enabled) { +	if (wl->radio_enabled != phy->radio_on) { +		if (wl->radio_enabled) {  			b43_software_rfkill(dev, false);  			b43info(dev->wl, "Radio turned on by software\n");  			if (!dev->radio_hw_enable) { @@ -4339,6 +4339,7 @@ static int b43_op_start(struct ieee80211_hw *hw)  	wl->beacon0_uploaded = 0;  	wl->beacon1_uploaded = 0;  	wl->beacon_templates_virgin = 1; +	wl->radio_enabled = 1;  	mutex_lock(&wl->mutex); @@ -4378,6 +4379,7 @@ static void b43_op_stop(struct ieee80211_hw *hw)  	if (b43_status(dev) >= B43_STAT_STARTED)  		b43_wireless_core_stop(dev);  	b43_wireless_core_exit(dev); +	wl->radio_enabled = 0;  	mutex_unlock(&wl->mutex);  	cancel_work_sync(&(wl->txpower_adjust_work)); @@ -4560,6 +4562,7 @@ static int b43_wireless_core_attach(struct b43_wldev *dev)  		B43_WARN_ON(1);  	dev->phy.gmode = have_2ghz_phy; +	dev->phy.radio_on = 1;  	tmp = dev->phy.gmode ? B43_TMSLOW_GMODE : 0;  	b43_wireless_core_reset(dev, tmp); diff --git a/drivers/net/wireless/b43/pcmcia.c b/drivers/net/wireless/b43/pcmcia.c index 3cfc30307a2..6c3a74964ab 100644 --- a/drivers/net/wireless/b43/pcmcia.c +++ b/drivers/net/wireless/b43/pcmcia.c @@ -35,6 +35,7 @@  static /*const */ struct pcmcia_device_id b43_pcmcia_tbl[] = {  	PCMCIA_DEVICE_MANF_CARD(0x2D0, 0x448), +	PCMCIA_DEVICE_MANF_CARD(0x2D0, 0x476),  	PCMCIA_DEVICE_NULL,  }; diff --git a/drivers/net/wireless/b43legacy/b43legacy.h b/drivers/net/wireless/b43legacy/b43legacy.h index 77fda148ac4..038baa8869e 100644 --- a/drivers/net/wireless/b43legacy/b43legacy.h +++ b/drivers/net/wireless/b43legacy/b43legacy.h @@ -607,6 +607,7 @@ struct b43legacy_wl {  	u8 nr_devs;  	bool radiotap_enabled; +	bool radio_enabled;  	/* The beacon we are currently using (AP or IBSS mode).  	 * This beacon stuff is protected by the irq_lock. */ diff --git a/drivers/net/wireless/b43legacy/main.c b/drivers/net/wireless/b43legacy/main.c index e5136fb65dd..c4973c1942b 100644 --- a/drivers/net/wireless/b43legacy/main.c +++ b/drivers/net/wireless/b43legacy/main.c @@ -2689,8 +2689,8 @@ static int b43legacy_op_dev_config(struct ieee80211_hw *hw,  	/* Antennas for RX and management frame TX. */  	b43legacy_mgmtframe_txantenna(dev, antenna_tx); -	if (!!conf->radio_enabled != phy->radio_on) { -		if (conf->radio_enabled) { +	if (wl->radio_enabled != phy->radio_on) { +		if (wl->radio_enabled) {  			b43legacy_radio_turn_on(dev);  			b43legacyinfo(dev->wl, "Radio turned on by software\n");  			if (!dev->radio_hw_enable) @@ -3441,6 +3441,7 @@ static int b43legacy_op_start(struct ieee80211_hw *hw)  	wl->beacon0_uploaded = 0;  	wl->beacon1_uploaded = 0;  	wl->beacon_templates_virgin = 1; +	wl->radio_enabled = 1;  	mutex_lock(&wl->mutex); @@ -3479,6 +3480,7 @@ static void b43legacy_op_stop(struct ieee80211_hw *hw)  	if (b43legacy_status(dev) >= B43legacy_STAT_STARTED)  		b43legacy_wireless_core_stop(dev);  	b43legacy_wireless_core_exit(dev); +	wl->radio_enabled = 0;  	mutex_unlock(&wl->mutex);  } @@ -3620,6 +3622,7 @@ static int b43legacy_wireless_core_attach(struct b43legacy_wldev *dev)  		have_bphy = 1;  	dev->phy.gmode = (have_gphy || have_bphy); +	dev->phy.radio_on = 1;  	tmp = dev->phy.gmode ? B43legacy_TMSLOW_GMODE : 0;  	b43legacy_wireless_core_reset(dev, tmp); diff --git a/drivers/net/wireless/ipw2x00/ipw2200.c b/drivers/net/wireless/ipw2x00/ipw2200.c index 44c29b3f672..6dcac73b4d2 100644 --- a/drivers/net/wireless/ipw2x00/ipw2200.c +++ b/drivers/net/wireless/ipw2x00/ipw2200.c @@ -6226,7 +6226,7 @@ static void ipw_add_scan_channels(struct ipw_priv *priv,  			};  			u8 channel; -			while (channel_index < IPW_SCAN_CHANNELS) { +			while (channel_index < IPW_SCAN_CHANNELS - 1) {  				channel =  				    priv->speed_scan[priv->speed_scan_pos];  				if (channel == 0) { diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.h b/drivers/net/wireless/iwlwifi/iwl-3945.h index fbb3a573463..2de6471d4be 100644 --- a/drivers/net/wireless/iwlwifi/iwl-3945.h +++ b/drivers/net/wireless/iwlwifi/iwl-3945.h @@ -112,7 +112,7 @@ enum iwl3945_antenna {  #define IWL_TX_FIFO_NONE	7  /* Minimum number of queues. MAX_NUM is defined in hw specific files */ -#define IWL_MIN_NUM_QUEUES	4 +#define IWL39_MIN_NUM_QUEUES	4  #define IEEE80211_DATA_LEN              2304  #define IEEE80211_4ADDR_LEN             30 diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 6d1519e1f01..355f50ea7fe 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -2675,12 +2675,10 @@ static ssize_t show_power_level(struct device *d,  				struct device_attribute *attr, char *buf)  {  	struct iwl_priv *priv = dev_get_drvdata(d); -	int mode = priv->power_data.user_power_setting;  	int level = priv->power_data.power_mode;  	char *p = buf; -	p += sprintf(p, "INDEX:%d\t", level); -	p += sprintf(p, "USER:%d\n", mode); +	p += sprintf(p, "%d\n", level);  	return p - buf + 1;  } diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index 6ab07165ea2..18b135f510e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c @@ -1332,6 +1332,9 @@ int iwl_setup_mac(struct iwl_priv *priv)  	hw->wiphy->custom_regulatory = true; +	/* Firmware does not support this */ +	hw->wiphy->disable_beacon_hints = true; +  	hw->wiphy->max_scan_ssids = PROBE_OPTION_MAX;  	/* we create the 802.11 header and a zero-length SSID element */  	hw->wiphy->max_scan_ie_len = IWL_MAX_PROBE_REQUEST - 24 - 2; diff --git a/drivers/net/wireless/iwlwifi/iwl-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-debugfs.c index 11e08c06891..ca00cc8ad4c 100644 --- a/drivers/net/wireless/iwlwifi/iwl-debugfs.c +++ b/drivers/net/wireless/iwlwifi/iwl-debugfs.c @@ -308,18 +308,18 @@ static ssize_t iwl_dbgfs_nvm_read(struct file *file,  		return -ENODATA;  	} +	ptr = priv->eeprom; +	if (!ptr) { +		IWL_ERR(priv, "Invalid EEPROM/OTP memory\n"); +		return -ENOMEM; +	} +  	/* 4 characters for byte 0xYY */  	buf = kzalloc(buf_size, GFP_KERNEL);  	if (!buf) {  		IWL_ERR(priv, "Can not allocate Buffer\n");  		return -ENOMEM;  	} - -	ptr = priv->eeprom; -	if (!ptr) { -		IWL_ERR(priv, "Invalid EEPROM/OTP memory\n"); -		return -ENOMEM; -	}  	pos += scnprintf(buf + pos, buf_size - pos, "NVM Type: %s\n",  			(priv->nvm_device_type == NVM_DEVICE_TYPE_OTP)  			? "OTP" : "EEPROM"); diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index e2d620f0b6e..650e20af20f 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h @@ -258,8 +258,10 @@ struct iwl_channel_info {  #define IWL_TX_FIFO_HCCA_2	6  #define IWL_TX_FIFO_NONE	7 -/* Minimum number of queues. MAX_NUM is defined in hw specific files */ -#define IWL_MIN_NUM_QUEUES	4 +/* Minimum number of queues. MAX_NUM is defined in hw specific files. + * Set the minimum to accommodate the 4 standard TX queues, 1 command + * queue, 2 (unused) HCCA queues, and 4 HT queues (one for each AC) */ +#define IWL_MIN_NUM_QUEUES	10  /* Power management (not Tx power) structures */ diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.c b/drivers/net/wireless/iwlwifi/iwl-sta.c index 2addf735b19..ffd5c61a755 100644 --- a/drivers/net/wireless/iwlwifi/iwl-sta.c +++ b/drivers/net/wireless/iwlwifi/iwl-sta.c @@ -566,6 +566,8 @@ int iwl_remove_default_wep_key(struct iwl_priv *priv,  	unsigned long flags;  	spin_lock_irqsave(&priv->sta_lock, flags); +	IWL_DEBUG_WEP(priv, "Removing default WEP key: idx=%d\n", +		      keyconf->keyidx);  	if (!test_and_clear_bit(keyconf->keyidx, &priv->ucode_key_table))  		IWL_ERR(priv, "index %d not used in uCode key table.\n", @@ -573,6 +575,11 @@ int iwl_remove_default_wep_key(struct iwl_priv *priv,  	priv->default_wep_key--;  	memset(&priv->wep_keys[keyconf->keyidx], 0, sizeof(priv->wep_keys[0])); +	if (iwl_is_rfkill(priv)) { +		IWL_DEBUG_WEP(priv, "Not sending REPLY_WEPKEY command due to RFKILL.\n"); +		spin_unlock_irqrestore(&priv->sta_lock, flags); +		return 0; +	}  	ret = iwl_send_static_wepkey_cmd(priv, 1);  	IWL_DEBUG_WEP(priv, "Remove default WEP key: idx=%d ret=%d\n",  		      keyconf->keyidx, ret); @@ -853,6 +860,11 @@ int iwl_remove_dynamic_key(struct iwl_priv *priv,  	priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_KEY_MASK;  	priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; +	if (iwl_is_rfkill(priv)) { +		IWL_DEBUG_WEP(priv, "Not sending REPLY_ADD_STA command because RFKILL enabled. \n"); +		spin_unlock_irqrestore(&priv->sta_lock, flags); +		return 0; +	}  	ret =  iwl_send_add_sta(priv, &priv->stations[sta_id].sta, CMD_ASYNC);  	spin_unlock_irqrestore(&priv->sta_lock, flags);  	return ret; diff --git a/drivers/net/wireless/iwlwifi/iwl-tx.c b/drivers/net/wireless/iwlwifi/iwl-tx.c index 85ae7a62109..2e89040e63b 100644 --- a/drivers/net/wireless/iwlwifi/iwl-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-tx.c @@ -720,8 +720,6 @@ int iwl_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)  		goto drop_unlock;  	} -	spin_unlock_irqrestore(&priv->lock, flags); -  	hdr_len = ieee80211_hdrlen(fc);  	/* Find (or create) index into station table for destination station */ @@ -729,7 +727,7 @@ int iwl_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)  	if (sta_id == IWL_INVALID_STATION) {  		IWL_DEBUG_DROP(priv, "Dropping - INVALID STATION: %pM\n",  			       hdr->addr1); -		goto drop; +		goto drop_unlock;  	}  	IWL_DEBUG_TX(priv, "station Id %d\n", sta_id); @@ -750,14 +748,17 @@ int iwl_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)  			txq_id = priv->stations[sta_id].tid[tid].agg.txq_id;  			swq_id = iwl_virtual_agg_queue_num(swq_id, txq_id);  		} -		priv->stations[sta_id].tid[tid].tfds_in_queue++;  	}  	txq = &priv->txq[txq_id];  	q = &txq->q;  	txq->swq_id = swq_id; -	spin_lock_irqsave(&priv->lock, flags); +	if (unlikely(iwl_queue_space(q) < q->high_mark)) +		goto drop_unlock; + +	if (ieee80211_is_data_qos(fc)) +		priv->stations[sta_id].tid[tid].tfds_in_queue++;  	/* Set up driver data for this TFD */  	memset(&(txq->txb[q->write_ptr]), 0, sizeof(struct iwl_tx_info)); @@ -872,7 +873,8 @@ int iwl_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)  	iwl_print_hex_dump(priv, IWL_DL_TX, (u8 *)tx_cmd->hdr, hdr_len);  	/* Set up entry for this TFD in Tx byte-count array */ -	priv->cfg->ops->lib->txq_update_byte_cnt_tbl(priv, txq, +	if (info->flags & IEEE80211_TX_CTL_AMPDU) +		priv->cfg->ops->lib->txq_update_byte_cnt_tbl(priv, txq,  						     le16_to_cpu(tx_cmd->len));  	pci_dma_sync_single_for_device(priv->pci_dev, txcmd_phys, @@ -901,7 +903,6 @@ int iwl_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)  drop_unlock:  	spin_unlock_irqrestore(&priv->lock, flags); -drop:  	return -1;  }  EXPORT_SYMBOL(iwl_tx_skb); @@ -1170,6 +1171,8 @@ int iwl_tx_agg_start(struct iwl_priv *priv, const u8 *ra, u16 tid, u16 *ssn)  		IWL_ERR(priv, "Start AGG on invalid station\n");  		return -ENXIO;  	} +	if (unlikely(tid >= MAX_TID_COUNT)) +		return -EINVAL;  	if (priv->stations[sta_id].tid[tid].agg.state != IWL_AGG_OFF) {  		IWL_ERR(priv, "Start AGG when state is not IWL_AGG_OFF !\n"); diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c index cb9bd4c8f25..523843369ca 100644 --- a/drivers/net/wireless/iwlwifi/iwl3945-base.c +++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c @@ -3643,12 +3643,10 @@ static ssize_t show_power_level(struct device *d,  				struct device_attribute *attr, char *buf)  {  	struct iwl_priv *priv = dev_get_drvdata(d); -	int mode = priv->power_data.user_power_setting;  	int level = priv->power_data.power_mode;  	char *p = buf; -	p += sprintf(p, "INDEX:%d\t", level); -	p += sprintf(p, "USER:%d\n", mode); +	p += sprintf(p, "%d\n", level);  	return p - buf + 1;  } @@ -3970,6 +3968,9 @@ static int iwl3945_setup_mac(struct iwl_priv *priv)  	hw->wiphy->custom_regulatory = true; +	/* Firmware does not support this */ +	hw->wiphy->disable_beacon_hints = true; +  	hw->wiphy->max_scan_ssids = PROBE_OPTION_MAX_3945;  	/* we create the 802.11 header and a zero-length SSID element */  	hw->wiphy->max_scan_ie_len = IWL_MAX_PROBE_REQUEST - 24 - 2; @@ -4020,10 +4021,10 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e  	SET_IEEE80211_DEV(hw, &pdev->dev);  	if ((iwl3945_mod_params.num_of_queues > IWL39_MAX_NUM_QUEUES) || -	     (iwl3945_mod_params.num_of_queues < IWL_MIN_NUM_QUEUES)) { +	     (iwl3945_mod_params.num_of_queues < IWL39_MIN_NUM_QUEUES)) {  		IWL_ERR(priv,  			"invalid queues_num, should be between %d and %d\n", -			IWL_MIN_NUM_QUEUES, IWL39_MAX_NUM_QUEUES); +			IWL39_MIN_NUM_QUEUES, IWL39_MAX_NUM_QUEUES);  		err = -EINVAL;  		goto out_ieee80211_free_hw;  	} diff --git a/drivers/net/wireless/iwmc3200wifi/Kconfig b/drivers/net/wireless/iwmc3200wifi/Kconfig index 1eccb6df46d..030401d367d 100644 --- a/drivers/net/wireless/iwmc3200wifi/Kconfig +++ b/drivers/net/wireless/iwmc3200wifi/Kconfig @@ -4,6 +4,15 @@ config IWM  	depends on CFG80211  	select WIRELESS_EXT  	select FW_LOADER +	help +	  The Intel Wireless Multicomm 3200 hardware is a combo +	  card with GPS, Bluetooth, WiMax and 802.11 radios. It +	  runs over SDIO and is typically found on Moorestown +	  based platform. This driver takes care of the 802.11 +	  part, which is a fullmac one. + +	  If you choose to build it as a module, it'll be called +	  iwmc3200wifi.ko.  config IWM_DEBUG  	bool "Enable full debugging output in iwmc3200wifi" diff --git a/drivers/net/wireless/iwmc3200wifi/commands.c b/drivers/net/wireless/iwmc3200wifi/commands.c index 834a7f544e5..e2334d12359 100644 --- a/drivers/net/wireless/iwmc3200wifi/commands.c +++ b/drivers/net/wireless/iwmc3200wifi/commands.c @@ -220,6 +220,7 @@ int iwm_store_rxiq_calib_result(struct iwm_priv *iwm)  	eeprom_rxiq = iwm_eeprom_access(iwm, IWM_EEPROM_CALIB_RXIQ);  	if (IS_ERR(eeprom_rxiq)) {  		IWM_ERR(iwm, "Couldn't access EEPROM RX IQ entry\n"); +		kfree(rxiq);  		return PTR_ERR(eeprom_rxiq);  	} diff --git a/drivers/net/wireless/iwmc3200wifi/netdev.c b/drivers/net/wireless/iwmc3200wifi/netdev.c index aaa20c6885c..bf294e41753 100644 --- a/drivers/net/wireless/iwmc3200wifi/netdev.c +++ b/drivers/net/wireless/iwmc3200wifi/netdev.c @@ -106,10 +106,8 @@ void *iwm_if_alloc(int sizeof_bus, struct device *dev,  	int ret = 0;  	wdev = iwm_wdev_alloc(sizeof_bus, dev); -	if (!wdev) { -		dev_err(dev, "no memory for wireless device instance\n"); -		return ERR_PTR(-ENOMEM); -	} +	if (IS_ERR(wdev)) +		return wdev;  	iwm = wdev_to_iwm(wdev);  	iwm->bus_ops = if_ops; @@ -151,8 +149,8 @@ void iwm_if_free(struct iwm_priv *iwm)  		return;  	free_netdev(iwm_to_ndev(iwm)); -	iwm_wdev_free(iwm);  	iwm_priv_deinit(iwm); +	iwm_wdev_free(iwm);  }  int iwm_if_add(struct iwm_priv *iwm) diff --git a/drivers/net/wireless/libertas/11d.c b/drivers/net/wireless/libertas/11d.c index 9a5408e7d94..5c6968101f0 100644 --- a/drivers/net/wireless/libertas/11d.c +++ b/drivers/net/wireless/libertas/11d.c @@ -47,7 +47,7 @@ static u8 lbs_region_2_code(u8 *region)  {  	u8 i; -	for (i = 0; region[i] && i < COUNTRY_CODE_LEN; i++) +	for (i = 0; i < COUNTRY_CODE_LEN && region[i]; i++)  		region[i] = toupper(region[i]);  	for (i = 0; i < ARRAY_SIZE(region_code_mapping); i++) { diff --git a/drivers/net/wireless/libertas/cmd.c b/drivers/net/wireless/libertas/cmd.c index 01db705a38e..685098148e1 100644 --- a/drivers/net/wireless/libertas/cmd.c +++ b/drivers/net/wireless/libertas/cmd.c @@ -135,8 +135,14 @@ int lbs_update_hw_spec(struct lbs_private *priv)  	/* Clamp region code to 8-bit since FW spec indicates that it should  	 * only ever be 8-bit, even though the field size is 16-bit.  Some firmware  	 * returns non-zero high 8 bits here. +	 * +	 * Firmware version 4.0.102 used in CF8381 has region code shifted.  We +	 * need to check for this problem and handle it properly.  	 */ -	priv->regioncode = le16_to_cpu(cmd.regioncode) & 0xFF; +	if (MRVL_FW_MAJOR_REV(priv->fwrelease) == MRVL_FW_V4) +		priv->regioncode = (le16_to_cpu(cmd.regioncode) >> 8) & 0xFF; +	else +		priv->regioncode = le16_to_cpu(cmd.regioncode) & 0xFF;  	for (i = 0; i < MRVDRV_MAX_REGION_CODE; i++) {  		/* use the region code to search for the index */ diff --git a/drivers/net/wireless/libertas/defs.h b/drivers/net/wireless/libertas/defs.h index 48da157d6cd..72f3479a4d7 100644 --- a/drivers/net/wireless/libertas/defs.h +++ b/drivers/net/wireless/libertas/defs.h @@ -234,6 +234,8 @@ static inline void lbs_deb_hex(unsigned int grp, const char *prompt, u8 *buf, in  /** Mesh enable bit in FW capability */  #define MESH_CAPINFO_ENABLE_MASK			(1<<16) +/** FW definition from Marvell v4 */ +#define MRVL_FW_V4					(0x04)  /** FW definition from Marvell v5 */  #define MRVL_FW_V5					(0x05)  /** FW definition from Marvell v10 */ diff --git a/drivers/net/wireless/libertas/hostcmd.h b/drivers/net/wireless/libertas/hostcmd.h index 0a2e29140ad..c8a1998d474 100644 --- a/drivers/net/wireless/libertas/hostcmd.h +++ b/drivers/net/wireless/libertas/hostcmd.h @@ -56,8 +56,8 @@ struct rxpd {  			u8 bss_type;  			/* BSS number */  			u8 bss_num; -		} bss; -	} u; +		} __attribute__ ((packed)) bss; +	} __attribute__ ((packed)) u;  	/* SNR */  	u8 snr; diff --git a/drivers/net/wireless/libertas/scan.c b/drivers/net/wireless/libertas/scan.c index 601b5424967..6c95af3023c 100644 --- a/drivers/net/wireless/libertas/scan.c +++ b/drivers/net/wireless/libertas/scan.c @@ -5,6 +5,7 @@    *  for sending scan commands to the firmware.    */  #include <linux/types.h> +#include <linux/kernel.h>  #include <linux/etherdevice.h>  #include <linux/if_arp.h>  #include <asm/unaligned.h> @@ -876,7 +877,7 @@ static inline char *lbs_translate_scan(struct lbs_private *priv,  	iwe.u.bitrate.disabled = 0;  	iwe.u.bitrate.value = 0; -	for (j = 0; bss->rates[j] && (j < sizeof(bss->rates)); j++) { +	for (j = 0; j < ARRAY_SIZE(bss->rates) && bss->rates[j]; j++) {  		/* Bit rate given in 500 kb/s units */  		iwe.u.bitrate.value = bss->rates[j] * 500000;  		current_val = iwe_stream_add_value(info, start, current_val, diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c index e789c6e9938..7916ca3f84c 100644 --- a/drivers/net/wireless/mac80211_hwsim.c +++ b/drivers/net/wireless/mac80211_hwsim.c @@ -418,6 +418,7 @@ static bool mac80211_hwsim_tx_frame(struct ieee80211_hw *hw,  			continue;  		if (!data2->started || !hwsim_ps_rx_ok(data2, skb) || +		    !data->channel || !data2->channel ||  		    data->channel->center_freq != data2->channel->center_freq ||  		    !(data->group & data2->group))  			continue; @@ -708,7 +709,7 @@ static const struct ieee80211_ops mac80211_hwsim_ops =  static void mac80211_hwsim_free(void)  {  	struct list_head tmplist, *i, *tmp; -	struct mac80211_hwsim_data *data; +	struct mac80211_hwsim_data *data, *tmpdata;  	INIT_LIST_HEAD(&tmplist); @@ -717,7 +718,7 @@ static void mac80211_hwsim_free(void)  		list_move(i, &tmplist);  	spin_unlock_bh(&hwsim_radio_lock); -	list_for_each_entry(data, &tmplist, list) { +	list_for_each_entry_safe(data, tmpdata, &tmplist, list) {  		debugfs_remove(data->debugfs_group);  		debugfs_remove(data->debugfs_ps);  		debugfs_remove(data->debugfs); @@ -1166,8 +1167,8 @@ static void __exit exit_mac80211_hwsim(void)  {  	printk(KERN_DEBUG "mac80211_hwsim: unregister radios\n"); -	unregister_netdev(hwsim_mon);  	mac80211_hwsim_free(); +	unregister_netdev(hwsim_mon);  } diff --git a/drivers/net/wireless/mwl8k.c b/drivers/net/wireless/mwl8k.c index a263d5c84c0..83967afe082 100644 --- a/drivers/net/wireless/mwl8k.c +++ b/drivers/net/wireless/mwl8k.c @@ -261,7 +261,7 @@ struct mwl8k_vif {  	 */  }; -#define MWL8K_VIF(_vif) (struct mwl8k_vif *)(&((_vif)->drv_priv)) +#define MWL8K_VIF(_vif) ((struct mwl8k_vif *)&((_vif)->drv_priv))  static const struct ieee80211_channel mwl8k_channels[] = {  	{ .center_freq = 2412, .hw_value = 1, }, @@ -1012,6 +1012,8 @@ static int rxq_process(struct ieee80211_hw *hw, int index, int limit)  		rmb();  		skb = rxq->rx_skb[rxq->rx_head]; +		if (skb == NULL) +			break;  		rxq->rx_skb[rxq->rx_head] = NULL;  		rxq->rx_head = (rxq->rx_head + 1) % MWL8K_RX_DESCS; @@ -1591,6 +1593,9 @@ static int mwl8k_post_cmd(struct ieee80211_hw *hw, struct mwl8k_cmd_pkt *cmd)  	timeout = wait_for_completion_timeout(&cmd_wait,  				msecs_to_jiffies(MWL8K_CMD_TIMEOUT_MS)); +	pci_unmap_single(priv->pdev, dma_addr, dma_size, +					PCI_DMA_BIDIRECTIONAL); +  	result = &cmd->result;  	if (!timeout) {  		spin_lock_irq(&priv->fw_lock); @@ -1610,8 +1615,6 @@ static int mwl8k_post_cmd(struct ieee80211_hw *hw, struct mwl8k_cmd_pkt *cmd)  			       *result);  	} -	pci_unmap_single(priv->pdev, dma_addr, dma_size, -					PCI_DMA_BIDIRECTIONAL);  	return rc;  } @@ -1654,18 +1657,18 @@ static int mwl8k_cmd_get_hw_spec(struct ieee80211_hw *hw)  	memset(cmd->perm_addr, 0xff, sizeof(cmd->perm_addr));  	cmd->ps_cookie = cpu_to_le32(priv->cookie_dma);  	cmd->rx_queue_ptr = cpu_to_le32(priv->rxq[0].rx_desc_dma); -	cmd->num_tx_queues = MWL8K_TX_QUEUES; +	cmd->num_tx_queues = cpu_to_le32(MWL8K_TX_QUEUES);  	for (i = 0; i < MWL8K_TX_QUEUES; i++)  		cmd->tx_queue_ptrs[i] = cpu_to_le32(priv->txq[i].tx_desc_dma); -	cmd->num_tx_desc_per_queue = MWL8K_TX_DESCS; -	cmd->total_rx_desc = MWL8K_RX_DESCS; +	cmd->num_tx_desc_per_queue = cpu_to_le32(MWL8K_TX_DESCS); +	cmd->total_rx_desc = cpu_to_le32(MWL8K_RX_DESCS);  	rc = mwl8k_post_cmd(hw, &cmd->header);  	if (!rc) {  		SET_IEEE80211_PERM_ADDR(hw, cmd->perm_addr);  		priv->num_mcaddrs = le16_to_cpu(cmd->num_mcaddrs); -		priv->fw_rev = cmd->fw_rev; +		priv->fw_rev = le32_to_cpu(cmd->fw_rev);  		priv->hw_rev = cmd->hw_rev;  		priv->region_code = le16_to_cpu(cmd->region_code);  	} @@ -3216,15 +3219,19 @@ static int mwl8k_configure_filter_wt(struct work_struct *wt)  	struct dev_addr_list *mclist = worker->mclist;  	struct mwl8k_priv *priv = hw->priv; -	struct mwl8k_vif *mv_vif;  	int rc = 0;  	if (changed_flags & FIF_BCN_PRBRESP_PROMISC) {  		if (*total_flags & FIF_BCN_PRBRESP_PROMISC)  			rc = mwl8k_cmd_set_pre_scan(hw);  		else { -			mv_vif = MWL8K_VIF(priv->vif); -			rc = mwl8k_cmd_set_post_scan(hw, mv_vif->bssid); +			u8 *bssid; + +			bssid = "\x00\x00\x00\x00\x00\x00"; +			if (priv->vif != NULL) +				bssid = MWL8K_VIF(priv->vif)->bssid; + +			rc = mwl8k_cmd_set_post_scan(hw, bssid);  		}  	} @@ -3726,6 +3733,8 @@ static void __devexit mwl8k_remove(struct pci_dev *pdev)  	ieee80211_stop_queues(hw); +	ieee80211_unregister_hw(hw); +  	/* Remove tx reclaim tasklet */  	tasklet_kill(&priv->tx_reclaim_task); @@ -3739,8 +3748,6 @@ static void __devexit mwl8k_remove(struct pci_dev *pdev)  	for (i = 0; i < MWL8K_TX_QUEUES; i++)  		mwl8k_txq_reclaim(hw, i, 1); -	ieee80211_unregister_hw(hw); -  	for (i = 0; i < MWL8K_TX_QUEUES; i++)  		mwl8k_txq_deinit(hw, i); diff --git a/drivers/net/wireless/orinoco/main.c b/drivers/net/wireless/orinoco/main.c index 345593c4acc..a370e510f19 100644 --- a/drivers/net/wireless/orinoco/main.c +++ b/drivers/net/wireless/orinoco/main.c @@ -2521,6 +2521,8 @@ static const struct net_device_ops orinoco_netdev_ops = {  	.ndo_start_xmit		= orinoco_xmit,  	.ndo_set_multicast_list	= orinoco_set_multicast_list,  	.ndo_change_mtu		= orinoco_change_mtu, +	.ndo_set_mac_address	= eth_mac_addr, +	.ndo_validate_addr	= eth_validate_addr,  	.ndo_tx_timeout		= orinoco_tx_timeout,  	.ndo_get_stats		= orinoco_get_stats,  }; @@ -2555,7 +2557,6 @@ struct net_device  	priv->wireless_data.spy_data = &priv->spy_data;  	dev->wireless_data = &priv->wireless_data;  #endif -	/* we use the default eth_mac_addr for setting the MAC addr */  	/* Reserve space in skb for the SNAP header */  	dev->hard_header_len += ENCAPS_OVERHEAD; diff --git a/drivers/net/wireless/p54/p54common.c b/drivers/net/wireless/p54/p54common.c index b618bd14583..22ca122bd79 100644 --- a/drivers/net/wireless/p54/p54common.c +++ b/drivers/net/wireless/p54/p54common.c @@ -823,30 +823,30 @@ void p54_free_skb(struct ieee80211_hw *dev, struct sk_buff *skb)  	struct p54_tx_info *range;  	unsigned long flags; -	if (unlikely(!skb || !dev || skb_queue_empty(&priv->tx_queue))) +	if (unlikely(!skb || !dev || !skb_queue_len(&priv->tx_queue)))  		return; -	/* There used to be a check here to see if the SKB was on the -	 * TX queue or not.  This can never happen because all SKBs we -	 * see here successfully went through p54_assign_address() -	 * which means the SKB is on the ->tx_queue. +	/* +	 * don't try to free an already unlinked skb  	 */ +	if (unlikely((!skb->next) || (!skb->prev))) +		return;  	spin_lock_irqsave(&priv->tx_queue.lock, flags);  	info = IEEE80211_SKB_CB(skb);  	range = (void *)info->rate_driver_data; -	if (!skb_queue_is_first(&priv->tx_queue, skb)) { +	if (skb->prev != (struct sk_buff *)&priv->tx_queue) {  		struct ieee80211_tx_info *ni;  		struct p54_tx_info *mr; -		ni = IEEE80211_SKB_CB(skb_queue_prev(&priv->tx_queue, skb)); +		ni = IEEE80211_SKB_CB(skb->prev);  		mr = (struct p54_tx_info *)ni->rate_driver_data;  	} -	if (!skb_queue_is_last(&priv->tx_queue, skb)) { +	if (skb->next != (struct sk_buff *)&priv->tx_queue) {  		struct ieee80211_tx_info *ni;  		struct p54_tx_info *mr; -		ni = IEEE80211_SKB_CB(skb_queue_next(&priv->tx_queue, skb)); +		ni = IEEE80211_SKB_CB(skb->next);  		mr = (struct p54_tx_info *)ni->rate_driver_data;  	}  	__skb_unlink(skb, &priv->tx_queue); @@ -864,13 +864,15 @@ static struct sk_buff *p54_find_tx_entry(struct ieee80211_hw *dev,  	unsigned long flags;  	spin_lock_irqsave(&priv->tx_queue.lock, flags); -	skb_queue_walk(&priv->tx_queue, entry) { +	entry = priv->tx_queue.next; +	while (entry != (struct sk_buff *)&priv->tx_queue) {  		struct p54_hdr *hdr = (struct p54_hdr *) entry->data;  		if (hdr->req_id == req_id) {  			spin_unlock_irqrestore(&priv->tx_queue.lock, flags);  			return entry;  		} +		entry = entry->next;  	}  	spin_unlock_irqrestore(&priv->tx_queue.lock, flags);  	return NULL; @@ -888,33 +890,36 @@ static void p54_rx_frame_sent(struct ieee80211_hw *dev, struct sk_buff *skb)  	int count, idx;  	spin_lock_irqsave(&priv->tx_queue.lock, flags); -	skb_queue_walk(&priv->tx_queue, entry) { +	entry = (struct sk_buff *) priv->tx_queue.next; +	while (entry != (struct sk_buff *)&priv->tx_queue) {  		struct ieee80211_tx_info *info = IEEE80211_SKB_CB(entry);  		struct p54_hdr *entry_hdr;  		struct p54_tx_data *entry_data;  		unsigned int pad = 0, frame_len;  		range = (void *)info->rate_driver_data; -		if (range->start_addr != addr) +		if (range->start_addr != addr) { +			entry = entry->next;  			continue; +		} -		if (!skb_queue_is_last(&priv->tx_queue, entry)) { +		if (entry->next != (struct sk_buff *)&priv->tx_queue) {  			struct ieee80211_tx_info *ni;  			struct p54_tx_info *mr; -			ni = IEEE80211_SKB_CB(skb_queue_next(&priv->tx_queue, -							     entry)); +			ni = IEEE80211_SKB_CB(entry->next);  			mr = (struct p54_tx_info *)ni->rate_driver_data;  		}  		__skb_unlink(entry, &priv->tx_queue); -		spin_unlock_irqrestore(&priv->tx_queue.lock, flags);  		frame_len = entry->len;  		entry_hdr = (struct p54_hdr *) entry->data;  		entry_data = (struct p54_tx_data *) entry_hdr->data; -		priv->tx_stats[entry_data->hw_queue].len--; +		if (priv->tx_stats[entry_data->hw_queue].len) +			priv->tx_stats[entry_data->hw_queue].len--;  		priv->stats.dot11ACKFailureCount += payload->tries - 1; +		spin_unlock_irqrestore(&priv->tx_queue.lock, flags);  		/*  		 * Frames in P54_QUEUE_FWSCAN and P54_QUEUE_BEACON are @@ -1164,21 +1169,23 @@ static int p54_assign_address(struct ieee80211_hw *dev, struct sk_buff *skb,  		}  	} -	skb_queue_walk(&priv->tx_queue, entry) { +	entry = priv->tx_queue.next; +	while (left--) {  		u32 hole_size;  		info = IEEE80211_SKB_CB(entry);  		range = (void *)info->rate_driver_data;  		hole_size = range->start_addr - last_addr;  		if (!target_skb && hole_size >= len) { -			target_skb = skb_queue_prev(&priv->tx_queue, entry); +			target_skb = entry->prev;  			hole_size -= len;  			target_addr = last_addr;  		}  		largest_hole = max(largest_hole, hole_size);  		last_addr = range->end_addr; +		entry = entry->next;  	}  	if (!target_skb && priv->rx_end - last_addr >= len) { -		target_skb = skb_peek_tail(&priv->tx_queue); +		target_skb = priv->tx_queue.prev;  		largest_hole = max(largest_hole, priv->rx_end - last_addr - len);  		if (!skb_queue_empty(&priv->tx_queue)) {  			info = IEEE80211_SKB_CB(target_skb); @@ -2084,6 +2091,7 @@ out:  static void p54_stop(struct ieee80211_hw *dev)  {  	struct p54_common *priv = dev->priv; +	struct sk_buff *skb;  	mutex_lock(&priv->conf_mutex);  	priv->mode = NL80211_IFTYPE_UNSPECIFIED; @@ -2098,7 +2106,8 @@ static void p54_stop(struct ieee80211_hw *dev)  		p54_tx_cancel(dev, priv->cached_beacon);  	priv->stop(dev); -	skb_queue_purge(&priv->tx_queue); +	while ((skb = skb_dequeue(&priv->tx_queue))) +		kfree_skb(skb);  	priv->cached_beacon = NULL;  	priv->tsf_high32 = priv->tsf_low32 = 0;  	mutex_unlock(&priv->conf_mutex); diff --git a/drivers/net/wireless/p54/p54spi.c b/drivers/net/wireless/p54/p54spi.c index 83116baeb11..72c7dbd39d0 100644 --- a/drivers/net/wireless/p54/p54spi.c +++ b/drivers/net/wireless/p54/p54spi.c @@ -635,7 +635,7 @@ static int __devinit p54spi_probe(struct spi_device *spi)  	hw = p54_init_common(sizeof(*priv));  	if (!hw) { -		dev_err(&priv->spi->dev, "could not alloc ieee80211_hw"); +		dev_err(&spi->dev, "could not alloc ieee80211_hw");  		return -ENOMEM;  	} diff --git a/drivers/net/wireless/ray_cs.c b/drivers/net/wireless/ray_cs.c index b10b0383dfa..698b11b1cad 100644 --- a/drivers/net/wireless/ray_cs.c +++ b/drivers/net/wireless/ray_cs.c @@ -2427,11 +2427,10 @@ static void untranslate(ray_dev_t *local, struct sk_buff *skb, int len)  #ifdef PCMCIA_DEBUG  	if (pc_debug > 3) { -		int i; -		printk(KERN_DEBUG "skb->data before untranslate"); -		for (i = 0; i < 64; i++) -			printk("%02x ", skb->data[i]); -		printk("\n" KERN_DEBUG +		print_hex_dump(KERN_DEBUG, "skb->data before untranslate: ", +			       DUMP_PREFIX_NONE, 16, 1, +			       skb->data, 64, true); +		printk(KERN_DEBUG  		       "type = %08x, xsap = %02x%02x%02x, org = %02x02x02x\n",  		       ntohs(type), psnap->dsap, psnap->ssap, psnap->ctrl,  		       psnap->org[0], psnap->org[1], psnap->org[2]); diff --git a/drivers/net/wireless/rt2x00/rt2500usb.c b/drivers/net/wireless/rt2x00/rt2500usb.c index 66daf68ff0e..ce75426764a 100644 --- a/drivers/net/wireless/rt2x00/rt2500usb.c +++ b/drivers/net/wireless/rt2x00/rt2500usb.c @@ -1550,7 +1550,9 @@ static int rt2500usb_init_eeprom(struct rt2x00_dev *rt2x00dev)  	rt2500usb_register_read(rt2x00dev, MAC_CSR0, ®);  	rt2x00_set_chip(rt2x00dev, RT2570, value, reg); -	if (!rt2x00_check_rev(&rt2x00dev->chip, 0x000ffff0, 0)) { +	if (!rt2x00_check_rev(&rt2x00dev->chip, 0x000ffff0, 0) || +	    rt2x00_check_rev(&rt2x00dev->chip, 0x0000000f, 0)) { +  		ERROR(rt2x00dev, "Invalid RT chipset detected.\n");  		return -ENODEV;  	} diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h index a498dde024e..49c9e2c1433 100644 --- a/drivers/net/wireless/rt2x00/rt2x00.h +++ b/drivers/net/wireless/rt2x00/rt2x00.h @@ -849,13 +849,15 @@ struct rt2x00_dev {  static inline void rt2x00_rf_read(struct rt2x00_dev *rt2x00dev,  				  const unsigned int word, u32 *data)  { -	*data = rt2x00dev->rf[word]; +	BUG_ON(word < 1 || word > rt2x00dev->ops->rf_size / sizeof(u32)); +	*data = rt2x00dev->rf[word - 1];  }  static inline void rt2x00_rf_write(struct rt2x00_dev *rt2x00dev,  				   const unsigned int word, u32 data)  { -	rt2x00dev->rf[word] = data; +	BUG_ON(word < 1 || word > rt2x00dev->ops->rf_size / sizeof(u32)); +	rt2x00dev->rf[word - 1] = data;  }  /* diff --git a/drivers/net/wireless/rtl818x/rtl8187_leds.c b/drivers/net/wireless/rtl818x/rtl8187_leds.c index b4425359224..cf9f899fe0e 100644 --- a/drivers/net/wireless/rtl818x/rtl8187_leds.c +++ b/drivers/net/wireless/rtl818x/rtl8187_leds.c @@ -208,11 +208,12 @@ void rtl8187_leds_exit(struct ieee80211_hw *dev)  {  	struct rtl8187_priv *priv = dev->priv; -	rtl8187_unregister_led(&priv->led_tx);  	/* turn the LED off before exiting */  	queue_delayed_work(dev->workqueue, &priv->led_off, 0);  	cancel_delayed_work_sync(&priv->led_off); +	cancel_delayed_work_sync(&priv->led_on);  	rtl8187_unregister_led(&priv->led_rx); +	rtl8187_unregister_led(&priv->led_tx);  }  #endif /* def CONFIG_RTL8187_LED */ diff --git a/drivers/net/wireless/wavelan_cs.c b/drivers/net/wireless/wavelan_cs.c index 6af706408ac..c6d300666ad 100644 --- a/drivers/net/wireless/wavelan_cs.c +++ b/drivers/net/wireless/wavelan_cs.c @@ -3556,17 +3556,8 @@ wv_82593_config(struct net_device *	dev)    cfblk.rcvstop = TRUE; 	/* Enable Receive Stop Register */  #ifdef DEBUG_I82593_SHOW -  { -    u_char *c = (u_char *) &cfblk; -    int i; -    printk(KERN_DEBUG "wavelan_cs: config block:"); -    for(i = 0; i < sizeof(struct i82593_conf_block); i++,c++) -      { -	if((i % 16) == 0) printk("\n" KERN_DEBUG); -	printk("%02x ", *c); -      } -    printk("\n"); -  } +  print_hex_dump(KERN_DEBUG, "wavelan_cs: config block: ", DUMP_PREFIX_NONE, +		 16, 1, &cfblk, sizeof(struct i82593_conf_block), false);  #endif    /* Copy the config block to the i82593 */ diff --git a/drivers/net/wireless/zd1211rw/zd_mac.c b/drivers/net/wireless/zd1211rw/zd_mac.c index 40b07b98822..3bd3c779fff 100644 --- a/drivers/net/wireless/zd1211rw/zd_mac.c +++ b/drivers/net/wireless/zd1211rw/zd_mac.c @@ -698,7 +698,7 @@ int zd_mac_rx(struct ieee80211_hw *hw, const u8 *buffer, unsigned int length)  			&& !mac->pass_ctrl)  		return 0; -	fc = *(__le16 *)buffer; +	fc = get_unaligned((__le16*)buffer);  	need_padding = ieee80211_is_data_qos(fc) ^ ieee80211_has_a4(fc);  	skb = dev_alloc_skb(length + (need_padding ? 2 : 0)); diff --git a/drivers/net/wireless/zd1211rw/zd_usb.c b/drivers/net/wireless/zd1211rw/zd_usb.c index 14a19baff21..0e6e44689cc 100644 --- a/drivers/net/wireless/zd1211rw/zd_usb.c +++ b/drivers/net/wireless/zd1211rw/zd_usb.c @@ -38,7 +38,6 @@ static struct usb_device_id usb_ids[] = {  	/* ZD1211 */  	{ USB_DEVICE(0x0ace, 0x1211), .driver_info = DEVICE_ZD1211 },  	{ USB_DEVICE(0x0ace, 0xa211), .driver_info = DEVICE_ZD1211 }, -	{ USB_DEVICE(0x07b8, 0x6001), .driver_info = DEVICE_ZD1211 },  	{ USB_DEVICE(0x126f, 0xa006), .driver_info = DEVICE_ZD1211 },  	{ USB_DEVICE(0x6891, 0xa727), .driver_info = DEVICE_ZD1211 },  	{ USB_DEVICE(0x0df6, 0x9071), .driver_info = DEVICE_ZD1211 }, @@ -61,6 +60,7 @@ static struct usb_device_id usb_ids[] = {  	{ USB_DEVICE(0x157e, 0x300a), .driver_info = DEVICE_ZD1211 },  	{ USB_DEVICE(0x0105, 0x145f), .driver_info = DEVICE_ZD1211 },  	/* ZD1211B */ +	{ USB_DEVICE(0x054c, 0x0257), .driver_info = DEVICE_ZD1211B },  	{ USB_DEVICE(0x0ace, 0x1215), .driver_info = DEVICE_ZD1211B },  	{ USB_DEVICE(0x0ace, 0xb215), .driver_info = DEVICE_ZD1211B },  	{ USB_DEVICE(0x157e, 0x300d), .driver_info = DEVICE_ZD1211B }, @@ -87,6 +87,7 @@ static struct usb_device_id usb_ids[] = {  	{ USB_DEVICE(0x0471, 0x1237), .driver_info = DEVICE_ZD1211B },  	{ USB_DEVICE(0x07fa, 0x1196), .driver_info = DEVICE_ZD1211B },  	{ USB_DEVICE(0x0df6, 0x0036), .driver_info = DEVICE_ZD1211B }, +	{ USB_DEVICE(0x07b8, 0x6001), .driver_info = DEVICE_ZD1211B },  	/* "Driverless" devices that need ejecting */  	{ USB_DEVICE(0x0ace, 0x2011), .driver_info = DEVICE_INSTALLER },  	{ USB_DEVICE(0x0ace, 0x20ff), .driver_info = DEVICE_INSTALLER },  |