Newer
Older
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
{ 9, 0x00002c0c, 0x00000796, 0x00068255, 0x000fea0b },
{ 10, 0x00002c0c, 0x00000796, 0x00068255, 0x000fea1f },
{ 11, 0x00002c0c, 0x0000079a, 0x00068255, 0x000fea0b },
{ 12, 0x00002c0c, 0x0000079a, 0x00068255, 0x000fea1f },
{ 13, 0x00002c0c, 0x0000079e, 0x00068255, 0x000fea0b },
{ 14, 0x00002c0c, 0x000007a2, 0x00068255, 0x000fea13 },
/* 802.11 UNI / HyperLan 2 */
{ 36, 0x00002c0c, 0x0000099a, 0x00098255, 0x000fea23 },
{ 40, 0x00002c0c, 0x000009a2, 0x00098255, 0x000fea03 },
{ 44, 0x00002c0c, 0x000009a6, 0x00098255, 0x000fea0b },
{ 48, 0x00002c0c, 0x000009aa, 0x00098255, 0x000fea13 },
{ 52, 0x00002c0c, 0x000009ae, 0x00098255, 0x000fea1b },
{ 56, 0x00002c0c, 0x000009b2, 0x00098255, 0x000fea23 },
{ 60, 0x00002c0c, 0x000009ba, 0x00098255, 0x000fea03 },
{ 64, 0x00002c0c, 0x000009be, 0x00098255, 0x000fea0b },
/* 802.11 HyperLan 2 */
{ 100, 0x00002c0c, 0x00000a2a, 0x000b8255, 0x000fea03 },
{ 104, 0x00002c0c, 0x00000a2e, 0x000b8255, 0x000fea0b },
{ 108, 0x00002c0c, 0x00000a32, 0x000b8255, 0x000fea13 },
{ 112, 0x00002c0c, 0x00000a36, 0x000b8255, 0x000fea1b },
{ 116, 0x00002c0c, 0x00000a3a, 0x000b8255, 0x000fea23 },
{ 120, 0x00002c0c, 0x00000a82, 0x000b8255, 0x000fea03 },
{ 124, 0x00002c0c, 0x00000a86, 0x000b8255, 0x000fea0b },
{ 128, 0x00002c0c, 0x00000a8a, 0x000b8255, 0x000fea13 },
{ 132, 0x00002c0c, 0x00000a8e, 0x000b8255, 0x000fea1b },
{ 136, 0x00002c0c, 0x00000a92, 0x000b8255, 0x000fea23 },
/* 802.11 UNII */
{ 140, 0x00002c0c, 0x00000a9a, 0x000b8255, 0x000fea03 },
{ 149, 0x00002c0c, 0x00000aa2, 0x000b8255, 0x000fea1f },
{ 153, 0x00002c0c, 0x00000aa6, 0x000b8255, 0x000fea27 },
{ 157, 0x00002c0c, 0x00000aae, 0x000b8255, 0x000fea07 },
{ 161, 0x00002c0c, 0x00000ab2, 0x000b8255, 0x000fea0f },
{ 165, 0x00002c0c, 0x00000ab6, 0x000b8255, 0x000fea17 },
/* MMAC(Japan)J52 ch 34,38,42,46 */
{ 34, 0x00002c0c, 0x0008099a, 0x000da255, 0x000d3a0b },
{ 38, 0x00002c0c, 0x0008099e, 0x000da255, 0x000d3a13 },
{ 42, 0x00002c0c, 0x000809a2, 0x000da255, 0x000d3a1b },
{ 46, 0x00002c0c, 0x000809a6, 0x000da255, 0x000d3a23 },
};
/*
* RF value list for RF5225 & RF2527
* Supports: 2.4 GHz & 5.2 GHz
*/
static const struct rf_channel rf_vals_5225_2527[] = {
{ 1, 0x00002ccc, 0x00004786, 0x00068455, 0x000ffa0b },
{ 2, 0x00002ccc, 0x00004786, 0x00068455, 0x000ffa1f },
{ 3, 0x00002ccc, 0x0000478a, 0x00068455, 0x000ffa0b },
{ 4, 0x00002ccc, 0x0000478a, 0x00068455, 0x000ffa1f },
{ 5, 0x00002ccc, 0x0000478e, 0x00068455, 0x000ffa0b },
{ 6, 0x00002ccc, 0x0000478e, 0x00068455, 0x000ffa1f },
{ 7, 0x00002ccc, 0x00004792, 0x00068455, 0x000ffa0b },
{ 8, 0x00002ccc, 0x00004792, 0x00068455, 0x000ffa1f },
{ 9, 0x00002ccc, 0x00004796, 0x00068455, 0x000ffa0b },
{ 10, 0x00002ccc, 0x00004796, 0x00068455, 0x000ffa1f },
{ 11, 0x00002ccc, 0x0000479a, 0x00068455, 0x000ffa0b },
{ 12, 0x00002ccc, 0x0000479a, 0x00068455, 0x000ffa1f },
{ 13, 0x00002ccc, 0x0000479e, 0x00068455, 0x000ffa0b },
{ 14, 0x00002ccc, 0x000047a2, 0x00068455, 0x000ffa13 },
/* 802.11 UNI / HyperLan 2 */
{ 36, 0x00002ccc, 0x0000499a, 0x0009be55, 0x000ffa23 },
{ 40, 0x00002ccc, 0x000049a2, 0x0009be55, 0x000ffa03 },
{ 44, 0x00002ccc, 0x000049a6, 0x0009be55, 0x000ffa0b },
{ 48, 0x00002ccc, 0x000049aa, 0x0009be55, 0x000ffa13 },
{ 52, 0x00002ccc, 0x000049ae, 0x0009ae55, 0x000ffa1b },
{ 56, 0x00002ccc, 0x000049b2, 0x0009ae55, 0x000ffa23 },
{ 60, 0x00002ccc, 0x000049ba, 0x0009ae55, 0x000ffa03 },
{ 64, 0x00002ccc, 0x000049be, 0x0009ae55, 0x000ffa0b },
/* 802.11 HyperLan 2 */
{ 100, 0x00002ccc, 0x00004a2a, 0x000bae55, 0x000ffa03 },
{ 104, 0x00002ccc, 0x00004a2e, 0x000bae55, 0x000ffa0b },
{ 108, 0x00002ccc, 0x00004a32, 0x000bae55, 0x000ffa13 },
{ 112, 0x00002ccc, 0x00004a36, 0x000bae55, 0x000ffa1b },
{ 116, 0x00002ccc, 0x00004a3a, 0x000bbe55, 0x000ffa23 },
{ 120, 0x00002ccc, 0x00004a82, 0x000bbe55, 0x000ffa03 },
{ 124, 0x00002ccc, 0x00004a86, 0x000bbe55, 0x000ffa0b },
{ 128, 0x00002ccc, 0x00004a8a, 0x000bbe55, 0x000ffa13 },
{ 132, 0x00002ccc, 0x00004a8e, 0x000bbe55, 0x000ffa1b },
{ 136, 0x00002ccc, 0x00004a92, 0x000bbe55, 0x000ffa23 },
/* 802.11 UNII */
{ 140, 0x00002ccc, 0x00004a9a, 0x000bbe55, 0x000ffa03 },
{ 149, 0x00002ccc, 0x00004aa2, 0x000bbe55, 0x000ffa1f },
{ 153, 0x00002ccc, 0x00004aa6, 0x000bbe55, 0x000ffa27 },
{ 157, 0x00002ccc, 0x00004aae, 0x000bbe55, 0x000ffa07 },
{ 161, 0x00002ccc, 0x00004ab2, 0x000bbe55, 0x000ffa0f },
{ 165, 0x00002ccc, 0x00004ab6, 0x000bbe55, 0x000ffa17 },
/* MMAC(Japan)J52 ch 34,38,42,46 */
{ 34, 0x00002ccc, 0x0000499a, 0x0009be55, 0x000ffa0b },
{ 38, 0x00002ccc, 0x0000499e, 0x0009be55, 0x000ffa13 },
{ 42, 0x00002ccc, 0x000049a2, 0x0009be55, 0x000ffa1b },
{ 46, 0x00002ccc, 0x000049a6, 0x0009be55, 0x000ffa23 },
};
static int rt73usb_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
{
struct hw_mode_spec *spec = &rt2x00dev->spec;
struct channel_info *info;
char *tx_power;
unsigned int i;
/*
* Initialize all hw fields.
*
* Don't set IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING unless we are
* capable of sending the buffered frames out after the DTIM
* transmission using rt2x00lib_beacondone. This will send out
* multicast and broadcast traffic immediately instead of buffering it
* infinitly and thus dropping it after some time.
*/
rt2x00dev->hw->flags =
IEEE80211_HW_SIGNAL_DBM |
IEEE80211_HW_SUPPORTS_PS |
IEEE80211_HW_PS_NULLFUNC_STACK;
SET_IEEE80211_DEV(rt2x00dev->hw, rt2x00dev->dev);
SET_IEEE80211_PERM_ADDR(rt2x00dev->hw,
rt2x00_eeprom_addr(rt2x00dev,
EEPROM_MAC_ADDR_0));
/*
* Initialize hw_mode information.
*/
spec->supported_bands = SUPPORT_BAND_2GHZ;
spec->supported_rates = SUPPORT_RATE_CCK | SUPPORT_RATE_OFDM;
if (rt2x00_rf(rt2x00dev, RF2528)) {
spec->num_channels = ARRAY_SIZE(rf_vals_bg_2528);
spec->channels = rf_vals_bg_2528;
} else if (rt2x00_rf(rt2x00dev, RF5226)) {
spec->supported_bands |= SUPPORT_BAND_5GHZ;
spec->num_channels = ARRAY_SIZE(rf_vals_5226);
spec->channels = rf_vals_5226;
} else if (rt2x00_rf(rt2x00dev, RF2527)) {
spec->num_channels = 14;
spec->channels = rf_vals_5225_2527;
} else if (rt2x00_rf(rt2x00dev, RF5225)) {
spec->supported_bands |= SUPPORT_BAND_5GHZ;
spec->num_channels = ARRAY_SIZE(rf_vals_5225_2527);
spec->channels = rf_vals_5225_2527;
}
/*
* Create channel information array
*/
info = kcalloc(spec->num_channels, sizeof(*info), GFP_KERNEL);
if (!info)
return -ENOMEM;
spec->channels_info = info;
tx_power = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_G_START);
for (i = 0; i < 14; i++) {
info[i].max_power = MAX_TXPOWER;
info[i].default_power1 = TXPOWER_FROM_DEV(tx_power[i]);
}
if (spec->num_channels > 14) {
tx_power = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_A_START);
for (i = 14; i < spec->num_channels; i++) {
info[i].max_power = MAX_TXPOWER;
info[i].default_power1 = TXPOWER_FROM_DEV(tx_power[i]);
}
}
static int rt73usb_probe_hw(struct rt2x00_dev *rt2x00dev)
{
int retval;
/*
* Allocate eeprom data.
*/
retval = rt73usb_validate_eeprom(rt2x00dev);
if (retval)
return retval;
retval = rt73usb_init_eeprom(rt2x00dev);
if (retval)
return retval;
/*
* Initialize hw specifications.
*/
retval = rt73usb_probe_hw_mode(rt2x00dev);
if (retval)
return retval;
/*
* This device has multiple filters for control frames,
* but has no a separate filter for PS Poll frames.
*/
__set_bit(CAPABILITY_CONTROL_FILTERS, &rt2x00dev->cap_flags);
* This device requires firmware.
__set_bit(REQUIRE_FIRMWARE, &rt2x00dev->cap_flags);
if (!modparam_nohwcrypt)
__set_bit(CAPABILITY_HW_CRYPTO, &rt2x00dev->cap_flags);
__set_bit(CAPABILITY_LINK_TUNING, &rt2x00dev->cap_flags);
/*
* Set the rssi offset.
*/
rt2x00dev->rssi_offset = DEFAULT_RSSI_OFFSET;
return 0;
}
/*
* IEEE80211 stack callback functions.
*/
static int rt73usb_conf_tx(struct ieee80211_hw *hw, u16 queue_idx,
const struct ieee80211_tx_queue_params *params)
{
struct rt2x00_dev *rt2x00dev = hw->priv;
struct data_queue *queue;
struct rt2x00_field32 field;
int retval;
u32 reg;
/*
* First pass the configuration through rt2x00lib, that will
* update the queue settings and validate the input. After that
* we are free to update the registers based on the value
* in the queue parameter.
*/
retval = rt2x00mac_conf_tx(hw, queue_idx, params);
if (retval)
return retval;
/*
* We only need to perform additional register initialization
* for WMM queues/
*/
if (queue_idx >= 4)
return 0;
queue = rt2x00queue_get_tx_queue(rt2x00dev, queue_idx);
/* Update WMM TXOP register */
offset = AC_TXOP_CSR0 + (sizeof(u32) * (!!(queue_idx & 2)));
field.bit_offset = (queue_idx & 1) * 16;
field.bit_mask = 0xffff << field.bit_offset;
rt2x00usb_register_read(rt2x00dev, offset, ®);
rt2x00_set_field32(®, field, queue->txop);
rt2x00usb_register_write(rt2x00dev, offset, reg);
/* Update WMM registers */
field.bit_offset = queue_idx * 4;
field.bit_mask = 0xf << field.bit_offset;
rt2x00usb_register_read(rt2x00dev, AIFSN_CSR, ®);
rt2x00_set_field32(®, field, queue->aifs);
rt2x00usb_register_write(rt2x00dev, AIFSN_CSR, reg);
rt2x00usb_register_read(rt2x00dev, CWMIN_CSR, ®);
rt2x00_set_field32(®, field, queue->cw_min);
rt2x00usb_register_write(rt2x00dev, CWMIN_CSR, reg);
rt2x00usb_register_read(rt2x00dev, CWMAX_CSR, ®);
rt2x00_set_field32(®, field, queue->cw_max);
rt2x00usb_register_write(rt2x00dev, CWMAX_CSR, reg);
return 0;
}
static u64 rt73usb_get_tsf(struct ieee80211_hw *hw)
{
struct rt2x00_dev *rt2x00dev = hw->priv;
u64 tsf;
u32 reg;
rt2x00usb_register_read(rt2x00dev, TXRX_CSR13, ®);
tsf = (u64) rt2x00_get_field32(reg, TXRX_CSR13_HIGH_TSFTIMER) << 32;
rt2x00usb_register_read(rt2x00dev, TXRX_CSR12, ®);
tsf |= rt2x00_get_field32(reg, TXRX_CSR12_LOW_TSFTIMER);
return tsf;
}
static const struct ieee80211_ops rt73usb_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,
.bss_info_changed = rt2x00mac_bss_info_changed,
.conf_tx = rt73usb_conf_tx,
.get_tsf = rt73usb_get_tsf,
.rfkill_poll = rt2x00mac_rfkill_poll,
.set_antenna = rt2x00mac_set_antenna,
.get_antenna = rt2x00mac_get_antenna,
.get_ringparam = rt2x00mac_get_ringparam,
};
static const struct rt2x00lib_ops rt73usb_rt2x00_ops = {
.probe_hw = rt73usb_probe_hw,
.get_firmware_name = rt73usb_get_firmware_name,
.check_firmware = rt73usb_check_firmware,
.load_firmware = rt73usb_load_firmware,
.initialize = rt2x00usb_initialize,
.uninitialize = rt2x00usb_uninitialize,
.clear_entry = rt2x00usb_clear_entry,
.set_device_state = rt73usb_set_device_state,
.rfkill_poll = rt73usb_rfkill_poll,
.link_stats = rt73usb_link_stats,
.reset_tuner = rt73usb_reset_tuner,
.link_tuner = rt73usb_link_tuner,
.start_queue = rt73usb_start_queue,
.kick_queue = rt2x00usb_kick_queue,
.stop_queue = rt73usb_stop_queue,
.flush_queue = rt2x00usb_flush_queue,
.write_tx_desc = rt73usb_write_tx_desc,
.write_beacon = rt73usb_write_beacon,
.clear_beacon = rt73usb_clear_beacon,
.get_tx_data_len = rt73usb_get_tx_data_len,
.fill_rxdone = rt73usb_fill_rxdone,
.config_shared_key = rt73usb_config_shared_key,
.config_pairwise_key = rt73usb_config_pairwise_key,
.config_intf = rt73usb_config_intf,
.config_erp = rt73usb_config_erp,
.config_ant = rt73usb_config_ant,
.config = rt73usb_config,
};
static const struct data_queue_desc rt73usb_queue_rx = {
.data_size = DATA_FRAME_SIZE,
.desc_size = RXD_DESC_SIZE,
.priv_size = sizeof(struct queue_entry_priv_usb),
};
static const struct data_queue_desc rt73usb_queue_tx = {
.data_size = DATA_FRAME_SIZE,
.desc_size = TXD_DESC_SIZE,
.priv_size = sizeof(struct queue_entry_priv_usb),
};
static const struct data_queue_desc rt73usb_queue_bcn = {
.data_size = MGMT_FRAME_SIZE,
.desc_size = TXINFO_SIZE,
.priv_size = sizeof(struct queue_entry_priv_usb),
static const struct rt2x00_ops rt73usb_ops = {
.name = KBUILD_MODNAME,
.max_sta_intf = 1,
.max_ap_intf = 4,
.eeprom_size = EEPROM_SIZE,
.rf_size = RF_SIZE,
.tx_queues = NUM_TX_QUEUES,
.extra_tx_headroom = TXD_DESC_SIZE,
.rx = &rt73usb_queue_rx,
.tx = &rt73usb_queue_tx,
.bcn = &rt73usb_queue_bcn,
.lib = &rt73usb_rt2x00_ops,
.hw = &rt73usb_mac80211_ops,
#ifdef CONFIG_RT2X00_LIB_DEBUGFS
#endif /* CONFIG_RT2X00_LIB_DEBUGFS */
};
/*
* rt73usb module information.
*/
static struct usb_device_id rt73usb_device_table[] = {
/* AboCom */
{ USB_DEVICE(0x07b8, 0xb21b) },
{ USB_DEVICE(0x07b8, 0xb21c) },
{ USB_DEVICE(0x07b8, 0xb21d) },
{ USB_DEVICE(0x07b8, 0xb21e) },
{ USB_DEVICE(0x07b8, 0xb21f) },
{ USB_DEVICE(0x14b2, 0x3c10) },
{ USB_DEVICE(0x148f, 0x9021) },
{ USB_DEVICE(0x0eb0, 0x9021) },
{ USB_DEVICE(0x18c5, 0x0002) },
{ USB_DEVICE(0x1690, 0x0722) },
{ USB_DEVICE(0x0b05, 0x1723) },
{ USB_DEVICE(0x0b05, 0x1724) },
{ USB_DEVICE(0x050d, 0x705a) },
{ USB_DEVICE(0x050d, 0x905b) },
{ USB_DEVICE(0x050d, 0x905c) },
{ USB_DEVICE(0x1631, 0xc019) },
{ USB_DEVICE(0x08dd, 0x0120) },
{ USB_DEVICE(0x0411, 0x00d8) },
{ USB_DEVICE(0x0411, 0x00d9) },
{ USB_DEVICE(0x0411, 0x00f4) },
{ USB_DEVICE(0x0411, 0x0116) },
{ USB_DEVICE(0x0411, 0x0119) },
{ USB_DEVICE(0x0411, 0x0137) },
{ USB_DEVICE(0x178d, 0x02be) },
{ USB_DEVICE(0x1371, 0x9022) },
{ USB_DEVICE(0x1371, 0x9032) },
{ USB_DEVICE(0x14b2, 0x3c22) },
{ USB_DEVICE(0x07aa, 0x002e) },
{ USB_DEVICE(0x07d1, 0x3c03) },
{ USB_DEVICE(0x07d1, 0x3c04) },
{ USB_DEVICE(0x07d1, 0x3c06) },
{ USB_DEVICE(0x07d1, 0x3c07) },
{ USB_DEVICE(0x7392, 0x7318) },
{ USB_DEVICE(0x7392, 0x7618) },
{ USB_DEVICE(0x1740, 0x3701) },
{ USB_DEVICE(0x15a9, 0x0004) },
{ USB_DEVICE(0x1044, 0x8008) },
{ USB_DEVICE(0x1044, 0x800a) },
{ USB_DEVICE(0x1472, 0x0009) },
{ USB_DEVICE(0x06f8, 0xe002) },
{ USB_DEVICE(0x06f8, 0xe010) },
{ USB_DEVICE(0x06f8, 0xe020) },
{ USB_DEVICE(0x13b1, 0x0020) },
{ USB_DEVICE(0x13b1, 0x0023) },
{ USB_DEVICE(0x13b1, 0x0028) },
{ USB_DEVICE(0x0db0, 0x4600) },
{ USB_DEVICE(0x0db0, 0x6877) },
{ USB_DEVICE(0x0db0, 0x6874) },
{ USB_DEVICE(0x0db0, 0xa861) },
{ USB_DEVICE(0x0db0, 0xa874) },
{ USB_DEVICE(0x1b75, 0x7318) },
{ USB_DEVICE(0x04bb, 0x093d) },
{ USB_DEVICE(0x148f, 0x2573) },
{ USB_DEVICE(0x148f, 0x2671) },
{ USB_DEVICE(0x0812, 0x3101) },
{ USB_DEVICE(0x18e8, 0x6196) },
{ USB_DEVICE(0x18e8, 0x6229) },
{ USB_DEVICE(0x18e8, 0x6238) },
{ USB_DEVICE(0x04e8, 0x4471) },
{ USB_DEVICE(0x1740, 0x7100) },
{ USB_DEVICE(0x0df6, 0x0024) },
{ USB_DEVICE(0x0df6, 0x0027) },
{ USB_DEVICE(0x0df6, 0x002f) },
{ USB_DEVICE(0x0df6, 0x90ac) },
{ USB_DEVICE(0x0df6, 0x9712) },
{ USB_DEVICE(0x0769, 0x31f3) },
{ USB_DEVICE(0x6933, 0x5001) },
{ USB_DEVICE(0x0471, 0x200a) },
{ USB_DEVICE(0x2019, 0xab01) },
{ USB_DEVICE(0x2019, 0xab50) },
{ USB_DEVICE(0x7167, 0x3840) },
{ USB_DEVICE(0x0cde, 0x001c) },
{ USB_DEVICE(0x0586, 0x3415) },
{ 0, }
};
MODULE_AUTHOR(DRV_PROJECT);
MODULE_VERSION(DRV_VERSION);
MODULE_DESCRIPTION("Ralink RT73 USB Wireless LAN driver.");
MODULE_SUPPORTED_DEVICE("Ralink RT2571W & RT2671 USB chipset based cards");
MODULE_DEVICE_TABLE(usb, rt73usb_device_table);
MODULE_FIRMWARE(FIRMWARE_RT2571);
MODULE_LICENSE("GPL");
static int rt73usb_probe(struct usb_interface *usb_intf,
const struct usb_device_id *id)
{
return rt2x00usb_probe(usb_intf, &rt73usb_ops);
}
static struct usb_driver rt73usb_driver = {
.id_table = rt73usb_device_table,
.probe = rt73usb_probe,
.disconnect = rt2x00usb_disconnect,
.suspend = rt2x00usb_suspend,
.resume = rt2x00usb_resume,
};
static int __init rt73usb_init(void)
{
return usb_register(&rt73usb_driver);
}
static void __exit rt73usb_exit(void)
{
usb_deregister(&rt73usb_driver);
}
module_init(rt73usb_init);
module_exit(rt73usb_exit);