Newer
Older
Copyright (C) 2004 - 2009 Ivo van Doorn <IvDoorn@gmail.com>
<http://rt2x00.serialmonkey.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the
Free Software Foundation, Inc.,
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/*
Module: rt61pci
Abstract: rt61pci device specific routines.
Supported chipsets: RT2561, RT2561s, RT2661.
*/
#include <linux/crc-itu-t.h>
#include <linux/delay.h>
#include <linux/etherdevice.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/pci.h>
#include <linux/eeprom_93cx6.h>
#include "rt2x00.h"
#include "rt2x00pci.h"
#include "rt61pci.h"
/*
* Allow hardware encryption to be disabled.
*/
static int modparam_nohwcrypt = 0;
module_param_named(nohwcrypt, modparam_nohwcrypt, bool, S_IRUGO);
MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption.");
/*
* Register access.
* BBP and RF register require indirect register access,
* and use the CSR registers PHY_CSR3 and PHY_CSR4 to achieve this.
* These indirect registers work with busy bits,
* and we will try maximal REGISTER_BUSY_COUNT times to access
* the register while taking a REGISTER_BUSY_DELAY us delay
* between each attempt. When the busy bit is still set at that time,
* the access attempt is considered to have failed,
* and we will print an error.
*/
#define WAIT_FOR_BBP(__dev, __reg) \
rt2x00pci_regbusy_read((__dev), PHY_CSR3, PHY_CSR3_BUSY, (__reg))
#define WAIT_FOR_RF(__dev, __reg) \
rt2x00pci_regbusy_read((__dev), PHY_CSR4, PHY_CSR4_BUSY, (__reg))
#define WAIT_FOR_MCU(__dev, __reg) \
rt2x00pci_regbusy_read((__dev), H2M_MAILBOX_CSR, \
H2M_MAILBOX_CSR_OWNER, (__reg))
static void rt61pci_bbp_write(struct rt2x00_dev *rt2x00dev,
const unsigned int word, const u8 value)
{
u32 reg;
mutex_lock(&rt2x00dev->csr_mutex);
* Wait until the BBP becomes available, afterwards we
* can safely write the new data into the register.
if (WAIT_FOR_BBP(rt2x00dev, ®)) {
reg = 0;
rt2x00_set_field32(®, PHY_CSR3_VALUE, value);
rt2x00_set_field32(®, PHY_CSR3_REGNUM, word);
rt2x00_set_field32(®, PHY_CSR3_BUSY, 1);
rt2x00_set_field32(®, PHY_CSR3_READ_CONTROL, 0);
rt2x00pci_register_write(rt2x00dev, PHY_CSR3, reg);
}
mutex_unlock(&rt2x00dev->csr_mutex);
static void rt61pci_bbp_read(struct rt2x00_dev *rt2x00dev,
const unsigned int word, u8 *value)
{
u32 reg;
mutex_lock(&rt2x00dev->csr_mutex);
* Wait until the BBP becomes available, afterwards we
* can safely write the read request into the register.
* After the data has been written, we wait until hardware
* returns the correct value, if at any time the register
* doesn't become available in time, reg will be 0xffffffff
* which means we return 0xff to the caller.
if (WAIT_FOR_BBP(rt2x00dev, ®)) {
reg = 0;
rt2x00_set_field32(®, PHY_CSR3_REGNUM, word);
rt2x00_set_field32(®, PHY_CSR3_BUSY, 1);
rt2x00_set_field32(®, PHY_CSR3_READ_CONTROL, 1);
rt2x00pci_register_write(rt2x00dev, PHY_CSR3, reg);
WAIT_FOR_BBP(rt2x00dev, ®);
}
*value = rt2x00_get_field32(reg, PHY_CSR3_VALUE);
mutex_unlock(&rt2x00dev->csr_mutex);
static void rt61pci_rf_write(struct rt2x00_dev *rt2x00dev,
const unsigned int word, const u32 value)
{
u32 reg;
mutex_lock(&rt2x00dev->csr_mutex);
/*
* Wait until the RF becomes available, afterwards we
* can safely write the new data into the register.
*/
if (WAIT_FOR_RF(rt2x00dev, ®)) {
reg = 0;
rt2x00_set_field32(®, PHY_CSR4_VALUE, value);
rt2x00_set_field32(®, PHY_CSR4_NUMBER_OF_BITS, 21);
rt2x00_set_field32(®, PHY_CSR4_IF_SELECT, 0);
rt2x00_set_field32(®, PHY_CSR4_BUSY, 1);
rt2x00pci_register_write(rt2x00dev, PHY_CSR4, reg);
rt2x00_rf_write(rt2x00dev, word, value);
mutex_unlock(&rt2x00dev->csr_mutex);
static void rt61pci_mcu_request(struct rt2x00_dev *rt2x00dev,
const u8 command, const u8 token,
const u8 arg0, const u8 arg1)
{
u32 reg;
mutex_lock(&rt2x00dev->csr_mutex);
/*
* Wait until the MCU becomes available, afterwards we
* can safely write the new data into the register.
*/
if (WAIT_FOR_MCU(rt2x00dev, ®)) {
rt2x00_set_field32(®, H2M_MAILBOX_CSR_OWNER, 1);
rt2x00_set_field32(®, H2M_MAILBOX_CSR_CMD_TOKEN, token);
rt2x00_set_field32(®, H2M_MAILBOX_CSR_ARG0, arg0);
rt2x00_set_field32(®, H2M_MAILBOX_CSR_ARG1, arg1);
rt2x00pci_register_write(rt2x00dev, H2M_MAILBOX_CSR, reg);
rt2x00pci_register_read(rt2x00dev, HOST_CMD_CSR, ®);
rt2x00_set_field32(®, HOST_CMD_CSR_HOST_COMMAND, command);
rt2x00_set_field32(®, HOST_CMD_CSR_INTERRUPT_MCU, 1);
rt2x00pci_register_write(rt2x00dev, HOST_CMD_CSR, reg);
}
mutex_unlock(&rt2x00dev->csr_mutex);
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
}
static void rt61pci_eepromregister_read(struct eeprom_93cx6 *eeprom)
{
struct rt2x00_dev *rt2x00dev = eeprom->data;
u32 reg;
rt2x00pci_register_read(rt2x00dev, E2PROM_CSR, ®);
eeprom->reg_data_in = !!rt2x00_get_field32(reg, E2PROM_CSR_DATA_IN);
eeprom->reg_data_out = !!rt2x00_get_field32(reg, E2PROM_CSR_DATA_OUT);
eeprom->reg_data_clock =
!!rt2x00_get_field32(reg, E2PROM_CSR_DATA_CLOCK);
eeprom->reg_chip_select =
!!rt2x00_get_field32(reg, E2PROM_CSR_CHIP_SELECT);
}
static void rt61pci_eepromregister_write(struct eeprom_93cx6 *eeprom)
{
struct rt2x00_dev *rt2x00dev = eeprom->data;
u32 reg = 0;
rt2x00_set_field32(®, E2PROM_CSR_DATA_IN, !!eeprom->reg_data_in);
rt2x00_set_field32(®, E2PROM_CSR_DATA_OUT, !!eeprom->reg_data_out);
rt2x00_set_field32(®, E2PROM_CSR_DATA_CLOCK,
!!eeprom->reg_data_clock);
rt2x00_set_field32(®, E2PROM_CSR_CHIP_SELECT,
!!eeprom->reg_chip_select);
rt2x00pci_register_write(rt2x00dev, E2PROM_CSR, reg);
}
#ifdef CONFIG_RT2X00_LIB_DEBUGFS
static const struct rt2x00debug rt61pci_rt2x00debug = {
.owner = THIS_MODULE,
.csr = {
.read = rt2x00pci_register_read,
.write = rt2x00pci_register_write,
.flags = RT2X00DEBUGFS_OFFSET,
.word_base = CSR_REG_BASE,
.word_size = sizeof(u32),
.word_count = CSR_REG_SIZE / sizeof(u32),
},
.eeprom = {
.read = rt2x00_eeprom_read,
.write = rt2x00_eeprom_write,
.word_size = sizeof(u16),
.word_count = EEPROM_SIZE / sizeof(u16),
},
.bbp = {
.read = rt61pci_bbp_read,
.write = rt61pci_bbp_write,
.word_size = sizeof(u8),
.word_count = BBP_SIZE / sizeof(u8),
},
.rf = {
.read = rt2x00_rf_read,
.write = rt61pci_rf_write,
.word_size = sizeof(u32),
.word_count = RF_SIZE / sizeof(u32),
},
};
#endif /* CONFIG_RT2X00_LIB_DEBUGFS */
static int rt61pci_rfkill_poll(struct rt2x00_dev *rt2x00dev)
{
u32 reg;
rt2x00pci_register_read(rt2x00dev, MAC_CSR13, ®);
return rt2x00_get_field32(reg, MAC_CSR13_BIT5);
#ifdef CONFIG_RT2X00_LIB_LEDS
static void rt61pci_brightness_set(struct led_classdev *led_cdev,
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
enum led_brightness brightness)
{
struct rt2x00_led *led =
container_of(led_cdev, struct rt2x00_led, led_dev);
unsigned int enabled = brightness != LED_OFF;
unsigned int a_mode =
(enabled && led->rt2x00dev->curr_band == IEEE80211_BAND_5GHZ);
unsigned int bg_mode =
(enabled && led->rt2x00dev->curr_band == IEEE80211_BAND_2GHZ);
if (led->type == LED_TYPE_RADIO) {
rt2x00_set_field16(&led->rt2x00dev->led_mcu_reg,
MCU_LEDCS_RADIO_STATUS, enabled);
rt61pci_mcu_request(led->rt2x00dev, MCU_LED, 0xff,
(led->rt2x00dev->led_mcu_reg & 0xff),
((led->rt2x00dev->led_mcu_reg >> 8)));
} else if (led->type == LED_TYPE_ASSOC) {
rt2x00_set_field16(&led->rt2x00dev->led_mcu_reg,
MCU_LEDCS_LINK_BG_STATUS, bg_mode);
rt2x00_set_field16(&led->rt2x00dev->led_mcu_reg,
MCU_LEDCS_LINK_A_STATUS, a_mode);
rt61pci_mcu_request(led->rt2x00dev, MCU_LED, 0xff,
(led->rt2x00dev->led_mcu_reg & 0xff),
((led->rt2x00dev->led_mcu_reg >> 8)));
} else if (led->type == LED_TYPE_QUALITY) {
/*
* The brightness is divided into 6 levels (0 - 5),
* this means we need to convert the brightness
* argument into the matching level within that range.
*/
rt61pci_mcu_request(led->rt2x00dev, MCU_LED_STRENGTH, 0xff,
brightness / (LED_FULL / 6), 0);
}
}
static int rt61pci_blink_set(struct led_classdev *led_cdev,
unsigned long *delay_on,
unsigned long *delay_off)
{
struct rt2x00_led *led =
container_of(led_cdev, struct rt2x00_led, led_dev);
u32 reg;
rt2x00pci_register_read(led->rt2x00dev, MAC_CSR14, ®);
rt2x00_set_field32(®, MAC_CSR14_ON_PERIOD, *delay_on);
rt2x00_set_field32(®, MAC_CSR14_OFF_PERIOD, *delay_off);
rt2x00pci_register_write(led->rt2x00dev, MAC_CSR14, reg);
return 0;
}
static void rt61pci_init_led(struct rt2x00_dev *rt2x00dev,
struct rt2x00_led *led,
enum led_type type)
{
led->rt2x00dev = rt2x00dev;
led->type = type;
led->led_dev.brightness_set = rt61pci_brightness_set;
led->led_dev.blink_set = rt61pci_blink_set;
led->flags = LED_INITIALIZED;
}
#endif /* CONFIG_RT2X00_LIB_LEDS */
/*
* Configuration handlers.
*/
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
static int rt61pci_config_shared_key(struct rt2x00_dev *rt2x00dev,
struct rt2x00lib_crypto *crypto,
struct ieee80211_key_conf *key)
{
struct hw_key_entry key_entry;
struct rt2x00_field32 field;
u32 mask;
u32 reg;
if (crypto->cmd == SET_KEY) {
/*
* rt2x00lib can't determine the correct free
* key_idx for shared keys. We have 1 register
* with key valid bits. The goal is simple, read
* the register, if that is full we have no slots
* left.
* Note that each BSS is allowed to have up to 4
* shared keys, so put a mask over the allowed
* entries.
*/
mask = (0xf << crypto->bssidx);
rt2x00pci_register_read(rt2x00dev, SEC_CSR0, ®);
reg &= mask;
if (reg && reg == mask)
return -ENOSPC;
key->hw_key_idx += reg ? ffz(reg) : 0;
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
/*
* Upload key to hardware
*/
memcpy(key_entry.key, crypto->key,
sizeof(key_entry.key));
memcpy(key_entry.tx_mic, crypto->tx_mic,
sizeof(key_entry.tx_mic));
memcpy(key_entry.rx_mic, crypto->rx_mic,
sizeof(key_entry.rx_mic));
reg = SHARED_KEY_ENTRY(key->hw_key_idx);
rt2x00pci_register_multiwrite(rt2x00dev, reg,
&key_entry, sizeof(key_entry));
/*
* The cipher types are stored over 2 registers.
* bssidx 0 and 1 keys are stored in SEC_CSR1 and
* bssidx 1 and 2 keys are stored in SEC_CSR5.
* Using the correct defines correctly will cause overhead,
* so just calculate the correct offset.
*/
if (key->hw_key_idx < 8) {
field.bit_offset = (3 * key->hw_key_idx);
field.bit_mask = 0x7 << field.bit_offset;
rt2x00pci_register_read(rt2x00dev, SEC_CSR1, ®);
rt2x00_set_field32(®, field, crypto->cipher);
rt2x00pci_register_write(rt2x00dev, SEC_CSR1, reg);
} else {
field.bit_offset = (3 * (key->hw_key_idx - 8));
field.bit_mask = 0x7 << field.bit_offset;
rt2x00pci_register_read(rt2x00dev, SEC_CSR5, ®);
rt2x00_set_field32(®, field, crypto->cipher);
rt2x00pci_register_write(rt2x00dev, SEC_CSR5, reg);
}
/*
* The driver does not support the IV/EIV generation
* in hardware. However it doesn't support the IV/EIV
* inside the ieee80211 frame either, but requires it
* to be provided separately for the descriptor.
* rt2x00lib will cut the IV/EIV data out of all frames
* given to us by mac80211, but we must tell mac80211
* to generate the IV/EIV data.
*/
key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
}
/*
* SEC_CSR0 contains only single-bit fields to indicate
* a particular key is valid. Because using the FIELD32()
* defines directly will cause a lot of overhead, we use
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
* a calculation to determine the correct bit directly.
*/
mask = 1 << key->hw_key_idx;
rt2x00pci_register_read(rt2x00dev, SEC_CSR0, ®);
if (crypto->cmd == SET_KEY)
reg |= mask;
else if (crypto->cmd == DISABLE_KEY)
reg &= ~mask;
rt2x00pci_register_write(rt2x00dev, SEC_CSR0, reg);
return 0;
}
static int rt61pci_config_pairwise_key(struct rt2x00_dev *rt2x00dev,
struct rt2x00lib_crypto *crypto,
struct ieee80211_key_conf *key)
{
struct hw_pairwise_ta_entry addr_entry;
struct hw_key_entry key_entry;
u32 mask;
u32 reg;
if (crypto->cmd == SET_KEY) {
/*
* rt2x00lib can't determine the correct free
* key_idx for pairwise keys. We have 2 registers
* with key valid bits. The goal is simple: read
* the first register. If that is full, move to
* When both registers are full, we drop the key.
* Otherwise, we use the first invalid entry.
*/
rt2x00pci_register_read(rt2x00dev, SEC_CSR2, ®);
if (reg && reg == ~0) {
key->hw_key_idx = 32;
rt2x00pci_register_read(rt2x00dev, SEC_CSR3, ®);
if (reg && reg == ~0)
return -ENOSPC;
}
key->hw_key_idx += reg ? ffz(reg) : 0;
/*
* Upload key to hardware
*/
memcpy(key_entry.key, crypto->key,
sizeof(key_entry.key));
memcpy(key_entry.tx_mic, crypto->tx_mic,
sizeof(key_entry.tx_mic));
memcpy(key_entry.rx_mic, crypto->rx_mic,
sizeof(key_entry.rx_mic));
memset(&addr_entry, 0, sizeof(addr_entry));
memcpy(&addr_entry, crypto->address, ETH_ALEN);
addr_entry.cipher = crypto->cipher;
reg = PAIRWISE_KEY_ENTRY(key->hw_key_idx);
rt2x00pci_register_multiwrite(rt2x00dev, reg,
&key_entry, sizeof(key_entry));
reg = PAIRWISE_TA_ENTRY(key->hw_key_idx);
rt2x00pci_register_multiwrite(rt2x00dev, reg,
&addr_entry, sizeof(addr_entry));
/*
* Enable pairwise lookup table for given BSS idx.
* Without this, received frames will not be decrypted
* by the hardware.
*/
rt2x00pci_register_read(rt2x00dev, SEC_CSR4, ®);
reg |= (1 << crypto->bssidx);
rt2x00pci_register_write(rt2x00dev, SEC_CSR4, reg);
/*
* The driver does not support the IV/EIV generation
* in hardware. However it doesn't support the IV/EIV
* inside the ieee80211 frame either, but requires it
* to be provided separately for the descriptor.
* rt2x00lib will cut the IV/EIV data out of all frames
* given to us by mac80211, but we must tell mac80211
* to generate the IV/EIV data.
*/
key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
}
/*
* SEC_CSR2 and SEC_CSR3 contain only single-bit fields to indicate
* a particular key is valid. Because using the FIELD32()
* defines directly will cause a lot of overhead, we use
* a calculation to determine the correct bit directly.
*/
if (key->hw_key_idx < 32) {
mask = 1 << key->hw_key_idx;
rt2x00pci_register_read(rt2x00dev, SEC_CSR2, ®);
if (crypto->cmd == SET_KEY)
reg |= mask;
else if (crypto->cmd == DISABLE_KEY)
reg &= ~mask;
rt2x00pci_register_write(rt2x00dev, SEC_CSR2, reg);
} else {
mask = 1 << (key->hw_key_idx - 32);
rt2x00pci_register_read(rt2x00dev, SEC_CSR3, ®);
if (crypto->cmd == SET_KEY)
reg |= mask;
else if (crypto->cmd == DISABLE_KEY)
reg &= ~mask;
rt2x00pci_register_write(rt2x00dev, SEC_CSR3, reg);
}
return 0;
}
static void rt61pci_config_filter(struct rt2x00_dev *rt2x00dev,
const unsigned int filter_flags)
{
u32 reg;
/*
* Start configuration steps.
* Note that the version error will always be dropped
* and broadcast frames will always be accepted since
* there is no filter for it at this time.
*/
rt2x00pci_register_read(rt2x00dev, TXRX_CSR0, ®);
rt2x00_set_field32(®, TXRX_CSR0_DROP_CRC,
!(filter_flags & FIF_FCSFAIL));
rt2x00_set_field32(®, TXRX_CSR0_DROP_PHYSICAL,
!(filter_flags & FIF_PLCPFAIL));
rt2x00_set_field32(®, TXRX_CSR0_DROP_CONTROL,
!(filter_flags & (FIF_CONTROL | FIF_PSPOLL)));
rt2x00_set_field32(®, TXRX_CSR0_DROP_NOT_TO_ME,
!(filter_flags & FIF_PROMISC_IN_BSS));
rt2x00_set_field32(®, TXRX_CSR0_DROP_TO_DS,
!(filter_flags & FIF_PROMISC_IN_BSS) &&
!rt2x00dev->intf_ap_count);
rt2x00_set_field32(®, TXRX_CSR0_DROP_VERSION_ERROR, 1);
rt2x00_set_field32(®, TXRX_CSR0_DROP_MULTICAST,
!(filter_flags & FIF_ALLMULTI));
rt2x00_set_field32(®, TXRX_CSR0_DROP_BROADCAST, 0);
rt2x00_set_field32(®, TXRX_CSR0_DROP_ACK_CTS,
!(filter_flags & FIF_CONTROL));
rt2x00pci_register_write(rt2x00dev, TXRX_CSR0, reg);
}
static void rt61pci_config_intf(struct rt2x00_dev *rt2x00dev,
struct rt2x00_intf *intf,
struct rt2x00intf_conf *conf,
const unsigned int flags)
unsigned int beacon_base;
u32 reg;
if (flags & CONFIG_UPDATE_TYPE) {
/*
* Clear current synchronisation setup.
* For the Beacon base registers, we only need to clear
* the first byte since that byte contains the VALID and OWNER
* bits which (when set to 0) will invalidate the entire beacon.
*/
beacon_base = HW_BEACON_OFFSET(intf->beacon->entry_idx);
rt2x00pci_register_write(rt2x00dev, beacon_base, 0);
/*
* Enable synchronisation.
*/
rt2x00pci_register_read(rt2x00dev, TXRX_CSR9, ®);
rt2x00_set_field32(®, TXRX_CSR9_TSF_TICKING, 1);
rt2x00_set_field32(®, TXRX_CSR9_TSF_SYNC, conf->sync);
rt2x00_set_field32(®, TXRX_CSR9_TBTT_ENABLE, 1);
rt2x00pci_register_write(rt2x00dev, TXRX_CSR9, reg);
}
if (flags & CONFIG_UPDATE_MAC) {
reg = le32_to_cpu(conf->mac[1]);
rt2x00_set_field32(®, MAC_CSR3_UNICAST_TO_ME_MASK, 0xff);
conf->mac[1] = cpu_to_le32(reg);
rt2x00pci_register_multiwrite(rt2x00dev, MAC_CSR2,
conf->mac, sizeof(conf->mac));
}
if (flags & CONFIG_UPDATE_BSSID) {
reg = le32_to_cpu(conf->bssid[1]);
rt2x00_set_field32(®, MAC_CSR5_BSS_ID_MASK, 3);
conf->bssid[1] = cpu_to_le32(reg);
rt2x00pci_register_multiwrite(rt2x00dev, MAC_CSR4,
conf->bssid, sizeof(conf->bssid));
}
static void rt61pci_config_erp(struct rt2x00_dev *rt2x00dev,
struct rt2x00lib_erp *erp,
u32 changed)
{
u32 reg;
rt2x00pci_register_read(rt2x00dev, TXRX_CSR0, ®);
rt2x00_set_field32(®, TXRX_CSR0_RX_ACK_TIMEOUT, 0x32);
rt2x00_set_field32(®, TXRX_CSR0_TSF_OFFSET, IEEE80211_HEADER);
rt2x00pci_register_write(rt2x00dev, TXRX_CSR0, reg);
if (changed & BSS_CHANGED_ERP_PREAMBLE) {
rt2x00pci_register_read(rt2x00dev, TXRX_CSR4, ®);
rt2x00_set_field32(®, TXRX_CSR4_AUTORESPOND_ENABLE, 1);
rt2x00_set_field32(®, TXRX_CSR4_AUTORESPOND_PREAMBLE,
!!erp->short_preamble);
rt2x00pci_register_write(rt2x00dev, TXRX_CSR4, reg);
}
if (changed & BSS_CHANGED_BASIC_RATES)
rt2x00pci_register_write(rt2x00dev, TXRX_CSR5,
erp->basic_rates);
if (changed & BSS_CHANGED_BEACON_INT) {
rt2x00pci_register_read(rt2x00dev, TXRX_CSR9, ®);
rt2x00_set_field32(®, TXRX_CSR9_BEACON_INTERVAL,
erp->beacon_int * 16);
rt2x00pci_register_write(rt2x00dev, TXRX_CSR9, reg);
}
if (changed & BSS_CHANGED_ERP_SLOT) {
rt2x00pci_register_read(rt2x00dev, MAC_CSR9, ®);
rt2x00_set_field32(®, MAC_CSR9_SLOT_TIME, erp->slot_time);
rt2x00pci_register_write(rt2x00dev, MAC_CSR9, reg);
rt2x00pci_register_read(rt2x00dev, MAC_CSR8, ®);
rt2x00_set_field32(®, MAC_CSR8_SIFS, erp->sifs);
rt2x00_set_field32(®, MAC_CSR8_SIFS_AFTER_RX_OFDM, 3);
rt2x00_set_field32(®, MAC_CSR8_EIFS, erp->eifs);
rt2x00pci_register_write(rt2x00dev, MAC_CSR8, reg);
}
}
static void rt61pci_config_antenna_5x(struct rt2x00_dev *rt2x00dev,
struct antenna_setup *ant)
{
u8 r3;
u8 r4;
u8 r77;
rt61pci_bbp_read(rt2x00dev, 3, &r3);
rt61pci_bbp_read(rt2x00dev, 4, &r4);
rt61pci_bbp_read(rt2x00dev, 77, &r77);
rt2x00_set_field8(&r3, BBP_R3_SMART_MODE, rt2x00_rf(rt2x00dev, RF5325));
/*
* Configure the RX antenna.
*/
switch (ant->rx) {
case ANTENNA_HW_DIVERSITY:
rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA_CONTROL, 2);
rt2x00_set_field8(&r4, BBP_R4_RX_FRAME_END,
(rt2x00dev->curr_band != IEEE80211_BAND_5GHZ));
break;
case ANTENNA_A:
rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA_CONTROL, 1);
rt2x00_set_field8(&r4, BBP_R4_RX_FRAME_END, 0);
if (rt2x00dev->curr_band == IEEE80211_BAND_5GHZ)
rt2x00_set_field8(&r77, BBP_R77_RX_ANTENNA, 0);
else
rt2x00_set_field8(&r77, BBP_R77_RX_ANTENNA, 3);
break;
case ANTENNA_B:
default:
rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA_CONTROL, 1);
rt2x00_set_field8(&r4, BBP_R4_RX_FRAME_END, 0);
if (rt2x00dev->curr_band == IEEE80211_BAND_5GHZ)
rt2x00_set_field8(&r77, BBP_R77_RX_ANTENNA, 3);
else
rt2x00_set_field8(&r77, BBP_R77_RX_ANTENNA, 0);
break;
}
rt61pci_bbp_write(rt2x00dev, 77, r77);
rt61pci_bbp_write(rt2x00dev, 3, r3);
rt61pci_bbp_write(rt2x00dev, 4, r4);
}
static void rt61pci_config_antenna_2x(struct rt2x00_dev *rt2x00dev,
struct antenna_setup *ant)
{
u8 r3;
u8 r4;
u8 r77;
rt61pci_bbp_read(rt2x00dev, 3, &r3);
rt61pci_bbp_read(rt2x00dev, 4, &r4);
rt61pci_bbp_read(rt2x00dev, 77, &r77);
rt2x00_set_field8(&r3, BBP_R3_SMART_MODE, rt2x00_rf(rt2x00dev, RF2529));
rt2x00_set_field8(&r4, BBP_R4_RX_FRAME_END,
!test_bit(CONFIG_FRAME_TYPE, &rt2x00dev->flags));
/*
* Configure the RX antenna.
*/
switch (ant->rx) {
case ANTENNA_HW_DIVERSITY:
rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA_CONTROL, 2);
break;
case ANTENNA_A:
rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA_CONTROL, 1);
rt2x00_set_field8(&r77, BBP_R77_RX_ANTENNA, 3);
break;
case ANTENNA_B:
default:
rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA_CONTROL, 1);
rt2x00_set_field8(&r77, BBP_R77_RX_ANTENNA, 0);
break;
}
rt61pci_bbp_write(rt2x00dev, 77, r77);
rt61pci_bbp_write(rt2x00dev, 3, r3);
rt61pci_bbp_write(rt2x00dev, 4, r4);
}
static void rt61pci_config_antenna_2529_rx(struct rt2x00_dev *rt2x00dev,
const int p1, const int p2)
{
u32 reg;
rt2x00pci_register_read(rt2x00dev, MAC_CSR13, ®);
rt2x00_set_field32(®, MAC_CSR13_BIT4, p1);
rt2x00_set_field32(®, MAC_CSR13_BIT12, 0);
rt2x00_set_field32(®, MAC_CSR13_BIT3, !p2);
rt2x00_set_field32(®, MAC_CSR13_BIT11, 0);
rt2x00pci_register_write(rt2x00dev, MAC_CSR13, reg);
}
static void rt61pci_config_antenna_2529(struct rt2x00_dev *rt2x00dev,
struct antenna_setup *ant)
{
u8 r3;
u8 r4;
u8 r77;
rt61pci_bbp_read(rt2x00dev, 3, &r3);
rt61pci_bbp_read(rt2x00dev, 4, &r4);
rt61pci_bbp_read(rt2x00dev, 77, &r77);
/*
* Configure the RX antenna.
*/
switch (ant->rx) {
case ANTENNA_A:
rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA_CONTROL, 1);
rt2x00_set_field8(&r77, BBP_R77_RX_ANTENNA, 0);
rt61pci_config_antenna_2529_rx(rt2x00dev, 0, 0);
break;
case ANTENNA_HW_DIVERSITY:
/*
* FIXME: Antenna selection for the rf 2529 is very confusing
* in the legacy driver. Just default to antenna B until the
* legacy code can be properly translated into rt2x00 code.
*/
case ANTENNA_B:
default:
rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA_CONTROL, 1);
rt2x00_set_field8(&r77, BBP_R77_RX_ANTENNA, 3);
rt61pci_config_antenna_2529_rx(rt2x00dev, 1, 1);
break;
}
rt61pci_bbp_write(rt2x00dev, 77, r77);
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
rt61pci_bbp_write(rt2x00dev, 3, r3);
rt61pci_bbp_write(rt2x00dev, 4, r4);
}
struct antenna_sel {
u8 word;
/*
* value[0] -> non-LNA
* value[1] -> LNA
*/
u8 value[2];
};
static const struct antenna_sel antenna_sel_a[] = {
{ 96, { 0x58, 0x78 } },
{ 104, { 0x38, 0x48 } },
{ 75, { 0xfe, 0x80 } },
{ 86, { 0xfe, 0x80 } },
{ 88, { 0xfe, 0x80 } },
{ 35, { 0x60, 0x60 } },
{ 97, { 0x58, 0x58 } },
{ 98, { 0x58, 0x58 } },
};
static const struct antenna_sel antenna_sel_bg[] = {
{ 96, { 0x48, 0x68 } },
{ 104, { 0x2c, 0x3c } },
{ 75, { 0xfe, 0x80 } },
{ 86, { 0xfe, 0x80 } },
{ 88, { 0xfe, 0x80 } },
{ 35, { 0x50, 0x50 } },
{ 97, { 0x48, 0x48 } },
{ 98, { 0x48, 0x48 } },
};
static void rt61pci_config_ant(struct rt2x00_dev *rt2x00dev,
struct antenna_setup *ant)
{
const struct antenna_sel *sel;
unsigned int lna;
unsigned int i;
u32 reg;
/*
* We should never come here because rt2x00lib is supposed
* to catch this and send us the correct antenna explicitely.
*/
BUG_ON(ant->rx == ANTENNA_SW_DIVERSITY ||
ant->tx == ANTENNA_SW_DIVERSITY);
if (rt2x00dev->curr_band == IEEE80211_BAND_5GHZ) {
sel = antenna_sel_a;
lna = test_bit(CONFIG_EXTERNAL_LNA_A, &rt2x00dev->flags);
} else {
sel = antenna_sel_bg;
lna = test_bit(CONFIG_EXTERNAL_LNA_BG, &rt2x00dev->flags);
}
for (i = 0; i < ARRAY_SIZE(antenna_sel_a); i++)
rt61pci_bbp_write(rt2x00dev, sel[i].word, sel[i].value[lna]);
rt2x00pci_register_read(rt2x00dev, PHY_CSR0, ®);
rt2x00_set_field32(®, PHY_CSR0_PA_PE_BG,
rt2x00dev->curr_band == IEEE80211_BAND_2GHZ);
rt2x00_set_field32(®, PHY_CSR0_PA_PE_A,
rt2x00dev->curr_band == IEEE80211_BAND_5GHZ);
rt2x00pci_register_write(rt2x00dev, PHY_CSR0, reg);
if (rt2x00_rf(rt2x00dev, RF5225) || rt2x00_rf(rt2x00dev, RF5325))
rt61pci_config_antenna_5x(rt2x00dev, ant);
else if (rt2x00_rf(rt2x00dev, RF2527))
rt61pci_config_antenna_2x(rt2x00dev, ant);
else if (rt2x00_rf(rt2x00dev, RF2529)) {
if (test_bit(CONFIG_DOUBLE_ANTENNA, &rt2x00dev->flags))
rt61pci_config_antenna_2x(rt2x00dev, ant);
rt61pci_config_antenna_2529(rt2x00dev, ant);
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
static void rt61pci_config_lna_gain(struct rt2x00_dev *rt2x00dev,
struct rt2x00lib_conf *libconf)
{
u16 eeprom;
short lna_gain = 0;
if (libconf->conf->channel->band == IEEE80211_BAND_2GHZ) {
if (test_bit(CONFIG_EXTERNAL_LNA_BG, &rt2x00dev->flags))
lna_gain += 14;
rt2x00_eeprom_read(rt2x00dev, EEPROM_RSSI_OFFSET_BG, &eeprom);
lna_gain -= rt2x00_get_field16(eeprom, EEPROM_RSSI_OFFSET_BG_1);
} else {
if (test_bit(CONFIG_EXTERNAL_LNA_A, &rt2x00dev->flags))
lna_gain += 14;
rt2x00_eeprom_read(rt2x00dev, EEPROM_RSSI_OFFSET_A, &eeprom);
lna_gain -= rt2x00_get_field16(eeprom, EEPROM_RSSI_OFFSET_A_1);
}
rt2x00dev->lna_gain = lna_gain;
}
static void rt61pci_config_channel(struct rt2x00_dev *rt2x00dev,
struct rf_channel *rf, const int txpower)
{
u8 r3;
u8 r94;
u8 smart;
rt2x00_set_field32(&rf->rf3, RF3_TXPOWER, TXPOWER_TO_DEV(txpower));
rt2x00_set_field32(&rf->rf4, RF4_FREQ_OFFSET, rt2x00dev->freq_offset);
smart = !(rt2x00_rf(rt2x00dev, RF5225) || rt2x00_rf(rt2x00dev, RF2527));
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
rt61pci_bbp_read(rt2x00dev, 3, &r3);
rt2x00_set_field8(&r3, BBP_R3_SMART_MODE, smart);
rt61pci_bbp_write(rt2x00dev, 3, r3);
r94 = 6;
if (txpower > MAX_TXPOWER && txpower <= (MAX_TXPOWER + r94))
r94 += txpower - MAX_TXPOWER;
else if (txpower < MIN_TXPOWER && txpower >= (MIN_TXPOWER - r94))
r94 += txpower;
rt61pci_bbp_write(rt2x00dev, 94, r94);
rt61pci_rf_write(rt2x00dev, 1, rf->rf1);
rt61pci_rf_write(rt2x00dev, 2, rf->rf2);
rt61pci_rf_write(rt2x00dev, 3, rf->rf3 & ~0x00000004);
rt61pci_rf_write(rt2x00dev, 4, rf->rf4);
udelay(200);
rt61pci_rf_write(rt2x00dev, 1, rf->rf1);
rt61pci_rf_write(rt2x00dev, 2, rf->rf2);
rt61pci_rf_write(rt2x00dev, 3, rf->rf3 | 0x00000004);
rt61pci_rf_write(rt2x00dev, 4, rf->rf4);
udelay(200);
rt61pci_rf_write(rt2x00dev, 1, rf->rf1);
rt61pci_rf_write(rt2x00dev, 2, rf->rf2);
rt61pci_rf_write(rt2x00dev, 3, rf->rf3 & ~0x00000004);
rt61pci_rf_write(rt2x00dev, 4, rf->rf4);
msleep(1);
}
static void rt61pci_config_txpower(struct rt2x00_dev *rt2x00dev,
const int txpower)
{
struct rf_channel rf;
rt2x00_rf_read(rt2x00dev, 1, &rf.rf1);
rt2x00_rf_read(rt2x00dev, 2, &rf.rf2);
rt2x00_rf_read(rt2x00dev, 3, &rf.rf3);
rt2x00_rf_read(rt2x00dev, 4, &rf.rf4);
rt61pci_config_channel(rt2x00dev, &rf, txpower);
}
static void rt61pci_config_retry_limit(struct rt2x00_dev *rt2x00dev,
struct rt2x00lib_conf *libconf)
rt2x00pci_register_read(rt2x00dev, TXRX_CSR4, ®);
rt2x00_set_field32(®, TXRX_CSR4_OFDM_TX_RATE_DOWN, 1);
rt2x00_set_field32(®, TXRX_CSR4_OFDM_TX_RATE_STEP, 0);
rt2x00_set_field32(®, TXRX_CSR4_OFDM_TX_FALLBACK_CCK, 0);
rt2x00_set_field32(®, TXRX_CSR4_LONG_RETRY_LIMIT,
libconf->conf->long_frame_max_tx_count);
rt2x00_set_field32(®, TXRX_CSR4_SHORT_RETRY_LIMIT,
libconf->conf->short_frame_max_tx_count);
rt2x00pci_register_write(rt2x00dev, TXRX_CSR4, reg);
}
static void rt61pci_config_ps(struct rt2x00_dev *rt2x00dev,
struct rt2x00lib_conf *libconf)
{
enum dev_state state =
(libconf->conf->flags & IEEE80211_CONF_PS) ?
STATE_SLEEP : STATE_AWAKE;
u32 reg;
if (state == STATE_SLEEP) {
rt2x00pci_register_read(rt2x00dev, MAC_CSR11, ®);
rt2x00_set_field32(®, MAC_CSR11_DELAY_AFTER_TBCN,
rt2x00dev->beacon_int - 10);
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
rt2x00_set_field32(®, MAC_CSR11_TBCN_BEFORE_WAKEUP,
libconf->conf->listen_interval - 1);
rt2x00_set_field32(®, MAC_CSR11_WAKEUP_LATENCY, 5);
/* We must first disable autowake before it can be enabled */
rt2x00_set_field32(®, MAC_CSR11_AUTOWAKE, 0);
rt2x00pci_register_write(rt2x00dev, MAC_CSR11, reg);
rt2x00_set_field32(®, MAC_CSR11_AUTOWAKE, 1);
rt2x00pci_register_write(rt2x00dev, MAC_CSR11, reg);
rt2x00pci_register_write(rt2x00dev, SOFT_RESET_CSR, 0x00000005);
rt2x00pci_register_write(rt2x00dev, IO_CNTL_CSR, 0x0000001c);
rt2x00pci_register_write(rt2x00dev, PCI_USEC_CSR, 0x00000060);
rt61pci_mcu_request(rt2x00dev, MCU_SLEEP, 0xff, 0, 0);
} else {
rt2x00pci_register_read(rt2x00dev, MAC_CSR11, ®);
rt2x00_set_field32(®, MAC_CSR11_DELAY_AFTER_TBCN, 0);
rt2x00_set_field32(®, MAC_CSR11_TBCN_BEFORE_WAKEUP, 0);
rt2x00_set_field32(®, MAC_CSR11_AUTOWAKE, 0);
rt2x00_set_field32(®, MAC_CSR11_WAKEUP_LATENCY, 0);
rt2x00pci_register_write(rt2x00dev, MAC_CSR11, reg);
rt2x00pci_register_write(rt2x00dev, SOFT_RESET_CSR, 0x00000007);
rt2x00pci_register_write(rt2x00dev, IO_CNTL_CSR, 0x00000018);
rt2x00pci_register_write(rt2x00dev, PCI_USEC_CSR, 0x00000020);
rt61pci_mcu_request(rt2x00dev, MCU_WAKEUP, 0xff, 0, 0);
}
}
static void rt61pci_config(struct rt2x00_dev *rt2x00dev,
struct rt2x00lib_conf *libconf,
const unsigned int flags)