1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660 |
- /*
- Copyright (C) 2009 Bartlomiej Zolnierkiewicz
- Based on the original rt2800pci.c and rt2800usb.c:
- Copyright (C) 2004 - 2009 rt2x00 SourceForge Project
- <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: rt2800lib
- Abstract: rt2800 generic device routines.
- */
- #include <linux/kernel.h>
- #include <linux/module.h>
- #include "rt2x00.h"
- #ifdef CONFIG_RT2800USB
- #include "rt2x00usb.h"
- #endif
- #include "rt2800lib.h"
- #include "rt2800.h"
- #include "rt2800usb.h"
- MODULE_AUTHOR("Bartlomiej Zolnierkiewicz");
- MODULE_DESCRIPTION("rt2800 library");
- MODULE_LICENSE("GPL");
- /*
- * Register access.
- * All access to the CSR registers will go through the methods
- * rt2800_register_read and rt2800_register_write.
- * BBP and RF register require indirect register access,
- * and use the CSR registers BBPCSR and RFCSR 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 attampt. When the busy bit is still set at that time,
- * the access attempt is considered to have failed,
- * and we will print an error.
- * The _lock versions must be used if you already hold the csr_mutex
- */
- #define WAIT_FOR_BBP(__dev, __reg) \
- rt2800_regbusy_read((__dev), BBP_CSR_CFG, BBP_CSR_CFG_BUSY, (__reg))
- #define WAIT_FOR_RFCSR(__dev, __reg) \
- rt2800_regbusy_read((__dev), RF_CSR_CFG, RF_CSR_CFG_BUSY, (__reg))
- #define WAIT_FOR_RF(__dev, __reg) \
- rt2800_regbusy_read((__dev), RF_CSR_CFG0, RF_CSR_CFG0_BUSY, (__reg))
- #define WAIT_FOR_MCU(__dev, __reg) \
- rt2800_regbusy_read((__dev), H2M_MAILBOX_CSR, \
- H2M_MAILBOX_CSR_OWNER, (__reg))
- static void rt2800_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(®, BBP_CSR_CFG_VALUE, value);
- rt2x00_set_field32(®, BBP_CSR_CFG_REGNUM, word);
- rt2x00_set_field32(®, BBP_CSR_CFG_BUSY, 1);
- rt2x00_set_field32(®, BBP_CSR_CFG_READ_CONTROL, 0);
- if (rt2x00_intf_is_pci(rt2x00dev))
- rt2x00_set_field32(®, BBP_CSR_CFG_BBP_RW_MODE, 1);
- rt2800_register_write_lock(rt2x00dev, BBP_CSR_CFG, reg);
- }
- mutex_unlock(&rt2x00dev->csr_mutex);
- }
- static void rt2800_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(®, BBP_CSR_CFG_REGNUM, word);
- rt2x00_set_field32(®, BBP_CSR_CFG_BUSY, 1);
- rt2x00_set_field32(®, BBP_CSR_CFG_READ_CONTROL, 1);
- if (rt2x00_intf_is_pci(rt2x00dev))
- rt2x00_set_field32(®, BBP_CSR_CFG_BBP_RW_MODE, 1);
- rt2800_register_write_lock(rt2x00dev, BBP_CSR_CFG, reg);
- WAIT_FOR_BBP(rt2x00dev, ®);
- }
- *value = rt2x00_get_field32(reg, BBP_CSR_CFG_VALUE);
- mutex_unlock(&rt2x00dev->csr_mutex);
- }
- static void rt2800_rfcsr_write(struct rt2x00_dev *rt2x00dev,
- const unsigned int word, const u8 value)
- {
- u32 reg;
- mutex_lock(&rt2x00dev->csr_mutex);
- /*
- * Wait until the RFCSR becomes available, afterwards we
- * can safely write the new data into the register.
- */
- if (WAIT_FOR_RFCSR(rt2x00dev, ®)) {
- reg = 0;
- rt2x00_set_field32(®, RF_CSR_CFG_DATA, value);
- rt2x00_set_field32(®, RF_CSR_CFG_REGNUM, word);
- rt2x00_set_field32(®, RF_CSR_CFG_WRITE, 1);
- rt2x00_set_field32(®, RF_CSR_CFG_BUSY, 1);
- rt2800_register_write_lock(rt2x00dev, RF_CSR_CFG, reg);
- }
- mutex_unlock(&rt2x00dev->csr_mutex);
- }
- static void rt2800_rfcsr_read(struct rt2x00_dev *rt2x00dev,
- const unsigned int word, u8 *value)
- {
- u32 reg;
- mutex_lock(&rt2x00dev->csr_mutex);
- /*
- * Wait until the RFCSR 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_RFCSR(rt2x00dev, ®)) {
- reg = 0;
- rt2x00_set_field32(®, RF_CSR_CFG_REGNUM, word);
- rt2x00_set_field32(®, RF_CSR_CFG_WRITE, 0);
- rt2x00_set_field32(®, RF_CSR_CFG_BUSY, 1);
- rt2800_register_write_lock(rt2x00dev, RF_CSR_CFG, reg);
- WAIT_FOR_RFCSR(rt2x00dev, ®);
- }
- *value = rt2x00_get_field32(reg, RF_CSR_CFG_DATA);
- mutex_unlock(&rt2x00dev->csr_mutex);
- }
- static void rt2800_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(®, RF_CSR_CFG0_REG_VALUE_BW, value);
- rt2x00_set_field32(®, RF_CSR_CFG0_STANDBYMODE, 0);
- rt2x00_set_field32(®, RF_CSR_CFG0_SEL, 0);
- rt2x00_set_field32(®, RF_CSR_CFG0_BUSY, 1);
- rt2800_register_write_lock(rt2x00dev, RF_CSR_CFG0, reg);
- rt2x00_rf_write(rt2x00dev, word, value);
- }
- mutex_unlock(&rt2x00dev->csr_mutex);
- }
- void rt2800_mcu_request(struct rt2x00_dev *rt2x00dev,
- const u8 command, const u8 token,
- const u8 arg0, const u8 arg1)
- {
- u32 reg;
- if (rt2x00_intf_is_pci(rt2x00dev)) {
- /*
- * RT2880 and RT3052 don't support MCU requests.
- */
- if (rt2x00_rt(&rt2x00dev->chip, RT2880) ||
- rt2x00_rt(&rt2x00dev->chip, RT3052))
- return;
- }
- 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);
- rt2800_register_write_lock(rt2x00dev, H2M_MAILBOX_CSR, reg);
- reg = 0;
- rt2x00_set_field32(®, HOST_CMD_CSR_HOST_COMMAND, command);
- rt2800_register_write_lock(rt2x00dev, HOST_CMD_CSR, reg);
- }
- mutex_unlock(&rt2x00dev->csr_mutex);
- }
- EXPORT_SYMBOL_GPL(rt2800_mcu_request);
- #ifdef CONFIG_RT2X00_LIB_DEBUGFS
- const struct rt2x00debug rt2800_rt2x00debug = {
- .owner = THIS_MODULE,
- .csr = {
- .read = rt2800_register_read,
- .write = rt2800_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_base = EEPROM_BASE,
- .word_size = sizeof(u16),
- .word_count = EEPROM_SIZE / sizeof(u16),
- },
- .bbp = {
- .read = rt2800_bbp_read,
- .write = rt2800_bbp_write,
- .word_base = BBP_BASE,
- .word_size = sizeof(u8),
- .word_count = BBP_SIZE / sizeof(u8),
- },
- .rf = {
- .read = rt2x00_rf_read,
- .write = rt2800_rf_write,
- .word_base = RF_BASE,
- .word_size = sizeof(u32),
- .word_count = RF_SIZE / sizeof(u32),
- },
- };
- EXPORT_SYMBOL_GPL(rt2800_rt2x00debug);
- #endif /* CONFIG_RT2X00_LIB_DEBUGFS */
- int rt2800_rfkill_poll(struct rt2x00_dev *rt2x00dev)
- {
- u32 reg;
- rt2800_register_read(rt2x00dev, GPIO_CTRL_CFG, ®);
- return rt2x00_get_field32(reg, GPIO_CTRL_CFG_BIT2);
- }
- EXPORT_SYMBOL_GPL(rt2800_rfkill_poll);
- #ifdef CONFIG_RT2X00_LIB_LEDS
- static void rt2800_brightness_set(struct led_classdev *led_cdev,
- 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 bg_mode =
- (enabled && led->rt2x00dev->curr_band == IEEE80211_BAND_2GHZ);
- unsigned int polarity =
- rt2x00_get_field16(led->rt2x00dev->led_mcu_reg,
- EEPROM_FREQ_LED_POLARITY);
- unsigned int ledmode =
- rt2x00_get_field16(led->rt2x00dev->led_mcu_reg,
- EEPROM_FREQ_LED_MODE);
- if (led->type == LED_TYPE_RADIO) {
- rt2800_mcu_request(led->rt2x00dev, MCU_LED, 0xff, ledmode,
- enabled ? 0x20 : 0);
- } else if (led->type == LED_TYPE_ASSOC) {
- rt2800_mcu_request(led->rt2x00dev, MCU_LED, 0xff, ledmode,
- enabled ? (bg_mode ? 0x60 : 0xa0) : 0x20);
- } else if (led->type == LED_TYPE_QUALITY) {
- /*
- * The brightness is divided into 6 levels (0 - 5),
- * The specs tell us the following levels:
- * 0, 1 ,3, 7, 15, 31
- * to determine the level in a simple way we can simply
- * work with bitshifting:
- * (1 << level) - 1
- */
- rt2800_mcu_request(led->rt2x00dev, MCU_LED_STRENGTH, 0xff,
- (1 << brightness / (LED_FULL / 6)) - 1,
- polarity);
- }
- }
- static int rt2800_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;
- rt2800_register_read(led->rt2x00dev, LED_CFG, ®);
- rt2x00_set_field32(®, LED_CFG_ON_PERIOD, *delay_on);
- rt2x00_set_field32(®, LED_CFG_OFF_PERIOD, *delay_off);
- rt2x00_set_field32(®, LED_CFG_SLOW_BLINK_PERIOD, 3);
- rt2x00_set_field32(®, LED_CFG_R_LED_MODE, 3);
- rt2x00_set_field32(®, LED_CFG_G_LED_MODE, 12);
- rt2x00_set_field32(®, LED_CFG_Y_LED_MODE, 3);
- rt2x00_set_field32(®, LED_CFG_LED_POLAR, 1);
- rt2800_register_write(led->rt2x00dev, LED_CFG, reg);
- return 0;
- }
- void rt2800_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 = rt2800_brightness_set;
- led->led_dev.blink_set = rt2800_blink_set;
- led->flags = LED_INITIALIZED;
- }
- EXPORT_SYMBOL_GPL(rt2800_init_led);
- #endif /* CONFIG_RT2X00_LIB_LEDS */
- /*
- * Configuration handlers.
- */
- static void rt2800_config_wcid_attr(struct rt2x00_dev *rt2x00dev,
- struct rt2x00lib_crypto *crypto,
- struct ieee80211_key_conf *key)
- {
- struct mac_wcid_entry wcid_entry;
- struct mac_iveiv_entry iveiv_entry;
- u32 offset;
- u32 reg;
- offset = MAC_WCID_ATTR_ENTRY(key->hw_key_idx);
- rt2800_register_read(rt2x00dev, offset, ®);
- rt2x00_set_field32(®, MAC_WCID_ATTRIBUTE_KEYTAB,
- !!(key->flags & IEEE80211_KEY_FLAG_PAIRWISE));
- rt2x00_set_field32(®, MAC_WCID_ATTRIBUTE_CIPHER,
- (crypto->cmd == SET_KEY) * crypto->cipher);
- rt2x00_set_field32(®, MAC_WCID_ATTRIBUTE_BSS_IDX,
- (crypto->cmd == SET_KEY) * crypto->bssidx);
- rt2x00_set_field32(®, MAC_WCID_ATTRIBUTE_RX_WIUDF, crypto->cipher);
- rt2800_register_write(rt2x00dev, offset, reg);
- offset = MAC_IVEIV_ENTRY(key->hw_key_idx);
- memset(&iveiv_entry, 0, sizeof(iveiv_entry));
- if ((crypto->cipher == CIPHER_TKIP) ||
- (crypto->cipher == CIPHER_TKIP_NO_MIC) ||
- (crypto->cipher == CIPHER_AES))
- iveiv_entry.iv[3] |= 0x20;
- iveiv_entry.iv[3] |= key->keyidx << 6;
- rt2800_register_multiwrite(rt2x00dev, offset,
- &iveiv_entry, sizeof(iveiv_entry));
- offset = MAC_WCID_ENTRY(key->hw_key_idx);
- memset(&wcid_entry, 0, sizeof(wcid_entry));
- if (crypto->cmd == SET_KEY)
- memcpy(&wcid_entry, crypto->address, ETH_ALEN);
- rt2800_register_multiwrite(rt2x00dev, offset,
- &wcid_entry, sizeof(wcid_entry));
- }
- int rt2800_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 offset;
- u32 reg;
- if (crypto->cmd == SET_KEY) {
- key->hw_key_idx = (4 * crypto->bssidx) + key->keyidx;
- 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));
- offset = SHARED_KEY_ENTRY(key->hw_key_idx);
- rt2800_register_multiwrite(rt2x00dev, offset,
- &key_entry, sizeof(key_entry));
- }
- /*
- * The cipher types are stored over multiple registers
- * starting with SHARED_KEY_MODE_BASE each word will have
- * 32 bits and contains the cipher types for 2 bssidx each.
- * Using the correct defines correctly will cause overhead,
- * so just calculate the correct offset.
- */
- field.bit_offset = 4 * (key->hw_key_idx % 8);
- field.bit_mask = 0x7 << field.bit_offset;
- offset = SHARED_KEY_MODE_ENTRY(key->hw_key_idx / 8);
- rt2800_register_read(rt2x00dev, offset, ®);
- rt2x00_set_field32(®, field,
- (crypto->cmd == SET_KEY) * crypto->cipher);
- rt2800_register_write(rt2x00dev, offset, reg);
- /*
- * Update WCID information
- */
- rt2800_config_wcid_attr(rt2x00dev, crypto, key);
- return 0;
- }
- EXPORT_SYMBOL_GPL(rt2800_config_shared_key);
- int rt2800_config_pairwise_key(struct rt2x00_dev *rt2x00dev,
- struct rt2x00lib_crypto *crypto,
- struct ieee80211_key_conf *key)
- {
- struct hw_key_entry key_entry;
- u32 offset;
- if (crypto->cmd == SET_KEY) {
- /*
- * 1 pairwise key is possible per AID, this means that the AID
- * equals our hw_key_idx. Make sure the WCID starts _after_ the
- * last possible shared key entry.
- */
- if (crypto->aid > (256 - 32))
- return -ENOSPC;
- key->hw_key_idx = 32 + crypto->aid;
- 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));
- offset = PAIRWISE_KEY_ENTRY(key->hw_key_idx);
- rt2800_register_multiwrite(rt2x00dev, offset,
- &key_entry, sizeof(key_entry));
- }
- /*
- * Update WCID information
- */
- rt2800_config_wcid_attr(rt2x00dev, crypto, key);
- return 0;
- }
- EXPORT_SYMBOL_GPL(rt2800_config_pairwise_key);
- void rt2800_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.
- */
- rt2800_register_read(rt2x00dev, RX_FILTER_CFG, ®);
- rt2x00_set_field32(®, RX_FILTER_CFG_DROP_CRC_ERROR,
- !(filter_flags & FIF_FCSFAIL));
- rt2x00_set_field32(®, RX_FILTER_CFG_DROP_PHY_ERROR,
- !(filter_flags & FIF_PLCPFAIL));
- rt2x00_set_field32(®, RX_FILTER_CFG_DROP_NOT_TO_ME,
- !(filter_flags & FIF_PROMISC_IN_BSS));
- rt2x00_set_field32(®, RX_FILTER_CFG_DROP_NOT_MY_BSSD, 0);
- rt2x00_set_field32(®, RX_FILTER_CFG_DROP_VER_ERROR, 1);
- rt2x00_set_field32(®, RX_FILTER_CFG_DROP_MULTICAST,
- !(filter_flags & FIF_ALLMULTI));
- rt2x00_set_field32(®, RX_FILTER_CFG_DROP_BROADCAST, 0);
- rt2x00_set_field32(®, RX_FILTER_CFG_DROP_DUPLICATE, 1);
- rt2x00_set_field32(®, RX_FILTER_CFG_DROP_CF_END_ACK,
- !(filter_flags & FIF_CONTROL));
- rt2x00_set_field32(®, RX_FILTER_CFG_DROP_CF_END,
- !(filter_flags & FIF_CONTROL));
- rt2x00_set_field32(®, RX_FILTER_CFG_DROP_ACK,
- !(filter_flags & FIF_CONTROL));
- rt2x00_set_field32(®, RX_FILTER_CFG_DROP_CTS,
- !(filter_flags & FIF_CONTROL));
- rt2x00_set_field32(®, RX_FILTER_CFG_DROP_RTS,
- !(filter_flags & FIF_CONTROL));
- rt2x00_set_field32(®, RX_FILTER_CFG_DROP_PSPOLL,
- !(filter_flags & FIF_PSPOLL));
- rt2x00_set_field32(®, RX_FILTER_CFG_DROP_BA, 1);
- rt2x00_set_field32(®, RX_FILTER_CFG_DROP_BAR, 0);
- rt2x00_set_field32(®, RX_FILTER_CFG_DROP_CNTL,
- !(filter_flags & FIF_CONTROL));
- rt2800_register_write(rt2x00dev, RX_FILTER_CFG, reg);
- }
- EXPORT_SYMBOL_GPL(rt2800_config_filter);
- void rt2800_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);
- rt2800_register_write(rt2x00dev, beacon_base, 0);
- /*
- * Enable synchronisation.
- */
- rt2800_register_read(rt2x00dev, BCN_TIME_CFG, ®);
- rt2x00_set_field32(®, BCN_TIME_CFG_TSF_TICKING, 1);
- rt2x00_set_field32(®, BCN_TIME_CFG_TSF_SYNC, conf->sync);
- rt2x00_set_field32(®, BCN_TIME_CFG_TBTT_ENABLE, 1);
- rt2800_register_write(rt2x00dev, BCN_TIME_CFG, reg);
- }
- if (flags & CONFIG_UPDATE_MAC) {
- reg = le32_to_cpu(conf->mac[1]);
- rt2x00_set_field32(®, MAC_ADDR_DW1_UNICAST_TO_ME_MASK, 0xff);
- conf->mac[1] = cpu_to_le32(reg);
- rt2800_register_multiwrite(rt2x00dev, MAC_ADDR_DW0,
- conf->mac, sizeof(conf->mac));
- }
- if (flags & CONFIG_UPDATE_BSSID) {
- reg = le32_to_cpu(conf->bssid[1]);
- rt2x00_set_field32(®, MAC_BSSID_DW1_BSS_ID_MASK, 0);
- rt2x00_set_field32(®, MAC_BSSID_DW1_BSS_BCN_NUM, 0);
- conf->bssid[1] = cpu_to_le32(reg);
- rt2800_register_multiwrite(rt2x00dev, MAC_BSSID_DW0,
- conf->bssid, sizeof(conf->bssid));
- }
- }
- EXPORT_SYMBOL_GPL(rt2800_config_intf);
- void rt2800_config_erp(struct rt2x00_dev *rt2x00dev, struct rt2x00lib_erp *erp)
- {
- u32 reg;
- rt2800_register_read(rt2x00dev, TX_TIMEOUT_CFG, ®);
- rt2x00_set_field32(®, TX_TIMEOUT_CFG_RX_ACK_TIMEOUT, 0x20);
- rt2800_register_write(rt2x00dev, TX_TIMEOUT_CFG, reg);
- rt2800_register_read(rt2x00dev, AUTO_RSP_CFG, ®);
- rt2x00_set_field32(®, AUTO_RSP_CFG_BAC_ACK_POLICY,
- !!erp->short_preamble);
- rt2x00_set_field32(®, AUTO_RSP_CFG_AR_PREAMBLE,
- !!erp->short_preamble);
- rt2800_register_write(rt2x00dev, AUTO_RSP_CFG, reg);
- rt2800_register_read(rt2x00dev, OFDM_PROT_CFG, ®);
- rt2x00_set_field32(®, OFDM_PROT_CFG_PROTECT_CTRL,
- erp->cts_protection ? 2 : 0);
- rt2800_register_write(rt2x00dev, OFDM_PROT_CFG, reg);
- rt2800_register_write(rt2x00dev, LEGACY_BASIC_RATE,
- erp->basic_rates);
- rt2800_register_write(rt2x00dev, HT_BASIC_RATE, 0x00008003);
- rt2800_register_read(rt2x00dev, BKOFF_SLOT_CFG, ®);
- rt2x00_set_field32(®, BKOFF_SLOT_CFG_SLOT_TIME, erp->slot_time);
- rt2x00_set_field32(®, BKOFF_SLOT_CFG_CC_DELAY_TIME, 2);
- rt2800_register_write(rt2x00dev, BKOFF_SLOT_CFG, reg);
- rt2800_register_read(rt2x00dev, XIFS_TIME_CFG, ®);
- rt2x00_set_field32(®, XIFS_TIME_CFG_CCKM_SIFS_TIME, erp->sifs);
- rt2x00_set_field32(®, XIFS_TIME_CFG_OFDM_SIFS_TIME, erp->sifs);
- rt2x00_set_field32(®, XIFS_TIME_CFG_OFDM_XIFS_TIME, 4);
- rt2x00_set_field32(®, XIFS_TIME_CFG_EIFS, erp->eifs);
- rt2x00_set_field32(®, XIFS_TIME_CFG_BB_RXEND_ENABLE, 1);
- rt2800_register_write(rt2x00dev, XIFS_TIME_CFG, reg);
- rt2800_register_read(rt2x00dev, BCN_TIME_CFG, ®);
- rt2x00_set_field32(®, BCN_TIME_CFG_BEACON_INTERVAL,
- erp->beacon_int * 16);
- rt2800_register_write(rt2x00dev, BCN_TIME_CFG, reg);
- }
- EXPORT_SYMBOL_GPL(rt2800_config_erp);
- void rt2800_config_ant(struct rt2x00_dev *rt2x00dev, struct antenna_setup *ant)
- {
- u8 r1;
- u8 r3;
- rt2800_bbp_read(rt2x00dev, 1, &r1);
- rt2800_bbp_read(rt2x00dev, 3, &r3);
- /*
- * Configure the TX antenna.
- */
- switch ((int)ant->tx) {
- case 1:
- rt2x00_set_field8(&r1, BBP1_TX_ANTENNA, 0);
- if (rt2x00_intf_is_pci(rt2x00dev))
- rt2x00_set_field8(&r3, BBP3_RX_ANTENNA, 0);
- break;
- case 2:
- rt2x00_set_field8(&r1, BBP1_TX_ANTENNA, 2);
- break;
- case 3:
- /* Do nothing */
- break;
- }
- /*
- * Configure the RX antenna.
- */
- switch ((int)ant->rx) {
- case 1:
- rt2x00_set_field8(&r3, BBP3_RX_ANTENNA, 0);
- break;
- case 2:
- rt2x00_set_field8(&r3, BBP3_RX_ANTENNA, 1);
- break;
- case 3:
- rt2x00_set_field8(&r3, BBP3_RX_ANTENNA, 2);
- break;
- }
- rt2800_bbp_write(rt2x00dev, 3, r3);
- rt2800_bbp_write(rt2x00dev, 1, r1);
- }
- EXPORT_SYMBOL_GPL(rt2800_config_ant);
- static void rt2800_config_lna_gain(struct rt2x00_dev *rt2x00dev,
- struct rt2x00lib_conf *libconf)
- {
- u16 eeprom;
- short lna_gain;
- if (libconf->rf.channel <= 14) {
- rt2x00_eeprom_read(rt2x00dev, EEPROM_LNA, &eeprom);
- lna_gain = rt2x00_get_field16(eeprom, EEPROM_LNA_BG);
- } else if (libconf->rf.channel <= 64) {
- rt2x00_eeprom_read(rt2x00dev, EEPROM_LNA, &eeprom);
- lna_gain = rt2x00_get_field16(eeprom, EEPROM_LNA_A0);
- } else if (libconf->rf.channel <= 128) {
- rt2x00_eeprom_read(rt2x00dev, EEPROM_RSSI_BG2, &eeprom);
- lna_gain = rt2x00_get_field16(eeprom, EEPROM_RSSI_BG2_LNA_A1);
- } else {
- rt2x00_eeprom_read(rt2x00dev, EEPROM_RSSI_A2, &eeprom);
- lna_gain = rt2x00_get_field16(eeprom, EEPROM_RSSI_A2_LNA_A2);
- }
- rt2x00dev->lna_gain = lna_gain;
- }
- static void rt2800_config_channel_rt2x(struct rt2x00_dev *rt2x00dev,
- struct ieee80211_conf *conf,
- struct rf_channel *rf,
- struct channel_info *info)
- {
- rt2x00_set_field32(&rf->rf4, RF4_FREQ_OFFSET, rt2x00dev->freq_offset);
- if (rt2x00dev->default_ant.tx == 1)
- rt2x00_set_field32(&rf->rf2, RF2_ANTENNA_TX1, 1);
- if (rt2x00dev->default_ant.rx == 1) {
- rt2x00_set_field32(&rf->rf2, RF2_ANTENNA_RX1, 1);
- rt2x00_set_field32(&rf->rf2, RF2_ANTENNA_RX2, 1);
- } else if (rt2x00dev->default_ant.rx == 2)
- rt2x00_set_field32(&rf->rf2, RF2_ANTENNA_RX2, 1);
- if (rf->channel > 14) {
- /*
- * When TX power is below 0, we should increase it by 7 to
- * make it a positive value (Minumum value is -7).
- * However this means that values between 0 and 7 have
- * double meaning, and we should set a 7DBm boost flag.
- */
- rt2x00_set_field32(&rf->rf3, RF3_TXPOWER_A_7DBM_BOOST,
- (info->tx_power1 >= 0));
- if (info->tx_power1 < 0)
- info->tx_power1 += 7;
- rt2x00_set_field32(&rf->rf3, RF3_TXPOWER_A,
- TXPOWER_A_TO_DEV(info->tx_power1));
- rt2x00_set_field32(&rf->rf4, RF4_TXPOWER_A_7DBM_BOOST,
- (info->tx_power2 >= 0));
- if (info->tx_power2 < 0)
- info->tx_power2 += 7;
- rt2x00_set_field32(&rf->rf4, RF4_TXPOWER_A,
- TXPOWER_A_TO_DEV(info->tx_power2));
- } else {
- rt2x00_set_field32(&rf->rf3, RF3_TXPOWER_G,
- TXPOWER_G_TO_DEV(info->tx_power1));
- rt2x00_set_field32(&rf->rf4, RF4_TXPOWER_G,
- TXPOWER_G_TO_DEV(info->tx_power2));
- }
- rt2x00_set_field32(&rf->rf4, RF4_HT40, conf_is_ht40(conf));
- rt2800_rf_write(rt2x00dev, 1, rf->rf1);
- rt2800_rf_write(rt2x00dev, 2, rf->rf2);
- rt2800_rf_write(rt2x00dev, 3, rf->rf3 & ~0x00000004);
- rt2800_rf_write(rt2x00dev, 4, rf->rf4);
- udelay(200);
- rt2800_rf_write(rt2x00dev, 1, rf->rf1);
- rt2800_rf_write(rt2x00dev, 2, rf->rf2);
- rt2800_rf_write(rt2x00dev, 3, rf->rf3 | 0x00000004);
- rt2800_rf_write(rt2x00dev, 4, rf->rf4);
- udelay(200);
- rt2800_rf_write(rt2x00dev, 1, rf->rf1);
- rt2800_rf_write(rt2x00dev, 2, rf->rf2);
- rt2800_rf_write(rt2x00dev, 3, rf->rf3 & ~0x00000004);
- rt2800_rf_write(rt2x00dev, 4, rf->rf4);
- }
- static void rt2800_config_channel_rt3x(struct rt2x00_dev *rt2x00dev,
- struct ieee80211_conf *conf,
- struct rf_channel *rf,
- struct channel_info *info)
- {
- u8 rfcsr;
- rt2800_rfcsr_write(rt2x00dev, 2, rf->rf1);
- rt2800_rfcsr_write(rt2x00dev, 2, rf->rf3);
- rt2800_rfcsr_read(rt2x00dev, 6, &rfcsr);
- rt2x00_set_field8(&rfcsr, RFCSR6_R, rf->rf2);
- rt2800_rfcsr_write(rt2x00dev, 6, rfcsr);
- rt2800_rfcsr_read(rt2x00dev, 12, &rfcsr);
- rt2x00_set_field8(&rfcsr, RFCSR12_TX_POWER,
- TXPOWER_G_TO_DEV(info->tx_power1));
- rt2800_rfcsr_write(rt2x00dev, 12, rfcsr);
- rt2800_rfcsr_read(rt2x00dev, 23, &rfcsr);
- rt2x00_set_field8(&rfcsr, RFCSR23_FREQ_OFFSET, rt2x00dev->freq_offset);
- rt2800_rfcsr_write(rt2x00dev, 23, rfcsr);
- rt2800_rfcsr_write(rt2x00dev, 24,
- rt2x00dev->calibration[conf_is_ht40(conf)]);
- rt2800_rfcsr_read(rt2x00dev, 23, &rfcsr);
- rt2x00_set_field8(&rfcsr, RFCSR7_RF_TUNING, 1);
- rt2800_rfcsr_write(rt2x00dev, 23, rfcsr);
- }
- static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev,
- struct ieee80211_conf *conf,
- struct rf_channel *rf,
- struct channel_info *info)
- {
- u32 reg;
- unsigned int tx_pin;
- u8 bbp;
- if (rt2x00_rev(&rt2x00dev->chip) != RT3070_VERSION)
- rt2800_config_channel_rt2x(rt2x00dev, conf, rf, info);
- else
- rt2800_config_channel_rt3x(rt2x00dev, conf, rf, info);
- /*
- * Change BBP settings
- */
- rt2800_bbp_write(rt2x00dev, 62, 0x37 - rt2x00dev->lna_gain);
- rt2800_bbp_write(rt2x00dev, 63, 0x37 - rt2x00dev->lna_gain);
- rt2800_bbp_write(rt2x00dev, 64, 0x37 - rt2x00dev->lna_gain);
- rt2800_bbp_write(rt2x00dev, 86, 0);
- if (rf->channel <= 14) {
- if (test_bit(CONFIG_EXTERNAL_LNA_BG, &rt2x00dev->flags)) {
- rt2800_bbp_write(rt2x00dev, 82, 0x62);
- rt2800_bbp_write(rt2x00dev, 75, 0x46);
- } else {
- rt2800_bbp_write(rt2x00dev, 82, 0x84);
- rt2800_bbp_write(rt2x00dev, 75, 0x50);
- }
- } else {
- rt2800_bbp_write(rt2x00dev, 82, 0xf2);
- if (test_bit(CONFIG_EXTERNAL_LNA_A, &rt2x00dev->flags))
- rt2800_bbp_write(rt2x00dev, 75, 0x46);
- else
- rt2800_bbp_write(rt2x00dev, 75, 0x50);
- }
- rt2800_register_read(rt2x00dev, TX_BAND_CFG, ®);
- rt2x00_set_field32(®, TX_BAND_CFG_HT40_PLUS, conf_is_ht40_plus(conf));
- rt2x00_set_field32(®, TX_BAND_CFG_A, rf->channel > 14);
- rt2x00_set_field32(®, TX_BAND_CFG_BG, rf->channel <= 14);
- rt2800_register_write(rt2x00dev, TX_BAND_CFG, reg);
- tx_pin = 0;
- /* Turn on unused PA or LNA when not using 1T or 1R */
- if (rt2x00dev->default_ant.tx != 1) {
- rt2x00_set_field32(&tx_pin, TX_PIN_CFG_PA_PE_A1_EN, 1);
- rt2x00_set_field32(&tx_pin, TX_PIN_CFG_PA_PE_G1_EN, 1);
- }
- /* Turn on unused PA or LNA when not using 1T or 1R */
- if (rt2x00dev->default_ant.rx != 1) {
- rt2x00_set_field32(&tx_pin, TX_PIN_CFG_LNA_PE_A1_EN, 1);
- rt2x00_set_field32(&tx_pin, TX_PIN_CFG_LNA_PE_G1_EN, 1);
- }
- rt2x00_set_field32(&tx_pin, TX_PIN_CFG_LNA_PE_A0_EN, 1);
- rt2x00_set_field32(&tx_pin, TX_PIN_CFG_LNA_PE_G0_EN, 1);
- rt2x00_set_field32(&tx_pin, TX_PIN_CFG_RFTR_EN, 1);
- rt2x00_set_field32(&tx_pin, TX_PIN_CFG_TRSW_EN, 1);
- rt2x00_set_field32(&tx_pin, TX_PIN_CFG_PA_PE_G0_EN, rf->channel <= 14);
- rt2x00_set_field32(&tx_pin, TX_PIN_CFG_PA_PE_A0_EN, rf->channel > 14);
- rt2800_register_write(rt2x00dev, TX_PIN_CFG, tx_pin);
- rt2800_bbp_read(rt2x00dev, 4, &bbp);
- rt2x00_set_field8(&bbp, BBP4_BANDWIDTH, 2 * conf_is_ht40(conf));
- rt2800_bbp_write(rt2x00dev, 4, bbp);
- rt2800_bbp_read(rt2x00dev, 3, &bbp);
- rt2x00_set_field8(&bbp, BBP3_HT40_PLUS, conf_is_ht40_plus(conf));
- rt2800_bbp_write(rt2x00dev, 3, bbp);
- if (rt2x00_rev(&rt2x00dev->chip) == RT2860C_VERSION) {
- if (conf_is_ht40(conf)) {
- rt2800_bbp_write(rt2x00dev, 69, 0x1a);
- rt2800_bbp_write(rt2x00dev, 70, 0x0a);
- rt2800_bbp_write(rt2x00dev, 73, 0x16);
- } else {
- rt2800_bbp_write(rt2x00dev, 69, 0x16);
- rt2800_bbp_write(rt2x00dev, 70, 0x08);
- rt2800_bbp_write(rt2x00dev, 73, 0x11);
- }
- }
- msleep(1);
- }
- static void rt2800_config_txpower(struct rt2x00_dev *rt2x00dev,
- const int txpower)
- {
- u32 reg;
- u32 value = TXPOWER_G_TO_DEV(txpower);
- u8 r1;
- rt2800_bbp_read(rt2x00dev, 1, &r1);
- rt2x00_set_field8(®, BBP1_TX_POWER, 0);
- rt2800_bbp_write(rt2x00dev, 1, r1);
- rt2800_register_read(rt2x00dev, TX_PWR_CFG_0, ®);
- rt2x00_set_field32(®, TX_PWR_CFG_0_1MBS, value);
- rt2x00_set_field32(®, TX_PWR_CFG_0_2MBS, value);
- rt2x00_set_field32(®, TX_PWR_CFG_0_55MBS, value);
- rt2x00_set_field32(®, TX_PWR_CFG_0_11MBS, value);
- rt2x00_set_field32(®, TX_PWR_CFG_0_6MBS, value);
- rt2x00_set_field32(®, TX_PWR_CFG_0_9MBS, value);
- rt2x00_set_field32(®, TX_PWR_CFG_0_12MBS, value);
- rt2x00_set_field32(®, TX_PWR_CFG_0_18MBS, value);
- rt2800_register_write(rt2x00dev, TX_PWR_CFG_0, reg);
- rt2800_register_read(rt2x00dev, TX_PWR_CFG_1, ®);
- rt2x00_set_field32(®, TX_PWR_CFG_1_24MBS, value);
- rt2x00_set_field32(®, TX_PWR_CFG_1_36MBS, value);
- rt2x00_set_field32(®, TX_PWR_CFG_1_48MBS, value);
- rt2x00_set_field32(®, TX_PWR_CFG_1_54MBS, value);
- rt2x00_set_field32(®, TX_PWR_CFG_1_MCS0, value);
- rt2x00_set_field32(®, TX_PWR_CFG_1_MCS1, value);
- rt2x00_set_field32(®, TX_PWR_CFG_1_MCS2, value);
- rt2x00_set_field32(®, TX_PWR_CFG_1_MCS3, value);
- rt2800_register_write(rt2x00dev, TX_PWR_CFG_1, reg);
- rt2800_register_read(rt2x00dev, TX_PWR_CFG_2, ®);
- rt2x00_set_field32(®, TX_PWR_CFG_2_MCS4, value);
- rt2x00_set_field32(®, TX_PWR_CFG_2_MCS5, value);
- rt2x00_set_field32(®, TX_PWR_CFG_2_MCS6, value);
- rt2x00_set_field32(®, TX_PWR_CFG_2_MCS7, value);
- rt2x00_set_field32(®, TX_PWR_CFG_2_MCS8, value);
- rt2x00_set_field32(®, TX_PWR_CFG_2_MCS9, value);
- rt2x00_set_field32(®, TX_PWR_CFG_2_MCS10, value);
- rt2x00_set_field32(®, TX_PWR_CFG_2_MCS11, value);
- rt2800_register_write(rt2x00dev, TX_PWR_CFG_2, reg);
- rt2800_register_read(rt2x00dev, TX_PWR_CFG_3, ®);
- rt2x00_set_field32(®, TX_PWR_CFG_3_MCS12, value);
- rt2x00_set_field32(®, TX_PWR_CFG_3_MCS13, value);
- rt2x00_set_field32(®, TX_PWR_CFG_3_MCS14, value);
- rt2x00_set_field32(®, TX_PWR_CFG_3_MCS15, value);
- rt2x00_set_field32(®, TX_PWR_CFG_3_UKNOWN1, value);
- rt2x00_set_field32(®, TX_PWR_CFG_3_UKNOWN2, value);
- rt2x00_set_field32(®, TX_PWR_CFG_3_UKNOWN3, value);
- rt2x00_set_field32(®, TX_PWR_CFG_3_UKNOWN4, value);
- rt2800_register_write(rt2x00dev, TX_PWR_CFG_3, reg);
- rt2800_register_read(rt2x00dev, TX_PWR_CFG_4, ®);
- rt2x00_set_field32(®, TX_PWR_CFG_4_UKNOWN5, value);
- rt2x00_set_field32(®, TX_PWR_CFG_4_UKNOWN6, value);
- rt2x00_set_field32(®, TX_PWR_CFG_4_UKNOWN7, value);
- rt2x00_set_field32(®, TX_PWR_CFG_4_UKNOWN8, value);
- rt2800_register_write(rt2x00dev, TX_PWR_CFG_4, reg);
- }
- static void rt2800_config_retry_limit(struct rt2x00_dev *rt2x00dev,
- struct rt2x00lib_conf *libconf)
- {
- u32 reg;
- rt2800_register_read(rt2x00dev, TX_RTY_CFG, ®);
- rt2x00_set_field32(®, TX_RTY_CFG_SHORT_RTY_LIMIT,
- libconf->conf->short_frame_max_tx_count);
- rt2x00_set_field32(®, TX_RTY_CFG_LONG_RTY_LIMIT,
- libconf->conf->long_frame_max_tx_count);
- rt2x00_set_field32(®, TX_RTY_CFG_LONG_RTY_THRE, 2000);
- rt2x00_set_field32(®, TX_RTY_CFG_NON_AGG_RTY_MODE, 0);
- rt2x00_set_field32(®, TX_RTY_CFG_AGG_RTY_MODE, 0);
- rt2x00_set_field32(®, TX_RTY_CFG_TX_AUTO_FB_ENABLE, 1);
- rt2800_register_write(rt2x00dev, TX_RTY_CFG, reg);
- }
- static void rt2800_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) {
- rt2800_register_write(rt2x00dev, AUTOWAKEUP_CFG, 0);
- rt2800_register_read(rt2x00dev, AUTOWAKEUP_CFG, ®);
- rt2x00_set_field32(®, AUTOWAKEUP_CFG_AUTO_LEAD_TIME, 5);
- rt2x00_set_field32(®, AUTOWAKEUP_CFG_TBCN_BEFORE_WAKE,
- libconf->conf->listen_interval - 1);
- rt2x00_set_field32(®, AUTOWAKEUP_CFG_AUTOWAKE, 1);
- rt2800_register_write(rt2x00dev, AUTOWAKEUP_CFG, reg);
- rt2x00dev->ops->lib->set_device_state(rt2x00dev, state);
- } else {
- rt2x00dev->ops->lib->set_device_state(rt2x00dev, state);
- rt2800_register_read(rt2x00dev, AUTOWAKEUP_CFG, ®);
- rt2x00_set_field32(®, AUTOWAKEUP_CFG_AUTO_LEAD_TIME, 0);
- rt2x00_set_field32(®, AUTOWAKEUP_CFG_TBCN_BEFORE_WAKE, 0);
- rt2x00_set_field32(®, AUTOWAKEUP_CFG_AUTOWAKE, 0);
- rt2800_register_write(rt2x00dev, AUTOWAKEUP_CFG, reg);
- }
- }
- void rt2800_config(struct rt2x00_dev *rt2x00dev,
- struct rt2x00lib_conf *libconf,
- const unsigned int flags)
- {
- /* Always recalculate LNA gain before changing configuration */
- rt2800_config_lna_gain(rt2x00dev, libconf);
- if (flags & IEEE80211_CONF_CHANGE_CHANNEL)
- rt2800_config_channel(rt2x00dev, libconf->conf,
- &libconf->rf, &libconf->channel);
- if (flags & IEEE80211_CONF_CHANGE_POWER)
- rt2800_config_txpower(rt2x00dev, libconf->conf->power_level);
- if (flags & IEEE80211_CONF_CHANGE_RETRY_LIMITS)
- rt2800_config_retry_limit(rt2x00dev, libconf);
- if (flags & IEEE80211_CONF_CHANGE_PS)
- rt2800_config_ps(rt2x00dev, libconf);
- }
- EXPORT_SYMBOL_GPL(rt2800_config);
- /*
- * Link tuning
- */
- void rt2800_link_stats(struct rt2x00_dev *rt2x00dev, struct link_qual *qual)
- {
- u32 reg;
- /*
- * Update FCS error count from register.
- */
- rt2800_register_read(rt2x00dev, RX_STA_CNT0, ®);
- qual->rx_failed = rt2x00_get_field32(reg, RX_STA_CNT0_CRC_ERR);
- }
- EXPORT_SYMBOL_GPL(rt2800_link_stats);
- static u8 rt2800_get_default_vgc(struct rt2x00_dev *rt2x00dev)
- {
- if (rt2x00dev->curr_band == IEEE80211_BAND_2GHZ) {
- if (rt2x00_intf_is_usb(rt2x00dev) &&
- rt2x00_rev(&rt2x00dev->chip) == RT3070_VERSION)
- return 0x1c + (2 * rt2x00dev->lna_gain);
- else
- return 0x2e + rt2x00dev->lna_gain;
- }
- if (!test_bit(CONFIG_CHANNEL_HT40, &rt2x00dev->flags))
- return 0x32 + (rt2x00dev->lna_gain * 5) / 3;
- else
- return 0x3a + (rt2x00dev->lna_gain * 5) / 3;
- }
- static inline void rt2800_set_vgc(struct rt2x00_dev *rt2x00dev,
- struct link_qual *qual, u8 vgc_level)
- {
- if (qual->vgc_level != vgc_level) {
- rt2800_bbp_write(rt2x00dev, 66, vgc_level);
- qual->vgc_level = vgc_level;
- qual->vgc_level_reg = vgc_level;
- }
- }
- void rt2800_reset_tuner(struct rt2x00_dev *rt2x00dev, struct link_qual *qual)
- {
- rt2800_set_vgc(rt2x00dev, qual, rt2800_get_default_vgc(rt2x00dev));
- }
- EXPORT_SYMBOL_GPL(rt2800_reset_tuner);
- void rt2800_link_tuner(struct rt2x00_dev *rt2x00dev, struct link_qual *qual,
- const u32 count)
- {
- if (rt2x00_rev(&rt2x00dev->chip) == RT2860C_VERSION)
- return;
- /*
- * When RSSI is better then -80 increase VGC level with 0x10
- */
- rt2800_set_vgc(rt2x00dev, qual,
- rt2800_get_default_vgc(rt2x00dev) +
- ((qual->rssi > -80) * 0x10));
- }
- EXPORT_SYMBOL_GPL(rt2800_link_tuner);
- /*
- * Initialization functions.
- */
- int rt2800_init_registers(struct rt2x00_dev *rt2x00dev)
- {
- u32 reg;
- unsigned int i;
- if (rt2x00_intf_is_usb(rt2x00dev)) {
- /*
- * Wait untill BBP and RF are ready.
- */
- for (i = 0; i < REGISTER_BUSY_COUNT; i++) {
- rt2800_register_read(rt2x00dev, MAC_CSR0, ®);
- if (reg && reg != ~0)
- break;
- msleep(1);
- }
- if (i == REGISTER_BUSY_COUNT) {
- ERROR(rt2x00dev, "Unstable hardware.\n");
- return -EBUSY;
- }
- rt2800_register_read(rt2x00dev, PBF_SYS_CTRL, ®);
- rt2800_register_write(rt2x00dev, PBF_SYS_CTRL,
- reg & ~0x00002000);
- } else if (rt2x00_intf_is_pci(rt2x00dev))
- rt2800_register_write(rt2x00dev, PWR_PIN_CFG, 0x00000003);
- rt2800_register_read(rt2x00dev, MAC_SYS_CTRL, ®);
- rt2x00_set_field32(®, MAC_SYS_CTRL_RESET_CSR, 1);
- rt2x00_set_field32(®, MAC_SYS_CTRL_RESET_BBP, 1);
- rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, reg);
- if (rt2x00_intf_is_usb(rt2x00dev)) {
- rt2800_register_write(rt2x00dev, USB_DMA_CFG, 0x00000000);
- #ifdef CONFIG_RT2800USB
- rt2x00usb_vendor_request_sw(rt2x00dev, USB_DEVICE_MODE, 0,
- USB_MODE_RESET, REGISTER_TIMEOUT);
- #endif
- }
- rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, 0x00000000);
- rt2800_register_read(rt2x00dev, BCN_OFFSET0, ®);
- rt2x00_set_field32(®, BCN_OFFSET0_BCN0, 0xe0); /* 0x3800 */
- rt2x00_set_field32(®, BCN_OFFSET0_BCN1, 0xe8); /* 0x3a00 */
- rt2x00_set_field32(®, BCN_OFFSET0_BCN2, 0xf0); /* 0x3c00 */
- rt2x00_set_field32(®, BCN_OFFSET0_BCN3, 0xf8); /* 0x3e00 */
- rt2800_register_write(rt2x00dev, BCN_OFFSET0, reg);
- rt2800_register_read(rt2x00dev, BCN_OFFSET1, ®);
- rt2x00_set_field32(®, BCN_OFFSET1_BCN4, 0xc8); /* 0x3200 */
- rt2x00_set_field32(®, BCN_OFFSET1_BCN5, 0xd0); /* 0x3400 */
- rt2x00_set_field32(®, BCN_OFFSET1_BCN6, 0x77); /* 0x1dc0 */
- rt2x00_set_field32(®, BCN_OFFSET1_BCN7, 0x6f); /* 0x1bc0 */
- rt2800_register_write(rt2x00dev, BCN_OFFSET1, reg);
- rt2800_register_write(rt2x00dev, LEGACY_BASIC_RATE, 0x0000013f);
- rt2800_register_write(rt2x00dev, HT_BASIC_RATE, 0x00008003);
- rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, 0x00000000);
- rt2800_register_read(rt2x00dev, BCN_TIME_CFG, ®);
- rt2x00_set_field32(®, BCN_TIME_CFG_BEACON_INTERVAL, 0);
- rt2x00_set_field32(®, BCN_TIME_CFG_TSF_TICKING, 0);
- rt2x00_set_field32(®, BCN_TIME_CFG_TSF_SYNC, 0);
- rt2x00_set_field32(®, BCN_TIME_CFG_TBTT_ENABLE, 0);
- rt2x00_set_field32(®, BCN_TIME_CFG_BEACON_GEN, 0);
- rt2x00_set_field32(®, BCN_TIME_CFG_TX_TIME_COMPENSATE, 0);
- rt2800_register_write(rt2x00dev, BCN_TIME_CFG, reg);
- if (rt2x00_intf_is_usb(rt2x00dev) &&
- rt2x00_rev(&rt2x00dev->chip) == RT3070_VERSION) {
- rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000400);
- rt2800_register_write(rt2x00dev, TX_SW_CFG1, 0x00000000);
- rt2800_register_write(rt2x00dev, TX_SW_CFG2, 0x00000000);
- } else {
- rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000000);
- rt2800_register_write(rt2x00dev, TX_SW_CFG1, 0x00080606);
- }
- rt2800_register_read(rt2x00dev, TX_LINK_CFG, ®);
- rt2x00_set_field32(®, TX_LINK_CFG_REMOTE_MFB_LIFETIME, 32);
- rt2x00_set_field32(®, TX_LINK_CFG_MFB_ENABLE, 0);
- rt2x00_set_field32(®, TX_LINK_CFG_REMOTE_UMFS_ENABLE, 0);
- rt2x00_set_field32(®, TX_LINK_CFG_TX_MRQ_EN, 0);
- rt2x00_set_field32(®, TX_LINK_CFG_TX_RDG_EN, 0);
- rt2x00_set_field32(®, TX_LINK_CFG_TX_CF_ACK_EN, 1);
- rt2x00_set_field32(®, TX_LINK_CFG_REMOTE_MFB, 0);
- rt2x00_set_field32(®, TX_LINK_CFG_REMOTE_MFS, 0);
- rt2800_register_write(rt2x00dev, TX_LINK_CFG, reg);
- rt2800_register_read(rt2x00dev, TX_TIMEOUT_CFG, ®);
- rt2x00_set_field32(®, TX_TIMEOUT_CFG_MPDU_LIFETIME, 9);
- rt2x00_set_field32(®, TX_TIMEOUT_CFG_TX_OP_TIMEOUT, 10);
- rt2800_register_write(rt2x00dev, TX_TIMEOUT_CFG, reg);
- rt2800_register_read(rt2x00dev, MAX_LEN_CFG, ®);
- rt2x00_set_field32(®, MAX_LEN_CFG_MAX_MPDU, AGGREGATION_SIZE);
- if (rt2x00_rev(&rt2x00dev->chip) >= RT2880E_VERSION &&
- rt2x00_rev(&rt2x00dev->chip) < RT3070_VERSION)
- rt2x00_set_field32(®, MAX_LEN_CFG_MAX_PSDU, 2);
- else
- rt2x00_set_field32(®, MAX_LEN_CFG_MAX_PSDU, 1);
- rt2x00_set_field32(®, MAX_LEN_CFG_MIN_PSDU, 0);
- rt2x00_set_field32(®, MAX_LEN_CFG_MIN_MPDU, 0);
- rt2800_register_write(rt2x00dev, MAX_LEN_CFG, reg);
- rt2800_register_write(rt2x00dev, PBF_MAX_PCNT, 0x1f3fbf9f);
- rt2800_register_read(rt2x00dev, AUTO_RSP_CFG, ®);
- rt2x00_set_field32(®, AUTO_RSP_CFG_AUTORESPONDER, 1);
- rt2x00_set_field32(®, AUTO_RSP_CFG_CTS_40_MMODE, 0);
- rt2x00_set_field32(®, AUTO_RSP_CFG_CTS_40_MREF, 0);
- rt2x00_set_field32(®, AUTO_RSP_CFG_DUAL_CTS_EN, 0);
- rt2x00_set_field32(®, AUTO_RSP_CFG_ACK_CTS_PSM_BIT, 0);
- rt2800_register_write(rt2x00dev, AUTO_RSP_CFG, reg);
- rt2800_register_read(rt2x00dev, CCK_PROT_CFG, ®);
- rt2x00_set_field32(®, CCK_PROT_CFG_PROTECT_RATE, 8);
- rt2x00_set_field32(®, CCK_PROT_CFG_PROTECT_CTRL, 0);
- rt2x00_set_field32(®, CCK_PROT_CFG_PROTECT_NAV, 1);
- rt2x00_set_field32(®, CCK_PROT_CFG_TX_OP_ALLOW_CCK, 1);
- rt2x00_set_field32(®, CCK_PROT_CFG_TX_OP_ALLOW_OFDM, 1);
- rt2x00_set_field32(®, CCK_PROT_CFG_TX_OP_ALLOW_MM20, 1);
- rt2x00_set_field32(®, CCK_PROT_CFG_TX_OP_ALLOW_MM40, 1);
- rt2x00_set_field32(®, CCK_PROT_CFG_TX_OP_ALLOW_GF20, 1);
- rt2x00_set_field32(®, CCK_PROT_CFG_TX_OP_ALLOW_GF40, 1);
- rt2800_register_write(rt2x00dev, CCK_PROT_CFG, reg);
- rt2800_register_read(rt2x00dev, OFDM_PROT_CFG, ®);
- rt2x00_set_field32(®, OFDM_PROT_CFG_PROTECT_RATE, 8);
- rt2x00_set_field32(®, OFDM_PROT_CFG_PROTECT_CTRL, 0);
- rt2x00_set_field32(®, OFDM_PROT_CFG_PROTECT_NAV, 1);
- rt2x00_set_field32(®, OFDM_PROT_CFG_TX_OP_ALLOW_CCK, 1);
- rt2x00_set_field32(®, OFDM_PROT_CFG_TX_OP_ALLOW_OFDM, 1);
- rt2x00_set_field32(®, OFDM_PROT_CFG_TX_OP_ALLOW_MM20, 1);
- rt2x00_set_field32(®, OFDM_PROT_CFG_TX_OP_ALLOW_MM40, 1);
- rt2x00_set_field32(®, OFDM_PROT_CFG_TX_OP_ALLOW_GF20, 1);
- rt2x00_set_field32(®, OFDM_PROT_CFG_TX_OP_ALLOW_GF40, 1);
- rt2800_register_write(rt2x00dev, OFDM_PROT_CFG, reg);
- rt2800_register_read(rt2x00dev, MM20_PROT_CFG, ®);
- rt2x00_set_field32(®, MM20_PROT_CFG_PROTECT_RATE, 0x4004);
- rt2x00_set_field32(®, MM20_PROT_CFG_PROTECT_CTRL, 0);
- rt2x00_set_field32(®, MM20_PROT_CFG_PROTECT_NAV, 1);
- rt2x00_set_field32(®, MM20_PROT_CFG_TX_OP_ALLOW_CCK, 1);
- rt2x00_set_field32(®, MM20_PROT_CFG_TX_OP_ALLOW_OFDM, 1);
- rt2x00_set_field32(®, MM20_PROT_CFG_TX_OP_ALLOW_MM20, 1);
- rt2x00_set_field32(®, MM20_PROT_CFG_TX_OP_ALLOW_MM40, 0);
- rt2x00_set_field32(®, MM20_PROT_CFG_TX_OP_ALLOW_GF20, 1);
- rt2x00_set_field32(®, MM20_PROT_CFG_TX_OP_ALLOW_GF40, 0);
- rt2800_register_write(rt2x00dev, MM20_PROT_CFG, reg);
- rt2800_register_read(rt2x00dev, MM40_PROT_CFG, ®);
- rt2x00_set_field32(®, MM40_PROT_CFG_PROTECT_RATE, 0x4084);
- rt2x00_set_field32(®, MM40_PROT_CFG_PROTECT_CTRL, 0);
- rt2x00_set_field32(®, MM40_PROT_CFG_PROTECT_NAV, 1);
- rt2x00_set_field32(®, MM40_PROT_CFG_TX_OP_ALLOW_CCK, 1);
- rt2x00_set_field32(®, MM40_PROT_CFG_TX_OP_ALLOW_OFDM, 1);
- rt2x00_set_field32(®, MM40_PROT_CFG_TX_OP_ALLOW_MM20, 1);
- rt2x00_set_field32(®, MM40_PROT_CFG_TX_OP_ALLOW_MM40, 1);
- rt2x00_set_field32(®, MM40_PROT_CFG_TX_OP_ALLOW_GF20, 1);
- rt2x00_set_field32(®, MM40_PROT_CFG_TX_OP_ALLOW_GF40, 1);
- rt2800_register_write(rt2x00dev, MM40_PROT_CFG, reg);
- rt2800_register_read(rt2x00dev, GF20_PROT_CFG, ®);
- rt2x00_set_field32(®, GF20_PROT_CFG_PROTECT_RATE, 0x4004);
- rt2x00_set_field32(®, GF20_PROT_CFG_PROTECT_CTRL, 0);
- rt2x00_set_field32(®, GF20_PROT_CFG_PROTECT_NAV, 1);
- rt2x00_set_field32(®, GF20_PROT_CFG_TX_OP_ALLOW_CCK, 1);
- rt2x00_set_field32(®, GF20_PROT_CFG_TX_OP_ALLOW_OFDM, 1);
- rt2x00_set_field32(®, GF20_PROT_CFG_TX_OP_ALLOW_MM20, 1);
- rt2x00_set_field32(®, GF20_PROT_CFG_TX_OP_ALLOW_MM40, 0);
- rt2x00_set_field32(®, GF20_PROT_CFG_TX_OP_ALLOW_GF20, 1);
- rt2x00_set_field32(®, GF20_PROT_CFG_TX_OP_ALLOW_GF40, 0);
- rt2800_register_write(rt2x00dev, GF20_PROT_CFG, reg);
- rt2800_register_read(rt2x00dev, GF40_PROT_CFG, ®);
- rt2x00_set_field32(®, GF40_PROT_CFG_PROTECT_RATE, 0x4084);
- rt2x00_set_field32(®, GF40_PROT_CFG_PROTECT_CTRL, 0);
- rt2x00_set_field32(®, GF40_PROT_CFG_PROTECT_NAV, 1);
- rt2x00_set_field32(®, GF40_PROT_CFG_TX_OP_ALLOW_CCK, 1);
- rt2x00_set_field32(®, GF40_PROT_CFG_TX_OP_ALLOW_OFDM, 1);
- rt2x00_set_field32(®, GF40_PROT_CFG_TX_OP_ALLOW_MM20, 1);
- rt2x00_set_field32(®, GF40_PROT_CFG_TX_OP_ALLOW_MM40, 1);
- rt2x00_set_field32(®, GF40_PROT_CFG_TX_OP_ALLOW_GF20, 1);
- rt2x00_set_field32(®, GF40_PROT_CFG_TX_OP_ALLOW_GF40, 1);
- rt2800_register_write(rt2x00dev, GF40_PROT_CFG, reg);
- if (rt2x00_intf_is_usb(rt2x00dev)) {
- rt2800_register_write(rt2x00dev, PBF_CFG, 0xf40006);
- rt2800_register_read(rt2x00dev, WPDMA_GLO_CFG, ®);
- rt2x00_set_field32(®, WPDMA_GLO_CFG_ENABLE_TX_DMA, 0);
- rt2x00_set_field32(®, WPDMA_GLO_CFG_TX_DMA_BUSY, 0);
- rt2x00_set_field32(®, WPDMA_GLO_CFG_ENABLE_RX_DMA, 0);
- rt2x00_set_field32(®, WPDMA_GLO_CFG_RX_DMA_BUSY, 0);
- rt2x00_set_field32(®, WPDMA_GLO_CFG_WP_DMA_BURST_SIZE, 3);
- rt2x00_set_field32(®, WPDMA_GLO_CFG_TX_WRITEBACK_DONE, 0);
- rt2x00_set_field32(®, WPDMA_GLO_CFG_BIG_ENDIAN, 0);
- rt2x00_set_field32(®, WPDMA_GLO_CFG_RX_HDR_SCATTER, 0);
- rt2x00_set_field32(®, WPDMA_GLO_CFG_HDR_SEG_LEN, 0);
- rt2800_register_write(rt2x00dev, WPDMA_GLO_CFG, reg);
- }
- rt2800_register_write(rt2x00dev, TXOP_CTRL_CFG, 0x0000583f);
- rt2800_register_write(rt2x00dev, TXOP_HLDR_ET, 0x00000002);
- rt2800_register_read(rt2x00dev, TX_RTS_CFG, ®);
- rt2x00_set_field32(®, TX_RTS_CFG_AUTO_RTS_RETRY_LIMIT, 32);
- rt2x00_set_field32(®, TX_RTS_CFG_RTS_THRES,
- IEEE80211_MAX_RTS_THRESHOLD);
- rt2x00_set_field32(®, TX_RTS_CFG_RTS_FBK_EN, 0);
- rt2800_register_write(rt2x00dev, TX_RTS_CFG, reg);
- rt2800_register_write(rt2x00dev, EXP_ACK_TIME, 0x002400ca);
- rt2800_register_write(rt2x00dev, PWR_PIN_CFG, 0x00000003);
- /*
- * ASIC will keep garbage value after boot, clear encryption keys.
- */
- for (i = 0; i < 4; i++)
- rt2800_register_write(rt2x00dev,
- SHARED_KEY_MODE_ENTRY(i), 0);
- for (i = 0; i < 256; i++) {
- u32 wcid[2] = { 0xffffffff, 0x00ffffff };
- rt2800_register_multiwrite(rt2x00dev, MAC_WCID_ENTRY(i),
- wcid, sizeof(wcid));
- rt2800_register_write(rt2x00dev, MAC_WCID_ATTR_ENTRY(i), 1);
- rt2800_register_write(rt2x00dev, MAC_IVEIV_ENTRY(i), 0);
- }
- /*
- * Clear all beacons
- * 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.
- */
- rt2800_register_write(rt2x00dev, HW_BEACON_BASE0, 0);
- rt2800_register_write(rt2x00dev, HW_BEACON_BASE1, 0);
- rt2800_register_write(rt2x00dev, HW_BEACON_BASE2, 0);
- rt2800_register_write(rt2x00dev, HW_BEACON_BASE3, 0);
- rt2800_register_write(rt2x00dev, HW_BEACON_BASE4, 0);
- rt2800_register_write(rt2x00dev, HW_BEACON_BASE5, 0);
- rt2800_register_write(rt2x00dev, HW_BEACON_BASE6, 0);
- rt2800_register_write(rt2x00dev, HW_BEACON_BASE7, 0);
- if (rt2x00_intf_is_usb(rt2x00dev)) {
- rt2800_register_read(rt2x00dev, USB_CYC_CFG, ®);
- rt2x00_set_field32(®, USB_CYC_CFG_CLOCK_CYCLE, 30);
- rt2800_register_write(rt2x00dev, USB_CYC_CFG, reg);
- }
- rt2800_register_read(rt2x00dev, HT_FBK_CFG0, ®);
- rt2x00_set_field32(®, HT_FBK_CFG0_HTMCS0FBK, 0);
- rt2x00_set_field32(®, HT_FBK_CFG0_HTMCS1FBK, 0);
- rt2x00_set_field32(®, HT_FBK_CFG0_HTMCS2FBK, 1);
- rt2x00_set_field32(®, HT_FBK_CFG0_HTMCS3FBK, 2);
- rt2x00_set_field32(®, HT_FBK_CFG0_HTMCS4FBK, 3);
- rt2x00_set_field32(®, HT_FBK_CFG0_HTMCS5FBK, 4);
- rt2x00_set_field32(®, HT_FBK_CFG0_HTMCS6FBK, 5);
- rt2x00_set_field32(®, HT_FBK_CFG0_HTMCS7FBK, 6);
- rt2800_register_write(rt2x00dev, HT_FBK_CFG0, reg);
- rt2800_register_read(rt2x00dev, HT_FBK_CFG1, ®);
- rt2x00_set_field32(®, HT_FBK_CFG1_HTMCS8FBK, 8);
- rt2x00_set_field32(®, HT_FBK_CFG1_HTMCS9FBK, 8);
- rt2x00_set_field32(®, HT_FBK_CFG1_HTMCS10FBK, 9);
- rt2x00_set_field32(®, HT_FBK_CFG1_HTMCS11FBK, 10);
- rt2x00_set_field32(®, HT_FBK_CFG1_HTMCS12FBK, 11);
- rt2x00_set_field32(®, HT_FBK_CFG1_HTMCS13FBK, 12);
- rt2x00_set_field32(®, HT_FBK_CFG1_HTMCS14FBK, 13);
- rt2x00_set_field32(®, HT_FBK_CFG1_HTMCS15FBK, 14);
- rt2800_register_write(rt2x00dev, HT_FBK_CFG1, reg);
- rt2800_register_read(rt2x00dev, LG_FBK_CFG0, ®);
- rt2x00_set_field32(®, LG_FBK_CFG0_OFDMMCS0FBK, 8);
- rt2x00_set_field32(®, LG_FBK_CFG0_OFDMMCS1FBK, 8);
- rt2x00_set_field32(®, LG_FBK_CFG0_OFDMMCS2FBK, 9);
- rt2x00_set_field32(®, LG_FBK_CFG0_OFDMMCS3FBK, 10);
- rt2x00_set_field32(®, LG_FBK_CFG0_OFDMMCS4FBK, 11);
- rt2x00_set_field32(®, LG_FBK_CFG0_OFDMMCS5FBK, 12);
- rt2x00_set_field32(®, LG_FBK_CFG0_OFDMMCS6FBK, 13);
- rt2x00_set_field32(®, LG_FBK_CFG0_OFDMMCS7FBK, 14);
- rt2800_register_write(rt2x00dev, LG_FBK_CFG0, reg);
- rt2800_register_read(rt2x00dev, LG_FBK_CFG1, ®);
- rt2x00_set_field32(®, LG_FBK_CFG0_CCKMCS0FBK, 0);
- rt2x00_set_field32(®, LG_FBK_CFG0_CCKMCS1FBK, 0);
- rt2x00_set_field32(®, LG_FBK_CFG0_CCKMCS2FBK, 1);
- rt2x00_set_field32(®, LG_FBK_CFG0_CCKMCS3FBK, 2);
- rt2800_register_write(rt2x00dev, LG_FBK_CFG1, reg);
- /*
- * We must clear the error counters.
- * These registers are cleared on read,
- * so we may pass a useless variable to store the value.
- */
- rt2800_register_read(rt2x00dev, RX_STA_CNT0, ®);
- rt2800_register_read(rt2x00dev, RX_STA_CNT1, ®);
- rt2800_register_read(rt2x00dev, RX_STA_CNT2, ®);
- rt2800_register_read(rt2x00dev, TX_STA_CNT0, ®);
- rt2800_register_read(rt2x00dev, TX_STA_CNT1, ®);
- rt2800_register_read(rt2x00dev, TX_STA_CNT2, ®);
- return 0;
- }
- EXPORT_SYMBOL_GPL(rt2800_init_registers);
- static int rt2800_wait_bbp_rf_ready(struct rt2x00_dev *rt2x00dev)
- {
- unsigned int i;
- u32 reg;
- for (i = 0; i < REGISTER_BUSY_COUNT; i++) {
- rt2800_register_read(rt2x00dev, MAC_STATUS_CFG, ®);
- if (!rt2x00_get_field32(reg, MAC_STATUS_CFG_BBP_RF_BUSY))
- return 0;
- udelay(REGISTER_BUSY_DELAY);
- }
- ERROR(rt2x00dev, "BBP/RF register access failed, aborting.\n");
- return -EACCES;
- }
- static int rt2800_wait_bbp_ready(struct rt2x00_dev *rt2x00dev)
- {
- unsigned int i;
- u8 value;
- /*
- * BBP was enabled after firmware was loaded,
- * but we need to reactivate it now.
- */
- rt2800_register_write(rt2x00dev, H2M_BBP_AGENT, 0);
- rt2800_register_write(rt2x00dev, H2M_MAILBOX_CSR, 0);
- msleep(1);
- for (i = 0; i < REGISTER_BUSY_COUNT; i++) {
- rt2800_bbp_read(rt2x00dev, 0, &value);
- if ((value != 0xff) && (value != 0x00))
- return 0;
- udelay(REGISTER_BUSY_DELAY);
- }
- ERROR(rt2x00dev, "BBP register access failed, aborting.\n");
- return -EACCES;
- }
- int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev)
- {
- unsigned int i;
- u16 eeprom;
- u8 reg_id;
- u8 value;
- if (unlikely(rt2800_wait_bbp_rf_ready(rt2x00dev) ||
- rt2800_wait_bbp_ready(rt2x00dev)))
- return -EACCES;
- rt2800_bbp_write(rt2x00dev, 65, 0x2c);
- rt2800_bbp_write(rt2x00dev, 66, 0x38);
- rt2800_bbp_write(rt2x00dev, 69, 0x12);
- rt2800_bbp_write(rt2x00dev, 70, 0x0a);
- rt2800_bbp_write(rt2x00dev, 73, 0x10);
- rt2800_bbp_write(rt2x00dev, 81, 0x37);
- rt2800_bbp_write(rt2x00dev, 82, 0x62);
- rt2800_bbp_write(rt2x00dev, 83, 0x6a);
- rt2800_bbp_write(rt2x00dev, 84, 0x99);
- rt2800_bbp_write(rt2x00dev, 86, 0x00);
- rt2800_bbp_write(rt2x00dev, 91, 0x04);
- rt2800_bbp_write(rt2x00dev, 92, 0x00);
- rt2800_bbp_write(rt2x00dev, 103, 0x00);
- rt2800_bbp_write(rt2x00dev, 105, 0x05);
- if (rt2x00_rev(&rt2x00dev->chip) == RT2860C_VERSION) {
- rt2800_bbp_write(rt2x00dev, 69, 0x16);
- rt2800_bbp_write(rt2x00dev, 73, 0x12);
- }
- if (rt2x00_rev(&rt2x00dev->chip) > RT2860D_VERSION)
- rt2800_bbp_write(rt2x00dev, 84, 0x19);
- if (rt2x00_intf_is_usb(rt2x00dev) &&
- rt2x00_rev(&rt2x00dev->chip) == RT3070_VERSION) {
- rt2800_bbp_write(rt2x00dev, 70, 0x0a);
- rt2800_bbp_write(rt2x00dev, 84, 0x99);
- rt2800_bbp_write(rt2x00dev, 105, 0x05);
- }
- if (rt2x00_intf_is_pci(rt2x00dev) &&
- rt2x00_rt(&rt2x00dev->chip, RT3052)) {
- rt2800_bbp_write(rt2x00dev, 31, 0x08);
- rt2800_bbp_write(rt2x00dev, 78, 0x0e);
- rt2800_bbp_write(rt2x00dev, 80, 0x08);
- }
- for (i = 0; i < EEPROM_BBP_SIZE; i++) {
- rt2x00_eeprom_read(rt2x00dev, EEPROM_BBP_START + i, &eeprom);
- if (eeprom != 0xffff && eeprom != 0x0000) {
- reg_id = rt2x00_get_field16(eeprom, EEPROM_BBP_REG_ID);
- value = rt2x00_get_field16(eeprom, EEPROM_BBP_VALUE);
- rt2800_bbp_write(rt2x00dev, reg_id, value);
- }
- }
- return 0;
- }
- EXPORT_SYMBOL_GPL(rt2800_init_bbp);
- static u8 rt2800_init_rx_filter(struct rt2x00_dev *rt2x00dev,
- bool bw40, u8 rfcsr24, u8 filter_target)
- {
- unsigned int i;
- u8 bbp;
- u8 rfcsr;
- u8 passband;
- u8 stopband;
- u8 overtuned = 0;
- rt2800_rfcsr_write(rt2x00dev, 24, rfcsr24);
- rt2800_bbp_read(rt2x00dev, 4, &bbp);
- rt2x00_set_field8(&bbp, BBP4_BANDWIDTH, 2 * bw40);
- rt2800_bbp_write(rt2x00dev, 4, bbp);
- rt2800_rfcsr_read(rt2x00dev, 22, &rfcsr);
- rt2x00_set_field8(&rfcsr, RFCSR22_BASEBAND_LOOPBACK, 1);
- rt2800_rfcsr_write(rt2x00dev, 22, rfcsr);
- /*
- * Set power & frequency of passband test tone
- */
- rt2800_bbp_write(rt2x00dev, 24, 0);
- for (i = 0; i < 100; i++) {
- rt2800_bbp_write(rt2x00dev, 25, 0x90);
- msleep(1);
- rt2800_bbp_read(rt2x00dev, 55, &passband);
- if (passband)
- break;
- }
- /*
- * Set power & frequency of stopband test tone
- */
- rt2800_bbp_write(rt2x00dev, 24, 0x06);
- for (i = 0; i < 100; i++) {
- rt2800_bbp_write(rt2x00dev, 25, 0x90);
- msleep(1);
- rt2800_bbp_read(rt2x00dev, 55, &stopband);
- if ((passband - stopband) <= filter_target) {
- rfcsr24++;
- overtuned += ((passband - stopband) == filter_target);
- } else
- break;
- rt2800_rfcsr_write(rt2x00dev, 24, rfcsr24);
- }
- rfcsr24 -= !!overtuned;
- rt2800_rfcsr_write(rt2x00dev, 24, rfcsr24);
- return rfcsr24;
- }
- int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev)
- {
- u8 rfcsr;
- u8 bbp;
- if (rt2x00_intf_is_usb(rt2x00dev) &&
- rt2x00_rev(&rt2x00dev->chip) != RT3070_VERSION)
- return 0;
- if (rt2x00_intf_is_pci(rt2x00dev)) {
- if (!rt2x00_rf(&rt2x00dev->chip, RF3020) &&
- !rt2x00_rf(&rt2x00dev->chip, RF3021) &&
- !rt2x00_rf(&rt2x00dev->chip, RF3022))
- return 0;
- }
- /*
- * Init RF calibration.
- */
- rt2800_rfcsr_read(rt2x00dev, 30, &rfcsr);
- rt2x00_set_field8(&rfcsr, RFCSR30_RF_CALIBRATION, 1);
- rt2800_rfcsr_write(rt2x00dev, 30, rfcsr);
- msleep(1);
- rt2x00_set_field8(&rfcsr, RFCSR30_RF_CALIBRATION, 0);
- rt2800_rfcsr_write(rt2x00dev, 30, rfcsr);
- if (rt2x00_intf_is_usb(rt2x00dev)) {
- rt2800_rfcsr_write(rt2x00dev, 4, 0x40);
- rt2800_rfcsr_write(rt2x00dev, 5, 0x03);
- rt2800_rfcsr_write(rt2x00dev, 6, 0x02);
- rt2800_rfcsr_write(rt2x00dev, 7, 0x70);
- rt2800_rfcsr_write(rt2x00dev, 9, 0x0f);
- rt2800_rfcsr_write(rt2x00dev, 10, 0x71);
- rt2800_rfcsr_write(rt2x00dev, 11, 0x21);
- rt2800_rfcsr_write(rt2x00dev, 12, 0x7b);
- rt2800_rfcsr_write(rt2x00dev, 14, 0x90);
- rt2800_rfcsr_write(rt2x00dev, 15, 0x58);
- rt2800_rfcsr_write(rt2x00dev, 16, 0xb3);
- rt2800_rfcsr_write(rt2x00dev, 17, 0x92);
- rt2800_rfcsr_write(rt2x00dev, 18, 0x2c);
- rt2800_rfcsr_write(rt2x00dev, 19, 0x02);
- rt2800_rfcsr_write(rt2x00dev, 20, 0xba);
- rt2800_rfcsr_write(rt2x00dev, 21, 0xdb);
- rt2800_rfcsr_write(rt2x00dev, 24, 0x16);
- rt2800_rfcsr_write(rt2x00dev, 25, 0x01);
- rt2800_rfcsr_write(rt2x00dev, 27, 0x03);
- rt2800_rfcsr_write(rt2x00dev, 29, 0x1f);
- } else if (rt2x00_intf_is_pci(rt2x00dev)) {
- rt2800_rfcsr_write(rt2x00dev, 0, 0x50);
- rt2800_rfcsr_write(rt2x00dev, 1, 0x01);
- rt2800_rfcsr_write(rt2x00dev, 2, 0xf7);
- rt2800_rfcsr_write(rt2x00dev, 3, 0x75);
- rt2800_rfcsr_write(rt2x00dev, 4, 0x40);
- rt2800_rfcsr_write(rt2x00dev, 5, 0x03);
- rt2800_rfcsr_write(rt2x00dev, 6, 0x02);
- rt2800_rfcsr_write(rt2x00dev, 7, 0x50);
- rt2800_rfcsr_write(rt2x00dev, 8, 0x39);
- rt2800_rfcsr_write(rt2x00dev, 9, 0x0f);
- rt2800_rfcsr_write(rt2x00dev, 10, 0x60);
- rt2800_rfcsr_write(rt2x00dev, 11, 0x21);
- rt2800_rfcsr_write(rt2x00dev, 12, 0x75);
- rt2800_rfcsr_write(rt2x00dev, 13, 0x75);
- rt2800_rfcsr_write(rt2x00dev, 14, 0x90);
- rt2800_rfcsr_write(rt2x00dev, 15, 0x58);
- rt2800_rfcsr_write(rt2x00dev, 16, 0xb3);
- rt2800_rfcsr_write(rt2x00dev, 17, 0x92);
- rt2800_rfcsr_write(rt2x00dev, 18, 0x2c);
- rt2800_rfcsr_write(rt2x00dev, 19, 0x02);
- rt2800_rfcsr_write(rt2x00dev, 20, 0xba);
- rt2800_rfcsr_write(rt2x00dev, 21, 0xdb);
- rt2800_rfcsr_write(rt2x00dev, 22, 0x00);
- rt2800_rfcsr_write(rt2x00dev, 23, 0x31);
- rt2800_rfcsr_write(rt2x00dev, 24, 0x08);
- rt2800_rfcsr_write(rt2x00dev, 25, 0x01);
- rt2800_rfcsr_write(rt2x00dev, 26, 0x25);
- rt2800_rfcsr_write(rt2x00dev, 27, 0x23);
- rt2800_rfcsr_write(rt2x00dev, 28, 0x13);
- rt2800_rfcsr_write(rt2x00dev, 29, 0x83);
- }
- /*
- * Set RX Filter calibration for 20MHz and 40MHz
- */
- rt2x00dev->calibration[0] =
- rt2800_init_rx_filter(rt2x00dev, false, 0x07, 0x16);
- rt2x00dev->calibration[1] =
- rt2800_init_rx_filter(rt2x00dev, true, 0x27, 0x19);
- /*
- * Set back to initial state
- */
- rt2800_bbp_write(rt2x00dev, 24, 0);
- rt2800_rfcsr_read(rt2x00dev, 22, &rfcsr);
- rt2x00_set_field8(&rfcsr, RFCSR22_BASEBAND_LOOPBACK, 0);
- rt2800_rfcsr_write(rt2x00dev, 22, rfcsr);
- /*
- * set BBP back to BW20
- */
- rt2800_bbp_read(rt2x00dev, 4, &bbp);
- rt2x00_set_field8(&bbp, BBP4_BANDWIDTH, 0);
- rt2800_bbp_write(rt2x00dev, 4, bbp);
- return 0;
- }
- EXPORT_SYMBOL_GPL(rt2800_init_rfcsr);
|