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