diff options
Diffstat (limited to 'drivers/net/wireless/rt2x00/rt2500usb.c')
| -rw-r--r-- | drivers/net/wireless/rt2x00/rt2500usb.c | 78 | 
1 files changed, 53 insertions, 25 deletions
diff --git a/drivers/net/wireless/rt2x00/rt2500usb.c b/drivers/net/wireless/rt2x00/rt2500usb.c index cdaf93f4826..93e44c7f3a7 100644 --- a/drivers/net/wireless/rt2x00/rt2500usb.c +++ b/drivers/net/wireless/rt2x00/rt2500usb.c @@ -355,7 +355,9 @@ static int rt2500usb_config_key(struct rt2x00_dev *rt2x00dev,  		 * it is known that not work at least on some hardware.  		 * SW crypto will be used in that case.  		 */ -		if (key->alg == ALG_WEP && key->keyidx != 0) +		if ((key->cipher == WLAN_CIPHER_SUITE_WEP40 || +		     key->cipher == WLAN_CIPHER_SUITE_WEP104) && +		    key->keyidx != 0)  			return -EOPNOTSUPP;  		/* @@ -492,24 +494,34 @@ static void rt2500usb_config_intf(struct rt2x00_dev *rt2x00dev,  }  static void rt2500usb_config_erp(struct rt2x00_dev *rt2x00dev, -				 struct rt2x00lib_erp *erp) +				 struct rt2x00lib_erp *erp, +				 u32 changed)  {  	u16 reg; -	rt2500usb_register_read(rt2x00dev, TXRX_CSR10, ®); -	rt2x00_set_field16(®, TXRX_CSR10_AUTORESPOND_PREAMBLE, -			   !!erp->short_preamble); -	rt2500usb_register_write(rt2x00dev, TXRX_CSR10, reg); +	if (changed & BSS_CHANGED_ERP_PREAMBLE) { +		rt2500usb_register_read(rt2x00dev, TXRX_CSR10, ®); +		rt2x00_set_field16(®, TXRX_CSR10_AUTORESPOND_PREAMBLE, +				   !!erp->short_preamble); +		rt2500usb_register_write(rt2x00dev, TXRX_CSR10, reg); +	} -	rt2500usb_register_write(rt2x00dev, TXRX_CSR11, erp->basic_rates); +	if (changed & BSS_CHANGED_BASIC_RATES) +		rt2500usb_register_write(rt2x00dev, TXRX_CSR11, +					 erp->basic_rates); -	rt2500usb_register_read(rt2x00dev, TXRX_CSR18, ®); -	rt2x00_set_field16(®, TXRX_CSR18_INTERVAL, erp->beacon_int * 4); -	rt2500usb_register_write(rt2x00dev, TXRX_CSR18, reg); +	if (changed & BSS_CHANGED_BEACON_INT) { +		rt2500usb_register_read(rt2x00dev, TXRX_CSR18, ®); +		rt2x00_set_field16(®, TXRX_CSR18_INTERVAL, +				   erp->beacon_int * 4); +		rt2500usb_register_write(rt2x00dev, TXRX_CSR18, reg); +	} -	rt2500usb_register_write(rt2x00dev, MAC_CSR10, erp->slot_time); -	rt2500usb_register_write(rt2x00dev, MAC_CSR11, erp->sifs); -	rt2500usb_register_write(rt2x00dev, MAC_CSR12, erp->eifs); +	if (changed & BSS_CHANGED_ERP_SLOT) { +		rt2500usb_register_write(rt2x00dev, MAC_CSR10, erp->slot_time); +		rt2500usb_register_write(rt2x00dev, MAC_CSR11, erp->sifs); +		rt2500usb_register_write(rt2x00dev, MAC_CSR12, erp->eifs); +	}  }  static void rt2500usb_config_ant(struct rt2x00_dev *rt2x00dev, @@ -1039,12 +1051,11 @@ static int rt2500usb_set_device_state(struct rt2x00_dev *rt2x00dev,  /*   * TX descriptor initialization   */ -static void rt2500usb_write_tx_desc(struct rt2x00_dev *rt2x00dev, -				    struct sk_buff *skb, +static void rt2500usb_write_tx_desc(struct queue_entry *entry,  				    struct txentry_desc *txdesc)  { -	struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb); -	__le32 *txd = (__le32 *) skb->data; +	struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb); +	__le32 *txd = (__le32 *) entry->skb->data;  	u32 word;  	/* @@ -1127,7 +1138,7 @@ static void rt2500usb_write_beacon(struct queue_entry *entry,  	/*  	 * Write the TX descriptor for the beacon.  	 */ -	rt2500usb_write_tx_desc(rt2x00dev, entry->skb, txdesc); +	rt2500usb_write_tx_desc(entry, txdesc);  	/*  	 * Dump beacon to userspace through debugfs. @@ -1195,6 +1206,14 @@ static int rt2500usb_get_tx_data_len(struct queue_entry *entry)  	return length;  } +static void rt2500usb_kill_tx_queue(struct data_queue *queue) +{ +	if (queue->qid == QID_BEACON) +		rt2500usb_register_write(queue->rt2x00dev, TXRX_CSR19, 0); + +	rt2x00usb_kill_tx_queue(queue); +} +  /*   * RX control handlers   */ @@ -1655,10 +1674,15 @@ static int rt2500usb_probe_hw_mode(struct rt2x00_dev *rt2x00dev)  	/*  	 * Initialize all hw fields. +	 * +	 * Don't set IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING unless we are +	 * capable of sending the buffered frames out after the DTIM +	 * transmission using rt2x00lib_beacondone. This will send out +	 * multicast and broadcast traffic immediately instead of buffering it +	 * infinitly and thus dropping it after some time.  	 */  	rt2x00dev->hw->flags =  	    IEEE80211_HW_RX_INCLUDES_FCS | -	    IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING |  	    IEEE80211_HW_SIGNAL_DBM |  	    IEEE80211_HW_SUPPORTS_PS |  	    IEEE80211_HW_PS_NULLFUNC_STACK; @@ -1698,19 +1722,23 @@ static int rt2500usb_probe_hw_mode(struct rt2x00_dev *rt2x00dev)  	/*  	 * Create channel information array  	 */ -	info = kzalloc(spec->num_channels * sizeof(*info), GFP_KERNEL); +	info = kcalloc(spec->num_channels, sizeof(*info), GFP_KERNEL);  	if (!info)  		return -ENOMEM;  	spec->channels_info = info;  	tx_power = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_START); -	for (i = 0; i < 14; i++) -		info[i].tx_power1 = TXPOWER_FROM_DEV(tx_power[i]); +	for (i = 0; i < 14; i++) { +		info[i].max_power = MAX_TXPOWER; +		info[i].default_power1 = TXPOWER_FROM_DEV(tx_power[i]); +	}  	if (spec->num_channels > 14) { -		for (i = 14; i < spec->num_channels; i++) -			info[i].tx_power1 = DEFAULT_TXPOWER; +		for (i = 14; i < spec->num_channels; i++) { +			info[i].max_power = MAX_TXPOWER; +			info[i].default_power1 = DEFAULT_TXPOWER; +		}  	}  	return 0; @@ -1789,7 +1817,7 @@ static const struct rt2x00lib_ops rt2500usb_rt2x00_ops = {  	.write_beacon		= rt2500usb_write_beacon,  	.get_tx_data_len	= rt2500usb_get_tx_data_len,  	.kick_tx_queue		= rt2x00usb_kick_tx_queue, -	.kill_tx_queue		= rt2x00usb_kill_tx_queue, +	.kill_tx_queue		= rt2500usb_kill_tx_queue,  	.fill_rxdone		= rt2500usb_fill_rxdone,  	.config_shared_key	= rt2500usb_config_key,  	.config_pairwise_key	= rt2500usb_config_key,  |