162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci Copyright (C) 2010 Willow Garage <http://www.willowgarage.com> 462306a36Sopenharmony_ci Copyright (C) 2009 - 2010 Ivo van Doorn <IvDoorn@gmail.com> 562306a36Sopenharmony_ci Copyright (C) 2009 Mattias Nissler <mattias.nissler@gmx.de> 662306a36Sopenharmony_ci Copyright (C) 2009 Felix Fietkau <nbd@openwrt.org> 762306a36Sopenharmony_ci Copyright (C) 2009 Xose Vazquez Perez <xose.vazquez@gmail.com> 862306a36Sopenharmony_ci Copyright (C) 2009 Axel Kollhofer <rain_maker@root-forum.org> 962306a36Sopenharmony_ci <http://rt2x00.serialmonkey.com> 1062306a36Sopenharmony_ci 1162306a36Sopenharmony_ci */ 1262306a36Sopenharmony_ci 1362306a36Sopenharmony_ci/* 1462306a36Sopenharmony_ci Module: rt2800usb 1562306a36Sopenharmony_ci Abstract: rt2800usb device specific routines. 1662306a36Sopenharmony_ci Supported chipsets: RT2800U. 1762306a36Sopenharmony_ci */ 1862306a36Sopenharmony_ci 1962306a36Sopenharmony_ci#include <linux/delay.h> 2062306a36Sopenharmony_ci#include <linux/etherdevice.h> 2162306a36Sopenharmony_ci#include <linux/kernel.h> 2262306a36Sopenharmony_ci#include <linux/module.h> 2362306a36Sopenharmony_ci#include <linux/usb.h> 2462306a36Sopenharmony_ci 2562306a36Sopenharmony_ci#include "rt2x00.h" 2662306a36Sopenharmony_ci#include "rt2x00usb.h" 2762306a36Sopenharmony_ci#include "rt2800lib.h" 2862306a36Sopenharmony_ci#include "rt2800.h" 2962306a36Sopenharmony_ci#include "rt2800usb.h" 3062306a36Sopenharmony_ci 3162306a36Sopenharmony_ci/* 3262306a36Sopenharmony_ci * Allow hardware encryption to be disabled. 3362306a36Sopenharmony_ci */ 3462306a36Sopenharmony_cistatic bool modparam_nohwcrypt; 3562306a36Sopenharmony_cimodule_param_named(nohwcrypt, modparam_nohwcrypt, bool, 0444); 3662306a36Sopenharmony_ciMODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption."); 3762306a36Sopenharmony_ci 3862306a36Sopenharmony_cistatic bool rt2800usb_hwcrypt_disabled(struct rt2x00_dev *rt2x00dev) 3962306a36Sopenharmony_ci{ 4062306a36Sopenharmony_ci return modparam_nohwcrypt; 4162306a36Sopenharmony_ci} 4262306a36Sopenharmony_ci 4362306a36Sopenharmony_ci/* 4462306a36Sopenharmony_ci * Queue handlers. 4562306a36Sopenharmony_ci */ 4662306a36Sopenharmony_cistatic void rt2800usb_start_queue(struct data_queue *queue) 4762306a36Sopenharmony_ci{ 4862306a36Sopenharmony_ci struct rt2x00_dev *rt2x00dev = queue->rt2x00dev; 4962306a36Sopenharmony_ci u32 reg; 5062306a36Sopenharmony_ci 5162306a36Sopenharmony_ci switch (queue->qid) { 5262306a36Sopenharmony_ci case QID_RX: 5362306a36Sopenharmony_ci reg = rt2x00usb_register_read(rt2x00dev, MAC_SYS_CTRL); 5462306a36Sopenharmony_ci rt2x00_set_field32(®, MAC_SYS_CTRL_ENABLE_RX, 1); 5562306a36Sopenharmony_ci rt2x00usb_register_write(rt2x00dev, MAC_SYS_CTRL, reg); 5662306a36Sopenharmony_ci break; 5762306a36Sopenharmony_ci case QID_BEACON: 5862306a36Sopenharmony_ci reg = rt2x00usb_register_read(rt2x00dev, BCN_TIME_CFG); 5962306a36Sopenharmony_ci rt2x00_set_field32(®, BCN_TIME_CFG_TSF_TICKING, 1); 6062306a36Sopenharmony_ci rt2x00_set_field32(®, BCN_TIME_CFG_TBTT_ENABLE, 1); 6162306a36Sopenharmony_ci rt2x00_set_field32(®, BCN_TIME_CFG_BEACON_GEN, 1); 6262306a36Sopenharmony_ci rt2x00usb_register_write(rt2x00dev, BCN_TIME_CFG, reg); 6362306a36Sopenharmony_ci break; 6462306a36Sopenharmony_ci default: 6562306a36Sopenharmony_ci break; 6662306a36Sopenharmony_ci } 6762306a36Sopenharmony_ci} 6862306a36Sopenharmony_ci 6962306a36Sopenharmony_cistatic void rt2800usb_stop_queue(struct data_queue *queue) 7062306a36Sopenharmony_ci{ 7162306a36Sopenharmony_ci struct rt2x00_dev *rt2x00dev = queue->rt2x00dev; 7262306a36Sopenharmony_ci u32 reg; 7362306a36Sopenharmony_ci 7462306a36Sopenharmony_ci switch (queue->qid) { 7562306a36Sopenharmony_ci case QID_RX: 7662306a36Sopenharmony_ci reg = rt2x00usb_register_read(rt2x00dev, MAC_SYS_CTRL); 7762306a36Sopenharmony_ci rt2x00_set_field32(®, MAC_SYS_CTRL_ENABLE_RX, 0); 7862306a36Sopenharmony_ci rt2x00usb_register_write(rt2x00dev, MAC_SYS_CTRL, reg); 7962306a36Sopenharmony_ci break; 8062306a36Sopenharmony_ci case QID_BEACON: 8162306a36Sopenharmony_ci reg = rt2x00usb_register_read(rt2x00dev, BCN_TIME_CFG); 8262306a36Sopenharmony_ci rt2x00_set_field32(®, BCN_TIME_CFG_TSF_TICKING, 0); 8362306a36Sopenharmony_ci rt2x00_set_field32(®, BCN_TIME_CFG_TBTT_ENABLE, 0); 8462306a36Sopenharmony_ci rt2x00_set_field32(®, BCN_TIME_CFG_BEACON_GEN, 0); 8562306a36Sopenharmony_ci rt2x00usb_register_write(rt2x00dev, BCN_TIME_CFG, reg); 8662306a36Sopenharmony_ci break; 8762306a36Sopenharmony_ci default: 8862306a36Sopenharmony_ci break; 8962306a36Sopenharmony_ci } 9062306a36Sopenharmony_ci} 9162306a36Sopenharmony_ci 9262306a36Sopenharmony_ci#define TXSTATUS_READ_INTERVAL 1000000 9362306a36Sopenharmony_ci 9462306a36Sopenharmony_cistatic bool rt2800usb_tx_sta_fifo_read_completed(struct rt2x00_dev *rt2x00dev, 9562306a36Sopenharmony_ci int urb_status, u32 tx_status) 9662306a36Sopenharmony_ci{ 9762306a36Sopenharmony_ci bool valid; 9862306a36Sopenharmony_ci 9962306a36Sopenharmony_ci if (urb_status) { 10062306a36Sopenharmony_ci rt2x00_warn(rt2x00dev, "TX status read failed %d\n", 10162306a36Sopenharmony_ci urb_status); 10262306a36Sopenharmony_ci 10362306a36Sopenharmony_ci goto stop_reading; 10462306a36Sopenharmony_ci } 10562306a36Sopenharmony_ci 10662306a36Sopenharmony_ci valid = rt2x00_get_field32(tx_status, TX_STA_FIFO_VALID); 10762306a36Sopenharmony_ci if (valid) { 10862306a36Sopenharmony_ci if (!kfifo_put(&rt2x00dev->txstatus_fifo, tx_status)) 10962306a36Sopenharmony_ci rt2x00_warn(rt2x00dev, "TX status FIFO overrun\n"); 11062306a36Sopenharmony_ci 11162306a36Sopenharmony_ci queue_work(rt2x00dev->workqueue, &rt2x00dev->txdone_work); 11262306a36Sopenharmony_ci 11362306a36Sopenharmony_ci /* Reschedule urb to read TX status again instantly */ 11462306a36Sopenharmony_ci return true; 11562306a36Sopenharmony_ci } 11662306a36Sopenharmony_ci 11762306a36Sopenharmony_ci /* Check if there is any entry that timedout waiting on TX status */ 11862306a36Sopenharmony_ci if (rt2800_txstatus_timeout(rt2x00dev)) 11962306a36Sopenharmony_ci queue_work(rt2x00dev->workqueue, &rt2x00dev->txdone_work); 12062306a36Sopenharmony_ci 12162306a36Sopenharmony_ci if (rt2800_txstatus_pending(rt2x00dev)) { 12262306a36Sopenharmony_ci /* Read register after 1 ms */ 12362306a36Sopenharmony_ci hrtimer_start(&rt2x00dev->txstatus_timer, 12462306a36Sopenharmony_ci TXSTATUS_READ_INTERVAL, 12562306a36Sopenharmony_ci HRTIMER_MODE_REL); 12662306a36Sopenharmony_ci return false; 12762306a36Sopenharmony_ci } 12862306a36Sopenharmony_ci 12962306a36Sopenharmony_cistop_reading: 13062306a36Sopenharmony_ci clear_bit(TX_STATUS_READING, &rt2x00dev->flags); 13162306a36Sopenharmony_ci /* 13262306a36Sopenharmony_ci * There is small race window above, between txstatus pending check and 13362306a36Sopenharmony_ci * clear_bit someone could do rt2x00usb_interrupt_txdone, so recheck 13462306a36Sopenharmony_ci * here again if status reading is needed. 13562306a36Sopenharmony_ci */ 13662306a36Sopenharmony_ci if (rt2800_txstatus_pending(rt2x00dev) && 13762306a36Sopenharmony_ci !test_and_set_bit(TX_STATUS_READING, &rt2x00dev->flags)) 13862306a36Sopenharmony_ci return true; 13962306a36Sopenharmony_ci else 14062306a36Sopenharmony_ci return false; 14162306a36Sopenharmony_ci} 14262306a36Sopenharmony_ci 14362306a36Sopenharmony_cistatic void rt2800usb_async_read_tx_status(struct rt2x00_dev *rt2x00dev) 14462306a36Sopenharmony_ci{ 14562306a36Sopenharmony_ci 14662306a36Sopenharmony_ci if (test_and_set_bit(TX_STATUS_READING, &rt2x00dev->flags)) 14762306a36Sopenharmony_ci return; 14862306a36Sopenharmony_ci 14962306a36Sopenharmony_ci /* Read TX_STA_FIFO register after 2 ms */ 15062306a36Sopenharmony_ci hrtimer_start(&rt2x00dev->txstatus_timer, 15162306a36Sopenharmony_ci 2 * TXSTATUS_READ_INTERVAL, 15262306a36Sopenharmony_ci HRTIMER_MODE_REL); 15362306a36Sopenharmony_ci} 15462306a36Sopenharmony_ci 15562306a36Sopenharmony_cistatic void rt2800usb_tx_dma_done(struct queue_entry *entry) 15662306a36Sopenharmony_ci{ 15762306a36Sopenharmony_ci struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; 15862306a36Sopenharmony_ci 15962306a36Sopenharmony_ci rt2800usb_async_read_tx_status(rt2x00dev); 16062306a36Sopenharmony_ci} 16162306a36Sopenharmony_ci 16262306a36Sopenharmony_cistatic enum hrtimer_restart rt2800usb_tx_sta_fifo_timeout(struct hrtimer *timer) 16362306a36Sopenharmony_ci{ 16462306a36Sopenharmony_ci struct rt2x00_dev *rt2x00dev = 16562306a36Sopenharmony_ci container_of(timer, struct rt2x00_dev, txstatus_timer); 16662306a36Sopenharmony_ci 16762306a36Sopenharmony_ci rt2x00usb_register_read_async(rt2x00dev, TX_STA_FIFO, 16862306a36Sopenharmony_ci rt2800usb_tx_sta_fifo_read_completed); 16962306a36Sopenharmony_ci 17062306a36Sopenharmony_ci return HRTIMER_NORESTART; 17162306a36Sopenharmony_ci} 17262306a36Sopenharmony_ci 17362306a36Sopenharmony_ci/* 17462306a36Sopenharmony_ci * Firmware functions 17562306a36Sopenharmony_ci */ 17662306a36Sopenharmony_cistatic int rt2800usb_autorun_detect(struct rt2x00_dev *rt2x00dev) 17762306a36Sopenharmony_ci{ 17862306a36Sopenharmony_ci __le32 *reg; 17962306a36Sopenharmony_ci u32 fw_mode; 18062306a36Sopenharmony_ci int ret; 18162306a36Sopenharmony_ci 18262306a36Sopenharmony_ci reg = kmalloc(sizeof(*reg), GFP_KERNEL); 18362306a36Sopenharmony_ci if (reg == NULL) 18462306a36Sopenharmony_ci return -ENOMEM; 18562306a36Sopenharmony_ci /* cannot use rt2x00usb_register_read here as it uses different 18662306a36Sopenharmony_ci * mode (MULTI_READ vs. DEVICE_MODE) and does not pass the 18762306a36Sopenharmony_ci * magic value USB_MODE_AUTORUN (0x11) to the device, thus the 18862306a36Sopenharmony_ci * returned value would be invalid. 18962306a36Sopenharmony_ci */ 19062306a36Sopenharmony_ci ret = rt2x00usb_vendor_request(rt2x00dev, USB_DEVICE_MODE, 19162306a36Sopenharmony_ci USB_VENDOR_REQUEST_IN, 0, 19262306a36Sopenharmony_ci USB_MODE_AUTORUN, reg, sizeof(*reg), 19362306a36Sopenharmony_ci REGISTER_TIMEOUT_FIRMWARE); 19462306a36Sopenharmony_ci fw_mode = le32_to_cpu(*reg); 19562306a36Sopenharmony_ci kfree(reg); 19662306a36Sopenharmony_ci if (ret < 0) 19762306a36Sopenharmony_ci return ret; 19862306a36Sopenharmony_ci 19962306a36Sopenharmony_ci if ((fw_mode & 0x00000003) == 2) 20062306a36Sopenharmony_ci return 1; 20162306a36Sopenharmony_ci 20262306a36Sopenharmony_ci return 0; 20362306a36Sopenharmony_ci} 20462306a36Sopenharmony_ci 20562306a36Sopenharmony_cistatic char *rt2800usb_get_firmware_name(struct rt2x00_dev *rt2x00dev) 20662306a36Sopenharmony_ci{ 20762306a36Sopenharmony_ci return FIRMWARE_RT2870; 20862306a36Sopenharmony_ci} 20962306a36Sopenharmony_ci 21062306a36Sopenharmony_cistatic int rt2800usb_write_firmware(struct rt2x00_dev *rt2x00dev, 21162306a36Sopenharmony_ci const u8 *data, const size_t len) 21262306a36Sopenharmony_ci{ 21362306a36Sopenharmony_ci int status; 21462306a36Sopenharmony_ci u32 offset; 21562306a36Sopenharmony_ci u32 length; 21662306a36Sopenharmony_ci int retval; 21762306a36Sopenharmony_ci 21862306a36Sopenharmony_ci /* 21962306a36Sopenharmony_ci * Check which section of the firmware we need. 22062306a36Sopenharmony_ci */ 22162306a36Sopenharmony_ci if (rt2x00_rt(rt2x00dev, RT2860) || 22262306a36Sopenharmony_ci rt2x00_rt(rt2x00dev, RT2872) || 22362306a36Sopenharmony_ci rt2x00_rt(rt2x00dev, RT3070)) { 22462306a36Sopenharmony_ci offset = 0; 22562306a36Sopenharmony_ci length = 4096; 22662306a36Sopenharmony_ci } else { 22762306a36Sopenharmony_ci offset = 4096; 22862306a36Sopenharmony_ci length = 4096; 22962306a36Sopenharmony_ci } 23062306a36Sopenharmony_ci 23162306a36Sopenharmony_ci /* 23262306a36Sopenharmony_ci * Write firmware to device. 23362306a36Sopenharmony_ci */ 23462306a36Sopenharmony_ci retval = rt2800usb_autorun_detect(rt2x00dev); 23562306a36Sopenharmony_ci if (retval < 0) 23662306a36Sopenharmony_ci return retval; 23762306a36Sopenharmony_ci if (retval) { 23862306a36Sopenharmony_ci rt2x00_info(rt2x00dev, 23962306a36Sopenharmony_ci "Firmware loading not required - NIC in AutoRun mode\n"); 24062306a36Sopenharmony_ci __clear_bit(REQUIRE_FIRMWARE, &rt2x00dev->cap_flags); 24162306a36Sopenharmony_ci } else { 24262306a36Sopenharmony_ci rt2x00usb_register_multiwrite(rt2x00dev, FIRMWARE_IMAGE_BASE, 24362306a36Sopenharmony_ci data + offset, length); 24462306a36Sopenharmony_ci } 24562306a36Sopenharmony_ci 24662306a36Sopenharmony_ci rt2x00usb_register_write(rt2x00dev, H2M_MAILBOX_CID, ~0); 24762306a36Sopenharmony_ci rt2x00usb_register_write(rt2x00dev, H2M_MAILBOX_STATUS, ~0); 24862306a36Sopenharmony_ci 24962306a36Sopenharmony_ci /* 25062306a36Sopenharmony_ci * Send firmware request to device to load firmware, 25162306a36Sopenharmony_ci * we need to specify a long timeout time. 25262306a36Sopenharmony_ci */ 25362306a36Sopenharmony_ci status = rt2x00usb_vendor_request_sw(rt2x00dev, USB_DEVICE_MODE, 25462306a36Sopenharmony_ci 0, USB_MODE_FIRMWARE, 25562306a36Sopenharmony_ci REGISTER_TIMEOUT_FIRMWARE); 25662306a36Sopenharmony_ci if (status < 0) { 25762306a36Sopenharmony_ci rt2x00_err(rt2x00dev, "Failed to write Firmware to device\n"); 25862306a36Sopenharmony_ci return status; 25962306a36Sopenharmony_ci } 26062306a36Sopenharmony_ci 26162306a36Sopenharmony_ci msleep(10); 26262306a36Sopenharmony_ci rt2x00usb_register_write(rt2x00dev, H2M_MAILBOX_CSR, 0); 26362306a36Sopenharmony_ci 26462306a36Sopenharmony_ci return 0; 26562306a36Sopenharmony_ci} 26662306a36Sopenharmony_ci 26762306a36Sopenharmony_ci/* 26862306a36Sopenharmony_ci * Device state switch handlers. 26962306a36Sopenharmony_ci */ 27062306a36Sopenharmony_cistatic int rt2800usb_init_registers(struct rt2x00_dev *rt2x00dev) 27162306a36Sopenharmony_ci{ 27262306a36Sopenharmony_ci u32 reg; 27362306a36Sopenharmony_ci 27462306a36Sopenharmony_ci /* 27562306a36Sopenharmony_ci * Wait until BBP and RF are ready. 27662306a36Sopenharmony_ci */ 27762306a36Sopenharmony_ci if (rt2800_wait_csr_ready(rt2x00dev)) 27862306a36Sopenharmony_ci return -EBUSY; 27962306a36Sopenharmony_ci 28062306a36Sopenharmony_ci reg = rt2x00usb_register_read(rt2x00dev, PBF_SYS_CTRL); 28162306a36Sopenharmony_ci rt2x00usb_register_write(rt2x00dev, PBF_SYS_CTRL, reg & ~0x00002000); 28262306a36Sopenharmony_ci 28362306a36Sopenharmony_ci reg = 0; 28462306a36Sopenharmony_ci rt2x00_set_field32(®, MAC_SYS_CTRL_RESET_CSR, 1); 28562306a36Sopenharmony_ci rt2x00_set_field32(®, MAC_SYS_CTRL_RESET_BBP, 1); 28662306a36Sopenharmony_ci rt2x00usb_register_write(rt2x00dev, MAC_SYS_CTRL, reg); 28762306a36Sopenharmony_ci 28862306a36Sopenharmony_ci rt2x00usb_vendor_request_sw(rt2x00dev, USB_DEVICE_MODE, 0, 28962306a36Sopenharmony_ci USB_MODE_RESET, REGISTER_TIMEOUT); 29062306a36Sopenharmony_ci 29162306a36Sopenharmony_ci rt2x00usb_register_write(rt2x00dev, MAC_SYS_CTRL, 0x00000000); 29262306a36Sopenharmony_ci 29362306a36Sopenharmony_ci return 0; 29462306a36Sopenharmony_ci} 29562306a36Sopenharmony_ci 29662306a36Sopenharmony_cistatic int rt2800usb_enable_radio(struct rt2x00_dev *rt2x00dev) 29762306a36Sopenharmony_ci{ 29862306a36Sopenharmony_ci u32 reg = 0; 29962306a36Sopenharmony_ci 30062306a36Sopenharmony_ci if (unlikely(rt2800_wait_wpdma_ready(rt2x00dev))) 30162306a36Sopenharmony_ci return -EIO; 30262306a36Sopenharmony_ci 30362306a36Sopenharmony_ci rt2x00_set_field32(®, USB_DMA_CFG_PHY_CLEAR, 0); 30462306a36Sopenharmony_ci rt2x00_set_field32(®, USB_DMA_CFG_RX_BULK_AGG_EN, 0); 30562306a36Sopenharmony_ci rt2x00_set_field32(®, USB_DMA_CFG_RX_BULK_AGG_TIMEOUT, 128); 30662306a36Sopenharmony_ci /* 30762306a36Sopenharmony_ci * Total room for RX frames in kilobytes, PBF might still exceed 30862306a36Sopenharmony_ci * this limit so reduce the number to prevent errors. 30962306a36Sopenharmony_ci */ 31062306a36Sopenharmony_ci rt2x00_set_field32(®, USB_DMA_CFG_RX_BULK_AGG_LIMIT, 31162306a36Sopenharmony_ci ((rt2x00dev->rx->limit * DATA_FRAME_SIZE) 31262306a36Sopenharmony_ci / 1024) - 3); 31362306a36Sopenharmony_ci rt2x00_set_field32(®, USB_DMA_CFG_RX_BULK_EN, 1); 31462306a36Sopenharmony_ci rt2x00_set_field32(®, USB_DMA_CFG_TX_BULK_EN, 1); 31562306a36Sopenharmony_ci rt2x00usb_register_write(rt2x00dev, USB_DMA_CFG, reg); 31662306a36Sopenharmony_ci 31762306a36Sopenharmony_ci return rt2800_enable_radio(rt2x00dev); 31862306a36Sopenharmony_ci} 31962306a36Sopenharmony_ci 32062306a36Sopenharmony_cistatic void rt2800usb_disable_radio(struct rt2x00_dev *rt2x00dev) 32162306a36Sopenharmony_ci{ 32262306a36Sopenharmony_ci rt2800_disable_radio(rt2x00dev); 32362306a36Sopenharmony_ci} 32462306a36Sopenharmony_ci 32562306a36Sopenharmony_cistatic int rt2800usb_set_state(struct rt2x00_dev *rt2x00dev, 32662306a36Sopenharmony_ci enum dev_state state) 32762306a36Sopenharmony_ci{ 32862306a36Sopenharmony_ci if (state == STATE_AWAKE) 32962306a36Sopenharmony_ci rt2800_mcu_request(rt2x00dev, MCU_WAKEUP, 0xff, 0, 2); 33062306a36Sopenharmony_ci else 33162306a36Sopenharmony_ci rt2800_mcu_request(rt2x00dev, MCU_SLEEP, 0xff, 0xff, 2); 33262306a36Sopenharmony_ci 33362306a36Sopenharmony_ci return 0; 33462306a36Sopenharmony_ci} 33562306a36Sopenharmony_ci 33662306a36Sopenharmony_cistatic int rt2800usb_set_device_state(struct rt2x00_dev *rt2x00dev, 33762306a36Sopenharmony_ci enum dev_state state) 33862306a36Sopenharmony_ci{ 33962306a36Sopenharmony_ci int retval = 0; 34062306a36Sopenharmony_ci 34162306a36Sopenharmony_ci switch (state) { 34262306a36Sopenharmony_ci case STATE_RADIO_ON: 34362306a36Sopenharmony_ci /* 34462306a36Sopenharmony_ci * Before the radio can be enabled, the device first has 34562306a36Sopenharmony_ci * to be woken up. After that it needs a bit of time 34662306a36Sopenharmony_ci * to be fully awake and then the radio can be enabled. 34762306a36Sopenharmony_ci */ 34862306a36Sopenharmony_ci rt2800usb_set_state(rt2x00dev, STATE_AWAKE); 34962306a36Sopenharmony_ci msleep(1); 35062306a36Sopenharmony_ci retval = rt2800usb_enable_radio(rt2x00dev); 35162306a36Sopenharmony_ci break; 35262306a36Sopenharmony_ci case STATE_RADIO_OFF: 35362306a36Sopenharmony_ci /* 35462306a36Sopenharmony_ci * After the radio has been disabled, the device should 35562306a36Sopenharmony_ci * be put to sleep for powersaving. 35662306a36Sopenharmony_ci */ 35762306a36Sopenharmony_ci rt2800usb_disable_radio(rt2x00dev); 35862306a36Sopenharmony_ci rt2800usb_set_state(rt2x00dev, STATE_SLEEP); 35962306a36Sopenharmony_ci break; 36062306a36Sopenharmony_ci case STATE_RADIO_IRQ_ON: 36162306a36Sopenharmony_ci case STATE_RADIO_IRQ_OFF: 36262306a36Sopenharmony_ci /* No support, but no error either */ 36362306a36Sopenharmony_ci break; 36462306a36Sopenharmony_ci case STATE_DEEP_SLEEP: 36562306a36Sopenharmony_ci case STATE_SLEEP: 36662306a36Sopenharmony_ci case STATE_STANDBY: 36762306a36Sopenharmony_ci case STATE_AWAKE: 36862306a36Sopenharmony_ci retval = rt2800usb_set_state(rt2x00dev, state); 36962306a36Sopenharmony_ci break; 37062306a36Sopenharmony_ci default: 37162306a36Sopenharmony_ci retval = -ENOTSUPP; 37262306a36Sopenharmony_ci break; 37362306a36Sopenharmony_ci } 37462306a36Sopenharmony_ci 37562306a36Sopenharmony_ci if (unlikely(retval)) 37662306a36Sopenharmony_ci rt2x00_err(rt2x00dev, "Device failed to enter state %d (%d)\n", 37762306a36Sopenharmony_ci state, retval); 37862306a36Sopenharmony_ci 37962306a36Sopenharmony_ci return retval; 38062306a36Sopenharmony_ci} 38162306a36Sopenharmony_ci 38262306a36Sopenharmony_cistatic unsigned int rt2800usb_get_dma_done(struct data_queue *queue) 38362306a36Sopenharmony_ci{ 38462306a36Sopenharmony_ci struct queue_entry *entry; 38562306a36Sopenharmony_ci 38662306a36Sopenharmony_ci entry = rt2x00queue_get_entry(queue, Q_INDEX_DMA_DONE); 38762306a36Sopenharmony_ci return entry->entry_idx; 38862306a36Sopenharmony_ci} 38962306a36Sopenharmony_ci 39062306a36Sopenharmony_ci/* 39162306a36Sopenharmony_ci * TX descriptor initialization 39262306a36Sopenharmony_ci */ 39362306a36Sopenharmony_cistatic __le32 *rt2800usb_get_txwi(struct queue_entry *entry) 39462306a36Sopenharmony_ci{ 39562306a36Sopenharmony_ci if (entry->queue->qid == QID_BEACON) 39662306a36Sopenharmony_ci return (__le32 *) (entry->skb->data); 39762306a36Sopenharmony_ci else 39862306a36Sopenharmony_ci return (__le32 *) (entry->skb->data + TXINFO_DESC_SIZE); 39962306a36Sopenharmony_ci} 40062306a36Sopenharmony_ci 40162306a36Sopenharmony_cistatic void rt2800usb_write_tx_desc(struct queue_entry *entry, 40262306a36Sopenharmony_ci struct txentry_desc *txdesc) 40362306a36Sopenharmony_ci{ 40462306a36Sopenharmony_ci struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb); 40562306a36Sopenharmony_ci __le32 *txi = (__le32 *) entry->skb->data; 40662306a36Sopenharmony_ci u32 word; 40762306a36Sopenharmony_ci 40862306a36Sopenharmony_ci /* 40962306a36Sopenharmony_ci * Initialize TXINFO descriptor 41062306a36Sopenharmony_ci */ 41162306a36Sopenharmony_ci word = rt2x00_desc_read(txi, 0); 41262306a36Sopenharmony_ci 41362306a36Sopenharmony_ci /* 41462306a36Sopenharmony_ci * The size of TXINFO_W0_USB_DMA_TX_PKT_LEN is 41562306a36Sopenharmony_ci * TXWI + 802.11 header + L2 pad + payload + pad, 41662306a36Sopenharmony_ci * so need to decrease size of TXINFO. 41762306a36Sopenharmony_ci */ 41862306a36Sopenharmony_ci rt2x00_set_field32(&word, TXINFO_W0_USB_DMA_TX_PKT_LEN, 41962306a36Sopenharmony_ci roundup(entry->skb->len, 4) - TXINFO_DESC_SIZE); 42062306a36Sopenharmony_ci rt2x00_set_field32(&word, TXINFO_W0_WIV, 42162306a36Sopenharmony_ci !test_bit(ENTRY_TXD_ENCRYPT_IV, &txdesc->flags)); 42262306a36Sopenharmony_ci rt2x00_set_field32(&word, TXINFO_W0_QSEL, 2); 42362306a36Sopenharmony_ci rt2x00_set_field32(&word, TXINFO_W0_SW_USE_LAST_ROUND, 0); 42462306a36Sopenharmony_ci rt2x00_set_field32(&word, TXINFO_W0_USB_DMA_NEXT_VALID, 0); 42562306a36Sopenharmony_ci rt2x00_set_field32(&word, TXINFO_W0_USB_DMA_TX_BURST, 42662306a36Sopenharmony_ci test_bit(ENTRY_TXD_BURST, &txdesc->flags)); 42762306a36Sopenharmony_ci rt2x00_desc_write(txi, 0, word); 42862306a36Sopenharmony_ci 42962306a36Sopenharmony_ci /* 43062306a36Sopenharmony_ci * Register descriptor details in skb frame descriptor. 43162306a36Sopenharmony_ci */ 43262306a36Sopenharmony_ci skbdesc->flags |= SKBDESC_DESC_IN_SKB; 43362306a36Sopenharmony_ci skbdesc->desc = txi; 43462306a36Sopenharmony_ci skbdesc->desc_len = TXINFO_DESC_SIZE + entry->queue->winfo_size; 43562306a36Sopenharmony_ci} 43662306a36Sopenharmony_ci 43762306a36Sopenharmony_ci/* 43862306a36Sopenharmony_ci * TX data initialization 43962306a36Sopenharmony_ci */ 44062306a36Sopenharmony_cistatic int rt2800usb_get_tx_data_len(struct queue_entry *entry) 44162306a36Sopenharmony_ci{ 44262306a36Sopenharmony_ci /* 44362306a36Sopenharmony_ci * pad(1~3 bytes) is needed after each 802.11 payload. 44462306a36Sopenharmony_ci * USB end pad(4 bytes) is needed at each USB bulk out packet end. 44562306a36Sopenharmony_ci * TX frame format is : 44662306a36Sopenharmony_ci * | TXINFO | TXWI | 802.11 header | L2 pad | payload | pad | USB end pad | 44762306a36Sopenharmony_ci * |<------------- tx_pkt_len ------------->| 44862306a36Sopenharmony_ci */ 44962306a36Sopenharmony_ci 45062306a36Sopenharmony_ci return roundup(entry->skb->len, 4) + 4; 45162306a36Sopenharmony_ci} 45262306a36Sopenharmony_ci 45362306a36Sopenharmony_ci/* 45462306a36Sopenharmony_ci * TX control handlers 45562306a36Sopenharmony_ci */ 45662306a36Sopenharmony_cistatic void rt2800usb_work_txdone(struct work_struct *work) 45762306a36Sopenharmony_ci{ 45862306a36Sopenharmony_ci struct rt2x00_dev *rt2x00dev = 45962306a36Sopenharmony_ci container_of(work, struct rt2x00_dev, txdone_work); 46062306a36Sopenharmony_ci 46162306a36Sopenharmony_ci while (!kfifo_is_empty(&rt2x00dev->txstatus_fifo) || 46262306a36Sopenharmony_ci rt2800_txstatus_timeout(rt2x00dev)) { 46362306a36Sopenharmony_ci 46462306a36Sopenharmony_ci rt2800_txdone(rt2x00dev, UINT_MAX); 46562306a36Sopenharmony_ci 46662306a36Sopenharmony_ci rt2800_txdone_nostatus(rt2x00dev); 46762306a36Sopenharmony_ci 46862306a36Sopenharmony_ci /* 46962306a36Sopenharmony_ci * The hw may delay sending the packet after DMA complete 47062306a36Sopenharmony_ci * if the medium is busy, thus the TX_STA_FIFO entry is 47162306a36Sopenharmony_ci * also delayed -> use a timer to retrieve it. 47262306a36Sopenharmony_ci */ 47362306a36Sopenharmony_ci if (rt2800_txstatus_pending(rt2x00dev)) 47462306a36Sopenharmony_ci rt2800usb_async_read_tx_status(rt2x00dev); 47562306a36Sopenharmony_ci } 47662306a36Sopenharmony_ci} 47762306a36Sopenharmony_ci 47862306a36Sopenharmony_ci/* 47962306a36Sopenharmony_ci * RX control handlers 48062306a36Sopenharmony_ci */ 48162306a36Sopenharmony_cistatic void rt2800usb_fill_rxdone(struct queue_entry *entry, 48262306a36Sopenharmony_ci struct rxdone_entry_desc *rxdesc) 48362306a36Sopenharmony_ci{ 48462306a36Sopenharmony_ci struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb); 48562306a36Sopenharmony_ci __le32 *rxi = (__le32 *)entry->skb->data; 48662306a36Sopenharmony_ci __le32 *rxd; 48762306a36Sopenharmony_ci u32 word; 48862306a36Sopenharmony_ci int rx_pkt_len; 48962306a36Sopenharmony_ci 49062306a36Sopenharmony_ci /* 49162306a36Sopenharmony_ci * Copy descriptor to the skbdesc->desc buffer, making it safe from 49262306a36Sopenharmony_ci * moving of frame data in rt2x00usb. 49362306a36Sopenharmony_ci */ 49462306a36Sopenharmony_ci memcpy(skbdesc->desc, rxi, skbdesc->desc_len); 49562306a36Sopenharmony_ci 49662306a36Sopenharmony_ci /* 49762306a36Sopenharmony_ci * RX frame format is : 49862306a36Sopenharmony_ci * | RXINFO | RXWI | header | L2 pad | payload | pad | RXD | USB pad | 49962306a36Sopenharmony_ci * |<------------ rx_pkt_len -------------->| 50062306a36Sopenharmony_ci */ 50162306a36Sopenharmony_ci word = rt2x00_desc_read(rxi, 0); 50262306a36Sopenharmony_ci rx_pkt_len = rt2x00_get_field32(word, RXINFO_W0_USB_DMA_RX_PKT_LEN); 50362306a36Sopenharmony_ci 50462306a36Sopenharmony_ci /* 50562306a36Sopenharmony_ci * Remove the RXINFO structure from the sbk. 50662306a36Sopenharmony_ci */ 50762306a36Sopenharmony_ci skb_pull(entry->skb, RXINFO_DESC_SIZE); 50862306a36Sopenharmony_ci 50962306a36Sopenharmony_ci /* 51062306a36Sopenharmony_ci * Check for rx_pkt_len validity. Return if invalid, leaving 51162306a36Sopenharmony_ci * rxdesc->size zeroed out by the upper level. 51262306a36Sopenharmony_ci */ 51362306a36Sopenharmony_ci if (unlikely(rx_pkt_len == 0 || 51462306a36Sopenharmony_ci rx_pkt_len > entry->queue->data_size)) { 51562306a36Sopenharmony_ci rt2x00_err(entry->queue->rt2x00dev, 51662306a36Sopenharmony_ci "Bad frame size %d, forcing to 0\n", rx_pkt_len); 51762306a36Sopenharmony_ci return; 51862306a36Sopenharmony_ci } 51962306a36Sopenharmony_ci 52062306a36Sopenharmony_ci rxd = (__le32 *)(entry->skb->data + rx_pkt_len); 52162306a36Sopenharmony_ci 52262306a36Sopenharmony_ci /* 52362306a36Sopenharmony_ci * It is now safe to read the descriptor on all architectures. 52462306a36Sopenharmony_ci */ 52562306a36Sopenharmony_ci word = rt2x00_desc_read(rxd, 0); 52662306a36Sopenharmony_ci 52762306a36Sopenharmony_ci if (rt2x00_get_field32(word, RXD_W0_CRC_ERROR)) 52862306a36Sopenharmony_ci rxdesc->flags |= RX_FLAG_FAILED_FCS_CRC; 52962306a36Sopenharmony_ci 53062306a36Sopenharmony_ci rxdesc->cipher_status = rt2x00_get_field32(word, RXD_W0_CIPHER_ERROR); 53162306a36Sopenharmony_ci 53262306a36Sopenharmony_ci if (rt2x00_get_field32(word, RXD_W0_DECRYPTED)) { 53362306a36Sopenharmony_ci /* 53462306a36Sopenharmony_ci * Hardware has stripped IV/EIV data from 802.11 frame during 53562306a36Sopenharmony_ci * decryption. Unfortunately the descriptor doesn't contain 53662306a36Sopenharmony_ci * any fields with the EIV/IV data either, so they can't 53762306a36Sopenharmony_ci * be restored by rt2x00lib. 53862306a36Sopenharmony_ci */ 53962306a36Sopenharmony_ci rxdesc->flags |= RX_FLAG_IV_STRIPPED; 54062306a36Sopenharmony_ci 54162306a36Sopenharmony_ci /* 54262306a36Sopenharmony_ci * The hardware has already checked the Michael Mic and has 54362306a36Sopenharmony_ci * stripped it from the frame. Signal this to mac80211. 54462306a36Sopenharmony_ci */ 54562306a36Sopenharmony_ci rxdesc->flags |= RX_FLAG_MMIC_STRIPPED; 54662306a36Sopenharmony_ci 54762306a36Sopenharmony_ci if (rxdesc->cipher_status == RX_CRYPTO_SUCCESS) { 54862306a36Sopenharmony_ci rxdesc->flags |= RX_FLAG_DECRYPTED; 54962306a36Sopenharmony_ci } else if (rxdesc->cipher_status == RX_CRYPTO_FAIL_MIC) { 55062306a36Sopenharmony_ci /* 55162306a36Sopenharmony_ci * In order to check the Michael Mic, the packet must have 55262306a36Sopenharmony_ci * been decrypted. Mac80211 doesnt check the MMIC failure 55362306a36Sopenharmony_ci * flag to initiate MMIC countermeasures if the decoded flag 55462306a36Sopenharmony_ci * has not been set. 55562306a36Sopenharmony_ci */ 55662306a36Sopenharmony_ci rxdesc->flags |= RX_FLAG_DECRYPTED; 55762306a36Sopenharmony_ci 55862306a36Sopenharmony_ci rxdesc->flags |= RX_FLAG_MMIC_ERROR; 55962306a36Sopenharmony_ci } 56062306a36Sopenharmony_ci } 56162306a36Sopenharmony_ci 56262306a36Sopenharmony_ci if (rt2x00_get_field32(word, RXD_W0_MY_BSS)) 56362306a36Sopenharmony_ci rxdesc->dev_flags |= RXDONE_MY_BSS; 56462306a36Sopenharmony_ci 56562306a36Sopenharmony_ci if (rt2x00_get_field32(word, RXD_W0_L2PAD)) 56662306a36Sopenharmony_ci rxdesc->dev_flags |= RXDONE_L2PAD; 56762306a36Sopenharmony_ci 56862306a36Sopenharmony_ci /* 56962306a36Sopenharmony_ci * Remove RXD descriptor from end of buffer. 57062306a36Sopenharmony_ci */ 57162306a36Sopenharmony_ci skb_trim(entry->skb, rx_pkt_len); 57262306a36Sopenharmony_ci 57362306a36Sopenharmony_ci /* 57462306a36Sopenharmony_ci * Process the RXWI structure. 57562306a36Sopenharmony_ci */ 57662306a36Sopenharmony_ci rt2800_process_rxwi(entry, rxdesc); 57762306a36Sopenharmony_ci} 57862306a36Sopenharmony_ci 57962306a36Sopenharmony_ci/* 58062306a36Sopenharmony_ci * Device probe functions. 58162306a36Sopenharmony_ci */ 58262306a36Sopenharmony_cistatic int rt2800usb_efuse_detect(struct rt2x00_dev *rt2x00dev) 58362306a36Sopenharmony_ci{ 58462306a36Sopenharmony_ci int retval; 58562306a36Sopenharmony_ci 58662306a36Sopenharmony_ci retval = rt2800usb_autorun_detect(rt2x00dev); 58762306a36Sopenharmony_ci if (retval < 0) 58862306a36Sopenharmony_ci return retval; 58962306a36Sopenharmony_ci if (retval) 59062306a36Sopenharmony_ci return 1; 59162306a36Sopenharmony_ci return rt2800_efuse_detect(rt2x00dev); 59262306a36Sopenharmony_ci} 59362306a36Sopenharmony_ci 59462306a36Sopenharmony_cistatic int rt2800usb_read_eeprom(struct rt2x00_dev *rt2x00dev) 59562306a36Sopenharmony_ci{ 59662306a36Sopenharmony_ci int retval; 59762306a36Sopenharmony_ci 59862306a36Sopenharmony_ci retval = rt2800usb_efuse_detect(rt2x00dev); 59962306a36Sopenharmony_ci if (retval < 0) 60062306a36Sopenharmony_ci return retval; 60162306a36Sopenharmony_ci if (retval) 60262306a36Sopenharmony_ci retval = rt2800_read_eeprom_efuse(rt2x00dev); 60362306a36Sopenharmony_ci else 60462306a36Sopenharmony_ci retval = rt2x00usb_eeprom_read(rt2x00dev, rt2x00dev->eeprom, 60562306a36Sopenharmony_ci EEPROM_SIZE); 60662306a36Sopenharmony_ci 60762306a36Sopenharmony_ci return retval; 60862306a36Sopenharmony_ci} 60962306a36Sopenharmony_ci 61062306a36Sopenharmony_cistatic int rt2800usb_probe_hw(struct rt2x00_dev *rt2x00dev) 61162306a36Sopenharmony_ci{ 61262306a36Sopenharmony_ci int retval; 61362306a36Sopenharmony_ci 61462306a36Sopenharmony_ci retval = rt2800_probe_hw(rt2x00dev); 61562306a36Sopenharmony_ci if (retval) 61662306a36Sopenharmony_ci return retval; 61762306a36Sopenharmony_ci 61862306a36Sopenharmony_ci /* 61962306a36Sopenharmony_ci * Set txstatus timer function. 62062306a36Sopenharmony_ci */ 62162306a36Sopenharmony_ci rt2x00dev->txstatus_timer.function = rt2800usb_tx_sta_fifo_timeout; 62262306a36Sopenharmony_ci 62362306a36Sopenharmony_ci /* 62462306a36Sopenharmony_ci * Overwrite TX done handler 62562306a36Sopenharmony_ci */ 62662306a36Sopenharmony_ci INIT_WORK(&rt2x00dev->txdone_work, rt2800usb_work_txdone); 62762306a36Sopenharmony_ci 62862306a36Sopenharmony_ci return 0; 62962306a36Sopenharmony_ci} 63062306a36Sopenharmony_ci 63162306a36Sopenharmony_cistatic const struct ieee80211_ops rt2800usb_mac80211_ops = { 63262306a36Sopenharmony_ci .tx = rt2x00mac_tx, 63362306a36Sopenharmony_ci .wake_tx_queue = ieee80211_handle_wake_tx_queue, 63462306a36Sopenharmony_ci .start = rt2x00mac_start, 63562306a36Sopenharmony_ci .stop = rt2x00mac_stop, 63662306a36Sopenharmony_ci .add_interface = rt2x00mac_add_interface, 63762306a36Sopenharmony_ci .remove_interface = rt2x00mac_remove_interface, 63862306a36Sopenharmony_ci .config = rt2x00mac_config, 63962306a36Sopenharmony_ci .configure_filter = rt2x00mac_configure_filter, 64062306a36Sopenharmony_ci .set_tim = rt2x00mac_set_tim, 64162306a36Sopenharmony_ci .set_key = rt2x00mac_set_key, 64262306a36Sopenharmony_ci .sw_scan_start = rt2x00mac_sw_scan_start, 64362306a36Sopenharmony_ci .sw_scan_complete = rt2x00mac_sw_scan_complete, 64462306a36Sopenharmony_ci .get_stats = rt2x00mac_get_stats, 64562306a36Sopenharmony_ci .get_key_seq = rt2800_get_key_seq, 64662306a36Sopenharmony_ci .set_rts_threshold = rt2800_set_rts_threshold, 64762306a36Sopenharmony_ci .sta_add = rt2800_sta_add, 64862306a36Sopenharmony_ci .sta_remove = rt2800_sta_remove, 64962306a36Sopenharmony_ci .bss_info_changed = rt2x00mac_bss_info_changed, 65062306a36Sopenharmony_ci .conf_tx = rt2800_conf_tx, 65162306a36Sopenharmony_ci .get_tsf = rt2800_get_tsf, 65262306a36Sopenharmony_ci .rfkill_poll = rt2x00mac_rfkill_poll, 65362306a36Sopenharmony_ci .ampdu_action = rt2800_ampdu_action, 65462306a36Sopenharmony_ci .flush = rt2x00mac_flush, 65562306a36Sopenharmony_ci .get_survey = rt2800_get_survey, 65662306a36Sopenharmony_ci .get_ringparam = rt2x00mac_get_ringparam, 65762306a36Sopenharmony_ci .tx_frames_pending = rt2x00mac_tx_frames_pending, 65862306a36Sopenharmony_ci .reconfig_complete = rt2x00mac_reconfig_complete, 65962306a36Sopenharmony_ci}; 66062306a36Sopenharmony_ci 66162306a36Sopenharmony_cistatic const struct rt2800_ops rt2800usb_rt2800_ops = { 66262306a36Sopenharmony_ci .register_read = rt2x00usb_register_read, 66362306a36Sopenharmony_ci .register_read_lock = rt2x00usb_register_read_lock, 66462306a36Sopenharmony_ci .register_write = rt2x00usb_register_write, 66562306a36Sopenharmony_ci .register_write_lock = rt2x00usb_register_write_lock, 66662306a36Sopenharmony_ci .register_multiread = rt2x00usb_register_multiread, 66762306a36Sopenharmony_ci .register_multiwrite = rt2x00usb_register_multiwrite, 66862306a36Sopenharmony_ci .regbusy_read = rt2x00usb_regbusy_read, 66962306a36Sopenharmony_ci .read_eeprom = rt2800usb_read_eeprom, 67062306a36Sopenharmony_ci .hwcrypt_disabled = rt2800usb_hwcrypt_disabled, 67162306a36Sopenharmony_ci .drv_write_firmware = rt2800usb_write_firmware, 67262306a36Sopenharmony_ci .drv_init_registers = rt2800usb_init_registers, 67362306a36Sopenharmony_ci .drv_get_txwi = rt2800usb_get_txwi, 67462306a36Sopenharmony_ci .drv_get_dma_done = rt2800usb_get_dma_done, 67562306a36Sopenharmony_ci}; 67662306a36Sopenharmony_ci 67762306a36Sopenharmony_cistatic const struct rt2x00lib_ops rt2800usb_rt2x00_ops = { 67862306a36Sopenharmony_ci .probe_hw = rt2800usb_probe_hw, 67962306a36Sopenharmony_ci .get_firmware_name = rt2800usb_get_firmware_name, 68062306a36Sopenharmony_ci .check_firmware = rt2800_check_firmware, 68162306a36Sopenharmony_ci .load_firmware = rt2800_load_firmware, 68262306a36Sopenharmony_ci .initialize = rt2x00usb_initialize, 68362306a36Sopenharmony_ci .uninitialize = rt2x00usb_uninitialize, 68462306a36Sopenharmony_ci .clear_entry = rt2x00usb_clear_entry, 68562306a36Sopenharmony_ci .set_device_state = rt2800usb_set_device_state, 68662306a36Sopenharmony_ci .rfkill_poll = rt2800_rfkill_poll, 68762306a36Sopenharmony_ci .link_stats = rt2800_link_stats, 68862306a36Sopenharmony_ci .reset_tuner = rt2800_reset_tuner, 68962306a36Sopenharmony_ci .link_tuner = rt2800_link_tuner, 69062306a36Sopenharmony_ci .gain_calibration = rt2800_gain_calibration, 69162306a36Sopenharmony_ci .vco_calibration = rt2800_vco_calibration, 69262306a36Sopenharmony_ci .watchdog = rt2800_watchdog, 69362306a36Sopenharmony_ci .start_queue = rt2800usb_start_queue, 69462306a36Sopenharmony_ci .kick_queue = rt2x00usb_kick_queue, 69562306a36Sopenharmony_ci .stop_queue = rt2800usb_stop_queue, 69662306a36Sopenharmony_ci .flush_queue = rt2x00usb_flush_queue, 69762306a36Sopenharmony_ci .tx_dma_done = rt2800usb_tx_dma_done, 69862306a36Sopenharmony_ci .write_tx_desc = rt2800usb_write_tx_desc, 69962306a36Sopenharmony_ci .write_tx_data = rt2800_write_tx_data, 70062306a36Sopenharmony_ci .write_beacon = rt2800_write_beacon, 70162306a36Sopenharmony_ci .clear_beacon = rt2800_clear_beacon, 70262306a36Sopenharmony_ci .get_tx_data_len = rt2800usb_get_tx_data_len, 70362306a36Sopenharmony_ci .fill_rxdone = rt2800usb_fill_rxdone, 70462306a36Sopenharmony_ci .config_shared_key = rt2800_config_shared_key, 70562306a36Sopenharmony_ci .config_pairwise_key = rt2800_config_pairwise_key, 70662306a36Sopenharmony_ci .config_filter = rt2800_config_filter, 70762306a36Sopenharmony_ci .config_intf = rt2800_config_intf, 70862306a36Sopenharmony_ci .config_erp = rt2800_config_erp, 70962306a36Sopenharmony_ci .config_ant = rt2800_config_ant, 71062306a36Sopenharmony_ci .config = rt2800_config, 71162306a36Sopenharmony_ci .pre_reset_hw = rt2800_pre_reset_hw, 71262306a36Sopenharmony_ci}; 71362306a36Sopenharmony_ci 71462306a36Sopenharmony_cistatic void rt2800usb_queue_init(struct data_queue *queue) 71562306a36Sopenharmony_ci{ 71662306a36Sopenharmony_ci struct rt2x00_dev *rt2x00dev = queue->rt2x00dev; 71762306a36Sopenharmony_ci unsigned short txwi_size, rxwi_size; 71862306a36Sopenharmony_ci 71962306a36Sopenharmony_ci rt2800_get_txwi_rxwi_size(rt2x00dev, &txwi_size, &rxwi_size); 72062306a36Sopenharmony_ci 72162306a36Sopenharmony_ci switch (queue->qid) { 72262306a36Sopenharmony_ci case QID_RX: 72362306a36Sopenharmony_ci queue->limit = 128; 72462306a36Sopenharmony_ci queue->data_size = AGGREGATION_SIZE; 72562306a36Sopenharmony_ci queue->desc_size = RXINFO_DESC_SIZE; 72662306a36Sopenharmony_ci queue->winfo_size = rxwi_size; 72762306a36Sopenharmony_ci queue->priv_size = sizeof(struct queue_entry_priv_usb); 72862306a36Sopenharmony_ci break; 72962306a36Sopenharmony_ci 73062306a36Sopenharmony_ci case QID_AC_VO: 73162306a36Sopenharmony_ci case QID_AC_VI: 73262306a36Sopenharmony_ci case QID_AC_BE: 73362306a36Sopenharmony_ci case QID_AC_BK: 73462306a36Sopenharmony_ci queue->limit = 16; 73562306a36Sopenharmony_ci queue->data_size = AGGREGATION_SIZE; 73662306a36Sopenharmony_ci queue->desc_size = TXINFO_DESC_SIZE; 73762306a36Sopenharmony_ci queue->winfo_size = txwi_size; 73862306a36Sopenharmony_ci queue->priv_size = sizeof(struct queue_entry_priv_usb); 73962306a36Sopenharmony_ci break; 74062306a36Sopenharmony_ci 74162306a36Sopenharmony_ci case QID_BEACON: 74262306a36Sopenharmony_ci queue->limit = 8; 74362306a36Sopenharmony_ci queue->data_size = MGMT_FRAME_SIZE; 74462306a36Sopenharmony_ci queue->desc_size = TXINFO_DESC_SIZE; 74562306a36Sopenharmony_ci queue->winfo_size = txwi_size; 74662306a36Sopenharmony_ci queue->priv_size = sizeof(struct queue_entry_priv_usb); 74762306a36Sopenharmony_ci break; 74862306a36Sopenharmony_ci 74962306a36Sopenharmony_ci case QID_ATIM: 75062306a36Sopenharmony_ci default: 75162306a36Sopenharmony_ci BUG(); 75262306a36Sopenharmony_ci break; 75362306a36Sopenharmony_ci } 75462306a36Sopenharmony_ci} 75562306a36Sopenharmony_ci 75662306a36Sopenharmony_cistatic const struct rt2x00_ops rt2800usb_ops = { 75762306a36Sopenharmony_ci .name = KBUILD_MODNAME, 75862306a36Sopenharmony_ci .drv_data_size = sizeof(struct rt2800_drv_data), 75962306a36Sopenharmony_ci .max_ap_intf = 8, 76062306a36Sopenharmony_ci .eeprom_size = EEPROM_SIZE, 76162306a36Sopenharmony_ci .rf_size = RF_SIZE, 76262306a36Sopenharmony_ci .tx_queues = NUM_TX_QUEUES, 76362306a36Sopenharmony_ci .queue_init = rt2800usb_queue_init, 76462306a36Sopenharmony_ci .lib = &rt2800usb_rt2x00_ops, 76562306a36Sopenharmony_ci .drv = &rt2800usb_rt2800_ops, 76662306a36Sopenharmony_ci .hw = &rt2800usb_mac80211_ops, 76762306a36Sopenharmony_ci#ifdef CONFIG_RT2X00_LIB_DEBUGFS 76862306a36Sopenharmony_ci .debugfs = &rt2800_rt2x00debug, 76962306a36Sopenharmony_ci#endif /* CONFIG_RT2X00_LIB_DEBUGFS */ 77062306a36Sopenharmony_ci}; 77162306a36Sopenharmony_ci 77262306a36Sopenharmony_ci/* 77362306a36Sopenharmony_ci * rt2800usb module information. 77462306a36Sopenharmony_ci */ 77562306a36Sopenharmony_cistatic const struct usb_device_id rt2800usb_device_table[] = { 77662306a36Sopenharmony_ci /* Abocom */ 77762306a36Sopenharmony_ci { USB_DEVICE(0x07b8, 0x2870) }, 77862306a36Sopenharmony_ci { USB_DEVICE(0x07b8, 0x2770) }, 77962306a36Sopenharmony_ci { USB_DEVICE(0x07b8, 0x3070) }, 78062306a36Sopenharmony_ci { USB_DEVICE(0x07b8, 0x3071) }, 78162306a36Sopenharmony_ci { USB_DEVICE(0x07b8, 0x3072) }, 78262306a36Sopenharmony_ci { USB_DEVICE(0x1482, 0x3c09) }, 78362306a36Sopenharmony_ci /* AirTies */ 78462306a36Sopenharmony_ci { USB_DEVICE(0x1eda, 0x2012) }, 78562306a36Sopenharmony_ci { USB_DEVICE(0x1eda, 0x2210) }, 78662306a36Sopenharmony_ci { USB_DEVICE(0x1eda, 0x2310) }, 78762306a36Sopenharmony_ci /* Allwin */ 78862306a36Sopenharmony_ci { USB_DEVICE(0x8516, 0x2070) }, 78962306a36Sopenharmony_ci { USB_DEVICE(0x8516, 0x2770) }, 79062306a36Sopenharmony_ci { USB_DEVICE(0x8516, 0x2870) }, 79162306a36Sopenharmony_ci { USB_DEVICE(0x8516, 0x3070) }, 79262306a36Sopenharmony_ci { USB_DEVICE(0x8516, 0x3071) }, 79362306a36Sopenharmony_ci { USB_DEVICE(0x8516, 0x3072) }, 79462306a36Sopenharmony_ci /* Alpha Networks */ 79562306a36Sopenharmony_ci { USB_DEVICE(0x14b2, 0x3c06) }, 79662306a36Sopenharmony_ci { USB_DEVICE(0x14b2, 0x3c07) }, 79762306a36Sopenharmony_ci { USB_DEVICE(0x14b2, 0x3c09) }, 79862306a36Sopenharmony_ci { USB_DEVICE(0x14b2, 0x3c12) }, 79962306a36Sopenharmony_ci { USB_DEVICE(0x14b2, 0x3c23) }, 80062306a36Sopenharmony_ci { USB_DEVICE(0x14b2, 0x3c25) }, 80162306a36Sopenharmony_ci { USB_DEVICE(0x14b2, 0x3c27) }, 80262306a36Sopenharmony_ci { USB_DEVICE(0x14b2, 0x3c28) }, 80362306a36Sopenharmony_ci { USB_DEVICE(0x14b2, 0x3c2c) }, 80462306a36Sopenharmony_ci /* Amit */ 80562306a36Sopenharmony_ci { USB_DEVICE(0x15c5, 0x0008) }, 80662306a36Sopenharmony_ci /* Askey */ 80762306a36Sopenharmony_ci { USB_DEVICE(0x1690, 0x0740) }, 80862306a36Sopenharmony_ci /* ASUS */ 80962306a36Sopenharmony_ci { USB_DEVICE(0x0b05, 0x1731) }, 81062306a36Sopenharmony_ci { USB_DEVICE(0x0b05, 0x1732) }, 81162306a36Sopenharmony_ci { USB_DEVICE(0x0b05, 0x1742) }, 81262306a36Sopenharmony_ci { USB_DEVICE(0x0b05, 0x1784) }, 81362306a36Sopenharmony_ci { USB_DEVICE(0x1761, 0x0b05) }, 81462306a36Sopenharmony_ci /* AzureWave */ 81562306a36Sopenharmony_ci { USB_DEVICE(0x13d3, 0x3247) }, 81662306a36Sopenharmony_ci { USB_DEVICE(0x13d3, 0x3273) }, 81762306a36Sopenharmony_ci { USB_DEVICE(0x13d3, 0x3305) }, 81862306a36Sopenharmony_ci { USB_DEVICE(0x13d3, 0x3307) }, 81962306a36Sopenharmony_ci { USB_DEVICE(0x13d3, 0x3321) }, 82062306a36Sopenharmony_ci /* Belkin */ 82162306a36Sopenharmony_ci { USB_DEVICE(0x050d, 0x8053) }, 82262306a36Sopenharmony_ci { USB_DEVICE(0x050d, 0x805c) }, 82362306a36Sopenharmony_ci { USB_DEVICE(0x050d, 0x815c) }, 82462306a36Sopenharmony_ci { USB_DEVICE(0x050d, 0x825a) }, 82562306a36Sopenharmony_ci { USB_DEVICE(0x050d, 0x825b) }, 82662306a36Sopenharmony_ci { USB_DEVICE(0x050d, 0x935a) }, 82762306a36Sopenharmony_ci { USB_DEVICE(0x050d, 0x935b) }, 82862306a36Sopenharmony_ci /* Buffalo */ 82962306a36Sopenharmony_ci { USB_DEVICE(0x0411, 0x00e8) }, 83062306a36Sopenharmony_ci { USB_DEVICE(0x0411, 0x0158) }, 83162306a36Sopenharmony_ci { USB_DEVICE(0x0411, 0x015d) }, 83262306a36Sopenharmony_ci { USB_DEVICE(0x0411, 0x016f) }, 83362306a36Sopenharmony_ci { USB_DEVICE(0x0411, 0x01a2) }, 83462306a36Sopenharmony_ci { USB_DEVICE(0x0411, 0x01ee) }, 83562306a36Sopenharmony_ci { USB_DEVICE(0x0411, 0x01a8) }, 83662306a36Sopenharmony_ci { USB_DEVICE(0x0411, 0x01fd) }, 83762306a36Sopenharmony_ci /* Corega */ 83862306a36Sopenharmony_ci { USB_DEVICE(0x07aa, 0x002f) }, 83962306a36Sopenharmony_ci { USB_DEVICE(0x07aa, 0x003c) }, 84062306a36Sopenharmony_ci { USB_DEVICE(0x07aa, 0x003f) }, 84162306a36Sopenharmony_ci { USB_DEVICE(0x18c5, 0x0012) }, 84262306a36Sopenharmony_ci /* D-Link */ 84362306a36Sopenharmony_ci { USB_DEVICE(0x07d1, 0x3c09) }, 84462306a36Sopenharmony_ci { USB_DEVICE(0x07d1, 0x3c0a) }, 84562306a36Sopenharmony_ci { USB_DEVICE(0x07d1, 0x3c0d) }, 84662306a36Sopenharmony_ci { USB_DEVICE(0x07d1, 0x3c0e) }, 84762306a36Sopenharmony_ci { USB_DEVICE(0x07d1, 0x3c0f) }, 84862306a36Sopenharmony_ci { USB_DEVICE(0x07d1, 0x3c11) }, 84962306a36Sopenharmony_ci { USB_DEVICE(0x07d1, 0x3c13) }, 85062306a36Sopenharmony_ci { USB_DEVICE(0x07d1, 0x3c15) }, 85162306a36Sopenharmony_ci { USB_DEVICE(0x07d1, 0x3c16) }, 85262306a36Sopenharmony_ci { USB_DEVICE(0x07d1, 0x3c17) }, 85362306a36Sopenharmony_ci { USB_DEVICE(0x2001, 0x3317) }, 85462306a36Sopenharmony_ci { USB_DEVICE(0x2001, 0x3c1b) }, 85562306a36Sopenharmony_ci { USB_DEVICE(0x2001, 0x3c25) }, 85662306a36Sopenharmony_ci /* Draytek */ 85762306a36Sopenharmony_ci { USB_DEVICE(0x07fa, 0x7712) }, 85862306a36Sopenharmony_ci /* DVICO */ 85962306a36Sopenharmony_ci { USB_DEVICE(0x0fe9, 0xb307) }, 86062306a36Sopenharmony_ci /* Edimax */ 86162306a36Sopenharmony_ci { USB_DEVICE(0x7392, 0x4085) }, 86262306a36Sopenharmony_ci { USB_DEVICE(0x7392, 0x7711) }, 86362306a36Sopenharmony_ci { USB_DEVICE(0x7392, 0x7717) }, 86462306a36Sopenharmony_ci { USB_DEVICE(0x7392, 0x7718) }, 86562306a36Sopenharmony_ci { USB_DEVICE(0x7392, 0x7722) }, 86662306a36Sopenharmony_ci /* Encore */ 86762306a36Sopenharmony_ci { USB_DEVICE(0x203d, 0x1480) }, 86862306a36Sopenharmony_ci { USB_DEVICE(0x203d, 0x14a9) }, 86962306a36Sopenharmony_ci /* EnGenius */ 87062306a36Sopenharmony_ci { USB_DEVICE(0x1740, 0x9701) }, 87162306a36Sopenharmony_ci { USB_DEVICE(0x1740, 0x9702) }, 87262306a36Sopenharmony_ci { USB_DEVICE(0x1740, 0x9703) }, 87362306a36Sopenharmony_ci { USB_DEVICE(0x1740, 0x9705) }, 87462306a36Sopenharmony_ci { USB_DEVICE(0x1740, 0x9706) }, 87562306a36Sopenharmony_ci { USB_DEVICE(0x1740, 0x9707) }, 87662306a36Sopenharmony_ci { USB_DEVICE(0x1740, 0x9708) }, 87762306a36Sopenharmony_ci { USB_DEVICE(0x1740, 0x9709) }, 87862306a36Sopenharmony_ci /* Gemtek */ 87962306a36Sopenharmony_ci { USB_DEVICE(0x15a9, 0x0012) }, 88062306a36Sopenharmony_ci /* Gigabyte */ 88162306a36Sopenharmony_ci { USB_DEVICE(0x1044, 0x800b) }, 88262306a36Sopenharmony_ci { USB_DEVICE(0x1044, 0x800d) }, 88362306a36Sopenharmony_ci /* Hawking */ 88462306a36Sopenharmony_ci { USB_DEVICE(0x0e66, 0x0001) }, 88562306a36Sopenharmony_ci { USB_DEVICE(0x0e66, 0x0003) }, 88662306a36Sopenharmony_ci { USB_DEVICE(0x0e66, 0x0009) }, 88762306a36Sopenharmony_ci { USB_DEVICE(0x0e66, 0x000b) }, 88862306a36Sopenharmony_ci { USB_DEVICE(0x0e66, 0x0013) }, 88962306a36Sopenharmony_ci { USB_DEVICE(0x0e66, 0x0017) }, 89062306a36Sopenharmony_ci { USB_DEVICE(0x0e66, 0x0018) }, 89162306a36Sopenharmony_ci /* I-O DATA */ 89262306a36Sopenharmony_ci { USB_DEVICE(0x04bb, 0x0945) }, 89362306a36Sopenharmony_ci { USB_DEVICE(0x04bb, 0x0947) }, 89462306a36Sopenharmony_ci { USB_DEVICE(0x04bb, 0x0948) }, 89562306a36Sopenharmony_ci /* Linksys */ 89662306a36Sopenharmony_ci { USB_DEVICE(0x13b1, 0x0031) }, 89762306a36Sopenharmony_ci { USB_DEVICE(0x1737, 0x0070) }, 89862306a36Sopenharmony_ci { USB_DEVICE(0x1737, 0x0071) }, 89962306a36Sopenharmony_ci { USB_DEVICE(0x1737, 0x0077) }, 90062306a36Sopenharmony_ci { USB_DEVICE(0x1737, 0x0078) }, 90162306a36Sopenharmony_ci /* Logitec */ 90262306a36Sopenharmony_ci { USB_DEVICE(0x0789, 0x0162) }, 90362306a36Sopenharmony_ci { USB_DEVICE(0x0789, 0x0163) }, 90462306a36Sopenharmony_ci { USB_DEVICE(0x0789, 0x0164) }, 90562306a36Sopenharmony_ci { USB_DEVICE(0x0789, 0x0166) }, 90662306a36Sopenharmony_ci /* Motorola */ 90762306a36Sopenharmony_ci { USB_DEVICE(0x100d, 0x9031) }, 90862306a36Sopenharmony_ci /* MSI */ 90962306a36Sopenharmony_ci { USB_DEVICE(0x0db0, 0x3820) }, 91062306a36Sopenharmony_ci { USB_DEVICE(0x0db0, 0x3821) }, 91162306a36Sopenharmony_ci { USB_DEVICE(0x0db0, 0x3822) }, 91262306a36Sopenharmony_ci { USB_DEVICE(0x0db0, 0x3870) }, 91362306a36Sopenharmony_ci { USB_DEVICE(0x0db0, 0x3871) }, 91462306a36Sopenharmony_ci { USB_DEVICE(0x0db0, 0x6899) }, 91562306a36Sopenharmony_ci { USB_DEVICE(0x0db0, 0x821a) }, 91662306a36Sopenharmony_ci { USB_DEVICE(0x0db0, 0x822a) }, 91762306a36Sopenharmony_ci { USB_DEVICE(0x0db0, 0x822b) }, 91862306a36Sopenharmony_ci { USB_DEVICE(0x0db0, 0x822c) }, 91962306a36Sopenharmony_ci { USB_DEVICE(0x0db0, 0x870a) }, 92062306a36Sopenharmony_ci { USB_DEVICE(0x0db0, 0x871a) }, 92162306a36Sopenharmony_ci { USB_DEVICE(0x0db0, 0x871b) }, 92262306a36Sopenharmony_ci { USB_DEVICE(0x0db0, 0x871c) }, 92362306a36Sopenharmony_ci { USB_DEVICE(0x0db0, 0x899a) }, 92462306a36Sopenharmony_ci /* Ovislink */ 92562306a36Sopenharmony_ci { USB_DEVICE(0x1b75, 0x3070) }, 92662306a36Sopenharmony_ci { USB_DEVICE(0x1b75, 0x3071) }, 92762306a36Sopenharmony_ci { USB_DEVICE(0x1b75, 0x3072) }, 92862306a36Sopenharmony_ci { USB_DEVICE(0x1b75, 0xa200) }, 92962306a36Sopenharmony_ci /* Para */ 93062306a36Sopenharmony_ci { USB_DEVICE(0x20b8, 0x8888) }, 93162306a36Sopenharmony_ci /* Pegatron */ 93262306a36Sopenharmony_ci { USB_DEVICE(0x1d4d, 0x0002) }, 93362306a36Sopenharmony_ci { USB_DEVICE(0x1d4d, 0x000c) }, 93462306a36Sopenharmony_ci { USB_DEVICE(0x1d4d, 0x000e) }, 93562306a36Sopenharmony_ci { USB_DEVICE(0x1d4d, 0x0011) }, 93662306a36Sopenharmony_ci /* Philips */ 93762306a36Sopenharmony_ci { USB_DEVICE(0x0471, 0x200f) }, 93862306a36Sopenharmony_ci /* Planex */ 93962306a36Sopenharmony_ci { USB_DEVICE(0x2019, 0x5201) }, 94062306a36Sopenharmony_ci { USB_DEVICE(0x2019, 0xab25) }, 94162306a36Sopenharmony_ci { USB_DEVICE(0x2019, 0xed06) }, 94262306a36Sopenharmony_ci /* Quanta */ 94362306a36Sopenharmony_ci { USB_DEVICE(0x1a32, 0x0304) }, 94462306a36Sopenharmony_ci /* Ralink */ 94562306a36Sopenharmony_ci { USB_DEVICE(0x148f, 0x2070) }, 94662306a36Sopenharmony_ci { USB_DEVICE(0x148f, 0x2770) }, 94762306a36Sopenharmony_ci { USB_DEVICE(0x148f, 0x2870) }, 94862306a36Sopenharmony_ci { USB_DEVICE(0x148f, 0x3070) }, 94962306a36Sopenharmony_ci { USB_DEVICE(0x148f, 0x3071) }, 95062306a36Sopenharmony_ci { USB_DEVICE(0x148f, 0x3072) }, 95162306a36Sopenharmony_ci /* Samsung */ 95262306a36Sopenharmony_ci { USB_DEVICE(0x04e8, 0x2018) }, 95362306a36Sopenharmony_ci /* Siemens */ 95462306a36Sopenharmony_ci { USB_DEVICE(0x129b, 0x1828) }, 95562306a36Sopenharmony_ci /* Sitecom */ 95662306a36Sopenharmony_ci { USB_DEVICE(0x0df6, 0x0017) }, 95762306a36Sopenharmony_ci { USB_DEVICE(0x0df6, 0x002b) }, 95862306a36Sopenharmony_ci { USB_DEVICE(0x0df6, 0x002c) }, 95962306a36Sopenharmony_ci { USB_DEVICE(0x0df6, 0x002d) }, 96062306a36Sopenharmony_ci { USB_DEVICE(0x0df6, 0x0039) }, 96162306a36Sopenharmony_ci { USB_DEVICE(0x0df6, 0x003b) }, 96262306a36Sopenharmony_ci { USB_DEVICE(0x0df6, 0x003d) }, 96362306a36Sopenharmony_ci { USB_DEVICE(0x0df6, 0x003e) }, 96462306a36Sopenharmony_ci { USB_DEVICE(0x0df6, 0x003f) }, 96562306a36Sopenharmony_ci { USB_DEVICE(0x0df6, 0x0040) }, 96662306a36Sopenharmony_ci { USB_DEVICE(0x0df6, 0x0042) }, 96762306a36Sopenharmony_ci { USB_DEVICE(0x0df6, 0x0047) }, 96862306a36Sopenharmony_ci { USB_DEVICE(0x0df6, 0x0048) }, 96962306a36Sopenharmony_ci { USB_DEVICE(0x0df6, 0x0051) }, 97062306a36Sopenharmony_ci { USB_DEVICE(0x0df6, 0x005f) }, 97162306a36Sopenharmony_ci { USB_DEVICE(0x0df6, 0x0060) }, 97262306a36Sopenharmony_ci /* SMC */ 97362306a36Sopenharmony_ci { USB_DEVICE(0x083a, 0x6618) }, 97462306a36Sopenharmony_ci { USB_DEVICE(0x083a, 0x7511) }, 97562306a36Sopenharmony_ci { USB_DEVICE(0x083a, 0x7512) }, 97662306a36Sopenharmony_ci { USB_DEVICE(0x083a, 0x7522) }, 97762306a36Sopenharmony_ci { USB_DEVICE(0x083a, 0x8522) }, 97862306a36Sopenharmony_ci { USB_DEVICE(0x083a, 0xa618) }, 97962306a36Sopenharmony_ci { USB_DEVICE(0x083a, 0xa701) }, 98062306a36Sopenharmony_ci { USB_DEVICE(0x083a, 0xa702) }, 98162306a36Sopenharmony_ci { USB_DEVICE(0x083a, 0xa703) }, 98262306a36Sopenharmony_ci { USB_DEVICE(0x083a, 0xb522) }, 98362306a36Sopenharmony_ci /* Sparklan */ 98462306a36Sopenharmony_ci { USB_DEVICE(0x15a9, 0x0006) }, 98562306a36Sopenharmony_ci /* Sweex */ 98662306a36Sopenharmony_ci { USB_DEVICE(0x177f, 0x0153) }, 98762306a36Sopenharmony_ci { USB_DEVICE(0x177f, 0x0164) }, 98862306a36Sopenharmony_ci { USB_DEVICE(0x177f, 0x0302) }, 98962306a36Sopenharmony_ci { USB_DEVICE(0x177f, 0x0313) }, 99062306a36Sopenharmony_ci { USB_DEVICE(0x177f, 0x0323) }, 99162306a36Sopenharmony_ci { USB_DEVICE(0x177f, 0x0324) }, 99262306a36Sopenharmony_ci { USB_DEVICE(0x177f, 0x1163) }, 99362306a36Sopenharmony_ci /* U-Media */ 99462306a36Sopenharmony_ci { USB_DEVICE(0x157e, 0x300e) }, 99562306a36Sopenharmony_ci { USB_DEVICE(0x157e, 0x3013) }, 99662306a36Sopenharmony_ci /* ZCOM */ 99762306a36Sopenharmony_ci { USB_DEVICE(0x0cde, 0x0022) }, 99862306a36Sopenharmony_ci { USB_DEVICE(0x0cde, 0x0025) }, 99962306a36Sopenharmony_ci /* Zinwell */ 100062306a36Sopenharmony_ci { USB_DEVICE(0x5a57, 0x0280) }, 100162306a36Sopenharmony_ci { USB_DEVICE(0x5a57, 0x0282) }, 100262306a36Sopenharmony_ci { USB_DEVICE(0x5a57, 0x0283) }, 100362306a36Sopenharmony_ci { USB_DEVICE(0x5a57, 0x5257) }, 100462306a36Sopenharmony_ci /* Zyxel */ 100562306a36Sopenharmony_ci { USB_DEVICE(0x0586, 0x3416) }, 100662306a36Sopenharmony_ci { USB_DEVICE(0x0586, 0x3418) }, 100762306a36Sopenharmony_ci { USB_DEVICE(0x0586, 0x341a) }, 100862306a36Sopenharmony_ci { USB_DEVICE(0x0586, 0x341e) }, 100962306a36Sopenharmony_ci { USB_DEVICE(0x0586, 0x343e) }, 101062306a36Sopenharmony_ci#ifdef CONFIG_RT2800USB_RT33XX 101162306a36Sopenharmony_ci /* Belkin */ 101262306a36Sopenharmony_ci { USB_DEVICE(0x050d, 0x945b) }, 101362306a36Sopenharmony_ci /* D-Link */ 101462306a36Sopenharmony_ci { USB_DEVICE(0x2001, 0x3c17) }, 101562306a36Sopenharmony_ci /* Panasonic */ 101662306a36Sopenharmony_ci { USB_DEVICE(0x083a, 0xb511) }, 101762306a36Sopenharmony_ci /* Accton/Arcadyan/Epson */ 101862306a36Sopenharmony_ci { USB_DEVICE(0x083a, 0xb512) }, 101962306a36Sopenharmony_ci /* Philips */ 102062306a36Sopenharmony_ci { USB_DEVICE(0x0471, 0x20dd) }, 102162306a36Sopenharmony_ci /* Ralink */ 102262306a36Sopenharmony_ci { USB_DEVICE(0x148f, 0x3370) }, 102362306a36Sopenharmony_ci { USB_DEVICE(0x148f, 0x8070) }, 102462306a36Sopenharmony_ci /* Sitecom */ 102562306a36Sopenharmony_ci { USB_DEVICE(0x0df6, 0x0050) }, 102662306a36Sopenharmony_ci /* Sweex */ 102762306a36Sopenharmony_ci { USB_DEVICE(0x177f, 0x0163) }, 102862306a36Sopenharmony_ci { USB_DEVICE(0x177f, 0x0165) }, 102962306a36Sopenharmony_ci#endif 103062306a36Sopenharmony_ci#ifdef CONFIG_RT2800USB_RT35XX 103162306a36Sopenharmony_ci /* Allwin */ 103262306a36Sopenharmony_ci { USB_DEVICE(0x8516, 0x3572) }, 103362306a36Sopenharmony_ci /* Askey */ 103462306a36Sopenharmony_ci { USB_DEVICE(0x1690, 0x0744) }, 103562306a36Sopenharmony_ci { USB_DEVICE(0x1690, 0x0761) }, 103662306a36Sopenharmony_ci { USB_DEVICE(0x1690, 0x0764) }, 103762306a36Sopenharmony_ci /* ASUS */ 103862306a36Sopenharmony_ci { USB_DEVICE(0x0b05, 0x179d) }, 103962306a36Sopenharmony_ci /* Cisco */ 104062306a36Sopenharmony_ci { USB_DEVICE(0x167b, 0x4001) }, 104162306a36Sopenharmony_ci /* EnGenius */ 104262306a36Sopenharmony_ci { USB_DEVICE(0x1740, 0x9801) }, 104362306a36Sopenharmony_ci /* I-O DATA */ 104462306a36Sopenharmony_ci { USB_DEVICE(0x04bb, 0x0944) }, 104562306a36Sopenharmony_ci /* Linksys */ 104662306a36Sopenharmony_ci { USB_DEVICE(0x13b1, 0x002f) }, 104762306a36Sopenharmony_ci { USB_DEVICE(0x1737, 0x0079) }, 104862306a36Sopenharmony_ci /* Logitec */ 104962306a36Sopenharmony_ci { USB_DEVICE(0x0789, 0x0170) }, 105062306a36Sopenharmony_ci /* Ralink */ 105162306a36Sopenharmony_ci { USB_DEVICE(0x148f, 0x3572) }, 105262306a36Sopenharmony_ci /* Sitecom */ 105362306a36Sopenharmony_ci { USB_DEVICE(0x0df6, 0x0041) }, 105462306a36Sopenharmony_ci { USB_DEVICE(0x0df6, 0x0062) }, 105562306a36Sopenharmony_ci { USB_DEVICE(0x0df6, 0x0065) }, 105662306a36Sopenharmony_ci { USB_DEVICE(0x0df6, 0x0066) }, 105762306a36Sopenharmony_ci { USB_DEVICE(0x0df6, 0x0068) }, 105862306a36Sopenharmony_ci /* Toshiba */ 105962306a36Sopenharmony_ci { USB_DEVICE(0x0930, 0x0a07) }, 106062306a36Sopenharmony_ci /* Zinwell */ 106162306a36Sopenharmony_ci { USB_DEVICE(0x5a57, 0x0284) }, 106262306a36Sopenharmony_ci#endif 106362306a36Sopenharmony_ci#ifdef CONFIG_RT2800USB_RT3573 106462306a36Sopenharmony_ci /* AirLive */ 106562306a36Sopenharmony_ci { USB_DEVICE(0x1b75, 0x7733) }, 106662306a36Sopenharmony_ci /* ASUS */ 106762306a36Sopenharmony_ci { USB_DEVICE(0x0b05, 0x17bc) }, 106862306a36Sopenharmony_ci { USB_DEVICE(0x0b05, 0x17ad) }, 106962306a36Sopenharmony_ci /* Belkin */ 107062306a36Sopenharmony_ci { USB_DEVICE(0x050d, 0x1103) }, 107162306a36Sopenharmony_ci /* Cameo */ 107262306a36Sopenharmony_ci { USB_DEVICE(0x148f, 0xf301) }, 107362306a36Sopenharmony_ci /* D-Link */ 107462306a36Sopenharmony_ci { USB_DEVICE(0x2001, 0x3c1f) }, 107562306a36Sopenharmony_ci /* Edimax */ 107662306a36Sopenharmony_ci { USB_DEVICE(0x7392, 0x7733) }, 107762306a36Sopenharmony_ci /* Hawking */ 107862306a36Sopenharmony_ci { USB_DEVICE(0x0e66, 0x0020) }, 107962306a36Sopenharmony_ci { USB_DEVICE(0x0e66, 0x0021) }, 108062306a36Sopenharmony_ci /* I-O DATA */ 108162306a36Sopenharmony_ci { USB_DEVICE(0x04bb, 0x094e) }, 108262306a36Sopenharmony_ci /* Linksys */ 108362306a36Sopenharmony_ci { USB_DEVICE(0x13b1, 0x003b) }, 108462306a36Sopenharmony_ci /* Logitec */ 108562306a36Sopenharmony_ci { USB_DEVICE(0x0789, 0x016b) }, 108662306a36Sopenharmony_ci /* NETGEAR */ 108762306a36Sopenharmony_ci { USB_DEVICE(0x0846, 0x9012) }, 108862306a36Sopenharmony_ci { USB_DEVICE(0x0846, 0x9013) }, 108962306a36Sopenharmony_ci { USB_DEVICE(0x0846, 0x9019) }, 109062306a36Sopenharmony_ci /* Planex */ 109162306a36Sopenharmony_ci { USB_DEVICE(0x2019, 0xed14) }, 109262306a36Sopenharmony_ci { USB_DEVICE(0x2019, 0xed19) }, 109362306a36Sopenharmony_ci /* Ralink */ 109462306a36Sopenharmony_ci { USB_DEVICE(0x148f, 0x3573) }, 109562306a36Sopenharmony_ci /* Sitecom */ 109662306a36Sopenharmony_ci { USB_DEVICE(0x0df6, 0x0067) }, 109762306a36Sopenharmony_ci { USB_DEVICE(0x0df6, 0x006a) }, 109862306a36Sopenharmony_ci { USB_DEVICE(0x0df6, 0x006e) }, 109962306a36Sopenharmony_ci /* ZyXEL */ 110062306a36Sopenharmony_ci { USB_DEVICE(0x0586, 0x3421) }, 110162306a36Sopenharmony_ci#endif 110262306a36Sopenharmony_ci#ifdef CONFIG_RT2800USB_RT53XX 110362306a36Sopenharmony_ci /* Arcadyan */ 110462306a36Sopenharmony_ci { USB_DEVICE(0x043e, 0x7a12) }, 110562306a36Sopenharmony_ci /* ASUS */ 110662306a36Sopenharmony_ci { USB_DEVICE(0x0b05, 0x17e8) }, 110762306a36Sopenharmony_ci /* Azurewave */ 110862306a36Sopenharmony_ci { USB_DEVICE(0x13d3, 0x3329) }, 110962306a36Sopenharmony_ci { USB_DEVICE(0x13d3, 0x3365) }, 111062306a36Sopenharmony_ci /* D-Link */ 111162306a36Sopenharmony_ci { USB_DEVICE(0x2001, 0x3c15) }, 111262306a36Sopenharmony_ci { USB_DEVICE(0x2001, 0x3c19) }, 111362306a36Sopenharmony_ci { USB_DEVICE(0x2001, 0x3c1c) }, 111462306a36Sopenharmony_ci { USB_DEVICE(0x2001, 0x3c1d) }, 111562306a36Sopenharmony_ci { USB_DEVICE(0x2001, 0x3c1e) }, 111662306a36Sopenharmony_ci { USB_DEVICE(0x2001, 0x3c20) }, 111762306a36Sopenharmony_ci { USB_DEVICE(0x2001, 0x3c22) }, 111862306a36Sopenharmony_ci { USB_DEVICE(0x2001, 0x3c23) }, 111962306a36Sopenharmony_ci /* LG innotek */ 112062306a36Sopenharmony_ci { USB_DEVICE(0x043e, 0x7a22) }, 112162306a36Sopenharmony_ci { USB_DEVICE(0x043e, 0x7a42) }, 112262306a36Sopenharmony_ci /* Panasonic */ 112362306a36Sopenharmony_ci { USB_DEVICE(0x04da, 0x1801) }, 112462306a36Sopenharmony_ci { USB_DEVICE(0x04da, 0x1800) }, 112562306a36Sopenharmony_ci { USB_DEVICE(0x04da, 0x23f6) }, 112662306a36Sopenharmony_ci /* Philips */ 112762306a36Sopenharmony_ci { USB_DEVICE(0x0471, 0x2104) }, 112862306a36Sopenharmony_ci { USB_DEVICE(0x0471, 0x2126) }, 112962306a36Sopenharmony_ci { USB_DEVICE(0x0471, 0x2180) }, 113062306a36Sopenharmony_ci { USB_DEVICE(0x0471, 0x2181) }, 113162306a36Sopenharmony_ci { USB_DEVICE(0x0471, 0x2182) }, 113262306a36Sopenharmony_ci /* Ralink */ 113362306a36Sopenharmony_ci { USB_DEVICE(0x148f, 0x5370) }, 113462306a36Sopenharmony_ci { USB_DEVICE(0x148f, 0x5372) }, 113562306a36Sopenharmony_ci#endif 113662306a36Sopenharmony_ci#ifdef CONFIG_RT2800USB_RT55XX 113762306a36Sopenharmony_ci /* Arcadyan */ 113862306a36Sopenharmony_ci { USB_DEVICE(0x043e, 0x7a32) }, 113962306a36Sopenharmony_ci /* AVM GmbH */ 114062306a36Sopenharmony_ci { USB_DEVICE(0x057c, 0x8501) }, 114162306a36Sopenharmony_ci /* Buffalo */ 114262306a36Sopenharmony_ci { USB_DEVICE(0x0411, 0x0241) }, 114362306a36Sopenharmony_ci { USB_DEVICE(0x0411, 0x0253) }, 114462306a36Sopenharmony_ci /* D-Link */ 114562306a36Sopenharmony_ci { USB_DEVICE(0x2001, 0x3c1a) }, 114662306a36Sopenharmony_ci { USB_DEVICE(0x2001, 0x3c21) }, 114762306a36Sopenharmony_ci /* Proware */ 114862306a36Sopenharmony_ci { USB_DEVICE(0x043e, 0x7a13) }, 114962306a36Sopenharmony_ci /* Ralink */ 115062306a36Sopenharmony_ci { USB_DEVICE(0x148f, 0x5572) }, 115162306a36Sopenharmony_ci /* TRENDnet */ 115262306a36Sopenharmony_ci { USB_DEVICE(0x20f4, 0x724a) }, 115362306a36Sopenharmony_ci#endif 115462306a36Sopenharmony_ci#ifdef CONFIG_RT2800USB_UNKNOWN 115562306a36Sopenharmony_ci /* 115662306a36Sopenharmony_ci * Unclear what kind of devices these are (they aren't supported by the 115762306a36Sopenharmony_ci * vendor linux driver). 115862306a36Sopenharmony_ci */ 115962306a36Sopenharmony_ci /* Abocom */ 116062306a36Sopenharmony_ci { USB_DEVICE(0x07b8, 0x3073) }, 116162306a36Sopenharmony_ci { USB_DEVICE(0x07b8, 0x3074) }, 116262306a36Sopenharmony_ci /* Alpha Networks */ 116362306a36Sopenharmony_ci { USB_DEVICE(0x14b2, 0x3c08) }, 116462306a36Sopenharmony_ci { USB_DEVICE(0x14b2, 0x3c11) }, 116562306a36Sopenharmony_ci /* Amigo */ 116662306a36Sopenharmony_ci { USB_DEVICE(0x0e0b, 0x9031) }, 116762306a36Sopenharmony_ci { USB_DEVICE(0x0e0b, 0x9041) }, 116862306a36Sopenharmony_ci /* ASUS */ 116962306a36Sopenharmony_ci { USB_DEVICE(0x0b05, 0x166a) }, 117062306a36Sopenharmony_ci { USB_DEVICE(0x0b05, 0x1760) }, 117162306a36Sopenharmony_ci { USB_DEVICE(0x0b05, 0x1761) }, 117262306a36Sopenharmony_ci { USB_DEVICE(0x0b05, 0x1790) }, 117362306a36Sopenharmony_ci { USB_DEVICE(0x0b05, 0x17a7) }, 117462306a36Sopenharmony_ci /* AzureWave */ 117562306a36Sopenharmony_ci { USB_DEVICE(0x13d3, 0x3262) }, 117662306a36Sopenharmony_ci { USB_DEVICE(0x13d3, 0x3284) }, 117762306a36Sopenharmony_ci { USB_DEVICE(0x13d3, 0x3322) }, 117862306a36Sopenharmony_ci { USB_DEVICE(0x13d3, 0x3340) }, 117962306a36Sopenharmony_ci { USB_DEVICE(0x13d3, 0x3399) }, 118062306a36Sopenharmony_ci { USB_DEVICE(0x13d3, 0x3400) }, 118162306a36Sopenharmony_ci { USB_DEVICE(0x13d3, 0x3401) }, 118262306a36Sopenharmony_ci /* Belkin */ 118362306a36Sopenharmony_ci { USB_DEVICE(0x050d, 0x1003) }, 118462306a36Sopenharmony_ci /* Buffalo */ 118562306a36Sopenharmony_ci { USB_DEVICE(0x0411, 0x012e) }, 118662306a36Sopenharmony_ci { USB_DEVICE(0x0411, 0x0148) }, 118762306a36Sopenharmony_ci { USB_DEVICE(0x0411, 0x0150) }, 118862306a36Sopenharmony_ci /* Corega */ 118962306a36Sopenharmony_ci { USB_DEVICE(0x07aa, 0x0041) }, 119062306a36Sopenharmony_ci { USB_DEVICE(0x07aa, 0x0042) }, 119162306a36Sopenharmony_ci { USB_DEVICE(0x18c5, 0x0008) }, 119262306a36Sopenharmony_ci /* D-Link */ 119362306a36Sopenharmony_ci { USB_DEVICE(0x07d1, 0x3c0b) }, 119462306a36Sopenharmony_ci /* Encore */ 119562306a36Sopenharmony_ci { USB_DEVICE(0x203d, 0x14a1) }, 119662306a36Sopenharmony_ci /* EnGenius */ 119762306a36Sopenharmony_ci { USB_DEVICE(0x1740, 0x0600) }, 119862306a36Sopenharmony_ci { USB_DEVICE(0x1740, 0x0602) }, 119962306a36Sopenharmony_ci /* Gemtek */ 120062306a36Sopenharmony_ci { USB_DEVICE(0x15a9, 0x0010) }, 120162306a36Sopenharmony_ci /* Gigabyte */ 120262306a36Sopenharmony_ci { USB_DEVICE(0x1044, 0x800c) }, 120362306a36Sopenharmony_ci /* Hercules */ 120462306a36Sopenharmony_ci { USB_DEVICE(0x06f8, 0xe036) }, 120562306a36Sopenharmony_ci /* Huawei */ 120662306a36Sopenharmony_ci { USB_DEVICE(0x148f, 0xf101) }, 120762306a36Sopenharmony_ci /* I-O DATA */ 120862306a36Sopenharmony_ci { USB_DEVICE(0x04bb, 0x094b) }, 120962306a36Sopenharmony_ci /* LevelOne */ 121062306a36Sopenharmony_ci { USB_DEVICE(0x1740, 0x0605) }, 121162306a36Sopenharmony_ci { USB_DEVICE(0x1740, 0x0615) }, 121262306a36Sopenharmony_ci /* Logitec */ 121362306a36Sopenharmony_ci { USB_DEVICE(0x0789, 0x0168) }, 121462306a36Sopenharmony_ci { USB_DEVICE(0x0789, 0x0169) }, 121562306a36Sopenharmony_ci /* Motorola */ 121662306a36Sopenharmony_ci { USB_DEVICE(0x100d, 0x9032) }, 121762306a36Sopenharmony_ci /* Pegatron */ 121862306a36Sopenharmony_ci { USB_DEVICE(0x05a6, 0x0101) }, 121962306a36Sopenharmony_ci { USB_DEVICE(0x1d4d, 0x0010) }, 122062306a36Sopenharmony_ci /* Planex */ 122162306a36Sopenharmony_ci { USB_DEVICE(0x2019, 0xab24) }, 122262306a36Sopenharmony_ci { USB_DEVICE(0x2019, 0xab29) }, 122362306a36Sopenharmony_ci /* Qcom */ 122462306a36Sopenharmony_ci { USB_DEVICE(0x18e8, 0x6259) }, 122562306a36Sopenharmony_ci /* RadioShack */ 122662306a36Sopenharmony_ci { USB_DEVICE(0x08b9, 0x1197) }, 122762306a36Sopenharmony_ci /* Sitecom */ 122862306a36Sopenharmony_ci { USB_DEVICE(0x0df6, 0x003c) }, 122962306a36Sopenharmony_ci { USB_DEVICE(0x0df6, 0x004a) }, 123062306a36Sopenharmony_ci { USB_DEVICE(0x0df6, 0x004d) }, 123162306a36Sopenharmony_ci { USB_DEVICE(0x0df6, 0x0053) }, 123262306a36Sopenharmony_ci { USB_DEVICE(0x0df6, 0x0069) }, 123362306a36Sopenharmony_ci { USB_DEVICE(0x0df6, 0x006f) }, 123462306a36Sopenharmony_ci { USB_DEVICE(0x0df6, 0x0078) }, 123562306a36Sopenharmony_ci /* SMC */ 123662306a36Sopenharmony_ci { USB_DEVICE(0x083a, 0xa512) }, 123762306a36Sopenharmony_ci { USB_DEVICE(0x083a, 0xc522) }, 123862306a36Sopenharmony_ci { USB_DEVICE(0x083a, 0xd522) }, 123962306a36Sopenharmony_ci { USB_DEVICE(0x083a, 0xf511) }, 124062306a36Sopenharmony_ci /* Sweex */ 124162306a36Sopenharmony_ci { USB_DEVICE(0x177f, 0x0254) }, 124262306a36Sopenharmony_ci /* TP-LINK */ 124362306a36Sopenharmony_ci { USB_DEVICE(0xf201, 0x5370) }, 124462306a36Sopenharmony_ci#endif 124562306a36Sopenharmony_ci { 0, } 124662306a36Sopenharmony_ci}; 124762306a36Sopenharmony_ci 124862306a36Sopenharmony_ciMODULE_AUTHOR(DRV_PROJECT); 124962306a36Sopenharmony_ciMODULE_VERSION(DRV_VERSION); 125062306a36Sopenharmony_ciMODULE_DESCRIPTION("Ralink RT2800 USB Wireless LAN driver."); 125162306a36Sopenharmony_ciMODULE_DEVICE_TABLE(usb, rt2800usb_device_table); 125262306a36Sopenharmony_ciMODULE_FIRMWARE(FIRMWARE_RT2870); 125362306a36Sopenharmony_ciMODULE_LICENSE("GPL"); 125462306a36Sopenharmony_ci 125562306a36Sopenharmony_cistatic int rt2800usb_probe(struct usb_interface *usb_intf, 125662306a36Sopenharmony_ci const struct usb_device_id *id) 125762306a36Sopenharmony_ci{ 125862306a36Sopenharmony_ci return rt2x00usb_probe(usb_intf, &rt2800usb_ops); 125962306a36Sopenharmony_ci} 126062306a36Sopenharmony_ci 126162306a36Sopenharmony_cistatic struct usb_driver rt2800usb_driver = { 126262306a36Sopenharmony_ci .name = KBUILD_MODNAME, 126362306a36Sopenharmony_ci .id_table = rt2800usb_device_table, 126462306a36Sopenharmony_ci .probe = rt2800usb_probe, 126562306a36Sopenharmony_ci .disconnect = rt2x00usb_disconnect, 126662306a36Sopenharmony_ci .suspend = rt2x00usb_suspend, 126762306a36Sopenharmony_ci .resume = rt2x00usb_resume, 126862306a36Sopenharmony_ci .reset_resume = rt2x00usb_resume, 126962306a36Sopenharmony_ci .disable_hub_initiated_lpm = 1, 127062306a36Sopenharmony_ci}; 127162306a36Sopenharmony_ci 127262306a36Sopenharmony_cimodule_usb_driver(rt2800usb_driver); 1273