diff options
Diffstat (limited to 'drivers/net/wireless/rt2x00/rt73usb.c')
| -rw-r--r-- | drivers/net/wireless/rt2x00/rt73usb.c | 96 | 
1 files changed, 61 insertions, 35 deletions
diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c index aa9de18fd41..9be8089317e 100644 --- a/drivers/net/wireless/rt2x00/rt73usb.c +++ b/drivers/net/wireless/rt2x00/rt73usb.c @@ -545,7 +545,8 @@ static void rt73usb_config_intf(struct rt2x00_dev *rt2x00dev,  }  static void rt73usb_config_erp(struct rt2x00_dev *rt2x00dev, -			       struct rt2x00lib_erp *erp) +			       struct rt2x00lib_erp *erp, +			       u32 changed)  {  	u32 reg; @@ -554,28 +555,36 @@ static void rt73usb_config_erp(struct rt2x00_dev *rt2x00dev,  	rt2x00_set_field32(®, TXRX_CSR0_TSF_OFFSET, IEEE80211_HEADER);  	rt2x00usb_register_write(rt2x00dev, TXRX_CSR0, reg); -	rt2x00usb_register_read(rt2x00dev, TXRX_CSR4, ®); -	rt2x00_set_field32(®, TXRX_CSR4_AUTORESPOND_ENABLE, 1); -	rt2x00_set_field32(®, TXRX_CSR4_AUTORESPOND_PREAMBLE, -			   !!erp->short_preamble); -	rt2x00usb_register_write(rt2x00dev, TXRX_CSR4, reg); +	if (changed & BSS_CHANGED_ERP_PREAMBLE) { +		rt2x00usb_register_read(rt2x00dev, TXRX_CSR4, ®); +		rt2x00_set_field32(®, TXRX_CSR4_AUTORESPOND_ENABLE, 1); +		rt2x00_set_field32(®, TXRX_CSR4_AUTORESPOND_PREAMBLE, +				   !!erp->short_preamble); +		rt2x00usb_register_write(rt2x00dev, TXRX_CSR4, reg); +	} -	rt2x00usb_register_write(rt2x00dev, TXRX_CSR5, erp->basic_rates); +	if (changed & BSS_CHANGED_BASIC_RATES) +		rt2x00usb_register_write(rt2x00dev, TXRX_CSR5, +					 erp->basic_rates); -	rt2x00usb_register_read(rt2x00dev, TXRX_CSR9, ®); -	rt2x00_set_field32(®, TXRX_CSR9_BEACON_INTERVAL, -			   erp->beacon_int * 16); -	rt2x00usb_register_write(rt2x00dev, TXRX_CSR9, reg); +	if (changed & BSS_CHANGED_BEACON_INT) { +		rt2x00usb_register_read(rt2x00dev, TXRX_CSR9, ®); +		rt2x00_set_field32(®, TXRX_CSR9_BEACON_INTERVAL, +				   erp->beacon_int * 16); +		rt2x00usb_register_write(rt2x00dev, TXRX_CSR9, reg); +	} -	rt2x00usb_register_read(rt2x00dev, MAC_CSR9, ®); -	rt2x00_set_field32(®, MAC_CSR9_SLOT_TIME, erp->slot_time); -	rt2x00usb_register_write(rt2x00dev, MAC_CSR9, reg); +	if (changed & BSS_CHANGED_ERP_SLOT) { +		rt2x00usb_register_read(rt2x00dev, MAC_CSR9, ®); +		rt2x00_set_field32(®, MAC_CSR9_SLOT_TIME, erp->slot_time); +		rt2x00usb_register_write(rt2x00dev, MAC_CSR9, reg); -	rt2x00usb_register_read(rt2x00dev, MAC_CSR8, ®); -	rt2x00_set_field32(®, MAC_CSR8_SIFS, erp->sifs); -	rt2x00_set_field32(®, MAC_CSR8_SIFS_AFTER_RX_OFDM, 3); -	rt2x00_set_field32(®, MAC_CSR8_EIFS, erp->eifs); -	rt2x00usb_register_write(rt2x00dev, MAC_CSR8, reg); +		rt2x00usb_register_read(rt2x00dev, MAC_CSR8, ®); +		rt2x00_set_field32(®, MAC_CSR8_SIFS, erp->sifs); +		rt2x00_set_field32(®, MAC_CSR8_SIFS_AFTER_RX_OFDM, 3); +		rt2x00_set_field32(®, MAC_CSR8_EIFS, erp->eifs); +		rt2x00usb_register_write(rt2x00dev, MAC_CSR8, reg); +	}  }  static void rt73usb_config_antenna_5x(struct rt2x00_dev *rt2x00dev, @@ -929,7 +938,7 @@ static void rt73usb_link_tuner(struct rt2x00_dev *rt2x00dev,  	/*  	 * Determine r17 bounds.  	 */ -	if (rt2x00dev->rx_status.band == IEEE80211_BAND_5GHZ) { +	if (rt2x00dev->curr_band == IEEE80211_BAND_5GHZ) {  		low_bound = 0x28;  		up_bound = 0x48; @@ -1426,12 +1435,11 @@ static int rt73usb_set_device_state(struct rt2x00_dev *rt2x00dev,  /*   * TX descriptor initialization   */ -static void rt73usb_write_tx_desc(struct rt2x00_dev *rt2x00dev, -				  struct sk_buff *skb, +static void rt73usb_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;  	/* @@ -1464,7 +1472,7 @@ static void rt73usb_write_tx_desc(struct rt2x00_dev *rt2x00dev,  	rt2x00_desc_write(txd, 0, word);  	rt2x00_desc_read(txd, 1, &word); -	rt2x00_set_field32(&word, TXD_W1_HOST_Q_ID, txdesc->queue); +	rt2x00_set_field32(&word, TXD_W1_HOST_Q_ID, txdesc->qid);  	rt2x00_set_field32(&word, TXD_W1_AIFSN, txdesc->aifs);  	rt2x00_set_field32(&word, TXD_W1_CWMIN, txdesc->cw_min);  	rt2x00_set_field32(&word, TXD_W1_CWMAX, txdesc->cw_max); @@ -1487,7 +1495,7 @@ static void rt73usb_write_tx_desc(struct rt2x00_dev *rt2x00dev,  	rt2x00_desc_read(txd, 5, &word);  	rt2x00_set_field32(&word, TXD_W5_TX_POWER, -			   TXPOWER_TO_DEV(rt2x00dev->tx_power)); +			   TXPOWER_TO_DEV(entry->queue->rt2x00dev->tx_power));  	rt2x00_set_field32(&word, TXD_W5_WAITING_DMA_DONE_INT, 1);  	rt2x00_desc_write(txd, 5, word); @@ -1526,7 +1534,7 @@ static void rt73usb_write_beacon(struct queue_entry *entry,  	/*  	 * Write the TX descriptor for the beacon.  	 */ -	rt73usb_write_tx_desc(rt2x00dev, entry->skb, txdesc); +	rt73usb_write_tx_desc(entry, txdesc);  	/*  	 * Dump beacon to userspace through debugfs. @@ -1574,6 +1582,14 @@ static int rt73usb_get_tx_data_len(struct queue_entry *entry)  	return length;  } +static void rt73usb_kill_tx_queue(struct data_queue *queue) +{ +	if (queue->qid == QID_BEACON) +		rt2x00usb_register_write(queue->rt2x00dev, TXRX_CSR9, 0); + +	rt2x00usb_kill_tx_queue(queue); +} +  /*   * RX control handlers   */ @@ -1597,7 +1613,7 @@ static int rt73usb_agc_to_rssi(struct rt2x00_dev *rt2x00dev, int rxd_w1)  		return 0;  	} -	if (rt2x00dev->rx_status.band == IEEE80211_BAND_5GHZ) { +	if (rt2x00dev->curr_band == IEEE80211_BAND_5GHZ) {  		if (test_bit(CONFIG_EXTERNAL_LNA_A, &rt2x00dev->flags)) {  			if (lna == 3 || lna == 2)  				offset += 10; @@ -2047,9 +2063,14 @@ static int rt73usb_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_HOST_BROADCAST_PS_BUFFERING |  	    IEEE80211_HW_SIGNAL_DBM |  	    IEEE80211_HW_SUPPORTS_PS |  	    IEEE80211_HW_PS_NULLFUNC_STACK; @@ -2084,20 +2105,24 @@ static int rt73usb_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_G_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) {  		tx_power = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_A_START); -		for (i = 14; i < spec->num_channels; i++) -			info[i].tx_power1 = TXPOWER_FROM_DEV(tx_power[i]); +		for (i = 14; i < spec->num_channels; i++) { +			info[i].max_power = MAX_TXPOWER; +			info[i].default_power1 = TXPOWER_FROM_DEV(tx_power[i]); +		}  	}  	return 0; @@ -2259,7 +2284,7 @@ static const struct rt2x00lib_ops rt73usb_rt2x00_ops = {  	.write_beacon		= rt73usb_write_beacon,  	.get_tx_data_len	= rt73usb_get_tx_data_len,  	.kick_tx_queue		= rt2x00usb_kick_tx_queue, -	.kill_tx_queue		= rt2x00usb_kill_tx_queue, +	.kill_tx_queue		= rt73usb_kill_tx_queue,  	.fill_rxdone		= rt73usb_fill_rxdone,  	.config_shared_key	= rt73usb_config_shared_key,  	.config_pairwise_key	= rt73usb_config_pairwise_key, @@ -2345,6 +2370,7 @@ static struct usb_device_id rt73usb_device_table[] = {  	{ USB_DEVICE(0x0411, 0x00f4), USB_DEVICE_DATA(&rt73usb_ops) },  	{ USB_DEVICE(0x0411, 0x0116), USB_DEVICE_DATA(&rt73usb_ops) },  	{ USB_DEVICE(0x0411, 0x0119), USB_DEVICE_DATA(&rt73usb_ops) }, +	{ USB_DEVICE(0x0411, 0x0137), USB_DEVICE_DATA(&rt73usb_ops) },  	/* CEIVA */  	{ USB_DEVICE(0x178d, 0x02be), USB_DEVICE_DATA(&rt73usb_ops) },  	/* CNet */  |