diff options
Diffstat (limited to 'drivers/net/wireless/rt2x00/rt61pci.c')
| -rw-r--r-- | drivers/net/wireless/rt2x00/rt61pci.c | 123 | 
1 files changed, 67 insertions, 56 deletions
diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c index e539c6cb636..af548c87f10 100644 --- a/drivers/net/wireless/rt2x00/rt61pci.c +++ b/drivers/net/wireless/rt2x00/rt61pci.c @@ -594,7 +594,8 @@ static void rt61pci_config_intf(struct rt2x00_dev *rt2x00dev,  }  static void rt61pci_config_erp(struct rt2x00_dev *rt2x00dev, -			       struct rt2x00lib_erp *erp) +			       struct rt2x00lib_erp *erp, +			       u32 changed)  {  	u32 reg; @@ -603,28 +604,36 @@ static void rt61pci_config_erp(struct rt2x00_dev *rt2x00dev,  	rt2x00_set_field32(®, TXRX_CSR0_TSF_OFFSET, IEEE80211_HEADER);  	rt2x00pci_register_write(rt2x00dev, TXRX_CSR0, reg); -	rt2x00pci_register_read(rt2x00dev, TXRX_CSR4, ®); -	rt2x00_set_field32(®, TXRX_CSR4_AUTORESPOND_ENABLE, 1); -	rt2x00_set_field32(®, TXRX_CSR4_AUTORESPOND_PREAMBLE, -			   !!erp->short_preamble); -	rt2x00pci_register_write(rt2x00dev, TXRX_CSR4, reg); +	if (changed & BSS_CHANGED_ERP_PREAMBLE) { +		rt2x00pci_register_read(rt2x00dev, TXRX_CSR4, ®); +		rt2x00_set_field32(®, TXRX_CSR4_AUTORESPOND_ENABLE, 1); +		rt2x00_set_field32(®, TXRX_CSR4_AUTORESPOND_PREAMBLE, +				   !!erp->short_preamble); +		rt2x00pci_register_write(rt2x00dev, TXRX_CSR4, reg); +	} -	rt2x00pci_register_write(rt2x00dev, TXRX_CSR5, erp->basic_rates); +	if (changed & BSS_CHANGED_BASIC_RATES) +		rt2x00pci_register_write(rt2x00dev, TXRX_CSR5, +					 erp->basic_rates); -	rt2x00pci_register_read(rt2x00dev, TXRX_CSR9, ®); -	rt2x00_set_field32(®, TXRX_CSR9_BEACON_INTERVAL, -			   erp->beacon_int * 16); -	rt2x00pci_register_write(rt2x00dev, TXRX_CSR9, reg); +	if (changed & BSS_CHANGED_BEACON_INT) { +		rt2x00pci_register_read(rt2x00dev, TXRX_CSR9, ®); +		rt2x00_set_field32(®, TXRX_CSR9_BEACON_INTERVAL, +				   erp->beacon_int * 16); +		rt2x00pci_register_write(rt2x00dev, TXRX_CSR9, reg); +	} -	rt2x00pci_register_read(rt2x00dev, MAC_CSR9, ®); -	rt2x00_set_field32(®, MAC_CSR9_SLOT_TIME, erp->slot_time); -	rt2x00pci_register_write(rt2x00dev, MAC_CSR9, reg); +	if (changed & BSS_CHANGED_ERP_SLOT) { +		rt2x00pci_register_read(rt2x00dev, MAC_CSR9, ®); +		rt2x00_set_field32(®, MAC_CSR9_SLOT_TIME, erp->slot_time); +		rt2x00pci_register_write(rt2x00dev, MAC_CSR9, reg); -	rt2x00pci_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); -	rt2x00pci_register_write(rt2x00dev, MAC_CSR8, reg); +		rt2x00pci_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); +		rt2x00pci_register_write(rt2x00dev, MAC_CSR8, reg); +	}  }  static void rt61pci_config_antenna_5x(struct rt2x00_dev *rt2x00dev, @@ -1050,7 +1059,7 @@ static void rt61pci_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;  		if (test_bit(CONFIG_EXTERNAL_LNA_A, &rt2x00dev->flags)) { @@ -1645,6 +1654,7 @@ static void rt61pci_toggle_irq(struct rt2x00_dev *rt2x00dev,  	rt2x00pci_register_read(rt2x00dev, INT_MASK_CSR, ®);  	rt2x00_set_field32(®, INT_MASK_CSR_TXDONE, mask);  	rt2x00_set_field32(®, INT_MASK_CSR_RXDONE, mask); +	rt2x00_set_field32(®, INT_MASK_CSR_BEACON_DONE, mask);  	rt2x00_set_field32(®, INT_MASK_CSR_ENABLE_MITIGATION, mask);  	rt2x00_set_field32(®, INT_MASK_CSR_MITIGATION_PERIOD, 0xff);  	rt2x00pci_register_write(rt2x00dev, INT_MASK_CSR, reg); @@ -1658,6 +1668,7 @@ static void rt61pci_toggle_irq(struct rt2x00_dev *rt2x00dev,  	rt2x00_set_field32(®, MCU_INT_MASK_CSR_5, mask);  	rt2x00_set_field32(®, MCU_INT_MASK_CSR_6, mask);  	rt2x00_set_field32(®, MCU_INT_MASK_CSR_7, mask); +	rt2x00_set_field32(®, MCU_INT_MASK_CSR_TWAKEUP, mask);  	rt2x00pci_register_write(rt2x00dev, MCU_INT_MASK_CSR, reg);  } @@ -1766,12 +1777,11 @@ static int rt61pci_set_device_state(struct rt2x00_dev *rt2x00dev,  /*   * TX descriptor initialization   */ -static void rt61pci_write_tx_desc(struct rt2x00_dev *rt2x00dev, -				  struct sk_buff *skb, +static void rt61pci_write_tx_desc(struct queue_entry *entry,  				  struct txentry_desc *txdesc)  { -	struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb); -	struct queue_entry_priv_pci *entry_priv = skbdesc->entry->priv_data; +	struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb); +	struct queue_entry_priv_pci *entry_priv = entry->priv_data;  	__le32 *txd = entry_priv->desc;  	u32 word; @@ -1779,7 +1789,7 @@ static void rt61pci_write_tx_desc(struct rt2x00_dev *rt2x00dev,  	 * Start writing the descriptor words.  	 */  	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); @@ -1802,15 +1812,15 @@ static void rt61pci_write_tx_desc(struct rt2x00_dev *rt2x00dev,  	}  	rt2x00_desc_read(txd, 5, &word); -	rt2x00_set_field32(&word, TXD_W5_PID_TYPE, skbdesc->entry->queue->qid); +	rt2x00_set_field32(&word, TXD_W5_PID_TYPE, entry->queue->qid);  	rt2x00_set_field32(&word, TXD_W5_PID_SUBTYPE,  			   skbdesc->entry->entry_idx);  	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); -	if (txdesc->queue != QID_BEACON) { +	if (txdesc->qid != QID_BEACON) {  		rt2x00_desc_read(txd, 6, &word);  		rt2x00_set_field32(&word, TXD_W6_BUFFER_PHYSICAL_ADDRESS,  				   skbdesc->skb_dma); @@ -1857,7 +1867,7 @@ static void rt61pci_write_tx_desc(struct rt2x00_dev *rt2x00dev,  	 */  	skbdesc->desc = txd;  	skbdesc->desc_len = -		(txdesc->queue == QID_BEACON) ?  TXINFO_SIZE : TXD_DESC_SIZE; +		(txdesc->qid == QID_BEACON) ?  TXINFO_SIZE : TXD_DESC_SIZE;  }  /* @@ -1882,7 +1892,7 @@ static void rt61pci_write_beacon(struct queue_entry *entry,  	/*  	 * Write the TX descriptor for the beacon.  	 */ -	rt61pci_write_tx_desc(rt2x00dev, entry->skb, txdesc); +	rt61pci_write_tx_desc(entry, txdesc);  	/*  	 * Dump beacon to userspace through debugfs. @@ -1918,34 +1928,34 @@ static void rt61pci_write_beacon(struct queue_entry *entry,  	entry->skb = NULL;  } -static void rt61pci_kick_tx_queue(struct rt2x00_dev *rt2x00dev, -				  const enum data_queue_qid queue) +static void rt61pci_kick_tx_queue(struct data_queue *queue)  { +	struct rt2x00_dev *rt2x00dev = queue->rt2x00dev;  	u32 reg;  	rt2x00pci_register_read(rt2x00dev, TX_CNTL_CSR, ®); -	rt2x00_set_field32(®, TX_CNTL_CSR_KICK_TX_AC0, (queue == QID_AC_BE)); -	rt2x00_set_field32(®, TX_CNTL_CSR_KICK_TX_AC1, (queue == QID_AC_BK)); -	rt2x00_set_field32(®, TX_CNTL_CSR_KICK_TX_AC2, (queue == QID_AC_VI)); -	rt2x00_set_field32(®, TX_CNTL_CSR_KICK_TX_AC3, (queue == QID_AC_VO)); +	rt2x00_set_field32(®, TX_CNTL_CSR_KICK_TX_AC0, (queue->qid == QID_AC_BE)); +	rt2x00_set_field32(®, TX_CNTL_CSR_KICK_TX_AC1, (queue->qid == QID_AC_BK)); +	rt2x00_set_field32(®, TX_CNTL_CSR_KICK_TX_AC2, (queue->qid == QID_AC_VI)); +	rt2x00_set_field32(®, TX_CNTL_CSR_KICK_TX_AC3, (queue->qid == QID_AC_VO));  	rt2x00pci_register_write(rt2x00dev, TX_CNTL_CSR, reg);  } -static void rt61pci_kill_tx_queue(struct rt2x00_dev *rt2x00dev, -				  const enum data_queue_qid qid) +static void rt61pci_kill_tx_queue(struct data_queue *queue)  { +	struct rt2x00_dev *rt2x00dev = queue->rt2x00dev;  	u32 reg; -	if (qid == QID_BEACON) { +	if (queue->qid == QID_BEACON) {  		rt2x00pci_register_write(rt2x00dev, TXRX_CSR9, 0);  		return;  	}  	rt2x00pci_register_read(rt2x00dev, TX_CNTL_CSR, ®); -	rt2x00_set_field32(®, TX_CNTL_CSR_ABORT_TX_AC0, (qid == QID_AC_BE)); -	rt2x00_set_field32(®, TX_CNTL_CSR_ABORT_TX_AC1, (qid == QID_AC_BK)); -	rt2x00_set_field32(®, TX_CNTL_CSR_ABORT_TX_AC2, (qid == QID_AC_VI)); -	rt2x00_set_field32(®, TX_CNTL_CSR_ABORT_TX_AC3, (qid == QID_AC_VO)); +	rt2x00_set_field32(®, TX_CNTL_CSR_ABORT_TX_AC0, (queue->qid == QID_AC_BE)); +	rt2x00_set_field32(®, TX_CNTL_CSR_ABORT_TX_AC1, (queue->qid == QID_AC_BK)); +	rt2x00_set_field32(®, TX_CNTL_CSR_ABORT_TX_AC2, (queue->qid == QID_AC_VI)); +	rt2x00_set_field32(®, TX_CNTL_CSR_ABORT_TX_AC3, (queue->qid == QID_AC_VO));  	rt2x00pci_register_write(rt2x00dev, TX_CNTL_CSR, reg);  } @@ -1972,7 +1982,7 @@ static int rt61pci_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 (lna == 3 || lna == 2)  			offset += 10;  	} @@ -2107,11 +2117,7 @@ static void rt61pci_txdone(struct rt2x00_dev *rt2x00dev)  				"TX status report missed for entry %d\n",  				entry_done->entry_idx); -			txdesc.flags = 0; -			__set_bit(TXDONE_UNKNOWN, &txdesc.flags); -			txdesc.retry = 0; - -			rt2x00lib_txdone(entry_done, &txdesc); +			rt2x00lib_txdone_noinfo(entry_done, TXDONE_UNKNOWN);  			entry_done = rt2x00queue_get_entry(queue, Q_INDEX_DONE);  		} @@ -2624,12 +2630,13 @@ static int rt61pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev)  	 * As rt61 has a global fallback table we cannot specify  	 * more then one tx rate per frame but since the hw will  	 * try several rates (based on the fallback table) we should -	 * still initialize max_rates to the maximum number of rates +	 * initialize max_report_rates to the maximum number of rates  	 * we are going to try. Otherwise mac80211 will truncate our  	 * reported tx rates and the rc algortihm will end up with  	 * incorrect data.  	 */ -	rt2x00dev->hw->max_rates = 7; +	rt2x00dev->hw->max_rates = 1; +	rt2x00dev->hw->max_report_rates = 7;  	rt2x00dev->hw->max_rate_tries = 1;  	/* @@ -2654,20 +2661,24 @@ static int rt61pci_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;  |