diff options
Diffstat (limited to 'drivers/net/wireless/rt2x00/rt73usb.c')
-rw-r--r-- | drivers/net/wireless/rt2x00/rt73usb.c | 179 |
1 files changed, 98 insertions, 81 deletions
diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c index 8ebf3fed9815..7907fd0d4aa5 100644 --- a/drivers/net/wireless/rt2x00/rt73usb.c +++ b/drivers/net/wireless/rt2x00/rt73usb.c | |||
@@ -281,74 +281,69 @@ static const struct rt2x00debug rt73usb_rt2x00debug = { | |||
281 | /* | 281 | /* |
282 | * Configuration handlers. | 282 | * Configuration handlers. |
283 | */ | 283 | */ |
284 | static void rt73usb_config_mac_addr(struct rt2x00_dev *rt2x00dev, __le32 *mac) | 284 | static void rt73usb_config_intf(struct rt2x00_dev *rt2x00dev, |
285 | struct rt2x00_intf *intf, | ||
286 | struct rt2x00intf_conf *conf, | ||
287 | const unsigned int flags) | ||
285 | { | 288 | { |
286 | u32 tmp; | 289 | unsigned int beacon_base; |
287 | 290 | u32 reg; | |
288 | tmp = le32_to_cpu(mac[1]); | ||
289 | rt2x00_set_field32(&tmp, MAC_CSR3_UNICAST_TO_ME_MASK, 0xff); | ||
290 | mac[1] = cpu_to_le32(tmp); | ||
291 | |||
292 | rt73usb_register_multiwrite(rt2x00dev, MAC_CSR2, mac, | ||
293 | (2 * sizeof(__le32))); | ||
294 | } | ||
295 | 291 | ||
296 | static void rt73usb_config_bssid(struct rt2x00_dev *rt2x00dev, __le32 *bssid) | 292 | if (flags & CONFIG_UPDATE_TYPE) { |
297 | { | 293 | /* |
298 | u32 tmp; | 294 | * Clear current synchronisation setup. |
295 | * For the Beacon base registers we only need to clear | ||
296 | * the first byte since that byte contains the VALID and OWNER | ||
297 | * bits which (when set to 0) will invalidate the entire beacon. | ||
298 | */ | ||
299 | beacon_base = HW_BEACON_OFFSET(intf->beacon->entry_idx); | ||
300 | rt73usb_register_write(rt2x00dev, TXRX_CSR9, 0); | ||
301 | rt73usb_register_write(rt2x00dev, beacon_base, 0); | ||
299 | 302 | ||
300 | tmp = le32_to_cpu(bssid[1]); | 303 | /* |
301 | rt2x00_set_field32(&tmp, MAC_CSR5_BSS_ID_MASK, 3); | 304 | * Enable synchronisation. |
302 | bssid[1] = cpu_to_le32(tmp); | 305 | */ |
306 | rt73usb_register_read(rt2x00dev, TXRX_CSR9, ®); | ||
307 | rt2x00_set_field32(®, TXRX_CSR9_TSF_TICKING, 1); | ||
308 | rt2x00_set_field32(®, TXRX_CSR9_TBTT_ENABLE, | ||
309 | (conf->sync == TSF_SYNC_BEACON)); | ||
310 | rt2x00_set_field32(®, TXRX_CSR9_BEACON_GEN, 0); | ||
311 | rt2x00_set_field32(®, TXRX_CSR9_TSF_SYNC, conf->sync); | ||
312 | rt73usb_register_write(rt2x00dev, TXRX_CSR9, reg); | ||
313 | } | ||
303 | 314 | ||
304 | rt73usb_register_multiwrite(rt2x00dev, MAC_CSR4, bssid, | 315 | if (flags & CONFIG_UPDATE_MAC) { |
305 | (2 * sizeof(__le32))); | 316 | reg = le32_to_cpu(conf->mac[1]); |
306 | } | 317 | rt2x00_set_field32(®, MAC_CSR3_UNICAST_TO_ME_MASK, 0xff); |
318 | conf->mac[1] = cpu_to_le32(reg); | ||
307 | 319 | ||
308 | static void rt73usb_config_type(struct rt2x00_dev *rt2x00dev, const int type, | 320 | rt73usb_register_multiwrite(rt2x00dev, MAC_CSR2, |
309 | const int tsf_sync) | 321 | conf->mac, sizeof(conf->mac)); |
310 | { | 322 | } |
311 | u32 reg; | ||
312 | 323 | ||
313 | /* | 324 | if (flags & CONFIG_UPDATE_BSSID) { |
314 | * Clear current synchronisation setup. | 325 | reg = le32_to_cpu(conf->bssid[1]); |
315 | * For the Beacon base registers we only need to clear | 326 | rt2x00_set_field32(®, MAC_CSR5_BSS_ID_MASK, 3); |
316 | * the first byte since that byte contains the VALID and OWNER | 327 | conf->bssid[1] = cpu_to_le32(reg); |
317 | * bits which (when set to 0) will invalidate the entire beacon. | ||
318 | */ | ||
319 | rt73usb_register_write(rt2x00dev, TXRX_CSR9, 0); | ||
320 | rt73usb_register_write(rt2x00dev, HW_BEACON_BASE0, 0); | ||
321 | rt73usb_register_write(rt2x00dev, HW_BEACON_BASE1, 0); | ||
322 | rt73usb_register_write(rt2x00dev, HW_BEACON_BASE2, 0); | ||
323 | rt73usb_register_write(rt2x00dev, HW_BEACON_BASE3, 0); | ||
324 | 328 | ||
325 | /* | 329 | rt73usb_register_multiwrite(rt2x00dev, MAC_CSR4, |
326 | * Enable synchronisation. | 330 | conf->bssid, sizeof(conf->bssid)); |
327 | */ | 331 | } |
328 | rt73usb_register_read(rt2x00dev, TXRX_CSR9, ®); | ||
329 | rt2x00_set_field32(®, TXRX_CSR9_TSF_TICKING, 1); | ||
330 | rt2x00_set_field32(®, TXRX_CSR9_TBTT_ENABLE, | ||
331 | (tsf_sync == TSF_SYNC_BEACON)); | ||
332 | rt2x00_set_field32(®, TXRX_CSR9_BEACON_GEN, 0); | ||
333 | rt2x00_set_field32(®, TXRX_CSR9_TSF_SYNC, tsf_sync); | ||
334 | rt73usb_register_write(rt2x00dev, TXRX_CSR9, reg); | ||
335 | } | 332 | } |
336 | 333 | ||
337 | static void rt73usb_config_preamble(struct rt2x00_dev *rt2x00dev, | 334 | static int rt73usb_config_preamble(struct rt2x00_dev *rt2x00dev, |
338 | const int short_preamble, | 335 | const int short_preamble, |
339 | const int ack_timeout, | 336 | const int ack_timeout, |
340 | const int ack_consume_time) | 337 | const int ack_consume_time) |
341 | { | 338 | { |
342 | u32 reg; | 339 | u32 reg; |
343 | 340 | ||
344 | /* | 341 | /* |
345 | * When in atomic context, reschedule and let rt2x00lib | 342 | * When in atomic context, we should let rt2x00lib |
346 | * call this function again. | 343 | * try this configuration again later. |
347 | */ | 344 | */ |
348 | if (in_atomic()) { | 345 | if (in_atomic()) |
349 | queue_work(rt2x00dev->hw->workqueue, &rt2x00dev->config_work); | 346 | return -EAGAIN; |
350 | return; | ||
351 | } | ||
352 | 347 | ||
353 | rt73usb_register_read(rt2x00dev, TXRX_CSR0, ®); | 348 | rt73usb_register_read(rt2x00dev, TXRX_CSR0, ®); |
354 | rt2x00_set_field32(®, TXRX_CSR0_RX_ACK_TIMEOUT, ack_timeout); | 349 | rt2x00_set_field32(®, TXRX_CSR0_RX_ACK_TIMEOUT, ack_timeout); |
@@ -358,6 +353,8 @@ static void rt73usb_config_preamble(struct rt2x00_dev *rt2x00dev, | |||
358 | rt2x00_set_field32(®, TXRX_CSR4_AUTORESPOND_PREAMBLE, | 353 | rt2x00_set_field32(®, TXRX_CSR4_AUTORESPOND_PREAMBLE, |
359 | !!short_preamble); | 354 | !!short_preamble); |
360 | rt73usb_register_write(rt2x00dev, TXRX_CSR4, reg); | 355 | rt73usb_register_write(rt2x00dev, TXRX_CSR4, reg); |
356 | |||
357 | return 0; | ||
361 | } | 358 | } |
362 | 359 | ||
363 | static void rt73usb_config_phymode(struct rt2x00_dev *rt2x00dev, | 360 | static void rt73usb_config_phymode(struct rt2x00_dev *rt2x00dev, |
@@ -617,8 +614,8 @@ static void rt73usb_config_duration(struct rt2x00_dev *rt2x00dev, | |||
617 | } | 614 | } |
618 | 615 | ||
619 | static void rt73usb_config(struct rt2x00_dev *rt2x00dev, | 616 | static void rt73usb_config(struct rt2x00_dev *rt2x00dev, |
620 | const unsigned int flags, | 617 | struct rt2x00lib_conf *libconf, |
621 | struct rt2x00lib_conf *libconf) | 618 | const unsigned int flags) |
622 | { | 619 | { |
623 | if (flags & CONFIG_UPDATE_PHYMODE) | 620 | if (flags & CONFIG_UPDATE_PHYMODE) |
624 | rt73usb_config_phymode(rt2x00dev, libconf->basic_rates); | 621 | rt73usb_config_phymode(rt2x00dev, libconf->basic_rates); |
@@ -766,6 +763,13 @@ static void rt73usb_link_tuner(struct rt2x00_dev *rt2x00dev) | |||
766 | } | 763 | } |
767 | 764 | ||
768 | /* | 765 | /* |
766 | * If we are not associated, we should go straight to the | ||
767 | * dynamic CCA tuning. | ||
768 | */ | ||
769 | if (!rt2x00dev->intf_associated) | ||
770 | goto dynamic_cca_tune; | ||
771 | |||
772 | /* | ||
769 | * Special big-R17 for very short distance | 773 | * Special big-R17 for very short distance |
770 | */ | 774 | */ |
771 | if (rssi > -35) { | 775 | if (rssi > -35) { |
@@ -815,6 +819,8 @@ static void rt73usb_link_tuner(struct rt2x00_dev *rt2x00dev) | |||
815 | return; | 819 | return; |
816 | } | 820 | } |
817 | 821 | ||
822 | dynamic_cca_tune: | ||
823 | |||
818 | /* | 824 | /* |
819 | * r17 does not yet exceed upper limit, continue and base | 825 | * r17 does not yet exceed upper limit, continue and base |
820 | * the r17 tuning on the false CCA count. | 826 | * the r17 tuning on the false CCA count. |
@@ -1021,6 +1027,17 @@ static int rt73usb_init_registers(struct rt2x00_dev *rt2x00dev) | |||
1021 | rt73usb_register_write(rt2x00dev, MAC_CSR9, reg); | 1027 | rt73usb_register_write(rt2x00dev, MAC_CSR9, reg); |
1022 | 1028 | ||
1023 | /* | 1029 | /* |
1030 | * Clear all beacons | ||
1031 | * For the Beacon base registers we only need to clear | ||
1032 | * the first byte since that byte contains the VALID and OWNER | ||
1033 | * bits which (when set to 0) will invalidate the entire beacon. | ||
1034 | */ | ||
1035 | rt73usb_register_write(rt2x00dev, HW_BEACON_BASE0, 0); | ||
1036 | rt73usb_register_write(rt2x00dev, HW_BEACON_BASE1, 0); | ||
1037 | rt73usb_register_write(rt2x00dev, HW_BEACON_BASE2, 0); | ||
1038 | rt73usb_register_write(rt2x00dev, HW_BEACON_BASE3, 0); | ||
1039 | |||
1040 | /* | ||
1024 | * We must clear the error counters. | 1041 | * We must clear the error counters. |
1025 | * These registers are cleared on read, | 1042 | * These registers are cleared on read, |
1026 | * so we may pass a useless variable to store the value. | 1043 | * so we may pass a useless variable to store the value. |
@@ -1985,52 +2002,52 @@ static void rt73usb_reset_tsf(struct ieee80211_hw *hw) | |||
1985 | } | 2002 | } |
1986 | 2003 | ||
1987 | static int rt73usb_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb, | 2004 | static int rt73usb_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb, |
1988 | struct ieee80211_tx_control *control) | 2005 | struct ieee80211_tx_control *control) |
1989 | { | 2006 | { |
1990 | struct rt2x00_dev *rt2x00dev = hw->priv; | 2007 | struct rt2x00_dev *rt2x00dev = hw->priv; |
2008 | struct rt2x00_intf *intf = vif_to_intf(control->vif); | ||
1991 | struct skb_frame_desc *skbdesc; | 2009 | struct skb_frame_desc *skbdesc; |
1992 | struct data_queue *queue; | 2010 | unsigned int beacon_base; |
1993 | struct queue_entry *entry; | 2011 | unsigned int timeout; |
1994 | int timeout; | ||
1995 | 2012 | ||
1996 | /* | 2013 | if (unlikely(!intf->beacon)) |
1997 | * Just in case the ieee80211 doesn't set this, | 2014 | return -ENOBUFS; |
1998 | * but we need this queue set for the descriptor | ||
1999 | * initialization. | ||
2000 | */ | ||
2001 | control->queue = IEEE80211_TX_QUEUE_BEACON; | ||
2002 | queue = rt2x00queue_get_queue(rt2x00dev, control->queue); | ||
2003 | entry = rt2x00queue_get_entry(queue, Q_INDEX); | ||
2004 | 2015 | ||
2005 | /* | 2016 | /* |
2006 | * Add the descriptor in front of the skb. | 2017 | * Add the descriptor in front of the skb. |
2007 | */ | 2018 | */ |
2008 | skb_push(skb, queue->desc_size); | 2019 | skb_push(skb, intf->beacon->queue->desc_size); |
2009 | memset(skb->data, 0, queue->desc_size); | 2020 | memset(skb->data, 0, intf->beacon->queue->desc_size); |
2010 | 2021 | ||
2011 | /* | 2022 | /* |
2012 | * Fill in skb descriptor | 2023 | * Fill in skb descriptor |
2013 | */ | 2024 | */ |
2014 | skbdesc = get_skb_frame_desc(skb); | 2025 | skbdesc = get_skb_frame_desc(skb); |
2015 | memset(skbdesc, 0, sizeof(*skbdesc)); | 2026 | memset(skbdesc, 0, sizeof(*skbdesc)); |
2016 | skbdesc->data = skb->data + queue->desc_size; | 2027 | skbdesc->data = skb->data + intf->beacon->queue->desc_size; |
2017 | skbdesc->data_len = queue->data_size; | 2028 | skbdesc->data_len = skb->len - intf->beacon->queue->desc_size; |
2018 | skbdesc->desc = skb->data; | 2029 | skbdesc->desc = skb->data; |
2019 | skbdesc->desc_len = queue->desc_size; | 2030 | skbdesc->desc_len = intf->beacon->queue->desc_size; |
2020 | skbdesc->entry = entry; | 2031 | skbdesc->entry = intf->beacon; |
2021 | 2032 | ||
2033 | /* | ||
2034 | * Just in case the ieee80211 doesn't set this, | ||
2035 | * but we need this queue set for the descriptor | ||
2036 | * initialization. | ||
2037 | */ | ||
2038 | control->queue = IEEE80211_TX_QUEUE_BEACON; | ||
2022 | rt2x00lib_write_tx_desc(rt2x00dev, skb, control); | 2039 | rt2x00lib_write_tx_desc(rt2x00dev, skb, control); |
2023 | 2040 | ||
2024 | /* | 2041 | /* |
2025 | * Write entire beacon with descriptor to register, | 2042 | * Write entire beacon with descriptor to register, |
2026 | * and kick the beacon generator. | 2043 | * and kick the beacon generator. |
2027 | */ | 2044 | */ |
2045 | beacon_base = HW_BEACON_OFFSET(intf->beacon->entry_idx); | ||
2028 | timeout = REGISTER_TIMEOUT * (skb->len / sizeof(u32)); | 2046 | timeout = REGISTER_TIMEOUT * (skb->len / sizeof(u32)); |
2029 | rt2x00usb_vendor_request(rt2x00dev, USB_MULTI_WRITE, | 2047 | rt2x00usb_vendor_request(rt2x00dev, USB_MULTI_WRITE, |
2030 | USB_VENDOR_REQUEST_OUT, | 2048 | USB_VENDOR_REQUEST_OUT, beacon_base, 0, |
2031 | HW_BEACON_BASE0, 0x0000, | ||
2032 | skb->data, skb->len, timeout); | 2049 | skb->data, skb->len, timeout); |
2033 | rt73usb_kick_tx_queue(rt2x00dev, IEEE80211_TX_QUEUE_BEACON); | 2050 | rt73usb_kick_tx_queue(rt2x00dev, control->queue); |
2034 | 2051 | ||
2035 | return 0; | 2052 | return 0; |
2036 | } | 2053 | } |
@@ -2071,9 +2088,7 @@ static const struct rt2x00lib_ops rt73usb_rt2x00_ops = { | |||
2071 | .get_tx_data_len = rt73usb_get_tx_data_len, | 2088 | .get_tx_data_len = rt73usb_get_tx_data_len, |
2072 | .kick_tx_queue = rt73usb_kick_tx_queue, | 2089 | .kick_tx_queue = rt73usb_kick_tx_queue, |
2073 | .fill_rxdone = rt73usb_fill_rxdone, | 2090 | .fill_rxdone = rt73usb_fill_rxdone, |
2074 | .config_mac_addr = rt73usb_config_mac_addr, | 2091 | .config_intf = rt73usb_config_intf, |
2075 | .config_bssid = rt73usb_config_bssid, | ||
2076 | .config_type = rt73usb_config_type, | ||
2077 | .config_preamble = rt73usb_config_preamble, | 2092 | .config_preamble = rt73usb_config_preamble, |
2078 | .config = rt73usb_config, | 2093 | .config = rt73usb_config, |
2079 | }; | 2094 | }; |
@@ -2093,7 +2108,7 @@ static const struct data_queue_desc rt73usb_queue_tx = { | |||
2093 | }; | 2108 | }; |
2094 | 2109 | ||
2095 | static const struct data_queue_desc rt73usb_queue_bcn = { | 2110 | static const struct data_queue_desc rt73usb_queue_bcn = { |
2096 | .entry_num = BEACON_ENTRIES, | 2111 | .entry_num = 4 * BEACON_ENTRIES, |
2097 | .data_size = MGMT_FRAME_SIZE, | 2112 | .data_size = MGMT_FRAME_SIZE, |
2098 | .desc_size = TXINFO_SIZE, | 2113 | .desc_size = TXINFO_SIZE, |
2099 | .priv_size = sizeof(struct queue_entry_priv_usb_tx), | 2114 | .priv_size = sizeof(struct queue_entry_priv_usb_tx), |
@@ -2101,6 +2116,8 @@ static const struct data_queue_desc rt73usb_queue_bcn = { | |||
2101 | 2116 | ||
2102 | static const struct rt2x00_ops rt73usb_ops = { | 2117 | static const struct rt2x00_ops rt73usb_ops = { |
2103 | .name = KBUILD_MODNAME, | 2118 | .name = KBUILD_MODNAME, |
2119 | .max_sta_intf = 1, | ||
2120 | .max_ap_intf = 4, | ||
2104 | .eeprom_size = EEPROM_SIZE, | 2121 | .eeprom_size = EEPROM_SIZE, |
2105 | .rf_size = RF_SIZE, | 2122 | .rf_size = RF_SIZE, |
2106 | .rx = &rt73usb_queue_rx, | 2123 | .rx = &rt73usb_queue_rx, |