195ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn/*
29c9a0d145fee73b5e821bb460732ac2a66c680b3Gertjan van Wingerde	Copyright (C) 2004 - 2009 Ivo van Doorn <IvDoorn@gmail.com>
395ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	<http://rt2x00.serialmonkey.com>
495ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn
595ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	This program is free software; you can redistribute it and/or modify
695ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	it under the terms of the GNU General Public License as published by
795ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	the Free Software Foundation; either version 2 of the License, or
895ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	(at your option) any later version.
995ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn
1095ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	This program is distributed in the hope that it will be useful,
1195ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	but WITHOUT ANY WARRANTY; without even the implied warranty of
1295ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1395ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	GNU General Public License for more details.
1495ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn
1595ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	You should have received a copy of the GNU General Public License
1695ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	along with this program; if not, write to the
1795ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	Free Software Foundation, Inc.,
1895ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
1995ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn */
2095ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn
2195ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn/*
2295ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	Module: rt2500pci
2395ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	Abstract: rt2500pci device specific routines.
2495ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	Supported chipsets: RT2560.
2595ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn */
2695ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn
2795ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn#include <linux/delay.h>
2895ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn#include <linux/etherdevice.h>
2995ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn#include <linux/init.h>
3095ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn#include <linux/kernel.h>
3195ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn#include <linux/module.h>
3295ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn#include <linux/pci.h>
3395ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn#include <linux/eeprom_93cx6.h>
345a0e3ad6af8660be21ca98a971cd00f331318c05Tejun Heo#include <linux/slab.h>
3595ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn
3695ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn#include "rt2x00.h"
3795ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn#include "rt2x00pci.h"
3895ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn#include "rt2500pci.h"
3995ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn
4095ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn/*
4195ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn * Register access.
4295ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn * All access to the CSR registers will go through the methods
4395ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn * rt2x00pci_register_read and rt2x00pci_register_write.
4495ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn * BBP and RF register require indirect register access,
4595ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn * and use the CSR registers BBPCSR and RFCSR to achieve this.
4695ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn * These indirect registers work with busy bits,
4795ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn * and we will try maximal REGISTER_BUSY_COUNT times to access
4895ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn * the register while taking a REGISTER_BUSY_DELAY us delay
4995ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn * between each attampt. When the busy bit is still set at that time,
5095ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn * the access attempt is considered to have failed,
5195ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn * and we will print an error.
5295ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn */
53c9c3b1a5deac4297503145840fffcd122b253db5Ivo van Doorn#define WAIT_FOR_BBP(__dev, __reg) \
54c9c3b1a5deac4297503145840fffcd122b253db5Ivo van Doorn	rt2x00pci_regbusy_read((__dev), BBPCSR, BBPCSR_BUSY, (__reg))
55c9c3b1a5deac4297503145840fffcd122b253db5Ivo van Doorn#define WAIT_FOR_RF(__dev, __reg) \
56c9c3b1a5deac4297503145840fffcd122b253db5Ivo van Doorn	rt2x00pci_regbusy_read((__dev), RFCSR, RFCSR_BUSY, (__reg))
5795ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn
580e14f6d3e088473b411d35ff63737e46efb9e6dfAdam Bakerstatic void rt2500pci_bbp_write(struct rt2x00_dev *rt2x00dev,
5995ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn				const unsigned int word, const u8 value)
6095ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn{
6195ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	u32 reg;
6295ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn
638ff48a8bbe4a1ba29dea2836dfce74660f97c1beIvo van Doorn	mutex_lock(&rt2x00dev->csr_mutex);
648ff48a8bbe4a1ba29dea2836dfce74660f97c1beIvo van Doorn
6595ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	/*
66c9c3b1a5deac4297503145840fffcd122b253db5Ivo van Doorn	 * Wait until the BBP becomes available, afterwards we
67c9c3b1a5deac4297503145840fffcd122b253db5Ivo van Doorn	 * can safely write the new data into the register.
6895ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	 */
69c9c3b1a5deac4297503145840fffcd122b253db5Ivo van Doorn	if (WAIT_FOR_BBP(rt2x00dev, &reg)) {
70c9c3b1a5deac4297503145840fffcd122b253db5Ivo van Doorn		reg = 0;
71c9c3b1a5deac4297503145840fffcd122b253db5Ivo van Doorn		rt2x00_set_field32(&reg, BBPCSR_VALUE, value);
72c9c3b1a5deac4297503145840fffcd122b253db5Ivo van Doorn		rt2x00_set_field32(&reg, BBPCSR_REGNUM, word);
73c9c3b1a5deac4297503145840fffcd122b253db5Ivo van Doorn		rt2x00_set_field32(&reg, BBPCSR_BUSY, 1);
74c9c3b1a5deac4297503145840fffcd122b253db5Ivo van Doorn		rt2x00_set_field32(&reg, BBPCSR_WRITE_CONTROL, 1);
75c9c3b1a5deac4297503145840fffcd122b253db5Ivo van Doorn
76c9c3b1a5deac4297503145840fffcd122b253db5Ivo van Doorn		rt2x00pci_register_write(rt2x00dev, BBPCSR, reg);
77c9c3b1a5deac4297503145840fffcd122b253db5Ivo van Doorn	}
788ff48a8bbe4a1ba29dea2836dfce74660f97c1beIvo van Doorn
798ff48a8bbe4a1ba29dea2836dfce74660f97c1beIvo van Doorn	mutex_unlock(&rt2x00dev->csr_mutex);
8095ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn}
8195ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn
820e14f6d3e088473b411d35ff63737e46efb9e6dfAdam Bakerstatic void rt2500pci_bbp_read(struct rt2x00_dev *rt2x00dev,
8395ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn			       const unsigned int word, u8 *value)
8495ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn{
8595ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	u32 reg;
8695ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn
878ff48a8bbe4a1ba29dea2836dfce74660f97c1beIvo van Doorn	mutex_lock(&rt2x00dev->csr_mutex);
888ff48a8bbe4a1ba29dea2836dfce74660f97c1beIvo van Doorn
8995ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	/*
90c9c3b1a5deac4297503145840fffcd122b253db5Ivo van Doorn	 * Wait until the BBP becomes available, afterwards we
91c9c3b1a5deac4297503145840fffcd122b253db5Ivo van Doorn	 * can safely write the read request into the register.
92c9c3b1a5deac4297503145840fffcd122b253db5Ivo van Doorn	 * After the data has been written, we wait until hardware
93c9c3b1a5deac4297503145840fffcd122b253db5Ivo van Doorn	 * returns the correct value, if at any time the register
94c9c3b1a5deac4297503145840fffcd122b253db5Ivo van Doorn	 * doesn't become available in time, reg will be 0xffffffff
95c9c3b1a5deac4297503145840fffcd122b253db5Ivo van Doorn	 * which means we return 0xff to the caller.
9695ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	 */
97c9c3b1a5deac4297503145840fffcd122b253db5Ivo van Doorn	if (WAIT_FOR_BBP(rt2x00dev, &reg)) {
98c9c3b1a5deac4297503145840fffcd122b253db5Ivo van Doorn		reg = 0;
99c9c3b1a5deac4297503145840fffcd122b253db5Ivo van Doorn		rt2x00_set_field32(&reg, BBPCSR_REGNUM, word);
100c9c3b1a5deac4297503145840fffcd122b253db5Ivo van Doorn		rt2x00_set_field32(&reg, BBPCSR_BUSY, 1);
101c9c3b1a5deac4297503145840fffcd122b253db5Ivo van Doorn		rt2x00_set_field32(&reg, BBPCSR_WRITE_CONTROL, 0);
10295ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn
103c9c3b1a5deac4297503145840fffcd122b253db5Ivo van Doorn		rt2x00pci_register_write(rt2x00dev, BBPCSR, reg);
10495ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn
105c9c3b1a5deac4297503145840fffcd122b253db5Ivo van Doorn		WAIT_FOR_BBP(rt2x00dev, &reg);
106c9c3b1a5deac4297503145840fffcd122b253db5Ivo van Doorn	}
10795ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn
10895ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	*value = rt2x00_get_field32(reg, BBPCSR_VALUE);
1098ff48a8bbe4a1ba29dea2836dfce74660f97c1beIvo van Doorn
1108ff48a8bbe4a1ba29dea2836dfce74660f97c1beIvo van Doorn	mutex_unlock(&rt2x00dev->csr_mutex);
11195ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn}
11295ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn
1130e14f6d3e088473b411d35ff63737e46efb9e6dfAdam Bakerstatic void rt2500pci_rf_write(struct rt2x00_dev *rt2x00dev,
11495ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn			       const unsigned int word, const u32 value)
11595ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn{
11695ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	u32 reg;
11795ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn
1188ff48a8bbe4a1ba29dea2836dfce74660f97c1beIvo van Doorn	mutex_lock(&rt2x00dev->csr_mutex);
1198ff48a8bbe4a1ba29dea2836dfce74660f97c1beIvo van Doorn
120c9c3b1a5deac4297503145840fffcd122b253db5Ivo van Doorn	/*
121c9c3b1a5deac4297503145840fffcd122b253db5Ivo van Doorn	 * Wait until the RF becomes available, afterwards we
122c9c3b1a5deac4297503145840fffcd122b253db5Ivo van Doorn	 * can safely write the new data into the register.
123c9c3b1a5deac4297503145840fffcd122b253db5Ivo van Doorn	 */
124c9c3b1a5deac4297503145840fffcd122b253db5Ivo van Doorn	if (WAIT_FOR_RF(rt2x00dev, &reg)) {
125c9c3b1a5deac4297503145840fffcd122b253db5Ivo van Doorn		reg = 0;
126c9c3b1a5deac4297503145840fffcd122b253db5Ivo van Doorn		rt2x00_set_field32(&reg, RFCSR_VALUE, value);
127c9c3b1a5deac4297503145840fffcd122b253db5Ivo van Doorn		rt2x00_set_field32(&reg, RFCSR_NUMBER_OF_BITS, 20);
128c9c3b1a5deac4297503145840fffcd122b253db5Ivo van Doorn		rt2x00_set_field32(&reg, RFCSR_IF_SELECT, 0);
129c9c3b1a5deac4297503145840fffcd122b253db5Ivo van Doorn		rt2x00_set_field32(&reg, RFCSR_BUSY, 1);
130c9c3b1a5deac4297503145840fffcd122b253db5Ivo van Doorn
131c9c3b1a5deac4297503145840fffcd122b253db5Ivo van Doorn		rt2x00pci_register_write(rt2x00dev, RFCSR, reg);
132c9c3b1a5deac4297503145840fffcd122b253db5Ivo van Doorn		rt2x00_rf_write(rt2x00dev, word, value);
13395ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	}
13495ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn
1358ff48a8bbe4a1ba29dea2836dfce74660f97c1beIvo van Doorn	mutex_unlock(&rt2x00dev->csr_mutex);
13695ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn}
13795ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn
13895ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doornstatic void rt2500pci_eepromregister_read(struct eeprom_93cx6 *eeprom)
13995ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn{
14095ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	struct rt2x00_dev *rt2x00dev = eeprom->data;
14195ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	u32 reg;
14295ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn
14395ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	rt2x00pci_register_read(rt2x00dev, CSR21, &reg);
14495ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn
14595ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	eeprom->reg_data_in = !!rt2x00_get_field32(reg, CSR21_EEPROM_DATA_IN);
14695ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	eeprom->reg_data_out = !!rt2x00_get_field32(reg, CSR21_EEPROM_DATA_OUT);
14795ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	eeprom->reg_data_clock =
14895ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	    !!rt2x00_get_field32(reg, CSR21_EEPROM_DATA_CLOCK);
14995ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	eeprom->reg_chip_select =
15095ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	    !!rt2x00_get_field32(reg, CSR21_EEPROM_CHIP_SELECT);
15195ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn}
15295ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn
15395ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doornstatic void rt2500pci_eepromregister_write(struct eeprom_93cx6 *eeprom)
15495ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn{
15595ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	struct rt2x00_dev *rt2x00dev = eeprom->data;
15695ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	u32 reg = 0;
15795ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn
15895ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	rt2x00_set_field32(&reg, CSR21_EEPROM_DATA_IN, !!eeprom->reg_data_in);
15995ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	rt2x00_set_field32(&reg, CSR21_EEPROM_DATA_OUT, !!eeprom->reg_data_out);
16095ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	rt2x00_set_field32(&reg, CSR21_EEPROM_DATA_CLOCK,
16195ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn			   !!eeprom->reg_data_clock);
16295ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	rt2x00_set_field32(&reg, CSR21_EEPROM_CHIP_SELECT,
16395ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn			   !!eeprom->reg_chip_select);
16495ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn
16595ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	rt2x00pci_register_write(rt2x00dev, CSR21, reg);
16695ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn}
16795ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn
16895ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn#ifdef CONFIG_RT2X00_LIB_DEBUGFS
16995ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doornstatic const struct rt2x00debug rt2500pci_rt2x00debug = {
17095ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	.owner	= THIS_MODULE,
17195ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	.csr	= {
172743b97caf98036ec8ee4bfc6fc6f85ad94e04783Ivo van Doorn		.read		= rt2x00pci_register_read,
173743b97caf98036ec8ee4bfc6fc6f85ad94e04783Ivo van Doorn		.write		= rt2x00pci_register_write,
174743b97caf98036ec8ee4bfc6fc6f85ad94e04783Ivo van Doorn		.flags		= RT2X00DEBUGFS_OFFSET,
175743b97caf98036ec8ee4bfc6fc6f85ad94e04783Ivo van Doorn		.word_base	= CSR_REG_BASE,
17695ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn		.word_size	= sizeof(u32),
17795ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn		.word_count	= CSR_REG_SIZE / sizeof(u32),
17895ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	},
17995ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	.eeprom	= {
18095ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn		.read		= rt2x00_eeprom_read,
18195ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn		.write		= rt2x00_eeprom_write,
182743b97caf98036ec8ee4bfc6fc6f85ad94e04783Ivo van Doorn		.word_base	= EEPROM_BASE,
18395ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn		.word_size	= sizeof(u16),
18495ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn		.word_count	= EEPROM_SIZE / sizeof(u16),
18595ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	},
18695ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	.bbp	= {
18795ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn		.read		= rt2500pci_bbp_read,
18895ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn		.write		= rt2500pci_bbp_write,
189743b97caf98036ec8ee4bfc6fc6f85ad94e04783Ivo van Doorn		.word_base	= BBP_BASE,
19095ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn		.word_size	= sizeof(u8),
19195ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn		.word_count	= BBP_SIZE / sizeof(u8),
19295ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	},
19395ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	.rf	= {
19495ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn		.read		= rt2x00_rf_read,
19595ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn		.write		= rt2500pci_rf_write,
196743b97caf98036ec8ee4bfc6fc6f85ad94e04783Ivo van Doorn		.word_base	= RF_BASE,
19795ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn		.word_size	= sizeof(u32),
19895ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn		.word_count	= RF_SIZE / sizeof(u32),
19995ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	},
20095ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn};
20195ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn#endif /* CONFIG_RT2X00_LIB_DEBUGFS */
20295ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn
20395ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doornstatic int rt2500pci_rfkill_poll(struct rt2x00_dev *rt2x00dev)
20495ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn{
20595ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	u32 reg;
20695ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn
20795ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	rt2x00pci_register_read(rt2x00dev, GPIOCSR, &reg);
20895ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	return rt2x00_get_field32(reg, GPIOCSR_BIT0);
20995ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn}
21095ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn
211771fd565195727d12f0b75d918b9fcb9f33a5476Ivo van Doorn#ifdef CONFIG_RT2X00_LIB_LEDS
212a2e1d52a32eab53f8ab03c4023310f65aaa054a7Ivo van Doornstatic void rt2500pci_brightness_set(struct led_classdev *led_cdev,
213a9450b70a755abf093600035ef5361c53343fe9aIvo van Doorn				     enum led_brightness brightness)
214a9450b70a755abf093600035ef5361c53343fe9aIvo van Doorn{
215a9450b70a755abf093600035ef5361c53343fe9aIvo van Doorn	struct rt2x00_led *led =
216a9450b70a755abf093600035ef5361c53343fe9aIvo van Doorn	    container_of(led_cdev, struct rt2x00_led, led_dev);
217a9450b70a755abf093600035ef5361c53343fe9aIvo van Doorn	unsigned int enabled = brightness != LED_OFF;
218a9450b70a755abf093600035ef5361c53343fe9aIvo van Doorn	u32 reg;
219a9450b70a755abf093600035ef5361c53343fe9aIvo van Doorn
220a9450b70a755abf093600035ef5361c53343fe9aIvo van Doorn	rt2x00pci_register_read(led->rt2x00dev, LEDCSR, &reg);
221a9450b70a755abf093600035ef5361c53343fe9aIvo van Doorn
222a2e1d52a32eab53f8ab03c4023310f65aaa054a7Ivo van Doorn	if (led->type == LED_TYPE_RADIO || led->type == LED_TYPE_ASSOC)
223a9450b70a755abf093600035ef5361c53343fe9aIvo van Doorn		rt2x00_set_field32(&reg, LEDCSR_LINK, enabled);
224a2e1d52a32eab53f8ab03c4023310f65aaa054a7Ivo van Doorn	else if (led->type == LED_TYPE_ACTIVITY)
225a2e1d52a32eab53f8ab03c4023310f65aaa054a7Ivo van Doorn		rt2x00_set_field32(&reg, LEDCSR_ACTIVITY, enabled);
226a9450b70a755abf093600035ef5361c53343fe9aIvo van Doorn
227a9450b70a755abf093600035ef5361c53343fe9aIvo van Doorn	rt2x00pci_register_write(led->rt2x00dev, LEDCSR, reg);
228a9450b70a755abf093600035ef5361c53343fe9aIvo van Doorn}
229a2e1d52a32eab53f8ab03c4023310f65aaa054a7Ivo van Doorn
230a2e1d52a32eab53f8ab03c4023310f65aaa054a7Ivo van Doornstatic int rt2500pci_blink_set(struct led_classdev *led_cdev,
231a2e1d52a32eab53f8ab03c4023310f65aaa054a7Ivo van Doorn			       unsigned long *delay_on,
232a2e1d52a32eab53f8ab03c4023310f65aaa054a7Ivo van Doorn			       unsigned long *delay_off)
233a2e1d52a32eab53f8ab03c4023310f65aaa054a7Ivo van Doorn{
234a2e1d52a32eab53f8ab03c4023310f65aaa054a7Ivo van Doorn	struct rt2x00_led *led =
235a2e1d52a32eab53f8ab03c4023310f65aaa054a7Ivo van Doorn	    container_of(led_cdev, struct rt2x00_led, led_dev);
236a2e1d52a32eab53f8ab03c4023310f65aaa054a7Ivo van Doorn	u32 reg;
237a2e1d52a32eab53f8ab03c4023310f65aaa054a7Ivo van Doorn
238a2e1d52a32eab53f8ab03c4023310f65aaa054a7Ivo van Doorn	rt2x00pci_register_read(led->rt2x00dev, LEDCSR, &reg);
239a2e1d52a32eab53f8ab03c4023310f65aaa054a7Ivo van Doorn	rt2x00_set_field32(&reg, LEDCSR_ON_PERIOD, *delay_on);
240a2e1d52a32eab53f8ab03c4023310f65aaa054a7Ivo van Doorn	rt2x00_set_field32(&reg, LEDCSR_OFF_PERIOD, *delay_off);
241a2e1d52a32eab53f8ab03c4023310f65aaa054a7Ivo van Doorn	rt2x00pci_register_write(led->rt2x00dev, LEDCSR, reg);
242a2e1d52a32eab53f8ab03c4023310f65aaa054a7Ivo van Doorn
243a2e1d52a32eab53f8ab03c4023310f65aaa054a7Ivo van Doorn	return 0;
244a2e1d52a32eab53f8ab03c4023310f65aaa054a7Ivo van Doorn}
245475433be3d8f4d840e2930eef96671b7f8d11053Ivo van Doorn
246475433be3d8f4d840e2930eef96671b7f8d11053Ivo van Doornstatic void rt2500pci_init_led(struct rt2x00_dev *rt2x00dev,
247475433be3d8f4d840e2930eef96671b7f8d11053Ivo van Doorn			       struct rt2x00_led *led,
248475433be3d8f4d840e2930eef96671b7f8d11053Ivo van Doorn			       enum led_type type)
249475433be3d8f4d840e2930eef96671b7f8d11053Ivo van Doorn{
250475433be3d8f4d840e2930eef96671b7f8d11053Ivo van Doorn	led->rt2x00dev = rt2x00dev;
251475433be3d8f4d840e2930eef96671b7f8d11053Ivo van Doorn	led->type = type;
252475433be3d8f4d840e2930eef96671b7f8d11053Ivo van Doorn	led->led_dev.brightness_set = rt2500pci_brightness_set;
253475433be3d8f4d840e2930eef96671b7f8d11053Ivo van Doorn	led->led_dev.blink_set = rt2500pci_blink_set;
254475433be3d8f4d840e2930eef96671b7f8d11053Ivo van Doorn	led->flags = LED_INITIALIZED;
255475433be3d8f4d840e2930eef96671b7f8d11053Ivo van Doorn}
256771fd565195727d12f0b75d918b9fcb9f33a5476Ivo van Doorn#endif /* CONFIG_RT2X00_LIB_LEDS */
257a9450b70a755abf093600035ef5361c53343fe9aIvo van Doorn
25895ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn/*
25995ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn * Configuration handlers.
26095ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn */
2613a643d244f09fa1fdd25d48a56a073c1a69583eeIvo van Doornstatic void rt2500pci_config_filter(struct rt2x00_dev *rt2x00dev,
2623a643d244f09fa1fdd25d48a56a073c1a69583eeIvo van Doorn				    const unsigned int filter_flags)
2633a643d244f09fa1fdd25d48a56a073c1a69583eeIvo van Doorn{
2643a643d244f09fa1fdd25d48a56a073c1a69583eeIvo van Doorn	u32 reg;
2653a643d244f09fa1fdd25d48a56a073c1a69583eeIvo van Doorn
2663a643d244f09fa1fdd25d48a56a073c1a69583eeIvo van Doorn	/*
2673a643d244f09fa1fdd25d48a56a073c1a69583eeIvo van Doorn	 * Start configuration steps.
2683a643d244f09fa1fdd25d48a56a073c1a69583eeIvo van Doorn	 * Note that the version error will always be dropped
2693a643d244f09fa1fdd25d48a56a073c1a69583eeIvo van Doorn	 * and broadcast frames will always be accepted since
2703a643d244f09fa1fdd25d48a56a073c1a69583eeIvo van Doorn	 * there is no filter for it at this time.
2713a643d244f09fa1fdd25d48a56a073c1a69583eeIvo van Doorn	 */
2723a643d244f09fa1fdd25d48a56a073c1a69583eeIvo van Doorn	rt2x00pci_register_read(rt2x00dev, RXCSR0, &reg);
2733a643d244f09fa1fdd25d48a56a073c1a69583eeIvo van Doorn	rt2x00_set_field32(&reg, RXCSR0_DROP_CRC,
2743a643d244f09fa1fdd25d48a56a073c1a69583eeIvo van Doorn			   !(filter_flags & FIF_FCSFAIL));
2753a643d244f09fa1fdd25d48a56a073c1a69583eeIvo van Doorn	rt2x00_set_field32(&reg, RXCSR0_DROP_PHYSICAL,
2763a643d244f09fa1fdd25d48a56a073c1a69583eeIvo van Doorn			   !(filter_flags & FIF_PLCPFAIL));
2773a643d244f09fa1fdd25d48a56a073c1a69583eeIvo van Doorn	rt2x00_set_field32(&reg, RXCSR0_DROP_CONTROL,
2783a643d244f09fa1fdd25d48a56a073c1a69583eeIvo van Doorn			   !(filter_flags & FIF_CONTROL));
2793a643d244f09fa1fdd25d48a56a073c1a69583eeIvo van Doorn	rt2x00_set_field32(&reg, RXCSR0_DROP_NOT_TO_ME,
2803a643d244f09fa1fdd25d48a56a073c1a69583eeIvo van Doorn			   !(filter_flags & FIF_PROMISC_IN_BSS));
2813a643d244f09fa1fdd25d48a56a073c1a69583eeIvo van Doorn	rt2x00_set_field32(&reg, RXCSR0_DROP_TODS,
282e0b005fa1479045fe879944036268af3ebcd1835Ivo van Doorn			   !(filter_flags & FIF_PROMISC_IN_BSS) &&
283e0b005fa1479045fe879944036268af3ebcd1835Ivo van Doorn			   !rt2x00dev->intf_ap_count);
2843a643d244f09fa1fdd25d48a56a073c1a69583eeIvo van Doorn	rt2x00_set_field32(&reg, RXCSR0_DROP_VERSION_ERROR, 1);
2853a643d244f09fa1fdd25d48a56a073c1a69583eeIvo van Doorn	rt2x00_set_field32(&reg, RXCSR0_DROP_MCAST,
2863a643d244f09fa1fdd25d48a56a073c1a69583eeIvo van Doorn			   !(filter_flags & FIF_ALLMULTI));
2873a643d244f09fa1fdd25d48a56a073c1a69583eeIvo van Doorn	rt2x00_set_field32(&reg, RXCSR0_DROP_BCAST, 0);
2883a643d244f09fa1fdd25d48a56a073c1a69583eeIvo van Doorn	rt2x00pci_register_write(rt2x00dev, RXCSR0, reg);
2893a643d244f09fa1fdd25d48a56a073c1a69583eeIvo van Doorn}
2903a643d244f09fa1fdd25d48a56a073c1a69583eeIvo van Doorn
2916bb40dd13b458beb55f5c60dba1cb28e814bd640Ivo van Doornstatic void rt2500pci_config_intf(struct rt2x00_dev *rt2x00dev,
2926bb40dd13b458beb55f5c60dba1cb28e814bd640Ivo van Doorn				  struct rt2x00_intf *intf,
2936bb40dd13b458beb55f5c60dba1cb28e814bd640Ivo van Doorn				  struct rt2x00intf_conf *conf,
2946bb40dd13b458beb55f5c60dba1cb28e814bd640Ivo van Doorn				  const unsigned int flags)
29595ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn{
296a24408307e930e21912e82c125648400041d66fbGertjan van Wingerde	struct data_queue *queue = rt2x00dev->bcn;
2976bb40dd13b458beb55f5c60dba1cb28e814bd640Ivo van Doorn	unsigned int bcn_preload;
29895ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	u32 reg;
29995ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn
3006bb40dd13b458beb55f5c60dba1cb28e814bd640Ivo van Doorn	if (flags & CONFIG_UPDATE_TYPE) {
3016bb40dd13b458beb55f5c60dba1cb28e814bd640Ivo van Doorn		/*
3026bb40dd13b458beb55f5c60dba1cb28e814bd640Ivo van Doorn		 * Enable beacon config
3036bb40dd13b458beb55f5c60dba1cb28e814bd640Ivo van Doorn		 */
304bad13639a30e1557fbe9d440adc1906673c9de4eIvo van Doorn		bcn_preload = PREAMBLE + GET_DURATION(IEEE80211_HEADER, 20);
3056bb40dd13b458beb55f5c60dba1cb28e814bd640Ivo van Doorn		rt2x00pci_register_read(rt2x00dev, BCNCSR1, &reg);
3066bb40dd13b458beb55f5c60dba1cb28e814bd640Ivo van Doorn		rt2x00_set_field32(&reg, BCNCSR1_PRELOAD, bcn_preload);
3076bb40dd13b458beb55f5c60dba1cb28e814bd640Ivo van Doorn		rt2x00_set_field32(&reg, BCNCSR1_BEACON_CWMIN, queue->cw_min);
3086bb40dd13b458beb55f5c60dba1cb28e814bd640Ivo van Doorn		rt2x00pci_register_write(rt2x00dev, BCNCSR1, reg);
30995ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn
3106bb40dd13b458beb55f5c60dba1cb28e814bd640Ivo van Doorn		/*
3116bb40dd13b458beb55f5c60dba1cb28e814bd640Ivo van Doorn		 * Enable synchronisation.
3126bb40dd13b458beb55f5c60dba1cb28e814bd640Ivo van Doorn		 */
3136bb40dd13b458beb55f5c60dba1cb28e814bd640Ivo van Doorn		rt2x00pci_register_read(rt2x00dev, CSR14, &reg);
3146bb40dd13b458beb55f5c60dba1cb28e814bd640Ivo van Doorn		rt2x00_set_field32(&reg, CSR14_TSF_SYNC, conf->sync);
3156bb40dd13b458beb55f5c60dba1cb28e814bd640Ivo van Doorn		rt2x00pci_register_write(rt2x00dev, CSR14, reg);
3166bb40dd13b458beb55f5c60dba1cb28e814bd640Ivo van Doorn	}
3176bb40dd13b458beb55f5c60dba1cb28e814bd640Ivo van Doorn
3186bb40dd13b458beb55f5c60dba1cb28e814bd640Ivo van Doorn	if (flags & CONFIG_UPDATE_MAC)
3196bb40dd13b458beb55f5c60dba1cb28e814bd640Ivo van Doorn		rt2x00pci_register_multiwrite(rt2x00dev, CSR3,
3206bb40dd13b458beb55f5c60dba1cb28e814bd640Ivo van Doorn					      conf->mac, sizeof(conf->mac));
3216bb40dd13b458beb55f5c60dba1cb28e814bd640Ivo van Doorn
3226bb40dd13b458beb55f5c60dba1cb28e814bd640Ivo van Doorn	if (flags & CONFIG_UPDATE_BSSID)
3236bb40dd13b458beb55f5c60dba1cb28e814bd640Ivo van Doorn		rt2x00pci_register_multiwrite(rt2x00dev, CSR5,
3246bb40dd13b458beb55f5c60dba1cb28e814bd640Ivo van Doorn					      conf->bssid, sizeof(conf->bssid));
32595ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn}
32695ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn
3273a643d244f09fa1fdd25d48a56a073c1a69583eeIvo van Doornstatic void rt2500pci_config_erp(struct rt2x00_dev *rt2x00dev,
3280204464329c17ba6d293e1899f71223599a0e582Helmut Schaa				 struct rt2x00lib_erp *erp,
3290204464329c17ba6d293e1899f71223599a0e582Helmut Schaa				 u32 changed)
33095ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn{
3315c58ee51ff8c0aca74c225e0263bc5dd2b917781Ivo van Doorn	int preamble_mask;
33295ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	u32 reg;
33395ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn
3345c58ee51ff8c0aca74c225e0263bc5dd2b917781Ivo van Doorn	/*
3355c58ee51ff8c0aca74c225e0263bc5dd2b917781Ivo van Doorn	 * When short preamble is enabled, we should set bit 0x08
3365c58ee51ff8c0aca74c225e0263bc5dd2b917781Ivo van Doorn	 */
3370204464329c17ba6d293e1899f71223599a0e582Helmut Schaa	if (changed & BSS_CHANGED_ERP_PREAMBLE) {
3380204464329c17ba6d293e1899f71223599a0e582Helmut Schaa		preamble_mask = erp->short_preamble << 3;
3390204464329c17ba6d293e1899f71223599a0e582Helmut Schaa
3400204464329c17ba6d293e1899f71223599a0e582Helmut Schaa		rt2x00pci_register_read(rt2x00dev, TXCSR1, &reg);
3410204464329c17ba6d293e1899f71223599a0e582Helmut Schaa		rt2x00_set_field32(&reg, TXCSR1_ACK_TIMEOUT, 0x162);
3420204464329c17ba6d293e1899f71223599a0e582Helmut Schaa		rt2x00_set_field32(&reg, TXCSR1_ACK_CONSUME_TIME, 0xa2);
3430204464329c17ba6d293e1899f71223599a0e582Helmut Schaa		rt2x00_set_field32(&reg, TXCSR1_TSF_OFFSET, IEEE80211_HEADER);
3440204464329c17ba6d293e1899f71223599a0e582Helmut Schaa		rt2x00_set_field32(&reg, TXCSR1_AUTORESPONDER, 1);
3450204464329c17ba6d293e1899f71223599a0e582Helmut Schaa		rt2x00pci_register_write(rt2x00dev, TXCSR1, reg);
3460204464329c17ba6d293e1899f71223599a0e582Helmut Schaa
3470204464329c17ba6d293e1899f71223599a0e582Helmut Schaa		rt2x00pci_register_read(rt2x00dev, ARCSR2, &reg);
3480204464329c17ba6d293e1899f71223599a0e582Helmut Schaa		rt2x00_set_field32(&reg, ARCSR2_SIGNAL, 0x00);
3490204464329c17ba6d293e1899f71223599a0e582Helmut Schaa		rt2x00_set_field32(&reg, ARCSR2_SERVICE, 0x04);
3500204464329c17ba6d293e1899f71223599a0e582Helmut Schaa		rt2x00_set_field32(&reg, ARCSR2_LENGTH,
3510204464329c17ba6d293e1899f71223599a0e582Helmut Schaa				   GET_DURATION(ACK_SIZE, 10));
3520204464329c17ba6d293e1899f71223599a0e582Helmut Schaa		rt2x00pci_register_write(rt2x00dev, ARCSR2, reg);
3530204464329c17ba6d293e1899f71223599a0e582Helmut Schaa
3540204464329c17ba6d293e1899f71223599a0e582Helmut Schaa		rt2x00pci_register_read(rt2x00dev, ARCSR3, &reg);
3550204464329c17ba6d293e1899f71223599a0e582Helmut Schaa		rt2x00_set_field32(&reg, ARCSR3_SIGNAL, 0x01 | preamble_mask);
3560204464329c17ba6d293e1899f71223599a0e582Helmut Schaa		rt2x00_set_field32(&reg, ARCSR3_SERVICE, 0x04);
3570204464329c17ba6d293e1899f71223599a0e582Helmut Schaa		rt2x00_set_field32(&reg, ARCSR2_LENGTH,
3580204464329c17ba6d293e1899f71223599a0e582Helmut Schaa				   GET_DURATION(ACK_SIZE, 20));
3590204464329c17ba6d293e1899f71223599a0e582Helmut Schaa		rt2x00pci_register_write(rt2x00dev, ARCSR3, reg);
3600204464329c17ba6d293e1899f71223599a0e582Helmut Schaa
3610204464329c17ba6d293e1899f71223599a0e582Helmut Schaa		rt2x00pci_register_read(rt2x00dev, ARCSR4, &reg);
3620204464329c17ba6d293e1899f71223599a0e582Helmut Schaa		rt2x00_set_field32(&reg, ARCSR4_SIGNAL, 0x02 | preamble_mask);
3630204464329c17ba6d293e1899f71223599a0e582Helmut Schaa		rt2x00_set_field32(&reg, ARCSR4_SERVICE, 0x04);
3640204464329c17ba6d293e1899f71223599a0e582Helmut Schaa		rt2x00_set_field32(&reg, ARCSR2_LENGTH,
3650204464329c17ba6d293e1899f71223599a0e582Helmut Schaa				   GET_DURATION(ACK_SIZE, 55));
3660204464329c17ba6d293e1899f71223599a0e582Helmut Schaa		rt2x00pci_register_write(rt2x00dev, ARCSR4, reg);
3670204464329c17ba6d293e1899f71223599a0e582Helmut Schaa
3680204464329c17ba6d293e1899f71223599a0e582Helmut Schaa		rt2x00pci_register_read(rt2x00dev, ARCSR5, &reg);
3690204464329c17ba6d293e1899f71223599a0e582Helmut Schaa		rt2x00_set_field32(&reg, ARCSR5_SIGNAL, 0x03 | preamble_mask);
3700204464329c17ba6d293e1899f71223599a0e582Helmut Schaa		rt2x00_set_field32(&reg, ARCSR5_SERVICE, 0x84);
3710204464329c17ba6d293e1899f71223599a0e582Helmut Schaa		rt2x00_set_field32(&reg, ARCSR2_LENGTH,
3720204464329c17ba6d293e1899f71223599a0e582Helmut Schaa				   GET_DURATION(ACK_SIZE, 110));
3730204464329c17ba6d293e1899f71223599a0e582Helmut Schaa		rt2x00pci_register_write(rt2x00dev, ARCSR5, reg);
3740204464329c17ba6d293e1899f71223599a0e582Helmut Schaa	}
3750204464329c17ba6d293e1899f71223599a0e582Helmut Schaa
3760204464329c17ba6d293e1899f71223599a0e582Helmut Schaa	if (changed & BSS_CHANGED_BASIC_RATES)
3770204464329c17ba6d293e1899f71223599a0e582Helmut Schaa		rt2x00pci_register_write(rt2x00dev, ARCSR1, erp->basic_rates);
3780204464329c17ba6d293e1899f71223599a0e582Helmut Schaa
3790204464329c17ba6d293e1899f71223599a0e582Helmut Schaa	if (changed & BSS_CHANGED_ERP_SLOT) {
3800204464329c17ba6d293e1899f71223599a0e582Helmut Schaa		rt2x00pci_register_read(rt2x00dev, CSR11, &reg);
3810204464329c17ba6d293e1899f71223599a0e582Helmut Schaa		rt2x00_set_field32(&reg, CSR11_SLOT_TIME, erp->slot_time);
3820204464329c17ba6d293e1899f71223599a0e582Helmut Schaa		rt2x00pci_register_write(rt2x00dev, CSR11, reg);
3830204464329c17ba6d293e1899f71223599a0e582Helmut Schaa
3840204464329c17ba6d293e1899f71223599a0e582Helmut Schaa		rt2x00pci_register_read(rt2x00dev, CSR18, &reg);
3850204464329c17ba6d293e1899f71223599a0e582Helmut Schaa		rt2x00_set_field32(&reg, CSR18_SIFS, erp->sifs);
3860204464329c17ba6d293e1899f71223599a0e582Helmut Schaa		rt2x00_set_field32(&reg, CSR18_PIFS, erp->pifs);
3870204464329c17ba6d293e1899f71223599a0e582Helmut Schaa		rt2x00pci_register_write(rt2x00dev, CSR18, reg);
3880204464329c17ba6d293e1899f71223599a0e582Helmut Schaa
3890204464329c17ba6d293e1899f71223599a0e582Helmut Schaa		rt2x00pci_register_read(rt2x00dev, CSR19, &reg);
3900204464329c17ba6d293e1899f71223599a0e582Helmut Schaa		rt2x00_set_field32(&reg, CSR19_DIFS, erp->difs);
3910204464329c17ba6d293e1899f71223599a0e582Helmut Schaa		rt2x00_set_field32(&reg, CSR19_EIFS, erp->eifs);
3920204464329c17ba6d293e1899f71223599a0e582Helmut Schaa		rt2x00pci_register_write(rt2x00dev, CSR19, reg);
3930204464329c17ba6d293e1899f71223599a0e582Helmut Schaa	}
3940204464329c17ba6d293e1899f71223599a0e582Helmut Schaa
3950204464329c17ba6d293e1899f71223599a0e582Helmut Schaa	if (changed & BSS_CHANGED_BEACON_INT) {
3960204464329c17ba6d293e1899f71223599a0e582Helmut Schaa		rt2x00pci_register_read(rt2x00dev, CSR12, &reg);
3970204464329c17ba6d293e1899f71223599a0e582Helmut Schaa		rt2x00_set_field32(&reg, CSR12_BEACON_INTERVAL,
3980204464329c17ba6d293e1899f71223599a0e582Helmut Schaa				   erp->beacon_int * 16);
3990204464329c17ba6d293e1899f71223599a0e582Helmut Schaa		rt2x00_set_field32(&reg, CSR12_CFP_MAX_DURATION,
4000204464329c17ba6d293e1899f71223599a0e582Helmut Schaa				   erp->beacon_int * 16);
4010204464329c17ba6d293e1899f71223599a0e582Helmut Schaa		rt2x00pci_register_write(rt2x00dev, CSR12, reg);
4020204464329c17ba6d293e1899f71223599a0e582Helmut Schaa	}
4030204464329c17ba6d293e1899f71223599a0e582Helmut Schaa
40495ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn}
40595ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn
406e4ea1c403acece78c271bf9cd6f797d1cb093df9Ivo van Doornstatic void rt2500pci_config_ant(struct rt2x00_dev *rt2x00dev,
407e4ea1c403acece78c271bf9cd6f797d1cb093df9Ivo van Doorn				 struct antenna_setup *ant)
40895ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn{
409e4ea1c403acece78c271bf9cd6f797d1cb093df9Ivo van Doorn	u32 reg;
410e4ea1c403acece78c271bf9cd6f797d1cb093df9Ivo van Doorn	u8 r14;
411e4ea1c403acece78c271bf9cd6f797d1cb093df9Ivo van Doorn	u8 r2;
412e4ea1c403acece78c271bf9cd6f797d1cb093df9Ivo van Doorn
413e4ea1c403acece78c271bf9cd6f797d1cb093df9Ivo van Doorn	/*
414e4ea1c403acece78c271bf9cd6f797d1cb093df9Ivo van Doorn	 * We should never come here because rt2x00lib is supposed
415e4ea1c403acece78c271bf9cd6f797d1cb093df9Ivo van Doorn	 * to catch this and send us the correct antenna explicitely.
416e4ea1c403acece78c271bf9cd6f797d1cb093df9Ivo van Doorn	 */
417e4ea1c403acece78c271bf9cd6f797d1cb093df9Ivo van Doorn	BUG_ON(ant->rx == ANTENNA_SW_DIVERSITY ||
418e4ea1c403acece78c271bf9cd6f797d1cb093df9Ivo van Doorn	       ant->tx == ANTENNA_SW_DIVERSITY);
419e4ea1c403acece78c271bf9cd6f797d1cb093df9Ivo van Doorn
420e4ea1c403acece78c271bf9cd6f797d1cb093df9Ivo van Doorn	rt2x00pci_register_read(rt2x00dev, BBPCSR1, &reg);
421e4ea1c403acece78c271bf9cd6f797d1cb093df9Ivo van Doorn	rt2500pci_bbp_read(rt2x00dev, 14, &r14);
422e4ea1c403acece78c271bf9cd6f797d1cb093df9Ivo van Doorn	rt2500pci_bbp_read(rt2x00dev, 2, &r2);
423e4ea1c403acece78c271bf9cd6f797d1cb093df9Ivo van Doorn
424e4ea1c403acece78c271bf9cd6f797d1cb093df9Ivo van Doorn	/*
425e4ea1c403acece78c271bf9cd6f797d1cb093df9Ivo van Doorn	 * Configure the TX antenna.
426e4ea1c403acece78c271bf9cd6f797d1cb093df9Ivo van Doorn	 */
427e4ea1c403acece78c271bf9cd6f797d1cb093df9Ivo van Doorn	switch (ant->tx) {
428e4ea1c403acece78c271bf9cd6f797d1cb093df9Ivo van Doorn	case ANTENNA_A:
429e4ea1c403acece78c271bf9cd6f797d1cb093df9Ivo van Doorn		rt2x00_set_field8(&r2, BBP_R2_TX_ANTENNA, 0);
430e4ea1c403acece78c271bf9cd6f797d1cb093df9Ivo van Doorn		rt2x00_set_field32(&reg, BBPCSR1_CCK, 0);
431e4ea1c403acece78c271bf9cd6f797d1cb093df9Ivo van Doorn		rt2x00_set_field32(&reg, BBPCSR1_OFDM, 0);
432e4ea1c403acece78c271bf9cd6f797d1cb093df9Ivo van Doorn		break;
433e4ea1c403acece78c271bf9cd6f797d1cb093df9Ivo van Doorn	case ANTENNA_B:
434e4ea1c403acece78c271bf9cd6f797d1cb093df9Ivo van Doorn	default:
435e4ea1c403acece78c271bf9cd6f797d1cb093df9Ivo van Doorn		rt2x00_set_field8(&r2, BBP_R2_TX_ANTENNA, 2);
436e4ea1c403acece78c271bf9cd6f797d1cb093df9Ivo van Doorn		rt2x00_set_field32(&reg, BBPCSR1_CCK, 2);
437e4ea1c403acece78c271bf9cd6f797d1cb093df9Ivo van Doorn		rt2x00_set_field32(&reg, BBPCSR1_OFDM, 2);
438e4ea1c403acece78c271bf9cd6f797d1cb093df9Ivo van Doorn		break;
439e4ea1c403acece78c271bf9cd6f797d1cb093df9Ivo van Doorn	}
440e4ea1c403acece78c271bf9cd6f797d1cb093df9Ivo van Doorn
441e4ea1c403acece78c271bf9cd6f797d1cb093df9Ivo van Doorn	/*
442e4ea1c403acece78c271bf9cd6f797d1cb093df9Ivo van Doorn	 * Configure the RX antenna.
443e4ea1c403acece78c271bf9cd6f797d1cb093df9Ivo van Doorn	 */
444e4ea1c403acece78c271bf9cd6f797d1cb093df9Ivo van Doorn	switch (ant->rx) {
445e4ea1c403acece78c271bf9cd6f797d1cb093df9Ivo van Doorn	case ANTENNA_A:
446e4ea1c403acece78c271bf9cd6f797d1cb093df9Ivo van Doorn		rt2x00_set_field8(&r14, BBP_R14_RX_ANTENNA, 0);
447e4ea1c403acece78c271bf9cd6f797d1cb093df9Ivo van Doorn		break;
448e4ea1c403acece78c271bf9cd6f797d1cb093df9Ivo van Doorn	case ANTENNA_B:
449e4ea1c403acece78c271bf9cd6f797d1cb093df9Ivo van Doorn	default:
450e4ea1c403acece78c271bf9cd6f797d1cb093df9Ivo van Doorn		rt2x00_set_field8(&r14, BBP_R14_RX_ANTENNA, 2);
451e4ea1c403acece78c271bf9cd6f797d1cb093df9Ivo van Doorn		break;
452e4ea1c403acece78c271bf9cd6f797d1cb093df9Ivo van Doorn	}
453e4ea1c403acece78c271bf9cd6f797d1cb093df9Ivo van Doorn
454e4ea1c403acece78c271bf9cd6f797d1cb093df9Ivo van Doorn	/*
455e4ea1c403acece78c271bf9cd6f797d1cb093df9Ivo van Doorn	 * RT2525E and RT5222 need to flip TX I/Q
456e4ea1c403acece78c271bf9cd6f797d1cb093df9Ivo van Doorn	 */
4575122d8986232ef2a761f5cf70c31666c4d65c3e4Gertjan van Wingerde	if (rt2x00_rf(rt2x00dev, RF2525E) || rt2x00_rf(rt2x00dev, RF5222)) {
458e4ea1c403acece78c271bf9cd6f797d1cb093df9Ivo van Doorn		rt2x00_set_field8(&r2, BBP_R2_TX_IQ_FLIP, 1);
459e4ea1c403acece78c271bf9cd6f797d1cb093df9Ivo van Doorn		rt2x00_set_field32(&reg, BBPCSR1_CCK_FLIP, 1);
460e4ea1c403acece78c271bf9cd6f797d1cb093df9Ivo van Doorn		rt2x00_set_field32(&reg, BBPCSR1_OFDM_FLIP, 1);
461e4ea1c403acece78c271bf9cd6f797d1cb093df9Ivo van Doorn
462e4ea1c403acece78c271bf9cd6f797d1cb093df9Ivo van Doorn		/*
463e4ea1c403acece78c271bf9cd6f797d1cb093df9Ivo van Doorn		 * RT2525E does not need RX I/Q Flip.
464e4ea1c403acece78c271bf9cd6f797d1cb093df9Ivo van Doorn		 */
4655122d8986232ef2a761f5cf70c31666c4d65c3e4Gertjan van Wingerde		if (rt2x00_rf(rt2x00dev, RF2525E))
466e4ea1c403acece78c271bf9cd6f797d1cb093df9Ivo van Doorn			rt2x00_set_field8(&r14, BBP_R14_RX_IQ_FLIP, 0);
467e4ea1c403acece78c271bf9cd6f797d1cb093df9Ivo van Doorn	} else {
468e4ea1c403acece78c271bf9cd6f797d1cb093df9Ivo van Doorn		rt2x00_set_field32(&reg, BBPCSR1_CCK_FLIP, 0);
469e4ea1c403acece78c271bf9cd6f797d1cb093df9Ivo van Doorn		rt2x00_set_field32(&reg, BBPCSR1_OFDM_FLIP, 0);
470e4ea1c403acece78c271bf9cd6f797d1cb093df9Ivo van Doorn	}
471e4ea1c403acece78c271bf9cd6f797d1cb093df9Ivo van Doorn
472e4ea1c403acece78c271bf9cd6f797d1cb093df9Ivo van Doorn	rt2x00pci_register_write(rt2x00dev, BBPCSR1, reg);
473e4ea1c403acece78c271bf9cd6f797d1cb093df9Ivo van Doorn	rt2500pci_bbp_write(rt2x00dev, 14, r14);
474e4ea1c403acece78c271bf9cd6f797d1cb093df9Ivo van Doorn	rt2500pci_bbp_write(rt2x00dev, 2, r2);
47595ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn}
47695ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn
47795ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doornstatic void rt2500pci_config_channel(struct rt2x00_dev *rt2x00dev,
4785c58ee51ff8c0aca74c225e0263bc5dd2b917781Ivo van Doorn				     struct rf_channel *rf, const int txpower)
47995ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn{
48095ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	u8 r70;
48195ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn
48295ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	/*
48395ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	 * Set TXpower.
48495ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	 */
4855c58ee51ff8c0aca74c225e0263bc5dd2b917781Ivo van Doorn	rt2x00_set_field32(&rf->rf3, RF3_TXPOWER, TXPOWER_TO_DEV(txpower));
48695ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn
48795ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	/*
48895ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	 * Switch on tuning bits.
48995ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	 * For RT2523 devices we do not need to update the R1 register.
49095ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	 */
4915122d8986232ef2a761f5cf70c31666c4d65c3e4Gertjan van Wingerde	if (!rt2x00_rf(rt2x00dev, RF2523))
4925c58ee51ff8c0aca74c225e0263bc5dd2b917781Ivo van Doorn		rt2x00_set_field32(&rf->rf1, RF1_TUNER, 1);
4935c58ee51ff8c0aca74c225e0263bc5dd2b917781Ivo van Doorn	rt2x00_set_field32(&rf->rf3, RF3_TUNER, 1);
49495ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn
49595ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	/*
49695ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	 * For RT2525 we should first set the channel to half band higher.
49795ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	 */
4985122d8986232ef2a761f5cf70c31666c4d65c3e4Gertjan van Wingerde	if (rt2x00_rf(rt2x00dev, RF2525)) {
49995ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn		static const u32 vals[] = {
50095ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn			0x00080cbe, 0x00080d02, 0x00080d06, 0x00080d0a,
50195ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn			0x00080d0e, 0x00080d12, 0x00080d16, 0x00080d1a,
50295ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn			0x00080d1e, 0x00080d22, 0x00080d26, 0x00080d2a,
50395ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn			0x00080d2e, 0x00080d3a
50495ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn		};
50595ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn
5065c58ee51ff8c0aca74c225e0263bc5dd2b917781Ivo van Doorn		rt2500pci_rf_write(rt2x00dev, 1, rf->rf1);
5075c58ee51ff8c0aca74c225e0263bc5dd2b917781Ivo van Doorn		rt2500pci_rf_write(rt2x00dev, 2, vals[rf->channel - 1]);
5085c58ee51ff8c0aca74c225e0263bc5dd2b917781Ivo van Doorn		rt2500pci_rf_write(rt2x00dev, 3, rf->rf3);
5095c58ee51ff8c0aca74c225e0263bc5dd2b917781Ivo van Doorn		if (rf->rf4)
5105c58ee51ff8c0aca74c225e0263bc5dd2b917781Ivo van Doorn			rt2500pci_rf_write(rt2x00dev, 4, rf->rf4);
51195ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	}
51295ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn
5135c58ee51ff8c0aca74c225e0263bc5dd2b917781Ivo van Doorn	rt2500pci_rf_write(rt2x00dev, 1, rf->rf1);
5145c58ee51ff8c0aca74c225e0263bc5dd2b917781Ivo van Doorn	rt2500pci_rf_write(rt2x00dev, 2, rf->rf2);
5155c58ee51ff8c0aca74c225e0263bc5dd2b917781Ivo van Doorn	rt2500pci_rf_write(rt2x00dev, 3, rf->rf3);
5165c58ee51ff8c0aca74c225e0263bc5dd2b917781Ivo van Doorn	if (rf->rf4)
5175c58ee51ff8c0aca74c225e0263bc5dd2b917781Ivo van Doorn		rt2500pci_rf_write(rt2x00dev, 4, rf->rf4);
51895ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn
51995ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	/*
52095ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	 * Channel 14 requires the Japan filter bit to be set.
52195ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	 */
52295ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	r70 = 0x46;
5235c58ee51ff8c0aca74c225e0263bc5dd2b917781Ivo van Doorn	rt2x00_set_field8(&r70, BBP_R70_JAPAN_FILTER, rf->channel == 14);
52495ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	rt2500pci_bbp_write(rt2x00dev, 70, r70);
52595ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn
52695ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	msleep(1);
52795ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn
52895ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	/*
52995ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	 * Switch off tuning bits.
53095ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	 * For RT2523 devices we do not need to update the R1 register.
53195ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	 */
5325122d8986232ef2a761f5cf70c31666c4d65c3e4Gertjan van Wingerde	if (!rt2x00_rf(rt2x00dev, RF2523)) {
5335c58ee51ff8c0aca74c225e0263bc5dd2b917781Ivo van Doorn		rt2x00_set_field32(&rf->rf1, RF1_TUNER, 0);
5345c58ee51ff8c0aca74c225e0263bc5dd2b917781Ivo van Doorn		rt2500pci_rf_write(rt2x00dev, 1, rf->rf1);
53595ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	}
53695ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn
5375c58ee51ff8c0aca74c225e0263bc5dd2b917781Ivo van Doorn	rt2x00_set_field32(&rf->rf3, RF3_TUNER, 0);
5385c58ee51ff8c0aca74c225e0263bc5dd2b917781Ivo van Doorn	rt2500pci_rf_write(rt2x00dev, 3, rf->rf3);
53995ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn
54095ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	/*
54195ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	 * Clear false CRC during channel switch.
54295ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	 */
5435c58ee51ff8c0aca74c225e0263bc5dd2b917781Ivo van Doorn	rt2x00pci_register_read(rt2x00dev, CNT0, &rf->rf1);
54495ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn}
54595ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn
54695ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doornstatic void rt2500pci_config_txpower(struct rt2x00_dev *rt2x00dev,
54795ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn				     const int txpower)
54895ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn{
54995ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	u32 rf3;
55095ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn
55195ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	rt2x00_rf_read(rt2x00dev, 3, &rf3);
55295ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	rt2x00_set_field32(&rf3, RF3_TXPOWER, TXPOWER_TO_DEV(txpower));
55395ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	rt2500pci_rf_write(rt2x00dev, 3, rf3);
55495ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn}
55595ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn
556e4ea1c403acece78c271bf9cd6f797d1cb093df9Ivo van Doornstatic void rt2500pci_config_retry_limit(struct rt2x00_dev *rt2x00dev,
557e4ea1c403acece78c271bf9cd6f797d1cb093df9Ivo van Doorn					 struct rt2x00lib_conf *libconf)
55895ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn{
55995ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	u32 reg;
56095ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn
561e4ea1c403acece78c271bf9cd6f797d1cb093df9Ivo van Doorn	rt2x00pci_register_read(rt2x00dev, CSR11, &reg);
562e4ea1c403acece78c271bf9cd6f797d1cb093df9Ivo van Doorn	rt2x00_set_field32(&reg, CSR11_LONG_RETRY,
563e4ea1c403acece78c271bf9cd6f797d1cb093df9Ivo van Doorn			   libconf->conf->long_frame_max_tx_count);
564e4ea1c403acece78c271bf9cd6f797d1cb093df9Ivo van Doorn	rt2x00_set_field32(&reg, CSR11_SHORT_RETRY,
565e4ea1c403acece78c271bf9cd6f797d1cb093df9Ivo van Doorn			   libconf->conf->short_frame_max_tx_count);
566e4ea1c403acece78c271bf9cd6f797d1cb093df9Ivo van Doorn	rt2x00pci_register_write(rt2x00dev, CSR11, reg);
56795ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn}
56895ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn
5697d7f19ccb777946df0a8fb7c83189ba2ae08b02eIvo van Doornstatic void rt2500pci_config_ps(struct rt2x00_dev *rt2x00dev,
5707d7f19ccb777946df0a8fb7c83189ba2ae08b02eIvo van Doorn				struct rt2x00lib_conf *libconf)
5717d7f19ccb777946df0a8fb7c83189ba2ae08b02eIvo van Doorn{
5727d7f19ccb777946df0a8fb7c83189ba2ae08b02eIvo van Doorn	enum dev_state state =
5737d7f19ccb777946df0a8fb7c83189ba2ae08b02eIvo van Doorn	    (libconf->conf->flags & IEEE80211_CONF_PS) ?
5747d7f19ccb777946df0a8fb7c83189ba2ae08b02eIvo van Doorn		STATE_SLEEP : STATE_AWAKE;
5757d7f19ccb777946df0a8fb7c83189ba2ae08b02eIvo van Doorn	u32 reg;
5767d7f19ccb777946df0a8fb7c83189ba2ae08b02eIvo van Doorn
5777d7f19ccb777946df0a8fb7c83189ba2ae08b02eIvo van Doorn	if (state == STATE_SLEEP) {
5787d7f19ccb777946df0a8fb7c83189ba2ae08b02eIvo van Doorn		rt2x00pci_register_read(rt2x00dev, CSR20, &reg);
5797d7f19ccb777946df0a8fb7c83189ba2ae08b02eIvo van Doorn		rt2x00_set_field32(&reg, CSR20_DELAY_AFTER_TBCN,
5806b347bff145f9a8a0972ca8fc3c44dd1f91b0f16Ivo van Doorn				   (rt2x00dev->beacon_int - 20) * 16);
5817d7f19ccb777946df0a8fb7c83189ba2ae08b02eIvo van Doorn		rt2x00_set_field32(&reg, CSR20_TBCN_BEFORE_WAKEUP,
5827d7f19ccb777946df0a8fb7c83189ba2ae08b02eIvo van Doorn				   libconf->conf->listen_interval - 1);
5837d7f19ccb777946df0a8fb7c83189ba2ae08b02eIvo van Doorn
5847d7f19ccb777946df0a8fb7c83189ba2ae08b02eIvo van Doorn		/* We must first disable autowake before it can be enabled */
5857d7f19ccb777946df0a8fb7c83189ba2ae08b02eIvo van Doorn		rt2x00_set_field32(&reg, CSR20_AUTOWAKE, 0);
5867d7f19ccb777946df0a8fb7c83189ba2ae08b02eIvo van Doorn		rt2x00pci_register_write(rt2x00dev, CSR20, reg);
5877d7f19ccb777946df0a8fb7c83189ba2ae08b02eIvo van Doorn
5887d7f19ccb777946df0a8fb7c83189ba2ae08b02eIvo van Doorn		rt2x00_set_field32(&reg, CSR20_AUTOWAKE, 1);
5897d7f19ccb777946df0a8fb7c83189ba2ae08b02eIvo van Doorn		rt2x00pci_register_write(rt2x00dev, CSR20, reg);
5905731858d0047cad309d334c4cd6ccb6199bf28feGertjan van Wingerde	} else {
5915731858d0047cad309d334c4cd6ccb6199bf28feGertjan van Wingerde		rt2x00pci_register_read(rt2x00dev, CSR20, &reg);
5925731858d0047cad309d334c4cd6ccb6199bf28feGertjan van Wingerde		rt2x00_set_field32(&reg, CSR20_AUTOWAKE, 0);
5935731858d0047cad309d334c4cd6ccb6199bf28feGertjan van Wingerde		rt2x00pci_register_write(rt2x00dev, CSR20, reg);
5947d7f19ccb777946df0a8fb7c83189ba2ae08b02eIvo van Doorn	}
5957d7f19ccb777946df0a8fb7c83189ba2ae08b02eIvo van Doorn
5967d7f19ccb777946df0a8fb7c83189ba2ae08b02eIvo van Doorn	rt2x00dev->ops->lib->set_device_state(rt2x00dev, state);
5977d7f19ccb777946df0a8fb7c83189ba2ae08b02eIvo van Doorn}
5987d7f19ccb777946df0a8fb7c83189ba2ae08b02eIvo van Doorn
59995ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doornstatic void rt2500pci_config(struct rt2x00_dev *rt2x00dev,
6006bb40dd13b458beb55f5c60dba1cb28e814bd640Ivo van Doorn			     struct rt2x00lib_conf *libconf,
6016bb40dd13b458beb55f5c60dba1cb28e814bd640Ivo van Doorn			     const unsigned int flags)
60295ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn{
603e4ea1c403acece78c271bf9cd6f797d1cb093df9Ivo van Doorn	if (flags & IEEE80211_CONF_CHANGE_CHANNEL)
6045c58ee51ff8c0aca74c225e0263bc5dd2b917781Ivo van Doorn		rt2500pci_config_channel(rt2x00dev, &libconf->rf,
6055c58ee51ff8c0aca74c225e0263bc5dd2b917781Ivo van Doorn					 libconf->conf->power_level);
606e4ea1c403acece78c271bf9cd6f797d1cb093df9Ivo van Doorn	if ((flags & IEEE80211_CONF_CHANGE_POWER) &&
607e4ea1c403acece78c271bf9cd6f797d1cb093df9Ivo van Doorn	    !(flags & IEEE80211_CONF_CHANGE_CHANNEL))
6085c58ee51ff8c0aca74c225e0263bc5dd2b917781Ivo van Doorn		rt2500pci_config_txpower(rt2x00dev,
6095c58ee51ff8c0aca74c225e0263bc5dd2b917781Ivo van Doorn					 libconf->conf->power_level);
610e4ea1c403acece78c271bf9cd6f797d1cb093df9Ivo van Doorn	if (flags & IEEE80211_CONF_CHANGE_RETRY_LIMITS)
611e4ea1c403acece78c271bf9cd6f797d1cb093df9Ivo van Doorn		rt2500pci_config_retry_limit(rt2x00dev, libconf);
6127d7f19ccb777946df0a8fb7c83189ba2ae08b02eIvo van Doorn	if (flags & IEEE80211_CONF_CHANGE_PS)
6137d7f19ccb777946df0a8fb7c83189ba2ae08b02eIvo van Doorn		rt2500pci_config_ps(rt2x00dev, libconf);
61495ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn}
61595ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn
61695ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn/*
61795ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn * Link tuning
61895ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn */
619ebcf26dae9f10e247ea41ef66f89b336ba456097Ivo van Doornstatic void rt2500pci_link_stats(struct rt2x00_dev *rt2x00dev,
620ebcf26dae9f10e247ea41ef66f89b336ba456097Ivo van Doorn				 struct link_qual *qual)
62195ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn{
62295ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	u32 reg;
62395ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn
62495ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	/*
62595ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	 * Update FCS error count from register.
62695ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	 */
62795ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	rt2x00pci_register_read(rt2x00dev, CNT0, &reg);
628ebcf26dae9f10e247ea41ef66f89b336ba456097Ivo van Doorn	qual->rx_failed = rt2x00_get_field32(reg, CNT0_FCS_ERROR);
62995ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn
63095ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	/*
63195ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	 * Update False CCA count from register.
63295ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	 */
63395ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	rt2x00pci_register_read(rt2x00dev, CNT3, &reg);
634ebcf26dae9f10e247ea41ef66f89b336ba456097Ivo van Doorn	qual->false_cca = rt2x00_get_field32(reg, CNT3_FALSE_CCA);
63595ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn}
63695ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn
6375352ff6510422d9a9bf13b7272f865eb53247f4dIvo van Doornstatic inline void rt2500pci_set_vgc(struct rt2x00_dev *rt2x00dev,
6385352ff6510422d9a9bf13b7272f865eb53247f4dIvo van Doorn				     struct link_qual *qual, u8 vgc_level)
639eb20b4e8a6998ca68d9ac0963ee36a1a36fe241dIvo van Doorn{
6405352ff6510422d9a9bf13b7272f865eb53247f4dIvo van Doorn	if (qual->vgc_level_reg != vgc_level) {
641eb20b4e8a6998ca68d9ac0963ee36a1a36fe241dIvo van Doorn		rt2500pci_bbp_write(rt2x00dev, 17, vgc_level);
642223dcc26591aa8e4a6bf623164b775b5bd89c9e1Ivo van Doorn		qual->vgc_level = vgc_level;
6435352ff6510422d9a9bf13b7272f865eb53247f4dIvo van Doorn		qual->vgc_level_reg = vgc_level;
644eb20b4e8a6998ca68d9ac0963ee36a1a36fe241dIvo van Doorn	}
645eb20b4e8a6998ca68d9ac0963ee36a1a36fe241dIvo van Doorn}
646eb20b4e8a6998ca68d9ac0963ee36a1a36fe241dIvo van Doorn
6475352ff6510422d9a9bf13b7272f865eb53247f4dIvo van Doornstatic void rt2500pci_reset_tuner(struct rt2x00_dev *rt2x00dev,
6485352ff6510422d9a9bf13b7272f865eb53247f4dIvo van Doorn				  struct link_qual *qual)
64995ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn{
6505352ff6510422d9a9bf13b7272f865eb53247f4dIvo van Doorn	rt2500pci_set_vgc(rt2x00dev, qual, 0x48);
65195ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn}
65295ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn
6535352ff6510422d9a9bf13b7272f865eb53247f4dIvo van Doornstatic void rt2500pci_link_tuner(struct rt2x00_dev *rt2x00dev,
6545352ff6510422d9a9bf13b7272f865eb53247f4dIvo van Doorn				 struct link_qual *qual, const u32 count)
65595ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn{
65695ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	/*
65795ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	 * To prevent collisions with MAC ASIC on chipsets
65895ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	 * up to version C the link tuning should halt after 20
6596bb40dd13b458beb55f5c60dba1cb28e814bd640Ivo van Doorn	 * seconds while being associated.
66095ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	 */
6615122d8986232ef2a761f5cf70c31666c4d65c3e4Gertjan van Wingerde	if (rt2x00_rev(rt2x00dev) < RT2560_VERSION_D &&
6625352ff6510422d9a9bf13b7272f865eb53247f4dIvo van Doorn	    rt2x00dev->intf_associated && count > 20)
66395ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn		return;
66495ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn
66595ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	/*
66695ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	 * Chipset versions C and lower should directly continue
6676bb40dd13b458beb55f5c60dba1cb28e814bd640Ivo van Doorn	 * to the dynamic CCA tuning. Chipset version D and higher
6686bb40dd13b458beb55f5c60dba1cb28e814bd640Ivo van Doorn	 * should go straight to dynamic CCA tuning when they
6696bb40dd13b458beb55f5c60dba1cb28e814bd640Ivo van Doorn	 * are not associated.
67095ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	 */
6715122d8986232ef2a761f5cf70c31666c4d65c3e4Gertjan van Wingerde	if (rt2x00_rev(rt2x00dev) < RT2560_VERSION_D ||
6726bb40dd13b458beb55f5c60dba1cb28e814bd640Ivo van Doorn	    !rt2x00dev->intf_associated)
67395ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn		goto dynamic_cca_tune;
67495ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn
67595ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	/*
67695ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	 * A too low RSSI will cause too much false CCA which will
67795ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	 * then corrupt the R17 tuning. To remidy this the tuning should
67895ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	 * be stopped (While making sure the R17 value will not exceed limits)
67995ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	 */
6805352ff6510422d9a9bf13b7272f865eb53247f4dIvo van Doorn	if (qual->rssi < -80 && count > 20) {
6815352ff6510422d9a9bf13b7272f865eb53247f4dIvo van Doorn		if (qual->vgc_level_reg >= 0x41)
6825352ff6510422d9a9bf13b7272f865eb53247f4dIvo van Doorn			rt2500pci_set_vgc(rt2x00dev, qual, qual->vgc_level);
68395ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn		return;
68495ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	}
68595ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn
68695ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	/*
68795ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	 * Special big-R17 for short distance
68895ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	 */
6895352ff6510422d9a9bf13b7272f865eb53247f4dIvo van Doorn	if (qual->rssi >= -58) {
6905352ff6510422d9a9bf13b7272f865eb53247f4dIvo van Doorn		rt2500pci_set_vgc(rt2x00dev, qual, 0x50);
69195ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn		return;
69295ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	}
69395ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn
69495ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	/*
69595ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	 * Special mid-R17 for middle distance
69695ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	 */
6975352ff6510422d9a9bf13b7272f865eb53247f4dIvo van Doorn	if (qual->rssi >= -74) {
6985352ff6510422d9a9bf13b7272f865eb53247f4dIvo van Doorn		rt2500pci_set_vgc(rt2x00dev, qual, 0x41);
69995ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn		return;
70095ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	}
70195ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn
70295ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	/*
70395ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	 * Leave short or middle distance condition, restore r17
70495ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	 * to the dynamic tuning range.
70595ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	 */
7065352ff6510422d9a9bf13b7272f865eb53247f4dIvo van Doorn	if (qual->vgc_level_reg >= 0x41) {
7075352ff6510422d9a9bf13b7272f865eb53247f4dIvo van Doorn		rt2500pci_set_vgc(rt2x00dev, qual, qual->vgc_level);
70895ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn		return;
70995ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	}
71095ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn
71195ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorndynamic_cca_tune:
71295ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn
71395ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	/*
71495ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	 * R17 is inside the dynamic tuning range,
71595ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	 * start tuning the link based on the false cca counter.
71695ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	 */
717223dcc26591aa8e4a6bf623164b775b5bd89c9e1Ivo van Doorn	if (qual->false_cca > 512 && qual->vgc_level_reg < 0x40)
7185352ff6510422d9a9bf13b7272f865eb53247f4dIvo van Doorn		rt2500pci_set_vgc(rt2x00dev, qual, ++qual->vgc_level_reg);
719223dcc26591aa8e4a6bf623164b775b5bd89c9e1Ivo van Doorn	else if (qual->false_cca < 100 && qual->vgc_level_reg > 0x32)
7205352ff6510422d9a9bf13b7272f865eb53247f4dIvo van Doorn		rt2500pci_set_vgc(rt2x00dev, qual, --qual->vgc_level_reg);
72195ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn}
72295ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn
72395ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn/*
7245450b7e2f0b47e52175b31399d8186a74ef3c46dIvo van Doorn * Queue handlers.
7255450b7e2f0b47e52175b31399d8186a74ef3c46dIvo van Doorn */
7265450b7e2f0b47e52175b31399d8186a74ef3c46dIvo van Doornstatic void rt2500pci_start_queue(struct data_queue *queue)
7275450b7e2f0b47e52175b31399d8186a74ef3c46dIvo van Doorn{
7285450b7e2f0b47e52175b31399d8186a74ef3c46dIvo van Doorn	struct rt2x00_dev *rt2x00dev = queue->rt2x00dev;
7295450b7e2f0b47e52175b31399d8186a74ef3c46dIvo van Doorn	u32 reg;
7305450b7e2f0b47e52175b31399d8186a74ef3c46dIvo van Doorn
7315450b7e2f0b47e52175b31399d8186a74ef3c46dIvo van Doorn	switch (queue->qid) {
7325450b7e2f0b47e52175b31399d8186a74ef3c46dIvo van Doorn	case QID_RX:
7335450b7e2f0b47e52175b31399d8186a74ef3c46dIvo van Doorn		rt2x00pci_register_read(rt2x00dev, RXCSR0, &reg);
7345450b7e2f0b47e52175b31399d8186a74ef3c46dIvo van Doorn		rt2x00_set_field32(&reg, RXCSR0_DISABLE_RX, 0);
7355450b7e2f0b47e52175b31399d8186a74ef3c46dIvo van Doorn		rt2x00pci_register_write(rt2x00dev, RXCSR0, reg);
7365450b7e2f0b47e52175b31399d8186a74ef3c46dIvo van Doorn		break;
7375450b7e2f0b47e52175b31399d8186a74ef3c46dIvo van Doorn	case QID_BEACON:
7385450b7e2f0b47e52175b31399d8186a74ef3c46dIvo van Doorn		rt2x00pci_register_read(rt2x00dev, CSR14, &reg);
7395450b7e2f0b47e52175b31399d8186a74ef3c46dIvo van Doorn		rt2x00_set_field32(&reg, CSR14_TSF_COUNT, 1);
7405450b7e2f0b47e52175b31399d8186a74ef3c46dIvo van Doorn		rt2x00_set_field32(&reg, CSR14_TBCN, 1);
7415450b7e2f0b47e52175b31399d8186a74ef3c46dIvo van Doorn		rt2x00_set_field32(&reg, CSR14_BEACON_GEN, 1);
7425450b7e2f0b47e52175b31399d8186a74ef3c46dIvo van Doorn		rt2x00pci_register_write(rt2x00dev, CSR14, reg);
7435450b7e2f0b47e52175b31399d8186a74ef3c46dIvo van Doorn		break;
7445450b7e2f0b47e52175b31399d8186a74ef3c46dIvo van Doorn	default:
7455450b7e2f0b47e52175b31399d8186a74ef3c46dIvo van Doorn		break;
7465450b7e2f0b47e52175b31399d8186a74ef3c46dIvo van Doorn	}
7475450b7e2f0b47e52175b31399d8186a74ef3c46dIvo van Doorn}
7485450b7e2f0b47e52175b31399d8186a74ef3c46dIvo van Doorn
7495450b7e2f0b47e52175b31399d8186a74ef3c46dIvo van Doornstatic void rt2500pci_kick_queue(struct data_queue *queue)
7505450b7e2f0b47e52175b31399d8186a74ef3c46dIvo van Doorn{
7515450b7e2f0b47e52175b31399d8186a74ef3c46dIvo van Doorn	struct rt2x00_dev *rt2x00dev = queue->rt2x00dev;
7525450b7e2f0b47e52175b31399d8186a74ef3c46dIvo van Doorn	u32 reg;
7535450b7e2f0b47e52175b31399d8186a74ef3c46dIvo van Doorn
7545450b7e2f0b47e52175b31399d8186a74ef3c46dIvo van Doorn	switch (queue->qid) {
755f615e9a38a8e6239d35891a05f2ac1159088780aIvo van Doorn	case QID_AC_VO:
7565450b7e2f0b47e52175b31399d8186a74ef3c46dIvo van Doorn		rt2x00pci_register_read(rt2x00dev, TXCSR0, &reg);
7575450b7e2f0b47e52175b31399d8186a74ef3c46dIvo van Doorn		rt2x00_set_field32(&reg, TXCSR0_KICK_PRIO, 1);
7585450b7e2f0b47e52175b31399d8186a74ef3c46dIvo van Doorn		rt2x00pci_register_write(rt2x00dev, TXCSR0, reg);
7595450b7e2f0b47e52175b31399d8186a74ef3c46dIvo van Doorn		break;
760f615e9a38a8e6239d35891a05f2ac1159088780aIvo van Doorn	case QID_AC_VI:
7615450b7e2f0b47e52175b31399d8186a74ef3c46dIvo van Doorn		rt2x00pci_register_read(rt2x00dev, TXCSR0, &reg);
7625450b7e2f0b47e52175b31399d8186a74ef3c46dIvo van Doorn		rt2x00_set_field32(&reg, TXCSR0_KICK_TX, 1);
7635450b7e2f0b47e52175b31399d8186a74ef3c46dIvo van Doorn		rt2x00pci_register_write(rt2x00dev, TXCSR0, reg);
7645450b7e2f0b47e52175b31399d8186a74ef3c46dIvo van Doorn		break;
7655450b7e2f0b47e52175b31399d8186a74ef3c46dIvo van Doorn	case QID_ATIM:
7665450b7e2f0b47e52175b31399d8186a74ef3c46dIvo van Doorn		rt2x00pci_register_read(rt2x00dev, TXCSR0, &reg);
7675450b7e2f0b47e52175b31399d8186a74ef3c46dIvo van Doorn		rt2x00_set_field32(&reg, TXCSR0_KICK_ATIM, 1);
7685450b7e2f0b47e52175b31399d8186a74ef3c46dIvo van Doorn		rt2x00pci_register_write(rt2x00dev, TXCSR0, reg);
7695450b7e2f0b47e52175b31399d8186a74ef3c46dIvo van Doorn		break;
7705450b7e2f0b47e52175b31399d8186a74ef3c46dIvo van Doorn	default:
7715450b7e2f0b47e52175b31399d8186a74ef3c46dIvo van Doorn		break;
7725450b7e2f0b47e52175b31399d8186a74ef3c46dIvo van Doorn	}
7735450b7e2f0b47e52175b31399d8186a74ef3c46dIvo van Doorn}
7745450b7e2f0b47e52175b31399d8186a74ef3c46dIvo van Doorn
7755450b7e2f0b47e52175b31399d8186a74ef3c46dIvo van Doornstatic void rt2500pci_stop_queue(struct data_queue *queue)
7765450b7e2f0b47e52175b31399d8186a74ef3c46dIvo van Doorn{
7775450b7e2f0b47e52175b31399d8186a74ef3c46dIvo van Doorn	struct rt2x00_dev *rt2x00dev = queue->rt2x00dev;
7785450b7e2f0b47e52175b31399d8186a74ef3c46dIvo van Doorn	u32 reg;
7795450b7e2f0b47e52175b31399d8186a74ef3c46dIvo van Doorn
7805450b7e2f0b47e52175b31399d8186a74ef3c46dIvo van Doorn	switch (queue->qid) {
781f615e9a38a8e6239d35891a05f2ac1159088780aIvo van Doorn	case QID_AC_VO:
782f615e9a38a8e6239d35891a05f2ac1159088780aIvo van Doorn	case QID_AC_VI:
7835450b7e2f0b47e52175b31399d8186a74ef3c46dIvo van Doorn	case QID_ATIM:
7845450b7e2f0b47e52175b31399d8186a74ef3c46dIvo van Doorn		rt2x00pci_register_read(rt2x00dev, TXCSR0, &reg);
7855450b7e2f0b47e52175b31399d8186a74ef3c46dIvo van Doorn		rt2x00_set_field32(&reg, TXCSR0_ABORT, 1);
7865450b7e2f0b47e52175b31399d8186a74ef3c46dIvo van Doorn		rt2x00pci_register_write(rt2x00dev, TXCSR0, reg);
7875450b7e2f0b47e52175b31399d8186a74ef3c46dIvo van Doorn		break;
7885450b7e2f0b47e52175b31399d8186a74ef3c46dIvo van Doorn	case QID_RX:
7895450b7e2f0b47e52175b31399d8186a74ef3c46dIvo van Doorn		rt2x00pci_register_read(rt2x00dev, RXCSR0, &reg);
7905450b7e2f0b47e52175b31399d8186a74ef3c46dIvo van Doorn		rt2x00_set_field32(&reg, RXCSR0_DISABLE_RX, 1);
7915450b7e2f0b47e52175b31399d8186a74ef3c46dIvo van Doorn		rt2x00pci_register_write(rt2x00dev, RXCSR0, reg);
7925450b7e2f0b47e52175b31399d8186a74ef3c46dIvo van Doorn		break;
7935450b7e2f0b47e52175b31399d8186a74ef3c46dIvo van Doorn	case QID_BEACON:
7945450b7e2f0b47e52175b31399d8186a74ef3c46dIvo van Doorn		rt2x00pci_register_read(rt2x00dev, CSR14, &reg);
7955450b7e2f0b47e52175b31399d8186a74ef3c46dIvo van Doorn		rt2x00_set_field32(&reg, CSR14_TSF_COUNT, 0);
7965450b7e2f0b47e52175b31399d8186a74ef3c46dIvo van Doorn		rt2x00_set_field32(&reg, CSR14_TBCN, 0);
7975450b7e2f0b47e52175b31399d8186a74ef3c46dIvo van Doorn		rt2x00_set_field32(&reg, CSR14_BEACON_GEN, 0);
7985450b7e2f0b47e52175b31399d8186a74ef3c46dIvo van Doorn		rt2x00pci_register_write(rt2x00dev, CSR14, reg);
79916222a0d06f5032d7e8bc7c65e8bf299e21f413aHelmut Schaa
80016222a0d06f5032d7e8bc7c65e8bf299e21f413aHelmut Schaa		/*
80116222a0d06f5032d7e8bc7c65e8bf299e21f413aHelmut Schaa		 * Wait for possibly running tbtt tasklets.
80216222a0d06f5032d7e8bc7c65e8bf299e21f413aHelmut Schaa		 */
803abc11994112bf7441519e35f51c29ff5de5b0d4dHelmut Schaa		tasklet_kill(&rt2x00dev->tbtt_tasklet);
8045450b7e2f0b47e52175b31399d8186a74ef3c46dIvo van Doorn		break;
8055450b7e2f0b47e52175b31399d8186a74ef3c46dIvo van Doorn	default:
8065450b7e2f0b47e52175b31399d8186a74ef3c46dIvo van Doorn		break;
8075450b7e2f0b47e52175b31399d8186a74ef3c46dIvo van Doorn	}
8085450b7e2f0b47e52175b31399d8186a74ef3c46dIvo van Doorn}
8095450b7e2f0b47e52175b31399d8186a74ef3c46dIvo van Doorn
8105450b7e2f0b47e52175b31399d8186a74ef3c46dIvo van Doorn/*
81195ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn * Initialization functions.
81295ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn */
813798b7adb4ed3533ab1282f51d16892034cfd8aaeIvo van Doornstatic bool rt2500pci_get_entry_state(struct queue_entry *entry)
81495ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn{
815b8be63ffa5dc44324e7f507997870fa3e4b17619Ivo van Doorn	struct queue_entry_priv_pci *entry_priv = entry->priv_data;
81695ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	u32 word;
81795ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn
818798b7adb4ed3533ab1282f51d16892034cfd8aaeIvo van Doorn	if (entry->queue->qid == QID_RX) {
819798b7adb4ed3533ab1282f51d16892034cfd8aaeIvo van Doorn		rt2x00_desc_read(entry_priv->desc, 0, &word);
820798b7adb4ed3533ab1282f51d16892034cfd8aaeIvo van Doorn
821798b7adb4ed3533ab1282f51d16892034cfd8aaeIvo van Doorn		return rt2x00_get_field32(word, RXD_W0_OWNER_NIC);
822798b7adb4ed3533ab1282f51d16892034cfd8aaeIvo van Doorn	} else {
823798b7adb4ed3533ab1282f51d16892034cfd8aaeIvo van Doorn		rt2x00_desc_read(entry_priv->desc, 0, &word);
82495ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn
825798b7adb4ed3533ab1282f51d16892034cfd8aaeIvo van Doorn		return (rt2x00_get_field32(word, TXD_W0_OWNER_NIC) ||
826798b7adb4ed3533ab1282f51d16892034cfd8aaeIvo van Doorn		        rt2x00_get_field32(word, TXD_W0_VALID));
827798b7adb4ed3533ab1282f51d16892034cfd8aaeIvo van Doorn	}
82895ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn}
82995ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn
830798b7adb4ed3533ab1282f51d16892034cfd8aaeIvo van Doornstatic void rt2500pci_clear_entry(struct queue_entry *entry)
83195ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn{
832b8be63ffa5dc44324e7f507997870fa3e4b17619Ivo van Doorn	struct queue_entry_priv_pci *entry_priv = entry->priv_data;
833798b7adb4ed3533ab1282f51d16892034cfd8aaeIvo van Doorn	struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb);
83495ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	u32 word;
83595ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn
836798b7adb4ed3533ab1282f51d16892034cfd8aaeIvo van Doorn	if (entry->queue->qid == QID_RX) {
837798b7adb4ed3533ab1282f51d16892034cfd8aaeIvo van Doorn		rt2x00_desc_read(entry_priv->desc, 1, &word);
838798b7adb4ed3533ab1282f51d16892034cfd8aaeIvo van Doorn		rt2x00_set_field32(&word, RXD_W1_BUFFER_ADDRESS, skbdesc->skb_dma);
839798b7adb4ed3533ab1282f51d16892034cfd8aaeIvo van Doorn		rt2x00_desc_write(entry_priv->desc, 1, word);
840798b7adb4ed3533ab1282f51d16892034cfd8aaeIvo van Doorn
841798b7adb4ed3533ab1282f51d16892034cfd8aaeIvo van Doorn		rt2x00_desc_read(entry_priv->desc, 0, &word);
842798b7adb4ed3533ab1282f51d16892034cfd8aaeIvo van Doorn		rt2x00_set_field32(&word, RXD_W0_OWNER_NIC, 1);
843798b7adb4ed3533ab1282f51d16892034cfd8aaeIvo van Doorn		rt2x00_desc_write(entry_priv->desc, 0, word);
844798b7adb4ed3533ab1282f51d16892034cfd8aaeIvo van Doorn	} else {
845798b7adb4ed3533ab1282f51d16892034cfd8aaeIvo van Doorn		rt2x00_desc_read(entry_priv->desc, 0, &word);
846798b7adb4ed3533ab1282f51d16892034cfd8aaeIvo van Doorn		rt2x00_set_field32(&word, TXD_W0_VALID, 0);
847798b7adb4ed3533ab1282f51d16892034cfd8aaeIvo van Doorn		rt2x00_set_field32(&word, TXD_W0_OWNER_NIC, 0);
848798b7adb4ed3533ab1282f51d16892034cfd8aaeIvo van Doorn		rt2x00_desc_write(entry_priv->desc, 0, word);
849798b7adb4ed3533ab1282f51d16892034cfd8aaeIvo van Doorn	}
85095ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn}
85195ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn
852181d6902b6bad978d157e69479c95cc0ff213a76Ivo van Doornstatic int rt2500pci_init_queues(struct rt2x00_dev *rt2x00dev)
85395ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn{
854b8be63ffa5dc44324e7f507997870fa3e4b17619Ivo van Doorn	struct queue_entry_priv_pci *entry_priv;
85595ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	u32 reg;
85695ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn
85795ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	/*
85895ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	 * Initialize registers.
85995ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	 */
86095ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	rt2x00pci_register_read(rt2x00dev, TXCSR2, &reg);
861181d6902b6bad978d157e69479c95cc0ff213a76Ivo van Doorn	rt2x00_set_field32(&reg, TXCSR2_TXD_SIZE, rt2x00dev->tx[0].desc_size);
862181d6902b6bad978d157e69479c95cc0ff213a76Ivo van Doorn	rt2x00_set_field32(&reg, TXCSR2_NUM_TXD, rt2x00dev->tx[1].limit);
863e74df4a7562da56a7e4dbf41ff167b2f44e84a50Gertjan van Wingerde	rt2x00_set_field32(&reg, TXCSR2_NUM_ATIM, rt2x00dev->atim->limit);
864181d6902b6bad978d157e69479c95cc0ff213a76Ivo van Doorn	rt2x00_set_field32(&reg, TXCSR2_NUM_PRIO, rt2x00dev->tx[0].limit);
86595ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	rt2x00pci_register_write(rt2x00dev, TXCSR2, reg);
86695ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn
867b8be63ffa5dc44324e7f507997870fa3e4b17619Ivo van Doorn	entry_priv = rt2x00dev->tx[1].entries[0].priv_data;
86895ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	rt2x00pci_register_read(rt2x00dev, TXCSR3, &reg);
86930b3a23c2594e122e7086f97b5252a87eaf8a817Ivo van Doorn	rt2x00_set_field32(&reg, TXCSR3_TX_RING_REGISTER,
870b8be63ffa5dc44324e7f507997870fa3e4b17619Ivo van Doorn			   entry_priv->desc_dma);
87195ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	rt2x00pci_register_write(rt2x00dev, TXCSR3, reg);
87295ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn
873b8be63ffa5dc44324e7f507997870fa3e4b17619Ivo van Doorn	entry_priv = rt2x00dev->tx[0].entries[0].priv_data;
87495ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	rt2x00pci_register_read(rt2x00dev, TXCSR5, &reg);
87530b3a23c2594e122e7086f97b5252a87eaf8a817Ivo van Doorn	rt2x00_set_field32(&reg, TXCSR5_PRIO_RING_REGISTER,
876b8be63ffa5dc44324e7f507997870fa3e4b17619Ivo van Doorn			   entry_priv->desc_dma);
87795ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	rt2x00pci_register_write(rt2x00dev, TXCSR5, reg);
87895ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn
879e74df4a7562da56a7e4dbf41ff167b2f44e84a50Gertjan van Wingerde	entry_priv = rt2x00dev->atim->entries[0].priv_data;
88095ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	rt2x00pci_register_read(rt2x00dev, TXCSR4, &reg);
88130b3a23c2594e122e7086f97b5252a87eaf8a817Ivo van Doorn	rt2x00_set_field32(&reg, TXCSR4_ATIM_RING_REGISTER,
882b8be63ffa5dc44324e7f507997870fa3e4b17619Ivo van Doorn			   entry_priv->desc_dma);
88395ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	rt2x00pci_register_write(rt2x00dev, TXCSR4, reg);
88495ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn
885e74df4a7562da56a7e4dbf41ff167b2f44e84a50Gertjan van Wingerde	entry_priv = rt2x00dev->bcn->entries[0].priv_data;
88695ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	rt2x00pci_register_read(rt2x00dev, TXCSR6, &reg);
88730b3a23c2594e122e7086f97b5252a87eaf8a817Ivo van Doorn	rt2x00_set_field32(&reg, TXCSR6_BEACON_RING_REGISTER,
888b8be63ffa5dc44324e7f507997870fa3e4b17619Ivo van Doorn			   entry_priv->desc_dma);
88995ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	rt2x00pci_register_write(rt2x00dev, TXCSR6, reg);
89095ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn
89195ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	rt2x00pci_register_read(rt2x00dev, RXCSR1, &reg);
89295ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	rt2x00_set_field32(&reg, RXCSR1_RXD_SIZE, rt2x00dev->rx->desc_size);
893181d6902b6bad978d157e69479c95cc0ff213a76Ivo van Doorn	rt2x00_set_field32(&reg, RXCSR1_NUM_RXD, rt2x00dev->rx->limit);
89495ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	rt2x00pci_register_write(rt2x00dev, RXCSR1, reg);
89595ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn
896b8be63ffa5dc44324e7f507997870fa3e4b17619Ivo van Doorn	entry_priv = rt2x00dev->rx->entries[0].priv_data;
89795ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	rt2x00pci_register_read(rt2x00dev, RXCSR2, &reg);
898b8be63ffa5dc44324e7f507997870fa3e4b17619Ivo van Doorn	rt2x00_set_field32(&reg, RXCSR2_RX_RING_REGISTER,
899b8be63ffa5dc44324e7f507997870fa3e4b17619Ivo van Doorn			   entry_priv->desc_dma);
90095ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	rt2x00pci_register_write(rt2x00dev, RXCSR2, reg);
90195ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn
90295ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	return 0;
90395ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn}
90495ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn
90595ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doornstatic int rt2500pci_init_registers(struct rt2x00_dev *rt2x00dev)
90695ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn{
90795ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	u32 reg;
90895ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn
90995ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	rt2x00pci_register_write(rt2x00dev, PSCSR0, 0x00020002);
91095ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	rt2x00pci_register_write(rt2x00dev, PSCSR1, 0x00000002);
91195ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	rt2x00pci_register_write(rt2x00dev, PSCSR2, 0x00020002);
91295ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	rt2x00pci_register_write(rt2x00dev, PSCSR3, 0x00000002);
91395ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn
91495ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	rt2x00pci_register_read(rt2x00dev, TIMECSR, &reg);
91595ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	rt2x00_set_field32(&reg, TIMECSR_US_COUNT, 33);
91695ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	rt2x00_set_field32(&reg, TIMECSR_US_64_COUNT, 63);
91795ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	rt2x00_set_field32(&reg, TIMECSR_BEACON_EXPECT, 0);
91895ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	rt2x00pci_register_write(rt2x00dev, TIMECSR, reg);
91995ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn
92095ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	rt2x00pci_register_read(rt2x00dev, CSR9, &reg);
92195ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	rt2x00_set_field32(&reg, CSR9_MAX_FRAME_UNIT,
92295ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn			   rt2x00dev->rx->data_size / 128);
92395ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	rt2x00pci_register_write(rt2x00dev, CSR9, reg);
92495ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn
92595ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	/*
92695ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	 * Always use CWmin and CWmax set in descriptor.
92795ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	 */
92895ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	rt2x00pci_register_read(rt2x00dev, CSR11, &reg);
92995ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	rt2x00_set_field32(&reg, CSR11_CW_SELECT, 0);
93095ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	rt2x00pci_register_write(rt2x00dev, CSR11, reg);
93195ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn
9321f90916264049a7d9e6106fd60d289c9a775d24fIvo van Doorn	rt2x00pci_register_read(rt2x00dev, CSR14, &reg);
9331f90916264049a7d9e6106fd60d289c9a775d24fIvo van Doorn	rt2x00_set_field32(&reg, CSR14_TSF_COUNT, 0);
9341f90916264049a7d9e6106fd60d289c9a775d24fIvo van Doorn	rt2x00_set_field32(&reg, CSR14_TSF_SYNC, 0);
9351f90916264049a7d9e6106fd60d289c9a775d24fIvo van Doorn	rt2x00_set_field32(&reg, CSR14_TBCN, 0);
9361f90916264049a7d9e6106fd60d289c9a775d24fIvo van Doorn	rt2x00_set_field32(&reg, CSR14_TCFP, 0);
9371f90916264049a7d9e6106fd60d289c9a775d24fIvo van Doorn	rt2x00_set_field32(&reg, CSR14_TATIMW, 0);
9381f90916264049a7d9e6106fd60d289c9a775d24fIvo van Doorn	rt2x00_set_field32(&reg, CSR14_BEACON_GEN, 0);
9391f90916264049a7d9e6106fd60d289c9a775d24fIvo van Doorn	rt2x00_set_field32(&reg, CSR14_CFP_COUNT_PRELOAD, 0);
9401f90916264049a7d9e6106fd60d289c9a775d24fIvo van Doorn	rt2x00_set_field32(&reg, CSR14_TBCM_PRELOAD, 0);
9411f90916264049a7d9e6106fd60d289c9a775d24fIvo van Doorn	rt2x00pci_register_write(rt2x00dev, CSR14, reg);
9421f90916264049a7d9e6106fd60d289c9a775d24fIvo van Doorn
94395ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	rt2x00pci_register_write(rt2x00dev, CNT3, 0);
94495ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn
94595ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	rt2x00pci_register_read(rt2x00dev, TXCSR8, &reg);
94695ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	rt2x00_set_field32(&reg, TXCSR8_BBP_ID0, 10);
94795ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	rt2x00_set_field32(&reg, TXCSR8_BBP_ID0_VALID, 1);
94895ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	rt2x00_set_field32(&reg, TXCSR8_BBP_ID1, 11);
94995ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	rt2x00_set_field32(&reg, TXCSR8_BBP_ID1_VALID, 1);
95095ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	rt2x00_set_field32(&reg, TXCSR8_BBP_ID2, 13);
95195ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	rt2x00_set_field32(&reg, TXCSR8_BBP_ID2_VALID, 1);
95295ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	rt2x00_set_field32(&reg, TXCSR8_BBP_ID3, 12);
95395ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	rt2x00_set_field32(&reg, TXCSR8_BBP_ID3_VALID, 1);
95495ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	rt2x00pci_register_write(rt2x00dev, TXCSR8, reg);
95595ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn
95695ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	rt2x00pci_register_read(rt2x00dev, ARTCSR0, &reg);
95795ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	rt2x00_set_field32(&reg, ARTCSR0_ACK_CTS_1MBS, 112);
95895ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	rt2x00_set_field32(&reg, ARTCSR0_ACK_CTS_2MBS, 56);
95995ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	rt2x00_set_field32(&reg, ARTCSR0_ACK_CTS_5_5MBS, 20);
96095ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	rt2x00_set_field32(&reg, ARTCSR0_ACK_CTS_11MBS, 10);
96195ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	rt2x00pci_register_write(rt2x00dev, ARTCSR0, reg);
96295ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn
96395ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	rt2x00pci_register_read(rt2x00dev, ARTCSR1, &reg);
96495ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	rt2x00_set_field32(&reg, ARTCSR1_ACK_CTS_6MBS, 45);
96595ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	rt2x00_set_field32(&reg, ARTCSR1_ACK_CTS_9MBS, 37);
96695ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	rt2x00_set_field32(&reg, ARTCSR1_ACK_CTS_12MBS, 33);
96795ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	rt2x00_set_field32(&reg, ARTCSR1_ACK_CTS_18MBS, 29);
96895ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	rt2x00pci_register_write(rt2x00dev, ARTCSR1, reg);
96995ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn
97095ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	rt2x00pci_register_read(rt2x00dev, ARTCSR2, &reg);
97195ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	rt2x00_set_field32(&reg, ARTCSR2_ACK_CTS_24MBS, 29);
97295ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	rt2x00_set_field32(&reg, ARTCSR2_ACK_CTS_36MBS, 25);
97395ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	rt2x00_set_field32(&reg, ARTCSR2_ACK_CTS_48MBS, 25);
97495ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	rt2x00_set_field32(&reg, ARTCSR2_ACK_CTS_54MBS, 25);
97595ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	rt2x00pci_register_write(rt2x00dev, ARTCSR2, reg);
97695ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn
97795ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	rt2x00pci_register_read(rt2x00dev, RXCSR3, &reg);
97895ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	rt2x00_set_field32(&reg, RXCSR3_BBP_ID0, 47); /* CCK Signal */
97995ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	rt2x00_set_field32(&reg, RXCSR3_BBP_ID0_VALID, 1);
98095ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	rt2x00_set_field32(&reg, RXCSR3_BBP_ID1, 51); /* Rssi */
98195ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	rt2x00_set_field32(&reg, RXCSR3_BBP_ID1_VALID, 1);
98295ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	rt2x00_set_field32(&reg, RXCSR3_BBP_ID2, 42); /* OFDM Rate */
98395ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	rt2x00_set_field32(&reg, RXCSR3_BBP_ID2_VALID, 1);
98495ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	rt2x00_set_field32(&reg, RXCSR3_BBP_ID3, 51); /* RSSI */
98595ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	rt2x00_set_field32(&reg, RXCSR3_BBP_ID3_VALID, 1);
98695ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	rt2x00pci_register_write(rt2x00dev, RXCSR3, reg);
98795ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn
98895ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	rt2x00pci_register_read(rt2x00dev, PCICSR, &reg);
98995ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	rt2x00_set_field32(&reg, PCICSR_BIG_ENDIAN, 0);
99095ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	rt2x00_set_field32(&reg, PCICSR_RX_TRESHOLD, 0);
99195ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	rt2x00_set_field32(&reg, PCICSR_TX_TRESHOLD, 3);
99295ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	rt2x00_set_field32(&reg, PCICSR_BURST_LENTH, 1);
99395ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	rt2x00_set_field32(&reg, PCICSR_ENABLE_CLK, 1);
99495ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	rt2x00_set_field32(&reg, PCICSR_READ_MULTIPLE, 1);
99595ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	rt2x00_set_field32(&reg, PCICSR_WRITE_INVALID, 1);
99695ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	rt2x00pci_register_write(rt2x00dev, PCICSR, reg);
99795ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn
99895ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	rt2x00pci_register_write(rt2x00dev, PWRCSR0, 0x3f3b3100);
99995ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn
100095ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	rt2x00pci_register_write(rt2x00dev, GPIOCSR, 0x0000ff00);
100195ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	rt2x00pci_register_write(rt2x00dev, TESTCSR, 0x000000f0);
100295ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn
100395ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	if (rt2x00dev->ops->lib->set_device_state(rt2x00dev, STATE_AWAKE))
100495ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn		return -EBUSY;
100595ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn
100695ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	rt2x00pci_register_write(rt2x00dev, MACCSR0, 0x00213223);
100795ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	rt2x00pci_register_write(rt2x00dev, MACCSR1, 0x00235518);
100895ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn
100995ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	rt2x00pci_register_read(rt2x00dev, MACCSR2, &reg);
101095ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	rt2x00_set_field32(&reg, MACCSR2_DELAY, 64);
101195ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	rt2x00pci_register_write(rt2x00dev, MACCSR2, reg);
101295ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn
101395ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	rt2x00pci_register_read(rt2x00dev, RALINKCSR, &reg);
101495ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	rt2x00_set_field32(&reg, RALINKCSR_AR_BBP_DATA0, 17);
101595ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	rt2x00_set_field32(&reg, RALINKCSR_AR_BBP_ID0, 26);
101695ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	rt2x00_set_field32(&reg, RALINKCSR_AR_BBP_VALID0, 1);
101795ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	rt2x00_set_field32(&reg, RALINKCSR_AR_BBP_DATA1, 0);
101895ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	rt2x00_set_field32(&reg, RALINKCSR_AR_BBP_ID1, 26);
101995ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	rt2x00_set_field32(&reg, RALINKCSR_AR_BBP_VALID1, 1);
102095ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	rt2x00pci_register_write(rt2x00dev, RALINKCSR, reg);
102195ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn
102295ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	rt2x00pci_register_write(rt2x00dev, BBPCSR1, 0x82188200);
102395ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn
102495ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	rt2x00pci_register_write(rt2x00dev, TXACKCSR0, 0x00000020);
102595ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn
102695ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	rt2x00pci_register_read(rt2x00dev, CSR1, &reg);
102795ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	rt2x00_set_field32(&reg, CSR1_SOFT_RESET, 1);
102895ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	rt2x00_set_field32(&reg, CSR1_BBP_RESET, 0);
102995ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	rt2x00_set_field32(&reg, CSR1_HOST_READY, 0);
103095ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	rt2x00pci_register_write(rt2x00dev, CSR1, reg);
103195ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn
103295ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	rt2x00pci_register_read(rt2x00dev, CSR1, &reg);
103395ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	rt2x00_set_field32(&reg, CSR1_SOFT_RESET, 0);
103495ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	rt2x00_set_field32(&reg, CSR1_HOST_READY, 1);
103595ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	rt2x00pci_register_write(rt2x00dev, CSR1, reg);
103695ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn
103795ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	/*
103895ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	 * We must clear the FCS and FIFO error count.
103995ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	 * These registers are cleared on read,
104095ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	 * so we may pass a useless variable to store the value.
104195ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	 */
104295ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	rt2x00pci_register_read(rt2x00dev, CNT0, &reg);
104395ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	rt2x00pci_register_read(rt2x00dev, CNT4, &reg);
104495ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn
104595ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	return 0;
104695ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn}
104795ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn
10482b08da3fb595432f87b5206c1c77dcb72300cacfIvo van Doornstatic int rt2500pci_wait_bbp_ready(struct rt2x00_dev *rt2x00dev)
104995ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn{
105095ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	unsigned int i;
105195ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	u8 value;
105295ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn
105395ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	for (i = 0; i < REGISTER_BUSY_COUNT; i++) {
105495ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn		rt2500pci_bbp_read(rt2x00dev, 0, &value);
105595ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn		if ((value != 0xff) && (value != 0x00))
10562b08da3fb595432f87b5206c1c77dcb72300cacfIvo van Doorn			return 0;
105795ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn		udelay(REGISTER_BUSY_DELAY);
105895ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	}
105995ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn
106095ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	ERROR(rt2x00dev, "BBP register access failed, aborting.\n");
106195ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	return -EACCES;
10622b08da3fb595432f87b5206c1c77dcb72300cacfIvo van Doorn}
10632b08da3fb595432f87b5206c1c77dcb72300cacfIvo van Doorn
10642b08da3fb595432f87b5206c1c77dcb72300cacfIvo van Doornstatic int rt2500pci_init_bbp(struct rt2x00_dev *rt2x00dev)
10652b08da3fb595432f87b5206c1c77dcb72300cacfIvo van Doorn{
10662b08da3fb595432f87b5206c1c77dcb72300cacfIvo van Doorn	unsigned int i;
10672b08da3fb595432f87b5206c1c77dcb72300cacfIvo van Doorn	u16 eeprom;
10682b08da3fb595432f87b5206c1c77dcb72300cacfIvo van Doorn	u8 reg_id;
10692b08da3fb595432f87b5206c1c77dcb72300cacfIvo van Doorn	u8 value;
10702b08da3fb595432f87b5206c1c77dcb72300cacfIvo van Doorn
10712b08da3fb595432f87b5206c1c77dcb72300cacfIvo van Doorn	if (unlikely(rt2500pci_wait_bbp_ready(rt2x00dev)))
10722b08da3fb595432f87b5206c1c77dcb72300cacfIvo van Doorn		return -EACCES;
107395ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn
107495ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	rt2500pci_bbp_write(rt2x00dev, 3, 0x02);
107595ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	rt2500pci_bbp_write(rt2x00dev, 4, 0x19);
107695ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	rt2500pci_bbp_write(rt2x00dev, 14, 0x1c);
107795ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	rt2500pci_bbp_write(rt2x00dev, 15, 0x30);
107895ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	rt2500pci_bbp_write(rt2x00dev, 16, 0xac);
107995ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	rt2500pci_bbp_write(rt2x00dev, 18, 0x18);
108095ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	rt2500pci_bbp_write(rt2x00dev, 19, 0xff);
108195ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	rt2500pci_bbp_write(rt2x00dev, 20, 0x1e);
108295ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	rt2500pci_bbp_write(rt2x00dev, 21, 0x08);
108395ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	rt2500pci_bbp_write(rt2x00dev, 22, 0x08);
108495ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	rt2500pci_bbp_write(rt2x00dev, 23, 0x08);
108595ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	rt2500pci_bbp_write(rt2x00dev, 24, 0x70);
108695ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	rt2500pci_bbp_write(rt2x00dev, 25, 0x40);
108795ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	rt2500pci_bbp_write(rt2x00dev, 26, 0x08);
108895ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	rt2500pci_bbp_write(rt2x00dev, 27, 0x23);
108995ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	rt2500pci_bbp_write(rt2x00dev, 30, 0x10);
109095ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	rt2500pci_bbp_write(rt2x00dev, 31, 0x2b);
109195ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	rt2500pci_bbp_write(rt2x00dev, 32, 0xb9);
109295ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	rt2500pci_bbp_write(rt2x00dev, 34, 0x12);
109395ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	rt2500pci_bbp_write(rt2x00dev, 35, 0x50);
109495ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	rt2500pci_bbp_write(rt2x00dev, 39, 0xc4);
109595ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	rt2500pci_bbp_write(rt2x00dev, 40, 0x02);
109695ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	rt2500pci_bbp_write(rt2x00dev, 41, 0x60);
109795ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	rt2500pci_bbp_write(rt2x00dev, 53, 0x10);
109895ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	rt2500pci_bbp_write(rt2x00dev, 54, 0x18);
109995ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	rt2500pci_bbp_write(rt2x00dev, 56, 0x08);
110095ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	rt2500pci_bbp_write(rt2x00dev, 57, 0x10);
110195ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	rt2500pci_bbp_write(rt2x00dev, 58, 0x08);
110295ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	rt2500pci_bbp_write(rt2x00dev, 61, 0x6d);
110395ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	rt2500pci_bbp_write(rt2x00dev, 62, 0x10);
110495ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn
110595ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	for (i = 0; i < EEPROM_BBP_SIZE; i++) {
110695ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn		rt2x00_eeprom_read(rt2x00dev, EEPROM_BBP_START + i, &eeprom);
110795ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn
110895ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn		if (eeprom != 0xffff && eeprom != 0x0000) {
110995ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn			reg_id = rt2x00_get_field16(eeprom, EEPROM_BBP_REG_ID);
111095ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn			value = rt2x00_get_field16(eeprom, EEPROM_BBP_VALUE);
111195ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn			rt2500pci_bbp_write(rt2x00dev, reg_id, value);
111295ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn		}
111395ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	}
111495ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn
111595ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	return 0;
111695ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn}
111795ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn
111895ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn/*
111995ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn * Device state switch handlers.
112095ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn */
112195ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doornstatic void rt2500pci_toggle_irq(struct rt2x00_dev *rt2x00dev,
112295ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn				 enum dev_state state)
112395ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn{
1124b550911abc0db069bb157f9769ffb7cf22c6c868Helmut Schaa	int mask = (state == STATE_RADIO_IRQ_OFF);
112595ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	u32 reg;
112616222a0d06f5032d7e8bc7c65e8bf299e21f413aHelmut Schaa	unsigned long flags;
112795ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn
112895ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	/*
112995ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	 * When interrupts are being enabled, the interrupt registers
113095ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	 * should clear the register to assure a clean state.
113195ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	 */
113295ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	if (state == STATE_RADIO_IRQ_ON) {
113395ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn		rt2x00pci_register_read(rt2x00dev, CSR7, &reg);
113495ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn		rt2x00pci_register_write(rt2x00dev, CSR7, reg);
113595ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	}
113695ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn
113795ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	/*
113895ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	 * Only toggle the interrupts bits we are going to use.
113995ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	 * Non-checked interrupt bits are disabled by default.
114095ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	 */
114116222a0d06f5032d7e8bc7c65e8bf299e21f413aHelmut Schaa	spin_lock_irqsave(&rt2x00dev->irqmask_lock, flags);
114216222a0d06f5032d7e8bc7c65e8bf299e21f413aHelmut Schaa
114395ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	rt2x00pci_register_read(rt2x00dev, CSR8, &reg);
114495ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	rt2x00_set_field32(&reg, CSR8_TBCN_EXPIRE, mask);
114595ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	rt2x00_set_field32(&reg, CSR8_TXDONE_TXRING, mask);
114695ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	rt2x00_set_field32(&reg, CSR8_TXDONE_ATIMRING, mask);
114795ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	rt2x00_set_field32(&reg, CSR8_TXDONE_PRIORING, mask);
114895ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	rt2x00_set_field32(&reg, CSR8_RXDONE, mask);
114995ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	rt2x00pci_register_write(rt2x00dev, CSR8, reg);
115016222a0d06f5032d7e8bc7c65e8bf299e21f413aHelmut Schaa
115116222a0d06f5032d7e8bc7c65e8bf299e21f413aHelmut Schaa	spin_unlock_irqrestore(&rt2x00dev->irqmask_lock, flags);
115216222a0d06f5032d7e8bc7c65e8bf299e21f413aHelmut Schaa
115316222a0d06f5032d7e8bc7c65e8bf299e21f413aHelmut Schaa	if (state == STATE_RADIO_IRQ_OFF) {
115416222a0d06f5032d7e8bc7c65e8bf299e21f413aHelmut Schaa		/*
115516222a0d06f5032d7e8bc7c65e8bf299e21f413aHelmut Schaa		 * Ensure that all tasklets are finished.
115616222a0d06f5032d7e8bc7c65e8bf299e21f413aHelmut Schaa		 */
1157abc11994112bf7441519e35f51c29ff5de5b0d4dHelmut Schaa		tasklet_kill(&rt2x00dev->txstatus_tasklet);
1158abc11994112bf7441519e35f51c29ff5de5b0d4dHelmut Schaa		tasklet_kill(&rt2x00dev->rxdone_tasklet);
1159abc11994112bf7441519e35f51c29ff5de5b0d4dHelmut Schaa		tasklet_kill(&rt2x00dev->tbtt_tasklet);
116016222a0d06f5032d7e8bc7c65e8bf299e21f413aHelmut Schaa	}
116195ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn}
116295ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn
116395ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doornstatic int rt2500pci_enable_radio(struct rt2x00_dev *rt2x00dev)
116495ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn{
116595ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	/*
116695ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	 * Initialize all registers.
116795ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	 */
11682b08da3fb595432f87b5206c1c77dcb72300cacfIvo van Doorn	if (unlikely(rt2500pci_init_queues(rt2x00dev) ||
11692b08da3fb595432f87b5206c1c77dcb72300cacfIvo van Doorn		     rt2500pci_init_registers(rt2x00dev) ||
11702b08da3fb595432f87b5206c1c77dcb72300cacfIvo van Doorn		     rt2500pci_init_bbp(rt2x00dev)))
117195ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn		return -EIO;
117295ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn
117395ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	return 0;
117495ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn}
117595ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn
117695ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doornstatic void rt2500pci_disable_radio(struct rt2x00_dev *rt2x00dev)
117795ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn{
117895ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	/*
1179a2c9b652a12a550d3d8509e9bae43bac396c5076Ivo van Doorn	 * Disable power
118095ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	 */
1181a2c9b652a12a550d3d8509e9bae43bac396c5076Ivo van Doorn	rt2x00pci_register_write(rt2x00dev, PWRCSR0, 0);
118295ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn}
118395ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn
118495ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doornstatic int rt2500pci_set_state(struct rt2x00_dev *rt2x00dev,
118595ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn			       enum dev_state state)
118695ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn{
11879655a6ec19ca656af246fb80817aa337892aefbfGertjan van Wingerde	u32 reg, reg2;
118895ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	unsigned int i;
118995ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	char put_to_sleep;
119095ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	char bbp_state;
119195ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	char rf_state;
119295ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn
119395ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	put_to_sleep = (state != STATE_AWAKE);
119495ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn
119595ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	rt2x00pci_register_read(rt2x00dev, PWRCSR1, &reg);
119695ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	rt2x00_set_field32(&reg, PWRCSR1_SET_STATE, 1);
119795ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	rt2x00_set_field32(&reg, PWRCSR1_BBP_DESIRE_STATE, state);
119895ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	rt2x00_set_field32(&reg, PWRCSR1_RF_DESIRE_STATE, state);
119995ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	rt2x00_set_field32(&reg, PWRCSR1_PUT_TO_SLEEP, put_to_sleep);
120095ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	rt2x00pci_register_write(rt2x00dev, PWRCSR1, reg);
120195ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn
120295ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	/*
120395ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	 * Device is not guaranteed to be in the requested state yet.
120495ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	 * We must wait until the register indicates that the
120595ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	 * device has entered the correct state.
120695ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	 */
120795ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	for (i = 0; i < REGISTER_BUSY_COUNT; i++) {
12089655a6ec19ca656af246fb80817aa337892aefbfGertjan van Wingerde		rt2x00pci_register_read(rt2x00dev, PWRCSR1, &reg2);
12099655a6ec19ca656af246fb80817aa337892aefbfGertjan van Wingerde		bbp_state = rt2x00_get_field32(reg2, PWRCSR1_BBP_CURR_STATE);
12109655a6ec19ca656af246fb80817aa337892aefbfGertjan van Wingerde		rf_state = rt2x00_get_field32(reg2, PWRCSR1_RF_CURR_STATE);
121195ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn		if (bbp_state == state && rf_state == state)
121295ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn			return 0;
12139655a6ec19ca656af246fb80817aa337892aefbfGertjan van Wingerde		rt2x00pci_register_write(rt2x00dev, PWRCSR1, reg);
121495ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn		msleep(10);
121595ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	}
121695ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn
121795ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	return -EBUSY;
121895ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn}
121995ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn
122095ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doornstatic int rt2500pci_set_device_state(struct rt2x00_dev *rt2x00dev,
122195ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn				      enum dev_state state)
122295ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn{
122395ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	int retval = 0;
122495ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn
122595ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	switch (state) {
122695ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	case STATE_RADIO_ON:
122795ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn		retval = rt2500pci_enable_radio(rt2x00dev);
122895ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn		break;
122995ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	case STATE_RADIO_OFF:
123095ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn		rt2500pci_disable_radio(rt2x00dev);
123195ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn		break;
12322b08da3fb595432f87b5206c1c77dcb72300cacfIvo van Doorn	case STATE_RADIO_IRQ_ON:
12332b08da3fb595432f87b5206c1c77dcb72300cacfIvo van Doorn	case STATE_RADIO_IRQ_OFF:
12342b08da3fb595432f87b5206c1c77dcb72300cacfIvo van Doorn		rt2500pci_toggle_irq(rt2x00dev, state);
123595ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn		break;
123695ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	case STATE_DEEP_SLEEP:
123795ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	case STATE_SLEEP:
123895ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	case STATE_STANDBY:
123995ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	case STATE_AWAKE:
124095ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn		retval = rt2500pci_set_state(rt2x00dev, state);
124195ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn		break;
124295ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	default:
124395ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn		retval = -ENOTSUPP;
124495ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn		break;
124595ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	}
124695ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn
12472b08da3fb595432f87b5206c1c77dcb72300cacfIvo van Doorn	if (unlikely(retval))
12482b08da3fb595432f87b5206c1c77dcb72300cacfIvo van Doorn		ERROR(rt2x00dev, "Device failed to enter state %d (%d).\n",
12492b08da3fb595432f87b5206c1c77dcb72300cacfIvo van Doorn		      state, retval);
12502b08da3fb595432f87b5206c1c77dcb72300cacfIvo van Doorn
125195ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	return retval;
125295ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn}
125395ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn
125495ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn/*
125595ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn * TX descriptor initialization
125695ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn */
1257933314582ee5db00123683cf4c4d713ec9add306Ivo van Doornstatic void rt2500pci_write_tx_desc(struct queue_entry *entry,
125861486e0f68d1f8966c09b734566a187d42d65c54Ivo van Doorn				    struct txentry_desc *txdesc)
125995ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn{
1260933314582ee5db00123683cf4c4d713ec9add306Ivo van Doorn	struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb);
1261933314582ee5db00123683cf4c4d713ec9add306Ivo van Doorn	struct queue_entry_priv_pci *entry_priv = entry->priv_data;
126285b7a8b3871bde7885516fed2a1c8da699913318Gertjan van Wingerde	__le32 *txd = entry_priv->desc;
126395ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	u32 word;
126495ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn
126595ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	/*
126695ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	 * Start writing the descriptor words.
126795ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	 */
126885b7a8b3871bde7885516fed2a1c8da699913318Gertjan van Wingerde	rt2x00_desc_read(txd, 1, &word);
1269c4da004857056e6ee034c4110ccdcba659077b7eGertjan van Wingerde	rt2x00_set_field32(&word, TXD_W1_BUFFER_ADDRESS, skbdesc->skb_dma);
127085b7a8b3871bde7885516fed2a1c8da699913318Gertjan van Wingerde	rt2x00_desc_write(txd, 1, word);
12714de36fe5abe077a4c65bf0b6a309865aa043e055Gertjan van Wingerde
127295ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	rt2x00_desc_read(txd, 2, &word);
127395ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	rt2x00_set_field32(&word, TXD_W2_IV_OFFSET, IEEE80211_HEADER);
12742b23cdaa3b0e9567597563e5a7a5103ecda447f0Helmut Schaa	rt2x00_set_field32(&word, TXD_W2_AIFS, entry->queue->aifs);
12752b23cdaa3b0e9567597563e5a7a5103ecda447f0Helmut Schaa	rt2x00_set_field32(&word, TXD_W2_CWMIN, entry->queue->cw_min);
12762b23cdaa3b0e9567597563e5a7a5103ecda447f0Helmut Schaa	rt2x00_set_field32(&word, TXD_W2_CWMAX, entry->queue->cw_max);
127795ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	rt2x00_desc_write(txd, 2, word);
127895ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn
127995ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	rt2x00_desc_read(txd, 3, &word);
128026a1d07f4176099a7b6f45009dad054e6ad5b7e4Helmut Schaa	rt2x00_set_field32(&word, TXD_W3_PLCP_SIGNAL, txdesc->u.plcp.signal);
128126a1d07f4176099a7b6f45009dad054e6ad5b7e4Helmut Schaa	rt2x00_set_field32(&word, TXD_W3_PLCP_SERVICE, txdesc->u.plcp.service);
128226a1d07f4176099a7b6f45009dad054e6ad5b7e4Helmut Schaa	rt2x00_set_field32(&word, TXD_W3_PLCP_LENGTH_LOW,
128326a1d07f4176099a7b6f45009dad054e6ad5b7e4Helmut Schaa			   txdesc->u.plcp.length_low);
128426a1d07f4176099a7b6f45009dad054e6ad5b7e4Helmut Schaa	rt2x00_set_field32(&word, TXD_W3_PLCP_LENGTH_HIGH,
128526a1d07f4176099a7b6f45009dad054e6ad5b7e4Helmut Schaa			   txdesc->u.plcp.length_high);
128695ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	rt2x00_desc_write(txd, 3, word);
128795ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn
128895ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	rt2x00_desc_read(txd, 10, &word);
128995ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	rt2x00_set_field32(&word, TXD_W10_RTS,
1290181d6902b6bad978d157e69479c95cc0ff213a76Ivo van Doorn			   test_bit(ENTRY_TXD_RTS_FRAME, &txdesc->flags));
129195ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	rt2x00_desc_write(txd, 10, word);
129295ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn
1293e01f1ec35ff91c8a3f4a3e48a0c8ab476124b973Gertjan van Wingerde	/*
1294e01f1ec35ff91c8a3f4a3e48a0c8ab476124b973Gertjan van Wingerde	 * Writing TXD word 0 must the last to prevent a race condition with
1295e01f1ec35ff91c8a3f4a3e48a0c8ab476124b973Gertjan van Wingerde	 * the device, whereby the device may take hold of the TXD before we
1296e01f1ec35ff91c8a3f4a3e48a0c8ab476124b973Gertjan van Wingerde	 * finished updating it.
1297e01f1ec35ff91c8a3f4a3e48a0c8ab476124b973Gertjan van Wingerde	 */
129895ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	rt2x00_desc_read(txd, 0, &word);
129995ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	rt2x00_set_field32(&word, TXD_W0_OWNER_NIC, 1);
130095ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	rt2x00_set_field32(&word, TXD_W0_VALID, 1);
130195ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	rt2x00_set_field32(&word, TXD_W0_MORE_FRAG,
1302181d6902b6bad978d157e69479c95cc0ff213a76Ivo van Doorn			   test_bit(ENTRY_TXD_MORE_FRAG, &txdesc->flags));
130395ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	rt2x00_set_field32(&word, TXD_W0_ACK,
1304181d6902b6bad978d157e69479c95cc0ff213a76Ivo van Doorn			   test_bit(ENTRY_TXD_ACK, &txdesc->flags));
130595ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	rt2x00_set_field32(&word, TXD_W0_TIMESTAMP,
1306181d6902b6bad978d157e69479c95cc0ff213a76Ivo van Doorn			   test_bit(ENTRY_TXD_REQ_TIMESTAMP, &txdesc->flags));
130795ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	rt2x00_set_field32(&word, TXD_W0_OFDM,
1308076f9582a6b82e54339ee815130315744b730787Ivo van Doorn			   (txdesc->rate_mode == RATE_MODE_OFDM));
130995ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	rt2x00_set_field32(&word, TXD_W0_CIPHER_OWNER, 1);
13102517794b702cf62bb049e57c0825fc4573f8a6a3Helmut Schaa	rt2x00_set_field32(&word, TXD_W0_IFS, txdesc->u.plcp.ifs);
131195ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	rt2x00_set_field32(&word, TXD_W0_RETRY_MODE,
131261486e0f68d1f8966c09b734566a187d42d65c54Ivo van Doorn			   test_bit(ENTRY_TXD_RETRY_MODE, &txdesc->flags));
1313df624ca5413d84b3082246de384823fbe8fed6e4Gertjan van Wingerde	rt2x00_set_field32(&word, TXD_W0_DATABYTE_COUNT, txdesc->length);
131495ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	rt2x00_set_field32(&word, TXD_W0_CIPHER_ALG, CIPHER_NONE);
131595ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	rt2x00_desc_write(txd, 0, word);
131685b7a8b3871bde7885516fed2a1c8da699913318Gertjan van Wingerde
131785b7a8b3871bde7885516fed2a1c8da699913318Gertjan van Wingerde	/*
131885b7a8b3871bde7885516fed2a1c8da699913318Gertjan van Wingerde	 * Register descriptor details in skb frame descriptor.
131985b7a8b3871bde7885516fed2a1c8da699913318Gertjan van Wingerde	 */
132085b7a8b3871bde7885516fed2a1c8da699913318Gertjan van Wingerde	skbdesc->desc = txd;
132185b7a8b3871bde7885516fed2a1c8da699913318Gertjan van Wingerde	skbdesc->desc_len = TXD_DESC_SIZE;
132295ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn}
132395ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn
132495ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn/*
132595ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn * TX data initialization
132695ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn */
1327f224f4ef794c4a9146a7fa7303018fecab8c9328Gertjan van Wingerdestatic void rt2500pci_write_beacon(struct queue_entry *entry,
1328f224f4ef794c4a9146a7fa7303018fecab8c9328Gertjan van Wingerde				   struct txentry_desc *txdesc)
1329bd88a7812f1afd50549f3789cacb707b983fef54Ivo van Doorn{
1330bd88a7812f1afd50549f3789cacb707b983fef54Ivo van Doorn	struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
1331bd88a7812f1afd50549f3789cacb707b983fef54Ivo van Doorn	u32 reg;
1332bd88a7812f1afd50549f3789cacb707b983fef54Ivo van Doorn
1333bd88a7812f1afd50549f3789cacb707b983fef54Ivo van Doorn	/*
1334bd88a7812f1afd50549f3789cacb707b983fef54Ivo van Doorn	 * Disable beaconing while we are reloading the beacon data,
1335bd88a7812f1afd50549f3789cacb707b983fef54Ivo van Doorn	 * otherwise we might be sending out invalid data.
1336bd88a7812f1afd50549f3789cacb707b983fef54Ivo van Doorn	 */
1337bd88a7812f1afd50549f3789cacb707b983fef54Ivo van Doorn	rt2x00pci_register_read(rt2x00dev, CSR14, &reg);
1338bd88a7812f1afd50549f3789cacb707b983fef54Ivo van Doorn	rt2x00_set_field32(&reg, CSR14_BEACON_GEN, 0);
1339bd88a7812f1afd50549f3789cacb707b983fef54Ivo van Doorn	rt2x00pci_register_write(rt2x00dev, CSR14, reg);
1340bd88a7812f1afd50549f3789cacb707b983fef54Ivo van Doorn
1341fa69560f317d961c56e29dea788b346d2b34fb87Ivo van Doorn	rt2x00queue_map_txskb(entry);
1342bd88a7812f1afd50549f3789cacb707b983fef54Ivo van Doorn
13435c3b685c79f38ac6b909b3650f3dad3993614cfbGertjan van Wingerde	/*
13445c3b685c79f38ac6b909b3650f3dad3993614cfbGertjan van Wingerde	 * Write the TX descriptor for the beacon.
13455c3b685c79f38ac6b909b3650f3dad3993614cfbGertjan van Wingerde	 */
1346933314582ee5db00123683cf4c4d713ec9add306Ivo van Doorn	rt2500pci_write_tx_desc(entry, txdesc);
13475c3b685c79f38ac6b909b3650f3dad3993614cfbGertjan van Wingerde
13485c3b685c79f38ac6b909b3650f3dad3993614cfbGertjan van Wingerde	/*
13495c3b685c79f38ac6b909b3650f3dad3993614cfbGertjan van Wingerde	 * Dump beacon to userspace through debugfs.
13505c3b685c79f38ac6b909b3650f3dad3993614cfbGertjan van Wingerde	 */
13515c3b685c79f38ac6b909b3650f3dad3993614cfbGertjan van Wingerde	rt2x00debug_dump_frame(rt2x00dev, DUMP_FRAME_BEACON, entry->skb);
1352d61cb26696e19494c049297def6c8f37d9e2f534Gertjan van Wingerde
1353d61cb26696e19494c049297def6c8f37d9e2f534Gertjan van Wingerde	/*
1354d61cb26696e19494c049297def6c8f37d9e2f534Gertjan van Wingerde	 * Enable beaconing again.
1355d61cb26696e19494c049297def6c8f37d9e2f534Gertjan van Wingerde	 */
1356d61cb26696e19494c049297def6c8f37d9e2f534Gertjan van Wingerde	rt2x00_set_field32(&reg, CSR14_BEACON_GEN, 1);
1357d61cb26696e19494c049297def6c8f37d9e2f534Gertjan van Wingerde	rt2x00pci_register_write(rt2x00dev, CSR14, reg);
1358bd88a7812f1afd50549f3789cacb707b983fef54Ivo van Doorn}
1359bd88a7812f1afd50549f3789cacb707b983fef54Ivo van Doorn
136095ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn/*
136195ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn * RX control handlers
136295ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn */
1363181d6902b6bad978d157e69479c95cc0ff213a76Ivo van Doornstatic void rt2500pci_fill_rxdone(struct queue_entry *entry,
1364181d6902b6bad978d157e69479c95cc0ff213a76Ivo van Doorn				  struct rxdone_entry_desc *rxdesc)
136595ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn{
1366b8be63ffa5dc44324e7f507997870fa3e4b17619Ivo van Doorn	struct queue_entry_priv_pci *entry_priv = entry->priv_data;
136795ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	u32 word0;
136895ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	u32 word2;
136995ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn
1370b8be63ffa5dc44324e7f507997870fa3e4b17619Ivo van Doorn	rt2x00_desc_read(entry_priv->desc, 0, &word0);
1371b8be63ffa5dc44324e7f507997870fa3e4b17619Ivo van Doorn	rt2x00_desc_read(entry_priv->desc, 2, &word2);
137295ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn
13734150c57212ad134765dd78c654a4b9906252b66dJohannes Berg	if (rt2x00_get_field32(word0, RXD_W0_CRC_ERROR))
1374181d6902b6bad978d157e69479c95cc0ff213a76Ivo van Doorn		rxdesc->flags |= RX_FLAG_FAILED_FCS_CRC;
13754150c57212ad134765dd78c654a4b9906252b66dJohannes Berg	if (rt2x00_get_field32(word0, RXD_W0_PHYSICAL_ERROR))
1376181d6902b6bad978d157e69479c95cc0ff213a76Ivo van Doorn		rxdesc->flags |= RX_FLAG_FAILED_PLCP_CRC;
1377181d6902b6bad978d157e69479c95cc0ff213a76Ivo van Doorn
137889993890aeb8fe58b2d49b2661965524802ab73cIvo van Doorn	/*
137989993890aeb8fe58b2d49b2661965524802ab73cIvo van Doorn	 * Obtain the status about this packet.
138089993890aeb8fe58b2d49b2661965524802ab73cIvo van Doorn	 * When frame was received with an OFDM bitrate,
138189993890aeb8fe58b2d49b2661965524802ab73cIvo van Doorn	 * the signal is the PLCP value. If it was received with
138289993890aeb8fe58b2d49b2661965524802ab73cIvo van Doorn	 * a CCK bitrate the signal is the rate in 100kbit/s.
138389993890aeb8fe58b2d49b2661965524802ab73cIvo van Doorn	 */
1384181d6902b6bad978d157e69479c95cc0ff213a76Ivo van Doorn	rxdesc->signal = rt2x00_get_field32(word2, RXD_W2_SIGNAL);
1385181d6902b6bad978d157e69479c95cc0ff213a76Ivo van Doorn	rxdesc->rssi = rt2x00_get_field32(word2, RXD_W2_RSSI) -
1386181d6902b6bad978d157e69479c95cc0ff213a76Ivo van Doorn	    entry->queue->rt2x00dev->rssi_offset;
1387181d6902b6bad978d157e69479c95cc0ff213a76Ivo van Doorn	rxdesc->size = rt2x00_get_field32(word0, RXD_W0_DATABYTE_COUNT);
138819d30e02998ef1eb9f82a7d3ce9b4a97dba5aa13Ivo van Doorn
138919d30e02998ef1eb9f82a7d3ce9b4a97dba5aa13Ivo van Doorn	if (rt2x00_get_field32(word0, RXD_W0_OFDM))
139019d30e02998ef1eb9f82a7d3ce9b4a97dba5aa13Ivo van Doorn		rxdesc->dev_flags |= RXDONE_SIGNAL_PLCP;
13916c6aa3c004e702532cb0f549a96eb2f75636bd3bIvo van Doorn	else
13926c6aa3c004e702532cb0f549a96eb2f75636bd3bIvo van Doorn		rxdesc->dev_flags |= RXDONE_SIGNAL_BITRATE;
139319d30e02998ef1eb9f82a7d3ce9b4a97dba5aa13Ivo van Doorn	if (rt2x00_get_field32(word0, RXD_W0_MY_BSS))
139419d30e02998ef1eb9f82a7d3ce9b4a97dba5aa13Ivo van Doorn		rxdesc->dev_flags |= RXDONE_MY_BSS;
139595ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn}
139695ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn
139795ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn/*
139895ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn * Interrupt functions.
139995ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn */
1400181d6902b6bad978d157e69479c95cc0ff213a76Ivo van Doornstatic void rt2500pci_txdone(struct rt2x00_dev *rt2x00dev,
1401e58c6aca99357d7f85f18e0b661d8c5a87f926a9Ivo van Doorn			     const enum data_queue_qid queue_idx)
140295ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn{
140361c6e4893f3070b6473ca4ec3176c7471d44278bGertjan van Wingerde	struct data_queue *queue = rt2x00queue_get_tx_queue(rt2x00dev, queue_idx);
1404b8be63ffa5dc44324e7f507997870fa3e4b17619Ivo van Doorn	struct queue_entry_priv_pci *entry_priv;
1405181d6902b6bad978d157e69479c95cc0ff213a76Ivo van Doorn	struct queue_entry *entry;
1406181d6902b6bad978d157e69479c95cc0ff213a76Ivo van Doorn	struct txdone_entry_desc txdesc;
140795ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	u32 word;
140895ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn
1409181d6902b6bad978d157e69479c95cc0ff213a76Ivo van Doorn	while (!rt2x00queue_empty(queue)) {
1410181d6902b6bad978d157e69479c95cc0ff213a76Ivo van Doorn		entry = rt2x00queue_get_entry(queue, Q_INDEX_DONE);
1411b8be63ffa5dc44324e7f507997870fa3e4b17619Ivo van Doorn		entry_priv = entry->priv_data;
1412b8be63ffa5dc44324e7f507997870fa3e4b17619Ivo van Doorn		rt2x00_desc_read(entry_priv->desc, 0, &word);
141395ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn
141495ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn		if (rt2x00_get_field32(word, TXD_W0_OWNER_NIC) ||
141595ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn		    !rt2x00_get_field32(word, TXD_W0_VALID))
141695ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn			break;
141795ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn
141895ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn		/*
141995ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn		 * Obtain the status about this packet.
142095ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn		 */
1421fb55f4d1fa252ba1e479284b79da1049d658c371Ivo van Doorn		txdesc.flags = 0;
1422fb55f4d1fa252ba1e479284b79da1049d658c371Ivo van Doorn		switch (rt2x00_get_field32(word, TXD_W0_RESULT)) {
1423fb55f4d1fa252ba1e479284b79da1049d658c371Ivo van Doorn		case 0: /* Success */
1424fb55f4d1fa252ba1e479284b79da1049d658c371Ivo van Doorn		case 1: /* Success with retry */
1425fb55f4d1fa252ba1e479284b79da1049d658c371Ivo van Doorn			__set_bit(TXDONE_SUCCESS, &txdesc.flags);
1426fb55f4d1fa252ba1e479284b79da1049d658c371Ivo van Doorn			break;
1427fb55f4d1fa252ba1e479284b79da1049d658c371Ivo van Doorn		case 2: /* Failure, excessive retries */
1428fb55f4d1fa252ba1e479284b79da1049d658c371Ivo van Doorn			__set_bit(TXDONE_EXCESSIVE_RETRY, &txdesc.flags);
1429fb55f4d1fa252ba1e479284b79da1049d658c371Ivo van Doorn			/* Don't break, this is a failed frame! */
1430fb55f4d1fa252ba1e479284b79da1049d658c371Ivo van Doorn		default: /* Failure */
1431fb55f4d1fa252ba1e479284b79da1049d658c371Ivo van Doorn			__set_bit(TXDONE_FAILURE, &txdesc.flags);
1432fb55f4d1fa252ba1e479284b79da1049d658c371Ivo van Doorn		}
1433181d6902b6bad978d157e69479c95cc0ff213a76Ivo van Doorn		txdesc.retry = rt2x00_get_field32(word, TXD_W0_RETRY_COUNT);
143495ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn
1435e513a0b6f1bf8e1b59b0e1382d4e7ef3d344d535Gertjan van Wingerde		rt2x00lib_txdone(entry, &txdesc);
143695ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	}
143795ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn}
143895ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn
14397a5a681a7df7d844b52f82a4388e078071eb883eHelmut Schaastatic inline void rt2500pci_enable_interrupt(struct rt2x00_dev *rt2x00dev,
14407a5a681a7df7d844b52f82a4388e078071eb883eHelmut Schaa					      struct rt2x00_field32 irq_field)
144195ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn{
144216222a0d06f5032d7e8bc7c65e8bf299e21f413aHelmut Schaa	u32 reg;
144395ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn
144495ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	/*
144516222a0d06f5032d7e8bc7c65e8bf299e21f413aHelmut Schaa	 * Enable a single interrupt. The interrupt mask register
144616222a0d06f5032d7e8bc7c65e8bf299e21f413aHelmut Schaa	 * access needs locking.
144795ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	 */
14480aa13b2e06fbb8327c7acb4ccf684b2b65c302ceHelmut Schaa	spin_lock_irq(&rt2x00dev->irqmask_lock);
144995ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn
145016222a0d06f5032d7e8bc7c65e8bf299e21f413aHelmut Schaa	rt2x00pci_register_read(rt2x00dev, CSR8, &reg);
145116222a0d06f5032d7e8bc7c65e8bf299e21f413aHelmut Schaa	rt2x00_set_field32(&reg, irq_field, 0);
145216222a0d06f5032d7e8bc7c65e8bf299e21f413aHelmut Schaa	rt2x00pci_register_write(rt2x00dev, CSR8, reg);
145395ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn
14540aa13b2e06fbb8327c7acb4ccf684b2b65c302ceHelmut Schaa	spin_unlock_irq(&rt2x00dev->irqmask_lock);
145516222a0d06f5032d7e8bc7c65e8bf299e21f413aHelmut Schaa}
145695ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn
145716222a0d06f5032d7e8bc7c65e8bf299e21f413aHelmut Schaastatic void rt2500pci_txstatus_tasklet(unsigned long data)
145816222a0d06f5032d7e8bc7c65e8bf299e21f413aHelmut Schaa{
145916222a0d06f5032d7e8bc7c65e8bf299e21f413aHelmut Schaa	struct rt2x00_dev *rt2x00dev = (struct rt2x00_dev *)data;
146016222a0d06f5032d7e8bc7c65e8bf299e21f413aHelmut Schaa	u32 reg;
146195ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn
146295ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	/*
146316222a0d06f5032d7e8bc7c65e8bf299e21f413aHelmut Schaa	 * Handle all tx queues.
146495ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	 */
146516222a0d06f5032d7e8bc7c65e8bf299e21f413aHelmut Schaa	rt2500pci_txdone(rt2x00dev, QID_ATIM);
146616222a0d06f5032d7e8bc7c65e8bf299e21f413aHelmut Schaa	rt2500pci_txdone(rt2x00dev, QID_AC_VO);
146716222a0d06f5032d7e8bc7c65e8bf299e21f413aHelmut Schaa	rt2500pci_txdone(rt2x00dev, QID_AC_VI);
146895ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn
146995ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	/*
147016222a0d06f5032d7e8bc7c65e8bf299e21f413aHelmut Schaa	 * Enable all TXDONE interrupts again.
147195ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	 */
1472abc11994112bf7441519e35f51c29ff5de5b0d4dHelmut Schaa	if (test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags)) {
1473abc11994112bf7441519e35f51c29ff5de5b0d4dHelmut Schaa		spin_lock_irq(&rt2x00dev->irqmask_lock);
147495ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn
1475abc11994112bf7441519e35f51c29ff5de5b0d4dHelmut Schaa		rt2x00pci_register_read(rt2x00dev, CSR8, &reg);
1476abc11994112bf7441519e35f51c29ff5de5b0d4dHelmut Schaa		rt2x00_set_field32(&reg, CSR8_TXDONE_TXRING, 0);
1477abc11994112bf7441519e35f51c29ff5de5b0d4dHelmut Schaa		rt2x00_set_field32(&reg, CSR8_TXDONE_ATIMRING, 0);
1478abc11994112bf7441519e35f51c29ff5de5b0d4dHelmut Schaa		rt2x00_set_field32(&reg, CSR8_TXDONE_PRIORING, 0);
1479abc11994112bf7441519e35f51c29ff5de5b0d4dHelmut Schaa		rt2x00pci_register_write(rt2x00dev, CSR8, reg);
148078e256c9a3717bcae2e9ed05c9ec7bed7bf2c55dHelmut Schaa
1481abc11994112bf7441519e35f51c29ff5de5b0d4dHelmut Schaa		spin_unlock_irq(&rt2x00dev->irqmask_lock);
1482abc11994112bf7441519e35f51c29ff5de5b0d4dHelmut Schaa	}
148316222a0d06f5032d7e8bc7c65e8bf299e21f413aHelmut Schaa}
148416222a0d06f5032d7e8bc7c65e8bf299e21f413aHelmut Schaa
148516222a0d06f5032d7e8bc7c65e8bf299e21f413aHelmut Schaastatic void rt2500pci_tbtt_tasklet(unsigned long data)
148616222a0d06f5032d7e8bc7c65e8bf299e21f413aHelmut Schaa{
148716222a0d06f5032d7e8bc7c65e8bf299e21f413aHelmut Schaa	struct rt2x00_dev *rt2x00dev = (struct rt2x00_dev *)data;
148816222a0d06f5032d7e8bc7c65e8bf299e21f413aHelmut Schaa	rt2x00lib_beacondone(rt2x00dev);
1489abc11994112bf7441519e35f51c29ff5de5b0d4dHelmut Schaa	if (test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags))
1490abc11994112bf7441519e35f51c29ff5de5b0d4dHelmut Schaa		rt2500pci_enable_interrupt(rt2x00dev, CSR8_TBCN_EXPIRE);
149116222a0d06f5032d7e8bc7c65e8bf299e21f413aHelmut Schaa}
149216222a0d06f5032d7e8bc7c65e8bf299e21f413aHelmut Schaa
149316222a0d06f5032d7e8bc7c65e8bf299e21f413aHelmut Schaastatic void rt2500pci_rxdone_tasklet(unsigned long data)
149416222a0d06f5032d7e8bc7c65e8bf299e21f413aHelmut Schaa{
149516222a0d06f5032d7e8bc7c65e8bf299e21f413aHelmut Schaa	struct rt2x00_dev *rt2x00dev = (struct rt2x00_dev *)data;
1496166389375d5a3894aa00a9c2e490ac4b9af2a891Helmut Schaa	if (rt2x00pci_rxdone(rt2x00dev))
1497166389375d5a3894aa00a9c2e490ac4b9af2a891Helmut Schaa		tasklet_schedule(&rt2x00dev->rxdone_tasklet);
1498abc11994112bf7441519e35f51c29ff5de5b0d4dHelmut Schaa	else if (test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags))
1499166389375d5a3894aa00a9c2e490ac4b9af2a891Helmut Schaa		rt2500pci_enable_interrupt(rt2x00dev, CSR8_RXDONE);
150095ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn}
150195ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn
150278e256c9a3717bcae2e9ed05c9ec7bed7bf2c55dHelmut Schaastatic irqreturn_t rt2500pci_interrupt(int irq, void *dev_instance)
150378e256c9a3717bcae2e9ed05c9ec7bed7bf2c55dHelmut Schaa{
150478e256c9a3717bcae2e9ed05c9ec7bed7bf2c55dHelmut Schaa	struct rt2x00_dev *rt2x00dev = dev_instance;
150516222a0d06f5032d7e8bc7c65e8bf299e21f413aHelmut Schaa	u32 reg, mask;
150678e256c9a3717bcae2e9ed05c9ec7bed7bf2c55dHelmut Schaa
150778e256c9a3717bcae2e9ed05c9ec7bed7bf2c55dHelmut Schaa	/*
150878e256c9a3717bcae2e9ed05c9ec7bed7bf2c55dHelmut Schaa	 * Get the interrupt sources & saved to local variable.
150978e256c9a3717bcae2e9ed05c9ec7bed7bf2c55dHelmut Schaa	 * Write register value back to clear pending interrupts.
151078e256c9a3717bcae2e9ed05c9ec7bed7bf2c55dHelmut Schaa	 */
151178e256c9a3717bcae2e9ed05c9ec7bed7bf2c55dHelmut Schaa	rt2x00pci_register_read(rt2x00dev, CSR7, &reg);
151278e256c9a3717bcae2e9ed05c9ec7bed7bf2c55dHelmut Schaa	rt2x00pci_register_write(rt2x00dev, CSR7, reg);
151378e256c9a3717bcae2e9ed05c9ec7bed7bf2c55dHelmut Schaa
151478e256c9a3717bcae2e9ed05c9ec7bed7bf2c55dHelmut Schaa	if (!reg)
151578e256c9a3717bcae2e9ed05c9ec7bed7bf2c55dHelmut Schaa		return IRQ_NONE;
151678e256c9a3717bcae2e9ed05c9ec7bed7bf2c55dHelmut Schaa
151778e256c9a3717bcae2e9ed05c9ec7bed7bf2c55dHelmut Schaa	if (!test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags))
151878e256c9a3717bcae2e9ed05c9ec7bed7bf2c55dHelmut Schaa		return IRQ_HANDLED;
151978e256c9a3717bcae2e9ed05c9ec7bed7bf2c55dHelmut Schaa
152016222a0d06f5032d7e8bc7c65e8bf299e21f413aHelmut Schaa	mask = reg;
152116222a0d06f5032d7e8bc7c65e8bf299e21f413aHelmut Schaa
152216222a0d06f5032d7e8bc7c65e8bf299e21f413aHelmut Schaa	/*
152316222a0d06f5032d7e8bc7c65e8bf299e21f413aHelmut Schaa	 * Schedule tasklets for interrupt handling.
152416222a0d06f5032d7e8bc7c65e8bf299e21f413aHelmut Schaa	 */
152516222a0d06f5032d7e8bc7c65e8bf299e21f413aHelmut Schaa	if (rt2x00_get_field32(reg, CSR7_TBCN_EXPIRE))
152616222a0d06f5032d7e8bc7c65e8bf299e21f413aHelmut Schaa		tasklet_hi_schedule(&rt2x00dev->tbtt_tasklet);
152716222a0d06f5032d7e8bc7c65e8bf299e21f413aHelmut Schaa
152816222a0d06f5032d7e8bc7c65e8bf299e21f413aHelmut Schaa	if (rt2x00_get_field32(reg, CSR7_RXDONE))
152916222a0d06f5032d7e8bc7c65e8bf299e21f413aHelmut Schaa		tasklet_schedule(&rt2x00dev->rxdone_tasklet);
153016222a0d06f5032d7e8bc7c65e8bf299e21f413aHelmut Schaa
153116222a0d06f5032d7e8bc7c65e8bf299e21f413aHelmut Schaa	if (rt2x00_get_field32(reg, CSR7_TXDONE_ATIMRING) ||
153216222a0d06f5032d7e8bc7c65e8bf299e21f413aHelmut Schaa	    rt2x00_get_field32(reg, CSR7_TXDONE_PRIORING) ||
153316222a0d06f5032d7e8bc7c65e8bf299e21f413aHelmut Schaa	    rt2x00_get_field32(reg, CSR7_TXDONE_TXRING)) {
153416222a0d06f5032d7e8bc7c65e8bf299e21f413aHelmut Schaa		tasklet_schedule(&rt2x00dev->txstatus_tasklet);
153516222a0d06f5032d7e8bc7c65e8bf299e21f413aHelmut Schaa		/*
153616222a0d06f5032d7e8bc7c65e8bf299e21f413aHelmut Schaa		 * Mask out all txdone interrupts.
153716222a0d06f5032d7e8bc7c65e8bf299e21f413aHelmut Schaa		 */
153816222a0d06f5032d7e8bc7c65e8bf299e21f413aHelmut Schaa		rt2x00_set_field32(&mask, CSR8_TXDONE_TXRING, 1);
153916222a0d06f5032d7e8bc7c65e8bf299e21f413aHelmut Schaa		rt2x00_set_field32(&mask, CSR8_TXDONE_ATIMRING, 1);
154016222a0d06f5032d7e8bc7c65e8bf299e21f413aHelmut Schaa		rt2x00_set_field32(&mask, CSR8_TXDONE_PRIORING, 1);
154116222a0d06f5032d7e8bc7c65e8bf299e21f413aHelmut Schaa	}
154216222a0d06f5032d7e8bc7c65e8bf299e21f413aHelmut Schaa
154316222a0d06f5032d7e8bc7c65e8bf299e21f413aHelmut Schaa	/*
154416222a0d06f5032d7e8bc7c65e8bf299e21f413aHelmut Schaa	 * Disable all interrupts for which a tasklet was scheduled right now,
154516222a0d06f5032d7e8bc7c65e8bf299e21f413aHelmut Schaa	 * the tasklet will reenable the appropriate interrupts.
154616222a0d06f5032d7e8bc7c65e8bf299e21f413aHelmut Schaa	 */
15470aa13b2e06fbb8327c7acb4ccf684b2b65c302ceHelmut Schaa	spin_lock(&rt2x00dev->irqmask_lock);
154878e256c9a3717bcae2e9ed05c9ec7bed7bf2c55dHelmut Schaa
154916222a0d06f5032d7e8bc7c65e8bf299e21f413aHelmut Schaa	rt2x00pci_register_read(rt2x00dev, CSR8, &reg);
155016222a0d06f5032d7e8bc7c65e8bf299e21f413aHelmut Schaa	reg |= mask;
155116222a0d06f5032d7e8bc7c65e8bf299e21f413aHelmut Schaa	rt2x00pci_register_write(rt2x00dev, CSR8, reg);
155216222a0d06f5032d7e8bc7c65e8bf299e21f413aHelmut Schaa
15530aa13b2e06fbb8327c7acb4ccf684b2b65c302ceHelmut Schaa	spin_unlock(&rt2x00dev->irqmask_lock);
155478e256c9a3717bcae2e9ed05c9ec7bed7bf2c55dHelmut Schaa
155516222a0d06f5032d7e8bc7c65e8bf299e21f413aHelmut Schaa	return IRQ_HANDLED;
155678e256c9a3717bcae2e9ed05c9ec7bed7bf2c55dHelmut Schaa}
155778e256c9a3717bcae2e9ed05c9ec7bed7bf2c55dHelmut Schaa
155895ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn/*
155995ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn * Device probe functions.
156095ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn */
156195ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doornstatic int rt2500pci_validate_eeprom(struct rt2x00_dev *rt2x00dev)
156295ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn{
156395ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	struct eeprom_93cx6 eeprom;
156495ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	u32 reg;
156595ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	u16 word;
156695ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	u8 *mac;
156795ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn
156895ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	rt2x00pci_register_read(rt2x00dev, CSR21, &reg);
156995ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn
157095ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	eeprom.data = rt2x00dev;
157195ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	eeprom.register_read = rt2500pci_eepromregister_read;
157295ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	eeprom.register_write = rt2500pci_eepromregister_write;
157395ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	eeprom.width = rt2x00_get_field32(reg, CSR21_TYPE_93C46) ?
157495ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	    PCI_EEPROM_WIDTH_93C46 : PCI_EEPROM_WIDTH_93C66;
157595ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	eeprom.reg_data_in = 0;
157695ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	eeprom.reg_data_out = 0;
157795ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	eeprom.reg_data_clock = 0;
157895ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	eeprom.reg_chip_select = 0;
157995ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn
158095ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	eeprom_93cx6_multiread(&eeprom, EEPROM_BASE, rt2x00dev->eeprom,
158195ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn			       EEPROM_SIZE / sizeof(u16));
158295ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn
158395ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	/*
158495ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	 * Start validation of the data that has been read.
158595ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	 */
158695ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	mac = rt2x00_eeprom_addr(rt2x00dev, EEPROM_MAC_ADDR_0);
158795ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	if (!is_valid_ether_addr(mac)) {
158895ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn		random_ether_addr(mac);
1589e174961ca1a0b28f7abf0be47973ad57cb74e5f0Johannes Berg		EEPROM(rt2x00dev, "MAC: %pM\n", mac);
159095ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	}
159195ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn
159295ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	rt2x00_eeprom_read(rt2x00dev, EEPROM_ANTENNA, &word);
159395ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	if (word == 0xffff) {
159495ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn		rt2x00_set_field16(&word, EEPROM_ANTENNA_NUM, 2);
1595362f3b6bfbb18b4b8bd8a8ef391fb95efb43c632Ivo van Doorn		rt2x00_set_field16(&word, EEPROM_ANTENNA_TX_DEFAULT,
1596362f3b6bfbb18b4b8bd8a8ef391fb95efb43c632Ivo van Doorn				   ANTENNA_SW_DIVERSITY);
1597362f3b6bfbb18b4b8bd8a8ef391fb95efb43c632Ivo van Doorn		rt2x00_set_field16(&word, EEPROM_ANTENNA_RX_DEFAULT,
1598362f3b6bfbb18b4b8bd8a8ef391fb95efb43c632Ivo van Doorn				   ANTENNA_SW_DIVERSITY);
1599362f3b6bfbb18b4b8bd8a8ef391fb95efb43c632Ivo van Doorn		rt2x00_set_field16(&word, EEPROM_ANTENNA_LED_MODE,
1600362f3b6bfbb18b4b8bd8a8ef391fb95efb43c632Ivo van Doorn				   LED_MODE_DEFAULT);
160195ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn		rt2x00_set_field16(&word, EEPROM_ANTENNA_DYN_TXAGC, 0);
160295ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn		rt2x00_set_field16(&word, EEPROM_ANTENNA_HARDWARE_RADIO, 0);
160395ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn		rt2x00_set_field16(&word, EEPROM_ANTENNA_RF_TYPE, RF2522);
160495ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn		rt2x00_eeprom_write(rt2x00dev, EEPROM_ANTENNA, word);
160595ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn		EEPROM(rt2x00dev, "Antenna: 0x%04x\n", word);
160695ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	}
160795ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn
160895ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC, &word);
160995ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	if (word == 0xffff) {
161095ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn		rt2x00_set_field16(&word, EEPROM_NIC_CARDBUS_ACCEL, 0);
161195ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn		rt2x00_set_field16(&word, EEPROM_NIC_DYN_BBP_TUNE, 0);
161295ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn		rt2x00_set_field16(&word, EEPROM_NIC_CCK_TX_POWER, 0);
161395ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn		rt2x00_eeprom_write(rt2x00dev, EEPROM_NIC, word);
161495ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn		EEPROM(rt2x00dev, "NIC: 0x%04x\n", word);
161595ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	}
161695ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn
161795ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	rt2x00_eeprom_read(rt2x00dev, EEPROM_CALIBRATE_OFFSET, &word);
161895ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	if (word == 0xffff) {
161995ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn		rt2x00_set_field16(&word, EEPROM_CALIBRATE_OFFSET_RSSI,
162095ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn				   DEFAULT_RSSI_OFFSET);
162195ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn		rt2x00_eeprom_write(rt2x00dev, EEPROM_CALIBRATE_OFFSET, word);
162295ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn		EEPROM(rt2x00dev, "Calibrate offset: 0x%04x\n", word);
162395ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	}
162495ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn
162595ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	return 0;
162695ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn}
162795ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn
162895ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doornstatic int rt2500pci_init_eeprom(struct rt2x00_dev *rt2x00dev)
162995ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn{
163095ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	u32 reg;
163195ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	u16 value;
163295ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	u16 eeprom;
163395ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn
163495ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	/*
163595ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	 * Read EEPROM word for configuration.
163695ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	 */
163795ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	rt2x00_eeprom_read(rt2x00dev, EEPROM_ANTENNA, &eeprom);
163895ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn
163995ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	/*
164095ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	 * Identify RF chipset.
164195ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	 */
164295ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	value = rt2x00_get_field16(eeprom, EEPROM_ANTENNA_RF_TYPE);
164395ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	rt2x00pci_register_read(rt2x00dev, CSR0, &reg);
164449e721ec6ca74f90ee99089ad2de1c338a95c6d5Gertjan van Wingerde	rt2x00_set_chip(rt2x00dev, RT2560, value,
164549e721ec6ca74f90ee99089ad2de1c338a95c6d5Gertjan van Wingerde			rt2x00_get_field32(reg, CSR0_REVISION));
164695ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn
16475122d8986232ef2a761f5cf70c31666c4d65c3e4Gertjan van Wingerde	if (!rt2x00_rf(rt2x00dev, RF2522) &&
16485122d8986232ef2a761f5cf70c31666c4d65c3e4Gertjan van Wingerde	    !rt2x00_rf(rt2x00dev, RF2523) &&
16495122d8986232ef2a761f5cf70c31666c4d65c3e4Gertjan van Wingerde	    !rt2x00_rf(rt2x00dev, RF2524) &&
16505122d8986232ef2a761f5cf70c31666c4d65c3e4Gertjan van Wingerde	    !rt2x00_rf(rt2x00dev, RF2525) &&
16515122d8986232ef2a761f5cf70c31666c4d65c3e4Gertjan van Wingerde	    !rt2x00_rf(rt2x00dev, RF2525E) &&
16525122d8986232ef2a761f5cf70c31666c4d65c3e4Gertjan van Wingerde	    !rt2x00_rf(rt2x00dev, RF5222)) {
165395ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn		ERROR(rt2x00dev, "Invalid RF chipset detected.\n");
165495ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn		return -ENODEV;
165595ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	}
165695ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn
165795ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	/*
165895ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	 * Identify default antenna configuration.
165995ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	 */
1660addc81bd428f9eb29ed2ab64ad4039c6aed55aeaIvo van Doorn	rt2x00dev->default_ant.tx =
166195ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	    rt2x00_get_field16(eeprom, EEPROM_ANTENNA_TX_DEFAULT);
1662addc81bd428f9eb29ed2ab64ad4039c6aed55aeaIvo van Doorn	rt2x00dev->default_ant.rx =
166395ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	    rt2x00_get_field16(eeprom, EEPROM_ANTENNA_RX_DEFAULT);
166495ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn
166595ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	/*
166695ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	 * Store led mode, for correct led behaviour.
166795ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	 */
1668771fd565195727d12f0b75d918b9fcb9f33a5476Ivo van Doorn#ifdef CONFIG_RT2X00_LIB_LEDS
1669a9450b70a755abf093600035ef5361c53343fe9aIvo van Doorn	value = rt2x00_get_field16(eeprom, EEPROM_ANTENNA_LED_MODE);
1670a9450b70a755abf093600035ef5361c53343fe9aIvo van Doorn
1671475433be3d8f4d840e2930eef96671b7f8d11053Ivo van Doorn	rt2500pci_init_led(rt2x00dev, &rt2x00dev->led_radio, LED_TYPE_RADIO);
16723d3e451ff71b4e951d4b522b460a94f36fb5b276Ivo van Doorn	if (value == LED_MODE_TXRX_ACTIVITY ||
16733d3e451ff71b4e951d4b522b460a94f36fb5b276Ivo van Doorn	    value == LED_MODE_DEFAULT ||
16743d3e451ff71b4e951d4b522b460a94f36fb5b276Ivo van Doorn	    value == LED_MODE_ASUS)
1675475433be3d8f4d840e2930eef96671b7f8d11053Ivo van Doorn		rt2500pci_init_led(rt2x00dev, &rt2x00dev->led_qual,
1676475433be3d8f4d840e2930eef96671b7f8d11053Ivo van Doorn				   LED_TYPE_ACTIVITY);
1677771fd565195727d12f0b75d918b9fcb9f33a5476Ivo van Doorn#endif /* CONFIG_RT2X00_LIB_LEDS */
167895ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn
167995ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	/*
168095ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	 * Detect if this device has an hardware controlled radio.
168195ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	 */
168295ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	if (rt2x00_get_field16(eeprom, EEPROM_ANTENNA_HARDWARE_RADIO))
16837dab73b37f5e8885cb73efd25e73861f9b4f0246Ivo van Doorn		__set_bit(CAPABILITY_HW_BUTTON, &rt2x00dev->cap_flags);
168495ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn
168595ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	/*
168695ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	 * Check if the BBP tuning should be enabled.
168795ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	 */
168895ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC, &eeprom);
168927df2a9ce9ea6a77b9959cf5cc03ee85324aced9Ivo van Doorn	if (!rt2x00_get_field16(eeprom, EEPROM_NIC_DYN_BBP_TUNE))
16907dab73b37f5e8885cb73efd25e73861f9b4f0246Ivo van Doorn		__set_bit(CAPABILITY_LINK_TUNING, &rt2x00dev->cap_flags);
169195ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn
169295ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	/*
169395ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	 * Read the RSSI <-> dBm offset information.
169495ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	 */
169595ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	rt2x00_eeprom_read(rt2x00dev, EEPROM_CALIBRATE_OFFSET, &eeprom);
169695ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	rt2x00dev->rssi_offset =
169795ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	    rt2x00_get_field16(eeprom, EEPROM_CALIBRATE_OFFSET_RSSI);
169895ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn
169995ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	return 0;
170095ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn}
170195ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn
170295ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn/*
170395ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn * RF value list for RF2522
170495ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn * Supports: 2.4 GHz
170595ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn */
170695ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doornstatic const struct rf_channel rf_vals_bg_2522[] = {
170795ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	{ 1,  0x00002050, 0x000c1fda, 0x00000101, 0 },
170895ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	{ 2,  0x00002050, 0x000c1fee, 0x00000101, 0 },
170995ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	{ 3,  0x00002050, 0x000c2002, 0x00000101, 0 },
171095ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	{ 4,  0x00002050, 0x000c2016, 0x00000101, 0 },
171195ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	{ 5,  0x00002050, 0x000c202a, 0x00000101, 0 },
171295ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	{ 6,  0x00002050, 0x000c203e, 0x00000101, 0 },
171395ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	{ 7,  0x00002050, 0x000c2052, 0x00000101, 0 },
171495ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	{ 8,  0x00002050, 0x000c2066, 0x00000101, 0 },
171595ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	{ 9,  0x00002050, 0x000c207a, 0x00000101, 0 },
171695ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	{ 10, 0x00002050, 0x000c208e, 0x00000101, 0 },
171795ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	{ 11, 0x00002050, 0x000c20a2, 0x00000101, 0 },
171895ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	{ 12, 0x00002050, 0x000c20b6, 0x00000101, 0 },
171995ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	{ 13, 0x00002050, 0x000c20ca, 0x00000101, 0 },
172095ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	{ 14, 0x00002050, 0x000c20fa, 0x00000101, 0 },
172195ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn};
172295ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn
172395ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn/*
172495ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn * RF value list for RF2523
172595ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn * Supports: 2.4 GHz
172695ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn */
172795ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doornstatic const struct rf_channel rf_vals_bg_2523[] = {
172895ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	{ 1,  0x00022010, 0x00000c9e, 0x000e0111, 0x00000a1b },
172995ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	{ 2,  0x00022010, 0x00000ca2, 0x000e0111, 0x00000a1b },
173095ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	{ 3,  0x00022010, 0x00000ca6, 0x000e0111, 0x00000a1b },
173195ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	{ 4,  0x00022010, 0x00000caa, 0x000e0111, 0x00000a1b },
173295ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	{ 5,  0x00022010, 0x00000cae, 0x000e0111, 0x00000a1b },
173395ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	{ 6,  0x00022010, 0x00000cb2, 0x000e0111, 0x00000a1b },
173495ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	{ 7,  0x00022010, 0x00000cb6, 0x000e0111, 0x00000a1b },
173595ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	{ 8,  0x00022010, 0x00000cba, 0x000e0111, 0x00000a1b },
173695ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	{ 9,  0x00022010, 0x00000cbe, 0x000e0111, 0x00000a1b },
173795ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	{ 10, 0x00022010, 0x00000d02, 0x000e0111, 0x00000a1b },
173895ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	{ 11, 0x00022010, 0x00000d06, 0x000e0111, 0x00000a1b },
173995ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	{ 12, 0x00022010, 0x00000d0a, 0x000e0111, 0x00000a1b },
174095ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	{ 13, 0x00022010, 0x00000d0e, 0x000e0111, 0x00000a1b },
174195ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	{ 14, 0x00022010, 0x00000d1a, 0x000e0111, 0x00000a03 },
174295ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn};
174395ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn
174495ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn/*
174595ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn * RF value list for RF2524
174695ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn * Supports: 2.4 GHz
174795ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn */
174895ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doornstatic const struct rf_channel rf_vals_bg_2524[] = {
174995ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	{ 1,  0x00032020, 0x00000c9e, 0x00000101, 0x00000a1b },
175095ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	{ 2,  0x00032020, 0x00000ca2, 0x00000101, 0x00000a1b },
175195ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	{ 3,  0x00032020, 0x00000ca6, 0x00000101, 0x00000a1b },
175295ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	{ 4,  0x00032020, 0x00000caa, 0x00000101, 0x00000a1b },
175395ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	{ 5,  0x00032020, 0x00000cae, 0x00000101, 0x00000a1b },
175495ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	{ 6,  0x00032020, 0x00000cb2, 0x00000101, 0x00000a1b },
175595ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	{ 7,  0x00032020, 0x00000cb6, 0x00000101, 0x00000a1b },
175695ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	{ 8,  0x00032020, 0x00000cba, 0x00000101, 0x00000a1b },
175795ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	{ 9,  0x00032020, 0x00000cbe, 0x00000101, 0x00000a1b },
175895ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	{ 10, 0x00032020, 0x00000d02, 0x00000101, 0x00000a1b },
175995ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	{ 11, 0x00032020, 0x00000d06, 0x00000101, 0x00000a1b },
176095ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	{ 12, 0x00032020, 0x00000d0a, 0x00000101, 0x00000a1b },
176195ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	{ 13, 0x00032020, 0x00000d0e, 0x00000101, 0x00000a1b },
176295ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	{ 14, 0x00032020, 0x00000d1a, 0x00000101, 0x00000a03 },
176395ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn};
176495ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn
176595ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn/*
176695ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn * RF value list for RF2525
176795ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn * Supports: 2.4 GHz
176895ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn */
176995ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doornstatic const struct rf_channel rf_vals_bg_2525[] = {
177095ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	{ 1,  0x00022020, 0x00080c9e, 0x00060111, 0x00000a1b },
177195ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	{ 2,  0x00022020, 0x00080ca2, 0x00060111, 0x00000a1b },
177295ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	{ 3,  0x00022020, 0x00080ca6, 0x00060111, 0x00000a1b },
177395ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	{ 4,  0x00022020, 0x00080caa, 0x00060111, 0x00000a1b },
177495ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	{ 5,  0x00022020, 0x00080cae, 0x00060111, 0x00000a1b },
177595ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	{ 6,  0x00022020, 0x00080cb2, 0x00060111, 0x00000a1b },
177695ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	{ 7,  0x00022020, 0x00080cb6, 0x00060111, 0x00000a1b },
177795ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	{ 8,  0x00022020, 0x00080cba, 0x00060111, 0x00000a1b },
177895ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	{ 9,  0x00022020, 0x00080cbe, 0x00060111, 0x00000a1b },
177995ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	{ 10, 0x00022020, 0x00080d02, 0x00060111, 0x00000a1b },
178095ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	{ 11, 0x00022020, 0x00080d06, 0x00060111, 0x00000a1b },
178195ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	{ 12, 0x00022020, 0x00080d0a, 0x00060111, 0x00000a1b },
178295ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	{ 13, 0x00022020, 0x00080d0e, 0x00060111, 0x00000a1b },
178395ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	{ 14, 0x00022020, 0x00080d1a, 0x00060111, 0x00000a03 },
178495ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn};
178595ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn
178695ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn/*
178795ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn * RF value list for RF2525e
178895ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn * Supports: 2.4 GHz
178995ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn */
179095ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doornstatic const struct rf_channel rf_vals_bg_2525e[] = {
179195ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	{ 1,  0x00022020, 0x00081136, 0x00060111, 0x00000a0b },
179295ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	{ 2,  0x00022020, 0x0008113a, 0x00060111, 0x00000a0b },
179395ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	{ 3,  0x00022020, 0x0008113e, 0x00060111, 0x00000a0b },
179495ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	{ 4,  0x00022020, 0x00081182, 0x00060111, 0x00000a0b },
179595ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	{ 5,  0x00022020, 0x00081186, 0x00060111, 0x00000a0b },
179695ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	{ 6,  0x00022020, 0x0008118a, 0x00060111, 0x00000a0b },
179795ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	{ 7,  0x00022020, 0x0008118e, 0x00060111, 0x00000a0b },
179895ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	{ 8,  0x00022020, 0x00081192, 0x00060111, 0x00000a0b },
179995ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	{ 9,  0x00022020, 0x00081196, 0x00060111, 0x00000a0b },
180095ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	{ 10, 0x00022020, 0x0008119a, 0x00060111, 0x00000a0b },
180195ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	{ 11, 0x00022020, 0x0008119e, 0x00060111, 0x00000a0b },
180295ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	{ 12, 0x00022020, 0x000811a2, 0x00060111, 0x00000a0b },
180395ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	{ 13, 0x00022020, 0x000811a6, 0x00060111, 0x00000a0b },
180495ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	{ 14, 0x00022020, 0x000811ae, 0x00060111, 0x00000a1b },
180595ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn};
180695ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn
180795ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn/*
180895ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn * RF value list for RF5222
180995ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn * Supports: 2.4 GHz & 5.2 GHz
181095ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn */
181195ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doornstatic const struct rf_channel rf_vals_5222[] = {
181295ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	{ 1,  0x00022020, 0x00001136, 0x00000101, 0x00000a0b },
181395ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	{ 2,  0x00022020, 0x0000113a, 0x00000101, 0x00000a0b },
181495ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	{ 3,  0x00022020, 0x0000113e, 0x00000101, 0x00000a0b },
181595ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	{ 4,  0x00022020, 0x00001182, 0x00000101, 0x00000a0b },
181695ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	{ 5,  0x00022020, 0x00001186, 0x00000101, 0x00000a0b },
181795ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	{ 6,  0x00022020, 0x0000118a, 0x00000101, 0x00000a0b },
181895ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	{ 7,  0x00022020, 0x0000118e, 0x00000101, 0x00000a0b },
181995ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	{ 8,  0x00022020, 0x00001192, 0x00000101, 0x00000a0b },
182095ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	{ 9,  0x00022020, 0x00001196, 0x00000101, 0x00000a0b },
182195ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	{ 10, 0x00022020, 0x0000119a, 0x00000101, 0x00000a0b },
182295ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	{ 11, 0x00022020, 0x0000119e, 0x00000101, 0x00000a0b },
182395ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	{ 12, 0x00022020, 0x000011a2, 0x00000101, 0x00000a0b },
182495ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	{ 13, 0x00022020, 0x000011a6, 0x00000101, 0x00000a0b },
182595ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	{ 14, 0x00022020, 0x000011ae, 0x00000101, 0x00000a1b },
182695ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn
182795ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	/* 802.11 UNI / HyperLan 2 */
182895ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	{ 36, 0x00022010, 0x00018896, 0x00000101, 0x00000a1f },
182995ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	{ 40, 0x00022010, 0x0001889a, 0x00000101, 0x00000a1f },
183095ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	{ 44, 0x00022010, 0x0001889e, 0x00000101, 0x00000a1f },
183195ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	{ 48, 0x00022010, 0x000188a2, 0x00000101, 0x00000a1f },
183295ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	{ 52, 0x00022010, 0x000188a6, 0x00000101, 0x00000a1f },
183395ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	{ 66, 0x00022010, 0x000188aa, 0x00000101, 0x00000a1f },
183495ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	{ 60, 0x00022010, 0x000188ae, 0x00000101, 0x00000a1f },
183595ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	{ 64, 0x00022010, 0x000188b2, 0x00000101, 0x00000a1f },
183695ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn
183795ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	/* 802.11 HyperLan 2 */
183895ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	{ 100, 0x00022010, 0x00008802, 0x00000101, 0x00000a0f },
183995ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	{ 104, 0x00022010, 0x00008806, 0x00000101, 0x00000a0f },
184095ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	{ 108, 0x00022010, 0x0000880a, 0x00000101, 0x00000a0f },
184195ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	{ 112, 0x00022010, 0x0000880e, 0x00000101, 0x00000a0f },
184295ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	{ 116, 0x00022010, 0x00008812, 0x00000101, 0x00000a0f },
184395ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	{ 120, 0x00022010, 0x00008816, 0x00000101, 0x00000a0f },
184495ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	{ 124, 0x00022010, 0x0000881a, 0x00000101, 0x00000a0f },
184595ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	{ 128, 0x00022010, 0x0000881e, 0x00000101, 0x00000a0f },
184695ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	{ 132, 0x00022010, 0x00008822, 0x00000101, 0x00000a0f },
184795ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	{ 136, 0x00022010, 0x00008826, 0x00000101, 0x00000a0f },
184895ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn
184995ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	/* 802.11 UNII */
185095ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	{ 140, 0x00022010, 0x0000882a, 0x00000101, 0x00000a0f },
185195ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	{ 149, 0x00022020, 0x000090a6, 0x00000101, 0x00000a07 },
185295ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	{ 153, 0x00022020, 0x000090ae, 0x00000101, 0x00000a07 },
185395ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	{ 157, 0x00022020, 0x000090b6, 0x00000101, 0x00000a07 },
185495ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	{ 161, 0x00022020, 0x000090be, 0x00000101, 0x00000a07 },
185595ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn};
185695ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn
18578c5e7a5f59f9d11597bd47de28334da318ea0e80Ivo van Doornstatic int rt2500pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
185895ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn{
185995ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	struct hw_mode_spec *spec = &rt2x00dev->spec;
18608c5e7a5f59f9d11597bd47de28334da318ea0e80Ivo van Doorn	struct channel_info *info;
18618c5e7a5f59f9d11597bd47de28334da318ea0e80Ivo van Doorn	char *tx_power;
186295ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	unsigned int i;
186395ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn
186495ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	/*
186595ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	 * Initialize all hw fields.
186695ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	 */
1867566bfe5a8bcde13188a356f77666f8115813cf31Bruno Randolf	rt2x00dev->hw->flags = IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING |
18684be8c3873e0b88397866d3ede578503e188f9ad2Johannes Berg			       IEEE80211_HW_SIGNAL_DBM |
18694be8c3873e0b88397866d3ede578503e188f9ad2Johannes Berg			       IEEE80211_HW_SUPPORTS_PS |
18704be8c3873e0b88397866d3ede578503e188f9ad2Johannes Berg			       IEEE80211_HW_PS_NULLFUNC_STACK;
1871566bfe5a8bcde13188a356f77666f8115813cf31Bruno Randolf
187214a3bf89212b5c758bd39bb4afc972c4ba6d599fGertjan van Wingerde	SET_IEEE80211_DEV(rt2x00dev->hw, rt2x00dev->dev);
187395ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	SET_IEEE80211_PERM_ADDR(rt2x00dev->hw,
187495ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn				rt2x00_eeprom_addr(rt2x00dev,
187595ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn						   EEPROM_MAC_ADDR_0));
187695ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn
187795ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	/*
187895ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	 * Initialize hw_mode information.
187995ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	 */
188031562e802a72caf0757f351fff563d558d48d087Ivo van Doorn	spec->supported_bands = SUPPORT_BAND_2GHZ;
188131562e802a72caf0757f351fff563d558d48d087Ivo van Doorn	spec->supported_rates = SUPPORT_RATE_CCK | SUPPORT_RATE_OFDM;
188295ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn
18835122d8986232ef2a761f5cf70c31666c4d65c3e4Gertjan van Wingerde	if (rt2x00_rf(rt2x00dev, RF2522)) {
188495ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn		spec->num_channels = ARRAY_SIZE(rf_vals_bg_2522);
188595ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn		spec->channels = rf_vals_bg_2522;
18865122d8986232ef2a761f5cf70c31666c4d65c3e4Gertjan van Wingerde	} else if (rt2x00_rf(rt2x00dev, RF2523)) {
188795ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn		spec->num_channels = ARRAY_SIZE(rf_vals_bg_2523);
188895ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn		spec->channels = rf_vals_bg_2523;
18895122d8986232ef2a761f5cf70c31666c4d65c3e4Gertjan van Wingerde	} else if (rt2x00_rf(rt2x00dev, RF2524)) {
189095ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn		spec->num_channels = ARRAY_SIZE(rf_vals_bg_2524);
189195ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn		spec->channels = rf_vals_bg_2524;
18925122d8986232ef2a761f5cf70c31666c4d65c3e4Gertjan van Wingerde	} else if (rt2x00_rf(rt2x00dev, RF2525)) {
189395ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn		spec->num_channels = ARRAY_SIZE(rf_vals_bg_2525);
189495ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn		spec->channels = rf_vals_bg_2525;
18955122d8986232ef2a761f5cf70c31666c4d65c3e4Gertjan van Wingerde	} else if (rt2x00_rf(rt2x00dev, RF2525E)) {
189695ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn		spec->num_channels = ARRAY_SIZE(rf_vals_bg_2525e);
189795ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn		spec->channels = rf_vals_bg_2525e;
18985122d8986232ef2a761f5cf70c31666c4d65c3e4Gertjan van Wingerde	} else if (rt2x00_rf(rt2x00dev, RF5222)) {
189931562e802a72caf0757f351fff563d558d48d087Ivo van Doorn		spec->supported_bands |= SUPPORT_BAND_5GHZ;
190095ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn		spec->num_channels = ARRAY_SIZE(rf_vals_5222);
190195ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn		spec->channels = rf_vals_5222;
190295ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	}
19038c5e7a5f59f9d11597bd47de28334da318ea0e80Ivo van Doorn
19048c5e7a5f59f9d11597bd47de28334da318ea0e80Ivo van Doorn	/*
19058c5e7a5f59f9d11597bd47de28334da318ea0e80Ivo van Doorn	 * Create channel information array
19068c5e7a5f59f9d11597bd47de28334da318ea0e80Ivo van Doorn	 */
1907baeb2ffab4e67bb9174e6166e070a9a8ec94b0f6Joe Perches	info = kcalloc(spec->num_channels, sizeof(*info), GFP_KERNEL);
19088c5e7a5f59f9d11597bd47de28334da318ea0e80Ivo van Doorn	if (!info)
19098c5e7a5f59f9d11597bd47de28334da318ea0e80Ivo van Doorn		return -ENOMEM;
19108c5e7a5f59f9d11597bd47de28334da318ea0e80Ivo van Doorn
19118c5e7a5f59f9d11597bd47de28334da318ea0e80Ivo van Doorn	spec->channels_info = info;
19128c5e7a5f59f9d11597bd47de28334da318ea0e80Ivo van Doorn
19138c5e7a5f59f9d11597bd47de28334da318ea0e80Ivo van Doorn	tx_power = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_START);
19148d1331b37d5b656a7a8e561f8e9d7661dd00c910Ivo van Doorn	for (i = 0; i < 14; i++) {
19158d1331b37d5b656a7a8e561f8e9d7661dd00c910Ivo van Doorn		info[i].max_power = MAX_TXPOWER;
19168d1331b37d5b656a7a8e561f8e9d7661dd00c910Ivo van Doorn		info[i].default_power1 = TXPOWER_FROM_DEV(tx_power[i]);
19178d1331b37d5b656a7a8e561f8e9d7661dd00c910Ivo van Doorn	}
19188c5e7a5f59f9d11597bd47de28334da318ea0e80Ivo van Doorn
19198c5e7a5f59f9d11597bd47de28334da318ea0e80Ivo van Doorn	if (spec->num_channels > 14) {
19208d1331b37d5b656a7a8e561f8e9d7661dd00c910Ivo van Doorn		for (i = 14; i < spec->num_channels; i++) {
19218d1331b37d5b656a7a8e561f8e9d7661dd00c910Ivo van Doorn			info[i].max_power = MAX_TXPOWER;
19228d1331b37d5b656a7a8e561f8e9d7661dd00c910Ivo van Doorn			info[i].default_power1 = DEFAULT_TXPOWER;
19238d1331b37d5b656a7a8e561f8e9d7661dd00c910Ivo van Doorn		}
19248c5e7a5f59f9d11597bd47de28334da318ea0e80Ivo van Doorn	}
19258c5e7a5f59f9d11597bd47de28334da318ea0e80Ivo van Doorn
19268c5e7a5f59f9d11597bd47de28334da318ea0e80Ivo van Doorn	return 0;
192795ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn}
192895ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn
192995ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doornstatic int rt2500pci_probe_hw(struct rt2x00_dev *rt2x00dev)
193095ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn{
193195ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	int retval;
193295ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn
193395ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	/*
193495ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	 * Allocate eeprom data.
193595ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	 */
193695ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	retval = rt2500pci_validate_eeprom(rt2x00dev);
193795ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	if (retval)
193895ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn		return retval;
193995ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn
194095ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	retval = rt2500pci_init_eeprom(rt2x00dev);
194195ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	if (retval)
194295ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn		return retval;
194395ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn
194495ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	/*
194595ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	 * Initialize hw specifications.
194695ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	 */
19478c5e7a5f59f9d11597bd47de28334da318ea0e80Ivo van Doorn	retval = rt2500pci_probe_hw_mode(rt2x00dev);
19488c5e7a5f59f9d11597bd47de28334da318ea0e80Ivo van Doorn	if (retval)
19498c5e7a5f59f9d11597bd47de28334da318ea0e80Ivo van Doorn		return retval;
195095ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn
195195ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	/*
1952c4da004857056e6ee034c4110ccdcba659077b7eGertjan van Wingerde	 * This device requires the atim queue and DMA-mapped skbs.
195395ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	 */
19547dab73b37f5e8885cb73efd25e73861f9b4f0246Ivo van Doorn	__set_bit(REQUIRE_ATIM_QUEUE, &rt2x00dev->cap_flags);
19557dab73b37f5e8885cb73efd25e73861f9b4f0246Ivo van Doorn	__set_bit(REQUIRE_DMA, &rt2x00dev->cap_flags);
19567dab73b37f5e8885cb73efd25e73861f9b4f0246Ivo van Doorn	__set_bit(REQUIRE_SW_SEQNO, &rt2x00dev->cap_flags);
195795ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn
195895ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	/*
195995ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	 * Set the rssi offset.
196095ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	 */
196195ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	rt2x00dev->rssi_offset = DEFAULT_RSSI_OFFSET;
196295ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn
196395ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	return 0;
196495ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn}
196595ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn
196695ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn/*
196795ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn * IEEE80211 stack callback functions.
196895ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn */
196937a41b4affa33bb237d3692bf51f1b5ebcaf29d8Eliad Pellerstatic u64 rt2500pci_get_tsf(struct ieee80211_hw *hw,
197037a41b4affa33bb237d3692bf51f1b5ebcaf29d8Eliad Peller			     struct ieee80211_vif *vif)
197195ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn{
197295ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	struct rt2x00_dev *rt2x00dev = hw->priv;
197395ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	u64 tsf;
197495ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	u32 reg;
197595ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn
197695ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	rt2x00pci_register_read(rt2x00dev, CSR17, &reg);
197795ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	tsf = (u64) rt2x00_get_field32(reg, CSR17_HIGH_TSFTIMER) << 32;
197895ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	rt2x00pci_register_read(rt2x00dev, CSR16, &reg);
197995ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	tsf |= rt2x00_get_field32(reg, CSR16_LOW_TSFTIMER);
198095ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn
198195ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	return tsf;
198295ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn}
198395ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn
198495ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doornstatic int rt2500pci_tx_last_beacon(struct ieee80211_hw *hw)
198595ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn{
198695ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	struct rt2x00_dev *rt2x00dev = hw->priv;
198795ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	u32 reg;
198895ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn
198995ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	rt2x00pci_register_read(rt2x00dev, CSR15, &reg);
199095ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	return rt2x00_get_field32(reg, CSR15_BEACON_SENT);
199195ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn}
199295ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn
199395ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doornstatic const struct ieee80211_ops rt2500pci_mac80211_ops = {
199495ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	.tx			= rt2x00mac_tx,
19954150c57212ad134765dd78c654a4b9906252b66dJohannes Berg	.start			= rt2x00mac_start,
19964150c57212ad134765dd78c654a4b9906252b66dJohannes Berg	.stop			= rt2x00mac_stop,
199795ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	.add_interface		= rt2x00mac_add_interface,
199895ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	.remove_interface	= rt2x00mac_remove_interface,
199995ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	.config			= rt2x00mac_config,
20003a643d244f09fa1fdd25d48a56a073c1a69583eeIvo van Doorn	.configure_filter	= rt2x00mac_configure_filter,
2001d8147f9d9ed6abfa105234a21f05af4a4839eb80Ivo van Doorn	.sw_scan_start		= rt2x00mac_sw_scan_start,
2002d8147f9d9ed6abfa105234a21f05af4a4839eb80Ivo van Doorn	.sw_scan_complete	= rt2x00mac_sw_scan_complete,
200395ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	.get_stats		= rt2x00mac_get_stats,
2004471b3efdfccc257591331724145f8ccf8b3217e1Johannes Berg	.bss_info_changed	= rt2x00mac_bss_info_changed,
200595ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	.conf_tx		= rt2x00mac_conf_tx,
200695ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	.get_tsf		= rt2500pci_get_tsf,
200795ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	.tx_last_beacon		= rt2500pci_tx_last_beacon,
2008e47a5cddf893815e7da16e3226b959af785d8aafIvo van Doorn	.rfkill_poll		= rt2x00mac_rfkill_poll,
2009f44df18c58d4debe3ec0bb76a490aa2f3929fd8bIvo van Doorn	.flush			= rt2x00mac_flush,
20100ed7b3c04434788ef03d267190c5e9e6e3f8e9ceIvo van Doorn	.set_antenna		= rt2x00mac_set_antenna,
20110ed7b3c04434788ef03d267190c5e9e6e3f8e9ceIvo van Doorn	.get_antenna		= rt2x00mac_get_antenna,
2012e7dee444263a103a9a2ac5fd5d0b5e9dc177d57cIvo van Doorn	.get_ringparam		= rt2x00mac_get_ringparam,
20135f0dd296a01c8173fcc05a8b262a1168ae90bc74Gertjan van Wingerde	.tx_frames_pending	= rt2x00mac_tx_frames_pending,
201495ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn};
201595ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn
201695ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doornstatic const struct rt2x00lib_ops rt2500pci_rt2x00_ops = {
201795ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	.irq_handler		= rt2500pci_interrupt,
201816222a0d06f5032d7e8bc7c65e8bf299e21f413aHelmut Schaa	.txstatus_tasklet	= rt2500pci_txstatus_tasklet,
201916222a0d06f5032d7e8bc7c65e8bf299e21f413aHelmut Schaa	.tbtt_tasklet		= rt2500pci_tbtt_tasklet,
202016222a0d06f5032d7e8bc7c65e8bf299e21f413aHelmut Schaa	.rxdone_tasklet		= rt2500pci_rxdone_tasklet,
202195ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	.probe_hw		= rt2500pci_probe_hw,
202295ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	.initialize		= rt2x00pci_initialize,
202395ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	.uninitialize		= rt2x00pci_uninitialize,
2024798b7adb4ed3533ab1282f51d16892034cfd8aaeIvo van Doorn	.get_entry_state	= rt2500pci_get_entry_state,
2025798b7adb4ed3533ab1282f51d16892034cfd8aaeIvo van Doorn	.clear_entry		= rt2500pci_clear_entry,
202695ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	.set_device_state	= rt2500pci_set_device_state,
202795ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	.rfkill_poll		= rt2500pci_rfkill_poll,
202895ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	.link_stats		= rt2500pci_link_stats,
202995ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	.reset_tuner		= rt2500pci_reset_tuner,
203095ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	.link_tuner		= rt2500pci_link_tuner,
2031dbba306f2ae574450a7a5133d6637fe6f5fafc72Ivo van Doorn	.start_queue		= rt2500pci_start_queue,
2032dbba306f2ae574450a7a5133d6637fe6f5fafc72Ivo van Doorn	.kick_queue		= rt2500pci_kick_queue,
2033dbba306f2ae574450a7a5133d6637fe6f5fafc72Ivo van Doorn	.stop_queue		= rt2500pci_stop_queue,
2034152a599274b15028604e24ae2d9c9d7f49853977Ivo van Doorn	.flush_queue		= rt2x00pci_flush_queue,
203595ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	.write_tx_desc		= rt2500pci_write_tx_desc,
2036bd88a7812f1afd50549f3789cacb707b983fef54Ivo van Doorn	.write_beacon		= rt2500pci_write_beacon,
203795ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	.fill_rxdone		= rt2500pci_fill_rxdone,
20383a643d244f09fa1fdd25d48a56a073c1a69583eeIvo van Doorn	.config_filter		= rt2500pci_config_filter,
20396bb40dd13b458beb55f5c60dba1cb28e814bd640Ivo van Doorn	.config_intf		= rt2500pci_config_intf,
2040728103794316f7ff8d98bc2ce044aff7a260ee21Ivo van Doorn	.config_erp		= rt2500pci_config_erp,
2041e4ea1c403acece78c271bf9cd6f797d1cb093df9Ivo van Doorn	.config_ant		= rt2500pci_config_ant,
204295ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	.config			= rt2500pci_config,
204395ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn};
204495ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn
2045181d6902b6bad978d157e69479c95cc0ff213a76Ivo van Doornstatic const struct data_queue_desc rt2500pci_queue_rx = {
2046efd2f271e44c7ea011cdb0363d38f40338ab80d2Helmut Schaa	.entry_num		= 32,
2047181d6902b6bad978d157e69479c95cc0ff213a76Ivo van Doorn	.data_size		= DATA_FRAME_SIZE,
2048181d6902b6bad978d157e69479c95cc0ff213a76Ivo van Doorn	.desc_size		= RXD_DESC_SIZE,
2049b8be63ffa5dc44324e7f507997870fa3e4b17619Ivo van Doorn	.priv_size		= sizeof(struct queue_entry_priv_pci),
2050181d6902b6bad978d157e69479c95cc0ff213a76Ivo van Doorn};
2051181d6902b6bad978d157e69479c95cc0ff213a76Ivo van Doorn
2052181d6902b6bad978d157e69479c95cc0ff213a76Ivo van Doornstatic const struct data_queue_desc rt2500pci_queue_tx = {
2053efd2f271e44c7ea011cdb0363d38f40338ab80d2Helmut Schaa	.entry_num		= 32,
2054181d6902b6bad978d157e69479c95cc0ff213a76Ivo van Doorn	.data_size		= DATA_FRAME_SIZE,
2055181d6902b6bad978d157e69479c95cc0ff213a76Ivo van Doorn	.desc_size		= TXD_DESC_SIZE,
2056b8be63ffa5dc44324e7f507997870fa3e4b17619Ivo van Doorn	.priv_size		= sizeof(struct queue_entry_priv_pci),
2057181d6902b6bad978d157e69479c95cc0ff213a76Ivo van Doorn};
2058181d6902b6bad978d157e69479c95cc0ff213a76Ivo van Doorn
2059181d6902b6bad978d157e69479c95cc0ff213a76Ivo van Doornstatic const struct data_queue_desc rt2500pci_queue_bcn = {
2060efd2f271e44c7ea011cdb0363d38f40338ab80d2Helmut Schaa	.entry_num		= 1,
2061181d6902b6bad978d157e69479c95cc0ff213a76Ivo van Doorn	.data_size		= MGMT_FRAME_SIZE,
2062181d6902b6bad978d157e69479c95cc0ff213a76Ivo van Doorn	.desc_size		= TXD_DESC_SIZE,
2063b8be63ffa5dc44324e7f507997870fa3e4b17619Ivo van Doorn	.priv_size		= sizeof(struct queue_entry_priv_pci),
2064181d6902b6bad978d157e69479c95cc0ff213a76Ivo van Doorn};
2065181d6902b6bad978d157e69479c95cc0ff213a76Ivo van Doorn
2066181d6902b6bad978d157e69479c95cc0ff213a76Ivo van Doornstatic const struct data_queue_desc rt2500pci_queue_atim = {
2067efd2f271e44c7ea011cdb0363d38f40338ab80d2Helmut Schaa	.entry_num		= 8,
2068181d6902b6bad978d157e69479c95cc0ff213a76Ivo van Doorn	.data_size		= DATA_FRAME_SIZE,
2069181d6902b6bad978d157e69479c95cc0ff213a76Ivo van Doorn	.desc_size		= TXD_DESC_SIZE,
2070b8be63ffa5dc44324e7f507997870fa3e4b17619Ivo van Doorn	.priv_size		= sizeof(struct queue_entry_priv_pci),
2071181d6902b6bad978d157e69479c95cc0ff213a76Ivo van Doorn};
2072181d6902b6bad978d157e69479c95cc0ff213a76Ivo van Doorn
207395ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doornstatic const struct rt2x00_ops rt2500pci_ops = {
207404d0362e2fa9d5f1ab560d0d59d04a535b4f3973Gertjan van Wingerde	.name			= KBUILD_MODNAME,
207504d0362e2fa9d5f1ab560d0d59d04a535b4f3973Gertjan van Wingerde	.max_sta_intf		= 1,
207604d0362e2fa9d5f1ab560d0d59d04a535b4f3973Gertjan van Wingerde	.max_ap_intf		= 1,
207704d0362e2fa9d5f1ab560d0d59d04a535b4f3973Gertjan van Wingerde	.eeprom_size		= EEPROM_SIZE,
207804d0362e2fa9d5f1ab560d0d59d04a535b4f3973Gertjan van Wingerde	.rf_size		= RF_SIZE,
207904d0362e2fa9d5f1ab560d0d59d04a535b4f3973Gertjan van Wingerde	.tx_queues		= NUM_TX_QUEUES,
2080e6218cc47bd54710dc523e8c983ceddba625e3aeGertjan van Wingerde	.extra_tx_headroom	= 0,
208104d0362e2fa9d5f1ab560d0d59d04a535b4f3973Gertjan van Wingerde	.rx			= &rt2500pci_queue_rx,
208204d0362e2fa9d5f1ab560d0d59d04a535b4f3973Gertjan van Wingerde	.tx			= &rt2500pci_queue_tx,
208304d0362e2fa9d5f1ab560d0d59d04a535b4f3973Gertjan van Wingerde	.bcn			= &rt2500pci_queue_bcn,
208404d0362e2fa9d5f1ab560d0d59d04a535b4f3973Gertjan van Wingerde	.atim			= &rt2500pci_queue_atim,
208504d0362e2fa9d5f1ab560d0d59d04a535b4f3973Gertjan van Wingerde	.lib			= &rt2500pci_rt2x00_ops,
208604d0362e2fa9d5f1ab560d0d59d04a535b4f3973Gertjan van Wingerde	.hw			= &rt2500pci_mac80211_ops,
208795ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn#ifdef CONFIG_RT2X00_LIB_DEBUGFS
208804d0362e2fa9d5f1ab560d0d59d04a535b4f3973Gertjan van Wingerde	.debugfs		= &rt2500pci_rt2x00debug,
208995ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn#endif /* CONFIG_RT2X00_LIB_DEBUGFS */
209095ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn};
209195ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn
209295ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn/*
209395ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn * RT2500pci module information.
209495ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn */
2095a3aa18842a5303fc28fcc4d57dbd16618bd830a0Alexey Dobriyanstatic DEFINE_PCI_DEVICE_TABLE(rt2500pci_device_table) = {
2096e01ae27f8ce6bd3ee26ef33c704f62449ce8233bGertjan van Wingerde	{ PCI_DEVICE(0x1814, 0x0201) },
209795ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	{ 0, }
209895ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn};
209995ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn
210095ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van DoornMODULE_AUTHOR(DRV_PROJECT);
210195ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van DoornMODULE_VERSION(DRV_VERSION);
210295ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van DoornMODULE_DESCRIPTION("Ralink RT2500 PCI & PCMCIA Wireless LAN driver.");
210395ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van DoornMODULE_SUPPORTED_DEVICE("Ralink RT2560 PCI & PCMCIA chipset based cards");
210495ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van DoornMODULE_DEVICE_TABLE(pci, rt2500pci_device_table);
210595ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van DoornMODULE_LICENSE("GPL");
210695ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn
2107e01ae27f8ce6bd3ee26ef33c704f62449ce8233bGertjan van Wingerdestatic int rt2500pci_probe(struct pci_dev *pci_dev,
2108e01ae27f8ce6bd3ee26ef33c704f62449ce8233bGertjan van Wingerde			   const struct pci_device_id *id)
2109e01ae27f8ce6bd3ee26ef33c704f62449ce8233bGertjan van Wingerde{
2110e01ae27f8ce6bd3ee26ef33c704f62449ce8233bGertjan van Wingerde	return rt2x00pci_probe(pci_dev, &rt2500pci_ops);
2111e01ae27f8ce6bd3ee26ef33c704f62449ce8233bGertjan van Wingerde}
2112e01ae27f8ce6bd3ee26ef33c704f62449ce8233bGertjan van Wingerde
211395ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doornstatic struct pci_driver rt2500pci_driver = {
21142360157c413b06fe2958a051daeab7bac68f6588Ivo van Doorn	.name		= KBUILD_MODNAME,
211595ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	.id_table	= rt2500pci_device_table,
2116e01ae27f8ce6bd3ee26ef33c704f62449ce8233bGertjan van Wingerde	.probe		= rt2500pci_probe,
211795ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	.remove		= __devexit_p(rt2x00pci_remove),
211895ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	.suspend	= rt2x00pci_suspend,
211995ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	.resume		= rt2x00pci_resume,
212095ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn};
212195ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn
212295ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doornstatic int __init rt2500pci_init(void)
212395ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn{
212495ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	return pci_register_driver(&rt2500pci_driver);
212595ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn}
212695ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn
212795ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doornstatic void __exit rt2500pci_exit(void)
212895ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn{
212995ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn	pci_unregister_driver(&rt2500pci_driver);
213095ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn}
213195ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doorn
213295ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doornmodule_init(rt2500pci_init);
213395ea36275f3c9a1d3d04c217b4b576c657c4e70eIvo van Doornmodule_exit(rt2500pci_exit);
2134