xref: /openbmc/linux/drivers/net/wireless/ralink/rt2x00/rt2500pci.c (revision 38651683aa98399f2e08e7978b8df0a707051887)
133aca94dSKalle Valo /*
233aca94dSKalle Valo 	Copyright (C) 2004 - 2009 Ivo van Doorn <IvDoorn@gmail.com>
333aca94dSKalle Valo 	<http://rt2x00.serialmonkey.com>
433aca94dSKalle Valo 
533aca94dSKalle Valo 	This program is free software; you can redistribute it and/or modify
633aca94dSKalle Valo 	it under the terms of the GNU General Public License as published by
733aca94dSKalle Valo 	the Free Software Foundation; either version 2 of the License, or
833aca94dSKalle Valo 	(at your option) any later version.
933aca94dSKalle Valo 
1033aca94dSKalle Valo 	This program is distributed in the hope that it will be useful,
1133aca94dSKalle Valo 	but WITHOUT ANY WARRANTY; without even the implied warranty of
1233aca94dSKalle Valo 	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1333aca94dSKalle Valo 	GNU General Public License for more details.
1433aca94dSKalle Valo 
1533aca94dSKalle Valo 	You should have received a copy of the GNU General Public License
1633aca94dSKalle Valo 	along with this program; if not, see <http://www.gnu.org/licenses/>.
1733aca94dSKalle Valo  */
1833aca94dSKalle Valo 
1933aca94dSKalle Valo /*
2033aca94dSKalle Valo 	Module: rt2500pci
2133aca94dSKalle Valo 	Abstract: rt2500pci device specific routines.
2233aca94dSKalle Valo 	Supported chipsets: RT2560.
2333aca94dSKalle Valo  */
2433aca94dSKalle Valo 
2533aca94dSKalle Valo #include <linux/delay.h>
2633aca94dSKalle Valo #include <linux/etherdevice.h>
2733aca94dSKalle Valo #include <linux/kernel.h>
2833aca94dSKalle Valo #include <linux/module.h>
2933aca94dSKalle Valo #include <linux/pci.h>
3033aca94dSKalle Valo #include <linux/eeprom_93cx6.h>
3133aca94dSKalle Valo #include <linux/slab.h>
3233aca94dSKalle Valo 
3333aca94dSKalle Valo #include "rt2x00.h"
3433aca94dSKalle Valo #include "rt2x00mmio.h"
3533aca94dSKalle Valo #include "rt2x00pci.h"
3633aca94dSKalle Valo #include "rt2500pci.h"
3733aca94dSKalle Valo 
3833aca94dSKalle Valo /*
3933aca94dSKalle Valo  * Register access.
4033aca94dSKalle Valo  * All access to the CSR registers will go through the methods
4133aca94dSKalle Valo  * rt2x00mmio_register_read and rt2x00mmio_register_write.
4233aca94dSKalle Valo  * BBP and RF register require indirect register access,
4333aca94dSKalle Valo  * and use the CSR registers BBPCSR and RFCSR to achieve this.
4433aca94dSKalle Valo  * These indirect registers work with busy bits,
4533aca94dSKalle Valo  * and we will try maximal REGISTER_BUSY_COUNT times to access
4633aca94dSKalle Valo  * the register while taking a REGISTER_BUSY_DELAY us delay
4733aca94dSKalle Valo  * between each attampt. When the busy bit is still set at that time,
4833aca94dSKalle Valo  * the access attempt is considered to have failed,
4933aca94dSKalle Valo  * and we will print an error.
5033aca94dSKalle Valo  */
5133aca94dSKalle Valo #define WAIT_FOR_BBP(__dev, __reg) \
5233aca94dSKalle Valo 	rt2x00mmio_regbusy_read((__dev), BBPCSR, BBPCSR_BUSY, (__reg))
5333aca94dSKalle Valo #define WAIT_FOR_RF(__dev, __reg) \
5433aca94dSKalle Valo 	rt2x00mmio_regbusy_read((__dev), RFCSR, RFCSR_BUSY, (__reg))
5533aca94dSKalle Valo 
5633aca94dSKalle Valo static void rt2500pci_bbp_write(struct rt2x00_dev *rt2x00dev,
5733aca94dSKalle Valo 				const unsigned int word, const u8 value)
5833aca94dSKalle Valo {
5933aca94dSKalle Valo 	u32 reg;
6033aca94dSKalle Valo 
6133aca94dSKalle Valo 	mutex_lock(&rt2x00dev->csr_mutex);
6233aca94dSKalle Valo 
6333aca94dSKalle Valo 	/*
6433aca94dSKalle Valo 	 * Wait until the BBP becomes available, afterwards we
6533aca94dSKalle Valo 	 * can safely write the new data into the register.
6633aca94dSKalle Valo 	 */
6733aca94dSKalle Valo 	if (WAIT_FOR_BBP(rt2x00dev, &reg)) {
6833aca94dSKalle Valo 		reg = 0;
6933aca94dSKalle Valo 		rt2x00_set_field32(&reg, BBPCSR_VALUE, value);
7033aca94dSKalle Valo 		rt2x00_set_field32(&reg, BBPCSR_REGNUM, word);
7133aca94dSKalle Valo 		rt2x00_set_field32(&reg, BBPCSR_BUSY, 1);
7233aca94dSKalle Valo 		rt2x00_set_field32(&reg, BBPCSR_WRITE_CONTROL, 1);
7333aca94dSKalle Valo 
7433aca94dSKalle Valo 		rt2x00mmio_register_write(rt2x00dev, BBPCSR, reg);
7533aca94dSKalle Valo 	}
7633aca94dSKalle Valo 
7733aca94dSKalle Valo 	mutex_unlock(&rt2x00dev->csr_mutex);
7833aca94dSKalle Valo }
7933aca94dSKalle Valo 
805fbbe378SArnd Bergmann static u8 rt2500pci_bbp_read(struct rt2x00_dev *rt2x00dev,
815fbbe378SArnd Bergmann 			     const unsigned int word)
8233aca94dSKalle Valo {
8333aca94dSKalle Valo 	u32 reg;
845fbbe378SArnd Bergmann 	u8 value;
8533aca94dSKalle Valo 
8633aca94dSKalle Valo 	mutex_lock(&rt2x00dev->csr_mutex);
8733aca94dSKalle Valo 
8833aca94dSKalle Valo 	/*
8933aca94dSKalle Valo 	 * Wait until the BBP becomes available, afterwards we
9033aca94dSKalle Valo 	 * can safely write the read request into the register.
9133aca94dSKalle Valo 	 * After the data has been written, we wait until hardware
9233aca94dSKalle Valo 	 * returns the correct value, if at any time the register
9333aca94dSKalle Valo 	 * doesn't become available in time, reg will be 0xffffffff
9433aca94dSKalle Valo 	 * which means we return 0xff to the caller.
9533aca94dSKalle Valo 	 */
9633aca94dSKalle Valo 	if (WAIT_FOR_BBP(rt2x00dev, &reg)) {
9733aca94dSKalle Valo 		reg = 0;
9833aca94dSKalle Valo 		rt2x00_set_field32(&reg, BBPCSR_REGNUM, word);
9933aca94dSKalle Valo 		rt2x00_set_field32(&reg, BBPCSR_BUSY, 1);
10033aca94dSKalle Valo 		rt2x00_set_field32(&reg, BBPCSR_WRITE_CONTROL, 0);
10133aca94dSKalle Valo 
10233aca94dSKalle Valo 		rt2x00mmio_register_write(rt2x00dev, BBPCSR, reg);
10333aca94dSKalle Valo 
10433aca94dSKalle Valo 		WAIT_FOR_BBP(rt2x00dev, &reg);
10533aca94dSKalle Valo 	}
10633aca94dSKalle Valo 
1075fbbe378SArnd Bergmann 	value = rt2x00_get_field32(reg, BBPCSR_VALUE);
10833aca94dSKalle Valo 
10933aca94dSKalle Valo 	mutex_unlock(&rt2x00dev->csr_mutex);
1105fbbe378SArnd Bergmann 
1115fbbe378SArnd Bergmann 	return value;
11233aca94dSKalle Valo }
11333aca94dSKalle Valo 
11433aca94dSKalle Valo static void rt2500pci_rf_write(struct rt2x00_dev *rt2x00dev,
11533aca94dSKalle Valo 			       const unsigned int word, const u32 value)
11633aca94dSKalle Valo {
11733aca94dSKalle Valo 	u32 reg;
11833aca94dSKalle Valo 
11933aca94dSKalle Valo 	mutex_lock(&rt2x00dev->csr_mutex);
12033aca94dSKalle Valo 
12133aca94dSKalle Valo 	/*
12233aca94dSKalle Valo 	 * Wait until the RF becomes available, afterwards we
12333aca94dSKalle Valo 	 * can safely write the new data into the register.
12433aca94dSKalle Valo 	 */
12533aca94dSKalle Valo 	if (WAIT_FOR_RF(rt2x00dev, &reg)) {
12633aca94dSKalle Valo 		reg = 0;
12733aca94dSKalle Valo 		rt2x00_set_field32(&reg, RFCSR_VALUE, value);
12833aca94dSKalle Valo 		rt2x00_set_field32(&reg, RFCSR_NUMBER_OF_BITS, 20);
12933aca94dSKalle Valo 		rt2x00_set_field32(&reg, RFCSR_IF_SELECT, 0);
13033aca94dSKalle Valo 		rt2x00_set_field32(&reg, RFCSR_BUSY, 1);
13133aca94dSKalle Valo 
13233aca94dSKalle Valo 		rt2x00mmio_register_write(rt2x00dev, RFCSR, reg);
13333aca94dSKalle Valo 		rt2x00_rf_write(rt2x00dev, word, value);
13433aca94dSKalle Valo 	}
13533aca94dSKalle Valo 
13633aca94dSKalle Valo 	mutex_unlock(&rt2x00dev->csr_mutex);
13733aca94dSKalle Valo }
13833aca94dSKalle Valo 
13933aca94dSKalle Valo static void rt2500pci_eepromregister_read(struct eeprom_93cx6 *eeprom)
14033aca94dSKalle Valo {
14133aca94dSKalle Valo 	struct rt2x00_dev *rt2x00dev = eeprom->data;
14233aca94dSKalle Valo 	u32 reg;
14333aca94dSKalle Valo 
1443954b4e3SArnd Bergmann 	reg = rt2x00mmio_register_read(rt2x00dev, CSR21);
14533aca94dSKalle Valo 
14633aca94dSKalle Valo 	eeprom->reg_data_in = !!rt2x00_get_field32(reg, CSR21_EEPROM_DATA_IN);
14733aca94dSKalle Valo 	eeprom->reg_data_out = !!rt2x00_get_field32(reg, CSR21_EEPROM_DATA_OUT);
14833aca94dSKalle Valo 	eeprom->reg_data_clock =
14933aca94dSKalle Valo 	    !!rt2x00_get_field32(reg, CSR21_EEPROM_DATA_CLOCK);
15033aca94dSKalle Valo 	eeprom->reg_chip_select =
15133aca94dSKalle Valo 	    !!rt2x00_get_field32(reg, CSR21_EEPROM_CHIP_SELECT);
15233aca94dSKalle Valo }
15333aca94dSKalle Valo 
15433aca94dSKalle Valo static void rt2500pci_eepromregister_write(struct eeprom_93cx6 *eeprom)
15533aca94dSKalle Valo {
15633aca94dSKalle Valo 	struct rt2x00_dev *rt2x00dev = eeprom->data;
15733aca94dSKalle Valo 	u32 reg = 0;
15833aca94dSKalle Valo 
15933aca94dSKalle Valo 	rt2x00_set_field32(&reg, CSR21_EEPROM_DATA_IN, !!eeprom->reg_data_in);
16033aca94dSKalle Valo 	rt2x00_set_field32(&reg, CSR21_EEPROM_DATA_OUT, !!eeprom->reg_data_out);
16133aca94dSKalle Valo 	rt2x00_set_field32(&reg, CSR21_EEPROM_DATA_CLOCK,
16233aca94dSKalle Valo 			   !!eeprom->reg_data_clock);
16333aca94dSKalle Valo 	rt2x00_set_field32(&reg, CSR21_EEPROM_CHIP_SELECT,
16433aca94dSKalle Valo 			   !!eeprom->reg_chip_select);
16533aca94dSKalle Valo 
16633aca94dSKalle Valo 	rt2x00mmio_register_write(rt2x00dev, CSR21, reg);
16733aca94dSKalle Valo }
16833aca94dSKalle Valo 
16933aca94dSKalle Valo #ifdef CONFIG_RT2X00_LIB_DEBUGFS
17033aca94dSKalle Valo static const struct rt2x00debug rt2500pci_rt2x00debug = {
17133aca94dSKalle Valo 	.owner	= THIS_MODULE,
17233aca94dSKalle Valo 	.csr	= {
1733954b4e3SArnd Bergmann 		.read		= rt2x00mmio_register_read,
17433aca94dSKalle Valo 		.write		= rt2x00mmio_register_write,
17533aca94dSKalle Valo 		.flags		= RT2X00DEBUGFS_OFFSET,
17633aca94dSKalle Valo 		.word_base	= CSR_REG_BASE,
17733aca94dSKalle Valo 		.word_size	= sizeof(u32),
17833aca94dSKalle Valo 		.word_count	= CSR_REG_SIZE / sizeof(u32),
17933aca94dSKalle Valo 	},
18033aca94dSKalle Valo 	.eeprom	= {
181*38651683SArnd Bergmann 		.read		= rt2x00_eeprom_read,
18233aca94dSKalle Valo 		.write		= rt2x00_eeprom_write,
18333aca94dSKalle Valo 		.word_base	= EEPROM_BASE,
18433aca94dSKalle Valo 		.word_size	= sizeof(u16),
18533aca94dSKalle Valo 		.word_count	= EEPROM_SIZE / sizeof(u16),
18633aca94dSKalle Valo 	},
18733aca94dSKalle Valo 	.bbp	= {
1885fbbe378SArnd Bergmann 		.read		= rt2500pci_bbp_read,
18933aca94dSKalle Valo 		.write		= rt2500pci_bbp_write,
19033aca94dSKalle Valo 		.word_base	= BBP_BASE,
19133aca94dSKalle Valo 		.word_size	= sizeof(u8),
19233aca94dSKalle Valo 		.word_count	= BBP_SIZE / sizeof(u8),
19333aca94dSKalle Valo 	},
19433aca94dSKalle Valo 	.rf	= {
195aea8baa1SArnd Bergmann 		.read		= rt2x00_rf_read,
19633aca94dSKalle Valo 		.write		= rt2500pci_rf_write,
19733aca94dSKalle Valo 		.word_base	= RF_BASE,
19833aca94dSKalle Valo 		.word_size	= sizeof(u32),
19933aca94dSKalle Valo 		.word_count	= RF_SIZE / sizeof(u32),
20033aca94dSKalle Valo 	},
20133aca94dSKalle Valo };
20233aca94dSKalle Valo #endif /* CONFIG_RT2X00_LIB_DEBUGFS */
20333aca94dSKalle Valo 
20433aca94dSKalle Valo static int rt2500pci_rfkill_poll(struct rt2x00_dev *rt2x00dev)
20533aca94dSKalle Valo {
20633aca94dSKalle Valo 	u32 reg;
20733aca94dSKalle Valo 
2083954b4e3SArnd Bergmann 	reg = rt2x00mmio_register_read(rt2x00dev, GPIOCSR);
20933aca94dSKalle Valo 	return rt2x00_get_field32(reg, GPIOCSR_VAL0);
21033aca94dSKalle Valo }
21133aca94dSKalle Valo 
21233aca94dSKalle Valo #ifdef CONFIG_RT2X00_LIB_LEDS
21333aca94dSKalle Valo static void rt2500pci_brightness_set(struct led_classdev *led_cdev,
21433aca94dSKalle Valo 				     enum led_brightness brightness)
21533aca94dSKalle Valo {
21633aca94dSKalle Valo 	struct rt2x00_led *led =
21733aca94dSKalle Valo 	    container_of(led_cdev, struct rt2x00_led, led_dev);
21833aca94dSKalle Valo 	unsigned int enabled = brightness != LED_OFF;
21933aca94dSKalle Valo 	u32 reg;
22033aca94dSKalle Valo 
2213954b4e3SArnd Bergmann 	reg = rt2x00mmio_register_read(led->rt2x00dev, LEDCSR);
22233aca94dSKalle Valo 
22333aca94dSKalle Valo 	if (led->type == LED_TYPE_RADIO || led->type == LED_TYPE_ASSOC)
22433aca94dSKalle Valo 		rt2x00_set_field32(&reg, LEDCSR_LINK, enabled);
22533aca94dSKalle Valo 	else if (led->type == LED_TYPE_ACTIVITY)
22633aca94dSKalle Valo 		rt2x00_set_field32(&reg, LEDCSR_ACTIVITY, enabled);
22733aca94dSKalle Valo 
22833aca94dSKalle Valo 	rt2x00mmio_register_write(led->rt2x00dev, LEDCSR, reg);
22933aca94dSKalle Valo }
23033aca94dSKalle Valo 
23133aca94dSKalle Valo static int rt2500pci_blink_set(struct led_classdev *led_cdev,
23233aca94dSKalle Valo 			       unsigned long *delay_on,
23333aca94dSKalle Valo 			       unsigned long *delay_off)
23433aca94dSKalle Valo {
23533aca94dSKalle Valo 	struct rt2x00_led *led =
23633aca94dSKalle Valo 	    container_of(led_cdev, struct rt2x00_led, led_dev);
23733aca94dSKalle Valo 	u32 reg;
23833aca94dSKalle Valo 
2393954b4e3SArnd Bergmann 	reg = rt2x00mmio_register_read(led->rt2x00dev, LEDCSR);
24033aca94dSKalle Valo 	rt2x00_set_field32(&reg, LEDCSR_ON_PERIOD, *delay_on);
24133aca94dSKalle Valo 	rt2x00_set_field32(&reg, LEDCSR_OFF_PERIOD, *delay_off);
24233aca94dSKalle Valo 	rt2x00mmio_register_write(led->rt2x00dev, LEDCSR, reg);
24333aca94dSKalle Valo 
24433aca94dSKalle Valo 	return 0;
24533aca94dSKalle Valo }
24633aca94dSKalle Valo 
24733aca94dSKalle Valo static void rt2500pci_init_led(struct rt2x00_dev *rt2x00dev,
24833aca94dSKalle Valo 			       struct rt2x00_led *led,
24933aca94dSKalle Valo 			       enum led_type type)
25033aca94dSKalle Valo {
25133aca94dSKalle Valo 	led->rt2x00dev = rt2x00dev;
25233aca94dSKalle Valo 	led->type = type;
25333aca94dSKalle Valo 	led->led_dev.brightness_set = rt2500pci_brightness_set;
25433aca94dSKalle Valo 	led->led_dev.blink_set = rt2500pci_blink_set;
25533aca94dSKalle Valo 	led->flags = LED_INITIALIZED;
25633aca94dSKalle Valo }
25733aca94dSKalle Valo #endif /* CONFIG_RT2X00_LIB_LEDS */
25833aca94dSKalle Valo 
25933aca94dSKalle Valo /*
26033aca94dSKalle Valo  * Configuration handlers.
26133aca94dSKalle Valo  */
26233aca94dSKalle Valo static void rt2500pci_config_filter(struct rt2x00_dev *rt2x00dev,
26333aca94dSKalle Valo 				    const unsigned int filter_flags)
26433aca94dSKalle Valo {
26533aca94dSKalle Valo 	u32 reg;
26633aca94dSKalle Valo 
26733aca94dSKalle Valo 	/*
26833aca94dSKalle Valo 	 * Start configuration steps.
26933aca94dSKalle Valo 	 * Note that the version error will always be dropped
27033aca94dSKalle Valo 	 * and broadcast frames will always be accepted since
27133aca94dSKalle Valo 	 * there is no filter for it at this time.
27233aca94dSKalle Valo 	 */
2733954b4e3SArnd Bergmann 	reg = rt2x00mmio_register_read(rt2x00dev, RXCSR0);
27433aca94dSKalle Valo 	rt2x00_set_field32(&reg, RXCSR0_DROP_CRC,
27533aca94dSKalle Valo 			   !(filter_flags & FIF_FCSFAIL));
27633aca94dSKalle Valo 	rt2x00_set_field32(&reg, RXCSR0_DROP_PHYSICAL,
27733aca94dSKalle Valo 			   !(filter_flags & FIF_PLCPFAIL));
27833aca94dSKalle Valo 	rt2x00_set_field32(&reg, RXCSR0_DROP_CONTROL,
27933aca94dSKalle Valo 			   !(filter_flags & FIF_CONTROL));
280262c741eSEli Cooper 	rt2x00_set_field32(&reg, RXCSR0_DROP_NOT_TO_ME,
281262c741eSEli Cooper 			   !test_bit(CONFIG_MONITORING, &rt2x00dev->flags));
28233aca94dSKalle Valo 	rt2x00_set_field32(&reg, RXCSR0_DROP_TODS,
283262c741eSEli Cooper 			   !test_bit(CONFIG_MONITORING, &rt2x00dev->flags) &&
28433aca94dSKalle Valo 			   !rt2x00dev->intf_ap_count);
28533aca94dSKalle Valo 	rt2x00_set_field32(&reg, RXCSR0_DROP_VERSION_ERROR, 1);
28633aca94dSKalle Valo 	rt2x00_set_field32(&reg, RXCSR0_DROP_MCAST,
28733aca94dSKalle Valo 			   !(filter_flags & FIF_ALLMULTI));
28833aca94dSKalle Valo 	rt2x00_set_field32(&reg, RXCSR0_DROP_BCAST, 0);
28933aca94dSKalle Valo 	rt2x00mmio_register_write(rt2x00dev, RXCSR0, reg);
29033aca94dSKalle Valo }
29133aca94dSKalle Valo 
29233aca94dSKalle Valo static void rt2500pci_config_intf(struct rt2x00_dev *rt2x00dev,
29333aca94dSKalle Valo 				  struct rt2x00_intf *intf,
29433aca94dSKalle Valo 				  struct rt2x00intf_conf *conf,
29533aca94dSKalle Valo 				  const unsigned int flags)
29633aca94dSKalle Valo {
29733aca94dSKalle Valo 	struct data_queue *queue = rt2x00dev->bcn;
29833aca94dSKalle Valo 	unsigned int bcn_preload;
29933aca94dSKalle Valo 	u32 reg;
30033aca94dSKalle Valo 
30133aca94dSKalle Valo 	if (flags & CONFIG_UPDATE_TYPE) {
30233aca94dSKalle Valo 		/*
30333aca94dSKalle Valo 		 * Enable beacon config
30433aca94dSKalle Valo 		 */
30533aca94dSKalle Valo 		bcn_preload = PREAMBLE + GET_DURATION(IEEE80211_HEADER, 20);
3063954b4e3SArnd Bergmann 		reg = rt2x00mmio_register_read(rt2x00dev, BCNCSR1);
30733aca94dSKalle Valo 		rt2x00_set_field32(&reg, BCNCSR1_PRELOAD, bcn_preload);
30833aca94dSKalle Valo 		rt2x00_set_field32(&reg, BCNCSR1_BEACON_CWMIN, queue->cw_min);
30933aca94dSKalle Valo 		rt2x00mmio_register_write(rt2x00dev, BCNCSR1, reg);
31033aca94dSKalle Valo 
31133aca94dSKalle Valo 		/*
31233aca94dSKalle Valo 		 * Enable synchronisation.
31333aca94dSKalle Valo 		 */
3143954b4e3SArnd Bergmann 		reg = rt2x00mmio_register_read(rt2x00dev, CSR14);
31533aca94dSKalle Valo 		rt2x00_set_field32(&reg, CSR14_TSF_SYNC, conf->sync);
31633aca94dSKalle Valo 		rt2x00mmio_register_write(rt2x00dev, CSR14, reg);
31733aca94dSKalle Valo 	}
31833aca94dSKalle Valo 
31933aca94dSKalle Valo 	if (flags & CONFIG_UPDATE_MAC)
32033aca94dSKalle Valo 		rt2x00mmio_register_multiwrite(rt2x00dev, CSR3,
32133aca94dSKalle Valo 					      conf->mac, sizeof(conf->mac));
32233aca94dSKalle Valo 
32333aca94dSKalle Valo 	if (flags & CONFIG_UPDATE_BSSID)
32433aca94dSKalle Valo 		rt2x00mmio_register_multiwrite(rt2x00dev, CSR5,
32533aca94dSKalle Valo 					      conf->bssid, sizeof(conf->bssid));
32633aca94dSKalle Valo }
32733aca94dSKalle Valo 
32833aca94dSKalle Valo static void rt2500pci_config_erp(struct rt2x00_dev *rt2x00dev,
32933aca94dSKalle Valo 				 struct rt2x00lib_erp *erp,
33033aca94dSKalle Valo 				 u32 changed)
33133aca94dSKalle Valo {
33233aca94dSKalle Valo 	int preamble_mask;
33333aca94dSKalle Valo 	u32 reg;
33433aca94dSKalle Valo 
33533aca94dSKalle Valo 	/*
33633aca94dSKalle Valo 	 * When short preamble is enabled, we should set bit 0x08
33733aca94dSKalle Valo 	 */
33833aca94dSKalle Valo 	if (changed & BSS_CHANGED_ERP_PREAMBLE) {
33933aca94dSKalle Valo 		preamble_mask = erp->short_preamble << 3;
34033aca94dSKalle Valo 
3413954b4e3SArnd Bergmann 		reg = rt2x00mmio_register_read(rt2x00dev, TXCSR1);
34233aca94dSKalle Valo 		rt2x00_set_field32(&reg, TXCSR1_ACK_TIMEOUT, 0x162);
34333aca94dSKalle Valo 		rt2x00_set_field32(&reg, TXCSR1_ACK_CONSUME_TIME, 0xa2);
34433aca94dSKalle Valo 		rt2x00_set_field32(&reg, TXCSR1_TSF_OFFSET, IEEE80211_HEADER);
34533aca94dSKalle Valo 		rt2x00_set_field32(&reg, TXCSR1_AUTORESPONDER, 1);
34633aca94dSKalle Valo 		rt2x00mmio_register_write(rt2x00dev, TXCSR1, reg);
34733aca94dSKalle Valo 
3483954b4e3SArnd Bergmann 		reg = rt2x00mmio_register_read(rt2x00dev, ARCSR2);
34933aca94dSKalle Valo 		rt2x00_set_field32(&reg, ARCSR2_SIGNAL, 0x00);
35033aca94dSKalle Valo 		rt2x00_set_field32(&reg, ARCSR2_SERVICE, 0x04);
35133aca94dSKalle Valo 		rt2x00_set_field32(&reg, ARCSR2_LENGTH,
35233aca94dSKalle Valo 				   GET_DURATION(ACK_SIZE, 10));
35333aca94dSKalle Valo 		rt2x00mmio_register_write(rt2x00dev, ARCSR2, reg);
35433aca94dSKalle Valo 
3553954b4e3SArnd Bergmann 		reg = rt2x00mmio_register_read(rt2x00dev, ARCSR3);
35633aca94dSKalle Valo 		rt2x00_set_field32(&reg, ARCSR3_SIGNAL, 0x01 | preamble_mask);
35733aca94dSKalle Valo 		rt2x00_set_field32(&reg, ARCSR3_SERVICE, 0x04);
35833aca94dSKalle Valo 		rt2x00_set_field32(&reg, ARCSR2_LENGTH,
35933aca94dSKalle Valo 				   GET_DURATION(ACK_SIZE, 20));
36033aca94dSKalle Valo 		rt2x00mmio_register_write(rt2x00dev, ARCSR3, reg);
36133aca94dSKalle Valo 
3623954b4e3SArnd Bergmann 		reg = rt2x00mmio_register_read(rt2x00dev, ARCSR4);
36333aca94dSKalle Valo 		rt2x00_set_field32(&reg, ARCSR4_SIGNAL, 0x02 | preamble_mask);
36433aca94dSKalle Valo 		rt2x00_set_field32(&reg, ARCSR4_SERVICE, 0x04);
36533aca94dSKalle Valo 		rt2x00_set_field32(&reg, ARCSR2_LENGTH,
36633aca94dSKalle Valo 				   GET_DURATION(ACK_SIZE, 55));
36733aca94dSKalle Valo 		rt2x00mmio_register_write(rt2x00dev, ARCSR4, reg);
36833aca94dSKalle Valo 
3693954b4e3SArnd Bergmann 		reg = rt2x00mmio_register_read(rt2x00dev, ARCSR5);
37033aca94dSKalle Valo 		rt2x00_set_field32(&reg, ARCSR5_SIGNAL, 0x03 | preamble_mask);
37133aca94dSKalle Valo 		rt2x00_set_field32(&reg, ARCSR5_SERVICE, 0x84);
37233aca94dSKalle Valo 		rt2x00_set_field32(&reg, ARCSR2_LENGTH,
37333aca94dSKalle Valo 				   GET_DURATION(ACK_SIZE, 110));
37433aca94dSKalle Valo 		rt2x00mmio_register_write(rt2x00dev, ARCSR5, reg);
37533aca94dSKalle Valo 	}
37633aca94dSKalle Valo 
37733aca94dSKalle Valo 	if (changed & BSS_CHANGED_BASIC_RATES)
37833aca94dSKalle Valo 		rt2x00mmio_register_write(rt2x00dev, ARCSR1, erp->basic_rates);
37933aca94dSKalle Valo 
38033aca94dSKalle Valo 	if (changed & BSS_CHANGED_ERP_SLOT) {
3813954b4e3SArnd Bergmann 		reg = rt2x00mmio_register_read(rt2x00dev, CSR11);
38233aca94dSKalle Valo 		rt2x00_set_field32(&reg, CSR11_SLOT_TIME, erp->slot_time);
38333aca94dSKalle Valo 		rt2x00mmio_register_write(rt2x00dev, CSR11, reg);
38433aca94dSKalle Valo 
3853954b4e3SArnd Bergmann 		reg = rt2x00mmio_register_read(rt2x00dev, CSR18);
38633aca94dSKalle Valo 		rt2x00_set_field32(&reg, CSR18_SIFS, erp->sifs);
38733aca94dSKalle Valo 		rt2x00_set_field32(&reg, CSR18_PIFS, erp->pifs);
38833aca94dSKalle Valo 		rt2x00mmio_register_write(rt2x00dev, CSR18, reg);
38933aca94dSKalle Valo 
3903954b4e3SArnd Bergmann 		reg = rt2x00mmio_register_read(rt2x00dev, CSR19);
39133aca94dSKalle Valo 		rt2x00_set_field32(&reg, CSR19_DIFS, erp->difs);
39233aca94dSKalle Valo 		rt2x00_set_field32(&reg, CSR19_EIFS, erp->eifs);
39333aca94dSKalle Valo 		rt2x00mmio_register_write(rt2x00dev, CSR19, reg);
39433aca94dSKalle Valo 	}
39533aca94dSKalle Valo 
39633aca94dSKalle Valo 	if (changed & BSS_CHANGED_BEACON_INT) {
3973954b4e3SArnd Bergmann 		reg = rt2x00mmio_register_read(rt2x00dev, CSR12);
39833aca94dSKalle Valo 		rt2x00_set_field32(&reg, CSR12_BEACON_INTERVAL,
39933aca94dSKalle Valo 				   erp->beacon_int * 16);
40033aca94dSKalle Valo 		rt2x00_set_field32(&reg, CSR12_CFP_MAX_DURATION,
40133aca94dSKalle Valo 				   erp->beacon_int * 16);
40233aca94dSKalle Valo 		rt2x00mmio_register_write(rt2x00dev, CSR12, reg);
40333aca94dSKalle Valo 	}
40433aca94dSKalle Valo 
40533aca94dSKalle Valo }
40633aca94dSKalle Valo 
40733aca94dSKalle Valo static void rt2500pci_config_ant(struct rt2x00_dev *rt2x00dev,
40833aca94dSKalle Valo 				 struct antenna_setup *ant)
40933aca94dSKalle Valo {
41033aca94dSKalle Valo 	u32 reg;
41133aca94dSKalle Valo 	u8 r14;
41233aca94dSKalle Valo 	u8 r2;
41333aca94dSKalle Valo 
41433aca94dSKalle Valo 	/*
41533aca94dSKalle Valo 	 * We should never come here because rt2x00lib is supposed
41633aca94dSKalle Valo 	 * to catch this and send us the correct antenna explicitely.
41733aca94dSKalle Valo 	 */
41833aca94dSKalle Valo 	BUG_ON(ant->rx == ANTENNA_SW_DIVERSITY ||
41933aca94dSKalle Valo 	       ant->tx == ANTENNA_SW_DIVERSITY);
42033aca94dSKalle Valo 
4213954b4e3SArnd Bergmann 	reg = rt2x00mmio_register_read(rt2x00dev, BBPCSR1);
4225fbbe378SArnd Bergmann 	r14 = rt2500pci_bbp_read(rt2x00dev, 14);
4235fbbe378SArnd Bergmann 	r2 = rt2500pci_bbp_read(rt2x00dev, 2);
42433aca94dSKalle Valo 
42533aca94dSKalle Valo 	/*
42633aca94dSKalle Valo 	 * Configure the TX antenna.
42733aca94dSKalle Valo 	 */
42833aca94dSKalle Valo 	switch (ant->tx) {
42933aca94dSKalle Valo 	case ANTENNA_A:
43033aca94dSKalle Valo 		rt2x00_set_field8(&r2, BBP_R2_TX_ANTENNA, 0);
43133aca94dSKalle Valo 		rt2x00_set_field32(&reg, BBPCSR1_CCK, 0);
43233aca94dSKalle Valo 		rt2x00_set_field32(&reg, BBPCSR1_OFDM, 0);
43333aca94dSKalle Valo 		break;
43433aca94dSKalle Valo 	case ANTENNA_B:
43533aca94dSKalle Valo 	default:
43633aca94dSKalle Valo 		rt2x00_set_field8(&r2, BBP_R2_TX_ANTENNA, 2);
43733aca94dSKalle Valo 		rt2x00_set_field32(&reg, BBPCSR1_CCK, 2);
43833aca94dSKalle Valo 		rt2x00_set_field32(&reg, BBPCSR1_OFDM, 2);
43933aca94dSKalle Valo 		break;
44033aca94dSKalle Valo 	}
44133aca94dSKalle Valo 
44233aca94dSKalle Valo 	/*
44333aca94dSKalle Valo 	 * Configure the RX antenna.
44433aca94dSKalle Valo 	 */
44533aca94dSKalle Valo 	switch (ant->rx) {
44633aca94dSKalle Valo 	case ANTENNA_A:
44733aca94dSKalle Valo 		rt2x00_set_field8(&r14, BBP_R14_RX_ANTENNA, 0);
44833aca94dSKalle Valo 		break;
44933aca94dSKalle Valo 	case ANTENNA_B:
45033aca94dSKalle Valo 	default:
45133aca94dSKalle Valo 		rt2x00_set_field8(&r14, BBP_R14_RX_ANTENNA, 2);
45233aca94dSKalle Valo 		break;
45333aca94dSKalle Valo 	}
45433aca94dSKalle Valo 
45533aca94dSKalle Valo 	/*
45633aca94dSKalle Valo 	 * RT2525E and RT5222 need to flip TX I/Q
45733aca94dSKalle Valo 	 */
45833aca94dSKalle Valo 	if (rt2x00_rf(rt2x00dev, RF2525E) || rt2x00_rf(rt2x00dev, RF5222)) {
45933aca94dSKalle Valo 		rt2x00_set_field8(&r2, BBP_R2_TX_IQ_FLIP, 1);
46033aca94dSKalle Valo 		rt2x00_set_field32(&reg, BBPCSR1_CCK_FLIP, 1);
46133aca94dSKalle Valo 		rt2x00_set_field32(&reg, BBPCSR1_OFDM_FLIP, 1);
46233aca94dSKalle Valo 
46333aca94dSKalle Valo 		/*
46433aca94dSKalle Valo 		 * RT2525E does not need RX I/Q Flip.
46533aca94dSKalle Valo 		 */
46633aca94dSKalle Valo 		if (rt2x00_rf(rt2x00dev, RF2525E))
46733aca94dSKalle Valo 			rt2x00_set_field8(&r14, BBP_R14_RX_IQ_FLIP, 0);
46833aca94dSKalle Valo 	} else {
46933aca94dSKalle Valo 		rt2x00_set_field32(&reg, BBPCSR1_CCK_FLIP, 0);
47033aca94dSKalle Valo 		rt2x00_set_field32(&reg, BBPCSR1_OFDM_FLIP, 0);
47133aca94dSKalle Valo 	}
47233aca94dSKalle Valo 
47333aca94dSKalle Valo 	rt2x00mmio_register_write(rt2x00dev, BBPCSR1, reg);
47433aca94dSKalle Valo 	rt2500pci_bbp_write(rt2x00dev, 14, r14);
47533aca94dSKalle Valo 	rt2500pci_bbp_write(rt2x00dev, 2, r2);
47633aca94dSKalle Valo }
47733aca94dSKalle Valo 
47833aca94dSKalle Valo static void rt2500pci_config_channel(struct rt2x00_dev *rt2x00dev,
47933aca94dSKalle Valo 				     struct rf_channel *rf, const int txpower)
48033aca94dSKalle Valo {
48133aca94dSKalle Valo 	u8 r70;
48233aca94dSKalle Valo 
48333aca94dSKalle Valo 	/*
48433aca94dSKalle Valo 	 * Set TXpower.
48533aca94dSKalle Valo 	 */
48633aca94dSKalle Valo 	rt2x00_set_field32(&rf->rf3, RF3_TXPOWER, TXPOWER_TO_DEV(txpower));
48733aca94dSKalle Valo 
48833aca94dSKalle Valo 	/*
48933aca94dSKalle Valo 	 * Switch on tuning bits.
49033aca94dSKalle Valo 	 * For RT2523 devices we do not need to update the R1 register.
49133aca94dSKalle Valo 	 */
49233aca94dSKalle Valo 	if (!rt2x00_rf(rt2x00dev, RF2523))
49333aca94dSKalle Valo 		rt2x00_set_field32(&rf->rf1, RF1_TUNER, 1);
49433aca94dSKalle Valo 	rt2x00_set_field32(&rf->rf3, RF3_TUNER, 1);
49533aca94dSKalle Valo 
49633aca94dSKalle Valo 	/*
49733aca94dSKalle Valo 	 * For RT2525 we should first set the channel to half band higher.
49833aca94dSKalle Valo 	 */
49933aca94dSKalle Valo 	if (rt2x00_rf(rt2x00dev, RF2525)) {
50033aca94dSKalle Valo 		static const u32 vals[] = {
50133aca94dSKalle Valo 			0x00080cbe, 0x00080d02, 0x00080d06, 0x00080d0a,
50233aca94dSKalle Valo 			0x00080d0e, 0x00080d12, 0x00080d16, 0x00080d1a,
50333aca94dSKalle Valo 			0x00080d1e, 0x00080d22, 0x00080d26, 0x00080d2a,
50433aca94dSKalle Valo 			0x00080d2e, 0x00080d3a
50533aca94dSKalle Valo 		};
50633aca94dSKalle Valo 
50733aca94dSKalle Valo 		rt2500pci_rf_write(rt2x00dev, 1, rf->rf1);
50833aca94dSKalle Valo 		rt2500pci_rf_write(rt2x00dev, 2, vals[rf->channel - 1]);
50933aca94dSKalle Valo 		rt2500pci_rf_write(rt2x00dev, 3, rf->rf3);
51033aca94dSKalle Valo 		if (rf->rf4)
51133aca94dSKalle Valo 			rt2500pci_rf_write(rt2x00dev, 4, rf->rf4);
51233aca94dSKalle Valo 	}
51333aca94dSKalle Valo 
51433aca94dSKalle Valo 	rt2500pci_rf_write(rt2x00dev, 1, rf->rf1);
51533aca94dSKalle Valo 	rt2500pci_rf_write(rt2x00dev, 2, rf->rf2);
51633aca94dSKalle Valo 	rt2500pci_rf_write(rt2x00dev, 3, rf->rf3);
51733aca94dSKalle Valo 	if (rf->rf4)
51833aca94dSKalle Valo 		rt2500pci_rf_write(rt2x00dev, 4, rf->rf4);
51933aca94dSKalle Valo 
52033aca94dSKalle Valo 	/*
52133aca94dSKalle Valo 	 * Channel 14 requires the Japan filter bit to be set.
52233aca94dSKalle Valo 	 */
52333aca94dSKalle Valo 	r70 = 0x46;
52433aca94dSKalle Valo 	rt2x00_set_field8(&r70, BBP_R70_JAPAN_FILTER, rf->channel == 14);
52533aca94dSKalle Valo 	rt2500pci_bbp_write(rt2x00dev, 70, r70);
52633aca94dSKalle Valo 
52733aca94dSKalle Valo 	msleep(1);
52833aca94dSKalle Valo 
52933aca94dSKalle Valo 	/*
53033aca94dSKalle Valo 	 * Switch off tuning bits.
53133aca94dSKalle Valo 	 * For RT2523 devices we do not need to update the R1 register.
53233aca94dSKalle Valo 	 */
53333aca94dSKalle Valo 	if (!rt2x00_rf(rt2x00dev, RF2523)) {
53433aca94dSKalle Valo 		rt2x00_set_field32(&rf->rf1, RF1_TUNER, 0);
53533aca94dSKalle Valo 		rt2500pci_rf_write(rt2x00dev, 1, rf->rf1);
53633aca94dSKalle Valo 	}
53733aca94dSKalle Valo 
53833aca94dSKalle Valo 	rt2x00_set_field32(&rf->rf3, RF3_TUNER, 0);
53933aca94dSKalle Valo 	rt2500pci_rf_write(rt2x00dev, 3, rf->rf3);
54033aca94dSKalle Valo 
54133aca94dSKalle Valo 	/*
54233aca94dSKalle Valo 	 * Clear false CRC during channel switch.
54333aca94dSKalle Valo 	 */
5443954b4e3SArnd Bergmann 	rf->rf1 = rt2x00mmio_register_read(rt2x00dev, CNT0);
54533aca94dSKalle Valo }
54633aca94dSKalle Valo 
54733aca94dSKalle Valo static void rt2500pci_config_txpower(struct rt2x00_dev *rt2x00dev,
54833aca94dSKalle Valo 				     const int txpower)
54933aca94dSKalle Valo {
55033aca94dSKalle Valo 	u32 rf3;
55133aca94dSKalle Valo 
552aea8baa1SArnd Bergmann 	rf3 = rt2x00_rf_read(rt2x00dev, 3);
55333aca94dSKalle Valo 	rt2x00_set_field32(&rf3, RF3_TXPOWER, TXPOWER_TO_DEV(txpower));
55433aca94dSKalle Valo 	rt2500pci_rf_write(rt2x00dev, 3, rf3);
55533aca94dSKalle Valo }
55633aca94dSKalle Valo 
55733aca94dSKalle Valo static void rt2500pci_config_retry_limit(struct rt2x00_dev *rt2x00dev,
55833aca94dSKalle Valo 					 struct rt2x00lib_conf *libconf)
55933aca94dSKalle Valo {
56033aca94dSKalle Valo 	u32 reg;
56133aca94dSKalle Valo 
5623954b4e3SArnd Bergmann 	reg = rt2x00mmio_register_read(rt2x00dev, CSR11);
56333aca94dSKalle Valo 	rt2x00_set_field32(&reg, CSR11_LONG_RETRY,
56433aca94dSKalle Valo 			   libconf->conf->long_frame_max_tx_count);
56533aca94dSKalle Valo 	rt2x00_set_field32(&reg, CSR11_SHORT_RETRY,
56633aca94dSKalle Valo 			   libconf->conf->short_frame_max_tx_count);
56733aca94dSKalle Valo 	rt2x00mmio_register_write(rt2x00dev, CSR11, reg);
56833aca94dSKalle Valo }
56933aca94dSKalle Valo 
57033aca94dSKalle Valo static void rt2500pci_config_ps(struct rt2x00_dev *rt2x00dev,
57133aca94dSKalle Valo 				struct rt2x00lib_conf *libconf)
57233aca94dSKalle Valo {
57333aca94dSKalle Valo 	enum dev_state state =
57433aca94dSKalle Valo 	    (libconf->conf->flags & IEEE80211_CONF_PS) ?
57533aca94dSKalle Valo 		STATE_SLEEP : STATE_AWAKE;
57633aca94dSKalle Valo 	u32 reg;
57733aca94dSKalle Valo 
57833aca94dSKalle Valo 	if (state == STATE_SLEEP) {
5793954b4e3SArnd Bergmann 		reg = rt2x00mmio_register_read(rt2x00dev, CSR20);
58033aca94dSKalle Valo 		rt2x00_set_field32(&reg, CSR20_DELAY_AFTER_TBCN,
58133aca94dSKalle Valo 				   (rt2x00dev->beacon_int - 20) * 16);
58233aca94dSKalle Valo 		rt2x00_set_field32(&reg, CSR20_TBCN_BEFORE_WAKEUP,
58333aca94dSKalle Valo 				   libconf->conf->listen_interval - 1);
58433aca94dSKalle Valo 
58533aca94dSKalle Valo 		/* We must first disable autowake before it can be enabled */
58633aca94dSKalle Valo 		rt2x00_set_field32(&reg, CSR20_AUTOWAKE, 0);
58733aca94dSKalle Valo 		rt2x00mmio_register_write(rt2x00dev, CSR20, reg);
58833aca94dSKalle Valo 
58933aca94dSKalle Valo 		rt2x00_set_field32(&reg, CSR20_AUTOWAKE, 1);
59033aca94dSKalle Valo 		rt2x00mmio_register_write(rt2x00dev, CSR20, reg);
59133aca94dSKalle Valo 	} else {
5923954b4e3SArnd Bergmann 		reg = rt2x00mmio_register_read(rt2x00dev, CSR20);
59333aca94dSKalle Valo 		rt2x00_set_field32(&reg, CSR20_AUTOWAKE, 0);
59433aca94dSKalle Valo 		rt2x00mmio_register_write(rt2x00dev, CSR20, reg);
59533aca94dSKalle Valo 	}
59633aca94dSKalle Valo 
59733aca94dSKalle Valo 	rt2x00dev->ops->lib->set_device_state(rt2x00dev, state);
59833aca94dSKalle Valo }
59933aca94dSKalle Valo 
60033aca94dSKalle Valo static void rt2500pci_config(struct rt2x00_dev *rt2x00dev,
60133aca94dSKalle Valo 			     struct rt2x00lib_conf *libconf,
60233aca94dSKalle Valo 			     const unsigned int flags)
60333aca94dSKalle Valo {
60433aca94dSKalle Valo 	if (flags & IEEE80211_CONF_CHANGE_CHANNEL)
60533aca94dSKalle Valo 		rt2500pci_config_channel(rt2x00dev, &libconf->rf,
60633aca94dSKalle Valo 					 libconf->conf->power_level);
60733aca94dSKalle Valo 	if ((flags & IEEE80211_CONF_CHANGE_POWER) &&
60833aca94dSKalle Valo 	    !(flags & IEEE80211_CONF_CHANGE_CHANNEL))
60933aca94dSKalle Valo 		rt2500pci_config_txpower(rt2x00dev,
61033aca94dSKalle Valo 					 libconf->conf->power_level);
61133aca94dSKalle Valo 	if (flags & IEEE80211_CONF_CHANGE_RETRY_LIMITS)
61233aca94dSKalle Valo 		rt2500pci_config_retry_limit(rt2x00dev, libconf);
61333aca94dSKalle Valo 	if (flags & IEEE80211_CONF_CHANGE_PS)
61433aca94dSKalle Valo 		rt2500pci_config_ps(rt2x00dev, libconf);
61533aca94dSKalle Valo }
61633aca94dSKalle Valo 
61733aca94dSKalle Valo /*
61833aca94dSKalle Valo  * Link tuning
61933aca94dSKalle Valo  */
62033aca94dSKalle Valo static void rt2500pci_link_stats(struct rt2x00_dev *rt2x00dev,
62133aca94dSKalle Valo 				 struct link_qual *qual)
62233aca94dSKalle Valo {
62333aca94dSKalle Valo 	u32 reg;
62433aca94dSKalle Valo 
62533aca94dSKalle Valo 	/*
62633aca94dSKalle Valo 	 * Update FCS error count from register.
62733aca94dSKalle Valo 	 */
6283954b4e3SArnd Bergmann 	reg = rt2x00mmio_register_read(rt2x00dev, CNT0);
62933aca94dSKalle Valo 	qual->rx_failed = rt2x00_get_field32(reg, CNT0_FCS_ERROR);
63033aca94dSKalle Valo 
63133aca94dSKalle Valo 	/*
63233aca94dSKalle Valo 	 * Update False CCA count from register.
63333aca94dSKalle Valo 	 */
6343954b4e3SArnd Bergmann 	reg = rt2x00mmio_register_read(rt2x00dev, CNT3);
63533aca94dSKalle Valo 	qual->false_cca = rt2x00_get_field32(reg, CNT3_FALSE_CCA);
63633aca94dSKalle Valo }
63733aca94dSKalle Valo 
63833aca94dSKalle Valo static inline void rt2500pci_set_vgc(struct rt2x00_dev *rt2x00dev,
63933aca94dSKalle Valo 				     struct link_qual *qual, u8 vgc_level)
64033aca94dSKalle Valo {
64133aca94dSKalle Valo 	if (qual->vgc_level_reg != vgc_level) {
64233aca94dSKalle Valo 		rt2500pci_bbp_write(rt2x00dev, 17, vgc_level);
64333aca94dSKalle Valo 		qual->vgc_level = vgc_level;
64433aca94dSKalle Valo 		qual->vgc_level_reg = vgc_level;
64533aca94dSKalle Valo 	}
64633aca94dSKalle Valo }
64733aca94dSKalle Valo 
64833aca94dSKalle Valo static void rt2500pci_reset_tuner(struct rt2x00_dev *rt2x00dev,
64933aca94dSKalle Valo 				  struct link_qual *qual)
65033aca94dSKalle Valo {
65133aca94dSKalle Valo 	rt2500pci_set_vgc(rt2x00dev, qual, 0x48);
65233aca94dSKalle Valo }
65333aca94dSKalle Valo 
65433aca94dSKalle Valo static void rt2500pci_link_tuner(struct rt2x00_dev *rt2x00dev,
65533aca94dSKalle Valo 				 struct link_qual *qual, const u32 count)
65633aca94dSKalle Valo {
65733aca94dSKalle Valo 	/*
65833aca94dSKalle Valo 	 * To prevent collisions with MAC ASIC on chipsets
65933aca94dSKalle Valo 	 * up to version C the link tuning should halt after 20
66033aca94dSKalle Valo 	 * seconds while being associated.
66133aca94dSKalle Valo 	 */
66233aca94dSKalle Valo 	if (rt2x00_rev(rt2x00dev) < RT2560_VERSION_D &&
66333aca94dSKalle Valo 	    rt2x00dev->intf_associated && count > 20)
66433aca94dSKalle Valo 		return;
66533aca94dSKalle Valo 
66633aca94dSKalle Valo 	/*
66733aca94dSKalle Valo 	 * Chipset versions C and lower should directly continue
66833aca94dSKalle Valo 	 * to the dynamic CCA tuning. Chipset version D and higher
66933aca94dSKalle Valo 	 * should go straight to dynamic CCA tuning when they
67033aca94dSKalle Valo 	 * are not associated.
67133aca94dSKalle Valo 	 */
67233aca94dSKalle Valo 	if (rt2x00_rev(rt2x00dev) < RT2560_VERSION_D ||
67333aca94dSKalle Valo 	    !rt2x00dev->intf_associated)
67433aca94dSKalle Valo 		goto dynamic_cca_tune;
67533aca94dSKalle Valo 
67633aca94dSKalle Valo 	/*
67733aca94dSKalle Valo 	 * A too low RSSI will cause too much false CCA which will
67833aca94dSKalle Valo 	 * then corrupt the R17 tuning. To remidy this the tuning should
67933aca94dSKalle Valo 	 * be stopped (While making sure the R17 value will not exceed limits)
68033aca94dSKalle Valo 	 */
68133aca94dSKalle Valo 	if (qual->rssi < -80 && count > 20) {
68233aca94dSKalle Valo 		if (qual->vgc_level_reg >= 0x41)
68333aca94dSKalle Valo 			rt2500pci_set_vgc(rt2x00dev, qual, qual->vgc_level);
68433aca94dSKalle Valo 		return;
68533aca94dSKalle Valo 	}
68633aca94dSKalle Valo 
68733aca94dSKalle Valo 	/*
68833aca94dSKalle Valo 	 * Special big-R17 for short distance
68933aca94dSKalle Valo 	 */
69033aca94dSKalle Valo 	if (qual->rssi >= -58) {
69133aca94dSKalle Valo 		rt2500pci_set_vgc(rt2x00dev, qual, 0x50);
69233aca94dSKalle Valo 		return;
69333aca94dSKalle Valo 	}
69433aca94dSKalle Valo 
69533aca94dSKalle Valo 	/*
69633aca94dSKalle Valo 	 * Special mid-R17 for middle distance
69733aca94dSKalle Valo 	 */
69833aca94dSKalle Valo 	if (qual->rssi >= -74) {
69933aca94dSKalle Valo 		rt2500pci_set_vgc(rt2x00dev, qual, 0x41);
70033aca94dSKalle Valo 		return;
70133aca94dSKalle Valo 	}
70233aca94dSKalle Valo 
70333aca94dSKalle Valo 	/*
70433aca94dSKalle Valo 	 * Leave short or middle distance condition, restore r17
70533aca94dSKalle Valo 	 * to the dynamic tuning range.
70633aca94dSKalle Valo 	 */
70733aca94dSKalle Valo 	if (qual->vgc_level_reg >= 0x41) {
70833aca94dSKalle Valo 		rt2500pci_set_vgc(rt2x00dev, qual, qual->vgc_level);
70933aca94dSKalle Valo 		return;
71033aca94dSKalle Valo 	}
71133aca94dSKalle Valo 
71233aca94dSKalle Valo dynamic_cca_tune:
71333aca94dSKalle Valo 
71433aca94dSKalle Valo 	/*
71533aca94dSKalle Valo 	 * R17 is inside the dynamic tuning range,
71633aca94dSKalle Valo 	 * start tuning the link based on the false cca counter.
71733aca94dSKalle Valo 	 */
71833aca94dSKalle Valo 	if (qual->false_cca > 512 && qual->vgc_level_reg < 0x40)
71933aca94dSKalle Valo 		rt2500pci_set_vgc(rt2x00dev, qual, ++qual->vgc_level_reg);
72033aca94dSKalle Valo 	else if (qual->false_cca < 100 && qual->vgc_level_reg > 0x32)
72133aca94dSKalle Valo 		rt2500pci_set_vgc(rt2x00dev, qual, --qual->vgc_level_reg);
72233aca94dSKalle Valo }
72333aca94dSKalle Valo 
72433aca94dSKalle Valo /*
72533aca94dSKalle Valo  * Queue handlers.
72633aca94dSKalle Valo  */
72733aca94dSKalle Valo static void rt2500pci_start_queue(struct data_queue *queue)
72833aca94dSKalle Valo {
72933aca94dSKalle Valo 	struct rt2x00_dev *rt2x00dev = queue->rt2x00dev;
73033aca94dSKalle Valo 	u32 reg;
73133aca94dSKalle Valo 
73233aca94dSKalle Valo 	switch (queue->qid) {
73333aca94dSKalle Valo 	case QID_RX:
7343954b4e3SArnd Bergmann 		reg = rt2x00mmio_register_read(rt2x00dev, RXCSR0);
73533aca94dSKalle Valo 		rt2x00_set_field32(&reg, RXCSR0_DISABLE_RX, 0);
73633aca94dSKalle Valo 		rt2x00mmio_register_write(rt2x00dev, RXCSR0, reg);
73733aca94dSKalle Valo 		break;
73833aca94dSKalle Valo 	case QID_BEACON:
7393954b4e3SArnd Bergmann 		reg = rt2x00mmio_register_read(rt2x00dev, CSR14);
74033aca94dSKalle Valo 		rt2x00_set_field32(&reg, CSR14_TSF_COUNT, 1);
74133aca94dSKalle Valo 		rt2x00_set_field32(&reg, CSR14_TBCN, 1);
74233aca94dSKalle Valo 		rt2x00_set_field32(&reg, CSR14_BEACON_GEN, 1);
74333aca94dSKalle Valo 		rt2x00mmio_register_write(rt2x00dev, CSR14, reg);
74433aca94dSKalle Valo 		break;
74533aca94dSKalle Valo 	default:
74633aca94dSKalle Valo 		break;
74733aca94dSKalle Valo 	}
74833aca94dSKalle Valo }
74933aca94dSKalle Valo 
75033aca94dSKalle Valo static void rt2500pci_kick_queue(struct data_queue *queue)
75133aca94dSKalle Valo {
75233aca94dSKalle Valo 	struct rt2x00_dev *rt2x00dev = queue->rt2x00dev;
75333aca94dSKalle Valo 	u32 reg;
75433aca94dSKalle Valo 
75533aca94dSKalle Valo 	switch (queue->qid) {
75633aca94dSKalle Valo 	case QID_AC_VO:
7573954b4e3SArnd Bergmann 		reg = rt2x00mmio_register_read(rt2x00dev, TXCSR0);
75833aca94dSKalle Valo 		rt2x00_set_field32(&reg, TXCSR0_KICK_PRIO, 1);
75933aca94dSKalle Valo 		rt2x00mmio_register_write(rt2x00dev, TXCSR0, reg);
76033aca94dSKalle Valo 		break;
76133aca94dSKalle Valo 	case QID_AC_VI:
7623954b4e3SArnd Bergmann 		reg = rt2x00mmio_register_read(rt2x00dev, TXCSR0);
76333aca94dSKalle Valo 		rt2x00_set_field32(&reg, TXCSR0_KICK_TX, 1);
76433aca94dSKalle Valo 		rt2x00mmio_register_write(rt2x00dev, TXCSR0, reg);
76533aca94dSKalle Valo 		break;
76633aca94dSKalle Valo 	case QID_ATIM:
7673954b4e3SArnd Bergmann 		reg = rt2x00mmio_register_read(rt2x00dev, TXCSR0);
76833aca94dSKalle Valo 		rt2x00_set_field32(&reg, TXCSR0_KICK_ATIM, 1);
76933aca94dSKalle Valo 		rt2x00mmio_register_write(rt2x00dev, TXCSR0, reg);
77033aca94dSKalle Valo 		break;
77133aca94dSKalle Valo 	default:
77233aca94dSKalle Valo 		break;
77333aca94dSKalle Valo 	}
77433aca94dSKalle Valo }
77533aca94dSKalle Valo 
77633aca94dSKalle Valo static void rt2500pci_stop_queue(struct data_queue *queue)
77733aca94dSKalle Valo {
77833aca94dSKalle Valo 	struct rt2x00_dev *rt2x00dev = queue->rt2x00dev;
77933aca94dSKalle Valo 	u32 reg;
78033aca94dSKalle Valo 
78133aca94dSKalle Valo 	switch (queue->qid) {
78233aca94dSKalle Valo 	case QID_AC_VO:
78333aca94dSKalle Valo 	case QID_AC_VI:
78433aca94dSKalle Valo 	case QID_ATIM:
7853954b4e3SArnd Bergmann 		reg = rt2x00mmio_register_read(rt2x00dev, TXCSR0);
78633aca94dSKalle Valo 		rt2x00_set_field32(&reg, TXCSR0_ABORT, 1);
78733aca94dSKalle Valo 		rt2x00mmio_register_write(rt2x00dev, TXCSR0, reg);
78833aca94dSKalle Valo 		break;
78933aca94dSKalle Valo 	case QID_RX:
7903954b4e3SArnd Bergmann 		reg = rt2x00mmio_register_read(rt2x00dev, RXCSR0);
79133aca94dSKalle Valo 		rt2x00_set_field32(&reg, RXCSR0_DISABLE_RX, 1);
79233aca94dSKalle Valo 		rt2x00mmio_register_write(rt2x00dev, RXCSR0, reg);
79333aca94dSKalle Valo 		break;
79433aca94dSKalle Valo 	case QID_BEACON:
7953954b4e3SArnd Bergmann 		reg = rt2x00mmio_register_read(rt2x00dev, CSR14);
79633aca94dSKalle Valo 		rt2x00_set_field32(&reg, CSR14_TSF_COUNT, 0);
79733aca94dSKalle Valo 		rt2x00_set_field32(&reg, CSR14_TBCN, 0);
79833aca94dSKalle Valo 		rt2x00_set_field32(&reg, CSR14_BEACON_GEN, 0);
79933aca94dSKalle Valo 		rt2x00mmio_register_write(rt2x00dev, CSR14, reg);
80033aca94dSKalle Valo 
80133aca94dSKalle Valo 		/*
80233aca94dSKalle Valo 		 * Wait for possibly running tbtt tasklets.
80333aca94dSKalle Valo 		 */
80433aca94dSKalle Valo 		tasklet_kill(&rt2x00dev->tbtt_tasklet);
80533aca94dSKalle Valo 		break;
80633aca94dSKalle Valo 	default:
80733aca94dSKalle Valo 		break;
80833aca94dSKalle Valo 	}
80933aca94dSKalle Valo }
81033aca94dSKalle Valo 
81133aca94dSKalle Valo /*
81233aca94dSKalle Valo  * Initialization functions.
81333aca94dSKalle Valo  */
81433aca94dSKalle Valo static bool rt2500pci_get_entry_state(struct queue_entry *entry)
81533aca94dSKalle Valo {
81633aca94dSKalle Valo 	struct queue_entry_priv_mmio *entry_priv = entry->priv_data;
81733aca94dSKalle Valo 	u32 word;
81833aca94dSKalle Valo 
81933aca94dSKalle Valo 	if (entry->queue->qid == QID_RX) {
82033aca94dSKalle Valo 		rt2x00_desc_read(entry_priv->desc, 0, &word);
82133aca94dSKalle Valo 
82233aca94dSKalle Valo 		return rt2x00_get_field32(word, RXD_W0_OWNER_NIC);
82333aca94dSKalle Valo 	} else {
82433aca94dSKalle Valo 		rt2x00_desc_read(entry_priv->desc, 0, &word);
82533aca94dSKalle Valo 
82633aca94dSKalle Valo 		return (rt2x00_get_field32(word, TXD_W0_OWNER_NIC) ||
82733aca94dSKalle Valo 		        rt2x00_get_field32(word, TXD_W0_VALID));
82833aca94dSKalle Valo 	}
82933aca94dSKalle Valo }
83033aca94dSKalle Valo 
83133aca94dSKalle Valo static void rt2500pci_clear_entry(struct queue_entry *entry)
83233aca94dSKalle Valo {
83333aca94dSKalle Valo 	struct queue_entry_priv_mmio *entry_priv = entry->priv_data;
83433aca94dSKalle Valo 	struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb);
83533aca94dSKalle Valo 	u32 word;
83633aca94dSKalle Valo 
83733aca94dSKalle Valo 	if (entry->queue->qid == QID_RX) {
83833aca94dSKalle Valo 		rt2x00_desc_read(entry_priv->desc, 1, &word);
83933aca94dSKalle Valo 		rt2x00_set_field32(&word, RXD_W1_BUFFER_ADDRESS, skbdesc->skb_dma);
84033aca94dSKalle Valo 		rt2x00_desc_write(entry_priv->desc, 1, word);
84133aca94dSKalle Valo 
84233aca94dSKalle Valo 		rt2x00_desc_read(entry_priv->desc, 0, &word);
84333aca94dSKalle Valo 		rt2x00_set_field32(&word, RXD_W0_OWNER_NIC, 1);
84433aca94dSKalle Valo 		rt2x00_desc_write(entry_priv->desc, 0, word);
84533aca94dSKalle Valo 	} else {
84633aca94dSKalle Valo 		rt2x00_desc_read(entry_priv->desc, 0, &word);
84733aca94dSKalle Valo 		rt2x00_set_field32(&word, TXD_W0_VALID, 0);
84833aca94dSKalle Valo 		rt2x00_set_field32(&word, TXD_W0_OWNER_NIC, 0);
84933aca94dSKalle Valo 		rt2x00_desc_write(entry_priv->desc, 0, word);
85033aca94dSKalle Valo 	}
85133aca94dSKalle Valo }
85233aca94dSKalle Valo 
85333aca94dSKalle Valo static int rt2500pci_init_queues(struct rt2x00_dev *rt2x00dev)
85433aca94dSKalle Valo {
85533aca94dSKalle Valo 	struct queue_entry_priv_mmio *entry_priv;
85633aca94dSKalle Valo 	u32 reg;
85733aca94dSKalle Valo 
85833aca94dSKalle Valo 	/*
85933aca94dSKalle Valo 	 * Initialize registers.
86033aca94dSKalle Valo 	 */
8613954b4e3SArnd Bergmann 	reg = rt2x00mmio_register_read(rt2x00dev, TXCSR2);
86233aca94dSKalle Valo 	rt2x00_set_field32(&reg, TXCSR2_TXD_SIZE, rt2x00dev->tx[0].desc_size);
86333aca94dSKalle Valo 	rt2x00_set_field32(&reg, TXCSR2_NUM_TXD, rt2x00dev->tx[1].limit);
86433aca94dSKalle Valo 	rt2x00_set_field32(&reg, TXCSR2_NUM_ATIM, rt2x00dev->atim->limit);
86533aca94dSKalle Valo 	rt2x00_set_field32(&reg, TXCSR2_NUM_PRIO, rt2x00dev->tx[0].limit);
86633aca94dSKalle Valo 	rt2x00mmio_register_write(rt2x00dev, TXCSR2, reg);
86733aca94dSKalle Valo 
86833aca94dSKalle Valo 	entry_priv = rt2x00dev->tx[1].entries[0].priv_data;
8693954b4e3SArnd Bergmann 	reg = rt2x00mmio_register_read(rt2x00dev, TXCSR3);
87033aca94dSKalle Valo 	rt2x00_set_field32(&reg, TXCSR3_TX_RING_REGISTER,
87133aca94dSKalle Valo 			   entry_priv->desc_dma);
87233aca94dSKalle Valo 	rt2x00mmio_register_write(rt2x00dev, TXCSR3, reg);
87333aca94dSKalle Valo 
87433aca94dSKalle Valo 	entry_priv = rt2x00dev->tx[0].entries[0].priv_data;
8753954b4e3SArnd Bergmann 	reg = rt2x00mmio_register_read(rt2x00dev, TXCSR5);
87633aca94dSKalle Valo 	rt2x00_set_field32(&reg, TXCSR5_PRIO_RING_REGISTER,
87733aca94dSKalle Valo 			   entry_priv->desc_dma);
87833aca94dSKalle Valo 	rt2x00mmio_register_write(rt2x00dev, TXCSR5, reg);
87933aca94dSKalle Valo 
88033aca94dSKalle Valo 	entry_priv = rt2x00dev->atim->entries[0].priv_data;
8813954b4e3SArnd Bergmann 	reg = rt2x00mmio_register_read(rt2x00dev, TXCSR4);
88233aca94dSKalle Valo 	rt2x00_set_field32(&reg, TXCSR4_ATIM_RING_REGISTER,
88333aca94dSKalle Valo 			   entry_priv->desc_dma);
88433aca94dSKalle Valo 	rt2x00mmio_register_write(rt2x00dev, TXCSR4, reg);
88533aca94dSKalle Valo 
88633aca94dSKalle Valo 	entry_priv = rt2x00dev->bcn->entries[0].priv_data;
8873954b4e3SArnd Bergmann 	reg = rt2x00mmio_register_read(rt2x00dev, TXCSR6);
88833aca94dSKalle Valo 	rt2x00_set_field32(&reg, TXCSR6_BEACON_RING_REGISTER,
88933aca94dSKalle Valo 			   entry_priv->desc_dma);
89033aca94dSKalle Valo 	rt2x00mmio_register_write(rt2x00dev, TXCSR6, reg);
89133aca94dSKalle Valo 
8923954b4e3SArnd Bergmann 	reg = rt2x00mmio_register_read(rt2x00dev, RXCSR1);
89333aca94dSKalle Valo 	rt2x00_set_field32(&reg, RXCSR1_RXD_SIZE, rt2x00dev->rx->desc_size);
89433aca94dSKalle Valo 	rt2x00_set_field32(&reg, RXCSR1_NUM_RXD, rt2x00dev->rx->limit);
89533aca94dSKalle Valo 	rt2x00mmio_register_write(rt2x00dev, RXCSR1, reg);
89633aca94dSKalle Valo 
89733aca94dSKalle Valo 	entry_priv = rt2x00dev->rx->entries[0].priv_data;
8983954b4e3SArnd Bergmann 	reg = rt2x00mmio_register_read(rt2x00dev, RXCSR2);
89933aca94dSKalle Valo 	rt2x00_set_field32(&reg, RXCSR2_RX_RING_REGISTER,
90033aca94dSKalle Valo 			   entry_priv->desc_dma);
90133aca94dSKalle Valo 	rt2x00mmio_register_write(rt2x00dev, RXCSR2, reg);
90233aca94dSKalle Valo 
90333aca94dSKalle Valo 	return 0;
90433aca94dSKalle Valo }
90533aca94dSKalle Valo 
90633aca94dSKalle Valo static int rt2500pci_init_registers(struct rt2x00_dev *rt2x00dev)
90733aca94dSKalle Valo {
90833aca94dSKalle Valo 	u32 reg;
90933aca94dSKalle Valo 
91033aca94dSKalle Valo 	rt2x00mmio_register_write(rt2x00dev, PSCSR0, 0x00020002);
91133aca94dSKalle Valo 	rt2x00mmio_register_write(rt2x00dev, PSCSR1, 0x00000002);
91233aca94dSKalle Valo 	rt2x00mmio_register_write(rt2x00dev, PSCSR2, 0x00020002);
91333aca94dSKalle Valo 	rt2x00mmio_register_write(rt2x00dev, PSCSR3, 0x00000002);
91433aca94dSKalle Valo 
9153954b4e3SArnd Bergmann 	reg = rt2x00mmio_register_read(rt2x00dev, TIMECSR);
91633aca94dSKalle Valo 	rt2x00_set_field32(&reg, TIMECSR_US_COUNT, 33);
91733aca94dSKalle Valo 	rt2x00_set_field32(&reg, TIMECSR_US_64_COUNT, 63);
91833aca94dSKalle Valo 	rt2x00_set_field32(&reg, TIMECSR_BEACON_EXPECT, 0);
91933aca94dSKalle Valo 	rt2x00mmio_register_write(rt2x00dev, TIMECSR, reg);
92033aca94dSKalle Valo 
9213954b4e3SArnd Bergmann 	reg = rt2x00mmio_register_read(rt2x00dev, CSR9);
92233aca94dSKalle Valo 	rt2x00_set_field32(&reg, CSR9_MAX_FRAME_UNIT,
92333aca94dSKalle Valo 			   rt2x00dev->rx->data_size / 128);
92433aca94dSKalle Valo 	rt2x00mmio_register_write(rt2x00dev, CSR9, reg);
92533aca94dSKalle Valo 
92633aca94dSKalle Valo 	/*
92733aca94dSKalle Valo 	 * Always use CWmin and CWmax set in descriptor.
92833aca94dSKalle Valo 	 */
9293954b4e3SArnd Bergmann 	reg = rt2x00mmio_register_read(rt2x00dev, CSR11);
93033aca94dSKalle Valo 	rt2x00_set_field32(&reg, CSR11_CW_SELECT, 0);
93133aca94dSKalle Valo 	rt2x00mmio_register_write(rt2x00dev, CSR11, reg);
93233aca94dSKalle Valo 
9333954b4e3SArnd Bergmann 	reg = rt2x00mmio_register_read(rt2x00dev, CSR14);
93433aca94dSKalle Valo 	rt2x00_set_field32(&reg, CSR14_TSF_COUNT, 0);
93533aca94dSKalle Valo 	rt2x00_set_field32(&reg, CSR14_TSF_SYNC, 0);
93633aca94dSKalle Valo 	rt2x00_set_field32(&reg, CSR14_TBCN, 0);
93733aca94dSKalle Valo 	rt2x00_set_field32(&reg, CSR14_TCFP, 0);
93833aca94dSKalle Valo 	rt2x00_set_field32(&reg, CSR14_TATIMW, 0);
93933aca94dSKalle Valo 	rt2x00_set_field32(&reg, CSR14_BEACON_GEN, 0);
94033aca94dSKalle Valo 	rt2x00_set_field32(&reg, CSR14_CFP_COUNT_PRELOAD, 0);
94133aca94dSKalle Valo 	rt2x00_set_field32(&reg, CSR14_TBCM_PRELOAD, 0);
94233aca94dSKalle Valo 	rt2x00mmio_register_write(rt2x00dev, CSR14, reg);
94333aca94dSKalle Valo 
94433aca94dSKalle Valo 	rt2x00mmio_register_write(rt2x00dev, CNT3, 0);
94533aca94dSKalle Valo 
9463954b4e3SArnd Bergmann 	reg = rt2x00mmio_register_read(rt2x00dev, TXCSR8);
94733aca94dSKalle Valo 	rt2x00_set_field32(&reg, TXCSR8_BBP_ID0, 10);
94833aca94dSKalle Valo 	rt2x00_set_field32(&reg, TXCSR8_BBP_ID0_VALID, 1);
94933aca94dSKalle Valo 	rt2x00_set_field32(&reg, TXCSR8_BBP_ID1, 11);
95033aca94dSKalle Valo 	rt2x00_set_field32(&reg, TXCSR8_BBP_ID1_VALID, 1);
95133aca94dSKalle Valo 	rt2x00_set_field32(&reg, TXCSR8_BBP_ID2, 13);
95233aca94dSKalle Valo 	rt2x00_set_field32(&reg, TXCSR8_BBP_ID2_VALID, 1);
95333aca94dSKalle Valo 	rt2x00_set_field32(&reg, TXCSR8_BBP_ID3, 12);
95433aca94dSKalle Valo 	rt2x00_set_field32(&reg, TXCSR8_BBP_ID3_VALID, 1);
95533aca94dSKalle Valo 	rt2x00mmio_register_write(rt2x00dev, TXCSR8, reg);
95633aca94dSKalle Valo 
9573954b4e3SArnd Bergmann 	reg = rt2x00mmio_register_read(rt2x00dev, ARTCSR0);
95833aca94dSKalle Valo 	rt2x00_set_field32(&reg, ARTCSR0_ACK_CTS_1MBS, 112);
95933aca94dSKalle Valo 	rt2x00_set_field32(&reg, ARTCSR0_ACK_CTS_2MBS, 56);
96033aca94dSKalle Valo 	rt2x00_set_field32(&reg, ARTCSR0_ACK_CTS_5_5MBS, 20);
96133aca94dSKalle Valo 	rt2x00_set_field32(&reg, ARTCSR0_ACK_CTS_11MBS, 10);
96233aca94dSKalle Valo 	rt2x00mmio_register_write(rt2x00dev, ARTCSR0, reg);
96333aca94dSKalle Valo 
9643954b4e3SArnd Bergmann 	reg = rt2x00mmio_register_read(rt2x00dev, ARTCSR1);
96533aca94dSKalle Valo 	rt2x00_set_field32(&reg, ARTCSR1_ACK_CTS_6MBS, 45);
96633aca94dSKalle Valo 	rt2x00_set_field32(&reg, ARTCSR1_ACK_CTS_9MBS, 37);
96733aca94dSKalle Valo 	rt2x00_set_field32(&reg, ARTCSR1_ACK_CTS_12MBS, 33);
96833aca94dSKalle Valo 	rt2x00_set_field32(&reg, ARTCSR1_ACK_CTS_18MBS, 29);
96933aca94dSKalle Valo 	rt2x00mmio_register_write(rt2x00dev, ARTCSR1, reg);
97033aca94dSKalle Valo 
9713954b4e3SArnd Bergmann 	reg = rt2x00mmio_register_read(rt2x00dev, ARTCSR2);
97233aca94dSKalle Valo 	rt2x00_set_field32(&reg, ARTCSR2_ACK_CTS_24MBS, 29);
97333aca94dSKalle Valo 	rt2x00_set_field32(&reg, ARTCSR2_ACK_CTS_36MBS, 25);
97433aca94dSKalle Valo 	rt2x00_set_field32(&reg, ARTCSR2_ACK_CTS_48MBS, 25);
97533aca94dSKalle Valo 	rt2x00_set_field32(&reg, ARTCSR2_ACK_CTS_54MBS, 25);
97633aca94dSKalle Valo 	rt2x00mmio_register_write(rt2x00dev, ARTCSR2, reg);
97733aca94dSKalle Valo 
9783954b4e3SArnd Bergmann 	reg = rt2x00mmio_register_read(rt2x00dev, RXCSR3);
97933aca94dSKalle Valo 	rt2x00_set_field32(&reg, RXCSR3_BBP_ID0, 47); /* CCK Signal */
98033aca94dSKalle Valo 	rt2x00_set_field32(&reg, RXCSR3_BBP_ID0_VALID, 1);
98133aca94dSKalle Valo 	rt2x00_set_field32(&reg, RXCSR3_BBP_ID1, 51); /* Rssi */
98233aca94dSKalle Valo 	rt2x00_set_field32(&reg, RXCSR3_BBP_ID1_VALID, 1);
98333aca94dSKalle Valo 	rt2x00_set_field32(&reg, RXCSR3_BBP_ID2, 42); /* OFDM Rate */
98433aca94dSKalle Valo 	rt2x00_set_field32(&reg, RXCSR3_BBP_ID2_VALID, 1);
98533aca94dSKalle Valo 	rt2x00_set_field32(&reg, RXCSR3_BBP_ID3, 51); /* RSSI */
98633aca94dSKalle Valo 	rt2x00_set_field32(&reg, RXCSR3_BBP_ID3_VALID, 1);
98733aca94dSKalle Valo 	rt2x00mmio_register_write(rt2x00dev, RXCSR3, reg);
98833aca94dSKalle Valo 
9893954b4e3SArnd Bergmann 	reg = rt2x00mmio_register_read(rt2x00dev, PCICSR);
99033aca94dSKalle Valo 	rt2x00_set_field32(&reg, PCICSR_BIG_ENDIAN, 0);
99133aca94dSKalle Valo 	rt2x00_set_field32(&reg, PCICSR_RX_TRESHOLD, 0);
99233aca94dSKalle Valo 	rt2x00_set_field32(&reg, PCICSR_TX_TRESHOLD, 3);
99333aca94dSKalle Valo 	rt2x00_set_field32(&reg, PCICSR_BURST_LENTH, 1);
99433aca94dSKalle Valo 	rt2x00_set_field32(&reg, PCICSR_ENABLE_CLK, 1);
99533aca94dSKalle Valo 	rt2x00_set_field32(&reg, PCICSR_READ_MULTIPLE, 1);
99633aca94dSKalle Valo 	rt2x00_set_field32(&reg, PCICSR_WRITE_INVALID, 1);
99733aca94dSKalle Valo 	rt2x00mmio_register_write(rt2x00dev, PCICSR, reg);
99833aca94dSKalle Valo 
99933aca94dSKalle Valo 	rt2x00mmio_register_write(rt2x00dev, PWRCSR0, 0x3f3b3100);
100033aca94dSKalle Valo 
100133aca94dSKalle Valo 	rt2x00mmio_register_write(rt2x00dev, GPIOCSR, 0x0000ff00);
100233aca94dSKalle Valo 	rt2x00mmio_register_write(rt2x00dev, TESTCSR, 0x000000f0);
100333aca94dSKalle Valo 
100433aca94dSKalle Valo 	if (rt2x00dev->ops->lib->set_device_state(rt2x00dev, STATE_AWAKE))
100533aca94dSKalle Valo 		return -EBUSY;
100633aca94dSKalle Valo 
100733aca94dSKalle Valo 	rt2x00mmio_register_write(rt2x00dev, MACCSR0, 0x00213223);
100833aca94dSKalle Valo 	rt2x00mmio_register_write(rt2x00dev, MACCSR1, 0x00235518);
100933aca94dSKalle Valo 
10103954b4e3SArnd Bergmann 	reg = rt2x00mmio_register_read(rt2x00dev, MACCSR2);
101133aca94dSKalle Valo 	rt2x00_set_field32(&reg, MACCSR2_DELAY, 64);
101233aca94dSKalle Valo 	rt2x00mmio_register_write(rt2x00dev, MACCSR2, reg);
101333aca94dSKalle Valo 
10143954b4e3SArnd Bergmann 	reg = rt2x00mmio_register_read(rt2x00dev, RALINKCSR);
101533aca94dSKalle Valo 	rt2x00_set_field32(&reg, RALINKCSR_AR_BBP_DATA0, 17);
101633aca94dSKalle Valo 	rt2x00_set_field32(&reg, RALINKCSR_AR_BBP_ID0, 26);
101733aca94dSKalle Valo 	rt2x00_set_field32(&reg, RALINKCSR_AR_BBP_VALID0, 1);
101833aca94dSKalle Valo 	rt2x00_set_field32(&reg, RALINKCSR_AR_BBP_DATA1, 0);
101933aca94dSKalle Valo 	rt2x00_set_field32(&reg, RALINKCSR_AR_BBP_ID1, 26);
102033aca94dSKalle Valo 	rt2x00_set_field32(&reg, RALINKCSR_AR_BBP_VALID1, 1);
102133aca94dSKalle Valo 	rt2x00mmio_register_write(rt2x00dev, RALINKCSR, reg);
102233aca94dSKalle Valo 
102333aca94dSKalle Valo 	rt2x00mmio_register_write(rt2x00dev, BBPCSR1, 0x82188200);
102433aca94dSKalle Valo 
102533aca94dSKalle Valo 	rt2x00mmio_register_write(rt2x00dev, TXACKCSR0, 0x00000020);
102633aca94dSKalle Valo 
10273954b4e3SArnd Bergmann 	reg = rt2x00mmio_register_read(rt2x00dev, CSR1);
102833aca94dSKalle Valo 	rt2x00_set_field32(&reg, CSR1_SOFT_RESET, 1);
102933aca94dSKalle Valo 	rt2x00_set_field32(&reg, CSR1_BBP_RESET, 0);
103033aca94dSKalle Valo 	rt2x00_set_field32(&reg, CSR1_HOST_READY, 0);
103133aca94dSKalle Valo 	rt2x00mmio_register_write(rt2x00dev, CSR1, reg);
103233aca94dSKalle Valo 
10333954b4e3SArnd Bergmann 	reg = rt2x00mmio_register_read(rt2x00dev, CSR1);
103433aca94dSKalle Valo 	rt2x00_set_field32(&reg, CSR1_SOFT_RESET, 0);
103533aca94dSKalle Valo 	rt2x00_set_field32(&reg, CSR1_HOST_READY, 1);
103633aca94dSKalle Valo 	rt2x00mmio_register_write(rt2x00dev, CSR1, reg);
103733aca94dSKalle Valo 
103833aca94dSKalle Valo 	/*
103933aca94dSKalle Valo 	 * We must clear the FCS and FIFO error count.
104033aca94dSKalle Valo 	 * These registers are cleared on read,
104133aca94dSKalle Valo 	 * so we may pass a useless variable to store the value.
104233aca94dSKalle Valo 	 */
10433954b4e3SArnd Bergmann 	reg = rt2x00mmio_register_read(rt2x00dev, CNT0);
10443954b4e3SArnd Bergmann 	reg = rt2x00mmio_register_read(rt2x00dev, CNT4);
104533aca94dSKalle Valo 
104633aca94dSKalle Valo 	return 0;
104733aca94dSKalle Valo }
104833aca94dSKalle Valo 
104933aca94dSKalle Valo static int rt2500pci_wait_bbp_ready(struct rt2x00_dev *rt2x00dev)
105033aca94dSKalle Valo {
105133aca94dSKalle Valo 	unsigned int i;
105233aca94dSKalle Valo 	u8 value;
105333aca94dSKalle Valo 
105433aca94dSKalle Valo 	for (i = 0; i < REGISTER_BUSY_COUNT; i++) {
10555fbbe378SArnd Bergmann 		value = rt2500pci_bbp_read(rt2x00dev, 0);
105633aca94dSKalle Valo 		if ((value != 0xff) && (value != 0x00))
105733aca94dSKalle Valo 			return 0;
105833aca94dSKalle Valo 		udelay(REGISTER_BUSY_DELAY);
105933aca94dSKalle Valo 	}
106033aca94dSKalle Valo 
106133aca94dSKalle Valo 	rt2x00_err(rt2x00dev, "BBP register access failed, aborting\n");
106233aca94dSKalle Valo 	return -EACCES;
106333aca94dSKalle Valo }
106433aca94dSKalle Valo 
106533aca94dSKalle Valo static int rt2500pci_init_bbp(struct rt2x00_dev *rt2x00dev)
106633aca94dSKalle Valo {
106733aca94dSKalle Valo 	unsigned int i;
106833aca94dSKalle Valo 	u16 eeprom;
106933aca94dSKalle Valo 	u8 reg_id;
107033aca94dSKalle Valo 	u8 value;
107133aca94dSKalle Valo 
107233aca94dSKalle Valo 	if (unlikely(rt2500pci_wait_bbp_ready(rt2x00dev)))
107333aca94dSKalle Valo 		return -EACCES;
107433aca94dSKalle Valo 
107533aca94dSKalle Valo 	rt2500pci_bbp_write(rt2x00dev, 3, 0x02);
107633aca94dSKalle Valo 	rt2500pci_bbp_write(rt2x00dev, 4, 0x19);
107733aca94dSKalle Valo 	rt2500pci_bbp_write(rt2x00dev, 14, 0x1c);
107833aca94dSKalle Valo 	rt2500pci_bbp_write(rt2x00dev, 15, 0x30);
107933aca94dSKalle Valo 	rt2500pci_bbp_write(rt2x00dev, 16, 0xac);
108033aca94dSKalle Valo 	rt2500pci_bbp_write(rt2x00dev, 18, 0x18);
108133aca94dSKalle Valo 	rt2500pci_bbp_write(rt2x00dev, 19, 0xff);
108233aca94dSKalle Valo 	rt2500pci_bbp_write(rt2x00dev, 20, 0x1e);
108333aca94dSKalle Valo 	rt2500pci_bbp_write(rt2x00dev, 21, 0x08);
108433aca94dSKalle Valo 	rt2500pci_bbp_write(rt2x00dev, 22, 0x08);
108533aca94dSKalle Valo 	rt2500pci_bbp_write(rt2x00dev, 23, 0x08);
108633aca94dSKalle Valo 	rt2500pci_bbp_write(rt2x00dev, 24, 0x70);
108733aca94dSKalle Valo 	rt2500pci_bbp_write(rt2x00dev, 25, 0x40);
108833aca94dSKalle Valo 	rt2500pci_bbp_write(rt2x00dev, 26, 0x08);
108933aca94dSKalle Valo 	rt2500pci_bbp_write(rt2x00dev, 27, 0x23);
109033aca94dSKalle Valo 	rt2500pci_bbp_write(rt2x00dev, 30, 0x10);
109133aca94dSKalle Valo 	rt2500pci_bbp_write(rt2x00dev, 31, 0x2b);
109233aca94dSKalle Valo 	rt2500pci_bbp_write(rt2x00dev, 32, 0xb9);
109333aca94dSKalle Valo 	rt2500pci_bbp_write(rt2x00dev, 34, 0x12);
109433aca94dSKalle Valo 	rt2500pci_bbp_write(rt2x00dev, 35, 0x50);
109533aca94dSKalle Valo 	rt2500pci_bbp_write(rt2x00dev, 39, 0xc4);
109633aca94dSKalle Valo 	rt2500pci_bbp_write(rt2x00dev, 40, 0x02);
109733aca94dSKalle Valo 	rt2500pci_bbp_write(rt2x00dev, 41, 0x60);
109833aca94dSKalle Valo 	rt2500pci_bbp_write(rt2x00dev, 53, 0x10);
109933aca94dSKalle Valo 	rt2500pci_bbp_write(rt2x00dev, 54, 0x18);
110033aca94dSKalle Valo 	rt2500pci_bbp_write(rt2x00dev, 56, 0x08);
110133aca94dSKalle Valo 	rt2500pci_bbp_write(rt2x00dev, 57, 0x10);
110233aca94dSKalle Valo 	rt2500pci_bbp_write(rt2x00dev, 58, 0x08);
110333aca94dSKalle Valo 	rt2500pci_bbp_write(rt2x00dev, 61, 0x6d);
110433aca94dSKalle Valo 	rt2500pci_bbp_write(rt2x00dev, 62, 0x10);
110533aca94dSKalle Valo 
110633aca94dSKalle Valo 	for (i = 0; i < EEPROM_BBP_SIZE; i++) {
1107*38651683SArnd Bergmann 		eeprom = rt2x00_eeprom_read(rt2x00dev, EEPROM_BBP_START + i);
110833aca94dSKalle Valo 
110933aca94dSKalle Valo 		if (eeprom != 0xffff && eeprom != 0x0000) {
111033aca94dSKalle Valo 			reg_id = rt2x00_get_field16(eeprom, EEPROM_BBP_REG_ID);
111133aca94dSKalle Valo 			value = rt2x00_get_field16(eeprom, EEPROM_BBP_VALUE);
111233aca94dSKalle Valo 			rt2500pci_bbp_write(rt2x00dev, reg_id, value);
111333aca94dSKalle Valo 		}
111433aca94dSKalle Valo 	}
111533aca94dSKalle Valo 
111633aca94dSKalle Valo 	return 0;
111733aca94dSKalle Valo }
111833aca94dSKalle Valo 
111933aca94dSKalle Valo /*
112033aca94dSKalle Valo  * Device state switch handlers.
112133aca94dSKalle Valo  */
112233aca94dSKalle Valo static void rt2500pci_toggle_irq(struct rt2x00_dev *rt2x00dev,
112333aca94dSKalle Valo 				 enum dev_state state)
112433aca94dSKalle Valo {
112533aca94dSKalle Valo 	int mask = (state == STATE_RADIO_IRQ_OFF);
112633aca94dSKalle Valo 	u32 reg;
112733aca94dSKalle Valo 	unsigned long flags;
112833aca94dSKalle Valo 
112933aca94dSKalle Valo 	/*
113033aca94dSKalle Valo 	 * When interrupts are being enabled, the interrupt registers
113133aca94dSKalle Valo 	 * should clear the register to assure a clean state.
113233aca94dSKalle Valo 	 */
113333aca94dSKalle Valo 	if (state == STATE_RADIO_IRQ_ON) {
11343954b4e3SArnd Bergmann 		reg = rt2x00mmio_register_read(rt2x00dev, CSR7);
113533aca94dSKalle Valo 		rt2x00mmio_register_write(rt2x00dev, CSR7, reg);
113633aca94dSKalle Valo 	}
113733aca94dSKalle Valo 
113833aca94dSKalle Valo 	/*
113933aca94dSKalle Valo 	 * Only toggle the interrupts bits we are going to use.
114033aca94dSKalle Valo 	 * Non-checked interrupt bits are disabled by default.
114133aca94dSKalle Valo 	 */
114233aca94dSKalle Valo 	spin_lock_irqsave(&rt2x00dev->irqmask_lock, flags);
114333aca94dSKalle Valo 
11443954b4e3SArnd Bergmann 	reg = rt2x00mmio_register_read(rt2x00dev, CSR8);
114533aca94dSKalle Valo 	rt2x00_set_field32(&reg, CSR8_TBCN_EXPIRE, mask);
114633aca94dSKalle Valo 	rt2x00_set_field32(&reg, CSR8_TXDONE_TXRING, mask);
114733aca94dSKalle Valo 	rt2x00_set_field32(&reg, CSR8_TXDONE_ATIMRING, mask);
114833aca94dSKalle Valo 	rt2x00_set_field32(&reg, CSR8_TXDONE_PRIORING, mask);
114933aca94dSKalle Valo 	rt2x00_set_field32(&reg, CSR8_RXDONE, mask);
115033aca94dSKalle Valo 	rt2x00mmio_register_write(rt2x00dev, CSR8, reg);
115133aca94dSKalle Valo 
115233aca94dSKalle Valo 	spin_unlock_irqrestore(&rt2x00dev->irqmask_lock, flags);
115333aca94dSKalle Valo 
115433aca94dSKalle Valo 	if (state == STATE_RADIO_IRQ_OFF) {
115533aca94dSKalle Valo 		/*
115633aca94dSKalle Valo 		 * Ensure that all tasklets are finished.
115733aca94dSKalle Valo 		 */
115833aca94dSKalle Valo 		tasklet_kill(&rt2x00dev->txstatus_tasklet);
115933aca94dSKalle Valo 		tasklet_kill(&rt2x00dev->rxdone_tasklet);
116033aca94dSKalle Valo 		tasklet_kill(&rt2x00dev->tbtt_tasklet);
116133aca94dSKalle Valo 	}
116233aca94dSKalle Valo }
116333aca94dSKalle Valo 
116433aca94dSKalle Valo static int rt2500pci_enable_radio(struct rt2x00_dev *rt2x00dev)
116533aca94dSKalle Valo {
116633aca94dSKalle Valo 	/*
116733aca94dSKalle Valo 	 * Initialize all registers.
116833aca94dSKalle Valo 	 */
116933aca94dSKalle Valo 	if (unlikely(rt2500pci_init_queues(rt2x00dev) ||
117033aca94dSKalle Valo 		     rt2500pci_init_registers(rt2x00dev) ||
117133aca94dSKalle Valo 		     rt2500pci_init_bbp(rt2x00dev)))
117233aca94dSKalle Valo 		return -EIO;
117333aca94dSKalle Valo 
117433aca94dSKalle Valo 	return 0;
117533aca94dSKalle Valo }
117633aca94dSKalle Valo 
117733aca94dSKalle Valo static void rt2500pci_disable_radio(struct rt2x00_dev *rt2x00dev)
117833aca94dSKalle Valo {
117933aca94dSKalle Valo 	/*
118033aca94dSKalle Valo 	 * Disable power
118133aca94dSKalle Valo 	 */
118233aca94dSKalle Valo 	rt2x00mmio_register_write(rt2x00dev, PWRCSR0, 0);
118333aca94dSKalle Valo }
118433aca94dSKalle Valo 
118533aca94dSKalle Valo static int rt2500pci_set_state(struct rt2x00_dev *rt2x00dev,
118633aca94dSKalle Valo 			       enum dev_state state)
118733aca94dSKalle Valo {
118833aca94dSKalle Valo 	u32 reg, reg2;
118933aca94dSKalle Valo 	unsigned int i;
119033aca94dSKalle Valo 	char put_to_sleep;
119133aca94dSKalle Valo 	char bbp_state;
119233aca94dSKalle Valo 	char rf_state;
119333aca94dSKalle Valo 
119433aca94dSKalle Valo 	put_to_sleep = (state != STATE_AWAKE);
119533aca94dSKalle Valo 
11963954b4e3SArnd Bergmann 	reg = rt2x00mmio_register_read(rt2x00dev, PWRCSR1);
119733aca94dSKalle Valo 	rt2x00_set_field32(&reg, PWRCSR1_SET_STATE, 1);
119833aca94dSKalle Valo 	rt2x00_set_field32(&reg, PWRCSR1_BBP_DESIRE_STATE, state);
119933aca94dSKalle Valo 	rt2x00_set_field32(&reg, PWRCSR1_RF_DESIRE_STATE, state);
120033aca94dSKalle Valo 	rt2x00_set_field32(&reg, PWRCSR1_PUT_TO_SLEEP, put_to_sleep);
120133aca94dSKalle Valo 	rt2x00mmio_register_write(rt2x00dev, PWRCSR1, reg);
120233aca94dSKalle Valo 
120333aca94dSKalle Valo 	/*
120433aca94dSKalle Valo 	 * Device is not guaranteed to be in the requested state yet.
120533aca94dSKalle Valo 	 * We must wait until the register indicates that the
120633aca94dSKalle Valo 	 * device has entered the correct state.
120733aca94dSKalle Valo 	 */
120833aca94dSKalle Valo 	for (i = 0; i < REGISTER_BUSY_COUNT; i++) {
12093954b4e3SArnd Bergmann 		reg2 = rt2x00mmio_register_read(rt2x00dev, PWRCSR1);
121033aca94dSKalle Valo 		bbp_state = rt2x00_get_field32(reg2, PWRCSR1_BBP_CURR_STATE);
121133aca94dSKalle Valo 		rf_state = rt2x00_get_field32(reg2, PWRCSR1_RF_CURR_STATE);
121233aca94dSKalle Valo 		if (bbp_state == state && rf_state == state)
121333aca94dSKalle Valo 			return 0;
121433aca94dSKalle Valo 		rt2x00mmio_register_write(rt2x00dev, PWRCSR1, reg);
121533aca94dSKalle Valo 		msleep(10);
121633aca94dSKalle Valo 	}
121733aca94dSKalle Valo 
121833aca94dSKalle Valo 	return -EBUSY;
121933aca94dSKalle Valo }
122033aca94dSKalle Valo 
122133aca94dSKalle Valo static int rt2500pci_set_device_state(struct rt2x00_dev *rt2x00dev,
122233aca94dSKalle Valo 				      enum dev_state state)
122333aca94dSKalle Valo {
122433aca94dSKalle Valo 	int retval = 0;
122533aca94dSKalle Valo 
122633aca94dSKalle Valo 	switch (state) {
122733aca94dSKalle Valo 	case STATE_RADIO_ON:
122833aca94dSKalle Valo 		retval = rt2500pci_enable_radio(rt2x00dev);
122933aca94dSKalle Valo 		break;
123033aca94dSKalle Valo 	case STATE_RADIO_OFF:
123133aca94dSKalle Valo 		rt2500pci_disable_radio(rt2x00dev);
123233aca94dSKalle Valo 		break;
123333aca94dSKalle Valo 	case STATE_RADIO_IRQ_ON:
123433aca94dSKalle Valo 	case STATE_RADIO_IRQ_OFF:
123533aca94dSKalle Valo 		rt2500pci_toggle_irq(rt2x00dev, state);
123633aca94dSKalle Valo 		break;
123733aca94dSKalle Valo 	case STATE_DEEP_SLEEP:
123833aca94dSKalle Valo 	case STATE_SLEEP:
123933aca94dSKalle Valo 	case STATE_STANDBY:
124033aca94dSKalle Valo 	case STATE_AWAKE:
124133aca94dSKalle Valo 		retval = rt2500pci_set_state(rt2x00dev, state);
124233aca94dSKalle Valo 		break;
124333aca94dSKalle Valo 	default:
124433aca94dSKalle Valo 		retval = -ENOTSUPP;
124533aca94dSKalle Valo 		break;
124633aca94dSKalle Valo 	}
124733aca94dSKalle Valo 
124833aca94dSKalle Valo 	if (unlikely(retval))
124933aca94dSKalle Valo 		rt2x00_err(rt2x00dev, "Device failed to enter state %d (%d)\n",
125033aca94dSKalle Valo 			   state, retval);
125133aca94dSKalle Valo 
125233aca94dSKalle Valo 	return retval;
125333aca94dSKalle Valo }
125433aca94dSKalle Valo 
125533aca94dSKalle Valo /*
125633aca94dSKalle Valo  * TX descriptor initialization
125733aca94dSKalle Valo  */
125833aca94dSKalle Valo static void rt2500pci_write_tx_desc(struct queue_entry *entry,
125933aca94dSKalle Valo 				    struct txentry_desc *txdesc)
126033aca94dSKalle Valo {
126133aca94dSKalle Valo 	struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb);
126233aca94dSKalle Valo 	struct queue_entry_priv_mmio *entry_priv = entry->priv_data;
126333aca94dSKalle Valo 	__le32 *txd = entry_priv->desc;
126433aca94dSKalle Valo 	u32 word;
126533aca94dSKalle Valo 
126633aca94dSKalle Valo 	/*
126733aca94dSKalle Valo 	 * Start writing the descriptor words.
126833aca94dSKalle Valo 	 */
126933aca94dSKalle Valo 	rt2x00_desc_read(txd, 1, &word);
127033aca94dSKalle Valo 	rt2x00_set_field32(&word, TXD_W1_BUFFER_ADDRESS, skbdesc->skb_dma);
127133aca94dSKalle Valo 	rt2x00_desc_write(txd, 1, word);
127233aca94dSKalle Valo 
127333aca94dSKalle Valo 	rt2x00_desc_read(txd, 2, &word);
127433aca94dSKalle Valo 	rt2x00_set_field32(&word, TXD_W2_IV_OFFSET, IEEE80211_HEADER);
127533aca94dSKalle Valo 	rt2x00_set_field32(&word, TXD_W2_AIFS, entry->queue->aifs);
127633aca94dSKalle Valo 	rt2x00_set_field32(&word, TXD_W2_CWMIN, entry->queue->cw_min);
127733aca94dSKalle Valo 	rt2x00_set_field32(&word, TXD_W2_CWMAX, entry->queue->cw_max);
127833aca94dSKalle Valo 	rt2x00_desc_write(txd, 2, word);
127933aca94dSKalle Valo 
128033aca94dSKalle Valo 	rt2x00_desc_read(txd, 3, &word);
128133aca94dSKalle Valo 	rt2x00_set_field32(&word, TXD_W3_PLCP_SIGNAL, txdesc->u.plcp.signal);
128233aca94dSKalle Valo 	rt2x00_set_field32(&word, TXD_W3_PLCP_SERVICE, txdesc->u.plcp.service);
128333aca94dSKalle Valo 	rt2x00_set_field32(&word, TXD_W3_PLCP_LENGTH_LOW,
128433aca94dSKalle Valo 			   txdesc->u.plcp.length_low);
128533aca94dSKalle Valo 	rt2x00_set_field32(&word, TXD_W3_PLCP_LENGTH_HIGH,
128633aca94dSKalle Valo 			   txdesc->u.plcp.length_high);
128733aca94dSKalle Valo 	rt2x00_desc_write(txd, 3, word);
128833aca94dSKalle Valo 
128933aca94dSKalle Valo 	rt2x00_desc_read(txd, 10, &word);
129033aca94dSKalle Valo 	rt2x00_set_field32(&word, TXD_W10_RTS,
129133aca94dSKalle Valo 			   test_bit(ENTRY_TXD_RTS_FRAME, &txdesc->flags));
129233aca94dSKalle Valo 	rt2x00_desc_write(txd, 10, word);
129333aca94dSKalle Valo 
129433aca94dSKalle Valo 	/*
129533aca94dSKalle Valo 	 * Writing TXD word 0 must the last to prevent a race condition with
129633aca94dSKalle Valo 	 * the device, whereby the device may take hold of the TXD before we
129733aca94dSKalle Valo 	 * finished updating it.
129833aca94dSKalle Valo 	 */
129933aca94dSKalle Valo 	rt2x00_desc_read(txd, 0, &word);
130033aca94dSKalle Valo 	rt2x00_set_field32(&word, TXD_W0_OWNER_NIC, 1);
130133aca94dSKalle Valo 	rt2x00_set_field32(&word, TXD_W0_VALID, 1);
130233aca94dSKalle Valo 	rt2x00_set_field32(&word, TXD_W0_MORE_FRAG,
130333aca94dSKalle Valo 			   test_bit(ENTRY_TXD_MORE_FRAG, &txdesc->flags));
130433aca94dSKalle Valo 	rt2x00_set_field32(&word, TXD_W0_ACK,
130533aca94dSKalle Valo 			   test_bit(ENTRY_TXD_ACK, &txdesc->flags));
130633aca94dSKalle Valo 	rt2x00_set_field32(&word, TXD_W0_TIMESTAMP,
130733aca94dSKalle Valo 			   test_bit(ENTRY_TXD_REQ_TIMESTAMP, &txdesc->flags));
130833aca94dSKalle Valo 	rt2x00_set_field32(&word, TXD_W0_OFDM,
130933aca94dSKalle Valo 			   (txdesc->rate_mode == RATE_MODE_OFDM));
131033aca94dSKalle Valo 	rt2x00_set_field32(&word, TXD_W0_CIPHER_OWNER, 1);
131133aca94dSKalle Valo 	rt2x00_set_field32(&word, TXD_W0_IFS, txdesc->u.plcp.ifs);
131233aca94dSKalle Valo 	rt2x00_set_field32(&word, TXD_W0_RETRY_MODE,
131333aca94dSKalle Valo 			   test_bit(ENTRY_TXD_RETRY_MODE, &txdesc->flags));
131433aca94dSKalle Valo 	rt2x00_set_field32(&word, TXD_W0_DATABYTE_COUNT, txdesc->length);
131533aca94dSKalle Valo 	rt2x00_set_field32(&word, TXD_W0_CIPHER_ALG, CIPHER_NONE);
131633aca94dSKalle Valo 	rt2x00_desc_write(txd, 0, word);
131733aca94dSKalle Valo 
131833aca94dSKalle Valo 	/*
131933aca94dSKalle Valo 	 * Register descriptor details in skb frame descriptor.
132033aca94dSKalle Valo 	 */
132133aca94dSKalle Valo 	skbdesc->desc = txd;
132233aca94dSKalle Valo 	skbdesc->desc_len = TXD_DESC_SIZE;
132333aca94dSKalle Valo }
132433aca94dSKalle Valo 
132533aca94dSKalle Valo /*
132633aca94dSKalle Valo  * TX data initialization
132733aca94dSKalle Valo  */
132833aca94dSKalle Valo static void rt2500pci_write_beacon(struct queue_entry *entry,
132933aca94dSKalle Valo 				   struct txentry_desc *txdesc)
133033aca94dSKalle Valo {
133133aca94dSKalle Valo 	struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
133233aca94dSKalle Valo 	u32 reg;
133333aca94dSKalle Valo 
133433aca94dSKalle Valo 	/*
133533aca94dSKalle Valo 	 * Disable beaconing while we are reloading the beacon data,
133633aca94dSKalle Valo 	 * otherwise we might be sending out invalid data.
133733aca94dSKalle Valo 	 */
13383954b4e3SArnd Bergmann 	reg = rt2x00mmio_register_read(rt2x00dev, CSR14);
133933aca94dSKalle Valo 	rt2x00_set_field32(&reg, CSR14_BEACON_GEN, 0);
134033aca94dSKalle Valo 	rt2x00mmio_register_write(rt2x00dev, CSR14, reg);
134133aca94dSKalle Valo 
134233aca94dSKalle Valo 	if (rt2x00queue_map_txskb(entry)) {
134333aca94dSKalle Valo 		rt2x00_err(rt2x00dev, "Fail to map beacon, aborting\n");
134433aca94dSKalle Valo 		goto out;
134533aca94dSKalle Valo 	}
134633aca94dSKalle Valo 
134733aca94dSKalle Valo 	/*
134833aca94dSKalle Valo 	 * Write the TX descriptor for the beacon.
134933aca94dSKalle Valo 	 */
135033aca94dSKalle Valo 	rt2500pci_write_tx_desc(entry, txdesc);
135133aca94dSKalle Valo 
135233aca94dSKalle Valo 	/*
135333aca94dSKalle Valo 	 * Dump beacon to userspace through debugfs.
135433aca94dSKalle Valo 	 */
13552ceb8137SStanislaw Gruszka 	rt2x00debug_dump_frame(rt2x00dev, DUMP_FRAME_BEACON, entry);
135633aca94dSKalle Valo out:
135733aca94dSKalle Valo 	/*
135833aca94dSKalle Valo 	 * Enable beaconing again.
135933aca94dSKalle Valo 	 */
136033aca94dSKalle Valo 	rt2x00_set_field32(&reg, CSR14_BEACON_GEN, 1);
136133aca94dSKalle Valo 	rt2x00mmio_register_write(rt2x00dev, CSR14, reg);
136233aca94dSKalle Valo }
136333aca94dSKalle Valo 
136433aca94dSKalle Valo /*
136533aca94dSKalle Valo  * RX control handlers
136633aca94dSKalle Valo  */
136733aca94dSKalle Valo static void rt2500pci_fill_rxdone(struct queue_entry *entry,
136833aca94dSKalle Valo 				  struct rxdone_entry_desc *rxdesc)
136933aca94dSKalle Valo {
137033aca94dSKalle Valo 	struct queue_entry_priv_mmio *entry_priv = entry->priv_data;
137133aca94dSKalle Valo 	u32 word0;
137233aca94dSKalle Valo 	u32 word2;
137333aca94dSKalle Valo 
137433aca94dSKalle Valo 	rt2x00_desc_read(entry_priv->desc, 0, &word0);
137533aca94dSKalle Valo 	rt2x00_desc_read(entry_priv->desc, 2, &word2);
137633aca94dSKalle Valo 
137733aca94dSKalle Valo 	if (rt2x00_get_field32(word0, RXD_W0_CRC_ERROR))
137833aca94dSKalle Valo 		rxdesc->flags |= RX_FLAG_FAILED_FCS_CRC;
137933aca94dSKalle Valo 	if (rt2x00_get_field32(word0, RXD_W0_PHYSICAL_ERROR))
138033aca94dSKalle Valo 		rxdesc->flags |= RX_FLAG_FAILED_PLCP_CRC;
138133aca94dSKalle Valo 
138233aca94dSKalle Valo 	/*
138333aca94dSKalle Valo 	 * Obtain the status about this packet.
138433aca94dSKalle Valo 	 * When frame was received with an OFDM bitrate,
138533aca94dSKalle Valo 	 * the signal is the PLCP value. If it was received with
138633aca94dSKalle Valo 	 * a CCK bitrate the signal is the rate in 100kbit/s.
138733aca94dSKalle Valo 	 */
138833aca94dSKalle Valo 	rxdesc->signal = rt2x00_get_field32(word2, RXD_W2_SIGNAL);
138933aca94dSKalle Valo 	rxdesc->rssi = rt2x00_get_field32(word2, RXD_W2_RSSI) -
139033aca94dSKalle Valo 	    entry->queue->rt2x00dev->rssi_offset;
139133aca94dSKalle Valo 	rxdesc->size = rt2x00_get_field32(word0, RXD_W0_DATABYTE_COUNT);
139233aca94dSKalle Valo 
139333aca94dSKalle Valo 	if (rt2x00_get_field32(word0, RXD_W0_OFDM))
139433aca94dSKalle Valo 		rxdesc->dev_flags |= RXDONE_SIGNAL_PLCP;
139533aca94dSKalle Valo 	else
139633aca94dSKalle Valo 		rxdesc->dev_flags |= RXDONE_SIGNAL_BITRATE;
139733aca94dSKalle Valo 	if (rt2x00_get_field32(word0, RXD_W0_MY_BSS))
139833aca94dSKalle Valo 		rxdesc->dev_flags |= RXDONE_MY_BSS;
139933aca94dSKalle Valo }
140033aca94dSKalle Valo 
140133aca94dSKalle Valo /*
140233aca94dSKalle Valo  * Interrupt functions.
140333aca94dSKalle Valo  */
140433aca94dSKalle Valo static void rt2500pci_txdone(struct rt2x00_dev *rt2x00dev,
140533aca94dSKalle Valo 			     const enum data_queue_qid queue_idx)
140633aca94dSKalle Valo {
140733aca94dSKalle Valo 	struct data_queue *queue = rt2x00queue_get_tx_queue(rt2x00dev, queue_idx);
140833aca94dSKalle Valo 	struct queue_entry_priv_mmio *entry_priv;
140933aca94dSKalle Valo 	struct queue_entry *entry;
141033aca94dSKalle Valo 	struct txdone_entry_desc txdesc;
141133aca94dSKalle Valo 	u32 word;
141233aca94dSKalle Valo 
141333aca94dSKalle Valo 	while (!rt2x00queue_empty(queue)) {
141433aca94dSKalle Valo 		entry = rt2x00queue_get_entry(queue, Q_INDEX_DONE);
141533aca94dSKalle Valo 		entry_priv = entry->priv_data;
141633aca94dSKalle Valo 		rt2x00_desc_read(entry_priv->desc, 0, &word);
141733aca94dSKalle Valo 
141833aca94dSKalle Valo 		if (rt2x00_get_field32(word, TXD_W0_OWNER_NIC) ||
141933aca94dSKalle Valo 		    !rt2x00_get_field32(word, TXD_W0_VALID))
142033aca94dSKalle Valo 			break;
142133aca94dSKalle Valo 
142233aca94dSKalle Valo 		/*
142333aca94dSKalle Valo 		 * Obtain the status about this packet.
142433aca94dSKalle Valo 		 */
142533aca94dSKalle Valo 		txdesc.flags = 0;
142633aca94dSKalle Valo 		switch (rt2x00_get_field32(word, TXD_W0_RESULT)) {
142733aca94dSKalle Valo 		case 0: /* Success */
142833aca94dSKalle Valo 		case 1: /* Success with retry */
142933aca94dSKalle Valo 			__set_bit(TXDONE_SUCCESS, &txdesc.flags);
143033aca94dSKalle Valo 			break;
143133aca94dSKalle Valo 		case 2: /* Failure, excessive retries */
143233aca94dSKalle Valo 			__set_bit(TXDONE_EXCESSIVE_RETRY, &txdesc.flags);
143333aca94dSKalle Valo 			/* Don't break, this is a failed frame! */
143433aca94dSKalle Valo 		default: /* Failure */
143533aca94dSKalle Valo 			__set_bit(TXDONE_FAILURE, &txdesc.flags);
143633aca94dSKalle Valo 		}
143733aca94dSKalle Valo 		txdesc.retry = rt2x00_get_field32(word, TXD_W0_RETRY_COUNT);
143833aca94dSKalle Valo 
143933aca94dSKalle Valo 		rt2x00lib_txdone(entry, &txdesc);
144033aca94dSKalle Valo 	}
144133aca94dSKalle Valo }
144233aca94dSKalle Valo 
144333aca94dSKalle Valo static inline void rt2500pci_enable_interrupt(struct rt2x00_dev *rt2x00dev,
144433aca94dSKalle Valo 					      struct rt2x00_field32 irq_field)
144533aca94dSKalle Valo {
144633aca94dSKalle Valo 	u32 reg;
144733aca94dSKalle Valo 
144833aca94dSKalle Valo 	/*
144933aca94dSKalle Valo 	 * Enable a single interrupt. The interrupt mask register
145033aca94dSKalle Valo 	 * access needs locking.
145133aca94dSKalle Valo 	 */
145233aca94dSKalle Valo 	spin_lock_irq(&rt2x00dev->irqmask_lock);
145333aca94dSKalle Valo 
14543954b4e3SArnd Bergmann 	reg = rt2x00mmio_register_read(rt2x00dev, CSR8);
145533aca94dSKalle Valo 	rt2x00_set_field32(&reg, irq_field, 0);
145633aca94dSKalle Valo 	rt2x00mmio_register_write(rt2x00dev, CSR8, reg);
145733aca94dSKalle Valo 
145833aca94dSKalle Valo 	spin_unlock_irq(&rt2x00dev->irqmask_lock);
145933aca94dSKalle Valo }
146033aca94dSKalle Valo 
146133aca94dSKalle Valo static void rt2500pci_txstatus_tasklet(unsigned long data)
146233aca94dSKalle Valo {
146333aca94dSKalle Valo 	struct rt2x00_dev *rt2x00dev = (struct rt2x00_dev *)data;
146433aca94dSKalle Valo 	u32 reg;
146533aca94dSKalle Valo 
146633aca94dSKalle Valo 	/*
146733aca94dSKalle Valo 	 * Handle all tx queues.
146833aca94dSKalle Valo 	 */
146933aca94dSKalle Valo 	rt2500pci_txdone(rt2x00dev, QID_ATIM);
147033aca94dSKalle Valo 	rt2500pci_txdone(rt2x00dev, QID_AC_VO);
147133aca94dSKalle Valo 	rt2500pci_txdone(rt2x00dev, QID_AC_VI);
147233aca94dSKalle Valo 
147333aca94dSKalle Valo 	/*
147433aca94dSKalle Valo 	 * Enable all TXDONE interrupts again.
147533aca94dSKalle Valo 	 */
147633aca94dSKalle Valo 	if (test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags)) {
147733aca94dSKalle Valo 		spin_lock_irq(&rt2x00dev->irqmask_lock);
147833aca94dSKalle Valo 
14793954b4e3SArnd Bergmann 		reg = rt2x00mmio_register_read(rt2x00dev, CSR8);
148033aca94dSKalle Valo 		rt2x00_set_field32(&reg, CSR8_TXDONE_TXRING, 0);
148133aca94dSKalle Valo 		rt2x00_set_field32(&reg, CSR8_TXDONE_ATIMRING, 0);
148233aca94dSKalle Valo 		rt2x00_set_field32(&reg, CSR8_TXDONE_PRIORING, 0);
148333aca94dSKalle Valo 		rt2x00mmio_register_write(rt2x00dev, CSR8, reg);
148433aca94dSKalle Valo 
148533aca94dSKalle Valo 		spin_unlock_irq(&rt2x00dev->irqmask_lock);
148633aca94dSKalle Valo 	}
148733aca94dSKalle Valo }
148833aca94dSKalle Valo 
148933aca94dSKalle Valo static void rt2500pci_tbtt_tasklet(unsigned long data)
149033aca94dSKalle Valo {
149133aca94dSKalle Valo 	struct rt2x00_dev *rt2x00dev = (struct rt2x00_dev *)data;
149233aca94dSKalle Valo 	rt2x00lib_beacondone(rt2x00dev);
149333aca94dSKalle Valo 	if (test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags))
149433aca94dSKalle Valo 		rt2500pci_enable_interrupt(rt2x00dev, CSR8_TBCN_EXPIRE);
149533aca94dSKalle Valo }
149633aca94dSKalle Valo 
149733aca94dSKalle Valo static void rt2500pci_rxdone_tasklet(unsigned long data)
149833aca94dSKalle Valo {
149933aca94dSKalle Valo 	struct rt2x00_dev *rt2x00dev = (struct rt2x00_dev *)data;
150033aca94dSKalle Valo 	if (rt2x00mmio_rxdone(rt2x00dev))
150133aca94dSKalle Valo 		tasklet_schedule(&rt2x00dev->rxdone_tasklet);
150233aca94dSKalle Valo 	else if (test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags))
150333aca94dSKalle Valo 		rt2500pci_enable_interrupt(rt2x00dev, CSR8_RXDONE);
150433aca94dSKalle Valo }
150533aca94dSKalle Valo 
150633aca94dSKalle Valo static irqreturn_t rt2500pci_interrupt(int irq, void *dev_instance)
150733aca94dSKalle Valo {
150833aca94dSKalle Valo 	struct rt2x00_dev *rt2x00dev = dev_instance;
150933aca94dSKalle Valo 	u32 reg, mask;
151033aca94dSKalle Valo 
151133aca94dSKalle Valo 	/*
151233aca94dSKalle Valo 	 * Get the interrupt sources & saved to local variable.
151333aca94dSKalle Valo 	 * Write register value back to clear pending interrupts.
151433aca94dSKalle Valo 	 */
15153954b4e3SArnd Bergmann 	reg = rt2x00mmio_register_read(rt2x00dev, CSR7);
151633aca94dSKalle Valo 	rt2x00mmio_register_write(rt2x00dev, CSR7, reg);
151733aca94dSKalle Valo 
151833aca94dSKalle Valo 	if (!reg)
151933aca94dSKalle Valo 		return IRQ_NONE;
152033aca94dSKalle Valo 
152133aca94dSKalle Valo 	if (!test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags))
152233aca94dSKalle Valo 		return IRQ_HANDLED;
152333aca94dSKalle Valo 
152433aca94dSKalle Valo 	mask = reg;
152533aca94dSKalle Valo 
152633aca94dSKalle Valo 	/*
152733aca94dSKalle Valo 	 * Schedule tasklets for interrupt handling.
152833aca94dSKalle Valo 	 */
152933aca94dSKalle Valo 	if (rt2x00_get_field32(reg, CSR7_TBCN_EXPIRE))
153033aca94dSKalle Valo 		tasklet_hi_schedule(&rt2x00dev->tbtt_tasklet);
153133aca94dSKalle Valo 
153233aca94dSKalle Valo 	if (rt2x00_get_field32(reg, CSR7_RXDONE))
153333aca94dSKalle Valo 		tasklet_schedule(&rt2x00dev->rxdone_tasklet);
153433aca94dSKalle Valo 
153533aca94dSKalle Valo 	if (rt2x00_get_field32(reg, CSR7_TXDONE_ATIMRING) ||
153633aca94dSKalle Valo 	    rt2x00_get_field32(reg, CSR7_TXDONE_PRIORING) ||
153733aca94dSKalle Valo 	    rt2x00_get_field32(reg, CSR7_TXDONE_TXRING)) {
153833aca94dSKalle Valo 		tasklet_schedule(&rt2x00dev->txstatus_tasklet);
153933aca94dSKalle Valo 		/*
154033aca94dSKalle Valo 		 * Mask out all txdone interrupts.
154133aca94dSKalle Valo 		 */
154233aca94dSKalle Valo 		rt2x00_set_field32(&mask, CSR8_TXDONE_TXRING, 1);
154333aca94dSKalle Valo 		rt2x00_set_field32(&mask, CSR8_TXDONE_ATIMRING, 1);
154433aca94dSKalle Valo 		rt2x00_set_field32(&mask, CSR8_TXDONE_PRIORING, 1);
154533aca94dSKalle Valo 	}
154633aca94dSKalle Valo 
154733aca94dSKalle Valo 	/*
154833aca94dSKalle Valo 	 * Disable all interrupts for which a tasklet was scheduled right now,
154933aca94dSKalle Valo 	 * the tasklet will reenable the appropriate interrupts.
155033aca94dSKalle Valo 	 */
155133aca94dSKalle Valo 	spin_lock(&rt2x00dev->irqmask_lock);
155233aca94dSKalle Valo 
15533954b4e3SArnd Bergmann 	reg = rt2x00mmio_register_read(rt2x00dev, CSR8);
155433aca94dSKalle Valo 	reg |= mask;
155533aca94dSKalle Valo 	rt2x00mmio_register_write(rt2x00dev, CSR8, reg);
155633aca94dSKalle Valo 
155733aca94dSKalle Valo 	spin_unlock(&rt2x00dev->irqmask_lock);
155833aca94dSKalle Valo 
155933aca94dSKalle Valo 	return IRQ_HANDLED;
156033aca94dSKalle Valo }
156133aca94dSKalle Valo 
156233aca94dSKalle Valo /*
156333aca94dSKalle Valo  * Device probe functions.
156433aca94dSKalle Valo  */
156533aca94dSKalle Valo static int rt2500pci_validate_eeprom(struct rt2x00_dev *rt2x00dev)
156633aca94dSKalle Valo {
156733aca94dSKalle Valo 	struct eeprom_93cx6 eeprom;
156833aca94dSKalle Valo 	u32 reg;
156933aca94dSKalle Valo 	u16 word;
157033aca94dSKalle Valo 	u8 *mac;
157133aca94dSKalle Valo 
15723954b4e3SArnd Bergmann 	reg = rt2x00mmio_register_read(rt2x00dev, CSR21);
157333aca94dSKalle Valo 
157433aca94dSKalle Valo 	eeprom.data = rt2x00dev;
157533aca94dSKalle Valo 	eeprom.register_read = rt2500pci_eepromregister_read;
157633aca94dSKalle Valo 	eeprom.register_write = rt2500pci_eepromregister_write;
157733aca94dSKalle Valo 	eeprom.width = rt2x00_get_field32(reg, CSR21_TYPE_93C46) ?
157833aca94dSKalle Valo 	    PCI_EEPROM_WIDTH_93C46 : PCI_EEPROM_WIDTH_93C66;
157933aca94dSKalle Valo 	eeprom.reg_data_in = 0;
158033aca94dSKalle Valo 	eeprom.reg_data_out = 0;
158133aca94dSKalle Valo 	eeprom.reg_data_clock = 0;
158233aca94dSKalle Valo 	eeprom.reg_chip_select = 0;
158333aca94dSKalle Valo 
158433aca94dSKalle Valo 	eeprom_93cx6_multiread(&eeprom, EEPROM_BASE, rt2x00dev->eeprom,
158533aca94dSKalle Valo 			       EEPROM_SIZE / sizeof(u16));
158633aca94dSKalle Valo 
158733aca94dSKalle Valo 	/*
158833aca94dSKalle Valo 	 * Start validation of the data that has been read.
158933aca94dSKalle Valo 	 */
159033aca94dSKalle Valo 	mac = rt2x00_eeprom_addr(rt2x00dev, EEPROM_MAC_ADDR_0);
15919766cb70SMathias Kresin 	rt2x00lib_set_mac_address(rt2x00dev, mac);
159233aca94dSKalle Valo 
1593*38651683SArnd Bergmann 	word = rt2x00_eeprom_read(rt2x00dev, EEPROM_ANTENNA);
159433aca94dSKalle Valo 	if (word == 0xffff) {
159533aca94dSKalle Valo 		rt2x00_set_field16(&word, EEPROM_ANTENNA_NUM, 2);
159633aca94dSKalle Valo 		rt2x00_set_field16(&word, EEPROM_ANTENNA_TX_DEFAULT,
159733aca94dSKalle Valo 				   ANTENNA_SW_DIVERSITY);
159833aca94dSKalle Valo 		rt2x00_set_field16(&word, EEPROM_ANTENNA_RX_DEFAULT,
159933aca94dSKalle Valo 				   ANTENNA_SW_DIVERSITY);
160033aca94dSKalle Valo 		rt2x00_set_field16(&word, EEPROM_ANTENNA_LED_MODE,
160133aca94dSKalle Valo 				   LED_MODE_DEFAULT);
160233aca94dSKalle Valo 		rt2x00_set_field16(&word, EEPROM_ANTENNA_DYN_TXAGC, 0);
160333aca94dSKalle Valo 		rt2x00_set_field16(&word, EEPROM_ANTENNA_HARDWARE_RADIO, 0);
160433aca94dSKalle Valo 		rt2x00_set_field16(&word, EEPROM_ANTENNA_RF_TYPE, RF2522);
160533aca94dSKalle Valo 		rt2x00_eeprom_write(rt2x00dev, EEPROM_ANTENNA, word);
160633aca94dSKalle Valo 		rt2x00_eeprom_dbg(rt2x00dev, "Antenna: 0x%04x\n", word);
160733aca94dSKalle Valo 	}
160833aca94dSKalle Valo 
1609*38651683SArnd Bergmann 	word = rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC);
161033aca94dSKalle Valo 	if (word == 0xffff) {
161133aca94dSKalle Valo 		rt2x00_set_field16(&word, EEPROM_NIC_CARDBUS_ACCEL, 0);
161233aca94dSKalle Valo 		rt2x00_set_field16(&word, EEPROM_NIC_DYN_BBP_TUNE, 0);
161333aca94dSKalle Valo 		rt2x00_set_field16(&word, EEPROM_NIC_CCK_TX_POWER, 0);
161433aca94dSKalle Valo 		rt2x00_eeprom_write(rt2x00dev, EEPROM_NIC, word);
161533aca94dSKalle Valo 		rt2x00_eeprom_dbg(rt2x00dev, "NIC: 0x%04x\n", word);
161633aca94dSKalle Valo 	}
161733aca94dSKalle Valo 
1618*38651683SArnd Bergmann 	word = rt2x00_eeprom_read(rt2x00dev, EEPROM_CALIBRATE_OFFSET);
161933aca94dSKalle Valo 	if (word == 0xffff) {
162033aca94dSKalle Valo 		rt2x00_set_field16(&word, EEPROM_CALIBRATE_OFFSET_RSSI,
162133aca94dSKalle Valo 				   DEFAULT_RSSI_OFFSET);
162233aca94dSKalle Valo 		rt2x00_eeprom_write(rt2x00dev, EEPROM_CALIBRATE_OFFSET, word);
162333aca94dSKalle Valo 		rt2x00_eeprom_dbg(rt2x00dev, "Calibrate offset: 0x%04x\n",
162433aca94dSKalle Valo 				  word);
162533aca94dSKalle Valo 	}
162633aca94dSKalle Valo 
162733aca94dSKalle Valo 	return 0;
162833aca94dSKalle Valo }
162933aca94dSKalle Valo 
163033aca94dSKalle Valo static int rt2500pci_init_eeprom(struct rt2x00_dev *rt2x00dev)
163133aca94dSKalle Valo {
163233aca94dSKalle Valo 	u32 reg;
163333aca94dSKalle Valo 	u16 value;
163433aca94dSKalle Valo 	u16 eeprom;
163533aca94dSKalle Valo 
163633aca94dSKalle Valo 	/*
163733aca94dSKalle Valo 	 * Read EEPROM word for configuration.
163833aca94dSKalle Valo 	 */
1639*38651683SArnd Bergmann 	eeprom = rt2x00_eeprom_read(rt2x00dev, EEPROM_ANTENNA);
164033aca94dSKalle Valo 
164133aca94dSKalle Valo 	/*
164233aca94dSKalle Valo 	 * Identify RF chipset.
164333aca94dSKalle Valo 	 */
164433aca94dSKalle Valo 	value = rt2x00_get_field16(eeprom, EEPROM_ANTENNA_RF_TYPE);
16453954b4e3SArnd Bergmann 	reg = rt2x00mmio_register_read(rt2x00dev, CSR0);
164633aca94dSKalle Valo 	rt2x00_set_chip(rt2x00dev, RT2560, value,
164733aca94dSKalle Valo 			rt2x00_get_field32(reg, CSR0_REVISION));
164833aca94dSKalle Valo 
164933aca94dSKalle Valo 	if (!rt2x00_rf(rt2x00dev, RF2522) &&
165033aca94dSKalle Valo 	    !rt2x00_rf(rt2x00dev, RF2523) &&
165133aca94dSKalle Valo 	    !rt2x00_rf(rt2x00dev, RF2524) &&
165233aca94dSKalle Valo 	    !rt2x00_rf(rt2x00dev, RF2525) &&
165333aca94dSKalle Valo 	    !rt2x00_rf(rt2x00dev, RF2525E) &&
165433aca94dSKalle Valo 	    !rt2x00_rf(rt2x00dev, RF5222)) {
165533aca94dSKalle Valo 		rt2x00_err(rt2x00dev, "Invalid RF chipset detected\n");
165633aca94dSKalle Valo 		return -ENODEV;
165733aca94dSKalle Valo 	}
165833aca94dSKalle Valo 
165933aca94dSKalle Valo 	/*
166033aca94dSKalle Valo 	 * Identify default antenna configuration.
166133aca94dSKalle Valo 	 */
166233aca94dSKalle Valo 	rt2x00dev->default_ant.tx =
166333aca94dSKalle Valo 	    rt2x00_get_field16(eeprom, EEPROM_ANTENNA_TX_DEFAULT);
166433aca94dSKalle Valo 	rt2x00dev->default_ant.rx =
166533aca94dSKalle Valo 	    rt2x00_get_field16(eeprom, EEPROM_ANTENNA_RX_DEFAULT);
166633aca94dSKalle Valo 
166733aca94dSKalle Valo 	/*
166833aca94dSKalle Valo 	 * Store led mode, for correct led behaviour.
166933aca94dSKalle Valo 	 */
167033aca94dSKalle Valo #ifdef CONFIG_RT2X00_LIB_LEDS
167133aca94dSKalle Valo 	value = rt2x00_get_field16(eeprom, EEPROM_ANTENNA_LED_MODE);
167233aca94dSKalle Valo 
167333aca94dSKalle Valo 	rt2500pci_init_led(rt2x00dev, &rt2x00dev->led_radio, LED_TYPE_RADIO);
167433aca94dSKalle Valo 	if (value == LED_MODE_TXRX_ACTIVITY ||
167533aca94dSKalle Valo 	    value == LED_MODE_DEFAULT ||
167633aca94dSKalle Valo 	    value == LED_MODE_ASUS)
167733aca94dSKalle Valo 		rt2500pci_init_led(rt2x00dev, &rt2x00dev->led_qual,
167833aca94dSKalle Valo 				   LED_TYPE_ACTIVITY);
167933aca94dSKalle Valo #endif /* CONFIG_RT2X00_LIB_LEDS */
168033aca94dSKalle Valo 
168133aca94dSKalle Valo 	/*
168233aca94dSKalle Valo 	 * Detect if this device has an hardware controlled radio.
168333aca94dSKalle Valo 	 */
168433aca94dSKalle Valo 	if (rt2x00_get_field16(eeprom, EEPROM_ANTENNA_HARDWARE_RADIO)) {
168533aca94dSKalle Valo 		__set_bit(CAPABILITY_HW_BUTTON, &rt2x00dev->cap_flags);
168633aca94dSKalle Valo 		/*
168733aca94dSKalle Valo 		 * On this device RFKILL initialized during probe does not work.
168833aca94dSKalle Valo 		 */
168933aca94dSKalle Valo 		__set_bit(REQUIRE_DELAYED_RFKILL, &rt2x00dev->cap_flags);
169033aca94dSKalle Valo 	}
169133aca94dSKalle Valo 
169233aca94dSKalle Valo 	/*
169333aca94dSKalle Valo 	 * Check if the BBP tuning should be enabled.
169433aca94dSKalle Valo 	 */
1695*38651683SArnd Bergmann 	eeprom = rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC);
169633aca94dSKalle Valo 	if (!rt2x00_get_field16(eeprom, EEPROM_NIC_DYN_BBP_TUNE))
169733aca94dSKalle Valo 		__set_bit(CAPABILITY_LINK_TUNING, &rt2x00dev->cap_flags);
169833aca94dSKalle Valo 
169933aca94dSKalle Valo 	/*
170033aca94dSKalle Valo 	 * Read the RSSI <-> dBm offset information.
170133aca94dSKalle Valo 	 */
1702*38651683SArnd Bergmann 	eeprom = rt2x00_eeprom_read(rt2x00dev, EEPROM_CALIBRATE_OFFSET);
170333aca94dSKalle Valo 	rt2x00dev->rssi_offset =
170433aca94dSKalle Valo 	    rt2x00_get_field16(eeprom, EEPROM_CALIBRATE_OFFSET_RSSI);
170533aca94dSKalle Valo 
170633aca94dSKalle Valo 	return 0;
170733aca94dSKalle Valo }
170833aca94dSKalle Valo 
170933aca94dSKalle Valo /*
171033aca94dSKalle Valo  * RF value list for RF2522
171133aca94dSKalle Valo  * Supports: 2.4 GHz
171233aca94dSKalle Valo  */
171333aca94dSKalle Valo static const struct rf_channel rf_vals_bg_2522[] = {
171433aca94dSKalle Valo 	{ 1,  0x00002050, 0x000c1fda, 0x00000101, 0 },
171533aca94dSKalle Valo 	{ 2,  0x00002050, 0x000c1fee, 0x00000101, 0 },
171633aca94dSKalle Valo 	{ 3,  0x00002050, 0x000c2002, 0x00000101, 0 },
171733aca94dSKalle Valo 	{ 4,  0x00002050, 0x000c2016, 0x00000101, 0 },
171833aca94dSKalle Valo 	{ 5,  0x00002050, 0x000c202a, 0x00000101, 0 },
171933aca94dSKalle Valo 	{ 6,  0x00002050, 0x000c203e, 0x00000101, 0 },
172033aca94dSKalle Valo 	{ 7,  0x00002050, 0x000c2052, 0x00000101, 0 },
172133aca94dSKalle Valo 	{ 8,  0x00002050, 0x000c2066, 0x00000101, 0 },
172233aca94dSKalle Valo 	{ 9,  0x00002050, 0x000c207a, 0x00000101, 0 },
172333aca94dSKalle Valo 	{ 10, 0x00002050, 0x000c208e, 0x00000101, 0 },
172433aca94dSKalle Valo 	{ 11, 0x00002050, 0x000c20a2, 0x00000101, 0 },
172533aca94dSKalle Valo 	{ 12, 0x00002050, 0x000c20b6, 0x00000101, 0 },
172633aca94dSKalle Valo 	{ 13, 0x00002050, 0x000c20ca, 0x00000101, 0 },
172733aca94dSKalle Valo 	{ 14, 0x00002050, 0x000c20fa, 0x00000101, 0 },
172833aca94dSKalle Valo };
172933aca94dSKalle Valo 
173033aca94dSKalle Valo /*
173133aca94dSKalle Valo  * RF value list for RF2523
173233aca94dSKalle Valo  * Supports: 2.4 GHz
173333aca94dSKalle Valo  */
173433aca94dSKalle Valo static const struct rf_channel rf_vals_bg_2523[] = {
173533aca94dSKalle Valo 	{ 1,  0x00022010, 0x00000c9e, 0x000e0111, 0x00000a1b },
173633aca94dSKalle Valo 	{ 2,  0x00022010, 0x00000ca2, 0x000e0111, 0x00000a1b },
173733aca94dSKalle Valo 	{ 3,  0x00022010, 0x00000ca6, 0x000e0111, 0x00000a1b },
173833aca94dSKalle Valo 	{ 4,  0x00022010, 0x00000caa, 0x000e0111, 0x00000a1b },
173933aca94dSKalle Valo 	{ 5,  0x00022010, 0x00000cae, 0x000e0111, 0x00000a1b },
174033aca94dSKalle Valo 	{ 6,  0x00022010, 0x00000cb2, 0x000e0111, 0x00000a1b },
174133aca94dSKalle Valo 	{ 7,  0x00022010, 0x00000cb6, 0x000e0111, 0x00000a1b },
174233aca94dSKalle Valo 	{ 8,  0x00022010, 0x00000cba, 0x000e0111, 0x00000a1b },
174333aca94dSKalle Valo 	{ 9,  0x00022010, 0x00000cbe, 0x000e0111, 0x00000a1b },
174433aca94dSKalle Valo 	{ 10, 0x00022010, 0x00000d02, 0x000e0111, 0x00000a1b },
174533aca94dSKalle Valo 	{ 11, 0x00022010, 0x00000d06, 0x000e0111, 0x00000a1b },
174633aca94dSKalle Valo 	{ 12, 0x00022010, 0x00000d0a, 0x000e0111, 0x00000a1b },
174733aca94dSKalle Valo 	{ 13, 0x00022010, 0x00000d0e, 0x000e0111, 0x00000a1b },
174833aca94dSKalle Valo 	{ 14, 0x00022010, 0x00000d1a, 0x000e0111, 0x00000a03 },
174933aca94dSKalle Valo };
175033aca94dSKalle Valo 
175133aca94dSKalle Valo /*
175233aca94dSKalle Valo  * RF value list for RF2524
175333aca94dSKalle Valo  * Supports: 2.4 GHz
175433aca94dSKalle Valo  */
175533aca94dSKalle Valo static const struct rf_channel rf_vals_bg_2524[] = {
175633aca94dSKalle Valo 	{ 1,  0x00032020, 0x00000c9e, 0x00000101, 0x00000a1b },
175733aca94dSKalle Valo 	{ 2,  0x00032020, 0x00000ca2, 0x00000101, 0x00000a1b },
175833aca94dSKalle Valo 	{ 3,  0x00032020, 0x00000ca6, 0x00000101, 0x00000a1b },
175933aca94dSKalle Valo 	{ 4,  0x00032020, 0x00000caa, 0x00000101, 0x00000a1b },
176033aca94dSKalle Valo 	{ 5,  0x00032020, 0x00000cae, 0x00000101, 0x00000a1b },
176133aca94dSKalle Valo 	{ 6,  0x00032020, 0x00000cb2, 0x00000101, 0x00000a1b },
176233aca94dSKalle Valo 	{ 7,  0x00032020, 0x00000cb6, 0x00000101, 0x00000a1b },
176333aca94dSKalle Valo 	{ 8,  0x00032020, 0x00000cba, 0x00000101, 0x00000a1b },
176433aca94dSKalle Valo 	{ 9,  0x00032020, 0x00000cbe, 0x00000101, 0x00000a1b },
176533aca94dSKalle Valo 	{ 10, 0x00032020, 0x00000d02, 0x00000101, 0x00000a1b },
176633aca94dSKalle Valo 	{ 11, 0x00032020, 0x00000d06, 0x00000101, 0x00000a1b },
176733aca94dSKalle Valo 	{ 12, 0x00032020, 0x00000d0a, 0x00000101, 0x00000a1b },
176833aca94dSKalle Valo 	{ 13, 0x00032020, 0x00000d0e, 0x00000101, 0x00000a1b },
176933aca94dSKalle Valo 	{ 14, 0x00032020, 0x00000d1a, 0x00000101, 0x00000a03 },
177033aca94dSKalle Valo };
177133aca94dSKalle Valo 
177233aca94dSKalle Valo /*
177333aca94dSKalle Valo  * RF value list for RF2525
177433aca94dSKalle Valo  * Supports: 2.4 GHz
177533aca94dSKalle Valo  */
177633aca94dSKalle Valo static const struct rf_channel rf_vals_bg_2525[] = {
177733aca94dSKalle Valo 	{ 1,  0x00022020, 0x00080c9e, 0x00060111, 0x00000a1b },
177833aca94dSKalle Valo 	{ 2,  0x00022020, 0x00080ca2, 0x00060111, 0x00000a1b },
177933aca94dSKalle Valo 	{ 3,  0x00022020, 0x00080ca6, 0x00060111, 0x00000a1b },
178033aca94dSKalle Valo 	{ 4,  0x00022020, 0x00080caa, 0x00060111, 0x00000a1b },
178133aca94dSKalle Valo 	{ 5,  0x00022020, 0x00080cae, 0x00060111, 0x00000a1b },
178233aca94dSKalle Valo 	{ 6,  0x00022020, 0x00080cb2, 0x00060111, 0x00000a1b },
178333aca94dSKalle Valo 	{ 7,  0x00022020, 0x00080cb6, 0x00060111, 0x00000a1b },
178433aca94dSKalle Valo 	{ 8,  0x00022020, 0x00080cba, 0x00060111, 0x00000a1b },
178533aca94dSKalle Valo 	{ 9,  0x00022020, 0x00080cbe, 0x00060111, 0x00000a1b },
178633aca94dSKalle Valo 	{ 10, 0x00022020, 0x00080d02, 0x00060111, 0x00000a1b },
178733aca94dSKalle Valo 	{ 11, 0x00022020, 0x00080d06, 0x00060111, 0x00000a1b },
178833aca94dSKalle Valo 	{ 12, 0x00022020, 0x00080d0a, 0x00060111, 0x00000a1b },
178933aca94dSKalle Valo 	{ 13, 0x00022020, 0x00080d0e, 0x00060111, 0x00000a1b },
179033aca94dSKalle Valo 	{ 14, 0x00022020, 0x00080d1a, 0x00060111, 0x00000a03 },
179133aca94dSKalle Valo };
179233aca94dSKalle Valo 
179333aca94dSKalle Valo /*
179433aca94dSKalle Valo  * RF value list for RF2525e
179533aca94dSKalle Valo  * Supports: 2.4 GHz
179633aca94dSKalle Valo  */
179733aca94dSKalle Valo static const struct rf_channel rf_vals_bg_2525e[] = {
179833aca94dSKalle Valo 	{ 1,  0x00022020, 0x00081136, 0x00060111, 0x00000a0b },
179933aca94dSKalle Valo 	{ 2,  0x00022020, 0x0008113a, 0x00060111, 0x00000a0b },
180033aca94dSKalle Valo 	{ 3,  0x00022020, 0x0008113e, 0x00060111, 0x00000a0b },
180133aca94dSKalle Valo 	{ 4,  0x00022020, 0x00081182, 0x00060111, 0x00000a0b },
180233aca94dSKalle Valo 	{ 5,  0x00022020, 0x00081186, 0x00060111, 0x00000a0b },
180333aca94dSKalle Valo 	{ 6,  0x00022020, 0x0008118a, 0x00060111, 0x00000a0b },
180433aca94dSKalle Valo 	{ 7,  0x00022020, 0x0008118e, 0x00060111, 0x00000a0b },
180533aca94dSKalle Valo 	{ 8,  0x00022020, 0x00081192, 0x00060111, 0x00000a0b },
180633aca94dSKalle Valo 	{ 9,  0x00022020, 0x00081196, 0x00060111, 0x00000a0b },
180733aca94dSKalle Valo 	{ 10, 0x00022020, 0x0008119a, 0x00060111, 0x00000a0b },
180833aca94dSKalle Valo 	{ 11, 0x00022020, 0x0008119e, 0x00060111, 0x00000a0b },
180933aca94dSKalle Valo 	{ 12, 0x00022020, 0x000811a2, 0x00060111, 0x00000a0b },
181033aca94dSKalle Valo 	{ 13, 0x00022020, 0x000811a6, 0x00060111, 0x00000a0b },
181133aca94dSKalle Valo 	{ 14, 0x00022020, 0x000811ae, 0x00060111, 0x00000a1b },
181233aca94dSKalle Valo };
181333aca94dSKalle Valo 
181433aca94dSKalle Valo /*
181533aca94dSKalle Valo  * RF value list for RF5222
181633aca94dSKalle Valo  * Supports: 2.4 GHz & 5.2 GHz
181733aca94dSKalle Valo  */
181833aca94dSKalle Valo static const struct rf_channel rf_vals_5222[] = {
181933aca94dSKalle Valo 	{ 1,  0x00022020, 0x00001136, 0x00000101, 0x00000a0b },
182033aca94dSKalle Valo 	{ 2,  0x00022020, 0x0000113a, 0x00000101, 0x00000a0b },
182133aca94dSKalle Valo 	{ 3,  0x00022020, 0x0000113e, 0x00000101, 0x00000a0b },
182233aca94dSKalle Valo 	{ 4,  0x00022020, 0x00001182, 0x00000101, 0x00000a0b },
182333aca94dSKalle Valo 	{ 5,  0x00022020, 0x00001186, 0x00000101, 0x00000a0b },
182433aca94dSKalle Valo 	{ 6,  0x00022020, 0x0000118a, 0x00000101, 0x00000a0b },
182533aca94dSKalle Valo 	{ 7,  0x00022020, 0x0000118e, 0x00000101, 0x00000a0b },
182633aca94dSKalle Valo 	{ 8,  0x00022020, 0x00001192, 0x00000101, 0x00000a0b },
182733aca94dSKalle Valo 	{ 9,  0x00022020, 0x00001196, 0x00000101, 0x00000a0b },
182833aca94dSKalle Valo 	{ 10, 0x00022020, 0x0000119a, 0x00000101, 0x00000a0b },
182933aca94dSKalle Valo 	{ 11, 0x00022020, 0x0000119e, 0x00000101, 0x00000a0b },
183033aca94dSKalle Valo 	{ 12, 0x00022020, 0x000011a2, 0x00000101, 0x00000a0b },
183133aca94dSKalle Valo 	{ 13, 0x00022020, 0x000011a6, 0x00000101, 0x00000a0b },
183233aca94dSKalle Valo 	{ 14, 0x00022020, 0x000011ae, 0x00000101, 0x00000a1b },
183333aca94dSKalle Valo 
183433aca94dSKalle Valo 	/* 802.11 UNI / HyperLan 2 */
183533aca94dSKalle Valo 	{ 36, 0x00022010, 0x00018896, 0x00000101, 0x00000a1f },
183633aca94dSKalle Valo 	{ 40, 0x00022010, 0x0001889a, 0x00000101, 0x00000a1f },
183733aca94dSKalle Valo 	{ 44, 0x00022010, 0x0001889e, 0x00000101, 0x00000a1f },
183833aca94dSKalle Valo 	{ 48, 0x00022010, 0x000188a2, 0x00000101, 0x00000a1f },
183933aca94dSKalle Valo 	{ 52, 0x00022010, 0x000188a6, 0x00000101, 0x00000a1f },
184033aca94dSKalle Valo 	{ 66, 0x00022010, 0x000188aa, 0x00000101, 0x00000a1f },
184133aca94dSKalle Valo 	{ 60, 0x00022010, 0x000188ae, 0x00000101, 0x00000a1f },
184233aca94dSKalle Valo 	{ 64, 0x00022010, 0x000188b2, 0x00000101, 0x00000a1f },
184333aca94dSKalle Valo 
184433aca94dSKalle Valo 	/* 802.11 HyperLan 2 */
184533aca94dSKalle Valo 	{ 100, 0x00022010, 0x00008802, 0x00000101, 0x00000a0f },
184633aca94dSKalle Valo 	{ 104, 0x00022010, 0x00008806, 0x00000101, 0x00000a0f },
184733aca94dSKalle Valo 	{ 108, 0x00022010, 0x0000880a, 0x00000101, 0x00000a0f },
184833aca94dSKalle Valo 	{ 112, 0x00022010, 0x0000880e, 0x00000101, 0x00000a0f },
184933aca94dSKalle Valo 	{ 116, 0x00022010, 0x00008812, 0x00000101, 0x00000a0f },
185033aca94dSKalle Valo 	{ 120, 0x00022010, 0x00008816, 0x00000101, 0x00000a0f },
185133aca94dSKalle Valo 	{ 124, 0x00022010, 0x0000881a, 0x00000101, 0x00000a0f },
185233aca94dSKalle Valo 	{ 128, 0x00022010, 0x0000881e, 0x00000101, 0x00000a0f },
185333aca94dSKalle Valo 	{ 132, 0x00022010, 0x00008822, 0x00000101, 0x00000a0f },
185433aca94dSKalle Valo 	{ 136, 0x00022010, 0x00008826, 0x00000101, 0x00000a0f },
185533aca94dSKalle Valo 
185633aca94dSKalle Valo 	/* 802.11 UNII */
185733aca94dSKalle Valo 	{ 140, 0x00022010, 0x0000882a, 0x00000101, 0x00000a0f },
185833aca94dSKalle Valo 	{ 149, 0x00022020, 0x000090a6, 0x00000101, 0x00000a07 },
185933aca94dSKalle Valo 	{ 153, 0x00022020, 0x000090ae, 0x00000101, 0x00000a07 },
186033aca94dSKalle Valo 	{ 157, 0x00022020, 0x000090b6, 0x00000101, 0x00000a07 },
186133aca94dSKalle Valo 	{ 161, 0x00022020, 0x000090be, 0x00000101, 0x00000a07 },
186233aca94dSKalle Valo };
186333aca94dSKalle Valo 
186433aca94dSKalle Valo static int rt2500pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
186533aca94dSKalle Valo {
186633aca94dSKalle Valo 	struct hw_mode_spec *spec = &rt2x00dev->spec;
186733aca94dSKalle Valo 	struct channel_info *info;
186833aca94dSKalle Valo 	char *tx_power;
186933aca94dSKalle Valo 	unsigned int i;
187033aca94dSKalle Valo 
187133aca94dSKalle Valo 	/*
187233aca94dSKalle Valo 	 * Initialize all hw fields.
187333aca94dSKalle Valo 	 */
187433aca94dSKalle Valo 	ieee80211_hw_set(rt2x00dev->hw, PS_NULLFUNC_STACK);
187533aca94dSKalle Valo 	ieee80211_hw_set(rt2x00dev->hw, SUPPORTS_PS);
187633aca94dSKalle Valo 	ieee80211_hw_set(rt2x00dev->hw, HOST_BROADCAST_PS_BUFFERING);
187733aca94dSKalle Valo 	ieee80211_hw_set(rt2x00dev->hw, SIGNAL_DBM);
187833aca94dSKalle Valo 
187933aca94dSKalle Valo 	SET_IEEE80211_DEV(rt2x00dev->hw, rt2x00dev->dev);
188033aca94dSKalle Valo 	SET_IEEE80211_PERM_ADDR(rt2x00dev->hw,
188133aca94dSKalle Valo 				rt2x00_eeprom_addr(rt2x00dev,
188233aca94dSKalle Valo 						   EEPROM_MAC_ADDR_0));
188333aca94dSKalle Valo 
188433aca94dSKalle Valo 	/*
188533aca94dSKalle Valo 	 * Disable powersaving as default.
188633aca94dSKalle Valo 	 */
188733aca94dSKalle Valo 	rt2x00dev->hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT;
188833aca94dSKalle Valo 
188933aca94dSKalle Valo 	/*
189033aca94dSKalle Valo 	 * Initialize hw_mode information.
189133aca94dSKalle Valo 	 */
189233aca94dSKalle Valo 	spec->supported_bands = SUPPORT_BAND_2GHZ;
189333aca94dSKalle Valo 	spec->supported_rates = SUPPORT_RATE_CCK | SUPPORT_RATE_OFDM;
189433aca94dSKalle Valo 
189533aca94dSKalle Valo 	if (rt2x00_rf(rt2x00dev, RF2522)) {
189633aca94dSKalle Valo 		spec->num_channels = ARRAY_SIZE(rf_vals_bg_2522);
189733aca94dSKalle Valo 		spec->channels = rf_vals_bg_2522;
189833aca94dSKalle Valo 	} else if (rt2x00_rf(rt2x00dev, RF2523)) {
189933aca94dSKalle Valo 		spec->num_channels = ARRAY_SIZE(rf_vals_bg_2523);
190033aca94dSKalle Valo 		spec->channels = rf_vals_bg_2523;
190133aca94dSKalle Valo 	} else if (rt2x00_rf(rt2x00dev, RF2524)) {
190233aca94dSKalle Valo 		spec->num_channels = ARRAY_SIZE(rf_vals_bg_2524);
190333aca94dSKalle Valo 		spec->channels = rf_vals_bg_2524;
190433aca94dSKalle Valo 	} else if (rt2x00_rf(rt2x00dev, RF2525)) {
190533aca94dSKalle Valo 		spec->num_channels = ARRAY_SIZE(rf_vals_bg_2525);
190633aca94dSKalle Valo 		spec->channels = rf_vals_bg_2525;
190733aca94dSKalle Valo 	} else if (rt2x00_rf(rt2x00dev, RF2525E)) {
190833aca94dSKalle Valo 		spec->num_channels = ARRAY_SIZE(rf_vals_bg_2525e);
190933aca94dSKalle Valo 		spec->channels = rf_vals_bg_2525e;
191033aca94dSKalle Valo 	} else if (rt2x00_rf(rt2x00dev, RF5222)) {
191133aca94dSKalle Valo 		spec->supported_bands |= SUPPORT_BAND_5GHZ;
191233aca94dSKalle Valo 		spec->num_channels = ARRAY_SIZE(rf_vals_5222);
191333aca94dSKalle Valo 		spec->channels = rf_vals_5222;
191433aca94dSKalle Valo 	}
191533aca94dSKalle Valo 
191633aca94dSKalle Valo 	/*
191733aca94dSKalle Valo 	 * Create channel information array
191833aca94dSKalle Valo 	 */
191933aca94dSKalle Valo 	info = kcalloc(spec->num_channels, sizeof(*info), GFP_KERNEL);
192033aca94dSKalle Valo 	if (!info)
192133aca94dSKalle Valo 		return -ENOMEM;
192233aca94dSKalle Valo 
192333aca94dSKalle Valo 	spec->channels_info = info;
192433aca94dSKalle Valo 
192533aca94dSKalle Valo 	tx_power = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_START);
192633aca94dSKalle Valo 	for (i = 0; i < 14; i++) {
192733aca94dSKalle Valo 		info[i].max_power = MAX_TXPOWER;
192833aca94dSKalle Valo 		info[i].default_power1 = TXPOWER_FROM_DEV(tx_power[i]);
192933aca94dSKalle Valo 	}
193033aca94dSKalle Valo 
193133aca94dSKalle Valo 	if (spec->num_channels > 14) {
193233aca94dSKalle Valo 		for (i = 14; i < spec->num_channels; i++) {
193333aca94dSKalle Valo 			info[i].max_power = MAX_TXPOWER;
193433aca94dSKalle Valo 			info[i].default_power1 = DEFAULT_TXPOWER;
193533aca94dSKalle Valo 		}
193633aca94dSKalle Valo 	}
193733aca94dSKalle Valo 
193833aca94dSKalle Valo 	return 0;
193933aca94dSKalle Valo }
194033aca94dSKalle Valo 
194133aca94dSKalle Valo static int rt2500pci_probe_hw(struct rt2x00_dev *rt2x00dev)
194233aca94dSKalle Valo {
194333aca94dSKalle Valo 	int retval;
194433aca94dSKalle Valo 	u32 reg;
194533aca94dSKalle Valo 
194633aca94dSKalle Valo 	/*
194733aca94dSKalle Valo 	 * Allocate eeprom data.
194833aca94dSKalle Valo 	 */
194933aca94dSKalle Valo 	retval = rt2500pci_validate_eeprom(rt2x00dev);
195033aca94dSKalle Valo 	if (retval)
195133aca94dSKalle Valo 		return retval;
195233aca94dSKalle Valo 
195333aca94dSKalle Valo 	retval = rt2500pci_init_eeprom(rt2x00dev);
195433aca94dSKalle Valo 	if (retval)
195533aca94dSKalle Valo 		return retval;
195633aca94dSKalle Valo 
195733aca94dSKalle Valo 	/*
195833aca94dSKalle Valo 	 * Enable rfkill polling by setting GPIO direction of the
195933aca94dSKalle Valo 	 * rfkill switch GPIO pin correctly.
196033aca94dSKalle Valo 	 */
19613954b4e3SArnd Bergmann 	reg = rt2x00mmio_register_read(rt2x00dev, GPIOCSR);
196233aca94dSKalle Valo 	rt2x00_set_field32(&reg, GPIOCSR_DIR0, 1);
196333aca94dSKalle Valo 	rt2x00mmio_register_write(rt2x00dev, GPIOCSR, reg);
196433aca94dSKalle Valo 
196533aca94dSKalle Valo 	/*
196633aca94dSKalle Valo 	 * Initialize hw specifications.
196733aca94dSKalle Valo 	 */
196833aca94dSKalle Valo 	retval = rt2500pci_probe_hw_mode(rt2x00dev);
196933aca94dSKalle Valo 	if (retval)
197033aca94dSKalle Valo 		return retval;
197133aca94dSKalle Valo 
197233aca94dSKalle Valo 	/*
197333aca94dSKalle Valo 	 * This device requires the atim queue and DMA-mapped skbs.
197433aca94dSKalle Valo 	 */
197533aca94dSKalle Valo 	__set_bit(REQUIRE_ATIM_QUEUE, &rt2x00dev->cap_flags);
197633aca94dSKalle Valo 	__set_bit(REQUIRE_DMA, &rt2x00dev->cap_flags);
197733aca94dSKalle Valo 	__set_bit(REQUIRE_SW_SEQNO, &rt2x00dev->cap_flags);
197833aca94dSKalle Valo 
197933aca94dSKalle Valo 	/*
198033aca94dSKalle Valo 	 * Set the rssi offset.
198133aca94dSKalle Valo 	 */
198233aca94dSKalle Valo 	rt2x00dev->rssi_offset = DEFAULT_RSSI_OFFSET;
198333aca94dSKalle Valo 
198433aca94dSKalle Valo 	return 0;
198533aca94dSKalle Valo }
198633aca94dSKalle Valo 
198733aca94dSKalle Valo /*
198833aca94dSKalle Valo  * IEEE80211 stack callback functions.
198933aca94dSKalle Valo  */
199033aca94dSKalle Valo static u64 rt2500pci_get_tsf(struct ieee80211_hw *hw,
199133aca94dSKalle Valo 			     struct ieee80211_vif *vif)
199233aca94dSKalle Valo {
199333aca94dSKalle Valo 	struct rt2x00_dev *rt2x00dev = hw->priv;
199433aca94dSKalle Valo 	u64 tsf;
199533aca94dSKalle Valo 	u32 reg;
199633aca94dSKalle Valo 
19973954b4e3SArnd Bergmann 	reg = rt2x00mmio_register_read(rt2x00dev, CSR17);
199833aca94dSKalle Valo 	tsf = (u64) rt2x00_get_field32(reg, CSR17_HIGH_TSFTIMER) << 32;
19993954b4e3SArnd Bergmann 	reg = rt2x00mmio_register_read(rt2x00dev, CSR16);
200033aca94dSKalle Valo 	tsf |= rt2x00_get_field32(reg, CSR16_LOW_TSFTIMER);
200133aca94dSKalle Valo 
200233aca94dSKalle Valo 	return tsf;
200333aca94dSKalle Valo }
200433aca94dSKalle Valo 
200533aca94dSKalle Valo static int rt2500pci_tx_last_beacon(struct ieee80211_hw *hw)
200633aca94dSKalle Valo {
200733aca94dSKalle Valo 	struct rt2x00_dev *rt2x00dev = hw->priv;
200833aca94dSKalle Valo 	u32 reg;
200933aca94dSKalle Valo 
20103954b4e3SArnd Bergmann 	reg = rt2x00mmio_register_read(rt2x00dev, CSR15);
201133aca94dSKalle Valo 	return rt2x00_get_field32(reg, CSR15_BEACON_SENT);
201233aca94dSKalle Valo }
201333aca94dSKalle Valo 
201433aca94dSKalle Valo static const struct ieee80211_ops rt2500pci_mac80211_ops = {
201533aca94dSKalle Valo 	.tx			= rt2x00mac_tx,
201633aca94dSKalle Valo 	.start			= rt2x00mac_start,
201733aca94dSKalle Valo 	.stop			= rt2x00mac_stop,
201833aca94dSKalle Valo 	.add_interface		= rt2x00mac_add_interface,
201933aca94dSKalle Valo 	.remove_interface	= rt2x00mac_remove_interface,
202033aca94dSKalle Valo 	.config			= rt2x00mac_config,
202133aca94dSKalle Valo 	.configure_filter	= rt2x00mac_configure_filter,
202233aca94dSKalle Valo 	.sw_scan_start		= rt2x00mac_sw_scan_start,
202333aca94dSKalle Valo 	.sw_scan_complete	= rt2x00mac_sw_scan_complete,
202433aca94dSKalle Valo 	.get_stats		= rt2x00mac_get_stats,
202533aca94dSKalle Valo 	.bss_info_changed	= rt2x00mac_bss_info_changed,
202633aca94dSKalle Valo 	.conf_tx		= rt2x00mac_conf_tx,
202733aca94dSKalle Valo 	.get_tsf		= rt2500pci_get_tsf,
202833aca94dSKalle Valo 	.tx_last_beacon		= rt2500pci_tx_last_beacon,
202933aca94dSKalle Valo 	.rfkill_poll		= rt2x00mac_rfkill_poll,
203033aca94dSKalle Valo 	.flush			= rt2x00mac_flush,
203133aca94dSKalle Valo 	.set_antenna		= rt2x00mac_set_antenna,
203233aca94dSKalle Valo 	.get_antenna		= rt2x00mac_get_antenna,
203333aca94dSKalle Valo 	.get_ringparam		= rt2x00mac_get_ringparam,
203433aca94dSKalle Valo 	.tx_frames_pending	= rt2x00mac_tx_frames_pending,
203533aca94dSKalle Valo };
203633aca94dSKalle Valo 
203733aca94dSKalle Valo static const struct rt2x00lib_ops rt2500pci_rt2x00_ops = {
203833aca94dSKalle Valo 	.irq_handler		= rt2500pci_interrupt,
203933aca94dSKalle Valo 	.txstatus_tasklet	= rt2500pci_txstatus_tasklet,
204033aca94dSKalle Valo 	.tbtt_tasklet		= rt2500pci_tbtt_tasklet,
204133aca94dSKalle Valo 	.rxdone_tasklet		= rt2500pci_rxdone_tasklet,
204233aca94dSKalle Valo 	.probe_hw		= rt2500pci_probe_hw,
204333aca94dSKalle Valo 	.initialize		= rt2x00mmio_initialize,
204433aca94dSKalle Valo 	.uninitialize		= rt2x00mmio_uninitialize,
204533aca94dSKalle Valo 	.get_entry_state	= rt2500pci_get_entry_state,
204633aca94dSKalle Valo 	.clear_entry		= rt2500pci_clear_entry,
204733aca94dSKalle Valo 	.set_device_state	= rt2500pci_set_device_state,
204833aca94dSKalle Valo 	.rfkill_poll		= rt2500pci_rfkill_poll,
204933aca94dSKalle Valo 	.link_stats		= rt2500pci_link_stats,
205033aca94dSKalle Valo 	.reset_tuner		= rt2500pci_reset_tuner,
205133aca94dSKalle Valo 	.link_tuner		= rt2500pci_link_tuner,
205233aca94dSKalle Valo 	.start_queue		= rt2500pci_start_queue,
205333aca94dSKalle Valo 	.kick_queue		= rt2500pci_kick_queue,
205433aca94dSKalle Valo 	.stop_queue		= rt2500pci_stop_queue,
205533aca94dSKalle Valo 	.flush_queue		= rt2x00mmio_flush_queue,
205633aca94dSKalle Valo 	.write_tx_desc		= rt2500pci_write_tx_desc,
205733aca94dSKalle Valo 	.write_beacon		= rt2500pci_write_beacon,
205833aca94dSKalle Valo 	.fill_rxdone		= rt2500pci_fill_rxdone,
205933aca94dSKalle Valo 	.config_filter		= rt2500pci_config_filter,
206033aca94dSKalle Valo 	.config_intf		= rt2500pci_config_intf,
206133aca94dSKalle Valo 	.config_erp		= rt2500pci_config_erp,
206233aca94dSKalle Valo 	.config_ant		= rt2500pci_config_ant,
206333aca94dSKalle Valo 	.config			= rt2500pci_config,
206433aca94dSKalle Valo };
206533aca94dSKalle Valo 
206633aca94dSKalle Valo static void rt2500pci_queue_init(struct data_queue *queue)
206733aca94dSKalle Valo {
206833aca94dSKalle Valo 	switch (queue->qid) {
206933aca94dSKalle Valo 	case QID_RX:
207033aca94dSKalle Valo 		queue->limit = 32;
207133aca94dSKalle Valo 		queue->data_size = DATA_FRAME_SIZE;
207233aca94dSKalle Valo 		queue->desc_size = RXD_DESC_SIZE;
207333aca94dSKalle Valo 		queue->priv_size = sizeof(struct queue_entry_priv_mmio);
207433aca94dSKalle Valo 		break;
207533aca94dSKalle Valo 
207633aca94dSKalle Valo 	case QID_AC_VO:
207733aca94dSKalle Valo 	case QID_AC_VI:
207833aca94dSKalle Valo 	case QID_AC_BE:
207933aca94dSKalle Valo 	case QID_AC_BK:
208033aca94dSKalle Valo 		queue->limit = 32;
208133aca94dSKalle Valo 		queue->data_size = DATA_FRAME_SIZE;
208233aca94dSKalle Valo 		queue->desc_size = TXD_DESC_SIZE;
208333aca94dSKalle Valo 		queue->priv_size = sizeof(struct queue_entry_priv_mmio);
208433aca94dSKalle Valo 		break;
208533aca94dSKalle Valo 
208633aca94dSKalle Valo 	case QID_BEACON:
208733aca94dSKalle Valo 		queue->limit = 1;
208833aca94dSKalle Valo 		queue->data_size = MGMT_FRAME_SIZE;
208933aca94dSKalle Valo 		queue->desc_size = TXD_DESC_SIZE;
209033aca94dSKalle Valo 		queue->priv_size = sizeof(struct queue_entry_priv_mmio);
209133aca94dSKalle Valo 		break;
209233aca94dSKalle Valo 
209333aca94dSKalle Valo 	case QID_ATIM:
209433aca94dSKalle Valo 		queue->limit = 8;
209533aca94dSKalle Valo 		queue->data_size = DATA_FRAME_SIZE;
209633aca94dSKalle Valo 		queue->desc_size = TXD_DESC_SIZE;
209733aca94dSKalle Valo 		queue->priv_size = sizeof(struct queue_entry_priv_mmio);
209833aca94dSKalle Valo 		break;
209933aca94dSKalle Valo 
210033aca94dSKalle Valo 	default:
210133aca94dSKalle Valo 		BUG();
210233aca94dSKalle Valo 		break;
210333aca94dSKalle Valo 	}
210433aca94dSKalle Valo }
210533aca94dSKalle Valo 
210633aca94dSKalle Valo static const struct rt2x00_ops rt2500pci_ops = {
210733aca94dSKalle Valo 	.name			= KBUILD_MODNAME,
210833aca94dSKalle Valo 	.max_ap_intf		= 1,
210933aca94dSKalle Valo 	.eeprom_size		= EEPROM_SIZE,
211033aca94dSKalle Valo 	.rf_size		= RF_SIZE,
211133aca94dSKalle Valo 	.tx_queues		= NUM_TX_QUEUES,
211233aca94dSKalle Valo 	.queue_init		= rt2500pci_queue_init,
211333aca94dSKalle Valo 	.lib			= &rt2500pci_rt2x00_ops,
211433aca94dSKalle Valo 	.hw			= &rt2500pci_mac80211_ops,
211533aca94dSKalle Valo #ifdef CONFIG_RT2X00_LIB_DEBUGFS
211633aca94dSKalle Valo 	.debugfs		= &rt2500pci_rt2x00debug,
211733aca94dSKalle Valo #endif /* CONFIG_RT2X00_LIB_DEBUGFS */
211833aca94dSKalle Valo };
211933aca94dSKalle Valo 
212033aca94dSKalle Valo /*
212133aca94dSKalle Valo  * RT2500pci module information.
212233aca94dSKalle Valo  */
212333aca94dSKalle Valo static const struct pci_device_id rt2500pci_device_table[] = {
212433aca94dSKalle Valo 	{ PCI_DEVICE(0x1814, 0x0201) },
212533aca94dSKalle Valo 	{ 0, }
212633aca94dSKalle Valo };
212733aca94dSKalle Valo 
212833aca94dSKalle Valo MODULE_AUTHOR(DRV_PROJECT);
212933aca94dSKalle Valo MODULE_VERSION(DRV_VERSION);
213033aca94dSKalle Valo MODULE_DESCRIPTION("Ralink RT2500 PCI & PCMCIA Wireless LAN driver.");
213133aca94dSKalle Valo MODULE_SUPPORTED_DEVICE("Ralink RT2560 PCI & PCMCIA chipset based cards");
213233aca94dSKalle Valo MODULE_DEVICE_TABLE(pci, rt2500pci_device_table);
213333aca94dSKalle Valo MODULE_LICENSE("GPL");
213433aca94dSKalle Valo 
213533aca94dSKalle Valo static int rt2500pci_probe(struct pci_dev *pci_dev,
213633aca94dSKalle Valo 			   const struct pci_device_id *id)
213733aca94dSKalle Valo {
213833aca94dSKalle Valo 	return rt2x00pci_probe(pci_dev, &rt2500pci_ops);
213933aca94dSKalle Valo }
214033aca94dSKalle Valo 
214133aca94dSKalle Valo static struct pci_driver rt2500pci_driver = {
214233aca94dSKalle Valo 	.name		= KBUILD_MODNAME,
214333aca94dSKalle Valo 	.id_table	= rt2500pci_device_table,
214433aca94dSKalle Valo 	.probe		= rt2500pci_probe,
214533aca94dSKalle Valo 	.remove		= rt2x00pci_remove,
214633aca94dSKalle Valo 	.suspend	= rt2x00pci_suspend,
214733aca94dSKalle Valo 	.resume		= rt2x00pci_resume,
214833aca94dSKalle Valo };
214933aca94dSKalle Valo 
215033aca94dSKalle Valo module_pci_driver(rt2500pci_driver);
2151