diff options
Diffstat (limited to 'drivers/net/wireless/rt2x00/rt73usb.c')
| -rw-r--r-- | drivers/net/wireless/rt2x00/rt73usb.c | 487 | 
1 files changed, 280 insertions, 207 deletions
diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c index 6f04552f581..95724ff9c72 100644 --- a/drivers/net/wireless/rt2x00/rt73usb.c +++ b/drivers/net/wireless/rt2x00/rt73usb.c @@ -13,9 +13,7 @@  	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. +	along with this program; if not, see <http://www.gnu.org/licenses/>.   */  /* @@ -27,7 +25,6 @@  #include <linux/crc-itu-t.h>  #include <linux/delay.h>  #include <linux/etherdevice.h> -#include <linux/init.h>  #include <linux/kernel.h>  #include <linux/module.h>  #include <linux/slab.h> @@ -40,7 +37,7 @@  /*   * Allow hardware encryption to be disabled.   */ -static int modparam_nohwcrypt; +static bool modparam_nohwcrypt;  module_param_named(nohwcrypt, modparam_nohwcrypt, bool, S_IRUGO);  MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption."); @@ -189,7 +186,7 @@ static int rt73usb_rfkill_poll(struct rt2x00_dev *rt2x00dev)  	u32 reg;  	rt2x00usb_register_read(rt2x00dev, MAC_CSR13, ®); -	return rt2x00_get_field32(reg, MAC_CSR13_BIT7); +	return rt2x00_get_field32(reg, MAC_CSR13_VAL7);  }  #ifdef CONFIG_RT2X00_LIB_LEDS @@ -502,26 +499,14 @@ static void rt73usb_config_intf(struct rt2x00_dev *rt2x00dev,  				struct rt2x00intf_conf *conf,  				const unsigned int flags)  { -	unsigned int beacon_base;  	u32 reg;  	if (flags & CONFIG_UPDATE_TYPE) {  		/* -		 * Clear current synchronisation setup. -		 * For the Beacon base registers we only need to clear -		 * the first byte since that byte contains the VALID and OWNER -		 * bits which (when set to 0) will invalidate the entire beacon. -		 */ -		beacon_base = HW_BEACON_OFFSET(intf->beacon->entry_idx); -		rt2x00usb_register_write(rt2x00dev, beacon_base, 0); - -		/*  		 * Enable synchronisation.  		 */  		rt2x00usb_register_read(rt2x00dev, TXRX_CSR9, ®); -		rt2x00_set_field32(®, TXRX_CSR9_TSF_TICKING, 1);  		rt2x00_set_field32(®, TXRX_CSR9_TSF_SYNC, conf->sync); -		rt2x00_set_field32(®, TXRX_CSR9_TBTT_ENABLE, 1);  		rt2x00usb_register_write(rt2x00dev, TXRX_CSR9, reg);  	} @@ -607,8 +592,8 @@ static void rt73usb_config_antenna_5x(struct rt2x00_dev *rt2x00dev,  	switch (ant->rx) {  	case ANTENNA_HW_DIVERSITY:  		rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA_CONTROL, 2); -		temp = !test_bit(CONFIG_FRAME_TYPE, &rt2x00dev->flags) -		       && (rt2x00dev->curr_band != IEEE80211_BAND_5GHZ); +		temp = !rt2x00_has_cap_frame_type(rt2x00dev) && +		       (rt2x00dev->curr_band != IEEE80211_BAND_5GHZ);  		rt2x00_set_field8(&r4, BBP_R4_RX_FRAME_END, temp);  		break;  	case ANTENNA_A: @@ -648,7 +633,7 @@ static void rt73usb_config_antenna_2x(struct rt2x00_dev *rt2x00dev,  	rt2x00_set_field8(&r3, BBP_R3_SMART_MODE, 0);  	rt2x00_set_field8(&r4, BBP_R4_RX_FRAME_END, -			  !test_bit(CONFIG_FRAME_TYPE, &rt2x00dev->flags)); +			  !rt2x00_has_cap_frame_type(rt2x00dev));  	/*  	 * Configure the RX antenna. @@ -721,10 +706,10 @@ static void rt73usb_config_ant(struct rt2x00_dev *rt2x00dev,  	if (rt2x00dev->curr_band == IEEE80211_BAND_5GHZ) {  		sel = antenna_sel_a; -		lna = test_bit(CONFIG_EXTERNAL_LNA_A, &rt2x00dev->flags); +		lna = rt2x00_has_cap_external_lna_a(rt2x00dev);  	} else {  		sel = antenna_sel_bg; -		lna = test_bit(CONFIG_EXTERNAL_LNA_BG, &rt2x00dev->flags); +		lna = rt2x00_has_cap_external_lna_bg(rt2x00dev);  	}  	for (i = 0; i < ARRAY_SIZE(antenna_sel_a); i++) @@ -751,8 +736,8 @@ static void rt73usb_config_lna_gain(struct rt2x00_dev *rt2x00dev,  	u16 eeprom;  	short lna_gain = 0; -	if (libconf->conf->channel->band == IEEE80211_BAND_2GHZ) { -		if (test_bit(CONFIG_EXTERNAL_LNA_BG, &rt2x00dev->flags)) +	if (libconf->conf->chandef.chan->band == IEEE80211_BAND_2GHZ) { +		if (rt2x00_has_cap_external_lna_bg(rt2x00dev))  			lna_gain += 14;  		rt2x00_eeprom_read(rt2x00dev, EEPROM_RSSI_OFFSET_BG, &eeprom); @@ -942,7 +927,7 @@ static void rt73usb_link_tuner(struct rt2x00_dev *rt2x00dev,  		low_bound = 0x28;  		up_bound = 0x48; -		if (test_bit(CONFIG_EXTERNAL_LNA_A, &rt2x00dev->flags)) { +		if (rt2x00_has_cap_external_lna_a(rt2x00dev)) {  			low_bound += 0x10;  			up_bound += 0x10;  		} @@ -958,7 +943,7 @@ static void rt73usb_link_tuner(struct rt2x00_dev *rt2x00dev,  			up_bound = 0x1c;  		} -		if (test_bit(CONFIG_EXTERNAL_LNA_BG, &rt2x00dev->flags)) { +		if (rt2x00_has_cap_external_lna_bg(rt2x00dev)) {  			low_bound += 0x14;  			up_bound += 0x10;  		} @@ -1031,6 +1016,55 @@ dynamic_cca_tune:  }  /* + * Queue handlers. + */ +static void rt73usb_start_queue(struct data_queue *queue) +{ +	struct rt2x00_dev *rt2x00dev = queue->rt2x00dev; +	u32 reg; + +	switch (queue->qid) { +	case QID_RX: +		rt2x00usb_register_read(rt2x00dev, TXRX_CSR0, ®); +		rt2x00_set_field32(®, TXRX_CSR0_DISABLE_RX, 0); +		rt2x00usb_register_write(rt2x00dev, TXRX_CSR0, reg); +		break; +	case QID_BEACON: +		rt2x00usb_register_read(rt2x00dev, TXRX_CSR9, ®); +		rt2x00_set_field32(®, TXRX_CSR9_TSF_TICKING, 1); +		rt2x00_set_field32(®, TXRX_CSR9_TBTT_ENABLE, 1); +		rt2x00_set_field32(®, TXRX_CSR9_BEACON_GEN, 1); +		rt2x00usb_register_write(rt2x00dev, TXRX_CSR9, reg); +		break; +	default: +		break; +	} +} + +static void rt73usb_stop_queue(struct data_queue *queue) +{ +	struct rt2x00_dev *rt2x00dev = queue->rt2x00dev; +	u32 reg; + +	switch (queue->qid) { +	case QID_RX: +		rt2x00usb_register_read(rt2x00dev, TXRX_CSR0, ®); +		rt2x00_set_field32(®, TXRX_CSR0_DISABLE_RX, 1); +		rt2x00usb_register_write(rt2x00dev, TXRX_CSR0, reg); +		break; +	case QID_BEACON: +		rt2x00usb_register_read(rt2x00dev, TXRX_CSR9, ®); +		rt2x00_set_field32(®, TXRX_CSR9_TSF_TICKING, 0); +		rt2x00_set_field32(®, TXRX_CSR9_TBTT_ENABLE, 0); +		rt2x00_set_field32(®, TXRX_CSR9_BEACON_GEN, 0); +		rt2x00usb_register_write(rt2x00dev, TXRX_CSR9, reg); +		break; +	default: +		break; +	} +} + +/*   * Firmware functions   */  static char *rt73usb_get_firmware_name(struct rt2x00_dev *rt2x00dev) @@ -1085,7 +1119,7 @@ static int rt73usb_load_firmware(struct rt2x00_dev *rt2x00dev,  	}  	if (!reg) { -		ERROR(rt2x00dev, "Unstable hardware.\n"); +		rt2x00_err(rt2x00dev, "Unstable hardware\n");  		return -EBUSY;  	} @@ -1102,7 +1136,7 @@ static int rt73usb_load_firmware(struct rt2x00_dev *rt2x00dev,  					     0, USB_MODE_FIRMWARE,  					     REGISTER_TIMEOUT_FIRMWARE);  	if (status < 0) { -		ERROR(rt2x00dev, "Failed to write Firmware to device.\n"); +		rt2x00_err(rt2x00dev, "Failed to write Firmware to device\n");  		return status;  	} @@ -1268,7 +1302,7 @@ static int rt73usb_wait_bbp_ready(struct rt2x00_dev *rt2x00dev)  		udelay(REGISTER_BUSY_DELAY);  	} -	ERROR(rt2x00dev, "BBP register access failed, aborting.\n"); +	rt2x00_err(rt2x00dev, "BBP register access failed, aborting\n");  	return -EACCES;  } @@ -1324,17 +1358,6 @@ static int rt73usb_init_bbp(struct rt2x00_dev *rt2x00dev)  /*   * Device state switch handlers.   */ -static void rt73usb_toggle_rx(struct rt2x00_dev *rt2x00dev, -			      enum dev_state state) -{ -	u32 reg; - -	rt2x00usb_register_read(rt2x00dev, TXRX_CSR0, ®); -	rt2x00_set_field32(®, TXRX_CSR0_DISABLE_RX, -			   (state == STATE_RADIO_RX_OFF)); -	rt2x00usb_register_write(rt2x00dev, TXRX_CSR0, reg); -} -  static int rt73usb_enable_radio(struct rt2x00_dev *rt2x00dev)  {  	/* @@ -1401,14 +1424,8 @@ static int rt73usb_set_device_state(struct rt2x00_dev *rt2x00dev,  	case STATE_RADIO_OFF:  		rt73usb_disable_radio(rt2x00dev);  		break; -	case STATE_RADIO_RX_ON: -	case STATE_RADIO_RX_OFF: -		rt73usb_toggle_rx(rt2x00dev, state); -		break;  	case STATE_RADIO_IRQ_ON: -	case STATE_RADIO_IRQ_ON_ISR:  	case STATE_RADIO_IRQ_OFF: -	case STATE_RADIO_IRQ_OFF_ISR:  		/* No support, but no error either */  		break;  	case STATE_DEEP_SLEEP: @@ -1423,8 +1440,8 @@ static int rt73usb_set_device_state(struct rt2x00_dev *rt2x00dev,  	}  	if (unlikely(retval)) -		ERROR(rt2x00dev, "Device failed to enter state %d (%d).\n", -		      state, retval); +		rt2x00_err(rt2x00dev, "Device failed to enter state %d (%d)\n", +			   state, retval);  	return retval;  } @@ -1454,7 +1471,7 @@ static void rt73usb_write_tx_desc(struct queue_entry *entry,  			   test_bit(ENTRY_TXD_REQ_TIMESTAMP, &txdesc->flags));  	rt2x00_set_field32(&word, TXD_W0_OFDM,  			   (txdesc->rate_mode == RATE_MODE_OFDM)); -	rt2x00_set_field32(&word, TXD_W0_IFS, txdesc->ifs); +	rt2x00_set_field32(&word, TXD_W0_IFS, txdesc->u.plcp.ifs);  	rt2x00_set_field32(&word, TXD_W0_RETRY_MODE,  			   test_bit(ENTRY_TXD_RETRY_MODE, &txdesc->flags));  	rt2x00_set_field32(&word, TXD_W0_TKIP_MIC, @@ -1479,10 +1496,12 @@ static void rt73usb_write_tx_desc(struct queue_entry *entry,  	rt2x00_desc_write(txd, 1, word);  	rt2x00_desc_read(txd, 2, &word); -	rt2x00_set_field32(&word, TXD_W2_PLCP_SIGNAL, txdesc->signal); -	rt2x00_set_field32(&word, TXD_W2_PLCP_SERVICE, txdesc->service); -	rt2x00_set_field32(&word, TXD_W2_PLCP_LENGTH_LOW, txdesc->length_low); -	rt2x00_set_field32(&word, TXD_W2_PLCP_LENGTH_HIGH, txdesc->length_high); +	rt2x00_set_field32(&word, TXD_W2_PLCP_SIGNAL, txdesc->u.plcp.signal); +	rt2x00_set_field32(&word, TXD_W2_PLCP_SERVICE, txdesc->u.plcp.service); +	rt2x00_set_field32(&word, TXD_W2_PLCP_LENGTH_LOW, +			   txdesc->u.plcp.length_low); +	rt2x00_set_field32(&word, TXD_W2_PLCP_LENGTH_HIGH, +			   txdesc->u.plcp.length_high);  	rt2x00_desc_write(txd, 2, word);  	if (test_bit(ENTRY_TXD_ENCRYPT, &txdesc->flags)) { @@ -1512,13 +1531,15 @@ static void rt73usb_write_beacon(struct queue_entry *entry,  {  	struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;  	unsigned int beacon_base; -	u32 reg; +	unsigned int padding_len; +	u32 orig_reg, reg;  	/*  	 * Disable beaconing while we are reloading the beacon data,  	 * otherwise we might be sending out invalid data.  	 */  	rt2x00usb_register_read(rt2x00dev, TXRX_CSR9, ®); +	orig_reg = reg;  	rt2x00_set_field32(®, TXRX_CSR9_BEACON_GEN, 0);  	rt2x00usb_register_write(rt2x00dev, TXRX_CSR9, reg); @@ -1539,11 +1560,20 @@ static void rt73usb_write_beacon(struct queue_entry *entry,  	rt2x00debug_dump_frame(rt2x00dev, DUMP_FRAME_BEACON, entry->skb);  	/* -	 * Write entire beacon with descriptor to register. +	 * Write entire beacon with descriptor and padding to register.  	 */ +	padding_len = roundup(entry->skb->len, 4) - entry->skb->len; +	if (padding_len && skb_pad(entry->skb, padding_len)) { +		rt2x00_err(rt2x00dev, "Failure padding beacon, aborting\n"); +		/* skb freed by skb_pad() on failure */ +		entry->skb = NULL; +		rt2x00usb_register_write(rt2x00dev, TXRX_CSR9, orig_reg); +		return; +	} +  	beacon_base = HW_BEACON_OFFSET(entry->entry_idx); -	rt2x00usb_register_multiwrite(rt2x00dev, beacon_base, -				      entry->skb->data, entry->skb->len); +	rt2x00usb_register_multiwrite(rt2x00dev, beacon_base, entry->skb->data, +				      entry->skb->len + padding_len);  	/*  	 * Enable beaconing again. @@ -1553,8 +1583,6 @@ static void rt73usb_write_beacon(struct queue_entry *entry,  	 */  	rt2x00usb_register_write(rt2x00dev, TXRX_CSR10, 0x00001008); -	rt2x00_set_field32(®, TXRX_CSR9_TSF_TICKING, 1); -	rt2x00_set_field32(®, TXRX_CSR9_TBTT_ENABLE, 1);  	rt2x00_set_field32(®, TXRX_CSR9_BEACON_GEN, 1);  	rt2x00usb_register_write(rt2x00dev, TXRX_CSR9, reg); @@ -1565,6 +1593,33 @@ static void rt73usb_write_beacon(struct queue_entry *entry,  	entry->skb = NULL;  } +static void rt73usb_clear_beacon(struct queue_entry *entry) +{ +	struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; +	unsigned int beacon_base; +	u32 orig_reg, reg; + +	/* +	 * Disable beaconing while we are reloading the beacon data, +	 * otherwise we might be sending out invalid data. +	 */ +	rt2x00usb_register_read(rt2x00dev, TXRX_CSR9, &orig_reg); +	reg = orig_reg; +	rt2x00_set_field32(®, TXRX_CSR9_BEACON_GEN, 0); +	rt2x00usb_register_write(rt2x00dev, TXRX_CSR9, reg); + +	/* +	 * Clear beacon. +	 */ +	beacon_base = HW_BEACON_OFFSET(entry->entry_idx); +	rt2x00usb_register_write(rt2x00dev, beacon_base, 0); + +	/* +	 * Restore beaconing state. +	 */ +	rt2x00usb_register_write(rt2x00dev, TXRX_CSR9, orig_reg); +} +  static int rt73usb_get_tx_data_len(struct queue_entry *entry)  {  	int length; @@ -1579,14 +1634,6 @@ static int rt73usb_get_tx_data_len(struct queue_entry *entry)  	return length;  } -static void rt73usb_kill_tx_queue(struct data_queue *queue) -{ -	if (queue->qid == QID_BEACON) -		rt2x00usb_register_write(queue->rt2x00dev, TXRX_CSR9, 0); - -	rt2x00usb_kill_tx_queue(queue); -} -  /*   * RX control handlers   */ @@ -1611,7 +1658,7 @@ static int rt73usb_agc_to_rssi(struct rt2x00_dev *rt2x00dev, int rxd_w1)  	}  	if (rt2x00dev->curr_band == IEEE80211_BAND_5GHZ) { -		if (test_bit(CONFIG_EXTERNAL_LNA_A, &rt2x00dev->flags)) { +		if (rt2x00_has_cap_external_lna_a(rt2x00dev)) {  			if (lna == 3 || lna == 2)  				offset += 10;  		} else { @@ -1669,9 +1716,8 @@ static void rt73usb_fill_rxdone(struct queue_entry *entry,  		rxdesc->flags |= RX_FLAG_IV_STRIPPED;  		/* -		 * FIXME: Legacy driver indicates that the frame does -		 * contain the Michael Mic. Unfortunately, in rt2x00 -		 * the MIC seems to be missing completely... +		 * 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; @@ -1721,8 +1767,8 @@ static int rt73usb_validate_eeprom(struct rt2x00_dev *rt2x00dev)  	 */  	mac = rt2x00_eeprom_addr(rt2x00dev, EEPROM_MAC_ADDR_0);  	if (!is_valid_ether_addr(mac)) { -		random_ether_addr(mac); -		EEPROM(rt2x00dev, "MAC: %pM\n", mac); +		eth_random_addr(mac); +		rt2x00_eeprom_dbg(rt2x00dev, "MAC: %pM\n", mac);  	}  	rt2x00_eeprom_read(rt2x00dev, EEPROM_ANTENNA, &word); @@ -1737,14 +1783,14 @@ static int rt73usb_validate_eeprom(struct rt2x00_dev *rt2x00dev)  		rt2x00_set_field16(&word, EEPROM_ANTENNA_HARDWARE_RADIO, 0);  		rt2x00_set_field16(&word, EEPROM_ANTENNA_RF_TYPE, RF5226);  		rt2x00_eeprom_write(rt2x00dev, EEPROM_ANTENNA, word); -		EEPROM(rt2x00dev, "Antenna: 0x%04x\n", word); +		rt2x00_eeprom_dbg(rt2x00dev, "Antenna: 0x%04x\n", word);  	}  	rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC, &word);  	if (word == 0xffff) {  		rt2x00_set_field16(&word, EEPROM_NIC_EXTERNAL_LNA, 0);  		rt2x00_eeprom_write(rt2x00dev, EEPROM_NIC, word); -		EEPROM(rt2x00dev, "NIC: 0x%04x\n", word); +		rt2x00_eeprom_dbg(rt2x00dev, "NIC: 0x%04x\n", word);  	}  	rt2x00_eeprom_read(rt2x00dev, EEPROM_LED, &word); @@ -1760,7 +1806,7 @@ static int rt73usb_validate_eeprom(struct rt2x00_dev *rt2x00dev)  		rt2x00_set_field16(&word, EEPROM_LED_LED_MODE,  				   LED_MODE_DEFAULT);  		rt2x00_eeprom_write(rt2x00dev, EEPROM_LED, word); -		EEPROM(rt2x00dev, "Led: 0x%04x\n", word); +		rt2x00_eeprom_dbg(rt2x00dev, "Led: 0x%04x\n", word);  	}  	rt2x00_eeprom_read(rt2x00dev, EEPROM_FREQ, &word); @@ -1768,7 +1814,7 @@ static int rt73usb_validate_eeprom(struct rt2x00_dev *rt2x00dev)  		rt2x00_set_field16(&word, EEPROM_FREQ_OFFSET, 0);  		rt2x00_set_field16(&word, EEPROM_FREQ_SEQ, 0);  		rt2x00_eeprom_write(rt2x00dev, EEPROM_FREQ, word); -		EEPROM(rt2x00dev, "Freq: 0x%04x\n", word); +		rt2x00_eeprom_dbg(rt2x00dev, "Freq: 0x%04x\n", word);  	}  	rt2x00_eeprom_read(rt2x00dev, EEPROM_RSSI_OFFSET_BG, &word); @@ -1776,7 +1822,7 @@ static int rt73usb_validate_eeprom(struct rt2x00_dev *rt2x00dev)  		rt2x00_set_field16(&word, EEPROM_RSSI_OFFSET_BG_1, 0);  		rt2x00_set_field16(&word, EEPROM_RSSI_OFFSET_BG_2, 0);  		rt2x00_eeprom_write(rt2x00dev, EEPROM_RSSI_OFFSET_BG, word); -		EEPROM(rt2x00dev, "RSSI OFFSET BG: 0x%04x\n", word); +		rt2x00_eeprom_dbg(rt2x00dev, "RSSI OFFSET BG: 0x%04x\n", word);  	} else {  		value = rt2x00_get_field16(word, EEPROM_RSSI_OFFSET_BG_1);  		if (value < -10 || value > 10) @@ -1792,7 +1838,7 @@ static int rt73usb_validate_eeprom(struct rt2x00_dev *rt2x00dev)  		rt2x00_set_field16(&word, EEPROM_RSSI_OFFSET_A_1, 0);  		rt2x00_set_field16(&word, EEPROM_RSSI_OFFSET_A_2, 0);  		rt2x00_eeprom_write(rt2x00dev, EEPROM_RSSI_OFFSET_A, word); -		EEPROM(rt2x00dev, "RSSI OFFSET A: 0x%04x\n", word); +		rt2x00_eeprom_dbg(rt2x00dev, "RSSI OFFSET A: 0x%04x\n", word);  	} else {  		value = rt2x00_get_field16(word, EEPROM_RSSI_OFFSET_A_1);  		if (value < -10 || value > 10) @@ -1826,7 +1872,7 @@ static int rt73usb_init_eeprom(struct rt2x00_dev *rt2x00dev)  			value, rt2x00_get_field32(reg, MAC_CSR0_REVISION));  	if (!rt2x00_rt(rt2x00dev, RT2573) || (rt2x00_rev(rt2x00dev) == 0)) { -		ERROR(rt2x00dev, "Invalid RT chipset detected.\n"); +		rt2x00_err(rt2x00dev, "Invalid RT chipset detected\n");  		return -ENODEV;  	} @@ -1834,7 +1880,7 @@ static int rt73usb_init_eeprom(struct rt2x00_dev *rt2x00dev)  	    !rt2x00_rf(rt2x00dev, RF2528) &&  	    !rt2x00_rf(rt2x00dev, RF5225) &&  	    !rt2x00_rf(rt2x00dev, RF2527)) { -		ERROR(rt2x00dev, "Invalid RF chipset detected.\n"); +		rt2x00_err(rt2x00dev, "Invalid RF chipset detected\n");  		return -ENODEV;  	} @@ -1850,13 +1896,13 @@ static int rt73usb_init_eeprom(struct rt2x00_dev *rt2x00dev)  	 * Read the Frame type.  	 */  	if (rt2x00_get_field16(eeprom, EEPROM_ANTENNA_FRAME_TYPE)) -		__set_bit(CONFIG_FRAME_TYPE, &rt2x00dev->flags); +		__set_bit(CAPABILITY_FRAME_TYPE, &rt2x00dev->cap_flags);  	/*  	 * Detect if this device has an hardware controlled radio.  	 */  	if (rt2x00_get_field16(eeprom, EEPROM_ANTENNA_HARDWARE_RADIO)) -		__set_bit(CONFIG_SUPPORT_HW_BUTTON, &rt2x00dev->flags); +		__set_bit(CAPABILITY_HW_BUTTON, &rt2x00dev->cap_flags);  	/*  	 * Read frequency offset. @@ -1870,8 +1916,8 @@ static int rt73usb_init_eeprom(struct rt2x00_dev *rt2x00dev)  	rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC, &eeprom);  	if (rt2x00_get_field16(eeprom, EEPROM_NIC_EXTERNAL_LNA)) { -		__set_bit(CONFIG_EXTERNAL_LNA_A, &rt2x00dev->flags); -		__set_bit(CONFIG_EXTERNAL_LNA_BG, &rt2x00dev->flags); +		__set_bit(CAPABILITY_EXTERNAL_LNA_A, &rt2x00dev->cap_flags); +		__set_bit(CAPABILITY_EXTERNAL_LNA_BG, &rt2x00dev->cap_flags);  	}  	/* @@ -2118,7 +2164,8 @@ static int rt73usb_probe_hw_mode(struct rt2x00_dev *rt2x00dev)  		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]); +			info[i].default_power1 = +					TXPOWER_FROM_DEV(tx_power[i - 14]);  		}  	} @@ -2128,6 +2175,7 @@ static int rt73usb_probe_hw_mode(struct rt2x00_dev *rt2x00dev)  static int rt73usb_probe_hw(struct rt2x00_dev *rt2x00dev)  {  	int retval; +	u32 reg;  	/*  	 * Allocate eeprom data. @@ -2141,6 +2189,14 @@ static int rt73usb_probe_hw(struct rt2x00_dev *rt2x00dev)  		return retval;  	/* +	 * Enable rfkill polling by setting GPIO direction of the +	 * rfkill switch GPIO pin correctly. +	 */ +	rt2x00usb_register_read(rt2x00dev, MAC_CSR13, ®); +	rt2x00_set_field32(®, MAC_CSR13_DIR7, 0); +	rt2x00usb_register_write(rt2x00dev, MAC_CSR13, reg); + +	/*  	 * Initialize hw specifications.  	 */  	retval = rt73usb_probe_hw_mode(rt2x00dev); @@ -2151,16 +2207,16 @@ static int rt73usb_probe_hw(struct rt2x00_dev *rt2x00dev)  	 * This device has multiple filters for control frames,  	 * but has no a separate filter for PS Poll frames.  	 */ -	__set_bit(DRIVER_SUPPORT_CONTROL_FILTERS, &rt2x00dev->flags); +	__set_bit(CAPABILITY_CONTROL_FILTERS, &rt2x00dev->cap_flags);  	/*  	 * This device requires firmware.  	 */ -	__set_bit(DRIVER_REQUIRE_FIRMWARE, &rt2x00dev->flags); +	__set_bit(REQUIRE_FIRMWARE, &rt2x00dev->cap_flags);  	if (!modparam_nohwcrypt) -		__set_bit(CONFIG_SUPPORT_HW_CRYPTO, &rt2x00dev->flags); -	__set_bit(DRIVER_SUPPORT_LINK_TUNING, &rt2x00dev->flags); -	__set_bit(DRIVER_SUPPORT_WATCHDOG, &rt2x00dev->flags); +		__set_bit(CAPABILITY_HW_CRYPTO, &rt2x00dev->cap_flags); +	__set_bit(CAPABILITY_LINK_TUNING, &rt2x00dev->cap_flags); +	__set_bit(REQUIRE_PS_AUTOWAKE, &rt2x00dev->cap_flags);  	/*  	 * Set the rssi offset. @@ -2173,7 +2229,8 @@ static int rt73usb_probe_hw(struct rt2x00_dev *rt2x00dev)  /*   * IEEE80211 stack callback functions.   */ -static int rt73usb_conf_tx(struct ieee80211_hw *hw, u16 queue_idx, +static int rt73usb_conf_tx(struct ieee80211_hw *hw, +			   struct ieee80211_vif *vif, u16 queue_idx,  			   const struct ieee80211_tx_queue_params *params)  {  	struct rt2x00_dev *rt2x00dev = hw->priv; @@ -2189,7 +2246,7 @@ static int rt73usb_conf_tx(struct ieee80211_hw *hw, u16 queue_idx,  	 * we are free to update the registers based on the value  	 * in the queue parameter.  	 */ -	retval = rt2x00mac_conf_tx(hw, queue_idx, params); +	retval = rt2x00mac_conf_tx(hw, vif, queue_idx, params);  	if (retval)  		return retval; @@ -2200,7 +2257,7 @@ static int rt73usb_conf_tx(struct ieee80211_hw *hw, u16 queue_idx,  	if (queue_idx >= 4)  		return 0; -	queue = rt2x00queue_get_queue(rt2x00dev, queue_idx); +	queue = rt2x00queue_get_tx_queue(rt2x00dev, queue_idx);  	/* Update WMM TXOP register */  	offset = AC_TXOP_CSR0 + (sizeof(u32) * (!!(queue_idx & 2))); @@ -2230,7 +2287,7 @@ static int rt73usb_conf_tx(struct ieee80211_hw *hw, u16 queue_idx,  	return 0;  } -static u64 rt73usb_get_tsf(struct ieee80211_hw *hw) +static u64 rt73usb_get_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif)  {  	struct rt2x00_dev *rt2x00dev = hw->priv;  	u64 tsf; @@ -2262,6 +2319,10 @@ static const struct ieee80211_ops rt73usb_mac80211_ops = {  	.get_tsf		= rt73usb_get_tsf,  	.rfkill_poll		= rt2x00mac_rfkill_poll,  	.flush			= rt2x00mac_flush, +	.set_antenna		= rt2x00mac_set_antenna, +	.get_antenna		= rt2x00mac_get_antenna, +	.get_ringparam		= rt2x00mac_get_ringparam, +	.tx_frames_pending	= rt2x00mac_tx_frames_pending,  };  static const struct rt2x00lib_ops rt73usb_rt2x00_ops = { @@ -2278,11 +2339,14 @@ static const struct rt2x00lib_ops rt73usb_rt2x00_ops = {  	.reset_tuner		= rt73usb_reset_tuner,  	.link_tuner		= rt73usb_link_tuner,  	.watchdog		= rt2x00usb_watchdog, +	.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, -	.kick_tx_queue		= rt2x00usb_kick_tx_queue, -	.kill_tx_queue		= rt73usb_kill_tx_queue,  	.fill_rxdone		= rt73usb_fill_rxdone,  	.config_shared_key	= rt73usb_config_shared_key,  	.config_pairwise_key	= rt73usb_config_pairwise_key, @@ -2293,38 +2357,48 @@ static const struct rt2x00lib_ops rt73usb_rt2x00_ops = {  	.config			= rt73usb_config,  }; -static const struct data_queue_desc rt73usb_queue_rx = { -	.entry_num		= 32, -	.data_size		= DATA_FRAME_SIZE, -	.desc_size		= RXD_DESC_SIZE, -	.priv_size		= sizeof(struct queue_entry_priv_usb), -}; +static void rt73usb_queue_init(struct data_queue *queue) +{ +	switch (queue->qid) { +	case QID_RX: +		queue->limit = 32; +		queue->data_size = DATA_FRAME_SIZE; +		queue->desc_size = RXD_DESC_SIZE; +		queue->priv_size = sizeof(struct queue_entry_priv_usb); +		break; -static const struct data_queue_desc rt73usb_queue_tx = { -	.entry_num		= 32, -	.data_size		= DATA_FRAME_SIZE, -	.desc_size		= TXD_DESC_SIZE, -	.priv_size		= sizeof(struct queue_entry_priv_usb), -}; +	case QID_AC_VO: +	case QID_AC_VI: +	case QID_AC_BE: +	case QID_AC_BK: +		queue->limit = 32; +		queue->data_size = DATA_FRAME_SIZE; +		queue->desc_size = TXD_DESC_SIZE; +		queue->priv_size = sizeof(struct queue_entry_priv_usb); +		break; -static const struct data_queue_desc rt73usb_queue_bcn = { -	.entry_num		= 4, -	.data_size		= MGMT_FRAME_SIZE, -	.desc_size		= TXINFO_SIZE, -	.priv_size		= sizeof(struct queue_entry_priv_usb), -}; +	case QID_BEACON: +		queue->limit = 4; +		queue->data_size = MGMT_FRAME_SIZE; +		queue->desc_size = TXINFO_SIZE; +		queue->priv_size = sizeof(struct queue_entry_priv_usb); +		break; + +	case QID_ATIM: +		/* fallthrough */ +	default: +		BUG(); +		break; +	} +}  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, +	.queue_init		= rt73usb_queue_init,  	.lib			= &rt73usb_rt2x00_ops,  	.hw			= &rt73usb_mac80211_ops,  #ifdef CONFIG_RT2X00_LIB_DEBUGFS @@ -2337,113 +2411,115 @@ static const struct rt2x00_ops rt73usb_ops = {   */  static struct usb_device_id rt73usb_device_table[] = {  	/* AboCom */ -	{ USB_DEVICE(0x07b8, 0xb21b), USB_DEVICE_DATA(&rt73usb_ops) }, -	{ USB_DEVICE(0x07b8, 0xb21c), USB_DEVICE_DATA(&rt73usb_ops) }, -	{ USB_DEVICE(0x07b8, 0xb21d), USB_DEVICE_DATA(&rt73usb_ops) }, -	{ USB_DEVICE(0x07b8, 0xb21e), USB_DEVICE_DATA(&rt73usb_ops) }, -	{ USB_DEVICE(0x07b8, 0xb21f), USB_DEVICE_DATA(&rt73usb_ops) }, +	{ USB_DEVICE(0x07b8, 0xb21b) }, +	{ USB_DEVICE(0x07b8, 0xb21c) }, +	{ USB_DEVICE(0x07b8, 0xb21d) }, +	{ USB_DEVICE(0x07b8, 0xb21e) }, +	{ USB_DEVICE(0x07b8, 0xb21f) },  	/* AL */ -	{ USB_DEVICE(0x14b2, 0x3c10), USB_DEVICE_DATA(&rt73usb_ops) }, +	{ USB_DEVICE(0x14b2, 0x3c10) },  	/* Amigo */ -	{ USB_DEVICE(0x148f, 0x9021), USB_DEVICE_DATA(&rt73usb_ops) }, -	{ USB_DEVICE(0x0eb0, 0x9021), USB_DEVICE_DATA(&rt73usb_ops) }, +	{ USB_DEVICE(0x148f, 0x9021) }, +	{ USB_DEVICE(0x0eb0, 0x9021) },  	/* AMIT  */ -	{ USB_DEVICE(0x18c5, 0x0002), USB_DEVICE_DATA(&rt73usb_ops) }, +	{ USB_DEVICE(0x18c5, 0x0002) },  	/* Askey */ -	{ USB_DEVICE(0x1690, 0x0722), USB_DEVICE_DATA(&rt73usb_ops) }, +	{ USB_DEVICE(0x1690, 0x0722) },  	/* ASUS */ -	{ USB_DEVICE(0x0b05, 0x1723), USB_DEVICE_DATA(&rt73usb_ops) }, -	{ USB_DEVICE(0x0b05, 0x1724), USB_DEVICE_DATA(&rt73usb_ops) }, +	{ USB_DEVICE(0x0b05, 0x1723) }, +	{ USB_DEVICE(0x0b05, 0x1724) },  	/* Belkin */ -	{ USB_DEVICE(0x050d, 0x7050), USB_DEVICE_DATA(&rt73usb_ops) }, -	{ USB_DEVICE(0x050d, 0x705a), USB_DEVICE_DATA(&rt73usb_ops) }, -	{ USB_DEVICE(0x050d, 0x905b), USB_DEVICE_DATA(&rt73usb_ops) }, -	{ USB_DEVICE(0x050d, 0x905c), USB_DEVICE_DATA(&rt73usb_ops) }, +	{ USB_DEVICE(0x050d, 0x7050) },	/* FCC ID: K7SF5D7050B ver. 3.x */ +	{ USB_DEVICE(0x050d, 0x705a) }, +	{ USB_DEVICE(0x050d, 0x905b) }, +	{ USB_DEVICE(0x050d, 0x905c) },  	/* Billionton */ -	{ USB_DEVICE(0x1631, 0xc019), USB_DEVICE_DATA(&rt73usb_ops) }, -	{ USB_DEVICE(0x08dd, 0x0120), USB_DEVICE_DATA(&rt73usb_ops) }, +	{ USB_DEVICE(0x1631, 0xc019) }, +	{ USB_DEVICE(0x08dd, 0x0120) },  	/* Buffalo */ -	{ USB_DEVICE(0x0411, 0x00d8), USB_DEVICE_DATA(&rt73usb_ops) }, -	{ USB_DEVICE(0x0411, 0x00d9), USB_DEVICE_DATA(&rt73usb_ops) }, -	{ USB_DEVICE(0x0411, 0x00f4), USB_DEVICE_DATA(&rt73usb_ops) }, -	{ USB_DEVICE(0x0411, 0x0116), USB_DEVICE_DATA(&rt73usb_ops) }, -	{ USB_DEVICE(0x0411, 0x0119), USB_DEVICE_DATA(&rt73usb_ops) }, -	{ USB_DEVICE(0x0411, 0x0137), USB_DEVICE_DATA(&rt73usb_ops) }, +	{ USB_DEVICE(0x0411, 0x00d8) }, +	{ USB_DEVICE(0x0411, 0x00d9) }, +	{ USB_DEVICE(0x0411, 0x00e6) }, +	{ USB_DEVICE(0x0411, 0x00f4) }, +	{ USB_DEVICE(0x0411, 0x0116) }, +	{ USB_DEVICE(0x0411, 0x0119) }, +	{ USB_DEVICE(0x0411, 0x0137) },  	/* CEIVA */ -	{ USB_DEVICE(0x178d, 0x02be), USB_DEVICE_DATA(&rt73usb_ops) }, +	{ USB_DEVICE(0x178d, 0x02be) },  	/* CNet */ -	{ USB_DEVICE(0x1371, 0x9022), USB_DEVICE_DATA(&rt73usb_ops) }, -	{ USB_DEVICE(0x1371, 0x9032), USB_DEVICE_DATA(&rt73usb_ops) }, +	{ USB_DEVICE(0x1371, 0x9022) }, +	{ USB_DEVICE(0x1371, 0x9032) },  	/* Conceptronic */ -	{ USB_DEVICE(0x14b2, 0x3c22), USB_DEVICE_DATA(&rt73usb_ops) }, +	{ USB_DEVICE(0x14b2, 0x3c22) },  	/* Corega */ -	{ USB_DEVICE(0x07aa, 0x002e), USB_DEVICE_DATA(&rt73usb_ops) }, +	{ USB_DEVICE(0x07aa, 0x002e) },  	/* D-Link */ -	{ USB_DEVICE(0x07d1, 0x3c03), USB_DEVICE_DATA(&rt73usb_ops) }, -	{ USB_DEVICE(0x07d1, 0x3c04), USB_DEVICE_DATA(&rt73usb_ops) }, -	{ USB_DEVICE(0x07d1, 0x3c06), USB_DEVICE_DATA(&rt73usb_ops) }, -	{ USB_DEVICE(0x07d1, 0x3c07), USB_DEVICE_DATA(&rt73usb_ops) }, +	{ USB_DEVICE(0x07d1, 0x3c03) }, +	{ USB_DEVICE(0x07d1, 0x3c04) }, +	{ USB_DEVICE(0x07d1, 0x3c06) }, +	{ USB_DEVICE(0x07d1, 0x3c07) },  	/* Edimax */ -	{ USB_DEVICE(0x7392, 0x7318), USB_DEVICE_DATA(&rt73usb_ops) }, -	{ USB_DEVICE(0x7392, 0x7618), USB_DEVICE_DATA(&rt73usb_ops) }, +	{ USB_DEVICE(0x7392, 0x7318) }, +	{ USB_DEVICE(0x7392, 0x7618) },  	/* EnGenius */ -	{ USB_DEVICE(0x1740, 0x3701), USB_DEVICE_DATA(&rt73usb_ops) }, +	{ USB_DEVICE(0x1740, 0x3701) },  	/* Gemtek */ -	{ USB_DEVICE(0x15a9, 0x0004), USB_DEVICE_DATA(&rt73usb_ops) }, +	{ USB_DEVICE(0x15a9, 0x0004) },  	/* Gigabyte */ -	{ USB_DEVICE(0x1044, 0x8008), USB_DEVICE_DATA(&rt73usb_ops) }, -	{ USB_DEVICE(0x1044, 0x800a), USB_DEVICE_DATA(&rt73usb_ops) }, +	{ USB_DEVICE(0x1044, 0x8008) }, +	{ USB_DEVICE(0x1044, 0x800a) },  	/* Huawei-3Com */ -	{ USB_DEVICE(0x1472, 0x0009), USB_DEVICE_DATA(&rt73usb_ops) }, +	{ USB_DEVICE(0x1472, 0x0009) },  	/* Hercules */ -	{ USB_DEVICE(0x06f8, 0xe002), USB_DEVICE_DATA(&rt73usb_ops) }, -	{ USB_DEVICE(0x06f8, 0xe010), USB_DEVICE_DATA(&rt73usb_ops) }, -	{ USB_DEVICE(0x06f8, 0xe020), USB_DEVICE_DATA(&rt73usb_ops) }, +	{ USB_DEVICE(0x06f8, 0xe002) }, +	{ USB_DEVICE(0x06f8, 0xe010) }, +	{ USB_DEVICE(0x06f8, 0xe020) },  	/* Linksys */ -	{ USB_DEVICE(0x13b1, 0x0020), USB_DEVICE_DATA(&rt73usb_ops) }, -	{ USB_DEVICE(0x13b1, 0x0023), USB_DEVICE_DATA(&rt73usb_ops) }, -	{ USB_DEVICE(0x13b1, 0x0028), USB_DEVICE_DATA(&rt73usb_ops) }, +	{ USB_DEVICE(0x13b1, 0x0020) }, +	{ USB_DEVICE(0x13b1, 0x0023) }, +	{ USB_DEVICE(0x13b1, 0x0028) },  	/* MSI */ -	{ USB_DEVICE(0x0db0, 0x4600), USB_DEVICE_DATA(&rt73usb_ops) }, -	{ USB_DEVICE(0x0db0, 0x6877), USB_DEVICE_DATA(&rt73usb_ops) }, -	{ USB_DEVICE(0x0db0, 0x6874), USB_DEVICE_DATA(&rt73usb_ops) }, -	{ USB_DEVICE(0x0db0, 0xa861), USB_DEVICE_DATA(&rt73usb_ops) }, -	{ USB_DEVICE(0x0db0, 0xa874), USB_DEVICE_DATA(&rt73usb_ops) }, +	{ USB_DEVICE(0x0db0, 0x4600) }, +	{ USB_DEVICE(0x0db0, 0x6877) }, +	{ USB_DEVICE(0x0db0, 0x6874) }, +	{ USB_DEVICE(0x0db0, 0xa861) }, +	{ USB_DEVICE(0x0db0, 0xa874) },  	/* Ovislink */ -	{ USB_DEVICE(0x1b75, 0x7318), USB_DEVICE_DATA(&rt73usb_ops) }, +	{ USB_DEVICE(0x1b75, 0x7318) },  	/* Ralink */ -	{ USB_DEVICE(0x04bb, 0x093d), USB_DEVICE_DATA(&rt73usb_ops) }, -	{ USB_DEVICE(0x148f, 0x2573), USB_DEVICE_DATA(&rt73usb_ops) }, -	{ USB_DEVICE(0x148f, 0x2671), USB_DEVICE_DATA(&rt73usb_ops) }, +	{ USB_DEVICE(0x04bb, 0x093d) }, +	{ USB_DEVICE(0x148f, 0x2573) }, +	{ USB_DEVICE(0x148f, 0x2671) }, +	{ USB_DEVICE(0x0812, 0x3101) },  	/* Qcom */ -	{ USB_DEVICE(0x18e8, 0x6196), USB_DEVICE_DATA(&rt73usb_ops) }, -	{ USB_DEVICE(0x18e8, 0x6229), USB_DEVICE_DATA(&rt73usb_ops) }, -	{ USB_DEVICE(0x18e8, 0x6238), USB_DEVICE_DATA(&rt73usb_ops) }, +	{ USB_DEVICE(0x18e8, 0x6196) }, +	{ USB_DEVICE(0x18e8, 0x6229) }, +	{ USB_DEVICE(0x18e8, 0x6238) },  	/* Samsung */ -	{ USB_DEVICE(0x04e8, 0x4471), USB_DEVICE_DATA(&rt73usb_ops) }, +	{ USB_DEVICE(0x04e8, 0x4471) },  	/* Senao */ -	{ USB_DEVICE(0x1740, 0x7100), USB_DEVICE_DATA(&rt73usb_ops) }, +	{ USB_DEVICE(0x1740, 0x7100) },  	/* Sitecom */ -	{ USB_DEVICE(0x0df6, 0x0024), USB_DEVICE_DATA(&rt73usb_ops) }, -	{ USB_DEVICE(0x0df6, 0x0027), USB_DEVICE_DATA(&rt73usb_ops) }, -	{ USB_DEVICE(0x0df6, 0x002f), USB_DEVICE_DATA(&rt73usb_ops) }, -	{ USB_DEVICE(0x0df6, 0x90ac), USB_DEVICE_DATA(&rt73usb_ops) }, -	{ USB_DEVICE(0x0df6, 0x9712), USB_DEVICE_DATA(&rt73usb_ops) }, +	{ USB_DEVICE(0x0df6, 0x0024) }, +	{ USB_DEVICE(0x0df6, 0x0027) }, +	{ USB_DEVICE(0x0df6, 0x002f) }, +	{ USB_DEVICE(0x0df6, 0x90ac) }, +	{ USB_DEVICE(0x0df6, 0x9712) },  	/* Surecom */ -	{ USB_DEVICE(0x0769, 0x31f3), USB_DEVICE_DATA(&rt73usb_ops) }, +	{ USB_DEVICE(0x0769, 0x31f3) },  	/* Tilgin */ -	{ USB_DEVICE(0x6933, 0x5001), USB_DEVICE_DATA(&rt73usb_ops) }, +	{ USB_DEVICE(0x6933, 0x5001) },  	/* Philips */ -	{ USB_DEVICE(0x0471, 0x200a), USB_DEVICE_DATA(&rt73usb_ops) }, +	{ USB_DEVICE(0x0471, 0x200a) },  	/* Planex */ -	{ USB_DEVICE(0x2019, 0xab01), USB_DEVICE_DATA(&rt73usb_ops) }, -	{ USB_DEVICE(0x2019, 0xab50), USB_DEVICE_DATA(&rt73usb_ops) }, +	{ USB_DEVICE(0x2019, 0xab01) }, +	{ USB_DEVICE(0x2019, 0xab50) },  	/* WideTell */ -	{ USB_DEVICE(0x7167, 0x3840), USB_DEVICE_DATA(&rt73usb_ops) }, +	{ USB_DEVICE(0x7167, 0x3840) },  	/* Zcom */ -	{ USB_DEVICE(0x0cde, 0x001c), USB_DEVICE_DATA(&rt73usb_ops) }, +	{ USB_DEVICE(0x0cde, 0x001c) },  	/* ZyXEL */ -	{ USB_DEVICE(0x0586, 0x3415), USB_DEVICE_DATA(&rt73usb_ops) }, +	{ USB_DEVICE(0x0586, 0x3415) },  	{ 0, }  }; @@ -2455,24 +2531,21 @@ 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 = {  	.name		= KBUILD_MODNAME,  	.id_table	= rt73usb_device_table, -	.probe		= rt2x00usb_probe, +	.probe		= rt73usb_probe,  	.disconnect	= rt2x00usb_disconnect,  	.suspend	= rt2x00usb_suspend,  	.resume		= rt2x00usb_resume, +	.reset_resume	= rt2x00usb_resume, +	.disable_hub_initiated_lpm = 1,  }; -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); +module_usb_driver(rt73usb_driver);  | 
