2009-04-26 15:47:48 +02:00
/*
2010-08-06 20:47:57 +02:00
Copyright ( C ) 2010 Willow Garage < http : //www.willowgarage.com>
Copyright ( C ) 2009 - 2010 Ivo van Doorn < IvDoorn @ gmail . com >
2009-11-08 16:39:55 +01:00
Copyright ( C ) 2009 Mattias Nissler < mattias . nissler @ gmx . de >
Copyright ( C ) 2009 Felix Fietkau < nbd @ openwrt . org >
Copyright ( C ) 2009 Xose Vazquez Perez < xose . vazquez @ gmail . com >
Copyright ( C ) 2009 Axel Kollhofer < rain_maker @ root - forum . org >
2009-04-26 15:47:48 +02:00
< 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 : rt2800usb
Abstract : rt2800usb device specific routines .
Supported chipsets : RT2800U .
*/
# include <linux/delay.h>
# include <linux/etherdevice.h>
# include <linux/init.h>
# include <linux/kernel.h>
# include <linux/module.h>
# include <linux/usb.h>
# include "rt2x00.h"
# include "rt2x00usb.h"
2009-11-04 18:35:32 +01:00
# include "rt2800lib.h"
2009-11-04 18:35:54 +01:00
# include "rt2800.h"
2009-04-26 15:47:48 +02:00
# include "rt2800usb.h"
/*
* Allow hardware encryption to be disabled .
*/
2011-12-19 14:08:01 +00:00
static bool modparam_nohwcrypt ;
2009-04-26 15:47:48 +02:00
module_param_named ( nohwcrypt , modparam_nohwcrypt , bool , S_IRUGO ) ;
MODULE_PARM_DESC ( nohwcrypt , " Disable hardware encryption. " ) ;
2010-12-13 12:34:22 +01:00
/*
* Queue handlers .
*/
static void rt2800usb_start_queue ( struct data_queue * queue )
{
struct rt2x00_dev * rt2x00dev = queue - > rt2x00dev ;
u32 reg ;
switch ( queue - > qid ) {
case QID_RX :
2011-04-18 15:34:22 +02:00
rt2x00usb_register_read ( rt2x00dev , MAC_SYS_CTRL , & reg ) ;
2010-12-13 12:34:22 +01:00
rt2x00_set_field32 ( & reg , MAC_SYS_CTRL_ENABLE_RX , 1 ) ;
2011-04-18 15:34:22 +02:00
rt2x00usb_register_write ( rt2x00dev , MAC_SYS_CTRL , reg ) ;
2010-12-13 12:34:22 +01:00
break ;
case QID_BEACON :
2011-04-18 15:34:22 +02:00
rt2x00usb_register_read ( rt2x00dev , BCN_TIME_CFG , & reg ) ;
2010-12-13 12:34:22 +01:00
rt2x00_set_field32 ( & reg , BCN_TIME_CFG_TSF_TICKING , 1 ) ;
rt2x00_set_field32 ( & reg , BCN_TIME_CFG_TBTT_ENABLE , 1 ) ;
rt2x00_set_field32 ( & reg , BCN_TIME_CFG_BEACON_GEN , 1 ) ;
2011-04-18 15:34:22 +02:00
rt2x00usb_register_write ( rt2x00dev , BCN_TIME_CFG , reg ) ;
2010-12-13 12:34:22 +01:00
break ;
default :
break ;
}
}
static void rt2800usb_stop_queue ( struct data_queue * queue )
{
struct rt2x00_dev * rt2x00dev = queue - > rt2x00dev ;
u32 reg ;
switch ( queue - > qid ) {
case QID_RX :
2011-04-18 15:34:22 +02:00
rt2x00usb_register_read ( rt2x00dev , MAC_SYS_CTRL , & reg ) ;
2010-12-13 12:34:22 +01:00
rt2x00_set_field32 ( & reg , MAC_SYS_CTRL_ENABLE_RX , 0 ) ;
2011-04-18 15:34:22 +02:00
rt2x00usb_register_write ( rt2x00dev , MAC_SYS_CTRL , reg ) ;
2010-12-13 12:34:22 +01:00
break ;
case QID_BEACON :
2011-04-18 15:34:22 +02:00
rt2x00usb_register_read ( rt2x00dev , BCN_TIME_CFG , & reg ) ;
2010-12-13 12:34:22 +01:00
rt2x00_set_field32 ( & reg , BCN_TIME_CFG_TSF_TICKING , 0 ) ;
rt2x00_set_field32 ( & reg , BCN_TIME_CFG_TBTT_ENABLE , 0 ) ;
rt2x00_set_field32 ( & reg , BCN_TIME_CFG_BEACON_GEN , 0 ) ;
2011-04-18 15:34:22 +02:00
rt2x00usb_register_write ( rt2x00dev , BCN_TIME_CFG , reg ) ;
2010-12-13 12:34:22 +01:00
break ;
default :
break ;
}
}
2011-04-18 15:30:36 +02:00
/*
* test if there is an entry in any TX queue for which DMA is done
* but the TX status has not been returned yet
*/
static bool rt2800usb_txstatus_pending ( struct rt2x00_dev * rt2x00dev )
{
struct data_queue * queue ;
tx_queue_for_each ( rt2x00dev , queue ) {
if ( rt2x00queue_get_entry ( queue , Q_INDEX_DMA_DONE ) ! =
rt2x00queue_get_entry ( queue , Q_INDEX_DONE ) )
return true ;
}
return false ;
}
2011-04-30 17:14:23 +02:00
static bool rt2800usb_tx_sta_fifo_read_completed ( struct rt2x00_dev * rt2x00dev ,
2011-04-18 15:29:12 +02:00
int urb_status , u32 tx_status )
{
if ( urb_status ) {
WARNING ( rt2x00dev , " rt2x00usb_register_read_async failed: %d \n " , urb_status ) ;
2011-04-30 17:14:23 +02:00
return false ;
2011-04-18 15:29:12 +02:00
}
/* try to read all TX_STA_FIFO entries before scheduling txdone_work */
if ( rt2x00_get_field32 ( tx_status , TX_STA_FIFO_VALID ) ) {
if ( ! kfifo_put ( & rt2x00dev - > txstatus_fifo , & tx_status ) ) {
WARNING ( rt2x00dev , " TX status FIFO overrun, "
" drop tx status report. \n " ) ;
queue_work ( rt2x00dev - > workqueue , & rt2x00dev - > txdone_work ) ;
} else
2011-04-30 17:14:23 +02:00
return true ;
2011-04-18 15:30:36 +02:00
} else if ( ! kfifo_is_empty ( & rt2x00dev - > txstatus_fifo ) ) {
2011-04-18 15:29:12 +02:00
queue_work ( rt2x00dev - > workqueue , & rt2x00dev - > txdone_work ) ;
2011-04-18 15:30:36 +02:00
} else if ( rt2800usb_txstatus_pending ( rt2x00dev ) ) {
2011-04-30 17:13:46 +02:00
mod_timer ( & rt2x00dev - > txstatus_timer , jiffies + msecs_to_jiffies ( 2 ) ) ;
2011-04-18 15:30:36 +02:00
}
2011-04-30 17:14:23 +02:00
return false ;
2011-04-18 15:29:12 +02:00
}
static void rt2800usb_tx_dma_done ( struct queue_entry * entry )
{
struct rt2x00_dev * rt2x00dev = entry - > queue - > rt2x00dev ;
rt2x00usb_register_read_async ( rt2x00dev , TX_STA_FIFO ,
rt2800usb_tx_sta_fifo_read_completed ) ;
}
2011-04-18 15:30:36 +02:00
static void rt2800usb_tx_sta_fifo_timeout ( unsigned long data )
{
struct rt2x00_dev * rt2x00dev = ( struct rt2x00_dev * ) data ;
rt2x00usb_register_read_async ( rt2x00dev , TX_STA_FIFO ,
rt2800usb_tx_sta_fifo_read_completed ) ;
}
2009-04-26 15:47:48 +02:00
/*
* Firmware functions
*/
static char * rt2800usb_get_firmware_name ( struct rt2x00_dev * rt2x00dev )
{
return FIRMWARE_RT2870 ;
}
2010-07-11 12:30:37 +02:00
static int rt2800usb_write_firmware ( struct rt2x00_dev * rt2x00dev ,
2009-04-26 15:47:48 +02:00
const u8 * data , const size_t len )
{
int status ;
u32 offset ;
u32 length ;
/*
* Check which section of the firmware we need .
*/
2010-02-13 20:55:49 +01:00
if ( rt2x00_rt ( rt2x00dev , RT2860 ) | |
rt2x00_rt ( rt2x00dev , RT2872 ) | |
rt2x00_rt ( rt2x00dev , RT3070 ) ) {
2009-04-26 15:47:48 +02:00
offset = 0 ;
length = 4096 ;
} else {
offset = 4096 ;
length = 4096 ;
}
/*
* Write firmware to device .
*/
2011-04-18 15:34:22 +02:00
rt2x00usb_register_multiwrite ( rt2x00dev , FIRMWARE_IMAGE_BASE ,
data + offset , length ) ;
2009-04-26 15:47:48 +02:00
2011-04-18 15:34:22 +02:00
rt2x00usb_register_write ( rt2x00dev , H2M_MAILBOX_CID , ~ 0 ) ;
rt2x00usb_register_write ( rt2x00dev , H2M_MAILBOX_STATUS , ~ 0 ) ;
2009-04-26 15:47:48 +02:00
/*
* Send firmware request to device to load firmware ,
* we need to specify a long timeout time .
*/
status = rt2x00usb_vendor_request_sw ( rt2x00dev , USB_DEVICE_MODE ,
0 , USB_MODE_FIRMWARE ,
REGISTER_TIMEOUT_FIRMWARE ) ;
if ( status < 0 ) {
ERROR ( rt2x00dev , " Failed to write Firmware to device. \n " ) ;
return status ;
}
2009-04-28 20:14:58 +02:00
msleep ( 10 ) ;
2011-04-18 15:34:22 +02:00
rt2x00usb_register_write ( rt2x00dev , H2M_MAILBOX_CSR , 0 ) ;
2009-04-28 20:14:58 +02:00
2009-04-26 15:47:48 +02:00
return 0 ;
}
/*
* Device state switch handlers .
*/
2010-06-03 10:52:04 +02:00
static int rt2800usb_init_registers ( struct rt2x00_dev * rt2x00dev )
{
u32 reg ;
/*
* Wait until BBP and RF are ready .
*/
2010-08-30 21:13:08 +02:00
if ( rt2800_wait_csr_ready ( rt2x00dev ) )
2010-06-03 10:52:04 +02:00
return - EBUSY ;
2011-04-18 15:34:22 +02:00
rt2x00usb_register_read ( rt2x00dev , PBF_SYS_CTRL , & reg ) ;
rt2x00usb_register_write ( rt2x00dev , PBF_SYS_CTRL , reg & ~ 0x00002000 ) ;
2010-06-03 10:52:04 +02:00
2012-01-24 14:09:08 +01:00
reg = 0 ;
2010-06-03 10:52:04 +02:00
rt2x00_set_field32 ( & reg , MAC_SYS_CTRL_RESET_CSR , 1 ) ;
rt2x00_set_field32 ( & reg , MAC_SYS_CTRL_RESET_BBP , 1 ) ;
2011-04-18 15:34:22 +02:00
rt2x00usb_register_write ( rt2x00dev , MAC_SYS_CTRL , reg ) ;
2010-06-03 10:52:04 +02:00
2011-04-18 15:34:22 +02:00
rt2x00usb_register_write ( rt2x00dev , USB_DMA_CFG , 0x00000000 ) ;
2010-06-03 10:52:04 +02:00
rt2x00usb_vendor_request_sw ( rt2x00dev , USB_DEVICE_MODE , 0 ,
USB_MODE_RESET , REGISTER_TIMEOUT ) ;
2011-04-18 15:34:22 +02:00
rt2x00usb_register_write ( rt2x00dev , MAC_SYS_CTRL , 0x00000000 ) ;
2010-06-03 10:52:04 +02:00
return 0 ;
}
2009-04-26 15:47:48 +02:00
static int rt2800usb_enable_radio ( struct rt2x00_dev * rt2x00dev )
{
u32 reg ;
2010-08-23 19:55:22 +02:00
if ( unlikely ( rt2800_wait_wpdma_ready ( rt2x00dev ) ) )
2009-04-26 15:47:48 +02:00
return - EIO ;
2011-04-18 15:34:22 +02:00
rt2x00usb_register_read ( rt2x00dev , USB_DMA_CFG , & reg ) ;
2009-04-26 15:47:48 +02:00
rt2x00_set_field32 ( & reg , USB_DMA_CFG_PHY_CLEAR , 0 ) ;
2009-12-04 23:47:05 +01:00
rt2x00_set_field32 ( & reg , USB_DMA_CFG_RX_BULK_AGG_EN , 0 ) ;
2009-04-26 15:47:48 +02:00
rt2x00_set_field32 ( & reg , USB_DMA_CFG_RX_BULK_AGG_TIMEOUT , 128 ) ;
2009-04-28 20:14:58 +02:00
/*
* Total room for RX frames in kilobytes , PBF might still exceed
* this limit so reduce the number to prevent errors .
*/
rt2x00_set_field32 ( & reg , USB_DMA_CFG_RX_BULK_AGG_LIMIT ,
2010-11-04 20:37:22 +01:00
( ( rt2x00dev - > ops - > rx - > entry_num * DATA_FRAME_SIZE )
/ 1024 ) - 3 ) ;
2009-04-26 15:47:48 +02:00
rt2x00_set_field32 ( & reg , USB_DMA_CFG_RX_BULK_EN , 1 ) ;
rt2x00_set_field32 ( & reg , USB_DMA_CFG_TX_BULK_EN , 1 ) ;
2011-04-18 15:34:22 +02:00
rt2x00usb_register_write ( rt2x00dev , USB_DMA_CFG , reg ) ;
2009-04-26 15:47:48 +02:00
2010-08-23 19:55:22 +02:00
return rt2800_enable_radio ( rt2x00dev ) ;
2009-04-26 15:47:48 +02:00
}
static void rt2800usb_disable_radio ( struct rt2x00_dev * rt2x00dev )
{
2010-08-23 19:55:22 +02:00
rt2800_disable_radio ( rt2x00dev ) ;
2009-04-26 15:47:48 +02:00
rt2x00usb_disable_radio ( rt2x00dev ) ;
}
static int rt2800usb_set_state ( struct rt2x00_dev * rt2x00dev ,
enum dev_state state )
{
if ( state = = STATE_AWAKE )
2010-11-04 20:40:46 +01:00
rt2800_mcu_request ( rt2x00dev , MCU_WAKEUP , 0xff , 0 , 2 ) ;
2009-04-26 15:47:48 +02:00
else
2010-11-04 20:40:46 +01:00
rt2800_mcu_request ( rt2x00dev , MCU_SLEEP , 0xff , 0xff , 2 ) ;
2009-04-26 15:47:48 +02:00
return 0 ;
}
static int rt2800usb_set_device_state ( struct rt2x00_dev * rt2x00dev ,
enum dev_state state )
{
int retval = 0 ;
switch ( state ) {
case STATE_RADIO_ON :
/*
* Before the radio can be enabled , the device first has
* to be woken up . After that it needs a bit of time
2009-07-17 21:39:19 +02:00
* to be fully awake and then the radio can be enabled .
2009-04-26 15:47:48 +02:00
*/
rt2800usb_set_state ( rt2x00dev , STATE_AWAKE ) ;
msleep ( 1 ) ;
retval = rt2800usb_enable_radio ( rt2x00dev ) ;
break ;
case STATE_RADIO_OFF :
/*
2009-07-17 21:39:19 +02:00
* After the radio has been disabled , the device should
2009-04-26 15:47:48 +02:00
* be put to sleep for powersaving .
*/
rt2800usb_disable_radio ( rt2x00dev ) ;
rt2800usb_set_state ( rt2x00dev , STATE_SLEEP ) ;
break ;
case STATE_RADIO_IRQ_ON :
case STATE_RADIO_IRQ_OFF :
/* No support, but no error either */
break ;
case STATE_DEEP_SLEEP :
case STATE_SLEEP :
case STATE_STANDBY :
case STATE_AWAKE :
retval = rt2800usb_set_state ( rt2x00dev , state ) ;
break ;
default :
retval = - ENOTSUPP ;
break ;
}
if ( unlikely ( retval ) )
ERROR ( rt2x00dev , " Device failed to enter state %d (%d). \n " ,
state , retval ) ;
return retval ;
}
2010-11-06 15:49:01 +01:00
/*
* Watchdog handlers
*/
static void rt2800usb_watchdog ( struct rt2x00_dev * rt2x00dev )
{
unsigned int i ;
u32 reg ;
2011-04-18 15:34:22 +02:00
rt2x00usb_register_read ( rt2x00dev , TXRXQ_PCNT , & reg ) ;
2010-11-06 15:49:01 +01:00
if ( rt2x00_get_field32 ( reg , TXRXQ_PCNT_TX0Q ) ) {
WARNING ( rt2x00dev , " TX HW queue 0 timed out, "
2010-12-13 12:34:00 +01:00
" invoke forced kick \n " ) ;
2010-11-06 15:49:01 +01:00
2011-04-18 15:34:22 +02:00
rt2x00usb_register_write ( rt2x00dev , PBF_CFG , 0xf40012 ) ;
2010-11-06 15:49:01 +01:00
for ( i = 0 ; i < 10 ; i + + ) {
udelay ( 10 ) ;
if ( ! rt2x00_get_field32 ( reg , TXRXQ_PCNT_TX0Q ) )
break ;
}
2011-04-18 15:34:22 +02:00
rt2x00usb_register_write ( rt2x00dev , PBF_CFG , 0xf40006 ) ;
2010-11-06 15:49:01 +01:00
}
2011-04-18 15:34:22 +02:00
rt2x00usb_register_read ( rt2x00dev , TXRXQ_PCNT , & reg ) ;
2010-11-06 15:49:01 +01:00
if ( rt2x00_get_field32 ( reg , TXRXQ_PCNT_TX1Q ) ) {
WARNING ( rt2x00dev , " TX HW queue 1 timed out, "
2010-12-13 12:34:00 +01:00
" invoke forced kick \n " ) ;
2010-11-06 15:49:01 +01:00
2011-04-18 15:34:22 +02:00
rt2x00usb_register_write ( rt2x00dev , PBF_CFG , 0xf4000a ) ;
2010-11-06 15:49:01 +01:00
for ( i = 0 ; i < 10 ; i + + ) {
udelay ( 10 ) ;
if ( ! rt2x00_get_field32 ( reg , TXRXQ_PCNT_TX1Q ) )
break ;
}
2011-04-18 15:34:22 +02:00
rt2x00usb_register_write ( rt2x00dev , PBF_CFG , 0xf40006 ) ;
2010-11-06 15:49:01 +01:00
}
rt2x00usb_watchdog ( rt2x00dev ) ;
}
2009-04-26 15:47:48 +02:00
/*
* TX descriptor initialization
*/
2010-08-06 20:47:20 +02:00
static __le32 * rt2800usb_get_txwi ( struct queue_entry * entry )
2010-06-29 21:43:03 +02:00
{
2010-08-06 20:47:20 +02:00
if ( entry - > queue - > qid = = QID_BEACON )
return ( __le32 * ) ( entry - > skb - > data ) ;
else
return ( __le32 * ) ( entry - > skb - > data + TXINFO_DESC_SIZE ) ;
2010-06-29 21:43:03 +02:00
}
2010-08-23 19:53:39 +02:00
static void rt2800usb_write_tx_desc ( struct queue_entry * entry ,
2009-04-26 15:47:48 +02:00
struct txentry_desc * txdesc )
{
2010-08-23 19:53:39 +02:00
struct skb_frame_desc * skbdesc = get_skb_frame_desc ( entry - > skb ) ;
__le32 * txi = ( __le32 * ) entry - > skb - > data ;
2009-04-26 15:47:48 +02:00
u32 word ;
/*
2010-05-08 23:40:21 +02:00
* Initialize TXINFO descriptor
2009-04-26 15:47:48 +02:00
*/
rt2x00_desc_read ( txi , 0 , & word ) ;
2010-11-13 19:11:46 +01:00
/*
* The size of TXINFO_W0_USB_DMA_TX_PKT_LEN is
* TXWI + 802.11 header + L2 pad + payload + pad ,
2011-12-28 01:53:21 +01:00
* so need to decrease size of TXINFO .
2010-11-13 19:11:46 +01:00
*/
2009-04-26 15:47:48 +02:00
rt2x00_set_field32 ( & word , TXINFO_W0_USB_DMA_TX_PKT_LEN ,
2011-12-28 01:53:21 +01:00
roundup ( entry - > skb - > len , 4 ) - TXINFO_DESC_SIZE ) ;
2009-04-26 15:47:48 +02:00
rt2x00_set_field32 ( & word , TXINFO_W0_WIV ,
! test_bit ( ENTRY_TXD_ENCRYPT_IV , & txdesc - > flags ) ) ;
rt2x00_set_field32 ( & word , TXINFO_W0_QSEL , 2 ) ;
rt2x00_set_field32 ( & word , TXINFO_W0_SW_USE_LAST_ROUND , 0 ) ;
rt2x00_set_field32 ( & word , TXINFO_W0_USB_DMA_NEXT_VALID , 0 ) ;
rt2x00_set_field32 ( & word , TXINFO_W0_USB_DMA_TX_BURST ,
test_bit ( ENTRY_TXD_BURST , & txdesc - > flags ) ) ;
rt2x00_desc_write ( txi , 0 , word ) ;
2010-05-11 23:51:40 +02:00
/*
* Register descriptor details in skb frame descriptor .
*/
2010-06-03 10:51:45 +02:00
skbdesc - > flags | = SKBDESC_DESC_IN_SKB ;
2010-05-11 23:51:40 +02:00
skbdesc - > desc = txi ;
skbdesc - > desc_len = TXINFO_DESC_SIZE + TXWI_DESC_SIZE ;
2009-04-26 15:47:48 +02:00
}
2011-12-28 01:53:21 +01:00
/*
* TX data initialization
*/
static int rt2800usb_get_tx_data_len ( struct queue_entry * entry )
2009-04-26 15:47:48 +02:00
{
/*
2011-12-28 01:53:21 +01:00
* pad ( 1 ~ 3 bytes ) is needed after each 802.11 payload .
* USB end pad ( 4 bytes ) is needed at each USB bulk out packet end .
2010-11-13 19:11:46 +01:00
* TX frame format is :
* | TXINFO | TXWI | 802.11 header | L2 pad | payload | pad | USB end pad |
* | < - - - - - - - - - - - - - tx_pkt_len - - - - - - - - - - - - - > |
2009-04-26 15:47:48 +02:00
*/
2010-12-27 15:06:17 +01:00
2011-12-28 01:53:21 +01:00
return roundup ( entry - > skb - > len , 4 ) + 4 ;
2009-04-26 15:47:48 +02:00
}
2010-08-06 20:47:57 +02:00
/*
* TX control handlers
*/
2011-05-18 20:25:49 +02:00
static bool rt2800usb_txdone_entry_check ( struct queue_entry * entry , u32 reg )
{
__le32 * txwi ;
u32 word ;
int wcid , ack , pid ;
int tx_wcid , tx_ack , tx_pid ;
2011-08-10 15:32:22 +02:00
if ( test_bit ( ENTRY_OWNER_DEVICE_DATA , & entry - > flags ) | |
! test_bit ( ENTRY_DATA_STATUS_PENDING , & entry - > flags ) ) {
WARNING ( entry - > queue - > rt2x00dev ,
" Data pending for entry %u in queue %u \n " ,
entry - > entry_idx , entry - > queue - > qid ) ;
cond_resched ( ) ;
return false ;
}
2011-05-18 20:25:49 +02:00
wcid = rt2x00_get_field32 ( reg , TX_STA_FIFO_WCID ) ;
ack = rt2x00_get_field32 ( reg , TX_STA_FIFO_TX_ACK_REQUIRED ) ;
pid = rt2x00_get_field32 ( reg , TX_STA_FIFO_PID_TYPE ) ;
/*
* This frames has returned with an IO error ,
* so the status report is not intended for this
* frame .
*/
if ( test_bit ( ENTRY_DATA_IO_FAILED , & entry - > flags ) ) {
rt2x00lib_txdone_noinfo ( entry , TXDONE_FAILURE ) ;
return false ;
}
/*
* Validate if this TX status report is intended for
* this entry by comparing the WCID / ACK / PID fields .
*/
txwi = rt2800usb_get_txwi ( entry ) ;
rt2x00_desc_read ( txwi , 1 , & word ) ;
tx_wcid = rt2x00_get_field32 ( word , TXWI_W1_WIRELESS_CLI_ID ) ;
tx_ack = rt2x00_get_field32 ( word , TXWI_W1_ACK ) ;
tx_pid = rt2x00_get_field32 ( word , TXWI_W1_PACKETID ) ;
if ( ( wcid ! = tx_wcid ) | | ( ack ! = tx_ack ) | | ( pid ! = tx_pid ) ) {
WARNING ( entry - > queue - > rt2x00dev ,
" TX status report missed for queue %d entry %d \n " ,
entry - > queue - > qid , entry - > entry_idx ) ;
rt2x00lib_txdone_noinfo ( entry , TXDONE_UNKNOWN ) ;
return false ;
}
return true ;
}
static void rt2800usb_txdone ( struct rt2x00_dev * rt2x00dev )
{
struct data_queue * queue ;
struct queue_entry * entry ;
u32 reg ;
u8 qid ;
while ( kfifo_get ( & rt2x00dev - > txstatus_fifo , & reg ) ) {
/* TX_STA_FIFO_PID_QUEUE is a 2-bit field, thus
* qid is guaranteed to be one of the TX QIDs
*/
qid = rt2x00_get_field32 ( reg , TX_STA_FIFO_PID_QUEUE ) ;
queue = rt2x00queue_get_tx_queue ( rt2x00dev , qid ) ;
if ( unlikely ( ! queue ) ) {
WARNING ( rt2x00dev , " Got TX status for an unavailable "
" queue %u, dropping \n " , qid ) ;
continue ;
}
/*
* Inside each queue , we process each entry in a chronological
* order . We first check that the queue is not empty .
*/
entry = NULL ;
while ( ! rt2x00queue_empty ( queue ) ) {
entry = rt2x00queue_get_entry ( queue , Q_INDEX_DONE ) ;
if ( rt2800usb_txdone_entry_check ( entry , reg ) )
break ;
2011-08-10 15:32:24 +02:00
entry = NULL ;
2011-05-18 20:25:49 +02:00
}
2011-08-10 15:32:24 +02:00
if ( entry )
2011-09-22 03:23:13 -04:00
rt2800_txdone_entry ( entry , reg ,
rt2800usb_get_txwi ( entry ) ) ;
2011-05-18 20:25:49 +02:00
}
}
2010-08-06 20:47:57 +02:00
static void rt2800usb_work_txdone ( struct work_struct * work )
{
struct rt2x00_dev * rt2x00dev =
container_of ( work , struct rt2x00_dev , txdone_work ) ;
struct data_queue * queue ;
struct queue_entry * entry ;
2011-05-18 20:25:49 +02:00
rt2800usb_txdone ( rt2x00dev ) ;
2010-08-06 20:47:57 +02:00
/*
* Process any trailing TX status reports for IO failures ,
* we loop until we find the first non - IO error entry . This
* can either be a frame which is free , is being uploaded ,
* or has completed the upload but didn ' t have an entry
* in the TX_STAT_FIFO register yet .
*/
tx_queue_for_each ( rt2x00dev , queue ) {
while ( ! rt2x00queue_empty ( queue ) ) {
entry = rt2x00queue_get_entry ( queue , Q_INDEX_DONE ) ;
2011-08-10 15:32:22 +02:00
if ( test_bit ( ENTRY_OWNER_DEVICE_DATA , & entry - > flags ) | |
! test_bit ( ENTRY_DATA_STATUS_PENDING , & entry - > flags ) )
2011-04-18 15:30:01 +02:00
break ;
2011-08-10 15:32:22 +02:00
2011-04-18 15:30:01 +02:00
if ( test_bit ( ENTRY_DATA_IO_FAILED , & entry - > flags ) )
rt2x00lib_txdone_noinfo ( entry , TXDONE_FAILURE ) ;
else if ( rt2x00queue_status_timeout ( entry ) )
rt2x00lib_txdone_noinfo ( entry , TXDONE_UNKNOWN ) ;
else
2010-08-06 20:47:57 +02:00
break ;
}
}
2011-04-18 15:30:36 +02:00
/*
* The hw may delay sending the packet after DMA complete
* if the medium is busy , thus the TX_STA_FIFO entry is
* also delayed - > use a timer to retrieve it .
*/
if ( rt2800usb_txstatus_pending ( rt2x00dev ) )
2011-04-30 17:13:46 +02:00
mod_timer ( & rt2x00dev - > txstatus_timer , jiffies + msecs_to_jiffies ( 2 ) ) ;
2010-08-06 20:47:57 +02:00
}
2009-04-26 15:47:48 +02:00
/*
* RX control handlers
*/
static void rt2800usb_fill_rxdone ( struct queue_entry * entry ,
struct rxdone_entry_desc * rxdesc )
{
struct skb_frame_desc * skbdesc = get_skb_frame_desc ( entry - > skb ) ;
2009-12-04 23:47:06 +01:00
__le32 * rxi = ( __le32 * ) entry - > skb - > data ;
__le32 * rxd ;
2010-05-08 23:40:22 +02:00
u32 word ;
2009-12-04 23:47:06 +01:00
int rx_pkt_len ;
2010-05-08 23:40:22 +02:00
/*
* Copy descriptor to the skbdesc - > desc buffer , making it safe from
* moving of frame data in rt2x00usb .
*/
memcpy ( skbdesc - > desc , rxi , skbdesc - > desc_len ) ;
2009-12-04 23:47:06 +01:00
/*
* RX frame format is :
* | RXINFO | RXWI | header | L2 pad | payload | pad | RXD | USB pad |
* | < - - - - - - - - - - - - rx_pkt_len - - - - - - - - - - - - - - > |
*/
2010-05-08 23:40:22 +02:00
rt2x00_desc_read ( rxi , 0 , & word ) ;
rx_pkt_len = rt2x00_get_field32 ( word , RXINFO_W0_USB_DMA_RX_PKT_LEN ) ;
2009-12-04 23:47:06 +01:00
/*
2010-05-08 23:40:22 +02:00
* Remove the RXINFO structure from the sbk .
2009-12-04 23:47:06 +01:00
*/
2010-05-08 23:40:22 +02:00
skb_pull ( entry - > skb , RXINFO_DESC_SIZE ) ;
2009-04-26 15:47:48 +02:00
/*
2010-05-08 23:40:22 +02:00
* FIXME : we need to check for rx_pkt_len validity
2009-04-26 15:47:48 +02:00
*/
2010-05-08 23:40:22 +02:00
rxd = ( __le32 * ) ( entry - > skb - > data + rx_pkt_len ) ;
2009-04-26 15:47:48 +02:00
/*
* It is now safe to read the descriptor on all architectures .
*/
2010-05-08 23:40:22 +02:00
rt2x00_desc_read ( rxd , 0 , & word ) ;
2009-04-26 15:47:48 +02:00
2010-05-08 23:40:22 +02:00
if ( rt2x00_get_field32 ( word , RXD_W0_CRC_ERROR ) )
2009-04-26 15:47:48 +02:00
rxdesc - > flags | = RX_FLAG_FAILED_FCS_CRC ;
2010-05-08 23:40:22 +02:00
rxdesc - > cipher_status = rt2x00_get_field32 ( word , RXD_W0_CIPHER_ERROR ) ;
2009-04-26 15:47:48 +02:00
2010-05-08 23:40:22 +02:00
if ( rt2x00_get_field32 ( word , RXD_W0_DECRYPTED ) ) {
2009-04-26 15:47:48 +02:00
/*
* Hardware has stripped IV / EIV data from 802.11 frame during
* decryption . Unfortunately the descriptor doesn ' t contain
* any fields with the EIV / IV data either , so they can ' t
* be restored by rt2x00lib .
*/
rxdesc - > flags | = RX_FLAG_IV_STRIPPED ;
2011-01-30 13:22:41 +01:00
/*
* The hardware has already checked the Michael Mic and has
* stripped it from the frame . Signal this to mac80211 .
*/
rxdesc - > flags | = RX_FLAG_MMIC_STRIPPED ;
2009-04-26 15:47:48 +02:00
if ( rxdesc - > cipher_status = = RX_CRYPTO_SUCCESS )
rxdesc - > flags | = RX_FLAG_DECRYPTED ;
else if ( rxdesc - > cipher_status = = RX_CRYPTO_FAIL_MIC )
rxdesc - > flags | = RX_FLAG_MMIC_ERROR ;
}
2010-05-08 23:40:22 +02:00
if ( rt2x00_get_field32 ( word , RXD_W0_MY_BSS ) )
2009-04-26 15:47:48 +02:00
rxdesc - > dev_flags | = RXDONE_MY_BSS ;
2010-05-08 23:40:22 +02:00
if ( rt2x00_get_field32 ( word , RXD_W0_L2PAD ) )
2009-04-26 15:47:48 +02:00
rxdesc - > dev_flags | = RXDONE_L2PAD ;
/*
2010-05-08 23:40:22 +02:00
* Remove RXD descriptor from end of buffer .
2009-04-26 15:47:48 +02:00
*/
2010-05-08 23:40:22 +02:00
skb_trim ( entry - > skb , rx_pkt_len ) ;
2009-04-26 15:47:48 +02:00
/*
2010-05-08 23:40:22 +02:00
* Process the RXWI structure .
2009-04-26 15:47:48 +02:00
*/
2010-07-11 12:23:50 +02:00
rt2800_process_rxwi ( entry , rxdesc ) ;
2009-04-26 15:47:48 +02:00
}
/*
* Device probe functions .
*/
2009-11-08 14:38:54 +01:00
static int rt2800usb_validate_eeprom ( struct rt2x00_dev * rt2x00dev )
{
2009-11-08 14:39:55 +01:00
if ( rt2800_efuse_detect ( rt2x00dev ) )
rt2800_read_eeprom_efuse ( rt2x00dev ) ;
else
rt2x00usb_eeprom_read ( rt2x00dev , rt2x00dev - > eeprom ,
EEPROM_SIZE ) ;
2009-11-08 14:38:54 +01:00
return rt2800_validate_eeprom ( rt2x00dev ) ;
}
2009-04-26 15:47:48 +02:00
static int rt2800usb_probe_hw ( struct rt2x00_dev * rt2x00dev )
{
int retval ;
/*
* Allocate eeprom data .
*/
retval = rt2800usb_validate_eeprom ( rt2x00dev ) ;
if ( retval )
return retval ;
2009-11-08 14:39:01 +01:00
retval = rt2800_init_eeprom ( rt2x00dev ) ;
2009-04-26 15:47:48 +02:00
if ( retval )
return retval ;
/*
* Initialize hw specifications .
*/
2009-11-08 14:39:32 +01:00
retval = rt2800_probe_hw_mode ( rt2x00dev ) ;
2009-04-26 15:47:48 +02:00
if ( retval )
return retval ;
2009-08-08 23:55:55 +02:00
/*
* This device has multiple filters for control frames
* and has a separate filter for PS Poll frames .
*/
2011-04-18 15:27:06 +02:00
__set_bit ( CAPABILITY_CONTROL_FILTERS , & rt2x00dev - > cap_flags ) ;
__set_bit ( CAPABILITY_CONTROL_FILTER_PSPOLL , & rt2x00dev - > cap_flags ) ;
2009-08-08 23:55:55 +02:00
2009-04-26 15:47:48 +02:00
/*
* This device requires firmware .
*/
2011-04-18 15:27:06 +02:00
__set_bit ( REQUIRE_FIRMWARE , & rt2x00dev - > cap_flags ) ;
__set_bit ( REQUIRE_L2PAD , & rt2x00dev - > cap_flags ) ;
2009-04-26 15:47:48 +02:00
if ( ! modparam_nohwcrypt )
2011-04-18 15:27:06 +02:00
__set_bit ( CAPABILITY_HW_CRYPTO , & rt2x00dev - > cap_flags ) ;
__set_bit ( CAPABILITY_LINK_TUNING , & rt2x00dev - > cap_flags ) ;
__set_bit ( REQUIRE_HT_TX_DESC , & rt2x00dev - > cap_flags ) ;
2011-04-18 15:29:12 +02:00
__set_bit ( REQUIRE_TXSTATUS_FIFO , & rt2x00dev - > cap_flags ) ;
2011-04-30 17:18:18 +02:00
__set_bit ( REQUIRE_PS_AUTOWAKE , & rt2x00dev - > cap_flags ) ;
2009-04-26 15:47:48 +02:00
2011-04-18 15:30:36 +02:00
setup_timer ( & rt2x00dev - > txstatus_timer ,
rt2800usb_tx_sta_fifo_timeout ,
( unsigned long ) rt2x00dev ) ;
2009-04-26 15:47:48 +02:00
/*
* Set the rssi offset .
*/
rt2x00dev - > rssi_offset = DEFAULT_RSSI_OFFSET ;
2010-08-06 20:47:57 +02:00
/*
* Overwrite TX done handler
*/
PREPARE_WORK ( & rt2x00dev - > txdone_work , rt2800usb_work_txdone ) ;
2009-04-26 15:47:48 +02:00
return 0 ;
}
2010-07-11 12:28:54 +02:00
static const struct ieee80211_ops rt2800usb_mac80211_ops = {
. tx = rt2x00mac_tx ,
. start = rt2x00mac_start ,
. stop = rt2x00mac_stop ,
. add_interface = rt2x00mac_add_interface ,
. remove_interface = rt2x00mac_remove_interface ,
. config = rt2x00mac_config ,
. configure_filter = rt2x00mac_configure_filter ,
. set_tim = rt2x00mac_set_tim ,
. set_key = rt2x00mac_set_key ,
. sw_scan_start = rt2x00mac_sw_scan_start ,
. sw_scan_complete = rt2x00mac_sw_scan_complete ,
. get_stats = rt2x00mac_get_stats ,
. get_tkip_seq = rt2800_get_tkip_seq ,
. set_rts_threshold = rt2800_set_rts_threshold ,
2011-09-08 14:38:01 +02:00
. sta_add = rt2x00mac_sta_add ,
. sta_remove = rt2x00mac_sta_remove ,
2010-07-11 12:28:54 +02:00
. bss_info_changed = rt2x00mac_bss_info_changed ,
. conf_tx = rt2800_conf_tx ,
. get_tsf = rt2800_get_tsf ,
. rfkill_poll = rt2x00mac_rfkill_poll ,
. ampdu_action = rt2800_ampdu_action ,
2010-11-04 20:40:11 +01:00
. flush = rt2x00mac_flush ,
2010-12-13 12:31:58 +01:00
. get_survey = rt2800_get_survey ,
2011-04-18 15:34:41 +02:00
. get_ringparam = rt2x00mac_get_ringparam ,
2011-07-06 23:00:21 +02:00
. tx_frames_pending = rt2x00mac_tx_frames_pending ,
2010-07-11 12:28:54 +02:00
} ;
2010-07-11 12:31:23 +02:00
static const struct rt2800_ops rt2800usb_rt2800_ops = {
. register_read = rt2x00usb_register_read ,
. register_read_lock = rt2x00usb_register_read_lock ,
. register_write = rt2x00usb_register_write ,
. register_write_lock = rt2x00usb_register_write_lock ,
. register_multiread = rt2x00usb_register_multiread ,
. register_multiwrite = rt2x00usb_register_multiwrite ,
. regbusy_read = rt2x00usb_regbusy_read ,
. drv_write_firmware = rt2800usb_write_firmware ,
. drv_init_registers = rt2800usb_init_registers ,
2010-08-06 20:47:20 +02:00
. drv_get_txwi = rt2800usb_get_txwi ,
2010-07-11 12:31:23 +02:00
} ;
2009-04-26 15:47:48 +02:00
static const struct rt2x00lib_ops rt2800usb_rt2x00_ops = {
. probe_hw = rt2800usb_probe_hw ,
. get_firmware_name = rt2800usb_get_firmware_name ,
2010-07-11 12:30:37 +02:00
. check_firmware = rt2800_check_firmware ,
. load_firmware = rt2800_load_firmware ,
2009-04-26 15:47:48 +02:00
. initialize = rt2x00usb_initialize ,
. uninitialize = rt2x00usb_uninitialize ,
. clear_entry = rt2x00usb_clear_entry ,
. set_device_state = rt2800usb_set_device_state ,
2009-11-04 18:36:40 +01:00
. rfkill_poll = rt2800_rfkill_poll ,
. link_stats = rt2800_link_stats ,
. reset_tuner = rt2800_reset_tuner ,
. link_tuner = rt2800_link_tuner ,
2011-03-28 13:33:40 +02:00
. gain_calibration = rt2800_gain_calibration ,
2012-02-16 21:40:57 +08:00
. vco_calibration = rt2800_vco_calibration ,
2010-11-06 15:49:01 +01:00
. watchdog = rt2800usb_watchdog ,
2010-12-13 12:34:54 +01:00
. start_queue = rt2800usb_start_queue ,
. kick_queue = rt2x00usb_kick_queue ,
. stop_queue = rt2800usb_stop_queue ,
2010-12-13 12:35:40 +01:00
. flush_queue = rt2x00usb_flush_queue ,
2011-04-18 15:29:12 +02:00
. tx_dma_done = rt2800usb_tx_dma_done ,
2009-04-26 15:47:48 +02:00
. write_tx_desc = rt2800usb_write_tx_desc ,
2011-12-28 01:53:21 +01:00
. write_tx_data = rt2800_write_tx_data ,
2010-06-03 10:51:53 +02:00
. write_beacon = rt2800_write_beacon ,
2011-01-30 13:16:03 +01:00
. clear_beacon = rt2800_clear_beacon ,
2009-04-26 15:47:48 +02:00
. get_tx_data_len = rt2800usb_get_tx_data_len ,
. fill_rxdone = rt2800usb_fill_rxdone ,
2009-11-04 18:36:40 +01:00
. config_shared_key = rt2800_config_shared_key ,
. config_pairwise_key = rt2800_config_pairwise_key ,
. config_filter = rt2800_config_filter ,
. config_intf = rt2800_config_intf ,
. config_erp = rt2800_config_erp ,
. config_ant = rt2800_config_ant ,
. config = rt2800_config ,
2011-09-08 14:38:01 +02:00
. sta_add = rt2800_sta_add ,
. sta_remove = rt2800_sta_remove ,
2009-04-26 15:47:48 +02:00
} ;
static const struct data_queue_desc rt2800usb_queue_rx = {
2010-11-04 20:37:22 +01:00
. entry_num = 128 ,
2009-04-26 15:47:48 +02:00
. data_size = AGGREGATION_SIZE ,
2009-11-04 18:35:47 +01:00
. desc_size = RXINFO_DESC_SIZE + RXWI_DESC_SIZE ,
2009-04-26 15:47:48 +02:00
. priv_size = sizeof ( struct queue_entry_priv_usb ) ,
} ;
static const struct data_queue_desc rt2800usb_queue_tx = {
2010-11-04 20:37:22 +01:00
. entry_num = 64 ,
2009-04-26 15:47:48 +02:00
. data_size = AGGREGATION_SIZE ,
. desc_size = TXINFO_DESC_SIZE + TXWI_DESC_SIZE ,
. priv_size = sizeof ( struct queue_entry_priv_usb ) ,
} ;
static const struct data_queue_desc rt2800usb_queue_bcn = {
2010-11-04 20:37:22 +01:00
. entry_num = 8 ,
2009-04-26 15:47:48 +02:00
. data_size = MGMT_FRAME_SIZE ,
. desc_size = TXINFO_DESC_SIZE + TXWI_DESC_SIZE ,
. priv_size = sizeof ( struct queue_entry_priv_usb ) ,
} ;
static const struct rt2x00_ops rt2800usb_ops = {
2009-11-23 22:44:51 +01:00
. name = KBUILD_MODNAME ,
2012-02-06 23:45:07 +01:00
. drv_data_size = sizeof ( struct rt2800_drv_data ) ,
2009-11-23 22:44:51 +01:00
. max_sta_intf = 1 ,
. max_ap_intf = 8 ,
. eeprom_size = EEPROM_SIZE ,
. rf_size = RF_SIZE ,
. tx_queues = NUM_TX_QUEUES ,
2009-11-23 22:44:52 +01:00
. extra_tx_headroom = TXINFO_DESC_SIZE + TXWI_DESC_SIZE ,
2009-11-23 22:44:51 +01:00
. rx = & rt2800usb_queue_rx ,
. tx = & rt2800usb_queue_tx ,
. bcn = & rt2800usb_queue_bcn ,
. lib = & rt2800usb_rt2x00_ops ,
2010-07-11 12:31:23 +02:00
. drv = & rt2800usb_rt2800_ops ,
2010-07-11 12:28:54 +02:00
. hw = & rt2800usb_mac80211_ops ,
2009-04-26 15:47:48 +02:00
# ifdef CONFIG_RT2X00_LIB_DEBUGFS
2009-11-23 22:44:51 +01:00
. debugfs = & rt2800_rt2x00debug ,
2009-04-26 15:47:48 +02:00
# endif /* CONFIG_RT2X00_LIB_DEBUGFS */
} ;
/*
* rt2800usb module information .
*/
static struct usb_device_id rt2800usb_device_table [ ] = {
/* Abocom */
2011-04-18 15:32:13 +02:00
{ USB_DEVICE ( 0x07b8 , 0x2870 ) } ,
{ USB_DEVICE ( 0x07b8 , 0x2770 ) } ,
{ USB_DEVICE ( 0x07b8 , 0x3070 ) } ,
{ USB_DEVICE ( 0x07b8 , 0x3071 ) } ,
{ USB_DEVICE ( 0x07b8 , 0x3072 ) } ,
{ USB_DEVICE ( 0x1482 , 0x3c09 ) } ,
2010-11-13 19:10:31 +01:00
/* AirTies */
2011-04-18 15:32:33 +02:00
{ USB_DEVICE ( 0x1eda , 0x2012 ) } ,
2011-04-18 15:32:13 +02:00
{ USB_DEVICE ( 0x1eda , 0x2310 ) } ,
2010-04-19 11:54:16 +02:00
/* Allwin */
2011-04-18 15:32:13 +02:00
{ USB_DEVICE ( 0x8516 , 0x2070 ) } ,
{ USB_DEVICE ( 0x8516 , 0x2770 ) } ,
{ USB_DEVICE ( 0x8516 , 0x2870 ) } ,
{ USB_DEVICE ( 0x8516 , 0x3070 ) } ,
{ USB_DEVICE ( 0x8516 , 0x3071 ) } ,
{ USB_DEVICE ( 0x8516 , 0x3072 ) } ,
2011-04-12 00:19:10 -04:00
/* Alpha Networks */
2011-04-18 15:32:13 +02:00
{ USB_DEVICE ( 0x14b2 , 0x3c06 ) } ,
{ USB_DEVICE ( 0x14b2 , 0x3c07 ) } ,
{ USB_DEVICE ( 0x14b2 , 0x3c09 ) } ,
{ USB_DEVICE ( 0x14b2 , 0x3c12 ) } ,
{ USB_DEVICE ( 0x14b2 , 0x3c23 ) } ,
{ USB_DEVICE ( 0x14b2 , 0x3c25 ) } ,
{ USB_DEVICE ( 0x14b2 , 0x3c27 ) } ,
{ USB_DEVICE ( 0x14b2 , 0x3c28 ) } ,
{ USB_DEVICE ( 0x14b2 , 0x3c2c ) } ,
2009-04-26 15:47:48 +02:00
/* Amit */
2011-04-18 15:32:13 +02:00
{ USB_DEVICE ( 0x15c5 , 0x0008 ) } ,
2009-11-17 13:43:16 +01:00
/* Askey */
2011-04-18 15:32:13 +02:00
{ USB_DEVICE ( 0x1690 , 0x0740 ) } ,
2009-04-26 15:47:48 +02:00
/* ASUS */
2011-04-18 15:32:13 +02:00
{ USB_DEVICE ( 0x0b05 , 0x1731 ) } ,
{ USB_DEVICE ( 0x0b05 , 0x1732 ) } ,
{ USB_DEVICE ( 0x0b05 , 0x1742 ) } ,
{ USB_DEVICE ( 0x0b05 , 0x1784 ) } ,
{ USB_DEVICE ( 0x1761 , 0x0b05 ) } ,
2009-04-26 15:47:48 +02:00
/* AzureWave */
2011-04-18 15:32:13 +02:00
{ USB_DEVICE ( 0x13d3 , 0x3247 ) } ,
{ USB_DEVICE ( 0x13d3 , 0x3273 ) } ,
{ USB_DEVICE ( 0x13d3 , 0x3305 ) } ,
{ USB_DEVICE ( 0x13d3 , 0x3307 ) } ,
{ USB_DEVICE ( 0x13d3 , 0x3321 ) } ,
2009-04-26 15:47:48 +02:00
/* Belkin */
2011-04-18 15:32:13 +02:00
{ USB_DEVICE ( 0x050d , 0x8053 ) } ,
{ USB_DEVICE ( 0x050d , 0x805c ) } ,
{ USB_DEVICE ( 0x050d , 0x815c ) } ,
2011-12-28 01:53:18 +01:00
{ USB_DEVICE ( 0x050d , 0x825a ) } ,
2011-04-18 15:32:13 +02:00
{ USB_DEVICE ( 0x050d , 0x825b ) } ,
{ USB_DEVICE ( 0x050d , 0x935a ) } ,
{ USB_DEVICE ( 0x050d , 0x935b ) } ,
2009-04-26 15:47:48 +02:00
/* Buffalo */
2011-04-18 15:32:13 +02:00
{ USB_DEVICE ( 0x0411 , 0x00e8 ) } ,
2011-11-12 19:10:43 +01:00
{ USB_DEVICE ( 0x0411 , 0x0158 ) } ,
2011-12-28 01:53:18 +01:00
{ USB_DEVICE ( 0x0411 , 0x015d ) } ,
2011-04-18 15:32:13 +02:00
{ USB_DEVICE ( 0x0411 , 0x016f ) } ,
{ USB_DEVICE ( 0x0411 , 0x01a2 ) } ,
2009-04-26 15:47:48 +02:00
/* Corega */
2011-04-18 15:32:13 +02:00
{ USB_DEVICE ( 0x07aa , 0x002f ) } ,
{ USB_DEVICE ( 0x07aa , 0x003c ) } ,
{ USB_DEVICE ( 0x07aa , 0x003f ) } ,
{ USB_DEVICE ( 0x18c5 , 0x0012 ) } ,
2010-02-14 12:52:05 +01:00
/* D-Link */
2011-04-18 15:32:13 +02:00
{ USB_DEVICE ( 0x07d1 , 0x3c09 ) } ,
{ USB_DEVICE ( 0x07d1 , 0x3c0a ) } ,
{ USB_DEVICE ( 0x07d1 , 0x3c0d ) } ,
{ USB_DEVICE ( 0x07d1 , 0x3c0e ) } ,
{ USB_DEVICE ( 0x07d1 , 0x3c0f ) } ,
{ USB_DEVICE ( 0x07d1 , 0x3c11 ) } ,
2011-12-28 01:53:18 +01:00
{ USB_DEVICE ( 0x07d1 , 0x3c13 ) } ,
{ USB_DEVICE ( 0x07d1 , 0x3c15 ) } ,
2011-04-18 15:32:13 +02:00
{ USB_DEVICE ( 0x07d1 , 0x3c16 ) } ,
2012-02-11 21:58:09 +01:00
{ USB_DEVICE ( 0x2001 , 0x3c1b ) } ,
2010-03-28 20:02:41 +02:00
/* Draytek */
2011-04-18 15:32:13 +02:00
{ USB_DEVICE ( 0x07fa , 0x7712 ) } ,
2011-08-05 07:46:32 +02:00
/* DVICO */
{ USB_DEVICE ( 0x0fe9 , 0xb307 ) } ,
2009-04-26 15:47:48 +02:00
/* Edimax */
2011-04-18 15:32:13 +02:00
{ USB_DEVICE ( 0x7392 , 0x7711 ) } ,
{ USB_DEVICE ( 0x7392 , 0x7717 ) } ,
{ USB_DEVICE ( 0x7392 , 0x7718 ) } ,
2011-12-28 01:53:18 +01:00
{ USB_DEVICE ( 0x7392 , 0x7722 ) } ,
2009-05-22 21:33:21 +02:00
/* Encore */
2011-04-18 15:32:13 +02:00
{ USB_DEVICE ( 0x203d , 0x1480 ) } ,
{ USB_DEVICE ( 0x203d , 0x14a9 ) } ,
2009-04-26 15:47:48 +02:00
/* EnGenius */
2011-04-18 15:32:13 +02:00
{ USB_DEVICE ( 0x1740 , 0x9701 ) } ,
{ USB_DEVICE ( 0x1740 , 0x9702 ) } ,
{ USB_DEVICE ( 0x1740 , 0x9703 ) } ,
{ USB_DEVICE ( 0x1740 , 0x9705 ) } ,
{ USB_DEVICE ( 0x1740 , 0x9706 ) } ,
{ USB_DEVICE ( 0x1740 , 0x9707 ) } ,
{ USB_DEVICE ( 0x1740 , 0x9708 ) } ,
{ USB_DEVICE ( 0x1740 , 0x9709 ) } ,
2011-04-12 00:19:10 -04:00
/* Gemtek */
2011-04-18 15:32:13 +02:00
{ USB_DEVICE ( 0x15a9 , 0x0012 ) } ,
2010-02-14 12:52:05 +01:00
/* Gigabyte */
2011-04-18 15:32:13 +02:00
{ USB_DEVICE ( 0x1044 , 0x800b ) } ,
{ USB_DEVICE ( 0x1044 , 0x800d ) } ,
2010-11-13 19:10:31 +01:00
/* Hawking */
2011-04-18 15:32:13 +02:00
{ USB_DEVICE ( 0x0e66 , 0x0001 ) } ,
{ USB_DEVICE ( 0x0e66 , 0x0003 ) } ,
{ USB_DEVICE ( 0x0e66 , 0x0009 ) } ,
{ USB_DEVICE ( 0x0e66 , 0x000b ) } ,
{ USB_DEVICE ( 0x0e66 , 0x0013 ) } ,
{ USB_DEVICE ( 0x0e66 , 0x0017 ) } ,
{ USB_DEVICE ( 0x0e66 , 0x0018 ) } ,
2010-02-14 12:52:05 +01:00
/* I-O DATA */
2011-04-18 15:32:13 +02:00
{ USB_DEVICE ( 0x04bb , 0x0945 ) } ,
{ USB_DEVICE ( 0x04bb , 0x0947 ) } ,
{ USB_DEVICE ( 0x04bb , 0x0948 ) } ,
2010-11-13 19:10:31 +01:00
/* Linksys */
2011-04-18 15:32:13 +02:00
{ USB_DEVICE ( 0x13b1 , 0x0031 ) } ,
{ USB_DEVICE ( 0x1737 , 0x0070 ) } ,
{ USB_DEVICE ( 0x1737 , 0x0071 ) } ,
2011-12-27 12:22:51 -06:00
{ USB_DEVICE ( 0x1737 , 0x0077 ) } ,
2011-12-28 01:53:18 +01:00
{ USB_DEVICE ( 0x1737 , 0x0078 ) } ,
2010-03-28 20:02:41 +02:00
/* Logitec */
2011-04-18 15:32:13 +02:00
{ USB_DEVICE ( 0x0789 , 0x0162 ) } ,
{ USB_DEVICE ( 0x0789 , 0x0163 ) } ,
{ USB_DEVICE ( 0x0789 , 0x0164 ) } ,
{ USB_DEVICE ( 0x0789 , 0x0166 ) } ,
2010-11-13 19:10:31 +01:00
/* Motorola */
2011-04-18 15:32:13 +02:00
{ USB_DEVICE ( 0x100d , 0x9031 ) } ,
2010-02-14 12:52:05 +01:00
/* MSI */
2011-04-18 15:32:13 +02:00
{ USB_DEVICE ( 0x0db0 , 0x3820 ) } ,
{ USB_DEVICE ( 0x0db0 , 0x3821 ) } ,
{ USB_DEVICE ( 0x0db0 , 0x3822 ) } ,
{ USB_DEVICE ( 0x0db0 , 0x3870 ) } ,
{ USB_DEVICE ( 0x0db0 , 0x3871 ) } ,
{ USB_DEVICE ( 0x0db0 , 0x6899 ) } ,
{ USB_DEVICE ( 0x0db0 , 0x821a ) } ,
{ USB_DEVICE ( 0x0db0 , 0x822a ) } ,
{ USB_DEVICE ( 0x0db0 , 0x822b ) } ,
{ USB_DEVICE ( 0x0db0 , 0x822c ) } ,
{ USB_DEVICE ( 0x0db0 , 0x870a ) } ,
{ USB_DEVICE ( 0x0db0 , 0x871a ) } ,
{ USB_DEVICE ( 0x0db0 , 0x871b ) } ,
{ USB_DEVICE ( 0x0db0 , 0x871c ) } ,
{ USB_DEVICE ( 0x0db0 , 0x899a ) } ,
2011-12-28 01:53:18 +01:00
/* Ovislink */
{ USB_DEVICE ( 0x1b75 , 0x3071 ) } ,
{ USB_DEVICE ( 0x1b75 , 0x3072 ) } ,
wireless: rt2x00: rt2800usb: identify ids-chips
Taken from ralink linux drivers:
RT3070_LinuxSTA_V2.3.0.1_20100208/common/rtusb_dev_id.c: {USB_DEVICE(0x0B05,0x1784)}, /* Asus 3072 */
RT3070_LinuxSTA_V2.3.0.1_20100208/common/rtusb_dev_id.c: {USB_DEVICE(0x13D3,0x3305)}, /* AzureWave 3070*/
RT3070_LinuxSTA_V2.3.0.1_20100208/common/rtusb_dev_id.c: {USB_DEVICE(0x07D1,0x3C16)}, /* D-Link 3070 */
RT3070_LinuxSTA_V2.3.0.1_20100208/common/rtusb_dev_id.c: {USB_DEVICE(0x203D,0x14A9)}, /* Encore 3070*/
RT3070_LinuxSTA_V2.3.0.1_20100208/common/rtusb_dev_id.c: {USB_DEVICE(0x1740,0x9707)}, /* EnGenius 3070 */
RT3070_LinuxSTA_V2.3.0.1_20100208/common/rtusb_dev_id.c: {USB_DEVICE(0x1740,0x9708)}, /* EnGenius 3071 */
RT3070_LinuxSTA_V2.3.0.1_20100208/common/rtusb_dev_id.c: {USB_DEVICE(0x1740,0x9709)}, /* EnGenius 3072 */
RT3070_LinuxSTA_V2.3.0.1_20100208/common/rtusb_dev_id.c: {USB_DEVICE(0x04BB,0x0947)}, /* I-O DATA 3070 */
RT3070_LinuxSTA_V2.3.0.1_20100208/common/rtusb_dev_id.c: {USB_DEVICE(0x04BB,0x0948)}, /* I-O DATA 3072 */
RT3070_LinuxSTA_V2.3.0.1_20100208/common/rtusb_dev_id.c: {USB_DEVICE(0x0DB0,0x3822)}, /* MSI 3070 */
RT3070_LinuxSTA_V2.3.0.1_20100208/common/rtusb_dev_id.c: {USB_DEVICE(0x0DB0,0x3821)}, /* Ralink 3070 */
RT3070_LinuxSTA_V2.3.0.1_20100208/common/rtusb_dev_id.c: {USB_DEVICE(0x0DB0,0x3870)}, /* MSI 3070*/
RT3070_LinuxSTA_V2.3.0.1_20100208/common/rtusb_dev_id.c: {USB_DEVICE(0x0DB0,0x3871)}, /* MSI 3070 */
RT3070_LinuxSTA_V2.3.0.1_20100208/common/rtusb_dev_id.c: {USB_DEVICE(0x0DB0,0x821A)}, /* Ralink 3070 */
RT3070_LinuxSTA_V2.3.0.1_20100208/common/rtusb_dev_id.c: {USB_DEVICE(0x0DB0,0x822A)}, /* MSI 3070 */
RT3070_LinuxSTA_V2.3.0.1_20100208/common/rtusb_dev_id.c: {USB_DEVICE(0x0DB0,0x870A)}, /* MSI 3070*/
RT3070_LinuxSTA_V2.3.0.1_20100208/common/rtusb_dev_id.c: {USB_DEVICE(0x0DB0,0x871A)}, /* MSI 3070 */
RT3070_LinuxSTA_V2.3.0.1_20100208/common/rtusb_dev_id.c: {USB_DEVICE(0x0DB0,0x899A)}, /* MSI 3070*/
RT3070_LinuxSTA_V2.3.0.1_20100208/common/rtusb_dev_id.c: {USB_DEVICE(0x20B8,0x8888)}, /* PARA INDUSTRIAL 3070 */
RT3070_LinuxSTA_V2.3.0.1_20100208/common/rtusb_dev_id.c: {USB_DEVICE(0x0DF6,0x0048)}, /* Sitecom 3070 */
RT3070_LinuxSTA_V2.3.0.1_20100208/common/rtusb_dev_id.c: {USB_DEVICE(0x0DF6,0x0047)}, /* Sitecom 3071 */
RT3070_LinuxSTA_V2.3.0.1_20100208/common/rtusb_dev_id.c: {USB_DEVICE(0x083A,0xA701)}, /* SMC 3070 */
RT3070_LinuxSTA_V2.3.0.1_20100208/common/rtusb_dev_id.c: {USB_DEVICE(0x083A,0xA702)}, /* SMC 3072 */
Signed-off-by: Xose Vazquez Perez <xose.vazquez@gmail.com>
Acked-by: Ivo van Doorn <IvDoorn@gmail.com>
Acked-by: Gertjan van Wingerde <gwingerde@gmail.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
2010-03-28 15:52:43 +02:00
/* Para */
2011-04-18 15:32:13 +02:00
{ USB_DEVICE ( 0x20b8 , 0x8888 ) } ,
2010-02-14 12:52:05 +01:00
/* Pegatron */
2011-12-28 01:53:18 +01:00
{ USB_DEVICE ( 0x1d4d , 0x0002 ) } ,
2011-04-18 15:32:13 +02:00
{ USB_DEVICE ( 0x1d4d , 0x000c ) } ,
{ USB_DEVICE ( 0x1d4d , 0x000e ) } ,
{ USB_DEVICE ( 0x1d4d , 0x0011 ) } ,
2010-11-13 19:10:31 +01:00
/* Philips */
2011-04-18 15:32:13 +02:00
{ USB_DEVICE ( 0x0471 , 0x200f ) } ,
2010-02-14 12:52:05 +01:00
/* Planex */
2011-04-18 15:32:13 +02:00
{ USB_DEVICE ( 0x2019 , 0xab25 ) } ,
{ USB_DEVICE ( 0x2019 , 0xed06 ) } ,
2010-02-14 12:52:05 +01:00
/* Quanta */
2011-04-18 15:32:13 +02:00
{ USB_DEVICE ( 0x1a32 , 0x0304 ) } ,
2010-02-14 12:52:05 +01:00
/* Ralink */
2011-04-18 15:32:13 +02:00
{ USB_DEVICE ( 0x148f , 0x2070 ) } ,
{ USB_DEVICE ( 0x148f , 0x2770 ) } ,
{ USB_DEVICE ( 0x148f , 0x2870 ) } ,
{ USB_DEVICE ( 0x148f , 0x3070 ) } ,
{ USB_DEVICE ( 0x148f , 0x3071 ) } ,
{ USB_DEVICE ( 0x148f , 0x3072 ) } ,
2010-11-13 19:10:31 +01:00
/* Samsung */
2011-04-18 15:32:13 +02:00
{ USB_DEVICE ( 0x04e8 , 0x2018 ) } ,
2010-11-13 19:10:31 +01:00
/* Siemens */
2011-04-18 15:32:13 +02:00
{ USB_DEVICE ( 0x129b , 0x1828 ) } ,
2010-02-14 12:52:05 +01:00
/* Sitecom */
2011-04-18 15:32:13 +02:00
{ USB_DEVICE ( 0x0df6 , 0x0017 ) } ,
{ USB_DEVICE ( 0x0df6 , 0x002b ) } ,
{ USB_DEVICE ( 0x0df6 , 0x002c ) } ,
{ USB_DEVICE ( 0x0df6 , 0x002d ) } ,
{ USB_DEVICE ( 0x0df6 , 0x0039 ) } ,
{ USB_DEVICE ( 0x0df6 , 0x003b ) } ,
{ USB_DEVICE ( 0x0df6 , 0x003d ) } ,
{ USB_DEVICE ( 0x0df6 , 0x003e ) } ,
{ USB_DEVICE ( 0x0df6 , 0x003f ) } ,
{ USB_DEVICE ( 0x0df6 , 0x0040 ) } ,
{ USB_DEVICE ( 0x0df6 , 0x0042 ) } ,
{ USB_DEVICE ( 0x0df6 , 0x0047 ) } ,
{ USB_DEVICE ( 0x0df6 , 0x0048 ) } ,
2011-04-18 15:32:33 +02:00
{ USB_DEVICE ( 0x0df6 , 0x0051 ) } ,
{ USB_DEVICE ( 0x0df6 , 0x005f ) } ,
2011-07-06 22:59:19 +02:00
{ USB_DEVICE ( 0x0df6 , 0x0060 ) } ,
2010-02-14 12:52:05 +01:00
/* SMC */
2011-04-18 15:32:13 +02:00
{ USB_DEVICE ( 0x083a , 0x6618 ) } ,
{ USB_DEVICE ( 0x083a , 0x7511 ) } ,
{ USB_DEVICE ( 0x083a , 0x7512 ) } ,
{ USB_DEVICE ( 0x083a , 0x7522 ) } ,
{ USB_DEVICE ( 0x083a , 0x8522 ) } ,
{ USB_DEVICE ( 0x083a , 0xa618 ) } ,
{ USB_DEVICE ( 0x083a , 0xa701 ) } ,
{ USB_DEVICE ( 0x083a , 0xa702 ) } ,
{ USB_DEVICE ( 0x083a , 0xa703 ) } ,
{ USB_DEVICE ( 0x083a , 0xb522 ) } ,
2010-11-13 19:10:31 +01:00
/* Sparklan */
2011-04-18 15:32:13 +02:00
{ USB_DEVICE ( 0x15a9 , 0x0006 ) } ,
2010-11-13 19:10:31 +01:00
/* Sweex */
2011-12-28 01:53:18 +01:00
{ USB_DEVICE ( 0x177f , 0x0153 ) } ,
2011-04-18 15:32:13 +02:00
{ USB_DEVICE ( 0x177f , 0x0302 ) } ,
2011-12-28 01:53:18 +01:00
{ USB_DEVICE ( 0x177f , 0x0313 ) } ,
2011-04-12 00:19:10 -04:00
/* U-Media */
2011-04-18 15:32:13 +02:00
{ USB_DEVICE ( 0x157e , 0x300e ) } ,
{ USB_DEVICE ( 0x157e , 0x3013 ) } ,
2010-11-13 19:10:31 +01:00
/* ZCOM */
2011-04-18 15:32:13 +02:00
{ USB_DEVICE ( 0x0cde , 0x0022 ) } ,
{ USB_DEVICE ( 0x0cde , 0x0025 ) } ,
2010-02-14 12:52:05 +01:00
/* Zinwell */
2011-04-18 15:32:13 +02:00
{ USB_DEVICE ( 0x5a57 , 0x0280 ) } ,
{ USB_DEVICE ( 0x5a57 , 0x0282 ) } ,
{ USB_DEVICE ( 0x5a57 , 0x0283 ) } ,
{ USB_DEVICE ( 0x5a57 , 0x5257 ) } ,
2010-11-13 19:10:31 +01:00
/* Zyxel */
2011-04-18 15:32:13 +02:00
{ USB_DEVICE ( 0x0586 , 0x3416 ) } ,
{ USB_DEVICE ( 0x0586 , 0x3418 ) } ,
{ USB_DEVICE ( 0x0586 , 0x341e ) } ,
2011-04-18 15:32:33 +02:00
{ USB_DEVICE ( 0x0586 , 0x343e ) } ,
2010-11-13 19:09:50 +01:00
# ifdef CONFIG_RT2800USB_RT33XX
2011-07-10 17:05:14 +02:00
/* Belkin */
{ USB_DEVICE ( 0x050d , 0x945b ) } ,
2010-11-13 19:09:50 +01:00
/* Ralink */
2011-04-18 15:32:13 +02:00
{ USB_DEVICE ( 0x148f , 0x3370 ) } ,
{ USB_DEVICE ( 0x148f , 0x8070 ) } ,
2010-11-13 19:09:50 +01:00
/* Sitecom */
2011-04-18 15:32:13 +02:00
{ USB_DEVICE ( 0x0df6 , 0x0050 ) } ,
2010-11-13 19:09:50 +01:00
# endif
2010-02-14 12:52:05 +01:00
# ifdef CONFIG_RT2800USB_RT35XX
2010-04-19 11:54:16 +02:00
/* Allwin */
2011-04-18 15:32:13 +02:00
{ USB_DEVICE ( 0x8516 , 0x3572 ) } ,
2010-02-14 12:52:05 +01:00
/* Askey */
2011-04-18 15:32:13 +02:00
{ USB_DEVICE ( 0x1690 , 0x0744 ) } ,
2010-02-14 12:52:05 +01:00
/* Cisco */
2011-04-18 15:32:13 +02:00
{ USB_DEVICE ( 0x167b , 0x4001 ) } ,
2010-02-14 12:52:05 +01:00
/* EnGenius */
2011-04-18 15:32:13 +02:00
{ USB_DEVICE ( 0x1740 , 0x9801 ) } ,
2010-02-14 12:52:05 +01:00
/* I-O DATA */
2011-04-18 15:32:13 +02:00
{ USB_DEVICE ( 0x04bb , 0x0944 ) } ,
2011-04-12 00:19:10 -04:00
/* Linksys */
2011-04-18 15:32:13 +02:00
{ USB_DEVICE ( 0x13b1 , 0x002f ) } ,
{ USB_DEVICE ( 0x1737 , 0x0079 ) } ,
2010-02-14 12:52:05 +01:00
/* Ralink */
2011-04-18 15:32:13 +02:00
{ USB_DEVICE ( 0x148f , 0x3572 ) } ,
2010-02-14 12:52:05 +01:00
/* Sitecom */
2011-04-18 15:32:13 +02:00
{ USB_DEVICE ( 0x0df6 , 0x0041 ) } ,
2011-07-06 22:59:19 +02:00
{ USB_DEVICE ( 0x0df6 , 0x0062 ) } ,
2011-03-27 20:33:06 +02:00
/* Toshiba */
2011-04-18 15:32:13 +02:00
{ USB_DEVICE ( 0x0930 , 0x0a07 ) } ,
2010-02-14 12:52:05 +01:00
/* Zinwell */
2011-04-18 15:32:13 +02:00
{ USB_DEVICE ( 0x5a57 , 0x0284 ) } ,
2010-02-14 12:52:05 +01:00
# endif
2011-05-04 21:41:36 +02:00
# ifdef CONFIG_RT2800USB_RT53XX
2012-02-17 17:33:06 +08:00
/* Alpha */
{ USB_DEVICE ( 0x2001 , 0x3c15 ) } ,
{ USB_DEVICE ( 0x2001 , 0x3c19 ) } ,
/* Arcadyan */
{ USB_DEVICE ( 0x043e , 0x7a12 ) } ,
2011-05-04 21:41:36 +02:00
/* Azurewave */
{ USB_DEVICE ( 0x13d3 , 0x3329 ) } ,
{ USB_DEVICE ( 0x13d3 , 0x3365 ) } ,
2012-02-17 17:33:06 +08:00
/* LG innotek */
{ USB_DEVICE ( 0x043e , 0x7a22 ) } ,
/* Panasonic */
{ USB_DEVICE ( 0x04da , 0x1801 ) } ,
{ USB_DEVICE ( 0x04da , 0x1800 ) } ,
/* Philips */
{ USB_DEVICE ( 0x0471 , 0x2104 ) } ,
2011-05-04 21:41:36 +02:00
/* Ralink */
{ USB_DEVICE ( 0x148f , 0x5370 ) } ,
{ USB_DEVICE ( 0x148f , 0x5372 ) } ,
2012-02-17 17:33:06 +08:00
/* Unknown */
{ USB_DEVICE ( 0x04da , 0x23f6 ) } ,
2011-05-04 21:41:36 +02:00
# endif
2010-02-14 12:52:05 +01:00
# ifdef CONFIG_RT2800USB_UNKNOWN
/*
* Unclear what kind of devices these are ( they aren ' t supported by the
2010-05-03 13:11:38 +02:00
* vendor linux driver ) .
2010-02-14 12:52:05 +01:00
*/
2011-04-18 15:32:33 +02:00
/* Abocom */
{ USB_DEVICE ( 0x07b8 , 0x3073 ) } ,
{ USB_DEVICE ( 0x07b8 , 0x3074 ) } ,
2011-04-12 00:19:10 -04:00
/* Alpha Networks */
2011-04-18 15:32:13 +02:00
{ USB_DEVICE ( 0x14b2 , 0x3c08 ) } ,
{ USB_DEVICE ( 0x14b2 , 0x3c11 ) } ,
2010-02-14 12:52:05 +01:00
/* Amigo */
2011-04-18 15:32:13 +02:00
{ USB_DEVICE ( 0x0e0b , 0x9031 ) } ,
{ USB_DEVICE ( 0x0e0b , 0x9041 ) } ,
2010-02-14 12:52:05 +01:00
/* ASUS */
2011-04-18 15:32:33 +02:00
{ USB_DEVICE ( 0x0b05 , 0x166a ) } ,
2011-04-18 15:32:13 +02:00
{ USB_DEVICE ( 0x0b05 , 0x1760 ) } ,
{ USB_DEVICE ( 0x0b05 , 0x1761 ) } ,
{ USB_DEVICE ( 0x0b05 , 0x1790 ) } ,
2011-04-18 15:32:33 +02:00
{ USB_DEVICE ( 0x0b05 , 0x179d ) } ,
2010-02-14 12:52:05 +01:00
/* AzureWave */
2011-04-18 15:32:13 +02:00
{ USB_DEVICE ( 0x13d3 , 0x3262 ) } ,
{ USB_DEVICE ( 0x13d3 , 0x3284 ) } ,
{ USB_DEVICE ( 0x13d3 , 0x3322 ) } ,
2010-02-14 12:52:05 +01:00
/* Belkin */
2011-04-18 15:32:33 +02:00
{ USB_DEVICE ( 0x050d , 0x1003 ) } ,
2010-02-14 12:52:05 +01:00
/* Buffalo */
2011-04-18 15:32:13 +02:00
{ USB_DEVICE ( 0x0411 , 0x012e ) } ,
{ USB_DEVICE ( 0x0411 , 0x0148 ) } ,
{ USB_DEVICE ( 0x0411 , 0x0150 ) } ,
2010-02-14 12:52:05 +01:00
/* Corega */
2011-04-18 15:32:13 +02:00
{ USB_DEVICE ( 0x07aa , 0x0041 ) } ,
{ USB_DEVICE ( 0x07aa , 0x0042 ) } ,
{ USB_DEVICE ( 0x18c5 , 0x0008 ) } ,
2010-02-14 12:52:05 +01:00
/* D-Link */
2011-04-18 15:32:13 +02:00
{ USB_DEVICE ( 0x07d1 , 0x3c0b ) } ,
{ USB_DEVICE ( 0x07d1 , 0x3c17 ) } ,
2011-04-18 15:32:33 +02:00
{ USB_DEVICE ( 0x2001 , 0x3c17 ) } ,
2011-03-16 17:12:17 +03:00
/* Edimax */
2011-04-18 15:32:13 +02:00
{ USB_DEVICE ( 0x7392 , 0x4085 ) } ,
2010-02-14 12:52:05 +01:00
/* Encore */
2011-04-18 15:32:13 +02:00
{ USB_DEVICE ( 0x203d , 0x14a1 ) } ,
2011-12-19 21:07:33 +00:00
/* Fujitsu Stylistic 550 */
{ USB_DEVICE ( 0x1690 , 0x0761 ) } ,
2009-04-26 15:47:48 +02:00
/* Gemtek */
2011-04-18 15:32:13 +02:00
{ USB_DEVICE ( 0x15a9 , 0x0010 ) } ,
2009-04-26 15:47:48 +02:00
/* Gigabyte */
2011-04-18 15:32:13 +02:00
{ USB_DEVICE ( 0x1044 , 0x800c ) } ,
2011-04-18 15:32:33 +02:00
/* Huawei */
{ USB_DEVICE ( 0x148f , 0xf101 ) } ,
/* I-O DATA */
{ USB_DEVICE ( 0x04bb , 0x094b ) } ,
2009-04-26 15:47:48 +02:00
/* LevelOne */
2011-04-18 15:32:13 +02:00
{ USB_DEVICE ( 0x1740 , 0x0605 ) } ,
{ USB_DEVICE ( 0x1740 , 0x0615 ) } ,
2011-04-18 15:32:33 +02:00
/* Logitec */
{ USB_DEVICE ( 0x0789 , 0x0168 ) } ,
{ USB_DEVICE ( 0x0789 , 0x0169 ) } ,
2009-04-26 15:47:48 +02:00
/* Motorola */
2011-04-18 15:32:13 +02:00
{ USB_DEVICE ( 0x100d , 0x9032 ) } ,
2009-04-26 15:47:48 +02:00
/* Pegatron */
2011-04-18 15:32:13 +02:00
{ USB_DEVICE ( 0x05a6 , 0x0101 ) } ,
{ USB_DEVICE ( 0x1d4d , 0x0010 ) } ,
2009-04-26 15:47:48 +02:00
/* Planex */
2011-04-18 15:32:13 +02:00
{ USB_DEVICE ( 0x2019 , 0x5201 ) } ,
{ USB_DEVICE ( 0x2019 , 0xab24 ) } ,
2009-04-26 15:47:48 +02:00
/* Qcom */
2011-04-18 15:32:13 +02:00
{ USB_DEVICE ( 0x18e8 , 0x6259 ) } ,
2011-04-18 15:32:33 +02:00
/* RadioShack */
{ USB_DEVICE ( 0x08b9 , 0x1197 ) } ,
/* Sitecom */
{ USB_DEVICE ( 0x0df6 , 0x003c ) } ,
{ USB_DEVICE ( 0x0df6 , 0x004a ) } ,
{ USB_DEVICE ( 0x0df6 , 0x004d ) } ,
{ USB_DEVICE ( 0x0df6 , 0x0053 ) } ,
2009-04-26 15:47:48 +02:00
/* SMC */
2011-04-18 15:32:13 +02:00
{ USB_DEVICE ( 0x083a , 0xa512 ) } ,
{ USB_DEVICE ( 0x083a , 0xc522 ) } ,
{ USB_DEVICE ( 0x083a , 0xd522 ) } ,
{ USB_DEVICE ( 0x083a , 0xf511 ) } ,
2009-04-26 15:47:48 +02:00
/* Zyxel */
2011-04-18 15:32:13 +02:00
{ USB_DEVICE ( 0x0586 , 0x341a ) } ,
2010-02-14 12:52:05 +01:00
# endif
2009-04-26 15:47:48 +02:00
{ 0 , }
} ;
MODULE_AUTHOR ( DRV_PROJECT ) ;
MODULE_VERSION ( DRV_VERSION ) ;
MODULE_DESCRIPTION ( " Ralink RT2800 USB Wireless LAN driver. " ) ;
MODULE_SUPPORTED_DEVICE ( " Ralink RT2870 USB chipset based cards " ) ;
MODULE_DEVICE_TABLE ( usb , rt2800usb_device_table ) ;
MODULE_FIRMWARE ( FIRMWARE_RT2870 ) ;
MODULE_LICENSE ( " GPL " ) ;
2011-04-18 15:32:13 +02:00
static int rt2800usb_probe ( struct usb_interface * usb_intf ,
const struct usb_device_id * id )
{
return rt2x00usb_probe ( usb_intf , & rt2800usb_ops ) ;
}
2009-04-26 15:47:48 +02:00
static struct usb_driver rt2800usb_driver = {
. name = KBUILD_MODNAME ,
. id_table = rt2800usb_device_table ,
2011-04-18 15:32:13 +02:00
. probe = rt2800usb_probe ,
2009-04-26 15:47:48 +02:00
. disconnect = rt2x00usb_disconnect ,
. suspend = rt2x00usb_suspend ,
. resume = rt2x00usb_resume ,
} ;
2011-11-18 09:44:20 -08:00
module_usb_driver ( rt2800usb_driver ) ;