|
@@ -1,5 +1,5 @@
|
|
/*
|
|
/*
|
|
- Copyright (C) 2004 - 2007 rt2x00 SourceForge Project
|
|
|
|
|
|
+ Copyright (C) 2004 - 2008 rt2x00 SourceForge Project
|
|
<http://rt2x00.serialmonkey.com>
|
|
<http://rt2x00.serialmonkey.com>
|
|
|
|
|
|
This program is free software; you can redistribute it and/or modify
|
|
This program is free software; you can redistribute it and/or modify
|
|
@@ -278,77 +278,122 @@ static const struct rt2x00debug rt73usb_rt2x00debug = {
|
|
};
|
|
};
|
|
#endif /* CONFIG_RT2X00_LIB_DEBUGFS */
|
|
#endif /* CONFIG_RT2X00_LIB_DEBUGFS */
|
|
|
|
|
|
-/*
|
|
|
|
- * Configuration handlers.
|
|
|
|
- */
|
|
|
|
-static void rt73usb_config_mac_addr(struct rt2x00_dev *rt2x00dev, __le32 *mac)
|
|
|
|
|
|
+#ifdef CONFIG_RT73USB_LEDS
|
|
|
|
+static void rt73usb_led_brightness(struct led_classdev *led_cdev,
|
|
|
|
+ enum led_brightness brightness)
|
|
{
|
|
{
|
|
- u32 tmp;
|
|
|
|
|
|
+ struct rt2x00_led *led =
|
|
|
|
+ container_of(led_cdev, struct rt2x00_led, led_dev);
|
|
|
|
+ unsigned int enabled = brightness != LED_OFF;
|
|
|
|
+ unsigned int a_mode =
|
|
|
|
+ (enabled && led->rt2x00dev->curr_band == IEEE80211_BAND_5GHZ);
|
|
|
|
+ unsigned int bg_mode =
|
|
|
|
+ (enabled && led->rt2x00dev->curr_band == IEEE80211_BAND_2GHZ);
|
|
|
|
|
|
- tmp = le32_to_cpu(mac[1]);
|
|
|
|
- rt2x00_set_field32(&tmp, MAC_CSR3_UNICAST_TO_ME_MASK, 0xff);
|
|
|
|
- mac[1] = cpu_to_le32(tmp);
|
|
|
|
|
|
+ if (in_atomic()) {
|
|
|
|
+ NOTICE(led->rt2x00dev,
|
|
|
|
+ "Ignoring LED brightness command for led %d", led->type);
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
|
|
- rt73usb_register_multiwrite(rt2x00dev, MAC_CSR2, mac,
|
|
|
|
- (2 * sizeof(__le32)));
|
|
|
|
|
|
+ if (led->type == LED_TYPE_RADIO) {
|
|
|
|
+ rt2x00_set_field16(&led->rt2x00dev->led_mcu_reg,
|
|
|
|
+ MCU_LEDCS_RADIO_STATUS, enabled);
|
|
|
|
+
|
|
|
|
+ rt2x00usb_vendor_request_sw(led->rt2x00dev, USB_LED_CONTROL,
|
|
|
|
+ 0, led->rt2x00dev->led_mcu_reg,
|
|
|
|
+ REGISTER_TIMEOUT);
|
|
|
|
+ } else if (led->type == LED_TYPE_ASSOC) {
|
|
|
|
+ rt2x00_set_field16(&led->rt2x00dev->led_mcu_reg,
|
|
|
|
+ MCU_LEDCS_LINK_BG_STATUS, bg_mode);
|
|
|
|
+ rt2x00_set_field16(&led->rt2x00dev->led_mcu_reg,
|
|
|
|
+ MCU_LEDCS_LINK_A_STATUS, a_mode);
|
|
|
|
+
|
|
|
|
+ rt2x00usb_vendor_request_sw(led->rt2x00dev, USB_LED_CONTROL,
|
|
|
|
+ 0, led->rt2x00dev->led_mcu_reg,
|
|
|
|
+ REGISTER_TIMEOUT);
|
|
|
|
+ } else if (led->type == LED_TYPE_QUALITY) {
|
|
|
|
+ /*
|
|
|
|
+ * The brightness is divided into 6 levels (0 - 5),
|
|
|
|
+ * this means we need to convert the brightness
|
|
|
|
+ * argument into the matching level within that range.
|
|
|
|
+ */
|
|
|
|
+ rt2x00usb_vendor_request_sw(led->rt2x00dev, USB_LED_CONTROL,
|
|
|
|
+ brightness / (LED_FULL / 6),
|
|
|
|
+ led->rt2x00dev->led_mcu_reg,
|
|
|
|
+ REGISTER_TIMEOUT);
|
|
|
|
+ }
|
|
}
|
|
}
|
|
|
|
+#else
|
|
|
|
+#define rt73usb_led_brightness NULL
|
|
|
|
+#endif /* CONFIG_RT73USB_LEDS */
|
|
|
|
|
|
-static void rt73usb_config_bssid(struct rt2x00_dev *rt2x00dev, __le32 *bssid)
|
|
|
|
|
|
+/*
|
|
|
|
+ * Configuration handlers.
|
|
|
|
+ */
|
|
|
|
+static void rt73usb_config_intf(struct rt2x00_dev *rt2x00dev,
|
|
|
|
+ struct rt2x00_intf *intf,
|
|
|
|
+ struct rt2x00intf_conf *conf,
|
|
|
|
+ const unsigned int flags)
|
|
{
|
|
{
|
|
- u32 tmp;
|
|
|
|
|
|
+ unsigned int beacon_base;
|
|
|
|
+ u32 reg;
|
|
|
|
|
|
- tmp = le32_to_cpu(bssid[1]);
|
|
|
|
- rt2x00_set_field32(&tmp, MAC_CSR5_BSS_ID_MASK, 3);
|
|
|
|
- bssid[1] = cpu_to_le32(tmp);
|
|
|
|
|
|
+ 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);
|
|
|
|
+ rt73usb_register_write(rt2x00dev, TXRX_CSR9, 0);
|
|
|
|
+ rt73usb_register_write(rt2x00dev, beacon_base, 0);
|
|
|
|
|
|
- rt73usb_register_multiwrite(rt2x00dev, MAC_CSR4, bssid,
|
|
|
|
- (2 * sizeof(__le32)));
|
|
|
|
-}
|
|
|
|
|
|
+ /*
|
|
|
|
+ * Enable synchronisation.
|
|
|
|
+ */
|
|
|
|
+ rt73usb_register_read(rt2x00dev, TXRX_CSR9, ®);
|
|
|
|
+ rt2x00_set_field32(®, TXRX_CSR9_TSF_TICKING, 1);
|
|
|
|
+ rt2x00_set_field32(®, TXRX_CSR9_TBTT_ENABLE,
|
|
|
|
+ (conf->sync == TSF_SYNC_BEACON));
|
|
|
|
+ rt2x00_set_field32(®, TXRX_CSR9_BEACON_GEN, 0);
|
|
|
|
+ rt2x00_set_field32(®, TXRX_CSR9_TSF_SYNC, conf->sync);
|
|
|
|
+ rt73usb_register_write(rt2x00dev, TXRX_CSR9, reg);
|
|
|
|
+ }
|
|
|
|
|
|
-static void rt73usb_config_type(struct rt2x00_dev *rt2x00dev, const int type,
|
|
|
|
- const int tsf_sync)
|
|
|
|
-{
|
|
|
|
- u32 reg;
|
|
|
|
|
|
+ if (flags & CONFIG_UPDATE_MAC) {
|
|
|
|
+ reg = le32_to_cpu(conf->mac[1]);
|
|
|
|
+ rt2x00_set_field32(®, MAC_CSR3_UNICAST_TO_ME_MASK, 0xff);
|
|
|
|
+ conf->mac[1] = cpu_to_le32(reg);
|
|
|
|
|
|
- /*
|
|
|
|
- * 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.
|
|
|
|
- */
|
|
|
|
- rt73usb_register_write(rt2x00dev, TXRX_CSR9, 0);
|
|
|
|
- rt73usb_register_write(rt2x00dev, HW_BEACON_BASE0, 0);
|
|
|
|
- rt73usb_register_write(rt2x00dev, HW_BEACON_BASE1, 0);
|
|
|
|
- rt73usb_register_write(rt2x00dev, HW_BEACON_BASE2, 0);
|
|
|
|
- rt73usb_register_write(rt2x00dev, HW_BEACON_BASE3, 0);
|
|
|
|
|
|
+ rt73usb_register_multiwrite(rt2x00dev, MAC_CSR2,
|
|
|
|
+ conf->mac, sizeof(conf->mac));
|
|
|
|
+ }
|
|
|
|
|
|
- /*
|
|
|
|
- * Enable synchronisation.
|
|
|
|
- */
|
|
|
|
- rt73usb_register_read(rt2x00dev, TXRX_CSR9, ®);
|
|
|
|
- rt2x00_set_field32(®, TXRX_CSR9_TSF_TICKING, 1);
|
|
|
|
- rt2x00_set_field32(®, TXRX_CSR9_TBTT_ENABLE,
|
|
|
|
- (tsf_sync == TSF_SYNC_BEACON));
|
|
|
|
- rt2x00_set_field32(®, TXRX_CSR9_BEACON_GEN, 0);
|
|
|
|
- rt2x00_set_field32(®, TXRX_CSR9_TSF_SYNC, tsf_sync);
|
|
|
|
- rt73usb_register_write(rt2x00dev, TXRX_CSR9, reg);
|
|
|
|
|
|
+ if (flags & CONFIG_UPDATE_BSSID) {
|
|
|
|
+ reg = le32_to_cpu(conf->bssid[1]);
|
|
|
|
+ rt2x00_set_field32(®, MAC_CSR5_BSS_ID_MASK, 3);
|
|
|
|
+ conf->bssid[1] = cpu_to_le32(reg);
|
|
|
|
+
|
|
|
|
+ rt73usb_register_multiwrite(rt2x00dev, MAC_CSR4,
|
|
|
|
+ conf->bssid, sizeof(conf->bssid));
|
|
|
|
+ }
|
|
}
|
|
}
|
|
|
|
|
|
-static void rt73usb_config_preamble(struct rt2x00_dev *rt2x00dev,
|
|
|
|
- const int short_preamble,
|
|
|
|
- const int ack_timeout,
|
|
|
|
- const int ack_consume_time)
|
|
|
|
|
|
+static int rt73usb_config_preamble(struct rt2x00_dev *rt2x00dev,
|
|
|
|
+ const int short_preamble,
|
|
|
|
+ const int ack_timeout,
|
|
|
|
+ const int ack_consume_time)
|
|
{
|
|
{
|
|
u32 reg;
|
|
u32 reg;
|
|
|
|
|
|
/*
|
|
/*
|
|
- * When in atomic context, reschedule and let rt2x00lib
|
|
|
|
- * call this function again.
|
|
|
|
|
|
+ * When in atomic context, we should let rt2x00lib
|
|
|
|
+ * try this configuration again later.
|
|
*/
|
|
*/
|
|
- if (in_atomic()) {
|
|
|
|
- queue_work(rt2x00dev->hw->workqueue, &rt2x00dev->config_work);
|
|
|
|
- return;
|
|
|
|
- }
|
|
|
|
|
|
+ if (in_atomic())
|
|
|
|
+ return -EAGAIN;
|
|
|
|
|
|
rt73usb_register_read(rt2x00dev, TXRX_CSR0, ®);
|
|
rt73usb_register_read(rt2x00dev, TXRX_CSR0, ®);
|
|
rt2x00_set_field32(®, TXRX_CSR0_RX_ACK_TIMEOUT, ack_timeout);
|
|
rt2x00_set_field32(®, TXRX_CSR0_RX_ACK_TIMEOUT, ack_timeout);
|
|
@@ -358,6 +403,8 @@ static void rt73usb_config_preamble(struct rt2x00_dev *rt2x00dev,
|
|
rt2x00_set_field32(®, TXRX_CSR4_AUTORESPOND_PREAMBLE,
|
|
rt2x00_set_field32(®, TXRX_CSR4_AUTORESPOND_PREAMBLE,
|
|
!!short_preamble);
|
|
!!short_preamble);
|
|
rt73usb_register_write(rt2x00dev, TXRX_CSR4, reg);
|
|
rt73usb_register_write(rt2x00dev, TXRX_CSR4, reg);
|
|
|
|
+
|
|
|
|
+ return 0;
|
|
}
|
|
}
|
|
|
|
|
|
static void rt73usb_config_phymode(struct rt2x00_dev *rt2x00dev,
|
|
static void rt73usb_config_phymode(struct rt2x00_dev *rt2x00dev,
|
|
@@ -442,13 +489,13 @@ static void rt73usb_config_antenna_5x(struct rt2x00_dev *rt2x00dev,
|
|
case ANTENNA_HW_DIVERSITY:
|
|
case ANTENNA_HW_DIVERSITY:
|
|
rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA_CONTROL, 2);
|
|
rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA_CONTROL, 2);
|
|
temp = !test_bit(CONFIG_FRAME_TYPE, &rt2x00dev->flags)
|
|
temp = !test_bit(CONFIG_FRAME_TYPE, &rt2x00dev->flags)
|
|
- && (rt2x00dev->curr_hwmode != HWMODE_A);
|
|
|
|
|
|
+ && (rt2x00dev->curr_band != IEEE80211_BAND_5GHZ);
|
|
rt2x00_set_field8(&r4, BBP_R4_RX_FRAME_END, temp);
|
|
rt2x00_set_field8(&r4, BBP_R4_RX_FRAME_END, temp);
|
|
break;
|
|
break;
|
|
case ANTENNA_A:
|
|
case ANTENNA_A:
|
|
rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA_CONTROL, 1);
|
|
rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA_CONTROL, 1);
|
|
rt2x00_set_field8(&r4, BBP_R4_RX_FRAME_END, 0);
|
|
rt2x00_set_field8(&r4, BBP_R4_RX_FRAME_END, 0);
|
|
- if (rt2x00dev->curr_hwmode == HWMODE_A)
|
|
|
|
|
|
+ if (rt2x00dev->curr_band == IEEE80211_BAND_5GHZ)
|
|
rt2x00_set_field8(&r77, BBP_R77_RX_ANTENNA, 0);
|
|
rt2x00_set_field8(&r77, BBP_R77_RX_ANTENNA, 0);
|
|
else
|
|
else
|
|
rt2x00_set_field8(&r77, BBP_R77_RX_ANTENNA, 3);
|
|
rt2x00_set_field8(&r77, BBP_R77_RX_ANTENNA, 3);
|
|
@@ -463,7 +510,7 @@ static void rt73usb_config_antenna_5x(struct rt2x00_dev *rt2x00dev,
|
|
case ANTENNA_B:
|
|
case ANTENNA_B:
|
|
rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA_CONTROL, 1);
|
|
rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA_CONTROL, 1);
|
|
rt2x00_set_field8(&r4, BBP_R4_RX_FRAME_END, 0);
|
|
rt2x00_set_field8(&r4, BBP_R4_RX_FRAME_END, 0);
|
|
- if (rt2x00dev->curr_hwmode == HWMODE_A)
|
|
|
|
|
|
+ if (rt2x00dev->curr_band == IEEE80211_BAND_5GHZ)
|
|
rt2x00_set_field8(&r77, BBP_R77_RX_ANTENNA, 3);
|
|
rt2x00_set_field8(&r77, BBP_R77_RX_ANTENNA, 3);
|
|
else
|
|
else
|
|
rt2x00_set_field8(&r77, BBP_R77_RX_ANTENNA, 0);
|
|
rt2x00_set_field8(&r77, BBP_R77_RX_ANTENNA, 0);
|
|
@@ -558,7 +605,7 @@ static void rt73usb_config_antenna(struct rt2x00_dev *rt2x00dev,
|
|
unsigned int i;
|
|
unsigned int i;
|
|
u32 reg;
|
|
u32 reg;
|
|
|
|
|
|
- if (rt2x00dev->curr_hwmode == HWMODE_A) {
|
|
|
|
|
|
+ if (rt2x00dev->curr_band == IEEE80211_BAND_5GHZ) {
|
|
sel = antenna_sel_a;
|
|
sel = antenna_sel_a;
|
|
lna = test_bit(CONFIG_EXTERNAL_LNA_A, &rt2x00dev->flags);
|
|
lna = test_bit(CONFIG_EXTERNAL_LNA_A, &rt2x00dev->flags);
|
|
} else {
|
|
} else {
|
|
@@ -572,10 +619,9 @@ static void rt73usb_config_antenna(struct rt2x00_dev *rt2x00dev,
|
|
rt73usb_register_read(rt2x00dev, PHY_CSR0, ®);
|
|
rt73usb_register_read(rt2x00dev, PHY_CSR0, ®);
|
|
|
|
|
|
rt2x00_set_field32(®, PHY_CSR0_PA_PE_BG,
|
|
rt2x00_set_field32(®, PHY_CSR0_PA_PE_BG,
|
|
- (rt2x00dev->curr_hwmode == HWMODE_B ||
|
|
|
|
- rt2x00dev->curr_hwmode == HWMODE_G));
|
|
|
|
|
|
+ (rt2x00dev->curr_band == IEEE80211_BAND_2GHZ));
|
|
rt2x00_set_field32(®, PHY_CSR0_PA_PE_A,
|
|
rt2x00_set_field32(®, PHY_CSR0_PA_PE_A,
|
|
- (rt2x00dev->curr_hwmode == HWMODE_A));
|
|
|
|
|
|
+ (rt2x00dev->curr_band == IEEE80211_BAND_5GHZ));
|
|
|
|
|
|
rt73usb_register_write(rt2x00dev, PHY_CSR0, reg);
|
|
rt73usb_register_write(rt2x00dev, PHY_CSR0, reg);
|
|
|
|
|
|
@@ -617,8 +663,8 @@ static void rt73usb_config_duration(struct rt2x00_dev *rt2x00dev,
|
|
}
|
|
}
|
|
|
|
|
|
static void rt73usb_config(struct rt2x00_dev *rt2x00dev,
|
|
static void rt73usb_config(struct rt2x00_dev *rt2x00dev,
|
|
- const unsigned int flags,
|
|
|
|
- struct rt2x00lib_conf *libconf)
|
|
|
|
|
|
+ struct rt2x00lib_conf *libconf,
|
|
|
|
+ const unsigned int flags)
|
|
{
|
|
{
|
|
if (flags & CONFIG_UPDATE_PHYMODE)
|
|
if (flags & CONFIG_UPDATE_PHYMODE)
|
|
rt73usb_config_phymode(rt2x00dev, libconf->basic_rates);
|
|
rt73usb_config_phymode(rt2x00dev, libconf->basic_rates);
|
|
@@ -633,68 +679,6 @@ static void rt73usb_config(struct rt2x00_dev *rt2x00dev,
|
|
rt73usb_config_duration(rt2x00dev, libconf);
|
|
rt73usb_config_duration(rt2x00dev, libconf);
|
|
}
|
|
}
|
|
|
|
|
|
-/*
|
|
|
|
- * LED functions.
|
|
|
|
- */
|
|
|
|
-static void rt73usb_enable_led(struct rt2x00_dev *rt2x00dev)
|
|
|
|
-{
|
|
|
|
- u32 reg;
|
|
|
|
-
|
|
|
|
- rt73usb_register_read(rt2x00dev, MAC_CSR14, ®);
|
|
|
|
- rt2x00_set_field32(®, MAC_CSR14_ON_PERIOD, 70);
|
|
|
|
- rt2x00_set_field32(®, MAC_CSR14_OFF_PERIOD, 30);
|
|
|
|
- rt73usb_register_write(rt2x00dev, MAC_CSR14, reg);
|
|
|
|
-
|
|
|
|
- rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_RADIO_STATUS, 1);
|
|
|
|
- rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_LINK_A_STATUS,
|
|
|
|
- (rt2x00dev->rx_status.phymode == MODE_IEEE80211A));
|
|
|
|
- rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_LINK_BG_STATUS,
|
|
|
|
- (rt2x00dev->rx_status.phymode != MODE_IEEE80211A));
|
|
|
|
-
|
|
|
|
- rt2x00usb_vendor_request_sw(rt2x00dev, USB_LED_CONTROL, 0x0000,
|
|
|
|
- rt2x00dev->led_reg, REGISTER_TIMEOUT);
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-static void rt73usb_disable_led(struct rt2x00_dev *rt2x00dev)
|
|
|
|
-{
|
|
|
|
- rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_RADIO_STATUS, 0);
|
|
|
|
- rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_LINK_BG_STATUS, 0);
|
|
|
|
- rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_LINK_A_STATUS, 0);
|
|
|
|
-
|
|
|
|
- rt2x00usb_vendor_request_sw(rt2x00dev, USB_LED_CONTROL, 0x0000,
|
|
|
|
- rt2x00dev->led_reg, REGISTER_TIMEOUT);
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-static void rt73usb_activity_led(struct rt2x00_dev *rt2x00dev, int rssi)
|
|
|
|
-{
|
|
|
|
- u32 led;
|
|
|
|
-
|
|
|
|
- if (rt2x00dev->led_mode != LED_MODE_SIGNAL_STRENGTH)
|
|
|
|
- return;
|
|
|
|
-
|
|
|
|
- /*
|
|
|
|
- * Led handling requires a positive value for the rssi,
|
|
|
|
- * to do that correctly we need to add the correction.
|
|
|
|
- */
|
|
|
|
- rssi += rt2x00dev->rssi_offset;
|
|
|
|
-
|
|
|
|
- if (rssi <= 30)
|
|
|
|
- led = 0;
|
|
|
|
- else if (rssi <= 39)
|
|
|
|
- led = 1;
|
|
|
|
- else if (rssi <= 49)
|
|
|
|
- led = 2;
|
|
|
|
- else if (rssi <= 53)
|
|
|
|
- led = 3;
|
|
|
|
- else if (rssi <= 63)
|
|
|
|
- led = 4;
|
|
|
|
- else
|
|
|
|
- led = 5;
|
|
|
|
-
|
|
|
|
- rt2x00usb_vendor_request_sw(rt2x00dev, USB_LED_CONTROL, led,
|
|
|
|
- rt2x00dev->led_reg, REGISTER_TIMEOUT);
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
/*
|
|
/*
|
|
* Link tuning
|
|
* Link tuning
|
|
*/
|
|
*/
|
|
@@ -729,17 +713,12 @@ static void rt73usb_link_tuner(struct rt2x00_dev *rt2x00dev)
|
|
u8 up_bound;
|
|
u8 up_bound;
|
|
u8 low_bound;
|
|
u8 low_bound;
|
|
|
|
|
|
- /*
|
|
|
|
- * Update Led strength
|
|
|
|
- */
|
|
|
|
- rt73usb_activity_led(rt2x00dev, rssi);
|
|
|
|
-
|
|
|
|
rt73usb_bbp_read(rt2x00dev, 17, &r17);
|
|
rt73usb_bbp_read(rt2x00dev, 17, &r17);
|
|
|
|
|
|
/*
|
|
/*
|
|
* Determine r17 bounds.
|
|
* Determine r17 bounds.
|
|
*/
|
|
*/
|
|
- if (rt2x00dev->rx_status.phymode == MODE_IEEE80211A) {
|
|
|
|
|
|
+ if (rt2x00dev->rx_status.band == IEEE80211_BAND_5GHZ) {
|
|
low_bound = 0x28;
|
|
low_bound = 0x28;
|
|
up_bound = 0x48;
|
|
up_bound = 0x48;
|
|
|
|
|
|
@@ -765,6 +744,13 @@ static void rt73usb_link_tuner(struct rt2x00_dev *rt2x00dev)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ /*
|
|
|
|
+ * If we are not associated, we should go straight to the
|
|
|
|
+ * dynamic CCA tuning.
|
|
|
|
+ */
|
|
|
|
+ if (!rt2x00dev->intf_associated)
|
|
|
|
+ goto dynamic_cca_tune;
|
|
|
|
+
|
|
/*
|
|
/*
|
|
* Special big-R17 for very short distance
|
|
* Special big-R17 for very short distance
|
|
*/
|
|
*/
|
|
@@ -815,6 +801,8 @@ static void rt73usb_link_tuner(struct rt2x00_dev *rt2x00dev)
|
|
return;
|
|
return;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+dynamic_cca_tune:
|
|
|
|
+
|
|
/*
|
|
/*
|
|
* r17 does not yet exceed upper limit, continue and base
|
|
* r17 does not yet exceed upper limit, continue and base
|
|
* the r17 tuning on the false CCA count.
|
|
* the r17 tuning on the false CCA count.
|
|
@@ -889,7 +877,7 @@ static int rt73usb_load_firmware(struct rt2x00_dev *rt2x00dev, void *data,
|
|
|
|
|
|
rt2x00usb_vendor_request(rt2x00dev, USB_MULTI_WRITE,
|
|
rt2x00usb_vendor_request(rt2x00dev, USB_MULTI_WRITE,
|
|
USB_VENDOR_REQUEST_OUT,
|
|
USB_VENDOR_REQUEST_OUT,
|
|
- FIRMWARE_IMAGE_BASE + i, 0x0000,
|
|
|
|
|
|
+ FIRMWARE_IMAGE_BASE + i, 0,
|
|
cache, buflen, timeout);
|
|
cache, buflen, timeout);
|
|
|
|
|
|
ptr += buflen;
|
|
ptr += buflen;
|
|
@@ -902,15 +890,13 @@ static int rt73usb_load_firmware(struct rt2x00_dev *rt2x00dev, void *data,
|
|
* we need to specify a long timeout time.
|
|
* we need to specify a long timeout time.
|
|
*/
|
|
*/
|
|
status = rt2x00usb_vendor_request_sw(rt2x00dev, USB_DEVICE_MODE,
|
|
status = rt2x00usb_vendor_request_sw(rt2x00dev, USB_DEVICE_MODE,
|
|
- 0x0000, USB_MODE_FIRMWARE,
|
|
|
|
|
|
+ 0, USB_MODE_FIRMWARE,
|
|
REGISTER_TIMEOUT_FIRMWARE);
|
|
REGISTER_TIMEOUT_FIRMWARE);
|
|
if (status < 0) {
|
|
if (status < 0) {
|
|
ERROR(rt2x00dev, "Failed to write Firmware to device.\n");
|
|
ERROR(rt2x00dev, "Failed to write Firmware to device.\n");
|
|
return status;
|
|
return status;
|
|
}
|
|
}
|
|
|
|
|
|
- rt73usb_disable_led(rt2x00dev);
|
|
|
|
-
|
|
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -988,6 +974,11 @@ static int rt73usb_init_registers(struct rt2x00_dev *rt2x00dev)
|
|
|
|
|
|
rt73usb_register_write(rt2x00dev, MAC_CSR13, 0x00007f00);
|
|
rt73usb_register_write(rt2x00dev, MAC_CSR13, 0x00007f00);
|
|
|
|
|
|
|
|
+ rt73usb_register_read(rt2x00dev, MAC_CSR14, ®);
|
|
|
|
+ rt2x00_set_field32(®, MAC_CSR14_ON_PERIOD, 70);
|
|
|
|
+ rt2x00_set_field32(®, MAC_CSR14_OFF_PERIOD, 30);
|
|
|
|
+ rt73usb_register_write(rt2x00dev, MAC_CSR14, reg);
|
|
|
|
+
|
|
/*
|
|
/*
|
|
* Invalidate all Shared Keys (SEC_CSR0),
|
|
* Invalidate all Shared Keys (SEC_CSR0),
|
|
* and clear the Shared key Cipher algorithms (SEC_CSR1 & SEC_CSR5)
|
|
* and clear the Shared key Cipher algorithms (SEC_CSR1 & SEC_CSR5)
|
|
@@ -1020,6 +1011,17 @@ static int rt73usb_init_registers(struct rt2x00_dev *rt2x00dev)
|
|
rt2x00_set_field32(®, MAC_CSR9_CW_SELECT, 0);
|
|
rt2x00_set_field32(®, MAC_CSR9_CW_SELECT, 0);
|
|
rt73usb_register_write(rt2x00dev, MAC_CSR9, reg);
|
|
rt73usb_register_write(rt2x00dev, MAC_CSR9, reg);
|
|
|
|
|
|
|
|
+ /*
|
|
|
|
+ * Clear all beacons
|
|
|
|
+ * For the Beacon base registers we only need to clear
|
|
|
|
+ * the first byte since that byte contains the VALID and OWNER
|
|
|
|
+ * bits which (when set to 0) will invalidate the entire beacon.
|
|
|
|
+ */
|
|
|
|
+ rt73usb_register_write(rt2x00dev, HW_BEACON_BASE0, 0);
|
|
|
|
+ rt73usb_register_write(rt2x00dev, HW_BEACON_BASE1, 0);
|
|
|
|
+ rt73usb_register_write(rt2x00dev, HW_BEACON_BASE2, 0);
|
|
|
|
+ rt73usb_register_write(rt2x00dev, HW_BEACON_BASE3, 0);
|
|
|
|
+
|
|
/*
|
|
/*
|
|
* We must clear the error counters.
|
|
* We must clear the error counters.
|
|
* These registers are cleared on read,
|
|
* These registers are cleared on read,
|
|
@@ -1094,19 +1096,15 @@ continue_csr_init:
|
|
rt73usb_bbp_write(rt2x00dev, 102, 0x16);
|
|
rt73usb_bbp_write(rt2x00dev, 102, 0x16);
|
|
rt73usb_bbp_write(rt2x00dev, 107, 0x04);
|
|
rt73usb_bbp_write(rt2x00dev, 107, 0x04);
|
|
|
|
|
|
- DEBUG(rt2x00dev, "Start initialization from EEPROM...\n");
|
|
|
|
for (i = 0; i < EEPROM_BBP_SIZE; i++) {
|
|
for (i = 0; i < EEPROM_BBP_SIZE; i++) {
|
|
rt2x00_eeprom_read(rt2x00dev, EEPROM_BBP_START + i, &eeprom);
|
|
rt2x00_eeprom_read(rt2x00dev, EEPROM_BBP_START + i, &eeprom);
|
|
|
|
|
|
if (eeprom != 0xffff && eeprom != 0x0000) {
|
|
if (eeprom != 0xffff && eeprom != 0x0000) {
|
|
reg_id = rt2x00_get_field16(eeprom, EEPROM_BBP_REG_ID);
|
|
reg_id = rt2x00_get_field16(eeprom, EEPROM_BBP_REG_ID);
|
|
value = rt2x00_get_field16(eeprom, EEPROM_BBP_VALUE);
|
|
value = rt2x00_get_field16(eeprom, EEPROM_BBP_VALUE);
|
|
- DEBUG(rt2x00dev, "BBP: 0x%02x, value: 0x%02x.\n",
|
|
|
|
- reg_id, value);
|
|
|
|
rt73usb_bbp_write(rt2x00dev, reg_id, value);
|
|
rt73usb_bbp_write(rt2x00dev, reg_id, value);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
- DEBUG(rt2x00dev, "...End initialization from EEPROM.\n");
|
|
|
|
|
|
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
@@ -1136,21 +1134,11 @@ static int rt73usb_enable_radio(struct rt2x00_dev *rt2x00dev)
|
|
return -EIO;
|
|
return -EIO;
|
|
}
|
|
}
|
|
|
|
|
|
- /*
|
|
|
|
- * Enable LED
|
|
|
|
- */
|
|
|
|
- rt73usb_enable_led(rt2x00dev);
|
|
|
|
-
|
|
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
|
|
static void rt73usb_disable_radio(struct rt2x00_dev *rt2x00dev)
|
|
static void rt73usb_disable_radio(struct rt2x00_dev *rt2x00dev)
|
|
{
|
|
{
|
|
- /*
|
|
|
|
- * Disable LED
|
|
|
|
- */
|
|
|
|
- rt73usb_disable_led(rt2x00dev);
|
|
|
|
-
|
|
|
|
rt73usb_register_write(rt2x00dev, MAC_CSR10, 0x00001818);
|
|
rt73usb_register_write(rt2x00dev, MAC_CSR10, 0x00001818);
|
|
|
|
|
|
/*
|
|
/*
|
|
@@ -1234,10 +1222,10 @@ static int rt73usb_set_device_state(struct rt2x00_dev *rt2x00dev,
|
|
*/
|
|
*/
|
|
static void rt73usb_write_tx_desc(struct rt2x00_dev *rt2x00dev,
|
|
static void rt73usb_write_tx_desc(struct rt2x00_dev *rt2x00dev,
|
|
struct sk_buff *skb,
|
|
struct sk_buff *skb,
|
|
- struct txdata_entry_desc *desc,
|
|
|
|
|
|
+ struct txentry_desc *txdesc,
|
|
struct ieee80211_tx_control *control)
|
|
struct ieee80211_tx_control *control)
|
|
{
|
|
{
|
|
- struct skb_desc *skbdesc = get_skb_desc(skb);
|
|
|
|
|
|
+ struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb);
|
|
__le32 *txd = skbdesc->desc;
|
|
__le32 *txd = skbdesc->desc;
|
|
u32 word;
|
|
u32 word;
|
|
|
|
|
|
@@ -1245,47 +1233,47 @@ static void rt73usb_write_tx_desc(struct rt2x00_dev *rt2x00dev,
|
|
* Start writing the descriptor words.
|
|
* Start writing the descriptor words.
|
|
*/
|
|
*/
|
|
rt2x00_desc_read(txd, 1, &word);
|
|
rt2x00_desc_read(txd, 1, &word);
|
|
- rt2x00_set_field32(&word, TXD_W1_HOST_Q_ID, desc->queue);
|
|
|
|
- rt2x00_set_field32(&word, TXD_W1_AIFSN, desc->aifs);
|
|
|
|
- rt2x00_set_field32(&word, TXD_W1_CWMIN, desc->cw_min);
|
|
|
|
- rt2x00_set_field32(&word, TXD_W1_CWMAX, desc->cw_max);
|
|
|
|
|
|
+ rt2x00_set_field32(&word, TXD_W1_HOST_Q_ID, txdesc->queue);
|
|
|
|
+ rt2x00_set_field32(&word, TXD_W1_AIFSN, txdesc->aifs);
|
|
|
|
+ rt2x00_set_field32(&word, TXD_W1_CWMIN, txdesc->cw_min);
|
|
|
|
+ rt2x00_set_field32(&word, TXD_W1_CWMAX, txdesc->cw_max);
|
|
rt2x00_set_field32(&word, TXD_W1_IV_OFFSET, IEEE80211_HEADER);
|
|
rt2x00_set_field32(&word, TXD_W1_IV_OFFSET, IEEE80211_HEADER);
|
|
rt2x00_set_field32(&word, TXD_W1_HW_SEQUENCE, 1);
|
|
rt2x00_set_field32(&word, TXD_W1_HW_SEQUENCE, 1);
|
|
rt2x00_desc_write(txd, 1, word);
|
|
rt2x00_desc_write(txd, 1, word);
|
|
|
|
|
|
rt2x00_desc_read(txd, 2, &word);
|
|
rt2x00_desc_read(txd, 2, &word);
|
|
- rt2x00_set_field32(&word, TXD_W2_PLCP_SIGNAL, desc->signal);
|
|
|
|
- rt2x00_set_field32(&word, TXD_W2_PLCP_SERVICE, desc->service);
|
|
|
|
- rt2x00_set_field32(&word, TXD_W2_PLCP_LENGTH_LOW, desc->length_low);
|
|
|
|
- rt2x00_set_field32(&word, TXD_W2_PLCP_LENGTH_HIGH, desc->length_high);
|
|
|
|
|
|
+ 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_desc_write(txd, 2, word);
|
|
rt2x00_desc_write(txd, 2, word);
|
|
|
|
|
|
rt2x00_desc_read(txd, 5, &word);
|
|
rt2x00_desc_read(txd, 5, &word);
|
|
rt2x00_set_field32(&word, TXD_W5_TX_POWER,
|
|
rt2x00_set_field32(&word, TXD_W5_TX_POWER,
|
|
- TXPOWER_TO_DEV(control->power_level));
|
|
|
|
|
|
+ TXPOWER_TO_DEV(rt2x00dev->tx_power));
|
|
rt2x00_set_field32(&word, TXD_W5_WAITING_DMA_DONE_INT, 1);
|
|
rt2x00_set_field32(&word, TXD_W5_WAITING_DMA_DONE_INT, 1);
|
|
rt2x00_desc_write(txd, 5, word);
|
|
rt2x00_desc_write(txd, 5, word);
|
|
|
|
|
|
rt2x00_desc_read(txd, 0, &word);
|
|
rt2x00_desc_read(txd, 0, &word);
|
|
rt2x00_set_field32(&word, TXD_W0_BURST,
|
|
rt2x00_set_field32(&word, TXD_W0_BURST,
|
|
- test_bit(ENTRY_TXD_BURST, &desc->flags));
|
|
|
|
|
|
+ test_bit(ENTRY_TXD_BURST, &txdesc->flags));
|
|
rt2x00_set_field32(&word, TXD_W0_VALID, 1);
|
|
rt2x00_set_field32(&word, TXD_W0_VALID, 1);
|
|
rt2x00_set_field32(&word, TXD_W0_MORE_FRAG,
|
|
rt2x00_set_field32(&word, TXD_W0_MORE_FRAG,
|
|
- test_bit(ENTRY_TXD_MORE_FRAG, &desc->flags));
|
|
|
|
|
|
+ test_bit(ENTRY_TXD_MORE_FRAG, &txdesc->flags));
|
|
rt2x00_set_field32(&word, TXD_W0_ACK,
|
|
rt2x00_set_field32(&word, TXD_W0_ACK,
|
|
- test_bit(ENTRY_TXD_ACK, &desc->flags));
|
|
|
|
|
|
+ test_bit(ENTRY_TXD_ACK, &txdesc->flags));
|
|
rt2x00_set_field32(&word, TXD_W0_TIMESTAMP,
|
|
rt2x00_set_field32(&word, TXD_W0_TIMESTAMP,
|
|
- test_bit(ENTRY_TXD_REQ_TIMESTAMP, &desc->flags));
|
|
|
|
|
|
+ test_bit(ENTRY_TXD_REQ_TIMESTAMP, &txdesc->flags));
|
|
rt2x00_set_field32(&word, TXD_W0_OFDM,
|
|
rt2x00_set_field32(&word, TXD_W0_OFDM,
|
|
- test_bit(ENTRY_TXD_OFDM_RATE, &desc->flags));
|
|
|
|
- rt2x00_set_field32(&word, TXD_W0_IFS, desc->ifs);
|
|
|
|
|
|
+ test_bit(ENTRY_TXD_OFDM_RATE, &txdesc->flags));
|
|
|
|
+ rt2x00_set_field32(&word, TXD_W0_IFS, txdesc->ifs);
|
|
rt2x00_set_field32(&word, TXD_W0_RETRY_MODE,
|
|
rt2x00_set_field32(&word, TXD_W0_RETRY_MODE,
|
|
!!(control->flags &
|
|
!!(control->flags &
|
|
IEEE80211_TXCTL_LONG_RETRY_LIMIT));
|
|
IEEE80211_TXCTL_LONG_RETRY_LIMIT));
|
|
rt2x00_set_field32(&word, TXD_W0_TKIP_MIC, 0);
|
|
rt2x00_set_field32(&word, TXD_W0_TKIP_MIC, 0);
|
|
rt2x00_set_field32(&word, TXD_W0_DATABYTE_COUNT, skbdesc->data_len);
|
|
rt2x00_set_field32(&word, TXD_W0_DATABYTE_COUNT, skbdesc->data_len);
|
|
rt2x00_set_field32(&word, TXD_W0_BURST2,
|
|
rt2x00_set_field32(&word, TXD_W0_BURST2,
|
|
- test_bit(ENTRY_TXD_BURST, &desc->flags));
|
|
|
|
|
|
+ test_bit(ENTRY_TXD_BURST, &txdesc->flags));
|
|
rt2x00_set_field32(&word, TXD_W0_CIPHER_ALG, CIPHER_NONE);
|
|
rt2x00_set_field32(&word, TXD_W0_CIPHER_ALG, CIPHER_NONE);
|
|
rt2x00_desc_write(txd, 0, word);
|
|
rt2x00_desc_write(txd, 0, word);
|
|
}
|
|
}
|
|
@@ -1309,11 +1297,11 @@ static int rt73usb_get_tx_data_len(struct rt2x00_dev *rt2x00dev,
|
|
* TX data initialization
|
|
* TX data initialization
|
|
*/
|
|
*/
|
|
static void rt73usb_kick_tx_queue(struct rt2x00_dev *rt2x00dev,
|
|
static void rt73usb_kick_tx_queue(struct rt2x00_dev *rt2x00dev,
|
|
- unsigned int queue)
|
|
|
|
|
|
+ const unsigned int queue)
|
|
{
|
|
{
|
|
u32 reg;
|
|
u32 reg;
|
|
|
|
|
|
- if (queue != IEEE80211_TX_QUEUE_BEACON)
|
|
|
|
|
|
+ if (queue != RT2X00_BCN_QUEUE_BEACON)
|
|
return;
|
|
return;
|
|
|
|
|
|
/*
|
|
/*
|
|
@@ -1353,7 +1341,7 @@ static int rt73usb_agc_to_rssi(struct rt2x00_dev *rt2x00dev, int rxd_w1)
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
|
|
- if (rt2x00dev->rx_status.phymode == MODE_IEEE80211A) {
|
|
|
|
|
|
+ if (rt2x00dev->rx_status.band == IEEE80211_BAND_5GHZ) {
|
|
if (test_bit(CONFIG_EXTERNAL_LNA_A, &rt2x00dev->flags)) {
|
|
if (test_bit(CONFIG_EXTERNAL_LNA_A, &rt2x00dev->flags)) {
|
|
if (lna == 3 || lna == 2)
|
|
if (lna == 3 || lna == 2)
|
|
offset += 10;
|
|
offset += 10;
|
|
@@ -1377,37 +1365,57 @@ static int rt73usb_agc_to_rssi(struct rt2x00_dev *rt2x00dev, int rxd_w1)
|
|
return rt2x00_get_field32(rxd_w1, RXD_W1_RSSI_AGC) * 2 - offset;
|
|
return rt2x00_get_field32(rxd_w1, RXD_W1_RSSI_AGC) * 2 - offset;
|
|
}
|
|
}
|
|
|
|
|
|
-static void rt73usb_fill_rxdone(struct data_entry *entry,
|
|
|
|
- struct rxdata_entry_desc *desc)
|
|
|
|
|
|
+static void rt73usb_fill_rxdone(struct queue_entry *entry,
|
|
|
|
+ struct rxdone_entry_desc *rxdesc)
|
|
{
|
|
{
|
|
- struct skb_desc *skbdesc = get_skb_desc(entry->skb);
|
|
|
|
|
|
+ struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb);
|
|
__le32 *rxd = (__le32 *)entry->skb->data;
|
|
__le32 *rxd = (__le32 *)entry->skb->data;
|
|
|
|
+ struct ieee80211_hdr *hdr =
|
|
|
|
+ (struct ieee80211_hdr *)entry->skb->data + entry->queue->desc_size;
|
|
|
|
+ int header_size = ieee80211_get_hdrlen(le16_to_cpu(hdr->frame_control));
|
|
u32 word0;
|
|
u32 word0;
|
|
u32 word1;
|
|
u32 word1;
|
|
|
|
|
|
rt2x00_desc_read(rxd, 0, &word0);
|
|
rt2x00_desc_read(rxd, 0, &word0);
|
|
rt2x00_desc_read(rxd, 1, &word1);
|
|
rt2x00_desc_read(rxd, 1, &word1);
|
|
|
|
|
|
- desc->flags = 0;
|
|
|
|
|
|
+ rxdesc->flags = 0;
|
|
if (rt2x00_get_field32(word0, RXD_W0_CRC_ERROR))
|
|
if (rt2x00_get_field32(word0, RXD_W0_CRC_ERROR))
|
|
- desc->flags |= RX_FLAG_FAILED_FCS_CRC;
|
|
|
|
|
|
+ rxdesc->flags |= RX_FLAG_FAILED_FCS_CRC;
|
|
|
|
|
|
/*
|
|
/*
|
|
* Obtain the status about this packet.
|
|
* Obtain the status about this packet.
|
|
*/
|
|
*/
|
|
- desc->signal = rt2x00_get_field32(word1, RXD_W1_SIGNAL);
|
|
|
|
- desc->rssi = rt73usb_agc_to_rssi(entry->ring->rt2x00dev, word1);
|
|
|
|
- desc->ofdm = rt2x00_get_field32(word0, RXD_W0_OFDM);
|
|
|
|
- desc->size = rt2x00_get_field32(word0, RXD_W0_DATABYTE_COUNT);
|
|
|
|
- desc->my_bss = !!rt2x00_get_field32(word0, RXD_W0_MY_BSS);
|
|
|
|
|
|
+ rxdesc->signal = rt2x00_get_field32(word1, RXD_W1_SIGNAL);
|
|
|
|
+ rxdesc->rssi = rt73usb_agc_to_rssi(entry->queue->rt2x00dev, word1);
|
|
|
|
+ rxdesc->ofdm = rt2x00_get_field32(word0, RXD_W0_OFDM);
|
|
|
|
+ rxdesc->size = rt2x00_get_field32(word0, RXD_W0_DATABYTE_COUNT);
|
|
|
|
+ rxdesc->my_bss = !!rt2x00_get_field32(word0, RXD_W0_MY_BSS);
|
|
|
|
+
|
|
|
|
+ /*
|
|
|
|
+ * The data behind the ieee80211 header must be
|
|
|
|
+ * aligned on a 4 byte boundary.
|
|
|
|
+ */
|
|
|
|
+ if (header_size % 4 == 0) {
|
|
|
|
+ skb_push(entry->skb, 2);
|
|
|
|
+ memmove(entry->skb->data, entry->skb->data + 2,
|
|
|
|
+ entry->skb->len - 2);
|
|
|
|
+ }
|
|
|
|
|
|
/*
|
|
/*
|
|
* Set descriptor and data pointer.
|
|
* Set descriptor and data pointer.
|
|
*/
|
|
*/
|
|
|
|
+ skbdesc->data = entry->skb->data + entry->queue->desc_size;
|
|
|
|
+ skbdesc->data_len = rxdesc->size;
|
|
skbdesc->desc = entry->skb->data;
|
|
skbdesc->desc = entry->skb->data;
|
|
- skbdesc->desc_len = entry->ring->desc_size;
|
|
|
|
- skbdesc->data = entry->skb->data + entry->ring->desc_size;
|
|
|
|
- skbdesc->data_len = desc->size;
|
|
|
|
|
|
+ skbdesc->desc_len = entry->queue->desc_size;
|
|
|
|
+
|
|
|
|
+ /*
|
|
|
|
+ * Remove descriptor from skb buffer and trim the whole thing
|
|
|
|
+ * down to only contain data.
|
|
|
|
+ */
|
|
|
|
+ skb_pull(entry->skb, skbdesc->desc_len);
|
|
|
|
+ skb_trim(entry->skb, rxdesc->size);
|
|
}
|
|
}
|
|
|
|
|
|
/*
|
|
/*
|
|
@@ -1499,7 +1507,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_1, 0);
|
|
rt2x00_set_field16(&word, EEPROM_RSSI_OFFSET_A_2, 0);
|
|
rt2x00_set_field16(&word, EEPROM_RSSI_OFFSET_A_2, 0);
|
|
rt2x00_eeprom_write(rt2x00dev, EEPROM_RSSI_OFFSET_A, word);
|
|
rt2x00_eeprom_write(rt2x00dev, EEPROM_RSSI_OFFSET_A, word);
|
|
- EEPROM(rt2x00dev, "RSSI OFFSET BG: 0x%04x\n", word);
|
|
|
|
|
|
+ EEPROM(rt2x00dev, "RSSI OFFSET A: 0x%04x\n", word);
|
|
} else {
|
|
} else {
|
|
value = rt2x00_get_field16(word, EEPROM_RSSI_OFFSET_A_1);
|
|
value = rt2x00_get_field16(word, EEPROM_RSSI_OFFSET_A_1);
|
|
if (value < -10 || value > 10)
|
|
if (value < -10 || value > 10)
|
|
@@ -1577,33 +1585,49 @@ static int rt73usb_init_eeprom(struct rt2x00_dev *rt2x00dev)
|
|
/*
|
|
/*
|
|
* Store led settings, for correct led behaviour.
|
|
* Store led settings, for correct led behaviour.
|
|
*/
|
|
*/
|
|
|
|
+#ifdef CONFIG_RT73USB_LEDS
|
|
rt2x00_eeprom_read(rt2x00dev, EEPROM_LED, &eeprom);
|
|
rt2x00_eeprom_read(rt2x00dev, EEPROM_LED, &eeprom);
|
|
|
|
|
|
- rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_LED_MODE,
|
|
|
|
- rt2x00dev->led_mode);
|
|
|
|
- rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_POLARITY_GPIO_0,
|
|
|
|
|
|
+ switch (value) {
|
|
|
|
+ case LED_MODE_TXRX_ACTIVITY:
|
|
|
|
+ case LED_MODE_ASUS:
|
|
|
|
+ case LED_MODE_ALPHA:
|
|
|
|
+ case LED_MODE_DEFAULT:
|
|
|
|
+ rt2x00dev->led_flags =
|
|
|
|
+ LED_SUPPORT_RADIO | LED_SUPPORT_ASSOC;
|
|
|
|
+ break;
|
|
|
|
+ case LED_MODE_SIGNAL_STRENGTH:
|
|
|
|
+ rt2x00dev->led_flags =
|
|
|
|
+ LED_SUPPORT_RADIO | LED_SUPPORT_ASSOC |
|
|
|
|
+ LED_SUPPORT_QUALITY;
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ rt2x00_set_field16(&rt2x00dev->led_mcu_reg, MCU_LEDCS_LED_MODE, value);
|
|
|
|
+ rt2x00_set_field16(&rt2x00dev->led_mcu_reg, MCU_LEDCS_POLARITY_GPIO_0,
|
|
rt2x00_get_field16(eeprom,
|
|
rt2x00_get_field16(eeprom,
|
|
EEPROM_LED_POLARITY_GPIO_0));
|
|
EEPROM_LED_POLARITY_GPIO_0));
|
|
- rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_POLARITY_GPIO_1,
|
|
|
|
|
|
+ rt2x00_set_field16(&rt2x00dev->led_mcu_reg, MCU_LEDCS_POLARITY_GPIO_1,
|
|
rt2x00_get_field16(eeprom,
|
|
rt2x00_get_field16(eeprom,
|
|
EEPROM_LED_POLARITY_GPIO_1));
|
|
EEPROM_LED_POLARITY_GPIO_1));
|
|
- rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_POLARITY_GPIO_2,
|
|
|
|
|
|
+ rt2x00_set_field16(&rt2x00dev->led_mcu_reg, MCU_LEDCS_POLARITY_GPIO_2,
|
|
rt2x00_get_field16(eeprom,
|
|
rt2x00_get_field16(eeprom,
|
|
EEPROM_LED_POLARITY_GPIO_2));
|
|
EEPROM_LED_POLARITY_GPIO_2));
|
|
- rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_POLARITY_GPIO_3,
|
|
|
|
|
|
+ rt2x00_set_field16(&rt2x00dev->led_mcu_reg, MCU_LEDCS_POLARITY_GPIO_3,
|
|
rt2x00_get_field16(eeprom,
|
|
rt2x00_get_field16(eeprom,
|
|
EEPROM_LED_POLARITY_GPIO_3));
|
|
EEPROM_LED_POLARITY_GPIO_3));
|
|
- rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_POLARITY_GPIO_4,
|
|
|
|
|
|
+ rt2x00_set_field16(&rt2x00dev->led_mcu_reg, MCU_LEDCS_POLARITY_GPIO_4,
|
|
rt2x00_get_field16(eeprom,
|
|
rt2x00_get_field16(eeprom,
|
|
EEPROM_LED_POLARITY_GPIO_4));
|
|
EEPROM_LED_POLARITY_GPIO_4));
|
|
- rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_POLARITY_ACT,
|
|
|
|
|
|
+ rt2x00_set_field16(&rt2x00dev->led_mcu_reg, MCU_LEDCS_POLARITY_ACT,
|
|
rt2x00_get_field16(eeprom, EEPROM_LED_POLARITY_ACT));
|
|
rt2x00_get_field16(eeprom, EEPROM_LED_POLARITY_ACT));
|
|
- rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_POLARITY_READY_BG,
|
|
|
|
|
|
+ rt2x00_set_field16(&rt2x00dev->led_mcu_reg, MCU_LEDCS_POLARITY_READY_BG,
|
|
rt2x00_get_field16(eeprom,
|
|
rt2x00_get_field16(eeprom,
|
|
EEPROM_LED_POLARITY_RDY_G));
|
|
EEPROM_LED_POLARITY_RDY_G));
|
|
- rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_POLARITY_READY_A,
|
|
|
|
|
|
+ rt2x00_set_field16(&rt2x00dev->led_mcu_reg, MCU_LEDCS_POLARITY_READY_A,
|
|
rt2x00_get_field16(eeprom,
|
|
rt2x00_get_field16(eeprom,
|
|
EEPROM_LED_POLARITY_RDY_A));
|
|
EEPROM_LED_POLARITY_RDY_A));
|
|
|
|
+#endif /* CONFIG_RT73USB_LEDS */
|
|
|
|
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
@@ -1759,7 +1783,7 @@ static void rt73usb_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
|
|
rt2x00dev->hw->extra_tx_headroom = TXD_DESC_SIZE;
|
|
rt2x00dev->hw->extra_tx_headroom = TXD_DESC_SIZE;
|
|
rt2x00dev->hw->max_signal = MAX_SIGNAL;
|
|
rt2x00dev->hw->max_signal = MAX_SIGNAL;
|
|
rt2x00dev->hw->max_rssi = MAX_RX_SSI;
|
|
rt2x00dev->hw->max_rssi = MAX_RX_SSI;
|
|
- rt2x00dev->hw->queues = 5;
|
|
|
|
|
|
+ rt2x00dev->hw->queues = 4;
|
|
|
|
|
|
SET_IEEE80211_DEV(rt2x00dev->hw, &rt2x00dev_usb(rt2x00dev)->dev);
|
|
SET_IEEE80211_DEV(rt2x00dev->hw, &rt2x00dev_usb(rt2x00dev)->dev);
|
|
SET_IEEE80211_PERM_ADDR(rt2x00dev->hw,
|
|
SET_IEEE80211_PERM_ADDR(rt2x00dev->hw,
|
|
@@ -1776,8 +1800,8 @@ static void rt73usb_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
|
|
/*
|
|
/*
|
|
* Initialize hw_mode information.
|
|
* Initialize hw_mode information.
|
|
*/
|
|
*/
|
|
- spec->num_modes = 2;
|
|
|
|
- spec->num_rates = 12;
|
|
|
|
|
|
+ spec->supported_bands = SUPPORT_BAND_2GHZ;
|
|
|
|
+ spec->supported_rates = SUPPORT_RATE_CCK | SUPPORT_RATE_OFDM;
|
|
spec->tx_power_a = NULL;
|
|
spec->tx_power_a = NULL;
|
|
spec->tx_power_bg = txpower;
|
|
spec->tx_power_bg = txpower;
|
|
spec->tx_power_default = DEFAULT_TXPOWER;
|
|
spec->tx_power_default = DEFAULT_TXPOWER;
|
|
@@ -1786,20 +1810,20 @@ static void rt73usb_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
|
|
spec->num_channels = ARRAY_SIZE(rf_vals_bg_2528);
|
|
spec->num_channels = ARRAY_SIZE(rf_vals_bg_2528);
|
|
spec->channels = rf_vals_bg_2528;
|
|
spec->channels = rf_vals_bg_2528;
|
|
} else if (rt2x00_rf(&rt2x00dev->chip, RF5226)) {
|
|
} else if (rt2x00_rf(&rt2x00dev->chip, RF5226)) {
|
|
|
|
+ spec->supported_bands |= SUPPORT_BAND_5GHZ;
|
|
spec->num_channels = ARRAY_SIZE(rf_vals_5226);
|
|
spec->num_channels = ARRAY_SIZE(rf_vals_5226);
|
|
spec->channels = rf_vals_5226;
|
|
spec->channels = rf_vals_5226;
|
|
} else if (rt2x00_rf(&rt2x00dev->chip, RF2527)) {
|
|
} else if (rt2x00_rf(&rt2x00dev->chip, RF2527)) {
|
|
spec->num_channels = 14;
|
|
spec->num_channels = 14;
|
|
spec->channels = rf_vals_5225_2527;
|
|
spec->channels = rf_vals_5225_2527;
|
|
} else if (rt2x00_rf(&rt2x00dev->chip, RF5225)) {
|
|
} else if (rt2x00_rf(&rt2x00dev->chip, RF5225)) {
|
|
|
|
+ spec->supported_bands |= SUPPORT_BAND_5GHZ;
|
|
spec->num_channels = ARRAY_SIZE(rf_vals_5225_2527);
|
|
spec->num_channels = ARRAY_SIZE(rf_vals_5225_2527);
|
|
spec->channels = rf_vals_5225_2527;
|
|
spec->channels = rf_vals_5225_2527;
|
|
}
|
|
}
|
|
|
|
|
|
if (rt2x00_rf(&rt2x00dev->chip, RF5225) ||
|
|
if (rt2x00_rf(&rt2x00dev->chip, RF5225) ||
|
|
rt2x00_rf(&rt2x00dev->chip, RF5226)) {
|
|
rt2x00_rf(&rt2x00dev->chip, RF5226)) {
|
|
- spec->num_modes = 3;
|
|
|
|
-
|
|
|
|
txpower = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_A_START);
|
|
txpower = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_A_START);
|
|
for (i = 0; i < 14; i++)
|
|
for (i = 0; i < 14; i++)
|
|
txpower[i] = TXPOWER_FROM_DEV(txpower[i]);
|
|
txpower[i] = TXPOWER_FROM_DEV(txpower[i]);
|
|
@@ -1829,9 +1853,10 @@ static int rt73usb_probe_hw(struct rt2x00_dev *rt2x00dev)
|
|
rt73usb_probe_hw_mode(rt2x00dev);
|
|
rt73usb_probe_hw_mode(rt2x00dev);
|
|
|
|
|
|
/*
|
|
/*
|
|
- * This device requires firmware
|
|
|
|
|
|
+ * This device requires firmware.
|
|
*/
|
|
*/
|
|
__set_bit(DRIVER_REQUIRE_FIRMWARE, &rt2x00dev->flags);
|
|
__set_bit(DRIVER_REQUIRE_FIRMWARE, &rt2x00dev->flags);
|
|
|
|
+ __set_bit(DRIVER_REQUIRE_FIRMWARE_CRC_ITU_T, &rt2x00dev->flags);
|
|
|
|
|
|
/*
|
|
/*
|
|
* Set the rssi offset.
|
|
* Set the rssi offset.
|
|
@@ -1913,7 +1938,8 @@ static void rt73usb_configure_filter(struct ieee80211_hw *hw,
|
|
rt2x00_set_field32(®, TXRX_CSR0_DROP_MULTICAST,
|
|
rt2x00_set_field32(®, TXRX_CSR0_DROP_MULTICAST,
|
|
!(*total_flags & FIF_ALLMULTI));
|
|
!(*total_flags & FIF_ALLMULTI));
|
|
rt2x00_set_field32(®, TXRX_CSR0_DROP_BROADCAST, 0);
|
|
rt2x00_set_field32(®, TXRX_CSR0_DROP_BROADCAST, 0);
|
|
- rt2x00_set_field32(®, TXRX_CSR0_DROP_ACK_CTS, 1);
|
|
|
|
|
|
+ rt2x00_set_field32(®, TXRX_CSR0_DROP_ACK_CTS,
|
|
|
|
+ !(*total_flags & FIF_CONTROL));
|
|
rt73usb_register_write(rt2x00dev, TXRX_CSR0, reg);
|
|
rt73usb_register_write(rt2x00dev, TXRX_CSR0, reg);
|
|
}
|
|
}
|
|
|
|
|
|
@@ -1955,61 +1981,54 @@ static u64 rt73usb_get_tsf(struct ieee80211_hw *hw)
|
|
#define rt73usb_get_tsf NULL
|
|
#define rt73usb_get_tsf NULL
|
|
#endif
|
|
#endif
|
|
|
|
|
|
-static void rt73usb_reset_tsf(struct ieee80211_hw *hw)
|
|
|
|
-{
|
|
|
|
- struct rt2x00_dev *rt2x00dev = hw->priv;
|
|
|
|
-
|
|
|
|
- rt73usb_register_write(rt2x00dev, TXRX_CSR12, 0);
|
|
|
|
- rt73usb_register_write(rt2x00dev, TXRX_CSR13, 0);
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
static int rt73usb_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb,
|
|
static int rt73usb_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb,
|
|
- struct ieee80211_tx_control *control)
|
|
|
|
|
|
+ struct ieee80211_tx_control *control)
|
|
{
|
|
{
|
|
struct rt2x00_dev *rt2x00dev = hw->priv;
|
|
struct rt2x00_dev *rt2x00dev = hw->priv;
|
|
- struct skb_desc *desc;
|
|
|
|
- struct data_ring *ring;
|
|
|
|
- struct data_entry *entry;
|
|
|
|
- int timeout;
|
|
|
|
|
|
+ struct rt2x00_intf *intf = vif_to_intf(control->vif);
|
|
|
|
+ struct skb_frame_desc *skbdesc;
|
|
|
|
+ unsigned int beacon_base;
|
|
|
|
+ unsigned int timeout;
|
|
|
|
|
|
- /*
|
|
|
|
- * Just in case the ieee80211 doesn't set this,
|
|
|
|
- * but we need this queue set for the descriptor
|
|
|
|
- * initialization.
|
|
|
|
- */
|
|
|
|
- control->queue = IEEE80211_TX_QUEUE_BEACON;
|
|
|
|
- ring = rt2x00lib_get_ring(rt2x00dev, control->queue);
|
|
|
|
- entry = rt2x00_get_data_entry(ring);
|
|
|
|
|
|
+ if (unlikely(!intf->beacon))
|
|
|
|
+ return -ENOBUFS;
|
|
|
|
|
|
/*
|
|
/*
|
|
* Add the descriptor in front of the skb.
|
|
* Add the descriptor in front of the skb.
|
|
*/
|
|
*/
|
|
- skb_push(skb, ring->desc_size);
|
|
|
|
- memset(skb->data, 0, ring->desc_size);
|
|
|
|
|
|
+ skb_push(skb, intf->beacon->queue->desc_size);
|
|
|
|
+ memset(skb->data, 0, intf->beacon->queue->desc_size);
|
|
|
|
|
|
/*
|
|
/*
|
|
* Fill in skb descriptor
|
|
* Fill in skb descriptor
|
|
*/
|
|
*/
|
|
- desc = get_skb_desc(skb);
|
|
|
|
- desc->desc_len = ring->desc_size;
|
|
|
|
- desc->data_len = skb->len - ring->desc_size;
|
|
|
|
- desc->desc = skb->data;
|
|
|
|
- desc->data = skb->data + ring->desc_size;
|
|
|
|
- desc->ring = ring;
|
|
|
|
- desc->entry = entry;
|
|
|
|
|
|
+ skbdesc = get_skb_frame_desc(skb);
|
|
|
|
+ memset(skbdesc, 0, sizeof(*skbdesc));
|
|
|
|
+ skbdesc->flags |= FRAME_DESC_DRIVER_GENERATED;
|
|
|
|
+ skbdesc->data = skb->data + intf->beacon->queue->desc_size;
|
|
|
|
+ skbdesc->data_len = skb->len - intf->beacon->queue->desc_size;
|
|
|
|
+ skbdesc->desc = skb->data;
|
|
|
|
+ skbdesc->desc_len = intf->beacon->queue->desc_size;
|
|
|
|
+ skbdesc->entry = intf->beacon;
|
|
|
|
|
|
|
|
+ /*
|
|
|
|
+ * mac80211 doesn't provide the control->queue variable
|
|
|
|
+ * for beacons. Set our own queue identification so
|
|
|
|
+ * it can be used during descriptor initialization.
|
|
|
|
+ */
|
|
|
|
+ control->queue = RT2X00_BCN_QUEUE_BEACON;
|
|
rt2x00lib_write_tx_desc(rt2x00dev, skb, control);
|
|
rt2x00lib_write_tx_desc(rt2x00dev, skb, control);
|
|
|
|
|
|
/*
|
|
/*
|
|
* Write entire beacon with descriptor to register,
|
|
* Write entire beacon with descriptor to register,
|
|
* and kick the beacon generator.
|
|
* and kick the beacon generator.
|
|
*/
|
|
*/
|
|
|
|
+ beacon_base = HW_BEACON_OFFSET(intf->beacon->entry_idx);
|
|
timeout = REGISTER_TIMEOUT * (skb->len / sizeof(u32));
|
|
timeout = REGISTER_TIMEOUT * (skb->len / sizeof(u32));
|
|
rt2x00usb_vendor_request(rt2x00dev, USB_MULTI_WRITE,
|
|
rt2x00usb_vendor_request(rt2x00dev, USB_MULTI_WRITE,
|
|
- USB_VENDOR_REQUEST_OUT,
|
|
|
|
- HW_BEACON_BASE0, 0x0000,
|
|
|
|
|
|
+ USB_VENDOR_REQUEST_OUT, beacon_base, 0,
|
|
skb->data, skb->len, timeout);
|
|
skb->data, skb->len, timeout);
|
|
- rt73usb_kick_tx_queue(rt2x00dev, IEEE80211_TX_QUEUE_BEACON);
|
|
|
|
|
|
+ rt73usb_kick_tx_queue(rt2x00dev, control->queue);
|
|
|
|
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
@@ -2029,7 +2048,6 @@ static const struct ieee80211_ops rt73usb_mac80211_ops = {
|
|
.conf_tx = rt2x00mac_conf_tx,
|
|
.conf_tx = rt2x00mac_conf_tx,
|
|
.get_tx_stats = rt2x00mac_get_tx_stats,
|
|
.get_tx_stats = rt2x00mac_get_tx_stats,
|
|
.get_tsf = rt73usb_get_tsf,
|
|
.get_tsf = rt73usb_get_tsf,
|
|
- .reset_tsf = rt73usb_reset_tsf,
|
|
|
|
.beacon_update = rt73usb_beacon_update,
|
|
.beacon_update = rt73usb_beacon_update,
|
|
};
|
|
};
|
|
|
|
|
|
@@ -2045,24 +2063,47 @@ static const struct rt2x00lib_ops rt73usb_rt2x00_ops = {
|
|
.link_stats = rt73usb_link_stats,
|
|
.link_stats = rt73usb_link_stats,
|
|
.reset_tuner = rt73usb_reset_tuner,
|
|
.reset_tuner = rt73usb_reset_tuner,
|
|
.link_tuner = rt73usb_link_tuner,
|
|
.link_tuner = rt73usb_link_tuner,
|
|
|
|
+ .led_brightness = rt73usb_led_brightness,
|
|
.write_tx_desc = rt73usb_write_tx_desc,
|
|
.write_tx_desc = rt73usb_write_tx_desc,
|
|
.write_tx_data = rt2x00usb_write_tx_data,
|
|
.write_tx_data = rt2x00usb_write_tx_data,
|
|
.get_tx_data_len = rt73usb_get_tx_data_len,
|
|
.get_tx_data_len = rt73usb_get_tx_data_len,
|
|
.kick_tx_queue = rt73usb_kick_tx_queue,
|
|
.kick_tx_queue = rt73usb_kick_tx_queue,
|
|
.fill_rxdone = rt73usb_fill_rxdone,
|
|
.fill_rxdone = rt73usb_fill_rxdone,
|
|
- .config_mac_addr = rt73usb_config_mac_addr,
|
|
|
|
- .config_bssid = rt73usb_config_bssid,
|
|
|
|
- .config_type = rt73usb_config_type,
|
|
|
|
|
|
+ .config_intf = rt73usb_config_intf,
|
|
.config_preamble = rt73usb_config_preamble,
|
|
.config_preamble = rt73usb_config_preamble,
|
|
.config = rt73usb_config,
|
|
.config = rt73usb_config,
|
|
};
|
|
};
|
|
|
|
|
|
|
|
+static const struct data_queue_desc rt73usb_queue_rx = {
|
|
|
|
+ .entry_num = RX_ENTRIES,
|
|
|
|
+ .data_size = DATA_FRAME_SIZE,
|
|
|
|
+ .desc_size = RXD_DESC_SIZE,
|
|
|
|
+ .priv_size = sizeof(struct queue_entry_priv_usb_rx),
|
|
|
|
+};
|
|
|
|
+
|
|
|
|
+static const struct data_queue_desc rt73usb_queue_tx = {
|
|
|
|
+ .entry_num = TX_ENTRIES,
|
|
|
|
+ .data_size = DATA_FRAME_SIZE,
|
|
|
|
+ .desc_size = TXD_DESC_SIZE,
|
|
|
|
+ .priv_size = sizeof(struct queue_entry_priv_usb_tx),
|
|
|
|
+};
|
|
|
|
+
|
|
|
|
+static const struct data_queue_desc rt73usb_queue_bcn = {
|
|
|
|
+ .entry_num = 4 * BEACON_ENTRIES,
|
|
|
|
+ .data_size = MGMT_FRAME_SIZE,
|
|
|
|
+ .desc_size = TXINFO_SIZE,
|
|
|
|
+ .priv_size = sizeof(struct queue_entry_priv_usb_tx),
|
|
|
|
+};
|
|
|
|
+
|
|
static const struct rt2x00_ops rt73usb_ops = {
|
|
static const struct rt2x00_ops rt73usb_ops = {
|
|
.name = KBUILD_MODNAME,
|
|
.name = KBUILD_MODNAME,
|
|
- .rxd_size = RXD_DESC_SIZE,
|
|
|
|
- .txd_size = TXD_DESC_SIZE,
|
|
|
|
|
|
+ .max_sta_intf = 1,
|
|
|
|
+ .max_ap_intf = 4,
|
|
.eeprom_size = EEPROM_SIZE,
|
|
.eeprom_size = EEPROM_SIZE,
|
|
.rf_size = RF_SIZE,
|
|
.rf_size = RF_SIZE,
|
|
|
|
+ .rx = &rt73usb_queue_rx,
|
|
|
|
+ .tx = &rt73usb_queue_tx,
|
|
|
|
+ .bcn = &rt73usb_queue_bcn,
|
|
.lib = &rt73usb_rt2x00_ops,
|
|
.lib = &rt73usb_rt2x00_ops,
|
|
.hw = &rt73usb_mac80211_ops,
|
|
.hw = &rt73usb_mac80211_ops,
|
|
#ifdef CONFIG_RT2X00_LIB_DEBUGFS
|
|
#ifdef CONFIG_RT2X00_LIB_DEBUGFS
|