xref: /openbmc/linux/drivers/net/wireless/ralink/rt2x00/rt2400pci.c (revision 7ae9fb1b7ecbb5d85d07857943f677fd1a559b18)
11ccea77eSThomas Gleixner // SPDX-License-Identifier: GPL-2.0-or-later
233aca94dSKalle Valo /*
333aca94dSKalle Valo 	Copyright (C) 2004 - 2009 Ivo van Doorn <IvDoorn@gmail.com>
433aca94dSKalle Valo 	<http://rt2x00.serialmonkey.com>
533aca94dSKalle Valo 
633aca94dSKalle Valo  */
733aca94dSKalle Valo 
833aca94dSKalle Valo /*
933aca94dSKalle Valo 	Module: rt2400pci
1033aca94dSKalle Valo 	Abstract: rt2400pci device specific routines.
1133aca94dSKalle Valo 	Supported chipsets: RT2460.
1233aca94dSKalle Valo  */
1333aca94dSKalle Valo 
1433aca94dSKalle Valo #include <linux/delay.h>
1533aca94dSKalle Valo #include <linux/etherdevice.h>
1633aca94dSKalle Valo #include <linux/kernel.h>
1733aca94dSKalle Valo #include <linux/module.h>
1833aca94dSKalle Valo #include <linux/pci.h>
1933aca94dSKalle Valo #include <linux/eeprom_93cx6.h>
2033aca94dSKalle Valo #include <linux/slab.h>
2133aca94dSKalle Valo 
2233aca94dSKalle Valo #include "rt2x00.h"
2333aca94dSKalle Valo #include "rt2x00mmio.h"
2433aca94dSKalle Valo #include "rt2x00pci.h"
2533aca94dSKalle Valo #include "rt2400pci.h"
2633aca94dSKalle Valo 
2733aca94dSKalle Valo /*
2833aca94dSKalle Valo  * Register access.
2933aca94dSKalle Valo  * All access to the CSR registers will go through the methods
3033aca94dSKalle Valo  * rt2x00mmio_register_read and rt2x00mmio_register_write.
3133aca94dSKalle Valo  * BBP and RF register require indirect register access,
3233aca94dSKalle Valo  * and use the CSR registers BBPCSR and RFCSR to achieve this.
3333aca94dSKalle Valo  * These indirect registers work with busy bits,
3433aca94dSKalle Valo  * and we will try maximal REGISTER_BUSY_COUNT times to access
3533aca94dSKalle Valo  * the register while taking a REGISTER_BUSY_DELAY us delay
3633aca94dSKalle Valo  * between each attempt. When the busy bit is still set at that time,
3733aca94dSKalle Valo  * the access attempt is considered to have failed,
3833aca94dSKalle Valo  * and we will print an error.
3933aca94dSKalle Valo  */
4033aca94dSKalle Valo #define WAIT_FOR_BBP(__dev, __reg) \
4133aca94dSKalle Valo 	rt2x00mmio_regbusy_read((__dev), BBPCSR, BBPCSR_BUSY, (__reg))
4233aca94dSKalle Valo #define WAIT_FOR_RF(__dev, __reg) \
4333aca94dSKalle Valo 	rt2x00mmio_regbusy_read((__dev), RFCSR, RFCSR_BUSY, (__reg))
4433aca94dSKalle Valo 
rt2400pci_bbp_write(struct rt2x00_dev * rt2x00dev,const unsigned int word,const u8 value)4533aca94dSKalle Valo static void rt2400pci_bbp_write(struct rt2x00_dev *rt2x00dev,
4633aca94dSKalle Valo 				const unsigned int word, const u8 value)
4733aca94dSKalle Valo {
4833aca94dSKalle Valo 	u32 reg;
4933aca94dSKalle Valo 
5033aca94dSKalle Valo 	mutex_lock(&rt2x00dev->csr_mutex);
5133aca94dSKalle Valo 
5233aca94dSKalle Valo 	/*
5333aca94dSKalle Valo 	 * Wait until the BBP becomes available, afterwards we
5433aca94dSKalle Valo 	 * can safely write the new data into the register.
5533aca94dSKalle Valo 	 */
5633aca94dSKalle Valo 	if (WAIT_FOR_BBP(rt2x00dev, &reg)) {
5733aca94dSKalle Valo 		reg = 0;
5833aca94dSKalle Valo 		rt2x00_set_field32(&reg, BBPCSR_VALUE, value);
5933aca94dSKalle Valo 		rt2x00_set_field32(&reg, BBPCSR_REGNUM, word);
6033aca94dSKalle Valo 		rt2x00_set_field32(&reg, BBPCSR_BUSY, 1);
6133aca94dSKalle Valo 		rt2x00_set_field32(&reg, BBPCSR_WRITE_CONTROL, 1);
6233aca94dSKalle Valo 
6333aca94dSKalle Valo 		rt2x00mmio_register_write(rt2x00dev, BBPCSR, reg);
6433aca94dSKalle Valo 	}
6533aca94dSKalle Valo 
6633aca94dSKalle Valo 	mutex_unlock(&rt2x00dev->csr_mutex);
6733aca94dSKalle Valo }
6833aca94dSKalle Valo 
rt2400pci_bbp_read(struct rt2x00_dev * rt2x00dev,const unsigned int word)695fbbe378SArnd Bergmann static u8 rt2400pci_bbp_read(struct rt2x00_dev *rt2x00dev,
705fbbe378SArnd Bergmann 			     const unsigned int word)
7133aca94dSKalle Valo {
7233aca94dSKalle Valo 	u32 reg;
735fbbe378SArnd Bergmann 	u8 value;
7433aca94dSKalle Valo 
7533aca94dSKalle Valo 	mutex_lock(&rt2x00dev->csr_mutex);
7633aca94dSKalle Valo 
7733aca94dSKalle Valo 	/*
7833aca94dSKalle Valo 	 * Wait until the BBP becomes available, afterwards we
7933aca94dSKalle Valo 	 * can safely write the read request into the register.
8033aca94dSKalle Valo 	 * After the data has been written, we wait until hardware
8133aca94dSKalle Valo 	 * returns the correct value, if at any time the register
8233aca94dSKalle Valo 	 * doesn't become available in time, reg will be 0xffffffff
8333aca94dSKalle Valo 	 * which means we return 0xff to the caller.
8433aca94dSKalle Valo 	 */
8533aca94dSKalle Valo 	if (WAIT_FOR_BBP(rt2x00dev, &reg)) {
8633aca94dSKalle Valo 		reg = 0;
8733aca94dSKalle Valo 		rt2x00_set_field32(&reg, BBPCSR_REGNUM, word);
8833aca94dSKalle Valo 		rt2x00_set_field32(&reg, BBPCSR_BUSY, 1);
8933aca94dSKalle Valo 		rt2x00_set_field32(&reg, BBPCSR_WRITE_CONTROL, 0);
9033aca94dSKalle Valo 
9133aca94dSKalle Valo 		rt2x00mmio_register_write(rt2x00dev, BBPCSR, reg);
9233aca94dSKalle Valo 
9333aca94dSKalle Valo 		WAIT_FOR_BBP(rt2x00dev, &reg);
9433aca94dSKalle Valo 	}
9533aca94dSKalle Valo 
965fbbe378SArnd Bergmann 	value = rt2x00_get_field32(reg, BBPCSR_VALUE);
9733aca94dSKalle Valo 
9833aca94dSKalle Valo 	mutex_unlock(&rt2x00dev->csr_mutex);
995fbbe378SArnd Bergmann 
1005fbbe378SArnd Bergmann 	return value;
10133aca94dSKalle Valo }
10233aca94dSKalle Valo 
rt2400pci_rf_write(struct rt2x00_dev * rt2x00dev,const unsigned int word,const u32 value)10333aca94dSKalle Valo static void rt2400pci_rf_write(struct rt2x00_dev *rt2x00dev,
10433aca94dSKalle Valo 			       const unsigned int word, const u32 value)
10533aca94dSKalle Valo {
10633aca94dSKalle Valo 	u32 reg;
10733aca94dSKalle Valo 
10833aca94dSKalle Valo 	mutex_lock(&rt2x00dev->csr_mutex);
10933aca94dSKalle Valo 
11033aca94dSKalle Valo 	/*
11133aca94dSKalle Valo 	 * Wait until the RF becomes available, afterwards we
11233aca94dSKalle Valo 	 * can safely write the new data into the register.
11333aca94dSKalle Valo 	 */
11433aca94dSKalle Valo 	if (WAIT_FOR_RF(rt2x00dev, &reg)) {
11533aca94dSKalle Valo 		reg = 0;
11633aca94dSKalle Valo 		rt2x00_set_field32(&reg, RFCSR_VALUE, value);
11733aca94dSKalle Valo 		rt2x00_set_field32(&reg, RFCSR_NUMBER_OF_BITS, 20);
11833aca94dSKalle Valo 		rt2x00_set_field32(&reg, RFCSR_IF_SELECT, 0);
11933aca94dSKalle Valo 		rt2x00_set_field32(&reg, RFCSR_BUSY, 1);
12033aca94dSKalle Valo 
12133aca94dSKalle Valo 		rt2x00mmio_register_write(rt2x00dev, RFCSR, reg);
12233aca94dSKalle Valo 		rt2x00_rf_write(rt2x00dev, word, value);
12333aca94dSKalle Valo 	}
12433aca94dSKalle Valo 
12533aca94dSKalle Valo 	mutex_unlock(&rt2x00dev->csr_mutex);
12633aca94dSKalle Valo }
12733aca94dSKalle Valo 
rt2400pci_eepromregister_read(struct eeprom_93cx6 * eeprom)12833aca94dSKalle Valo static void rt2400pci_eepromregister_read(struct eeprom_93cx6 *eeprom)
12933aca94dSKalle Valo {
13033aca94dSKalle Valo 	struct rt2x00_dev *rt2x00dev = eeprom->data;
13133aca94dSKalle Valo 	u32 reg;
13233aca94dSKalle Valo 
1333954b4e3SArnd Bergmann 	reg = rt2x00mmio_register_read(rt2x00dev, CSR21);
13433aca94dSKalle Valo 
13533aca94dSKalle Valo 	eeprom->reg_data_in = !!rt2x00_get_field32(reg, CSR21_EEPROM_DATA_IN);
13633aca94dSKalle Valo 	eeprom->reg_data_out = !!rt2x00_get_field32(reg, CSR21_EEPROM_DATA_OUT);
13733aca94dSKalle Valo 	eeprom->reg_data_clock =
13833aca94dSKalle Valo 	    !!rt2x00_get_field32(reg, CSR21_EEPROM_DATA_CLOCK);
13933aca94dSKalle Valo 	eeprom->reg_chip_select =
14033aca94dSKalle Valo 	    !!rt2x00_get_field32(reg, CSR21_EEPROM_CHIP_SELECT);
14133aca94dSKalle Valo }
14233aca94dSKalle Valo 
rt2400pci_eepromregister_write(struct eeprom_93cx6 * eeprom)14333aca94dSKalle Valo static void rt2400pci_eepromregister_write(struct eeprom_93cx6 *eeprom)
14433aca94dSKalle Valo {
14533aca94dSKalle Valo 	struct rt2x00_dev *rt2x00dev = eeprom->data;
14633aca94dSKalle Valo 	u32 reg = 0;
14733aca94dSKalle Valo 
14833aca94dSKalle Valo 	rt2x00_set_field32(&reg, CSR21_EEPROM_DATA_IN, !!eeprom->reg_data_in);
14933aca94dSKalle Valo 	rt2x00_set_field32(&reg, CSR21_EEPROM_DATA_OUT, !!eeprom->reg_data_out);
15033aca94dSKalle Valo 	rt2x00_set_field32(&reg, CSR21_EEPROM_DATA_CLOCK,
15133aca94dSKalle Valo 			   !!eeprom->reg_data_clock);
15233aca94dSKalle Valo 	rt2x00_set_field32(&reg, CSR21_EEPROM_CHIP_SELECT,
15333aca94dSKalle Valo 			   !!eeprom->reg_chip_select);
15433aca94dSKalle Valo 
15533aca94dSKalle Valo 	rt2x00mmio_register_write(rt2x00dev, CSR21, reg);
15633aca94dSKalle Valo }
15733aca94dSKalle Valo 
15833aca94dSKalle Valo #ifdef CONFIG_RT2X00_LIB_DEBUGFS
15933aca94dSKalle Valo static const struct rt2x00debug rt2400pci_rt2x00debug = {
16033aca94dSKalle Valo 	.owner	= THIS_MODULE,
16133aca94dSKalle Valo 	.csr	= {
1623954b4e3SArnd Bergmann 		.read		= rt2x00mmio_register_read,
16333aca94dSKalle Valo 		.write		= rt2x00mmio_register_write,
16433aca94dSKalle Valo 		.flags		= RT2X00DEBUGFS_OFFSET,
16533aca94dSKalle Valo 		.word_base	= CSR_REG_BASE,
16633aca94dSKalle Valo 		.word_size	= sizeof(u32),
16733aca94dSKalle Valo 		.word_count	= CSR_REG_SIZE / sizeof(u32),
16833aca94dSKalle Valo 	},
16933aca94dSKalle Valo 	.eeprom	= {
17038651683SArnd Bergmann 		.read		= rt2x00_eeprom_read,
17133aca94dSKalle Valo 		.write		= rt2x00_eeprom_write,
17233aca94dSKalle Valo 		.word_base	= EEPROM_BASE,
17333aca94dSKalle Valo 		.word_size	= sizeof(u16),
17433aca94dSKalle Valo 		.word_count	= EEPROM_SIZE / sizeof(u16),
17533aca94dSKalle Valo 	},
17633aca94dSKalle Valo 	.bbp	= {
1775fbbe378SArnd Bergmann 		.read		= rt2400pci_bbp_read,
17833aca94dSKalle Valo 		.write		= rt2400pci_bbp_write,
17933aca94dSKalle Valo 		.word_base	= BBP_BASE,
18033aca94dSKalle Valo 		.word_size	= sizeof(u8),
18133aca94dSKalle Valo 		.word_count	= BBP_SIZE / sizeof(u8),
18233aca94dSKalle Valo 	},
18333aca94dSKalle Valo 	.rf	= {
184aea8baa1SArnd Bergmann 		.read		= rt2x00_rf_read,
18533aca94dSKalle Valo 		.write		= rt2400pci_rf_write,
18633aca94dSKalle Valo 		.word_base	= RF_BASE,
18733aca94dSKalle Valo 		.word_size	= sizeof(u32),
18833aca94dSKalle Valo 		.word_count	= RF_SIZE / sizeof(u32),
18933aca94dSKalle Valo 	},
19033aca94dSKalle Valo };
19133aca94dSKalle Valo #endif /* CONFIG_RT2X00_LIB_DEBUGFS */
19233aca94dSKalle Valo 
rt2400pci_rfkill_poll(struct rt2x00_dev * rt2x00dev)19333aca94dSKalle Valo static int rt2400pci_rfkill_poll(struct rt2x00_dev *rt2x00dev)
19433aca94dSKalle Valo {
19533aca94dSKalle Valo 	u32 reg;
19633aca94dSKalle Valo 
1973954b4e3SArnd Bergmann 	reg = rt2x00mmio_register_read(rt2x00dev, GPIOCSR);
19833aca94dSKalle Valo 	return rt2x00_get_field32(reg, GPIOCSR_VAL0);
19933aca94dSKalle Valo }
20033aca94dSKalle Valo 
20133aca94dSKalle Valo #ifdef CONFIG_RT2X00_LIB_LEDS
rt2400pci_brightness_set(struct led_classdev * led_cdev,enum led_brightness brightness)20233aca94dSKalle Valo static void rt2400pci_brightness_set(struct led_classdev *led_cdev,
20333aca94dSKalle Valo 				     enum led_brightness brightness)
20433aca94dSKalle Valo {
20533aca94dSKalle Valo 	struct rt2x00_led *led =
20633aca94dSKalle Valo 	    container_of(led_cdev, struct rt2x00_led, led_dev);
20733aca94dSKalle Valo 	unsigned int enabled = brightness != LED_OFF;
20833aca94dSKalle Valo 	u32 reg;
20933aca94dSKalle Valo 
2103954b4e3SArnd Bergmann 	reg = rt2x00mmio_register_read(led->rt2x00dev, LEDCSR);
21133aca94dSKalle Valo 
21233aca94dSKalle Valo 	if (led->type == LED_TYPE_RADIO || led->type == LED_TYPE_ASSOC)
21333aca94dSKalle Valo 		rt2x00_set_field32(&reg, LEDCSR_LINK, enabled);
21433aca94dSKalle Valo 	else if (led->type == LED_TYPE_ACTIVITY)
21533aca94dSKalle Valo 		rt2x00_set_field32(&reg, LEDCSR_ACTIVITY, enabled);
21633aca94dSKalle Valo 
21733aca94dSKalle Valo 	rt2x00mmio_register_write(led->rt2x00dev, LEDCSR, reg);
21833aca94dSKalle Valo }
21933aca94dSKalle Valo 
rt2400pci_blink_set(struct led_classdev * led_cdev,unsigned long * delay_on,unsigned long * delay_off)22033aca94dSKalle Valo static int rt2400pci_blink_set(struct led_classdev *led_cdev,
22133aca94dSKalle Valo 			       unsigned long *delay_on,
22233aca94dSKalle Valo 			       unsigned long *delay_off)
22333aca94dSKalle Valo {
22433aca94dSKalle Valo 	struct rt2x00_led *led =
22533aca94dSKalle Valo 	    container_of(led_cdev, struct rt2x00_led, led_dev);
22633aca94dSKalle Valo 	u32 reg;
22733aca94dSKalle Valo 
2283954b4e3SArnd Bergmann 	reg = rt2x00mmio_register_read(led->rt2x00dev, LEDCSR);
22933aca94dSKalle Valo 	rt2x00_set_field32(&reg, LEDCSR_ON_PERIOD, *delay_on);
23033aca94dSKalle Valo 	rt2x00_set_field32(&reg, LEDCSR_OFF_PERIOD, *delay_off);
23133aca94dSKalle Valo 	rt2x00mmio_register_write(led->rt2x00dev, LEDCSR, reg);
23233aca94dSKalle Valo 
23333aca94dSKalle Valo 	return 0;
23433aca94dSKalle Valo }
23533aca94dSKalle Valo 
rt2400pci_init_led(struct rt2x00_dev * rt2x00dev,struct rt2x00_led * led,enum led_type type)23633aca94dSKalle Valo static void rt2400pci_init_led(struct rt2x00_dev *rt2x00dev,
23733aca94dSKalle Valo 			       struct rt2x00_led *led,
23833aca94dSKalle Valo 			       enum led_type type)
23933aca94dSKalle Valo {
24033aca94dSKalle Valo 	led->rt2x00dev = rt2x00dev;
24133aca94dSKalle Valo 	led->type = type;
24233aca94dSKalle Valo 	led->led_dev.brightness_set = rt2400pci_brightness_set;
24333aca94dSKalle Valo 	led->led_dev.blink_set = rt2400pci_blink_set;
24433aca94dSKalle Valo 	led->flags = LED_INITIALIZED;
24533aca94dSKalle Valo }
24633aca94dSKalle Valo #endif /* CONFIG_RT2X00_LIB_LEDS */
24733aca94dSKalle Valo 
24833aca94dSKalle Valo /*
24933aca94dSKalle Valo  * Configuration handlers.
25033aca94dSKalle Valo  */
rt2400pci_config_filter(struct rt2x00_dev * rt2x00dev,const unsigned int filter_flags)25133aca94dSKalle Valo static void rt2400pci_config_filter(struct rt2x00_dev *rt2x00dev,
25233aca94dSKalle Valo 				    const unsigned int filter_flags)
25333aca94dSKalle Valo {
25433aca94dSKalle Valo 	u32 reg;
25533aca94dSKalle Valo 
25633aca94dSKalle Valo 	/*
25733aca94dSKalle Valo 	 * Start configuration steps.
25833aca94dSKalle Valo 	 * Note that the version error will always be dropped
25933aca94dSKalle Valo 	 * since there is no filter for it at this time.
26033aca94dSKalle Valo 	 */
2613954b4e3SArnd Bergmann 	reg = rt2x00mmio_register_read(rt2x00dev, RXCSR0);
26233aca94dSKalle Valo 	rt2x00_set_field32(&reg, RXCSR0_DROP_CRC,
26333aca94dSKalle Valo 			   !(filter_flags & FIF_FCSFAIL));
26433aca94dSKalle Valo 	rt2x00_set_field32(&reg, RXCSR0_DROP_PHYSICAL,
26533aca94dSKalle Valo 			   !(filter_flags & FIF_PLCPFAIL));
26633aca94dSKalle Valo 	rt2x00_set_field32(&reg, RXCSR0_DROP_CONTROL,
26733aca94dSKalle Valo 			   !(filter_flags & FIF_CONTROL));
268262c741eSEli Cooper 	rt2x00_set_field32(&reg, RXCSR0_DROP_NOT_TO_ME,
269262c741eSEli Cooper 			   !test_bit(CONFIG_MONITORING, &rt2x00dev->flags));
27033aca94dSKalle Valo 	rt2x00_set_field32(&reg, RXCSR0_DROP_TODS,
271262c741eSEli Cooper 			   !test_bit(CONFIG_MONITORING, &rt2x00dev->flags) &&
27233aca94dSKalle Valo 			   !rt2x00dev->intf_ap_count);
27333aca94dSKalle Valo 	rt2x00_set_field32(&reg, RXCSR0_DROP_VERSION_ERROR, 1);
27433aca94dSKalle Valo 	rt2x00mmio_register_write(rt2x00dev, RXCSR0, reg);
27533aca94dSKalle Valo }
27633aca94dSKalle Valo 
rt2400pci_config_intf(struct rt2x00_dev * rt2x00dev,struct rt2x00_intf * intf,struct rt2x00intf_conf * conf,const unsigned int flags)27733aca94dSKalle Valo static void rt2400pci_config_intf(struct rt2x00_dev *rt2x00dev,
27833aca94dSKalle Valo 				  struct rt2x00_intf *intf,
27933aca94dSKalle Valo 				  struct rt2x00intf_conf *conf,
28033aca94dSKalle Valo 				  const unsigned int flags)
28133aca94dSKalle Valo {
28233aca94dSKalle Valo 	unsigned int bcn_preload;
28333aca94dSKalle Valo 	u32 reg;
28433aca94dSKalle Valo 
28533aca94dSKalle Valo 	if (flags & CONFIG_UPDATE_TYPE) {
28633aca94dSKalle Valo 		/*
28733aca94dSKalle Valo 		 * Enable beacon config
28833aca94dSKalle Valo 		 */
28933aca94dSKalle Valo 		bcn_preload = PREAMBLE + GET_DURATION(IEEE80211_HEADER, 20);
2903954b4e3SArnd Bergmann 		reg = rt2x00mmio_register_read(rt2x00dev, BCNCSR1);
29133aca94dSKalle Valo 		rt2x00_set_field32(&reg, BCNCSR1_PRELOAD, bcn_preload);
29233aca94dSKalle Valo 		rt2x00mmio_register_write(rt2x00dev, BCNCSR1, reg);
29333aca94dSKalle Valo 
29433aca94dSKalle Valo 		/*
29533aca94dSKalle Valo 		 * Enable synchronisation.
29633aca94dSKalle Valo 		 */
2973954b4e3SArnd Bergmann 		reg = rt2x00mmio_register_read(rt2x00dev, CSR14);
29833aca94dSKalle Valo 		rt2x00_set_field32(&reg, CSR14_TSF_SYNC, conf->sync);
29933aca94dSKalle Valo 		rt2x00mmio_register_write(rt2x00dev, CSR14, reg);
30033aca94dSKalle Valo 	}
30133aca94dSKalle Valo 
30233aca94dSKalle Valo 	if (flags & CONFIG_UPDATE_MAC)
30333aca94dSKalle Valo 		rt2x00mmio_register_multiwrite(rt2x00dev, CSR3,
30433aca94dSKalle Valo 					       conf->mac, sizeof(conf->mac));
30533aca94dSKalle Valo 
30633aca94dSKalle Valo 	if (flags & CONFIG_UPDATE_BSSID)
30733aca94dSKalle Valo 		rt2x00mmio_register_multiwrite(rt2x00dev, CSR5,
30833aca94dSKalle Valo 					       conf->bssid,
30933aca94dSKalle Valo 					       sizeof(conf->bssid));
31033aca94dSKalle Valo }
31133aca94dSKalle Valo 
rt2400pci_config_erp(struct rt2x00_dev * rt2x00dev,struct rt2x00lib_erp * erp,u32 changed)31233aca94dSKalle Valo static void rt2400pci_config_erp(struct rt2x00_dev *rt2x00dev,
31333aca94dSKalle Valo 				 struct rt2x00lib_erp *erp,
31433aca94dSKalle Valo 				 u32 changed)
31533aca94dSKalle Valo {
31633aca94dSKalle Valo 	int preamble_mask;
31733aca94dSKalle Valo 	u32 reg;
31833aca94dSKalle Valo 
31933aca94dSKalle Valo 	/*
32033aca94dSKalle Valo 	 * When short preamble is enabled, we should set bit 0x08
32133aca94dSKalle Valo 	 */
32233aca94dSKalle Valo 	if (changed & BSS_CHANGED_ERP_PREAMBLE) {
32333aca94dSKalle Valo 		preamble_mask = erp->short_preamble << 3;
32433aca94dSKalle Valo 
3253954b4e3SArnd Bergmann 		reg = rt2x00mmio_register_read(rt2x00dev, TXCSR1);
32633aca94dSKalle Valo 		rt2x00_set_field32(&reg, TXCSR1_ACK_TIMEOUT, 0x1ff);
32733aca94dSKalle Valo 		rt2x00_set_field32(&reg, TXCSR1_ACK_CONSUME_TIME, 0x13a);
32833aca94dSKalle Valo 		rt2x00_set_field32(&reg, TXCSR1_TSF_OFFSET, IEEE80211_HEADER);
32933aca94dSKalle Valo 		rt2x00_set_field32(&reg, TXCSR1_AUTORESPONDER, 1);
33033aca94dSKalle Valo 		rt2x00mmio_register_write(rt2x00dev, TXCSR1, reg);
33133aca94dSKalle Valo 
3323954b4e3SArnd Bergmann 		reg = rt2x00mmio_register_read(rt2x00dev, ARCSR2);
33333aca94dSKalle Valo 		rt2x00_set_field32(&reg, ARCSR2_SIGNAL, 0x00);
33433aca94dSKalle Valo 		rt2x00_set_field32(&reg, ARCSR2_SERVICE, 0x04);
33533aca94dSKalle Valo 		rt2x00_set_field32(&reg, ARCSR2_LENGTH,
33633aca94dSKalle Valo 				   GET_DURATION(ACK_SIZE, 10));
33733aca94dSKalle Valo 		rt2x00mmio_register_write(rt2x00dev, ARCSR2, reg);
33833aca94dSKalle Valo 
3393954b4e3SArnd Bergmann 		reg = rt2x00mmio_register_read(rt2x00dev, ARCSR3);
34033aca94dSKalle Valo 		rt2x00_set_field32(&reg, ARCSR3_SIGNAL, 0x01 | preamble_mask);
34133aca94dSKalle Valo 		rt2x00_set_field32(&reg, ARCSR3_SERVICE, 0x04);
34233aca94dSKalle Valo 		rt2x00_set_field32(&reg, ARCSR2_LENGTH,
34333aca94dSKalle Valo 				   GET_DURATION(ACK_SIZE, 20));
34433aca94dSKalle Valo 		rt2x00mmio_register_write(rt2x00dev, ARCSR3, reg);
34533aca94dSKalle Valo 
3463954b4e3SArnd Bergmann 		reg = rt2x00mmio_register_read(rt2x00dev, ARCSR4);
34733aca94dSKalle Valo 		rt2x00_set_field32(&reg, ARCSR4_SIGNAL, 0x02 | preamble_mask);
34833aca94dSKalle Valo 		rt2x00_set_field32(&reg, ARCSR4_SERVICE, 0x04);
34933aca94dSKalle Valo 		rt2x00_set_field32(&reg, ARCSR2_LENGTH,
35033aca94dSKalle Valo 				   GET_DURATION(ACK_SIZE, 55));
35133aca94dSKalle Valo 		rt2x00mmio_register_write(rt2x00dev, ARCSR4, reg);
35233aca94dSKalle Valo 
3533954b4e3SArnd Bergmann 		reg = rt2x00mmio_register_read(rt2x00dev, ARCSR5);
35433aca94dSKalle Valo 		rt2x00_set_field32(&reg, ARCSR5_SIGNAL, 0x03 | preamble_mask);
35533aca94dSKalle Valo 		rt2x00_set_field32(&reg, ARCSR5_SERVICE, 0x84);
35633aca94dSKalle Valo 		rt2x00_set_field32(&reg, ARCSR2_LENGTH,
35733aca94dSKalle Valo 				   GET_DURATION(ACK_SIZE, 110));
35833aca94dSKalle Valo 		rt2x00mmio_register_write(rt2x00dev, ARCSR5, reg);
35933aca94dSKalle Valo 	}
36033aca94dSKalle Valo 
36133aca94dSKalle Valo 	if (changed & BSS_CHANGED_BASIC_RATES)
36233aca94dSKalle Valo 		rt2x00mmio_register_write(rt2x00dev, ARCSR1, erp->basic_rates);
36333aca94dSKalle Valo 
36433aca94dSKalle Valo 	if (changed & BSS_CHANGED_ERP_SLOT) {
3653954b4e3SArnd Bergmann 		reg = rt2x00mmio_register_read(rt2x00dev, CSR11);
36633aca94dSKalle Valo 		rt2x00_set_field32(&reg, CSR11_SLOT_TIME, erp->slot_time);
36733aca94dSKalle Valo 		rt2x00mmio_register_write(rt2x00dev, CSR11, reg);
36833aca94dSKalle Valo 
3693954b4e3SArnd Bergmann 		reg = rt2x00mmio_register_read(rt2x00dev, CSR18);
37033aca94dSKalle Valo 		rt2x00_set_field32(&reg, CSR18_SIFS, erp->sifs);
37133aca94dSKalle Valo 		rt2x00_set_field32(&reg, CSR18_PIFS, erp->pifs);
37233aca94dSKalle Valo 		rt2x00mmio_register_write(rt2x00dev, CSR18, reg);
37333aca94dSKalle Valo 
3743954b4e3SArnd Bergmann 		reg = rt2x00mmio_register_read(rt2x00dev, CSR19);
37533aca94dSKalle Valo 		rt2x00_set_field32(&reg, CSR19_DIFS, erp->difs);
37633aca94dSKalle Valo 		rt2x00_set_field32(&reg, CSR19_EIFS, erp->eifs);
37733aca94dSKalle Valo 		rt2x00mmio_register_write(rt2x00dev, CSR19, reg);
37833aca94dSKalle Valo 	}
37933aca94dSKalle Valo 
38033aca94dSKalle Valo 	if (changed & BSS_CHANGED_BEACON_INT) {
3813954b4e3SArnd Bergmann 		reg = rt2x00mmio_register_read(rt2x00dev, CSR12);
38233aca94dSKalle Valo 		rt2x00_set_field32(&reg, CSR12_BEACON_INTERVAL,
38333aca94dSKalle Valo 				   erp->beacon_int * 16);
38433aca94dSKalle Valo 		rt2x00_set_field32(&reg, CSR12_CFP_MAX_DURATION,
38533aca94dSKalle Valo 				   erp->beacon_int * 16);
38633aca94dSKalle Valo 		rt2x00mmio_register_write(rt2x00dev, CSR12, reg);
38733aca94dSKalle Valo 	}
38833aca94dSKalle Valo }
38933aca94dSKalle Valo 
rt2400pci_config_ant(struct rt2x00_dev * rt2x00dev,struct antenna_setup * ant)39033aca94dSKalle Valo static void rt2400pci_config_ant(struct rt2x00_dev *rt2x00dev,
39133aca94dSKalle Valo 				 struct antenna_setup *ant)
39233aca94dSKalle Valo {
39333aca94dSKalle Valo 	u8 r1;
39433aca94dSKalle Valo 	u8 r4;
39533aca94dSKalle Valo 
39633aca94dSKalle Valo 	/*
39733aca94dSKalle Valo 	 * We should never come here because rt2x00lib is supposed
39833aca94dSKalle Valo 	 * to catch this and send us the correct antenna explicitely.
39933aca94dSKalle Valo 	 */
40033aca94dSKalle Valo 	BUG_ON(ant->rx == ANTENNA_SW_DIVERSITY ||
40133aca94dSKalle Valo 	       ant->tx == ANTENNA_SW_DIVERSITY);
40233aca94dSKalle Valo 
4035fbbe378SArnd Bergmann 	r4 = rt2400pci_bbp_read(rt2x00dev, 4);
4045fbbe378SArnd Bergmann 	r1 = rt2400pci_bbp_read(rt2x00dev, 1);
40533aca94dSKalle Valo 
40633aca94dSKalle Valo 	/*
40733aca94dSKalle Valo 	 * Configure the TX antenna.
40833aca94dSKalle Valo 	 */
40933aca94dSKalle Valo 	switch (ant->tx) {
41033aca94dSKalle Valo 	case ANTENNA_HW_DIVERSITY:
41133aca94dSKalle Valo 		rt2x00_set_field8(&r1, BBP_R1_TX_ANTENNA, 1);
41233aca94dSKalle Valo 		break;
41333aca94dSKalle Valo 	case ANTENNA_A:
41433aca94dSKalle Valo 		rt2x00_set_field8(&r1, BBP_R1_TX_ANTENNA, 0);
41533aca94dSKalle Valo 		break;
41633aca94dSKalle Valo 	case ANTENNA_B:
41733aca94dSKalle Valo 	default:
41833aca94dSKalle Valo 		rt2x00_set_field8(&r1, BBP_R1_TX_ANTENNA, 2);
41933aca94dSKalle Valo 		break;
42033aca94dSKalle Valo 	}
42133aca94dSKalle Valo 
42233aca94dSKalle Valo 	/*
42333aca94dSKalle Valo 	 * Configure the RX antenna.
42433aca94dSKalle Valo 	 */
42533aca94dSKalle Valo 	switch (ant->rx) {
42633aca94dSKalle Valo 	case ANTENNA_HW_DIVERSITY:
42733aca94dSKalle Valo 		rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA, 1);
42833aca94dSKalle Valo 		break;
42933aca94dSKalle Valo 	case ANTENNA_A:
43033aca94dSKalle Valo 		rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA, 0);
43133aca94dSKalle Valo 		break;
43233aca94dSKalle Valo 	case ANTENNA_B:
43333aca94dSKalle Valo 	default:
43433aca94dSKalle Valo 		rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA, 2);
43533aca94dSKalle Valo 		break;
43633aca94dSKalle Valo 	}
43733aca94dSKalle Valo 
43833aca94dSKalle Valo 	rt2400pci_bbp_write(rt2x00dev, 4, r4);
43933aca94dSKalle Valo 	rt2400pci_bbp_write(rt2x00dev, 1, r1);
44033aca94dSKalle Valo }
44133aca94dSKalle Valo 
rt2400pci_config_channel(struct rt2x00_dev * rt2x00dev,struct rf_channel * rf)44233aca94dSKalle Valo static void rt2400pci_config_channel(struct rt2x00_dev *rt2x00dev,
44333aca94dSKalle Valo 				     struct rf_channel *rf)
44433aca94dSKalle Valo {
44533aca94dSKalle Valo 	/*
44633aca94dSKalle Valo 	 * Switch on tuning bits.
44733aca94dSKalle Valo 	 */
44833aca94dSKalle Valo 	rt2x00_set_field32(&rf->rf1, RF1_TUNER, 1);
44933aca94dSKalle Valo 	rt2x00_set_field32(&rf->rf3, RF3_TUNER, 1);
45033aca94dSKalle Valo 
45133aca94dSKalle Valo 	rt2400pci_rf_write(rt2x00dev, 1, rf->rf1);
45233aca94dSKalle Valo 	rt2400pci_rf_write(rt2x00dev, 2, rf->rf2);
45333aca94dSKalle Valo 	rt2400pci_rf_write(rt2x00dev, 3, rf->rf3);
45433aca94dSKalle Valo 
45533aca94dSKalle Valo 	/*
45633aca94dSKalle Valo 	 * RF2420 chipset don't need any additional actions.
45733aca94dSKalle Valo 	 */
45833aca94dSKalle Valo 	if (rt2x00_rf(rt2x00dev, RF2420))
45933aca94dSKalle Valo 		return;
46033aca94dSKalle Valo 
46133aca94dSKalle Valo 	/*
46233aca94dSKalle Valo 	 * For the RT2421 chipsets we need to write an invalid
46333aca94dSKalle Valo 	 * reference clock rate to activate auto_tune.
46433aca94dSKalle Valo 	 * After that we set the value back to the correct channel.
46533aca94dSKalle Valo 	 */
46633aca94dSKalle Valo 	rt2400pci_rf_write(rt2x00dev, 1, rf->rf1);
46733aca94dSKalle Valo 	rt2400pci_rf_write(rt2x00dev, 2, 0x000c2a32);
46833aca94dSKalle Valo 	rt2400pci_rf_write(rt2x00dev, 3, rf->rf3);
46933aca94dSKalle Valo 
47033aca94dSKalle Valo 	msleep(1);
47133aca94dSKalle Valo 
47233aca94dSKalle Valo 	rt2400pci_rf_write(rt2x00dev, 1, rf->rf1);
47333aca94dSKalle Valo 	rt2400pci_rf_write(rt2x00dev, 2, rf->rf2);
47433aca94dSKalle Valo 	rt2400pci_rf_write(rt2x00dev, 3, rf->rf3);
47533aca94dSKalle Valo 
47633aca94dSKalle Valo 	msleep(1);
47733aca94dSKalle Valo 
47833aca94dSKalle Valo 	/*
47933aca94dSKalle Valo 	 * Switch off tuning bits.
48033aca94dSKalle Valo 	 */
48133aca94dSKalle Valo 	rt2x00_set_field32(&rf->rf1, RF1_TUNER, 0);
48233aca94dSKalle Valo 	rt2x00_set_field32(&rf->rf3, RF3_TUNER, 0);
48333aca94dSKalle Valo 
48433aca94dSKalle Valo 	rt2400pci_rf_write(rt2x00dev, 1, rf->rf1);
48533aca94dSKalle Valo 	rt2400pci_rf_write(rt2x00dev, 3, rf->rf3);
48633aca94dSKalle Valo 
48733aca94dSKalle Valo 	/*
48833aca94dSKalle Valo 	 * Clear false CRC during channel switch.
48933aca94dSKalle Valo 	 */
4903954b4e3SArnd Bergmann 	rf->rf1 = rt2x00mmio_register_read(rt2x00dev, CNT0);
49133aca94dSKalle Valo }
49233aca94dSKalle Valo 
rt2400pci_config_txpower(struct rt2x00_dev * rt2x00dev,int txpower)49333aca94dSKalle Valo static void rt2400pci_config_txpower(struct rt2x00_dev *rt2x00dev, int txpower)
49433aca94dSKalle Valo {
49533aca94dSKalle Valo 	rt2400pci_bbp_write(rt2x00dev, 3, TXPOWER_TO_DEV(txpower));
49633aca94dSKalle Valo }
49733aca94dSKalle Valo 
rt2400pci_config_retry_limit(struct rt2x00_dev * rt2x00dev,struct rt2x00lib_conf * libconf)49833aca94dSKalle Valo static void rt2400pci_config_retry_limit(struct rt2x00_dev *rt2x00dev,
49933aca94dSKalle Valo 					 struct rt2x00lib_conf *libconf)
50033aca94dSKalle Valo {
50133aca94dSKalle Valo 	u32 reg;
50233aca94dSKalle Valo 
5033954b4e3SArnd Bergmann 	reg = rt2x00mmio_register_read(rt2x00dev, CSR11);
50433aca94dSKalle Valo 	rt2x00_set_field32(&reg, CSR11_LONG_RETRY,
50533aca94dSKalle Valo 			   libconf->conf->long_frame_max_tx_count);
50633aca94dSKalle Valo 	rt2x00_set_field32(&reg, CSR11_SHORT_RETRY,
50733aca94dSKalle Valo 			   libconf->conf->short_frame_max_tx_count);
50833aca94dSKalle Valo 	rt2x00mmio_register_write(rt2x00dev, CSR11, reg);
50933aca94dSKalle Valo }
51033aca94dSKalle Valo 
rt2400pci_config_ps(struct rt2x00_dev * rt2x00dev,struct rt2x00lib_conf * libconf)51133aca94dSKalle Valo static void rt2400pci_config_ps(struct rt2x00_dev *rt2x00dev,
51233aca94dSKalle Valo 				struct rt2x00lib_conf *libconf)
51333aca94dSKalle Valo {
51433aca94dSKalle Valo 	enum dev_state state =
51533aca94dSKalle Valo 	    (libconf->conf->flags & IEEE80211_CONF_PS) ?
51633aca94dSKalle Valo 		STATE_SLEEP : STATE_AWAKE;
51733aca94dSKalle Valo 	u32 reg;
51833aca94dSKalle Valo 
51933aca94dSKalle Valo 	if (state == STATE_SLEEP) {
5203954b4e3SArnd Bergmann 		reg = rt2x00mmio_register_read(rt2x00dev, CSR20);
52133aca94dSKalle Valo 		rt2x00_set_field32(&reg, CSR20_DELAY_AFTER_TBCN,
52233aca94dSKalle Valo 				   (rt2x00dev->beacon_int - 20) * 16);
52333aca94dSKalle Valo 		rt2x00_set_field32(&reg, CSR20_TBCN_BEFORE_WAKEUP,
52433aca94dSKalle Valo 				   libconf->conf->listen_interval - 1);
52533aca94dSKalle Valo 
52633aca94dSKalle Valo 		/* We must first disable autowake before it can be enabled */
52733aca94dSKalle Valo 		rt2x00_set_field32(&reg, CSR20_AUTOWAKE, 0);
52833aca94dSKalle Valo 		rt2x00mmio_register_write(rt2x00dev, CSR20, reg);
52933aca94dSKalle Valo 
53033aca94dSKalle Valo 		rt2x00_set_field32(&reg, CSR20_AUTOWAKE, 1);
53133aca94dSKalle Valo 		rt2x00mmio_register_write(rt2x00dev, CSR20, reg);
53233aca94dSKalle Valo 	} else {
5333954b4e3SArnd Bergmann 		reg = rt2x00mmio_register_read(rt2x00dev, CSR20);
53433aca94dSKalle Valo 		rt2x00_set_field32(&reg, CSR20_AUTOWAKE, 0);
53533aca94dSKalle Valo 		rt2x00mmio_register_write(rt2x00dev, CSR20, reg);
53633aca94dSKalle Valo 	}
53733aca94dSKalle Valo 
53833aca94dSKalle Valo 	rt2x00dev->ops->lib->set_device_state(rt2x00dev, state);
53933aca94dSKalle Valo }
54033aca94dSKalle Valo 
rt2400pci_config(struct rt2x00_dev * rt2x00dev,struct rt2x00lib_conf * libconf,const unsigned int flags)54133aca94dSKalle Valo static void rt2400pci_config(struct rt2x00_dev *rt2x00dev,
54233aca94dSKalle Valo 			     struct rt2x00lib_conf *libconf,
54333aca94dSKalle Valo 			     const unsigned int flags)
54433aca94dSKalle Valo {
54533aca94dSKalle Valo 	if (flags & IEEE80211_CONF_CHANGE_CHANNEL)
54633aca94dSKalle Valo 		rt2400pci_config_channel(rt2x00dev, &libconf->rf);
54733aca94dSKalle Valo 	if (flags & IEEE80211_CONF_CHANGE_POWER)
54833aca94dSKalle Valo 		rt2400pci_config_txpower(rt2x00dev,
54933aca94dSKalle Valo 					 libconf->conf->power_level);
55033aca94dSKalle Valo 	if (flags & IEEE80211_CONF_CHANGE_RETRY_LIMITS)
55133aca94dSKalle Valo 		rt2400pci_config_retry_limit(rt2x00dev, libconf);
55233aca94dSKalle Valo 	if (flags & IEEE80211_CONF_CHANGE_PS)
55333aca94dSKalle Valo 		rt2400pci_config_ps(rt2x00dev, libconf);
55433aca94dSKalle Valo }
55533aca94dSKalle Valo 
rt2400pci_config_cw(struct rt2x00_dev * rt2x00dev,const int cw_min,const int cw_max)55633aca94dSKalle Valo static void rt2400pci_config_cw(struct rt2x00_dev *rt2x00dev,
55733aca94dSKalle Valo 				const int cw_min, const int cw_max)
55833aca94dSKalle Valo {
55933aca94dSKalle Valo 	u32 reg;
56033aca94dSKalle Valo 
5613954b4e3SArnd Bergmann 	reg = rt2x00mmio_register_read(rt2x00dev, CSR11);
56233aca94dSKalle Valo 	rt2x00_set_field32(&reg, CSR11_CWMIN, cw_min);
56333aca94dSKalle Valo 	rt2x00_set_field32(&reg, CSR11_CWMAX, cw_max);
56433aca94dSKalle Valo 	rt2x00mmio_register_write(rt2x00dev, CSR11, reg);
56533aca94dSKalle Valo }
56633aca94dSKalle Valo 
56733aca94dSKalle Valo /*
56833aca94dSKalle Valo  * Link tuning
56933aca94dSKalle Valo  */
rt2400pci_link_stats(struct rt2x00_dev * rt2x00dev,struct link_qual * qual)57033aca94dSKalle Valo static void rt2400pci_link_stats(struct rt2x00_dev *rt2x00dev,
57133aca94dSKalle Valo 				 struct link_qual *qual)
57233aca94dSKalle Valo {
57333aca94dSKalle Valo 	u32 reg;
57433aca94dSKalle Valo 	u8 bbp;
57533aca94dSKalle Valo 
57633aca94dSKalle Valo 	/*
57733aca94dSKalle Valo 	 * Update FCS error count from register.
57833aca94dSKalle Valo 	 */
5793954b4e3SArnd Bergmann 	reg = rt2x00mmio_register_read(rt2x00dev, CNT0);
58033aca94dSKalle Valo 	qual->rx_failed = rt2x00_get_field32(reg, CNT0_FCS_ERROR);
58133aca94dSKalle Valo 
58233aca94dSKalle Valo 	/*
58333aca94dSKalle Valo 	 * Update False CCA count from register.
58433aca94dSKalle Valo 	 */
5855fbbe378SArnd Bergmann 	bbp = rt2400pci_bbp_read(rt2x00dev, 39);
58633aca94dSKalle Valo 	qual->false_cca = bbp;
58733aca94dSKalle Valo }
58833aca94dSKalle Valo 
rt2400pci_set_vgc(struct rt2x00_dev * rt2x00dev,struct link_qual * qual,u8 vgc_level)58933aca94dSKalle Valo static inline void rt2400pci_set_vgc(struct rt2x00_dev *rt2x00dev,
59033aca94dSKalle Valo 				     struct link_qual *qual, u8 vgc_level)
59133aca94dSKalle Valo {
59233aca94dSKalle Valo 	if (qual->vgc_level_reg != vgc_level) {
59333aca94dSKalle Valo 		rt2400pci_bbp_write(rt2x00dev, 13, vgc_level);
59433aca94dSKalle Valo 		qual->vgc_level = vgc_level;
59533aca94dSKalle Valo 		qual->vgc_level_reg = vgc_level;
59633aca94dSKalle Valo 	}
59733aca94dSKalle Valo }
59833aca94dSKalle Valo 
rt2400pci_reset_tuner(struct rt2x00_dev * rt2x00dev,struct link_qual * qual)59933aca94dSKalle Valo static void rt2400pci_reset_tuner(struct rt2x00_dev *rt2x00dev,
60033aca94dSKalle Valo 				  struct link_qual *qual)
60133aca94dSKalle Valo {
60233aca94dSKalle Valo 	rt2400pci_set_vgc(rt2x00dev, qual, 0x08);
60333aca94dSKalle Valo }
60433aca94dSKalle Valo 
rt2400pci_link_tuner(struct rt2x00_dev * rt2x00dev,struct link_qual * qual,const u32 count)60533aca94dSKalle Valo static void rt2400pci_link_tuner(struct rt2x00_dev *rt2x00dev,
60633aca94dSKalle Valo 				 struct link_qual *qual, const u32 count)
60733aca94dSKalle Valo {
60833aca94dSKalle Valo 	/*
60933aca94dSKalle Valo 	 * The link tuner should not run longer then 60 seconds,
61033aca94dSKalle Valo 	 * and should run once every 2 seconds.
61133aca94dSKalle Valo 	 */
61233aca94dSKalle Valo 	if (count > 60 || !(count & 1))
61333aca94dSKalle Valo 		return;
61433aca94dSKalle Valo 
61533aca94dSKalle Valo 	/*
61633aca94dSKalle Valo 	 * Base r13 link tuning on the false cca count.
61733aca94dSKalle Valo 	 */
61833aca94dSKalle Valo 	if ((qual->false_cca > 512) && (qual->vgc_level < 0x20))
61933aca94dSKalle Valo 		rt2400pci_set_vgc(rt2x00dev, qual, ++qual->vgc_level);
62033aca94dSKalle Valo 	else if ((qual->false_cca < 100) && (qual->vgc_level > 0x08))
62133aca94dSKalle Valo 		rt2400pci_set_vgc(rt2x00dev, qual, --qual->vgc_level);
62233aca94dSKalle Valo }
62333aca94dSKalle Valo 
62433aca94dSKalle Valo /*
62533aca94dSKalle Valo  * Queue handlers.
62633aca94dSKalle Valo  */
rt2400pci_start_queue(struct data_queue * queue)62733aca94dSKalle Valo static void rt2400pci_start_queue(struct data_queue *queue)
62833aca94dSKalle Valo {
62933aca94dSKalle Valo 	struct rt2x00_dev *rt2x00dev = queue->rt2x00dev;
63033aca94dSKalle Valo 	u32 reg;
63133aca94dSKalle Valo 
63233aca94dSKalle Valo 	switch (queue->qid) {
63333aca94dSKalle Valo 	case QID_RX:
6343954b4e3SArnd Bergmann 		reg = rt2x00mmio_register_read(rt2x00dev, RXCSR0);
63533aca94dSKalle Valo 		rt2x00_set_field32(&reg, RXCSR0_DISABLE_RX, 0);
63633aca94dSKalle Valo 		rt2x00mmio_register_write(rt2x00dev, RXCSR0, reg);
63733aca94dSKalle Valo 		break;
63833aca94dSKalle Valo 	case QID_BEACON:
6393954b4e3SArnd Bergmann 		reg = rt2x00mmio_register_read(rt2x00dev, CSR14);
64033aca94dSKalle Valo 		rt2x00_set_field32(&reg, CSR14_TSF_COUNT, 1);
64133aca94dSKalle Valo 		rt2x00_set_field32(&reg, CSR14_TBCN, 1);
64233aca94dSKalle Valo 		rt2x00_set_field32(&reg, CSR14_BEACON_GEN, 1);
64333aca94dSKalle Valo 		rt2x00mmio_register_write(rt2x00dev, CSR14, reg);
64433aca94dSKalle Valo 		break;
64533aca94dSKalle Valo 	default:
64633aca94dSKalle Valo 		break;
64733aca94dSKalle Valo 	}
64833aca94dSKalle Valo }
64933aca94dSKalle Valo 
rt2400pci_kick_queue(struct data_queue * queue)65033aca94dSKalle Valo static void rt2400pci_kick_queue(struct data_queue *queue)
65133aca94dSKalle Valo {
65233aca94dSKalle Valo 	struct rt2x00_dev *rt2x00dev = queue->rt2x00dev;
65333aca94dSKalle Valo 	u32 reg;
65433aca94dSKalle Valo 
65533aca94dSKalle Valo 	switch (queue->qid) {
65633aca94dSKalle Valo 	case QID_AC_VO:
6573954b4e3SArnd Bergmann 		reg = rt2x00mmio_register_read(rt2x00dev, TXCSR0);
65833aca94dSKalle Valo 		rt2x00_set_field32(&reg, TXCSR0_KICK_PRIO, 1);
65933aca94dSKalle Valo 		rt2x00mmio_register_write(rt2x00dev, TXCSR0, reg);
66033aca94dSKalle Valo 		break;
66133aca94dSKalle Valo 	case QID_AC_VI:
6623954b4e3SArnd Bergmann 		reg = rt2x00mmio_register_read(rt2x00dev, TXCSR0);
66333aca94dSKalle Valo 		rt2x00_set_field32(&reg, TXCSR0_KICK_TX, 1);
66433aca94dSKalle Valo 		rt2x00mmio_register_write(rt2x00dev, TXCSR0, reg);
66533aca94dSKalle Valo 		break;
66633aca94dSKalle Valo 	case QID_ATIM:
6673954b4e3SArnd Bergmann 		reg = rt2x00mmio_register_read(rt2x00dev, TXCSR0);
66833aca94dSKalle Valo 		rt2x00_set_field32(&reg, TXCSR0_KICK_ATIM, 1);
66933aca94dSKalle Valo 		rt2x00mmio_register_write(rt2x00dev, TXCSR0, reg);
67033aca94dSKalle Valo 		break;
67133aca94dSKalle Valo 	default:
67233aca94dSKalle Valo 		break;
67333aca94dSKalle Valo 	}
67433aca94dSKalle Valo }
67533aca94dSKalle Valo 
rt2400pci_stop_queue(struct data_queue * queue)67633aca94dSKalle Valo static void rt2400pci_stop_queue(struct data_queue *queue)
67733aca94dSKalle Valo {
67833aca94dSKalle Valo 	struct rt2x00_dev *rt2x00dev = queue->rt2x00dev;
67933aca94dSKalle Valo 	u32 reg;
68033aca94dSKalle Valo 
68133aca94dSKalle Valo 	switch (queue->qid) {
68233aca94dSKalle Valo 	case QID_AC_VO:
68333aca94dSKalle Valo 	case QID_AC_VI:
68433aca94dSKalle Valo 	case QID_ATIM:
6853954b4e3SArnd Bergmann 		reg = rt2x00mmio_register_read(rt2x00dev, TXCSR0);
68633aca94dSKalle Valo 		rt2x00_set_field32(&reg, TXCSR0_ABORT, 1);
68733aca94dSKalle Valo 		rt2x00mmio_register_write(rt2x00dev, TXCSR0, reg);
68833aca94dSKalle Valo 		break;
68933aca94dSKalle Valo 	case QID_RX:
6903954b4e3SArnd Bergmann 		reg = rt2x00mmio_register_read(rt2x00dev, RXCSR0);
69133aca94dSKalle Valo 		rt2x00_set_field32(&reg, RXCSR0_DISABLE_RX, 1);
69233aca94dSKalle Valo 		rt2x00mmio_register_write(rt2x00dev, RXCSR0, reg);
69333aca94dSKalle Valo 		break;
69433aca94dSKalle Valo 	case QID_BEACON:
6953954b4e3SArnd Bergmann 		reg = rt2x00mmio_register_read(rt2x00dev, CSR14);
69633aca94dSKalle Valo 		rt2x00_set_field32(&reg, CSR14_TSF_COUNT, 0);
69733aca94dSKalle Valo 		rt2x00_set_field32(&reg, CSR14_TBCN, 0);
69833aca94dSKalle Valo 		rt2x00_set_field32(&reg, CSR14_BEACON_GEN, 0);
69933aca94dSKalle Valo 		rt2x00mmio_register_write(rt2x00dev, CSR14, reg);
70033aca94dSKalle Valo 
70133aca94dSKalle Valo 		/*
70233aca94dSKalle Valo 		 * Wait for possibly running tbtt tasklets.
70333aca94dSKalle Valo 		 */
70433aca94dSKalle Valo 		tasklet_kill(&rt2x00dev->tbtt_tasklet);
70533aca94dSKalle Valo 		break;
70633aca94dSKalle Valo 	default:
70733aca94dSKalle Valo 		break;
70833aca94dSKalle Valo 	}
70933aca94dSKalle Valo }
71033aca94dSKalle Valo 
71133aca94dSKalle Valo /*
71233aca94dSKalle Valo  * Initialization functions.
71333aca94dSKalle Valo  */
rt2400pci_get_entry_state(struct queue_entry * entry)71433aca94dSKalle Valo static bool rt2400pci_get_entry_state(struct queue_entry *entry)
71533aca94dSKalle Valo {
71633aca94dSKalle Valo 	struct queue_entry_priv_mmio *entry_priv = entry->priv_data;
71733aca94dSKalle Valo 	u32 word;
71833aca94dSKalle Valo 
71933aca94dSKalle Valo 	if (entry->queue->qid == QID_RX) {
720b9b23872SArnd Bergmann 		word = rt2x00_desc_read(entry_priv->desc, 0);
72133aca94dSKalle Valo 
72233aca94dSKalle Valo 		return rt2x00_get_field32(word, RXD_W0_OWNER_NIC);
72333aca94dSKalle Valo 	} else {
724b9b23872SArnd Bergmann 		word = rt2x00_desc_read(entry_priv->desc, 0);
72533aca94dSKalle Valo 
72633aca94dSKalle Valo 		return (rt2x00_get_field32(word, TXD_W0_OWNER_NIC) ||
72733aca94dSKalle Valo 		        rt2x00_get_field32(word, TXD_W0_VALID));
72833aca94dSKalle Valo 	}
72933aca94dSKalle Valo }
73033aca94dSKalle Valo 
rt2400pci_clear_entry(struct queue_entry * entry)73133aca94dSKalle Valo static void rt2400pci_clear_entry(struct queue_entry *entry)
73233aca94dSKalle Valo {
73333aca94dSKalle Valo 	struct queue_entry_priv_mmio *entry_priv = entry->priv_data;
73433aca94dSKalle Valo 	struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb);
73533aca94dSKalle Valo 	u32 word;
73633aca94dSKalle Valo 
73733aca94dSKalle Valo 	if (entry->queue->qid == QID_RX) {
738b9b23872SArnd Bergmann 		word = rt2x00_desc_read(entry_priv->desc, 2);
73933aca94dSKalle Valo 		rt2x00_set_field32(&word, RXD_W2_BUFFER_LENGTH, entry->skb->len);
74033aca94dSKalle Valo 		rt2x00_desc_write(entry_priv->desc, 2, word);
74133aca94dSKalle Valo 
742b9b23872SArnd Bergmann 		word = rt2x00_desc_read(entry_priv->desc, 1);
74333aca94dSKalle Valo 		rt2x00_set_field32(&word, RXD_W1_BUFFER_ADDRESS, skbdesc->skb_dma);
74433aca94dSKalle Valo 		rt2x00_desc_write(entry_priv->desc, 1, word);
74533aca94dSKalle Valo 
746b9b23872SArnd Bergmann 		word = rt2x00_desc_read(entry_priv->desc, 0);
74733aca94dSKalle Valo 		rt2x00_set_field32(&word, RXD_W0_OWNER_NIC, 1);
74833aca94dSKalle Valo 		rt2x00_desc_write(entry_priv->desc, 0, word);
74933aca94dSKalle Valo 	} else {
750b9b23872SArnd Bergmann 		word = rt2x00_desc_read(entry_priv->desc, 0);
75133aca94dSKalle Valo 		rt2x00_set_field32(&word, TXD_W0_VALID, 0);
75233aca94dSKalle Valo 		rt2x00_set_field32(&word, TXD_W0_OWNER_NIC, 0);
75333aca94dSKalle Valo 		rt2x00_desc_write(entry_priv->desc, 0, word);
75433aca94dSKalle Valo 	}
75533aca94dSKalle Valo }
75633aca94dSKalle Valo 
rt2400pci_init_queues(struct rt2x00_dev * rt2x00dev)75733aca94dSKalle Valo static int rt2400pci_init_queues(struct rt2x00_dev *rt2x00dev)
75833aca94dSKalle Valo {
75933aca94dSKalle Valo 	struct queue_entry_priv_mmio *entry_priv;
76033aca94dSKalle Valo 	u32 reg;
76133aca94dSKalle Valo 
76233aca94dSKalle Valo 	/*
76333aca94dSKalle Valo 	 * Initialize registers.
76433aca94dSKalle Valo 	 */
7653954b4e3SArnd Bergmann 	reg = rt2x00mmio_register_read(rt2x00dev, TXCSR2);
76633aca94dSKalle Valo 	rt2x00_set_field32(&reg, TXCSR2_TXD_SIZE, rt2x00dev->tx[0].desc_size);
76733aca94dSKalle Valo 	rt2x00_set_field32(&reg, TXCSR2_NUM_TXD, rt2x00dev->tx[1].limit);
76833aca94dSKalle Valo 	rt2x00_set_field32(&reg, TXCSR2_NUM_ATIM, rt2x00dev->atim->limit);
76933aca94dSKalle Valo 	rt2x00_set_field32(&reg, TXCSR2_NUM_PRIO, rt2x00dev->tx[0].limit);
77033aca94dSKalle Valo 	rt2x00mmio_register_write(rt2x00dev, TXCSR2, reg);
77133aca94dSKalle Valo 
77233aca94dSKalle Valo 	entry_priv = rt2x00dev->tx[1].entries[0].priv_data;
7733954b4e3SArnd Bergmann 	reg = rt2x00mmio_register_read(rt2x00dev, TXCSR3);
77433aca94dSKalle Valo 	rt2x00_set_field32(&reg, TXCSR3_TX_RING_REGISTER,
77533aca94dSKalle Valo 			   entry_priv->desc_dma);
77633aca94dSKalle Valo 	rt2x00mmio_register_write(rt2x00dev, TXCSR3, reg);
77733aca94dSKalle Valo 
77833aca94dSKalle Valo 	entry_priv = rt2x00dev->tx[0].entries[0].priv_data;
7793954b4e3SArnd Bergmann 	reg = rt2x00mmio_register_read(rt2x00dev, TXCSR5);
78033aca94dSKalle Valo 	rt2x00_set_field32(&reg, TXCSR5_PRIO_RING_REGISTER,
78133aca94dSKalle Valo 			   entry_priv->desc_dma);
78233aca94dSKalle Valo 	rt2x00mmio_register_write(rt2x00dev, TXCSR5, reg);
78333aca94dSKalle Valo 
78433aca94dSKalle Valo 	entry_priv = rt2x00dev->atim->entries[0].priv_data;
7853954b4e3SArnd Bergmann 	reg = rt2x00mmio_register_read(rt2x00dev, TXCSR4);
78633aca94dSKalle Valo 	rt2x00_set_field32(&reg, TXCSR4_ATIM_RING_REGISTER,
78733aca94dSKalle Valo 			   entry_priv->desc_dma);
78833aca94dSKalle Valo 	rt2x00mmio_register_write(rt2x00dev, TXCSR4, reg);
78933aca94dSKalle Valo 
79033aca94dSKalle Valo 	entry_priv = rt2x00dev->bcn->entries[0].priv_data;
7913954b4e3SArnd Bergmann 	reg = rt2x00mmio_register_read(rt2x00dev, TXCSR6);
79233aca94dSKalle Valo 	rt2x00_set_field32(&reg, TXCSR6_BEACON_RING_REGISTER,
79333aca94dSKalle Valo 			   entry_priv->desc_dma);
79433aca94dSKalle Valo 	rt2x00mmio_register_write(rt2x00dev, TXCSR6, reg);
79533aca94dSKalle Valo 
7963954b4e3SArnd Bergmann 	reg = rt2x00mmio_register_read(rt2x00dev, RXCSR1);
79733aca94dSKalle Valo 	rt2x00_set_field32(&reg, RXCSR1_RXD_SIZE, rt2x00dev->rx->desc_size);
79833aca94dSKalle Valo 	rt2x00_set_field32(&reg, RXCSR1_NUM_RXD, rt2x00dev->rx->limit);
79933aca94dSKalle Valo 	rt2x00mmio_register_write(rt2x00dev, RXCSR1, reg);
80033aca94dSKalle Valo 
80133aca94dSKalle Valo 	entry_priv = rt2x00dev->rx->entries[0].priv_data;
8023954b4e3SArnd Bergmann 	reg = rt2x00mmio_register_read(rt2x00dev, RXCSR2);
80333aca94dSKalle Valo 	rt2x00_set_field32(&reg, RXCSR2_RX_RING_REGISTER,
80433aca94dSKalle Valo 			   entry_priv->desc_dma);
80533aca94dSKalle Valo 	rt2x00mmio_register_write(rt2x00dev, RXCSR2, reg);
80633aca94dSKalle Valo 
80733aca94dSKalle Valo 	return 0;
80833aca94dSKalle Valo }
80933aca94dSKalle Valo 
rt2400pci_init_registers(struct rt2x00_dev * rt2x00dev)81033aca94dSKalle Valo static int rt2400pci_init_registers(struct rt2x00_dev *rt2x00dev)
81133aca94dSKalle Valo {
81233aca94dSKalle Valo 	u32 reg;
81333aca94dSKalle Valo 
81433aca94dSKalle Valo 	rt2x00mmio_register_write(rt2x00dev, PSCSR0, 0x00020002);
81533aca94dSKalle Valo 	rt2x00mmio_register_write(rt2x00dev, PSCSR1, 0x00000002);
81633aca94dSKalle Valo 	rt2x00mmio_register_write(rt2x00dev, PSCSR2, 0x00023f20);
81733aca94dSKalle Valo 	rt2x00mmio_register_write(rt2x00dev, PSCSR3, 0x00000002);
81833aca94dSKalle Valo 
8193954b4e3SArnd Bergmann 	reg = rt2x00mmio_register_read(rt2x00dev, TIMECSR);
82033aca94dSKalle Valo 	rt2x00_set_field32(&reg, TIMECSR_US_COUNT, 33);
82133aca94dSKalle Valo 	rt2x00_set_field32(&reg, TIMECSR_US_64_COUNT, 63);
82233aca94dSKalle Valo 	rt2x00_set_field32(&reg, TIMECSR_BEACON_EXPECT, 0);
82333aca94dSKalle Valo 	rt2x00mmio_register_write(rt2x00dev, TIMECSR, reg);
82433aca94dSKalle Valo 
8253954b4e3SArnd Bergmann 	reg = rt2x00mmio_register_read(rt2x00dev, CSR9);
82633aca94dSKalle Valo 	rt2x00_set_field32(&reg, CSR9_MAX_FRAME_UNIT,
82733aca94dSKalle Valo 			   (rt2x00dev->rx->data_size / 128));
82833aca94dSKalle Valo 	rt2x00mmio_register_write(rt2x00dev, CSR9, reg);
82933aca94dSKalle Valo 
8303954b4e3SArnd Bergmann 	reg = rt2x00mmio_register_read(rt2x00dev, CSR14);
83133aca94dSKalle Valo 	rt2x00_set_field32(&reg, CSR14_TSF_COUNT, 0);
83233aca94dSKalle Valo 	rt2x00_set_field32(&reg, CSR14_TSF_SYNC, 0);
83333aca94dSKalle Valo 	rt2x00_set_field32(&reg, CSR14_TBCN, 0);
83433aca94dSKalle Valo 	rt2x00_set_field32(&reg, CSR14_TCFP, 0);
83533aca94dSKalle Valo 	rt2x00_set_field32(&reg, CSR14_TATIMW, 0);
83633aca94dSKalle Valo 	rt2x00_set_field32(&reg, CSR14_BEACON_GEN, 0);
83733aca94dSKalle Valo 	rt2x00_set_field32(&reg, CSR14_CFP_COUNT_PRELOAD, 0);
83833aca94dSKalle Valo 	rt2x00_set_field32(&reg, CSR14_TBCM_PRELOAD, 0);
83933aca94dSKalle Valo 	rt2x00mmio_register_write(rt2x00dev, CSR14, reg);
84033aca94dSKalle Valo 
84133aca94dSKalle Valo 	rt2x00mmio_register_write(rt2x00dev, CNT3, 0x3f080000);
84233aca94dSKalle Valo 
8433954b4e3SArnd Bergmann 	reg = rt2x00mmio_register_read(rt2x00dev, ARCSR0);
84433aca94dSKalle Valo 	rt2x00_set_field32(&reg, ARCSR0_AR_BBP_DATA0, 133);
84533aca94dSKalle Valo 	rt2x00_set_field32(&reg, ARCSR0_AR_BBP_ID0, 134);
84633aca94dSKalle Valo 	rt2x00_set_field32(&reg, ARCSR0_AR_BBP_DATA1, 136);
84733aca94dSKalle Valo 	rt2x00_set_field32(&reg, ARCSR0_AR_BBP_ID1, 135);
84833aca94dSKalle Valo 	rt2x00mmio_register_write(rt2x00dev, ARCSR0, reg);
84933aca94dSKalle Valo 
8503954b4e3SArnd Bergmann 	reg = rt2x00mmio_register_read(rt2x00dev, RXCSR3);
85133aca94dSKalle Valo 	rt2x00_set_field32(&reg, RXCSR3_BBP_ID0, 3); /* Tx power.*/
85233aca94dSKalle Valo 	rt2x00_set_field32(&reg, RXCSR3_BBP_ID0_VALID, 1);
85333aca94dSKalle Valo 	rt2x00_set_field32(&reg, RXCSR3_BBP_ID1, 32); /* Signal */
85433aca94dSKalle Valo 	rt2x00_set_field32(&reg, RXCSR3_BBP_ID1_VALID, 1);
85533aca94dSKalle Valo 	rt2x00_set_field32(&reg, RXCSR3_BBP_ID2, 36); /* Rssi */
85633aca94dSKalle Valo 	rt2x00_set_field32(&reg, RXCSR3_BBP_ID2_VALID, 1);
85733aca94dSKalle Valo 	rt2x00mmio_register_write(rt2x00dev, RXCSR3, reg);
85833aca94dSKalle Valo 
85933aca94dSKalle Valo 	rt2x00mmio_register_write(rt2x00dev, PWRCSR0, 0x3f3b3100);
86033aca94dSKalle Valo 
86133aca94dSKalle Valo 	if (rt2x00dev->ops->lib->set_device_state(rt2x00dev, STATE_AWAKE))
86233aca94dSKalle Valo 		return -EBUSY;
86333aca94dSKalle Valo 
86433aca94dSKalle Valo 	rt2x00mmio_register_write(rt2x00dev, MACCSR0, 0x00217223);
86533aca94dSKalle Valo 	rt2x00mmio_register_write(rt2x00dev, MACCSR1, 0x00235518);
86633aca94dSKalle Valo 
8673954b4e3SArnd Bergmann 	reg = rt2x00mmio_register_read(rt2x00dev, MACCSR2);
86833aca94dSKalle Valo 	rt2x00_set_field32(&reg, MACCSR2_DELAY, 64);
86933aca94dSKalle Valo 	rt2x00mmio_register_write(rt2x00dev, MACCSR2, reg);
87033aca94dSKalle Valo 
8713954b4e3SArnd Bergmann 	reg = rt2x00mmio_register_read(rt2x00dev, RALINKCSR);
87233aca94dSKalle Valo 	rt2x00_set_field32(&reg, RALINKCSR_AR_BBP_DATA0, 17);
87333aca94dSKalle Valo 	rt2x00_set_field32(&reg, RALINKCSR_AR_BBP_ID0, 154);
87433aca94dSKalle Valo 	rt2x00_set_field32(&reg, RALINKCSR_AR_BBP_DATA1, 0);
87533aca94dSKalle Valo 	rt2x00_set_field32(&reg, RALINKCSR_AR_BBP_ID1, 154);
87633aca94dSKalle Valo 	rt2x00mmio_register_write(rt2x00dev, RALINKCSR, reg);
87733aca94dSKalle Valo 
8783954b4e3SArnd Bergmann 	reg = rt2x00mmio_register_read(rt2x00dev, CSR1);
87933aca94dSKalle Valo 	rt2x00_set_field32(&reg, CSR1_SOFT_RESET, 1);
88033aca94dSKalle Valo 	rt2x00_set_field32(&reg, CSR1_BBP_RESET, 0);
88133aca94dSKalle Valo 	rt2x00_set_field32(&reg, CSR1_HOST_READY, 0);
88233aca94dSKalle Valo 	rt2x00mmio_register_write(rt2x00dev, CSR1, reg);
88333aca94dSKalle Valo 
8843954b4e3SArnd Bergmann 	reg = rt2x00mmio_register_read(rt2x00dev, CSR1);
88533aca94dSKalle Valo 	rt2x00_set_field32(&reg, CSR1_SOFT_RESET, 0);
88633aca94dSKalle Valo 	rt2x00_set_field32(&reg, CSR1_HOST_READY, 1);
88733aca94dSKalle Valo 	rt2x00mmio_register_write(rt2x00dev, CSR1, reg);
88833aca94dSKalle Valo 
88933aca94dSKalle Valo 	/*
89033aca94dSKalle Valo 	 * We must clear the FCS and FIFO error count.
89133aca94dSKalle Valo 	 * These registers are cleared on read,
89233aca94dSKalle Valo 	 * so we may pass a useless variable to store the value.
89333aca94dSKalle Valo 	 */
8943954b4e3SArnd Bergmann 	reg = rt2x00mmio_register_read(rt2x00dev, CNT0);
8953954b4e3SArnd Bergmann 	reg = rt2x00mmio_register_read(rt2x00dev, CNT4);
89633aca94dSKalle Valo 
89733aca94dSKalle Valo 	return 0;
89833aca94dSKalle Valo }
89933aca94dSKalle Valo 
rt2400pci_wait_bbp_ready(struct rt2x00_dev * rt2x00dev)90033aca94dSKalle Valo static int rt2400pci_wait_bbp_ready(struct rt2x00_dev *rt2x00dev)
90133aca94dSKalle Valo {
90233aca94dSKalle Valo 	unsigned int i;
90333aca94dSKalle Valo 	u8 value;
90433aca94dSKalle Valo 
90533aca94dSKalle Valo 	for (i = 0; i < REGISTER_BUSY_COUNT; i++) {
9065fbbe378SArnd Bergmann 		value = rt2400pci_bbp_read(rt2x00dev, 0);
90733aca94dSKalle Valo 		if ((value != 0xff) && (value != 0x00))
90833aca94dSKalle Valo 			return 0;
90933aca94dSKalle Valo 		udelay(REGISTER_BUSY_DELAY);
91033aca94dSKalle Valo 	}
91133aca94dSKalle Valo 
91233aca94dSKalle Valo 	rt2x00_err(rt2x00dev, "BBP register access failed, aborting\n");
91333aca94dSKalle Valo 	return -EACCES;
91433aca94dSKalle Valo }
91533aca94dSKalle Valo 
rt2400pci_init_bbp(struct rt2x00_dev * rt2x00dev)91633aca94dSKalle Valo static int rt2400pci_init_bbp(struct rt2x00_dev *rt2x00dev)
91733aca94dSKalle Valo {
91833aca94dSKalle Valo 	unsigned int i;
91933aca94dSKalle Valo 	u16 eeprom;
92033aca94dSKalle Valo 	u8 reg_id;
92133aca94dSKalle Valo 	u8 value;
92233aca94dSKalle Valo 
92333aca94dSKalle Valo 	if (unlikely(rt2400pci_wait_bbp_ready(rt2x00dev)))
92433aca94dSKalle Valo 		return -EACCES;
92533aca94dSKalle Valo 
92633aca94dSKalle Valo 	rt2400pci_bbp_write(rt2x00dev, 1, 0x00);
92733aca94dSKalle Valo 	rt2400pci_bbp_write(rt2x00dev, 3, 0x27);
92833aca94dSKalle Valo 	rt2400pci_bbp_write(rt2x00dev, 4, 0x08);
92933aca94dSKalle Valo 	rt2400pci_bbp_write(rt2x00dev, 10, 0x0f);
93033aca94dSKalle Valo 	rt2400pci_bbp_write(rt2x00dev, 15, 0x72);
93133aca94dSKalle Valo 	rt2400pci_bbp_write(rt2x00dev, 16, 0x74);
93233aca94dSKalle Valo 	rt2400pci_bbp_write(rt2x00dev, 17, 0x20);
93333aca94dSKalle Valo 	rt2400pci_bbp_write(rt2x00dev, 18, 0x72);
93433aca94dSKalle Valo 	rt2400pci_bbp_write(rt2x00dev, 19, 0x0b);
93533aca94dSKalle Valo 	rt2400pci_bbp_write(rt2x00dev, 20, 0x00);
93633aca94dSKalle Valo 	rt2400pci_bbp_write(rt2x00dev, 28, 0x11);
93733aca94dSKalle Valo 	rt2400pci_bbp_write(rt2x00dev, 29, 0x04);
93833aca94dSKalle Valo 	rt2400pci_bbp_write(rt2x00dev, 30, 0x21);
93933aca94dSKalle Valo 	rt2400pci_bbp_write(rt2x00dev, 31, 0x00);
94033aca94dSKalle Valo 
94133aca94dSKalle Valo 	for (i = 0; i < EEPROM_BBP_SIZE; i++) {
94238651683SArnd Bergmann 		eeprom = rt2x00_eeprom_read(rt2x00dev, EEPROM_BBP_START + i);
94333aca94dSKalle Valo 
94433aca94dSKalle Valo 		if (eeprom != 0xffff && eeprom != 0x0000) {
94533aca94dSKalle Valo 			reg_id = rt2x00_get_field16(eeprom, EEPROM_BBP_REG_ID);
94633aca94dSKalle Valo 			value = rt2x00_get_field16(eeprom, EEPROM_BBP_VALUE);
94733aca94dSKalle Valo 			rt2400pci_bbp_write(rt2x00dev, reg_id, value);
94833aca94dSKalle Valo 		}
94933aca94dSKalle Valo 	}
95033aca94dSKalle Valo 
95133aca94dSKalle Valo 	return 0;
95233aca94dSKalle Valo }
95333aca94dSKalle Valo 
95433aca94dSKalle Valo /*
95533aca94dSKalle Valo  * Device state switch handlers.
95633aca94dSKalle Valo  */
rt2400pci_toggle_irq(struct rt2x00_dev * rt2x00dev,enum dev_state state)95733aca94dSKalle Valo static void rt2400pci_toggle_irq(struct rt2x00_dev *rt2x00dev,
95833aca94dSKalle Valo 				 enum dev_state state)
95933aca94dSKalle Valo {
96033aca94dSKalle Valo 	int mask = (state == STATE_RADIO_IRQ_OFF);
96133aca94dSKalle Valo 	u32 reg;
96233aca94dSKalle Valo 	unsigned long flags;
96333aca94dSKalle Valo 
96433aca94dSKalle Valo 	/*
96533aca94dSKalle Valo 	 * When interrupts are being enabled, the interrupt registers
96633aca94dSKalle Valo 	 * should clear the register to assure a clean state.
96733aca94dSKalle Valo 	 */
96833aca94dSKalle Valo 	if (state == STATE_RADIO_IRQ_ON) {
9693954b4e3SArnd Bergmann 		reg = rt2x00mmio_register_read(rt2x00dev, CSR7);
97033aca94dSKalle Valo 		rt2x00mmio_register_write(rt2x00dev, CSR7, reg);
97133aca94dSKalle Valo 	}
97233aca94dSKalle Valo 
97333aca94dSKalle Valo 	/*
97433aca94dSKalle Valo 	 * Only toggle the interrupts bits we are going to use.
97533aca94dSKalle Valo 	 * Non-checked interrupt bits are disabled by default.
97633aca94dSKalle Valo 	 */
97733aca94dSKalle Valo 	spin_lock_irqsave(&rt2x00dev->irqmask_lock, flags);
97833aca94dSKalle Valo 
9793954b4e3SArnd Bergmann 	reg = rt2x00mmio_register_read(rt2x00dev, CSR8);
98033aca94dSKalle Valo 	rt2x00_set_field32(&reg, CSR8_TBCN_EXPIRE, mask);
98133aca94dSKalle Valo 	rt2x00_set_field32(&reg, CSR8_TXDONE_TXRING, mask);
98233aca94dSKalle Valo 	rt2x00_set_field32(&reg, CSR8_TXDONE_ATIMRING, mask);
98333aca94dSKalle Valo 	rt2x00_set_field32(&reg, CSR8_TXDONE_PRIORING, mask);
98433aca94dSKalle Valo 	rt2x00_set_field32(&reg, CSR8_RXDONE, mask);
98533aca94dSKalle Valo 	rt2x00mmio_register_write(rt2x00dev, CSR8, reg);
98633aca94dSKalle Valo 
98733aca94dSKalle Valo 	spin_unlock_irqrestore(&rt2x00dev->irqmask_lock, flags);
98833aca94dSKalle Valo 
98933aca94dSKalle Valo 	if (state == STATE_RADIO_IRQ_OFF) {
99033aca94dSKalle Valo 		/*
99133aca94dSKalle Valo 		 * Ensure that all tasklets are finished before
99233aca94dSKalle Valo 		 * disabling the interrupts.
99333aca94dSKalle Valo 		 */
99433aca94dSKalle Valo 		tasklet_kill(&rt2x00dev->txstatus_tasklet);
99533aca94dSKalle Valo 		tasklet_kill(&rt2x00dev->rxdone_tasklet);
99633aca94dSKalle Valo 		tasklet_kill(&rt2x00dev->tbtt_tasklet);
99733aca94dSKalle Valo 	}
99833aca94dSKalle Valo }
99933aca94dSKalle Valo 
rt2400pci_enable_radio(struct rt2x00_dev * rt2x00dev)100033aca94dSKalle Valo static int rt2400pci_enable_radio(struct rt2x00_dev *rt2x00dev)
100133aca94dSKalle Valo {
100233aca94dSKalle Valo 	/*
100333aca94dSKalle Valo 	 * Initialize all registers.
100433aca94dSKalle Valo 	 */
100533aca94dSKalle Valo 	if (unlikely(rt2400pci_init_queues(rt2x00dev) ||
100633aca94dSKalle Valo 		     rt2400pci_init_registers(rt2x00dev) ||
100733aca94dSKalle Valo 		     rt2400pci_init_bbp(rt2x00dev)))
100833aca94dSKalle Valo 		return -EIO;
100933aca94dSKalle Valo 
101033aca94dSKalle Valo 	return 0;
101133aca94dSKalle Valo }
101233aca94dSKalle Valo 
rt2400pci_disable_radio(struct rt2x00_dev * rt2x00dev)101333aca94dSKalle Valo static void rt2400pci_disable_radio(struct rt2x00_dev *rt2x00dev)
101433aca94dSKalle Valo {
101533aca94dSKalle Valo 	/*
101633aca94dSKalle Valo 	 * Disable power
101733aca94dSKalle Valo 	 */
101833aca94dSKalle Valo 	rt2x00mmio_register_write(rt2x00dev, PWRCSR0, 0);
101933aca94dSKalle Valo }
102033aca94dSKalle Valo 
rt2400pci_set_state(struct rt2x00_dev * rt2x00dev,enum dev_state state)102133aca94dSKalle Valo static int rt2400pci_set_state(struct rt2x00_dev *rt2x00dev,
102233aca94dSKalle Valo 			       enum dev_state state)
102333aca94dSKalle Valo {
102433aca94dSKalle Valo 	u32 reg, reg2;
102533aca94dSKalle Valo 	unsigned int i;
1026*66063033SJason A. Donenfeld 	bool put_to_sleep;
1027*66063033SJason A. Donenfeld 	u8 bbp_state;
1028*66063033SJason A. Donenfeld 	u8 rf_state;
102933aca94dSKalle Valo 
103033aca94dSKalle Valo 	put_to_sleep = (state != STATE_AWAKE);
103133aca94dSKalle Valo 
10323954b4e3SArnd Bergmann 	reg = rt2x00mmio_register_read(rt2x00dev, PWRCSR1);
103333aca94dSKalle Valo 	rt2x00_set_field32(&reg, PWRCSR1_SET_STATE, 1);
103433aca94dSKalle Valo 	rt2x00_set_field32(&reg, PWRCSR1_BBP_DESIRE_STATE, state);
103533aca94dSKalle Valo 	rt2x00_set_field32(&reg, PWRCSR1_RF_DESIRE_STATE, state);
103633aca94dSKalle Valo 	rt2x00_set_field32(&reg, PWRCSR1_PUT_TO_SLEEP, put_to_sleep);
103733aca94dSKalle Valo 	rt2x00mmio_register_write(rt2x00dev, PWRCSR1, reg);
103833aca94dSKalle Valo 
103933aca94dSKalle Valo 	/*
104033aca94dSKalle Valo 	 * Device is not guaranteed to be in the requested state yet.
104133aca94dSKalle Valo 	 * We must wait until the register indicates that the
104233aca94dSKalle Valo 	 * device has entered the correct state.
104333aca94dSKalle Valo 	 */
104433aca94dSKalle Valo 	for (i = 0; i < REGISTER_BUSY_COUNT; i++) {
10453954b4e3SArnd Bergmann 		reg2 = rt2x00mmio_register_read(rt2x00dev, PWRCSR1);
104633aca94dSKalle Valo 		bbp_state = rt2x00_get_field32(reg2, PWRCSR1_BBP_CURR_STATE);
104733aca94dSKalle Valo 		rf_state = rt2x00_get_field32(reg2, PWRCSR1_RF_CURR_STATE);
104833aca94dSKalle Valo 		if (bbp_state == state && rf_state == state)
104933aca94dSKalle Valo 			return 0;
105033aca94dSKalle Valo 		rt2x00mmio_register_write(rt2x00dev, PWRCSR1, reg);
105133aca94dSKalle Valo 		msleep(10);
105233aca94dSKalle Valo 	}
105333aca94dSKalle Valo 
105433aca94dSKalle Valo 	return -EBUSY;
105533aca94dSKalle Valo }
105633aca94dSKalle Valo 
rt2400pci_set_device_state(struct rt2x00_dev * rt2x00dev,enum dev_state state)105733aca94dSKalle Valo static int rt2400pci_set_device_state(struct rt2x00_dev *rt2x00dev,
105833aca94dSKalle Valo 				      enum dev_state state)
105933aca94dSKalle Valo {
106033aca94dSKalle Valo 	int retval = 0;
106133aca94dSKalle Valo 
106233aca94dSKalle Valo 	switch (state) {
106333aca94dSKalle Valo 	case STATE_RADIO_ON:
106433aca94dSKalle Valo 		retval = rt2400pci_enable_radio(rt2x00dev);
106533aca94dSKalle Valo 		break;
106633aca94dSKalle Valo 	case STATE_RADIO_OFF:
106733aca94dSKalle Valo 		rt2400pci_disable_radio(rt2x00dev);
106833aca94dSKalle Valo 		break;
106933aca94dSKalle Valo 	case STATE_RADIO_IRQ_ON:
107033aca94dSKalle Valo 	case STATE_RADIO_IRQ_OFF:
107133aca94dSKalle Valo 		rt2400pci_toggle_irq(rt2x00dev, state);
107233aca94dSKalle Valo 		break;
107333aca94dSKalle Valo 	case STATE_DEEP_SLEEP:
107433aca94dSKalle Valo 	case STATE_SLEEP:
107533aca94dSKalle Valo 	case STATE_STANDBY:
107633aca94dSKalle Valo 	case STATE_AWAKE:
107733aca94dSKalle Valo 		retval = rt2400pci_set_state(rt2x00dev, state);
107833aca94dSKalle Valo 		break;
107933aca94dSKalle Valo 	default:
108033aca94dSKalle Valo 		retval = -ENOTSUPP;
108133aca94dSKalle Valo 		break;
108233aca94dSKalle Valo 	}
108333aca94dSKalle Valo 
108433aca94dSKalle Valo 	if (unlikely(retval))
108533aca94dSKalle Valo 		rt2x00_err(rt2x00dev, "Device failed to enter state %d (%d)\n",
108633aca94dSKalle Valo 			   state, retval);
108733aca94dSKalle Valo 
108833aca94dSKalle Valo 	return retval;
108933aca94dSKalle Valo }
109033aca94dSKalle Valo 
109133aca94dSKalle Valo /*
109233aca94dSKalle Valo  * TX descriptor initialization
109333aca94dSKalle Valo  */
rt2400pci_write_tx_desc(struct queue_entry * entry,struct txentry_desc * txdesc)109433aca94dSKalle Valo static void rt2400pci_write_tx_desc(struct queue_entry *entry,
109533aca94dSKalle Valo 				    struct txentry_desc *txdesc)
109633aca94dSKalle Valo {
109733aca94dSKalle Valo 	struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb);
109833aca94dSKalle Valo 	struct queue_entry_priv_mmio *entry_priv = entry->priv_data;
109933aca94dSKalle Valo 	__le32 *txd = entry_priv->desc;
110033aca94dSKalle Valo 	u32 word;
110133aca94dSKalle Valo 
110233aca94dSKalle Valo 	/*
110333aca94dSKalle Valo 	 * Start writing the descriptor words.
110433aca94dSKalle Valo 	 */
1105b9b23872SArnd Bergmann 	word = rt2x00_desc_read(txd, 1);
110633aca94dSKalle Valo 	rt2x00_set_field32(&word, TXD_W1_BUFFER_ADDRESS, skbdesc->skb_dma);
110733aca94dSKalle Valo 	rt2x00_desc_write(txd, 1, word);
110833aca94dSKalle Valo 
1109b9b23872SArnd Bergmann 	word = rt2x00_desc_read(txd, 2);
111033aca94dSKalle Valo 	rt2x00_set_field32(&word, TXD_W2_BUFFER_LENGTH, txdesc->length);
111133aca94dSKalle Valo 	rt2x00_set_field32(&word, TXD_W2_DATABYTE_COUNT, txdesc->length);
111233aca94dSKalle Valo 	rt2x00_desc_write(txd, 2, word);
111333aca94dSKalle Valo 
1114b9b23872SArnd Bergmann 	word = rt2x00_desc_read(txd, 3);
111533aca94dSKalle Valo 	rt2x00_set_field32(&word, TXD_W3_PLCP_SIGNAL, txdesc->u.plcp.signal);
111633aca94dSKalle Valo 	rt2x00_set_field32(&word, TXD_W3_PLCP_SIGNAL_REGNUM, 5);
111733aca94dSKalle Valo 	rt2x00_set_field32(&word, TXD_W3_PLCP_SIGNAL_BUSY, 1);
111833aca94dSKalle Valo 	rt2x00_set_field32(&word, TXD_W3_PLCP_SERVICE, txdesc->u.plcp.service);
111933aca94dSKalle Valo 	rt2x00_set_field32(&word, TXD_W3_PLCP_SERVICE_REGNUM, 6);
112033aca94dSKalle Valo 	rt2x00_set_field32(&word, TXD_W3_PLCP_SERVICE_BUSY, 1);
112133aca94dSKalle Valo 	rt2x00_desc_write(txd, 3, word);
112233aca94dSKalle Valo 
1123b9b23872SArnd Bergmann 	word = rt2x00_desc_read(txd, 4);
112433aca94dSKalle Valo 	rt2x00_set_field32(&word, TXD_W4_PLCP_LENGTH_LOW,
112533aca94dSKalle Valo 			   txdesc->u.plcp.length_low);
112633aca94dSKalle Valo 	rt2x00_set_field32(&word, TXD_W3_PLCP_LENGTH_LOW_REGNUM, 8);
112733aca94dSKalle Valo 	rt2x00_set_field32(&word, TXD_W3_PLCP_LENGTH_LOW_BUSY, 1);
112833aca94dSKalle Valo 	rt2x00_set_field32(&word, TXD_W4_PLCP_LENGTH_HIGH,
112933aca94dSKalle Valo 			   txdesc->u.plcp.length_high);
113033aca94dSKalle Valo 	rt2x00_set_field32(&word, TXD_W3_PLCP_LENGTH_HIGH_REGNUM, 7);
113133aca94dSKalle Valo 	rt2x00_set_field32(&word, TXD_W3_PLCP_LENGTH_HIGH_BUSY, 1);
113233aca94dSKalle Valo 	rt2x00_desc_write(txd, 4, word);
113333aca94dSKalle Valo 
113433aca94dSKalle Valo 	/*
113533aca94dSKalle Valo 	 * Writing TXD word 0 must the last to prevent a race condition with
113633aca94dSKalle Valo 	 * the device, whereby the device may take hold of the TXD before we
113733aca94dSKalle Valo 	 * finished updating it.
113833aca94dSKalle Valo 	 */
1139b9b23872SArnd Bergmann 	word = rt2x00_desc_read(txd, 0);
114033aca94dSKalle Valo 	rt2x00_set_field32(&word, TXD_W0_OWNER_NIC, 1);
114133aca94dSKalle Valo 	rt2x00_set_field32(&word, TXD_W0_VALID, 1);
114233aca94dSKalle Valo 	rt2x00_set_field32(&word, TXD_W0_MORE_FRAG,
114333aca94dSKalle Valo 			   test_bit(ENTRY_TXD_MORE_FRAG, &txdesc->flags));
114433aca94dSKalle Valo 	rt2x00_set_field32(&word, TXD_W0_ACK,
114533aca94dSKalle Valo 			   test_bit(ENTRY_TXD_ACK, &txdesc->flags));
114633aca94dSKalle Valo 	rt2x00_set_field32(&word, TXD_W0_TIMESTAMP,
114733aca94dSKalle Valo 			   test_bit(ENTRY_TXD_REQ_TIMESTAMP, &txdesc->flags));
114833aca94dSKalle Valo 	rt2x00_set_field32(&word, TXD_W0_RTS,
114933aca94dSKalle Valo 			   test_bit(ENTRY_TXD_RTS_FRAME, &txdesc->flags));
115033aca94dSKalle Valo 	rt2x00_set_field32(&word, TXD_W0_IFS, txdesc->u.plcp.ifs);
115133aca94dSKalle Valo 	rt2x00_set_field32(&word, TXD_W0_RETRY_MODE,
115233aca94dSKalle Valo 			   test_bit(ENTRY_TXD_RETRY_MODE, &txdesc->flags));
115333aca94dSKalle Valo 	rt2x00_desc_write(txd, 0, word);
115433aca94dSKalle Valo 
115533aca94dSKalle Valo 	/*
115633aca94dSKalle Valo 	 * Register descriptor details in skb frame descriptor.
115733aca94dSKalle Valo 	 */
115833aca94dSKalle Valo 	skbdesc->desc = txd;
115933aca94dSKalle Valo 	skbdesc->desc_len = TXD_DESC_SIZE;
116033aca94dSKalle Valo }
116133aca94dSKalle Valo 
116233aca94dSKalle Valo /*
116333aca94dSKalle Valo  * TX data initialization
116433aca94dSKalle Valo  */
rt2400pci_write_beacon(struct queue_entry * entry,struct txentry_desc * txdesc)116533aca94dSKalle Valo static void rt2400pci_write_beacon(struct queue_entry *entry,
116633aca94dSKalle Valo 				   struct txentry_desc *txdesc)
116733aca94dSKalle Valo {
116833aca94dSKalle Valo 	struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
116933aca94dSKalle Valo 	u32 reg;
117033aca94dSKalle Valo 
117133aca94dSKalle Valo 	/*
117233aca94dSKalle Valo 	 * Disable beaconing while we are reloading the beacon data,
117333aca94dSKalle Valo 	 * otherwise we might be sending out invalid data.
117433aca94dSKalle Valo 	 */
11753954b4e3SArnd Bergmann 	reg = rt2x00mmio_register_read(rt2x00dev, CSR14);
117633aca94dSKalle Valo 	rt2x00_set_field32(&reg, CSR14_BEACON_GEN, 0);
117733aca94dSKalle Valo 	rt2x00mmio_register_write(rt2x00dev, CSR14, reg);
117833aca94dSKalle Valo 
117933aca94dSKalle Valo 	if (rt2x00queue_map_txskb(entry)) {
118033aca94dSKalle Valo 		rt2x00_err(rt2x00dev, "Fail to map beacon, aborting\n");
118133aca94dSKalle Valo 		goto out;
118233aca94dSKalle Valo 	}
118333aca94dSKalle Valo 	/*
118433aca94dSKalle Valo 	 * Enable beaconing again.
118533aca94dSKalle Valo 	 */
118633aca94dSKalle Valo 	rt2x00_set_field32(&reg, CSR14_BEACON_GEN, 1);
118733aca94dSKalle Valo 	/*
118833aca94dSKalle Valo 	 * Write the TX descriptor for the beacon.
118933aca94dSKalle Valo 	 */
119033aca94dSKalle Valo 	rt2400pci_write_tx_desc(entry, txdesc);
119133aca94dSKalle Valo 
119233aca94dSKalle Valo 	/*
119333aca94dSKalle Valo 	 * Dump beacon to userspace through debugfs.
119433aca94dSKalle Valo 	 */
11952ceb8137SStanislaw Gruszka 	rt2x00debug_dump_frame(rt2x00dev, DUMP_FRAME_BEACON, entry);
119633aca94dSKalle Valo out:
119733aca94dSKalle Valo 	/*
119833aca94dSKalle Valo 	 * Enable beaconing again.
119933aca94dSKalle Valo 	 */
120033aca94dSKalle Valo 	rt2x00_set_field32(&reg, CSR14_BEACON_GEN, 1);
120133aca94dSKalle Valo 	rt2x00mmio_register_write(rt2x00dev, CSR14, reg);
120233aca94dSKalle Valo }
120333aca94dSKalle Valo 
120433aca94dSKalle Valo /*
120533aca94dSKalle Valo  * RX control handlers
120633aca94dSKalle Valo  */
rt2400pci_fill_rxdone(struct queue_entry * entry,struct rxdone_entry_desc * rxdesc)120733aca94dSKalle Valo static void rt2400pci_fill_rxdone(struct queue_entry *entry,
120833aca94dSKalle Valo 				  struct rxdone_entry_desc *rxdesc)
120933aca94dSKalle Valo {
121033aca94dSKalle Valo 	struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
121133aca94dSKalle Valo 	struct queue_entry_priv_mmio *entry_priv = entry->priv_data;
121233aca94dSKalle Valo 	u32 word0;
121333aca94dSKalle Valo 	u32 word2;
121433aca94dSKalle Valo 	u32 word3;
121533aca94dSKalle Valo 	u32 word4;
121633aca94dSKalle Valo 	u64 tsf;
121733aca94dSKalle Valo 	u32 rx_low;
121833aca94dSKalle Valo 	u32 rx_high;
121933aca94dSKalle Valo 
1220b9b23872SArnd Bergmann 	word0 = rt2x00_desc_read(entry_priv->desc, 0);
1221b9b23872SArnd Bergmann 	word2 = rt2x00_desc_read(entry_priv->desc, 2);
1222b9b23872SArnd Bergmann 	word3 = rt2x00_desc_read(entry_priv->desc, 3);
1223b9b23872SArnd Bergmann 	word4 = rt2x00_desc_read(entry_priv->desc, 4);
122433aca94dSKalle Valo 
122533aca94dSKalle Valo 	if (rt2x00_get_field32(word0, RXD_W0_CRC_ERROR))
122633aca94dSKalle Valo 		rxdesc->flags |= RX_FLAG_FAILED_FCS_CRC;
122733aca94dSKalle Valo 	if (rt2x00_get_field32(word0, RXD_W0_PHYSICAL_ERROR))
122833aca94dSKalle Valo 		rxdesc->flags |= RX_FLAG_FAILED_PLCP_CRC;
122933aca94dSKalle Valo 
123033aca94dSKalle Valo 	/*
123133aca94dSKalle Valo 	 * We only get the lower 32bits from the timestamp,
123233aca94dSKalle Valo 	 * to get the full 64bits we must complement it with
123333aca94dSKalle Valo 	 * the timestamp from get_tsf().
123433aca94dSKalle Valo 	 * Note that when a wraparound of the lower 32bits
123533aca94dSKalle Valo 	 * has occurred between the frame arrival and the get_tsf()
123633aca94dSKalle Valo 	 * call, we must decrease the higher 32bits with 1 to get
123733aca94dSKalle Valo 	 * to correct value.
123833aca94dSKalle Valo 	 */
123933aca94dSKalle Valo 	tsf = rt2x00dev->ops->hw->get_tsf(rt2x00dev->hw, NULL);
124033aca94dSKalle Valo 	rx_low = rt2x00_get_field32(word4, RXD_W4_RX_END_TIME);
124133aca94dSKalle Valo 	rx_high = upper_32_bits(tsf);
124233aca94dSKalle Valo 
124333aca94dSKalle Valo 	if ((u32)tsf <= rx_low)
124433aca94dSKalle Valo 		rx_high--;
124533aca94dSKalle Valo 
124633aca94dSKalle Valo 	/*
124733aca94dSKalle Valo 	 * Obtain the status about this packet.
124833aca94dSKalle Valo 	 * The signal is the PLCP value, and needs to be stripped
124933aca94dSKalle Valo 	 * of the preamble bit (0x08).
125033aca94dSKalle Valo 	 */
125133aca94dSKalle Valo 	rxdesc->timestamp = ((u64)rx_high << 32) | rx_low;
125233aca94dSKalle Valo 	rxdesc->signal = rt2x00_get_field32(word2, RXD_W2_SIGNAL) & ~0x08;
125333aca94dSKalle Valo 	rxdesc->rssi = rt2x00_get_field32(word3, RXD_W3_RSSI) -
125433aca94dSKalle Valo 	    entry->queue->rt2x00dev->rssi_offset;
125533aca94dSKalle Valo 	rxdesc->size = rt2x00_get_field32(word0, RXD_W0_DATABYTE_COUNT);
125633aca94dSKalle Valo 
125733aca94dSKalle Valo 	rxdesc->dev_flags |= RXDONE_SIGNAL_PLCP;
125833aca94dSKalle Valo 	if (rt2x00_get_field32(word0, RXD_W0_MY_BSS))
125933aca94dSKalle Valo 		rxdesc->dev_flags |= RXDONE_MY_BSS;
126033aca94dSKalle Valo }
126133aca94dSKalle Valo 
126233aca94dSKalle Valo /*
126333aca94dSKalle Valo  * Interrupt functions.
126433aca94dSKalle Valo  */
rt2400pci_txdone(struct rt2x00_dev * rt2x00dev,const enum data_queue_qid queue_idx)126533aca94dSKalle Valo static void rt2400pci_txdone(struct rt2x00_dev *rt2x00dev,
126633aca94dSKalle Valo 			     const enum data_queue_qid queue_idx)
126733aca94dSKalle Valo {
126833aca94dSKalle Valo 	struct data_queue *queue = rt2x00queue_get_tx_queue(rt2x00dev, queue_idx);
126933aca94dSKalle Valo 	struct queue_entry_priv_mmio *entry_priv;
127033aca94dSKalle Valo 	struct queue_entry *entry;
127133aca94dSKalle Valo 	struct txdone_entry_desc txdesc;
127233aca94dSKalle Valo 	u32 word;
127333aca94dSKalle Valo 
127433aca94dSKalle Valo 	while (!rt2x00queue_empty(queue)) {
127533aca94dSKalle Valo 		entry = rt2x00queue_get_entry(queue, Q_INDEX_DONE);
127633aca94dSKalle Valo 		entry_priv = entry->priv_data;
1277b9b23872SArnd Bergmann 		word = rt2x00_desc_read(entry_priv->desc, 0);
127833aca94dSKalle Valo 
127933aca94dSKalle Valo 		if (rt2x00_get_field32(word, TXD_W0_OWNER_NIC) ||
128033aca94dSKalle Valo 		    !rt2x00_get_field32(word, TXD_W0_VALID))
128133aca94dSKalle Valo 			break;
128233aca94dSKalle Valo 
128333aca94dSKalle Valo 		/*
128433aca94dSKalle Valo 		 * Obtain the status about this packet.
128533aca94dSKalle Valo 		 */
128633aca94dSKalle Valo 		txdesc.flags = 0;
128733aca94dSKalle Valo 		switch (rt2x00_get_field32(word, TXD_W0_RESULT)) {
128833aca94dSKalle Valo 		case 0: /* Success */
128933aca94dSKalle Valo 		case 1: /* Success with retry */
129033aca94dSKalle Valo 			__set_bit(TXDONE_SUCCESS, &txdesc.flags);
129133aca94dSKalle Valo 			break;
129233aca94dSKalle Valo 		case 2: /* Failure, excessive retries */
129333aca94dSKalle Valo 			__set_bit(TXDONE_EXCESSIVE_RETRY, &txdesc.flags);
129474aad394SGustavo A. R. Silva 			fallthrough;	/* this is a failed frame! */
129533aca94dSKalle Valo 		default: /* Failure */
129633aca94dSKalle Valo 			__set_bit(TXDONE_FAILURE, &txdesc.flags);
129733aca94dSKalle Valo 		}
129833aca94dSKalle Valo 		txdesc.retry = rt2x00_get_field32(word, TXD_W0_RETRY_COUNT);
129933aca94dSKalle Valo 
130033aca94dSKalle Valo 		rt2x00lib_txdone(entry, &txdesc);
130133aca94dSKalle Valo 	}
130233aca94dSKalle Valo }
130333aca94dSKalle Valo 
rt2400pci_enable_interrupt(struct rt2x00_dev * rt2x00dev,struct rt2x00_field32 irq_field)130433aca94dSKalle Valo static inline void rt2400pci_enable_interrupt(struct rt2x00_dev *rt2x00dev,
130533aca94dSKalle Valo 					      struct rt2x00_field32 irq_field)
130633aca94dSKalle Valo {
130733aca94dSKalle Valo 	u32 reg;
130833aca94dSKalle Valo 
130933aca94dSKalle Valo 	/*
131033aca94dSKalle Valo 	 * Enable a single interrupt. The interrupt mask register
131133aca94dSKalle Valo 	 * access needs locking.
131233aca94dSKalle Valo 	 */
131333aca94dSKalle Valo 	spin_lock_irq(&rt2x00dev->irqmask_lock);
131433aca94dSKalle Valo 
13153954b4e3SArnd Bergmann 	reg = rt2x00mmio_register_read(rt2x00dev, CSR8);
131633aca94dSKalle Valo 	rt2x00_set_field32(&reg, irq_field, 0);
131733aca94dSKalle Valo 	rt2x00mmio_register_write(rt2x00dev, CSR8, reg);
131833aca94dSKalle Valo 
131933aca94dSKalle Valo 	spin_unlock_irq(&rt2x00dev->irqmask_lock);
132033aca94dSKalle Valo }
132133aca94dSKalle Valo 
rt2400pci_txstatus_tasklet(struct tasklet_struct * t)1322a0d6ea9bSAllen Pais static void rt2400pci_txstatus_tasklet(struct tasklet_struct *t)
132333aca94dSKalle Valo {
1324a0d6ea9bSAllen Pais 	struct rt2x00_dev *rt2x00dev = from_tasklet(rt2x00dev, t,
1325a0d6ea9bSAllen Pais 						    txstatus_tasklet);
132633aca94dSKalle Valo 	u32 reg;
132733aca94dSKalle Valo 
132833aca94dSKalle Valo 	/*
132933aca94dSKalle Valo 	 * Handle all tx queues.
133033aca94dSKalle Valo 	 */
133133aca94dSKalle Valo 	rt2400pci_txdone(rt2x00dev, QID_ATIM);
133233aca94dSKalle Valo 	rt2400pci_txdone(rt2x00dev, QID_AC_VO);
133333aca94dSKalle Valo 	rt2400pci_txdone(rt2x00dev, QID_AC_VI);
133433aca94dSKalle Valo 
133533aca94dSKalle Valo 	/*
133633aca94dSKalle Valo 	 * Enable all TXDONE interrupts again.
133733aca94dSKalle Valo 	 */
133833aca94dSKalle Valo 	if (test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags)) {
133933aca94dSKalle Valo 		spin_lock_irq(&rt2x00dev->irqmask_lock);
134033aca94dSKalle Valo 
13413954b4e3SArnd Bergmann 		reg = rt2x00mmio_register_read(rt2x00dev, CSR8);
134233aca94dSKalle Valo 		rt2x00_set_field32(&reg, CSR8_TXDONE_TXRING, 0);
134333aca94dSKalle Valo 		rt2x00_set_field32(&reg, CSR8_TXDONE_ATIMRING, 0);
134433aca94dSKalle Valo 		rt2x00_set_field32(&reg, CSR8_TXDONE_PRIORING, 0);
134533aca94dSKalle Valo 		rt2x00mmio_register_write(rt2x00dev, CSR8, reg);
134633aca94dSKalle Valo 
134733aca94dSKalle Valo 		spin_unlock_irq(&rt2x00dev->irqmask_lock);
134833aca94dSKalle Valo 	}
134933aca94dSKalle Valo }
135033aca94dSKalle Valo 
rt2400pci_tbtt_tasklet(struct tasklet_struct * t)1351a0d6ea9bSAllen Pais static void rt2400pci_tbtt_tasklet(struct tasklet_struct *t)
135233aca94dSKalle Valo {
1353a0d6ea9bSAllen Pais 	struct rt2x00_dev *rt2x00dev = from_tasklet(rt2x00dev, t, tbtt_tasklet);
135433aca94dSKalle Valo 	rt2x00lib_beacondone(rt2x00dev);
135533aca94dSKalle Valo 	if (test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags))
135633aca94dSKalle Valo 		rt2400pci_enable_interrupt(rt2x00dev, CSR8_TBCN_EXPIRE);
135733aca94dSKalle Valo }
135833aca94dSKalle Valo 
rt2400pci_rxdone_tasklet(struct tasklet_struct * t)1359a0d6ea9bSAllen Pais static void rt2400pci_rxdone_tasklet(struct tasklet_struct *t)
136033aca94dSKalle Valo {
1361a0d6ea9bSAllen Pais 	struct rt2x00_dev *rt2x00dev = from_tasklet(rt2x00dev, t,
1362a0d6ea9bSAllen Pais 						    rxdone_tasklet);
136333aca94dSKalle Valo 	if (rt2x00mmio_rxdone(rt2x00dev))
136433aca94dSKalle Valo 		tasklet_schedule(&rt2x00dev->rxdone_tasklet);
136533aca94dSKalle Valo 	else if (test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags))
136633aca94dSKalle Valo 		rt2400pci_enable_interrupt(rt2x00dev, CSR8_RXDONE);
136733aca94dSKalle Valo }
136833aca94dSKalle Valo 
rt2400pci_interrupt(int irq,void * dev_instance)136933aca94dSKalle Valo static irqreturn_t rt2400pci_interrupt(int irq, void *dev_instance)
137033aca94dSKalle Valo {
137133aca94dSKalle Valo 	struct rt2x00_dev *rt2x00dev = dev_instance;
137233aca94dSKalle Valo 	u32 reg, mask;
137333aca94dSKalle Valo 
137433aca94dSKalle Valo 	/*
137533aca94dSKalle Valo 	 * Get the interrupt sources & saved to local variable.
137633aca94dSKalle Valo 	 * Write register value back to clear pending interrupts.
137733aca94dSKalle Valo 	 */
13783954b4e3SArnd Bergmann 	reg = rt2x00mmio_register_read(rt2x00dev, CSR7);
137933aca94dSKalle Valo 	rt2x00mmio_register_write(rt2x00dev, CSR7, reg);
138033aca94dSKalle Valo 
138133aca94dSKalle Valo 	if (!reg)
138233aca94dSKalle Valo 		return IRQ_NONE;
138333aca94dSKalle Valo 
138433aca94dSKalle Valo 	if (!test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags))
138533aca94dSKalle Valo 		return IRQ_HANDLED;
138633aca94dSKalle Valo 
138733aca94dSKalle Valo 	mask = reg;
138833aca94dSKalle Valo 
138933aca94dSKalle Valo 	/*
139033aca94dSKalle Valo 	 * Schedule tasklets for interrupt handling.
139133aca94dSKalle Valo 	 */
139233aca94dSKalle Valo 	if (rt2x00_get_field32(reg, CSR7_TBCN_EXPIRE))
139333aca94dSKalle Valo 		tasklet_hi_schedule(&rt2x00dev->tbtt_tasklet);
139433aca94dSKalle Valo 
139533aca94dSKalle Valo 	if (rt2x00_get_field32(reg, CSR7_RXDONE))
139633aca94dSKalle Valo 		tasklet_schedule(&rt2x00dev->rxdone_tasklet);
139733aca94dSKalle Valo 
139833aca94dSKalle Valo 	if (rt2x00_get_field32(reg, CSR7_TXDONE_ATIMRING) ||
139933aca94dSKalle Valo 	    rt2x00_get_field32(reg, CSR7_TXDONE_PRIORING) ||
140033aca94dSKalle Valo 	    rt2x00_get_field32(reg, CSR7_TXDONE_TXRING)) {
140133aca94dSKalle Valo 		tasklet_schedule(&rt2x00dev->txstatus_tasklet);
140233aca94dSKalle Valo 		/*
140333aca94dSKalle Valo 		 * Mask out all txdone interrupts.
140433aca94dSKalle Valo 		 */
140533aca94dSKalle Valo 		rt2x00_set_field32(&mask, CSR8_TXDONE_TXRING, 1);
140633aca94dSKalle Valo 		rt2x00_set_field32(&mask, CSR8_TXDONE_ATIMRING, 1);
140733aca94dSKalle Valo 		rt2x00_set_field32(&mask, CSR8_TXDONE_PRIORING, 1);
140833aca94dSKalle Valo 	}
140933aca94dSKalle Valo 
141033aca94dSKalle Valo 	/*
141133aca94dSKalle Valo 	 * Disable all interrupts for which a tasklet was scheduled right now,
141233aca94dSKalle Valo 	 * the tasklet will reenable the appropriate interrupts.
141333aca94dSKalle Valo 	 */
141433aca94dSKalle Valo 	spin_lock(&rt2x00dev->irqmask_lock);
141533aca94dSKalle Valo 
14163954b4e3SArnd Bergmann 	reg = rt2x00mmio_register_read(rt2x00dev, CSR8);
141733aca94dSKalle Valo 	reg |= mask;
141833aca94dSKalle Valo 	rt2x00mmio_register_write(rt2x00dev, CSR8, reg);
141933aca94dSKalle Valo 
142033aca94dSKalle Valo 	spin_unlock(&rt2x00dev->irqmask_lock);
142133aca94dSKalle Valo 
142233aca94dSKalle Valo 
142333aca94dSKalle Valo 
142433aca94dSKalle Valo 	return IRQ_HANDLED;
142533aca94dSKalle Valo }
142633aca94dSKalle Valo 
142733aca94dSKalle Valo /*
142833aca94dSKalle Valo  * Device probe functions.
142933aca94dSKalle Valo  */
rt2400pci_validate_eeprom(struct rt2x00_dev * rt2x00dev)143033aca94dSKalle Valo static int rt2400pci_validate_eeprom(struct rt2x00_dev *rt2x00dev)
143133aca94dSKalle Valo {
143233aca94dSKalle Valo 	struct eeprom_93cx6 eeprom;
143333aca94dSKalle Valo 	u32 reg;
143433aca94dSKalle Valo 	u16 word;
143533aca94dSKalle Valo 	u8 *mac;
143633aca94dSKalle Valo 
14373954b4e3SArnd Bergmann 	reg = rt2x00mmio_register_read(rt2x00dev, CSR21);
143833aca94dSKalle Valo 
143933aca94dSKalle Valo 	eeprom.data = rt2x00dev;
144033aca94dSKalle Valo 	eeprom.register_read = rt2400pci_eepromregister_read;
144133aca94dSKalle Valo 	eeprom.register_write = rt2400pci_eepromregister_write;
144233aca94dSKalle Valo 	eeprom.width = rt2x00_get_field32(reg, CSR21_TYPE_93C46) ?
144333aca94dSKalle Valo 	    PCI_EEPROM_WIDTH_93C46 : PCI_EEPROM_WIDTH_93C66;
144433aca94dSKalle Valo 	eeprom.reg_data_in = 0;
144533aca94dSKalle Valo 	eeprom.reg_data_out = 0;
144633aca94dSKalle Valo 	eeprom.reg_data_clock = 0;
144733aca94dSKalle Valo 	eeprom.reg_chip_select = 0;
144833aca94dSKalle Valo 
144933aca94dSKalle Valo 	eeprom_93cx6_multiread(&eeprom, EEPROM_BASE, rt2x00dev->eeprom,
145033aca94dSKalle Valo 			       EEPROM_SIZE / sizeof(u16));
145133aca94dSKalle Valo 
145233aca94dSKalle Valo 	/*
145333aca94dSKalle Valo 	 * Start validation of the data that has been read.
145433aca94dSKalle Valo 	 */
145533aca94dSKalle Valo 	mac = rt2x00_eeprom_addr(rt2x00dev, EEPROM_MAC_ADDR_0);
14569766cb70SMathias Kresin 	rt2x00lib_set_mac_address(rt2x00dev, mac);
145733aca94dSKalle Valo 
145838651683SArnd Bergmann 	word = rt2x00_eeprom_read(rt2x00dev, EEPROM_ANTENNA);
145933aca94dSKalle Valo 	if (word == 0xffff) {
146033aca94dSKalle Valo 		rt2x00_err(rt2x00dev, "Invalid EEPROM data detected\n");
146133aca94dSKalle Valo 		return -EINVAL;
146233aca94dSKalle Valo 	}
146333aca94dSKalle Valo 
146433aca94dSKalle Valo 	return 0;
146533aca94dSKalle Valo }
146633aca94dSKalle Valo 
rt2400pci_init_eeprom(struct rt2x00_dev * rt2x00dev)146733aca94dSKalle Valo static int rt2400pci_init_eeprom(struct rt2x00_dev *rt2x00dev)
146833aca94dSKalle Valo {
146933aca94dSKalle Valo 	u32 reg;
147033aca94dSKalle Valo 	u16 value;
147133aca94dSKalle Valo 	u16 eeprom;
147233aca94dSKalle Valo 
147333aca94dSKalle Valo 	/*
147433aca94dSKalle Valo 	 * Read EEPROM word for configuration.
147533aca94dSKalle Valo 	 */
147638651683SArnd Bergmann 	eeprom = rt2x00_eeprom_read(rt2x00dev, EEPROM_ANTENNA);
147733aca94dSKalle Valo 
147833aca94dSKalle Valo 	/*
147933aca94dSKalle Valo 	 * Identify RF chipset.
148033aca94dSKalle Valo 	 */
148133aca94dSKalle Valo 	value = rt2x00_get_field16(eeprom, EEPROM_ANTENNA_RF_TYPE);
14823954b4e3SArnd Bergmann 	reg = rt2x00mmio_register_read(rt2x00dev, CSR0);
148333aca94dSKalle Valo 	rt2x00_set_chip(rt2x00dev, RT2460, value,
148433aca94dSKalle Valo 			rt2x00_get_field32(reg, CSR0_REVISION));
148533aca94dSKalle Valo 
148633aca94dSKalle Valo 	if (!rt2x00_rf(rt2x00dev, RF2420) && !rt2x00_rf(rt2x00dev, RF2421)) {
148733aca94dSKalle Valo 		rt2x00_err(rt2x00dev, "Invalid RF chipset detected\n");
148833aca94dSKalle Valo 		return -ENODEV;
148933aca94dSKalle Valo 	}
149033aca94dSKalle Valo 
149133aca94dSKalle Valo 	/*
149233aca94dSKalle Valo 	 * Identify default antenna configuration.
149333aca94dSKalle Valo 	 */
149433aca94dSKalle Valo 	rt2x00dev->default_ant.tx =
149533aca94dSKalle Valo 	    rt2x00_get_field16(eeprom, EEPROM_ANTENNA_TX_DEFAULT);
149633aca94dSKalle Valo 	rt2x00dev->default_ant.rx =
149733aca94dSKalle Valo 	    rt2x00_get_field16(eeprom, EEPROM_ANTENNA_RX_DEFAULT);
149833aca94dSKalle Valo 
149933aca94dSKalle Valo 	/*
150033aca94dSKalle Valo 	 * When the eeprom indicates SW_DIVERSITY use HW_DIVERSITY instead.
150133aca94dSKalle Valo 	 * I am not 100% sure about this, but the legacy drivers do not
150233aca94dSKalle Valo 	 * indicate antenna swapping in software is required when
150333aca94dSKalle Valo 	 * diversity is enabled.
150433aca94dSKalle Valo 	 */
150533aca94dSKalle Valo 	if (rt2x00dev->default_ant.tx == ANTENNA_SW_DIVERSITY)
150633aca94dSKalle Valo 		rt2x00dev->default_ant.tx = ANTENNA_HW_DIVERSITY;
150733aca94dSKalle Valo 	if (rt2x00dev->default_ant.rx == ANTENNA_SW_DIVERSITY)
150833aca94dSKalle Valo 		rt2x00dev->default_ant.rx = ANTENNA_HW_DIVERSITY;
150933aca94dSKalle Valo 
151033aca94dSKalle Valo 	/*
151133aca94dSKalle Valo 	 * Store led mode, for correct led behaviour.
151233aca94dSKalle Valo 	 */
151333aca94dSKalle Valo #ifdef CONFIG_RT2X00_LIB_LEDS
151433aca94dSKalle Valo 	value = rt2x00_get_field16(eeprom, EEPROM_ANTENNA_LED_MODE);
151533aca94dSKalle Valo 
151633aca94dSKalle Valo 	rt2400pci_init_led(rt2x00dev, &rt2x00dev->led_radio, LED_TYPE_RADIO);
151733aca94dSKalle Valo 	if (value == LED_MODE_TXRX_ACTIVITY ||
151833aca94dSKalle Valo 	    value == LED_MODE_DEFAULT ||
151933aca94dSKalle Valo 	    value == LED_MODE_ASUS)
152033aca94dSKalle Valo 		rt2400pci_init_led(rt2x00dev, &rt2x00dev->led_qual,
152133aca94dSKalle Valo 				   LED_TYPE_ACTIVITY);
152233aca94dSKalle Valo #endif /* CONFIG_RT2X00_LIB_LEDS */
152333aca94dSKalle Valo 
152433aca94dSKalle Valo 	/*
152533aca94dSKalle Valo 	 * Detect if this device has an hardware controlled radio.
152633aca94dSKalle Valo 	 */
152733aca94dSKalle Valo 	if (rt2x00_get_field16(eeprom, EEPROM_ANTENNA_HARDWARE_RADIO))
152833aca94dSKalle Valo 		__set_bit(CAPABILITY_HW_BUTTON, &rt2x00dev->cap_flags);
152933aca94dSKalle Valo 
153033aca94dSKalle Valo 	/*
153133aca94dSKalle Valo 	 * Check if the BBP tuning should be enabled.
153233aca94dSKalle Valo 	 */
153333aca94dSKalle Valo 	if (rt2x00_get_field16(eeprom, EEPROM_ANTENNA_RX_AGCVGC_TUNING))
153433aca94dSKalle Valo 		__set_bit(CAPABILITY_LINK_TUNING, &rt2x00dev->cap_flags);
153533aca94dSKalle Valo 
153633aca94dSKalle Valo 	return 0;
153733aca94dSKalle Valo }
153833aca94dSKalle Valo 
153933aca94dSKalle Valo /*
154033aca94dSKalle Valo  * RF value list for RF2420 & RF2421
154133aca94dSKalle Valo  * Supports: 2.4 GHz
154233aca94dSKalle Valo  */
154333aca94dSKalle Valo static const struct rf_channel rf_vals_b[] = {
154433aca94dSKalle Valo 	{ 1,  0x00022058, 0x000c1fda, 0x00000101, 0 },
154533aca94dSKalle Valo 	{ 2,  0x00022058, 0x000c1fee, 0x00000101, 0 },
154633aca94dSKalle Valo 	{ 3,  0x00022058, 0x000c2002, 0x00000101, 0 },
154733aca94dSKalle Valo 	{ 4,  0x00022058, 0x000c2016, 0x00000101, 0 },
154833aca94dSKalle Valo 	{ 5,  0x00022058, 0x000c202a, 0x00000101, 0 },
154933aca94dSKalle Valo 	{ 6,  0x00022058, 0x000c203e, 0x00000101, 0 },
155033aca94dSKalle Valo 	{ 7,  0x00022058, 0x000c2052, 0x00000101, 0 },
155133aca94dSKalle Valo 	{ 8,  0x00022058, 0x000c2066, 0x00000101, 0 },
155233aca94dSKalle Valo 	{ 9,  0x00022058, 0x000c207a, 0x00000101, 0 },
155333aca94dSKalle Valo 	{ 10, 0x00022058, 0x000c208e, 0x00000101, 0 },
155433aca94dSKalle Valo 	{ 11, 0x00022058, 0x000c20a2, 0x00000101, 0 },
155533aca94dSKalle Valo 	{ 12, 0x00022058, 0x000c20b6, 0x00000101, 0 },
155633aca94dSKalle Valo 	{ 13, 0x00022058, 0x000c20ca, 0x00000101, 0 },
155733aca94dSKalle Valo 	{ 14, 0x00022058, 0x000c20fa, 0x00000101, 0 },
155833aca94dSKalle Valo };
155933aca94dSKalle Valo 
rt2400pci_probe_hw_mode(struct rt2x00_dev * rt2x00dev)156033aca94dSKalle Valo static int rt2400pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
156133aca94dSKalle Valo {
156233aca94dSKalle Valo 	struct hw_mode_spec *spec = &rt2x00dev->spec;
156333aca94dSKalle Valo 	struct channel_info *info;
1564*66063033SJason A. Donenfeld 	u8 *tx_power;
156533aca94dSKalle Valo 	unsigned int i;
156633aca94dSKalle Valo 
156733aca94dSKalle Valo 	/*
156833aca94dSKalle Valo 	 * Initialize all hw fields.
156933aca94dSKalle Valo 	 */
157033aca94dSKalle Valo 	ieee80211_hw_set(rt2x00dev->hw, PS_NULLFUNC_STACK);
157133aca94dSKalle Valo 	ieee80211_hw_set(rt2x00dev->hw, SUPPORTS_PS);
157233aca94dSKalle Valo 	ieee80211_hw_set(rt2x00dev->hw, HOST_BROADCAST_PS_BUFFERING);
157333aca94dSKalle Valo 	ieee80211_hw_set(rt2x00dev->hw, SIGNAL_DBM);
157433aca94dSKalle Valo 
157533aca94dSKalle Valo 	SET_IEEE80211_DEV(rt2x00dev->hw, rt2x00dev->dev);
157633aca94dSKalle Valo 	SET_IEEE80211_PERM_ADDR(rt2x00dev->hw,
157733aca94dSKalle Valo 				rt2x00_eeprom_addr(rt2x00dev,
157833aca94dSKalle Valo 						   EEPROM_MAC_ADDR_0));
157933aca94dSKalle Valo 
158033aca94dSKalle Valo 	/*
158133aca94dSKalle Valo 	 * Initialize hw_mode information.
158233aca94dSKalle Valo 	 */
158333aca94dSKalle Valo 	spec->supported_bands = SUPPORT_BAND_2GHZ;
158433aca94dSKalle Valo 	spec->supported_rates = SUPPORT_RATE_CCK;
158533aca94dSKalle Valo 
158633aca94dSKalle Valo 	spec->num_channels = ARRAY_SIZE(rf_vals_b);
158733aca94dSKalle Valo 	spec->channels = rf_vals_b;
158833aca94dSKalle Valo 
158933aca94dSKalle Valo 	/*
159033aca94dSKalle Valo 	 * Create channel information array
159133aca94dSKalle Valo 	 */
159233aca94dSKalle Valo 	info = kcalloc(spec->num_channels, sizeof(*info), GFP_KERNEL);
159333aca94dSKalle Valo 	if (!info)
159433aca94dSKalle Valo 		return -ENOMEM;
159533aca94dSKalle Valo 
159633aca94dSKalle Valo 	spec->channels_info = info;
159733aca94dSKalle Valo 
159833aca94dSKalle Valo 	tx_power = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_START);
159933aca94dSKalle Valo 	for (i = 0; i < 14; i++) {
160033aca94dSKalle Valo 		info[i].max_power = TXPOWER_FROM_DEV(MAX_TXPOWER);
160133aca94dSKalle Valo 		info[i].default_power1 = TXPOWER_FROM_DEV(tx_power[i]);
160233aca94dSKalle Valo 	}
160333aca94dSKalle Valo 
160433aca94dSKalle Valo 	return 0;
160533aca94dSKalle Valo }
160633aca94dSKalle Valo 
rt2400pci_probe_hw(struct rt2x00_dev * rt2x00dev)160733aca94dSKalle Valo static int rt2400pci_probe_hw(struct rt2x00_dev *rt2x00dev)
160833aca94dSKalle Valo {
160933aca94dSKalle Valo 	int retval;
161033aca94dSKalle Valo 	u32 reg;
161133aca94dSKalle Valo 
161233aca94dSKalle Valo 	/*
161333aca94dSKalle Valo 	 * Allocate eeprom data.
161433aca94dSKalle Valo 	 */
161533aca94dSKalle Valo 	retval = rt2400pci_validate_eeprom(rt2x00dev);
161633aca94dSKalle Valo 	if (retval)
161733aca94dSKalle Valo 		return retval;
161833aca94dSKalle Valo 
161933aca94dSKalle Valo 	retval = rt2400pci_init_eeprom(rt2x00dev);
162033aca94dSKalle Valo 	if (retval)
162133aca94dSKalle Valo 		return retval;
162233aca94dSKalle Valo 
162333aca94dSKalle Valo 	/*
162433aca94dSKalle Valo 	 * Enable rfkill polling by setting GPIO direction of the
162533aca94dSKalle Valo 	 * rfkill switch GPIO pin correctly.
162633aca94dSKalle Valo 	 */
16273954b4e3SArnd Bergmann 	reg = rt2x00mmio_register_read(rt2x00dev, GPIOCSR);
162833aca94dSKalle Valo 	rt2x00_set_field32(&reg, GPIOCSR_DIR0, 1);
162933aca94dSKalle Valo 	rt2x00mmio_register_write(rt2x00dev, GPIOCSR, reg);
163033aca94dSKalle Valo 
163133aca94dSKalle Valo 	/*
163233aca94dSKalle Valo 	 * Initialize hw specifications.
163333aca94dSKalle Valo 	 */
163433aca94dSKalle Valo 	retval = rt2400pci_probe_hw_mode(rt2x00dev);
163533aca94dSKalle Valo 	if (retval)
163633aca94dSKalle Valo 		return retval;
163733aca94dSKalle Valo 
163833aca94dSKalle Valo 	/*
163933aca94dSKalle Valo 	 * This device requires the atim queue and DMA-mapped skbs.
164033aca94dSKalle Valo 	 */
164133aca94dSKalle Valo 	__set_bit(REQUIRE_ATIM_QUEUE, &rt2x00dev->cap_flags);
164233aca94dSKalle Valo 	__set_bit(REQUIRE_DMA, &rt2x00dev->cap_flags);
164333aca94dSKalle Valo 	__set_bit(REQUIRE_SW_SEQNO, &rt2x00dev->cap_flags);
164433aca94dSKalle Valo 
164533aca94dSKalle Valo 	/*
164633aca94dSKalle Valo 	 * Set the rssi offset.
164733aca94dSKalle Valo 	 */
164833aca94dSKalle Valo 	rt2x00dev->rssi_offset = DEFAULT_RSSI_OFFSET;
164933aca94dSKalle Valo 
165033aca94dSKalle Valo 	return 0;
165133aca94dSKalle Valo }
165233aca94dSKalle Valo 
165333aca94dSKalle Valo /*
165433aca94dSKalle Valo  * IEEE80211 stack callback functions.
165533aca94dSKalle Valo  */
rt2400pci_conf_tx(struct ieee80211_hw * hw,struct ieee80211_vif * vif,unsigned int link_id,u16 queue,const struct ieee80211_tx_queue_params * params)165633aca94dSKalle Valo static int rt2400pci_conf_tx(struct ieee80211_hw *hw,
1657b3e2130bSJohannes Berg 			     struct ieee80211_vif *vif,
1658b3e2130bSJohannes Berg 			     unsigned int link_id, u16 queue,
165933aca94dSKalle Valo 			     const struct ieee80211_tx_queue_params *params)
166033aca94dSKalle Valo {
166133aca94dSKalle Valo 	struct rt2x00_dev *rt2x00dev = hw->priv;
166233aca94dSKalle Valo 
166333aca94dSKalle Valo 	/*
166433aca94dSKalle Valo 	 * We don't support variating cw_min and cw_max variables
166533aca94dSKalle Valo 	 * per queue. So by default we only configure the TX queue,
166633aca94dSKalle Valo 	 * and ignore all other configurations.
166733aca94dSKalle Valo 	 */
166833aca94dSKalle Valo 	if (queue != 0)
166933aca94dSKalle Valo 		return -EINVAL;
167033aca94dSKalle Valo 
1671b3e2130bSJohannes Berg 	if (rt2x00mac_conf_tx(hw, vif, link_id, queue, params))
167233aca94dSKalle Valo 		return -EINVAL;
167333aca94dSKalle Valo 
167433aca94dSKalle Valo 	/*
167533aca94dSKalle Valo 	 * Write configuration to register.
167633aca94dSKalle Valo 	 */
167733aca94dSKalle Valo 	rt2400pci_config_cw(rt2x00dev,
167833aca94dSKalle Valo 			    rt2x00dev->tx->cw_min, rt2x00dev->tx->cw_max);
167933aca94dSKalle Valo 
168033aca94dSKalle Valo 	return 0;
168133aca94dSKalle Valo }
168233aca94dSKalle Valo 
rt2400pci_get_tsf(struct ieee80211_hw * hw,struct ieee80211_vif * vif)168333aca94dSKalle Valo static u64 rt2400pci_get_tsf(struct ieee80211_hw *hw,
168433aca94dSKalle Valo 			     struct ieee80211_vif *vif)
168533aca94dSKalle Valo {
168633aca94dSKalle Valo 	struct rt2x00_dev *rt2x00dev = hw->priv;
168733aca94dSKalle Valo 	u64 tsf;
168833aca94dSKalle Valo 	u32 reg;
168933aca94dSKalle Valo 
16903954b4e3SArnd Bergmann 	reg = rt2x00mmio_register_read(rt2x00dev, CSR17);
169133aca94dSKalle Valo 	tsf = (u64) rt2x00_get_field32(reg, CSR17_HIGH_TSFTIMER) << 32;
16923954b4e3SArnd Bergmann 	reg = rt2x00mmio_register_read(rt2x00dev, CSR16);
169333aca94dSKalle Valo 	tsf |= rt2x00_get_field32(reg, CSR16_LOW_TSFTIMER);
169433aca94dSKalle Valo 
169533aca94dSKalle Valo 	return tsf;
169633aca94dSKalle Valo }
169733aca94dSKalle Valo 
rt2400pci_tx_last_beacon(struct ieee80211_hw * hw)169833aca94dSKalle Valo static int rt2400pci_tx_last_beacon(struct ieee80211_hw *hw)
169933aca94dSKalle Valo {
170033aca94dSKalle Valo 	struct rt2x00_dev *rt2x00dev = hw->priv;
170133aca94dSKalle Valo 	u32 reg;
170233aca94dSKalle Valo 
17033954b4e3SArnd Bergmann 	reg = rt2x00mmio_register_read(rt2x00dev, CSR15);
170433aca94dSKalle Valo 	return rt2x00_get_field32(reg, CSR15_BEACON_SENT);
170533aca94dSKalle Valo }
170633aca94dSKalle Valo 
170733aca94dSKalle Valo static const struct ieee80211_ops rt2400pci_mac80211_ops = {
170833aca94dSKalle Valo 	.tx			= rt2x00mac_tx,
1709a790cc3aSAlexander Wetzel 	.wake_tx_queue		= ieee80211_handle_wake_tx_queue,
171033aca94dSKalle Valo 	.start			= rt2x00mac_start,
171133aca94dSKalle Valo 	.stop			= rt2x00mac_stop,
171233aca94dSKalle Valo 	.add_interface		= rt2x00mac_add_interface,
171333aca94dSKalle Valo 	.remove_interface	= rt2x00mac_remove_interface,
171433aca94dSKalle Valo 	.config			= rt2x00mac_config,
171533aca94dSKalle Valo 	.configure_filter	= rt2x00mac_configure_filter,
171633aca94dSKalle Valo 	.sw_scan_start		= rt2x00mac_sw_scan_start,
171733aca94dSKalle Valo 	.sw_scan_complete	= rt2x00mac_sw_scan_complete,
171833aca94dSKalle Valo 	.get_stats		= rt2x00mac_get_stats,
171933aca94dSKalle Valo 	.bss_info_changed	= rt2x00mac_bss_info_changed,
172033aca94dSKalle Valo 	.conf_tx		= rt2400pci_conf_tx,
172133aca94dSKalle Valo 	.get_tsf		= rt2400pci_get_tsf,
172233aca94dSKalle Valo 	.tx_last_beacon		= rt2400pci_tx_last_beacon,
172333aca94dSKalle Valo 	.rfkill_poll		= rt2x00mac_rfkill_poll,
172433aca94dSKalle Valo 	.flush			= rt2x00mac_flush,
172533aca94dSKalle Valo 	.set_antenna		= rt2x00mac_set_antenna,
172633aca94dSKalle Valo 	.get_antenna		= rt2x00mac_get_antenna,
172733aca94dSKalle Valo 	.get_ringparam		= rt2x00mac_get_ringparam,
172833aca94dSKalle Valo 	.tx_frames_pending	= rt2x00mac_tx_frames_pending,
172933aca94dSKalle Valo };
173033aca94dSKalle Valo 
173133aca94dSKalle Valo static const struct rt2x00lib_ops rt2400pci_rt2x00_ops = {
173233aca94dSKalle Valo 	.irq_handler		= rt2400pci_interrupt,
173333aca94dSKalle Valo 	.txstatus_tasklet	= rt2400pci_txstatus_tasklet,
173433aca94dSKalle Valo 	.tbtt_tasklet		= rt2400pci_tbtt_tasklet,
173533aca94dSKalle Valo 	.rxdone_tasklet		= rt2400pci_rxdone_tasklet,
173633aca94dSKalle Valo 	.probe_hw		= rt2400pci_probe_hw,
173733aca94dSKalle Valo 	.initialize		= rt2x00mmio_initialize,
173833aca94dSKalle Valo 	.uninitialize		= rt2x00mmio_uninitialize,
173933aca94dSKalle Valo 	.get_entry_state	= rt2400pci_get_entry_state,
174033aca94dSKalle Valo 	.clear_entry		= rt2400pci_clear_entry,
174133aca94dSKalle Valo 	.set_device_state	= rt2400pci_set_device_state,
174233aca94dSKalle Valo 	.rfkill_poll		= rt2400pci_rfkill_poll,
174333aca94dSKalle Valo 	.link_stats		= rt2400pci_link_stats,
174433aca94dSKalle Valo 	.reset_tuner		= rt2400pci_reset_tuner,
174533aca94dSKalle Valo 	.link_tuner		= rt2400pci_link_tuner,
174633aca94dSKalle Valo 	.start_queue		= rt2400pci_start_queue,
174733aca94dSKalle Valo 	.kick_queue		= rt2400pci_kick_queue,
174833aca94dSKalle Valo 	.stop_queue		= rt2400pci_stop_queue,
174933aca94dSKalle Valo 	.flush_queue		= rt2x00mmio_flush_queue,
175033aca94dSKalle Valo 	.write_tx_desc		= rt2400pci_write_tx_desc,
175133aca94dSKalle Valo 	.write_beacon		= rt2400pci_write_beacon,
175233aca94dSKalle Valo 	.fill_rxdone		= rt2400pci_fill_rxdone,
175333aca94dSKalle Valo 	.config_filter		= rt2400pci_config_filter,
175433aca94dSKalle Valo 	.config_intf		= rt2400pci_config_intf,
175533aca94dSKalle Valo 	.config_erp		= rt2400pci_config_erp,
175633aca94dSKalle Valo 	.config_ant		= rt2400pci_config_ant,
175733aca94dSKalle Valo 	.config			= rt2400pci_config,
175833aca94dSKalle Valo };
175933aca94dSKalle Valo 
rt2400pci_queue_init(struct data_queue * queue)176033aca94dSKalle Valo static void rt2400pci_queue_init(struct data_queue *queue)
176133aca94dSKalle Valo {
176233aca94dSKalle Valo 	switch (queue->qid) {
176333aca94dSKalle Valo 	case QID_RX:
176433aca94dSKalle Valo 		queue->limit = 24;
176533aca94dSKalle Valo 		queue->data_size = DATA_FRAME_SIZE;
176633aca94dSKalle Valo 		queue->desc_size = RXD_DESC_SIZE;
176733aca94dSKalle Valo 		queue->priv_size = sizeof(struct queue_entry_priv_mmio);
176833aca94dSKalle Valo 		break;
176933aca94dSKalle Valo 
177033aca94dSKalle Valo 	case QID_AC_VO:
177133aca94dSKalle Valo 	case QID_AC_VI:
177233aca94dSKalle Valo 	case QID_AC_BE:
177333aca94dSKalle Valo 	case QID_AC_BK:
177433aca94dSKalle Valo 		queue->limit = 24;
177533aca94dSKalle Valo 		queue->data_size = DATA_FRAME_SIZE;
177633aca94dSKalle Valo 		queue->desc_size = TXD_DESC_SIZE;
177733aca94dSKalle Valo 		queue->priv_size = sizeof(struct queue_entry_priv_mmio);
177833aca94dSKalle Valo 		break;
177933aca94dSKalle Valo 
178033aca94dSKalle Valo 	case QID_BEACON:
178133aca94dSKalle Valo 		queue->limit = 1;
178233aca94dSKalle Valo 		queue->data_size = MGMT_FRAME_SIZE;
178333aca94dSKalle Valo 		queue->desc_size = TXD_DESC_SIZE;
178433aca94dSKalle Valo 		queue->priv_size = sizeof(struct queue_entry_priv_mmio);
178533aca94dSKalle Valo 		break;
178633aca94dSKalle Valo 
178733aca94dSKalle Valo 	case QID_ATIM:
178833aca94dSKalle Valo 		queue->limit = 8;
178933aca94dSKalle Valo 		queue->data_size = DATA_FRAME_SIZE;
179033aca94dSKalle Valo 		queue->desc_size = TXD_DESC_SIZE;
179133aca94dSKalle Valo 		queue->priv_size = sizeof(struct queue_entry_priv_mmio);
179233aca94dSKalle Valo 		break;
179333aca94dSKalle Valo 
179433aca94dSKalle Valo 	default:
179533aca94dSKalle Valo 		BUG();
179633aca94dSKalle Valo 		break;
179733aca94dSKalle Valo 	}
179833aca94dSKalle Valo }
179933aca94dSKalle Valo 
180033aca94dSKalle Valo static const struct rt2x00_ops rt2400pci_ops = {
180133aca94dSKalle Valo 	.name			= KBUILD_MODNAME,
180233aca94dSKalle Valo 	.max_ap_intf		= 1,
180333aca94dSKalle Valo 	.eeprom_size		= EEPROM_SIZE,
180433aca94dSKalle Valo 	.rf_size		= RF_SIZE,
180533aca94dSKalle Valo 	.tx_queues		= NUM_TX_QUEUES,
180633aca94dSKalle Valo 	.queue_init		= rt2400pci_queue_init,
180733aca94dSKalle Valo 	.lib			= &rt2400pci_rt2x00_ops,
180833aca94dSKalle Valo 	.hw			= &rt2400pci_mac80211_ops,
180933aca94dSKalle Valo #ifdef CONFIG_RT2X00_LIB_DEBUGFS
181033aca94dSKalle Valo 	.debugfs		= &rt2400pci_rt2x00debug,
181133aca94dSKalle Valo #endif /* CONFIG_RT2X00_LIB_DEBUGFS */
181233aca94dSKalle Valo };
181333aca94dSKalle Valo 
181433aca94dSKalle Valo /*
181533aca94dSKalle Valo  * RT2400pci module information.
181633aca94dSKalle Valo  */
181733aca94dSKalle Valo static const struct pci_device_id rt2400pci_device_table[] = {
181833aca94dSKalle Valo 	{ PCI_DEVICE(0x1814, 0x0101) },
181933aca94dSKalle Valo 	{ 0, }
182033aca94dSKalle Valo };
182133aca94dSKalle Valo 
182233aca94dSKalle Valo 
182333aca94dSKalle Valo MODULE_AUTHOR(DRV_PROJECT);
182433aca94dSKalle Valo MODULE_VERSION(DRV_VERSION);
182533aca94dSKalle Valo MODULE_DESCRIPTION("Ralink RT2400 PCI & PCMCIA Wireless LAN driver.");
182633aca94dSKalle Valo MODULE_DEVICE_TABLE(pci, rt2400pci_device_table);
182733aca94dSKalle Valo MODULE_LICENSE("GPL");
182833aca94dSKalle Valo 
rt2400pci_probe(struct pci_dev * pci_dev,const struct pci_device_id * id)182933aca94dSKalle Valo static int rt2400pci_probe(struct pci_dev *pci_dev,
183033aca94dSKalle Valo 			   const struct pci_device_id *id)
183133aca94dSKalle Valo {
183233aca94dSKalle Valo 	return rt2x00pci_probe(pci_dev, &rt2400pci_ops);
183333aca94dSKalle Valo }
183433aca94dSKalle Valo 
183533aca94dSKalle Valo static struct pci_driver rt2400pci_driver = {
183633aca94dSKalle Valo 	.name		= KBUILD_MODNAME,
183733aca94dSKalle Valo 	.id_table	= rt2400pci_device_table,
183833aca94dSKalle Valo 	.probe		= rt2400pci_probe,
183933aca94dSKalle Valo 	.remove		= rt2x00pci_remove,
1840560a218dSVaibhav Gupta 	.driver.pm	= &rt2x00pci_pm_ops,
184133aca94dSKalle Valo };
184233aca94dSKalle Valo 
184333aca94dSKalle Valo module_pci_driver(rt2400pci_driver);
1844