diff options
Diffstat (limited to 'drivers/net/wireless/rt2x00/rt2500pci.c')
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2500pci.c | 491 |
1 files changed, 288 insertions, 203 deletions
diff --git a/drivers/net/wireless/rt2x00/rt2500pci.c b/drivers/net/wireless/rt2x00/rt2500pci.c index 91e87b53374f..0f5139a2f238 100644 --- a/drivers/net/wireless/rt2x00/rt2500pci.c +++ b/drivers/net/wireless/rt2x00/rt2500pci.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | Copyright (C) 2004 - 2007 rt2x00 SourceForge Project | 2 | Copyright (C) 2004 - 2008 rt2x00 SourceForge Project |
3 | <http://rt2x00.serialmonkey.com> | 3 | <http://rt2x00.serialmonkey.com> |
4 | 4 | ||
5 | This program is free software; you can redistribute it and/or modify | 5 | This program is free software; you can redistribute it and/or modify |
@@ -243,57 +243,74 @@ static int rt2500pci_rfkill_poll(struct rt2x00_dev *rt2x00dev) | |||
243 | #define rt2500pci_rfkill_poll NULL | 243 | #define rt2500pci_rfkill_poll NULL |
244 | #endif /* CONFIG_RT2500PCI_RFKILL */ | 244 | #endif /* CONFIG_RT2500PCI_RFKILL */ |
245 | 245 | ||
246 | /* | 246 | #ifdef CONFIG_RT2500PCI_LEDS |
247 | * Configuration handlers. | 247 | static void rt2500pci_led_brightness(struct led_classdev *led_cdev, |
248 | */ | 248 | enum led_brightness brightness) |
249 | static void rt2500pci_config_mac_addr(struct rt2x00_dev *rt2x00dev, | ||
250 | __le32 *mac) | ||
251 | { | 249 | { |
252 | rt2x00pci_register_multiwrite(rt2x00dev, CSR3, mac, | 250 | struct rt2x00_led *led = |
253 | (2 * sizeof(__le32))); | 251 | container_of(led_cdev, struct rt2x00_led, led_dev); |
254 | } | 252 | unsigned int enabled = brightness != LED_OFF; |
253 | unsigned int activity = | ||
254 | led->rt2x00dev->led_flags & LED_SUPPORT_ACTIVITY; | ||
255 | u32 reg; | ||
255 | 256 | ||
256 | static void rt2500pci_config_bssid(struct rt2x00_dev *rt2x00dev, | 257 | rt2x00pci_register_read(led->rt2x00dev, LEDCSR, ®); |
257 | __le32 *bssid) | 258 | |
258 | { | 259 | if (led->type == LED_TYPE_RADIO || led->type == LED_TYPE_ASSOC) { |
259 | rt2x00pci_register_multiwrite(rt2x00dev, CSR5, bssid, | 260 | rt2x00_set_field32(®, LEDCSR_LINK, enabled); |
260 | (2 * sizeof(__le32))); | 261 | rt2x00_set_field32(®, LEDCSR_ACTIVITY, enabled && activity); |
262 | } | ||
263 | |||
264 | rt2x00pci_register_write(led->rt2x00dev, LEDCSR, reg); | ||
261 | } | 265 | } |
266 | #else | ||
267 | #define rt2500pci_led_brightness NULL | ||
268 | #endif /* CONFIG_RT2500PCI_LEDS */ | ||
262 | 269 | ||
263 | static void rt2500pci_config_type(struct rt2x00_dev *rt2x00dev, const int type, | 270 | /* |
264 | const int tsf_sync) | 271 | * Configuration handlers. |
272 | */ | ||
273 | static void rt2500pci_config_intf(struct rt2x00_dev *rt2x00dev, | ||
274 | struct rt2x00_intf *intf, | ||
275 | struct rt2x00intf_conf *conf, | ||
276 | const unsigned int flags) | ||
265 | { | 277 | { |
278 | struct data_queue *queue = | ||
279 | rt2x00queue_get_queue(rt2x00dev, RT2X00_BCN_QUEUE_BEACON); | ||
280 | unsigned int bcn_preload; | ||
266 | u32 reg; | 281 | u32 reg; |
267 | 282 | ||
268 | rt2x00pci_register_write(rt2x00dev, CSR14, 0); | 283 | if (flags & CONFIG_UPDATE_TYPE) { |
284 | /* | ||
285 | * Enable beacon config | ||
286 | */ | ||
287 | bcn_preload = PREAMBLE + get_duration(IEEE80211_HEADER, 20); | ||
288 | rt2x00pci_register_read(rt2x00dev, BCNCSR1, ®); | ||
289 | rt2x00_set_field32(®, BCNCSR1_PRELOAD, bcn_preload); | ||
290 | rt2x00_set_field32(®, BCNCSR1_BEACON_CWMIN, queue->cw_min); | ||
291 | rt2x00pci_register_write(rt2x00dev, BCNCSR1, reg); | ||
269 | 292 | ||
270 | /* | 293 | /* |
271 | * Enable beacon config | 294 | * Enable synchronisation. |
272 | */ | 295 | */ |
273 | rt2x00pci_register_read(rt2x00dev, BCNCSR1, ®); | 296 | rt2x00pci_register_read(rt2x00dev, CSR14, ®); |
274 | rt2x00_set_field32(®, BCNCSR1_PRELOAD, | 297 | rt2x00_set_field32(®, CSR14_TSF_COUNT, 1); |
275 | PREAMBLE + get_duration(IEEE80211_HEADER, 20)); | 298 | rt2x00_set_field32(®, CSR14_TSF_SYNC, conf->sync); |
276 | rt2x00_set_field32(®, BCNCSR1_BEACON_CWMIN, | 299 | rt2x00_set_field32(®, CSR14_TBCN, 1); |
277 | rt2x00lib_get_ring(rt2x00dev, | 300 | rt2x00pci_register_write(rt2x00dev, CSR14, reg); |
278 | IEEE80211_TX_QUEUE_BEACON) | 301 | } |
279 | ->tx_params.cw_min); | ||
280 | rt2x00pci_register_write(rt2x00dev, BCNCSR1, reg); | ||
281 | 302 | ||
282 | /* | 303 | if (flags & CONFIG_UPDATE_MAC) |
283 | * Enable synchronisation. | 304 | rt2x00pci_register_multiwrite(rt2x00dev, CSR3, |
284 | */ | 305 | conf->mac, sizeof(conf->mac)); |
285 | rt2x00pci_register_read(rt2x00dev, CSR14, ®); | 306 | |
286 | rt2x00_set_field32(®, CSR14_TSF_COUNT, 1); | 307 | if (flags & CONFIG_UPDATE_BSSID) |
287 | rt2x00_set_field32(®, CSR14_TBCN, (tsf_sync == TSF_SYNC_BEACON)); | 308 | rt2x00pci_register_multiwrite(rt2x00dev, CSR5, |
288 | rt2x00_set_field32(®, CSR14_BEACON_GEN, 0); | 309 | conf->bssid, sizeof(conf->bssid)); |
289 | rt2x00_set_field32(®, CSR14_TSF_SYNC, tsf_sync); | ||
290 | rt2x00pci_register_write(rt2x00dev, CSR14, reg); | ||
291 | } | 310 | } |
292 | 311 | ||
293 | static void rt2500pci_config_preamble(struct rt2x00_dev *rt2x00dev, | 312 | static int rt2500pci_config_erp(struct rt2x00_dev *rt2x00dev, |
294 | const int short_preamble, | 313 | struct rt2x00lib_erp *erp) |
295 | const int ack_timeout, | ||
296 | const int ack_consume_time) | ||
297 | { | 314 | { |
298 | int preamble_mask; | 315 | int preamble_mask; |
299 | u32 reg; | 316 | u32 reg; |
@@ -301,11 +318,13 @@ static void rt2500pci_config_preamble(struct rt2x00_dev *rt2x00dev, | |||
301 | /* | 318 | /* |
302 | * When short preamble is enabled, we should set bit 0x08 | 319 | * When short preamble is enabled, we should set bit 0x08 |
303 | */ | 320 | */ |
304 | preamble_mask = short_preamble << 3; | 321 | preamble_mask = erp->short_preamble << 3; |
305 | 322 | ||
306 | rt2x00pci_register_read(rt2x00dev, TXCSR1, ®); | 323 | rt2x00pci_register_read(rt2x00dev, TXCSR1, ®); |
307 | rt2x00_set_field32(®, TXCSR1_ACK_TIMEOUT, ack_timeout); | 324 | rt2x00_set_field32(®, TXCSR1_ACK_TIMEOUT, |
308 | rt2x00_set_field32(®, TXCSR1_ACK_CONSUME_TIME, ack_consume_time); | 325 | erp->ack_timeout); |
326 | rt2x00_set_field32(®, TXCSR1_ACK_CONSUME_TIME, | ||
327 | erp->ack_consume_time); | ||
309 | rt2x00pci_register_write(rt2x00dev, TXCSR1, reg); | 328 | rt2x00pci_register_write(rt2x00dev, TXCSR1, reg); |
310 | 329 | ||
311 | rt2x00pci_register_read(rt2x00dev, ARCSR2, ®); | 330 | rt2x00pci_register_read(rt2x00dev, ARCSR2, ®); |
@@ -331,6 +350,8 @@ static void rt2500pci_config_preamble(struct rt2x00_dev *rt2x00dev, | |||
331 | rt2x00_set_field32(®, ARCSR5_SERVICE, 0x84); | 350 | rt2x00_set_field32(®, ARCSR5_SERVICE, 0x84); |
332 | rt2x00_set_field32(®, ARCSR2_LENGTH, get_duration(ACK_SIZE, 110)); | 351 | rt2x00_set_field32(®, ARCSR2_LENGTH, get_duration(ACK_SIZE, 110)); |
333 | rt2x00pci_register_write(rt2x00dev, ARCSR5, reg); | 352 | rt2x00pci_register_write(rt2x00dev, ARCSR5, reg); |
353 | |||
354 | return 0; | ||
334 | } | 355 | } |
335 | 356 | ||
336 | static void rt2500pci_config_phymode(struct rt2x00_dev *rt2x00dev, | 357 | static void rt2500pci_config_phymode(struct rt2x00_dev *rt2x00dev, |
@@ -425,6 +446,13 @@ static void rt2500pci_config_antenna(struct rt2x00_dev *rt2x00dev, | |||
425 | u8 r14; | 446 | u8 r14; |
426 | u8 r2; | 447 | u8 r2; |
427 | 448 | ||
449 | /* | ||
450 | * We should never come here because rt2x00lib is supposed | ||
451 | * to catch this and send us the correct antenna explicitely. | ||
452 | */ | ||
453 | BUG_ON(ant->rx == ANTENNA_SW_DIVERSITY || | ||
454 | ant->tx == ANTENNA_SW_DIVERSITY); | ||
455 | |||
428 | rt2x00pci_register_read(rt2x00dev, BBPCSR1, ®); | 456 | rt2x00pci_register_read(rt2x00dev, BBPCSR1, ®); |
429 | rt2500pci_bbp_read(rt2x00dev, 14, &r14); | 457 | rt2500pci_bbp_read(rt2x00dev, 14, &r14); |
430 | rt2500pci_bbp_read(rt2x00dev, 2, &r2); | 458 | rt2500pci_bbp_read(rt2x00dev, 2, &r2); |
@@ -438,15 +466,8 @@ static void rt2500pci_config_antenna(struct rt2x00_dev *rt2x00dev, | |||
438 | rt2x00_set_field32(®, BBPCSR1_CCK, 0); | 466 | rt2x00_set_field32(®, BBPCSR1_CCK, 0); |
439 | rt2x00_set_field32(®, BBPCSR1_OFDM, 0); | 467 | rt2x00_set_field32(®, BBPCSR1_OFDM, 0); |
440 | break; | 468 | break; |
441 | case ANTENNA_HW_DIVERSITY: | ||
442 | case ANTENNA_SW_DIVERSITY: | ||
443 | /* | ||
444 | * NOTE: We should never come here because rt2x00lib is | ||
445 | * supposed to catch this and send us the correct antenna | ||
446 | * explicitely. However we are nog going to bug about this. | ||
447 | * Instead, just default to antenna B. | ||
448 | */ | ||
449 | case ANTENNA_B: | 469 | case ANTENNA_B: |
470 | default: | ||
450 | rt2x00_set_field8(&r2, BBP_R2_TX_ANTENNA, 2); | 471 | rt2x00_set_field8(&r2, BBP_R2_TX_ANTENNA, 2); |
451 | rt2x00_set_field32(®, BBPCSR1_CCK, 2); | 472 | rt2x00_set_field32(®, BBPCSR1_CCK, 2); |
452 | rt2x00_set_field32(®, BBPCSR1_OFDM, 2); | 473 | rt2x00_set_field32(®, BBPCSR1_OFDM, 2); |
@@ -460,15 +481,8 @@ static void rt2500pci_config_antenna(struct rt2x00_dev *rt2x00dev, | |||
460 | case ANTENNA_A: | 481 | case ANTENNA_A: |
461 | rt2x00_set_field8(&r14, BBP_R14_RX_ANTENNA, 0); | 482 | rt2x00_set_field8(&r14, BBP_R14_RX_ANTENNA, 0); |
462 | break; | 483 | break; |
463 | case ANTENNA_HW_DIVERSITY: | ||
464 | case ANTENNA_SW_DIVERSITY: | ||
465 | /* | ||
466 | * NOTE: We should never come here because rt2x00lib is | ||
467 | * supposed to catch this and send us the correct antenna | ||
468 | * explicitely. However we are nog going to bug about this. | ||
469 | * Instead, just default to antenna B. | ||
470 | */ | ||
471 | case ANTENNA_B: | 484 | case ANTENNA_B: |
485 | default: | ||
472 | rt2x00_set_field8(&r14, BBP_R14_RX_ANTENNA, 2); | 486 | rt2x00_set_field8(&r14, BBP_R14_RX_ANTENNA, 2); |
473 | break; | 487 | break; |
474 | } | 488 | } |
@@ -530,8 +544,8 @@ static void rt2500pci_config_duration(struct rt2x00_dev *rt2x00dev, | |||
530 | } | 544 | } |
531 | 545 | ||
532 | static void rt2500pci_config(struct rt2x00_dev *rt2x00dev, | 546 | static void rt2500pci_config(struct rt2x00_dev *rt2x00dev, |
533 | const unsigned int flags, | 547 | struct rt2x00lib_conf *libconf, |
534 | struct rt2x00lib_conf *libconf) | 548 | const unsigned int flags) |
535 | { | 549 | { |
536 | if (flags & CONFIG_UPDATE_PHYMODE) | 550 | if (flags & CONFIG_UPDATE_PHYMODE) |
537 | rt2500pci_config_phymode(rt2x00dev, libconf->basic_rates); | 551 | rt2500pci_config_phymode(rt2x00dev, libconf->basic_rates); |
@@ -548,34 +562,6 @@ static void rt2500pci_config(struct rt2x00_dev *rt2x00dev, | |||
548 | } | 562 | } |
549 | 563 | ||
550 | /* | 564 | /* |
551 | * LED functions. | ||
552 | */ | ||
553 | static void rt2500pci_enable_led(struct rt2x00_dev *rt2x00dev) | ||
554 | { | ||
555 | u32 reg; | ||
556 | |||
557 | rt2x00pci_register_read(rt2x00dev, LEDCSR, ®); | ||
558 | |||
559 | rt2x00_set_field32(®, LEDCSR_ON_PERIOD, 70); | ||
560 | rt2x00_set_field32(®, LEDCSR_OFF_PERIOD, 30); | ||
561 | rt2x00_set_field32(®, LEDCSR_LINK, | ||
562 | (rt2x00dev->led_mode != LED_MODE_ASUS)); | ||
563 | rt2x00_set_field32(®, LEDCSR_ACTIVITY, | ||
564 | (rt2x00dev->led_mode != LED_MODE_TXRX_ACTIVITY)); | ||
565 | rt2x00pci_register_write(rt2x00dev, LEDCSR, reg); | ||
566 | } | ||
567 | |||
568 | static void rt2500pci_disable_led(struct rt2x00_dev *rt2x00dev) | ||
569 | { | ||
570 | u32 reg; | ||
571 | |||
572 | rt2x00pci_register_read(rt2x00dev, LEDCSR, ®); | ||
573 | rt2x00_set_field32(®, LEDCSR_LINK, 0); | ||
574 | rt2x00_set_field32(®, LEDCSR_ACTIVITY, 0); | ||
575 | rt2x00pci_register_write(rt2x00dev, LEDCSR, reg); | ||
576 | } | ||
577 | |||
578 | /* | ||
579 | * Link tuning | 565 | * Link tuning |
580 | */ | 566 | */ |
581 | static void rt2500pci_link_stats(struct rt2x00_dev *rt2x00dev, | 567 | static void rt2500pci_link_stats(struct rt2x00_dev *rt2x00dev, |
@@ -610,9 +596,10 @@ static void rt2500pci_link_tuner(struct rt2x00_dev *rt2x00dev) | |||
610 | /* | 596 | /* |
611 | * To prevent collisions with MAC ASIC on chipsets | 597 | * To prevent collisions with MAC ASIC on chipsets |
612 | * up to version C the link tuning should halt after 20 | 598 | * up to version C the link tuning should halt after 20 |
613 | * seconds. | 599 | * seconds while being associated. |
614 | */ | 600 | */ |
615 | if (rt2x00_rev(&rt2x00dev->chip) < RT2560_VERSION_D && | 601 | if (rt2x00_rev(&rt2x00dev->chip) < RT2560_VERSION_D && |
602 | rt2x00dev->intf_associated && | ||
616 | rt2x00dev->link.count > 20) | 603 | rt2x00dev->link.count > 20) |
617 | return; | 604 | return; |
618 | 605 | ||
@@ -620,9 +607,12 @@ static void rt2500pci_link_tuner(struct rt2x00_dev *rt2x00dev) | |||
620 | 607 | ||
621 | /* | 608 | /* |
622 | * Chipset versions C and lower should directly continue | 609 | * Chipset versions C and lower should directly continue |
623 | * to the dynamic CCA tuning. | 610 | * to the dynamic CCA tuning. Chipset version D and higher |
611 | * should go straight to dynamic CCA tuning when they | ||
612 | * are not associated. | ||
624 | */ | 613 | */ |
625 | if (rt2x00_rev(&rt2x00dev->chip) < RT2560_VERSION_D) | 614 | if (rt2x00_rev(&rt2x00dev->chip) < RT2560_VERSION_D || |
615 | !rt2x00dev->intf_associated) | ||
626 | goto dynamic_cca_tune; | 616 | goto dynamic_cca_tune; |
627 | 617 | ||
628 | /* | 618 | /* |
@@ -684,82 +674,84 @@ dynamic_cca_tune: | |||
684 | * Initialization functions. | 674 | * Initialization functions. |
685 | */ | 675 | */ |
686 | static void rt2500pci_init_rxentry(struct rt2x00_dev *rt2x00dev, | 676 | static void rt2500pci_init_rxentry(struct rt2x00_dev *rt2x00dev, |
687 | struct data_entry *entry) | 677 | struct queue_entry *entry) |
688 | { | 678 | { |
689 | __le32 *rxd = entry->priv; | 679 | struct queue_entry_priv_pci_rx *priv_rx = entry->priv_data; |
690 | u32 word; | 680 | u32 word; |
691 | 681 | ||
692 | rt2x00_desc_read(rxd, 1, &word); | 682 | rt2x00_desc_read(priv_rx->desc, 1, &word); |
693 | rt2x00_set_field32(&word, RXD_W1_BUFFER_ADDRESS, entry->data_dma); | 683 | rt2x00_set_field32(&word, RXD_W1_BUFFER_ADDRESS, priv_rx->data_dma); |
694 | rt2x00_desc_write(rxd, 1, word); | 684 | rt2x00_desc_write(priv_rx->desc, 1, word); |
695 | 685 | ||
696 | rt2x00_desc_read(rxd, 0, &word); | 686 | rt2x00_desc_read(priv_rx->desc, 0, &word); |
697 | rt2x00_set_field32(&word, RXD_W0_OWNER_NIC, 1); | 687 | rt2x00_set_field32(&word, RXD_W0_OWNER_NIC, 1); |
698 | rt2x00_desc_write(rxd, 0, word); | 688 | rt2x00_desc_write(priv_rx->desc, 0, word); |
699 | } | 689 | } |
700 | 690 | ||
701 | static void rt2500pci_init_txentry(struct rt2x00_dev *rt2x00dev, | 691 | static void rt2500pci_init_txentry(struct rt2x00_dev *rt2x00dev, |
702 | struct data_entry *entry) | 692 | struct queue_entry *entry) |
703 | { | 693 | { |
704 | __le32 *txd = entry->priv; | 694 | struct queue_entry_priv_pci_tx *priv_tx = entry->priv_data; |
705 | u32 word; | 695 | u32 word; |
706 | 696 | ||
707 | rt2x00_desc_read(txd, 1, &word); | 697 | rt2x00_desc_read(priv_tx->desc, 1, &word); |
708 | rt2x00_set_field32(&word, TXD_W1_BUFFER_ADDRESS, entry->data_dma); | 698 | rt2x00_set_field32(&word, TXD_W1_BUFFER_ADDRESS, priv_tx->data_dma); |
709 | rt2x00_desc_write(txd, 1, word); | 699 | rt2x00_desc_write(priv_tx->desc, 1, word); |
710 | 700 | ||
711 | rt2x00_desc_read(txd, 0, &word); | 701 | rt2x00_desc_read(priv_tx->desc, 0, &word); |
712 | rt2x00_set_field32(&word, TXD_W0_VALID, 0); | 702 | rt2x00_set_field32(&word, TXD_W0_VALID, 0); |
713 | rt2x00_set_field32(&word, TXD_W0_OWNER_NIC, 0); | 703 | rt2x00_set_field32(&word, TXD_W0_OWNER_NIC, 0); |
714 | rt2x00_desc_write(txd, 0, word); | 704 | rt2x00_desc_write(priv_tx->desc, 0, word); |
715 | } | 705 | } |
716 | 706 | ||
717 | static int rt2500pci_init_rings(struct rt2x00_dev *rt2x00dev) | 707 | static int rt2500pci_init_queues(struct rt2x00_dev *rt2x00dev) |
718 | { | 708 | { |
709 | struct queue_entry_priv_pci_rx *priv_rx; | ||
710 | struct queue_entry_priv_pci_tx *priv_tx; | ||
719 | u32 reg; | 711 | u32 reg; |
720 | 712 | ||
721 | /* | 713 | /* |
722 | * Initialize registers. | 714 | * Initialize registers. |
723 | */ | 715 | */ |
724 | rt2x00pci_register_read(rt2x00dev, TXCSR2, ®); | 716 | rt2x00pci_register_read(rt2x00dev, TXCSR2, ®); |
725 | rt2x00_set_field32(®, TXCSR2_TXD_SIZE, | 717 | rt2x00_set_field32(®, TXCSR2_TXD_SIZE, rt2x00dev->tx[0].desc_size); |
726 | rt2x00dev->tx[IEEE80211_TX_QUEUE_DATA0].desc_size); | 718 | rt2x00_set_field32(®, TXCSR2_NUM_TXD, rt2x00dev->tx[1].limit); |
727 | rt2x00_set_field32(®, TXCSR2_NUM_TXD, | 719 | rt2x00_set_field32(®, TXCSR2_NUM_ATIM, rt2x00dev->bcn[1].limit); |
728 | rt2x00dev->tx[IEEE80211_TX_QUEUE_DATA1].stats.limit); | 720 | rt2x00_set_field32(®, TXCSR2_NUM_PRIO, rt2x00dev->tx[0].limit); |
729 | rt2x00_set_field32(®, TXCSR2_NUM_ATIM, | ||
730 | rt2x00dev->bcn[1].stats.limit); | ||
731 | rt2x00_set_field32(®, TXCSR2_NUM_PRIO, | ||
732 | rt2x00dev->tx[IEEE80211_TX_QUEUE_DATA0].stats.limit); | ||
733 | rt2x00pci_register_write(rt2x00dev, TXCSR2, reg); | 721 | rt2x00pci_register_write(rt2x00dev, TXCSR2, reg); |
734 | 722 | ||
723 | priv_tx = rt2x00dev->tx[1].entries[0].priv_data; | ||
735 | rt2x00pci_register_read(rt2x00dev, TXCSR3, ®); | 724 | rt2x00pci_register_read(rt2x00dev, TXCSR3, ®); |
736 | rt2x00_set_field32(®, TXCSR3_TX_RING_REGISTER, | 725 | rt2x00_set_field32(®, TXCSR3_TX_RING_REGISTER, |
737 | rt2x00dev->tx[IEEE80211_TX_QUEUE_DATA1].data_dma); | 726 | priv_tx->desc_dma); |
738 | rt2x00pci_register_write(rt2x00dev, TXCSR3, reg); | 727 | rt2x00pci_register_write(rt2x00dev, TXCSR3, reg); |
739 | 728 | ||
729 | priv_tx = rt2x00dev->tx[0].entries[0].priv_data; | ||
740 | rt2x00pci_register_read(rt2x00dev, TXCSR5, ®); | 730 | rt2x00pci_register_read(rt2x00dev, TXCSR5, ®); |
741 | rt2x00_set_field32(®, TXCSR5_PRIO_RING_REGISTER, | 731 | rt2x00_set_field32(®, TXCSR5_PRIO_RING_REGISTER, |
742 | rt2x00dev->tx[IEEE80211_TX_QUEUE_DATA0].data_dma); | 732 | priv_tx->desc_dma); |
743 | rt2x00pci_register_write(rt2x00dev, TXCSR5, reg); | 733 | rt2x00pci_register_write(rt2x00dev, TXCSR5, reg); |
744 | 734 | ||
735 | priv_tx = rt2x00dev->bcn[1].entries[0].priv_data; | ||
745 | rt2x00pci_register_read(rt2x00dev, TXCSR4, ®); | 736 | rt2x00pci_register_read(rt2x00dev, TXCSR4, ®); |
746 | rt2x00_set_field32(®, TXCSR4_ATIM_RING_REGISTER, | 737 | rt2x00_set_field32(®, TXCSR4_ATIM_RING_REGISTER, |
747 | rt2x00dev->bcn[1].data_dma); | 738 | priv_tx->desc_dma); |
748 | rt2x00pci_register_write(rt2x00dev, TXCSR4, reg); | 739 | rt2x00pci_register_write(rt2x00dev, TXCSR4, reg); |
749 | 740 | ||
741 | priv_tx = rt2x00dev->bcn[0].entries[0].priv_data; | ||
750 | rt2x00pci_register_read(rt2x00dev, TXCSR6, ®); | 742 | rt2x00pci_register_read(rt2x00dev, TXCSR6, ®); |
751 | rt2x00_set_field32(®, TXCSR6_BEACON_RING_REGISTER, | 743 | rt2x00_set_field32(®, TXCSR6_BEACON_RING_REGISTER, |
752 | rt2x00dev->bcn[0].data_dma); | 744 | priv_tx->desc_dma); |
753 | rt2x00pci_register_write(rt2x00dev, TXCSR6, reg); | 745 | rt2x00pci_register_write(rt2x00dev, TXCSR6, reg); |
754 | 746 | ||
755 | rt2x00pci_register_read(rt2x00dev, RXCSR1, ®); | 747 | rt2x00pci_register_read(rt2x00dev, RXCSR1, ®); |
756 | rt2x00_set_field32(®, RXCSR1_RXD_SIZE, rt2x00dev->rx->desc_size); | 748 | rt2x00_set_field32(®, RXCSR1_RXD_SIZE, rt2x00dev->rx->desc_size); |
757 | rt2x00_set_field32(®, RXCSR1_NUM_RXD, rt2x00dev->rx->stats.limit); | 749 | rt2x00_set_field32(®, RXCSR1_NUM_RXD, rt2x00dev->rx->limit); |
758 | rt2x00pci_register_write(rt2x00dev, RXCSR1, reg); | 750 | rt2x00pci_register_write(rt2x00dev, RXCSR1, reg); |
759 | 751 | ||
752 | priv_rx = rt2x00dev->rx->entries[0].priv_data; | ||
760 | rt2x00pci_register_read(rt2x00dev, RXCSR2, ®); | 753 | rt2x00pci_register_read(rt2x00dev, RXCSR2, ®); |
761 | rt2x00_set_field32(®, RXCSR2_RX_RING_REGISTER, | 754 | rt2x00_set_field32(®, RXCSR2_RX_RING_REGISTER, priv_rx->desc_dma); |
762 | rt2x00dev->rx->data_dma); | ||
763 | rt2x00pci_register_write(rt2x00dev, RXCSR2, reg); | 755 | rt2x00pci_register_write(rt2x00dev, RXCSR2, reg); |
764 | 756 | ||
765 | return 0; | 757 | return 0; |
@@ -792,6 +784,11 @@ static int rt2500pci_init_registers(struct rt2x00_dev *rt2x00dev) | |||
792 | rt2x00_set_field32(®, CSR11_CW_SELECT, 0); | 784 | rt2x00_set_field32(®, CSR11_CW_SELECT, 0); |
793 | rt2x00pci_register_write(rt2x00dev, CSR11, reg); | 785 | rt2x00pci_register_write(rt2x00dev, CSR11, reg); |
794 | 786 | ||
787 | rt2x00pci_register_read(rt2x00dev, LEDCSR, ®); | ||
788 | rt2x00_set_field32(®, LEDCSR_ON_PERIOD, 70); | ||
789 | rt2x00_set_field32(®, LEDCSR_OFF_PERIOD, 30); | ||
790 | rt2x00pci_register_write(rt2x00dev, LEDCSR, reg); | ||
791 | |||
795 | rt2x00pci_register_write(rt2x00dev, CNT3, 0); | 792 | rt2x00pci_register_write(rt2x00dev, CNT3, 0); |
796 | 793 | ||
797 | rt2x00pci_register_read(rt2x00dev, TXCSR8, ®); | 794 | rt2x00pci_register_read(rt2x00dev, TXCSR8, ®); |
@@ -947,19 +944,15 @@ continue_csr_init: | |||
947 | rt2500pci_bbp_write(rt2x00dev, 61, 0x6d); | 944 | rt2500pci_bbp_write(rt2x00dev, 61, 0x6d); |
948 | rt2500pci_bbp_write(rt2x00dev, 62, 0x10); | 945 | rt2500pci_bbp_write(rt2x00dev, 62, 0x10); |
949 | 946 | ||
950 | DEBUG(rt2x00dev, "Start initialization from EEPROM...\n"); | ||
951 | for (i = 0; i < EEPROM_BBP_SIZE; i++) { | 947 | for (i = 0; i < EEPROM_BBP_SIZE; i++) { |
952 | rt2x00_eeprom_read(rt2x00dev, EEPROM_BBP_START + i, &eeprom); | 948 | rt2x00_eeprom_read(rt2x00dev, EEPROM_BBP_START + i, &eeprom); |
953 | 949 | ||
954 | if (eeprom != 0xffff && eeprom != 0x0000) { | 950 | if (eeprom != 0xffff && eeprom != 0x0000) { |
955 | reg_id = rt2x00_get_field16(eeprom, EEPROM_BBP_REG_ID); | 951 | reg_id = rt2x00_get_field16(eeprom, EEPROM_BBP_REG_ID); |
956 | value = rt2x00_get_field16(eeprom, EEPROM_BBP_VALUE); | 952 | value = rt2x00_get_field16(eeprom, EEPROM_BBP_VALUE); |
957 | DEBUG(rt2x00dev, "BBP: 0x%02x, value: 0x%02x.\n", | ||
958 | reg_id, value); | ||
959 | rt2500pci_bbp_write(rt2x00dev, reg_id, value); | 953 | rt2500pci_bbp_write(rt2x00dev, reg_id, value); |
960 | } | 954 | } |
961 | } | 955 | } |
962 | DEBUG(rt2x00dev, "...End initialization from EEPROM.\n"); | ||
963 | 956 | ||
964 | return 0; | 957 | return 0; |
965 | } | 958 | } |
@@ -1011,7 +1004,7 @@ static int rt2500pci_enable_radio(struct rt2x00_dev *rt2x00dev) | |||
1011 | /* | 1004 | /* |
1012 | * Initialize all registers. | 1005 | * Initialize all registers. |
1013 | */ | 1006 | */ |
1014 | if (rt2500pci_init_rings(rt2x00dev) || | 1007 | if (rt2500pci_init_queues(rt2x00dev) || |
1015 | rt2500pci_init_registers(rt2x00dev) || | 1008 | rt2500pci_init_registers(rt2x00dev) || |
1016 | rt2500pci_init_bbp(rt2x00dev)) { | 1009 | rt2500pci_init_bbp(rt2x00dev)) { |
1017 | ERROR(rt2x00dev, "Register initialization failed.\n"); | 1010 | ERROR(rt2x00dev, "Register initialization failed.\n"); |
@@ -1023,11 +1016,6 @@ static int rt2500pci_enable_radio(struct rt2x00_dev *rt2x00dev) | |||
1023 | */ | 1016 | */ |
1024 | rt2500pci_toggle_irq(rt2x00dev, STATE_RADIO_IRQ_ON); | 1017 | rt2500pci_toggle_irq(rt2x00dev, STATE_RADIO_IRQ_ON); |
1025 | 1018 | ||
1026 | /* | ||
1027 | * Enable LED | ||
1028 | */ | ||
1029 | rt2500pci_enable_led(rt2x00dev); | ||
1030 | |||
1031 | return 0; | 1019 | return 0; |
1032 | } | 1020 | } |
1033 | 1021 | ||
@@ -1035,11 +1023,6 @@ static void rt2500pci_disable_radio(struct rt2x00_dev *rt2x00dev) | |||
1035 | { | 1023 | { |
1036 | u32 reg; | 1024 | u32 reg; |
1037 | 1025 | ||
1038 | /* | ||
1039 | * Disable LED | ||
1040 | */ | ||
1041 | rt2500pci_disable_led(rt2x00dev); | ||
1042 | |||
1043 | rt2x00pci_register_write(rt2x00dev, PWRCSR0, 0); | 1026 | rt2x00pci_register_write(rt2x00dev, PWRCSR0, 0); |
1044 | 1027 | ||
1045 | /* | 1028 | /* |
@@ -1138,10 +1121,10 @@ static int rt2500pci_set_device_state(struct rt2x00_dev *rt2x00dev, | |||
1138 | */ | 1121 | */ |
1139 | static void rt2500pci_write_tx_desc(struct rt2x00_dev *rt2x00dev, | 1122 | static void rt2500pci_write_tx_desc(struct rt2x00_dev *rt2x00dev, |
1140 | struct sk_buff *skb, | 1123 | struct sk_buff *skb, |
1141 | struct txdata_entry_desc *desc, | 1124 | struct txentry_desc *txdesc, |
1142 | struct ieee80211_tx_control *control) | 1125 | struct ieee80211_tx_control *control) |
1143 | { | 1126 | { |
1144 | struct skb_desc *skbdesc = get_skb_desc(skb); | 1127 | struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb); |
1145 | __le32 *txd = skbdesc->desc; | 1128 | __le32 *txd = skbdesc->desc; |
1146 | u32 word; | 1129 | u32 word; |
1147 | 1130 | ||
@@ -1150,36 +1133,36 @@ static void rt2500pci_write_tx_desc(struct rt2x00_dev *rt2x00dev, | |||
1150 | */ | 1133 | */ |
1151 | rt2x00_desc_read(txd, 2, &word); | 1134 | rt2x00_desc_read(txd, 2, &word); |
1152 | rt2x00_set_field32(&word, TXD_W2_IV_OFFSET, IEEE80211_HEADER); | 1135 | rt2x00_set_field32(&word, TXD_W2_IV_OFFSET, IEEE80211_HEADER); |
1153 | rt2x00_set_field32(&word, TXD_W2_AIFS, desc->aifs); | 1136 | rt2x00_set_field32(&word, TXD_W2_AIFS, txdesc->aifs); |
1154 | rt2x00_set_field32(&word, TXD_W2_CWMIN, desc->cw_min); | 1137 | rt2x00_set_field32(&word, TXD_W2_CWMIN, txdesc->cw_min); |
1155 | rt2x00_set_field32(&word, TXD_W2_CWMAX, desc->cw_max); | 1138 | rt2x00_set_field32(&word, TXD_W2_CWMAX, txdesc->cw_max); |
1156 | rt2x00_desc_write(txd, 2, word); | 1139 | rt2x00_desc_write(txd, 2, word); |
1157 | 1140 | ||
1158 | rt2x00_desc_read(txd, 3, &word); | 1141 | rt2x00_desc_read(txd, 3, &word); |
1159 | rt2x00_set_field32(&word, TXD_W3_PLCP_SIGNAL, desc->signal); | 1142 | rt2x00_set_field32(&word, TXD_W3_PLCP_SIGNAL, txdesc->signal); |
1160 | rt2x00_set_field32(&word, TXD_W3_PLCP_SERVICE, desc->service); | 1143 | rt2x00_set_field32(&word, TXD_W3_PLCP_SERVICE, txdesc->service); |
1161 | rt2x00_set_field32(&word, TXD_W3_PLCP_LENGTH_LOW, desc->length_low); | 1144 | rt2x00_set_field32(&word, TXD_W3_PLCP_LENGTH_LOW, txdesc->length_low); |
1162 | rt2x00_set_field32(&word, TXD_W3_PLCP_LENGTH_HIGH, desc->length_high); | 1145 | rt2x00_set_field32(&word, TXD_W3_PLCP_LENGTH_HIGH, txdesc->length_high); |
1163 | rt2x00_desc_write(txd, 3, word); | 1146 | rt2x00_desc_write(txd, 3, word); |
1164 | 1147 | ||
1165 | rt2x00_desc_read(txd, 10, &word); | 1148 | rt2x00_desc_read(txd, 10, &word); |
1166 | rt2x00_set_field32(&word, TXD_W10_RTS, | 1149 | rt2x00_set_field32(&word, TXD_W10_RTS, |
1167 | test_bit(ENTRY_TXD_RTS_FRAME, &desc->flags)); | 1150 | test_bit(ENTRY_TXD_RTS_FRAME, &txdesc->flags)); |
1168 | rt2x00_desc_write(txd, 10, word); | 1151 | rt2x00_desc_write(txd, 10, word); |
1169 | 1152 | ||
1170 | rt2x00_desc_read(txd, 0, &word); | 1153 | rt2x00_desc_read(txd, 0, &word); |
1171 | rt2x00_set_field32(&word, TXD_W0_OWNER_NIC, 1); | 1154 | rt2x00_set_field32(&word, TXD_W0_OWNER_NIC, 1); |
1172 | rt2x00_set_field32(&word, TXD_W0_VALID, 1); | 1155 | rt2x00_set_field32(&word, TXD_W0_VALID, 1); |
1173 | rt2x00_set_field32(&word, TXD_W0_MORE_FRAG, | 1156 | rt2x00_set_field32(&word, TXD_W0_MORE_FRAG, |
1174 | test_bit(ENTRY_TXD_MORE_FRAG, &desc->flags)); | 1157 | test_bit(ENTRY_TXD_MORE_FRAG, &txdesc->flags)); |
1175 | rt2x00_set_field32(&word, TXD_W0_ACK, | 1158 | rt2x00_set_field32(&word, TXD_W0_ACK, |
1176 | test_bit(ENTRY_TXD_ACK, &desc->flags)); | 1159 | test_bit(ENTRY_TXD_ACK, &txdesc->flags)); |
1177 | rt2x00_set_field32(&word, TXD_W0_TIMESTAMP, | 1160 | rt2x00_set_field32(&word, TXD_W0_TIMESTAMP, |
1178 | test_bit(ENTRY_TXD_REQ_TIMESTAMP, &desc->flags)); | 1161 | test_bit(ENTRY_TXD_REQ_TIMESTAMP, &txdesc->flags)); |
1179 | rt2x00_set_field32(&word, TXD_W0_OFDM, | 1162 | rt2x00_set_field32(&word, TXD_W0_OFDM, |
1180 | test_bit(ENTRY_TXD_OFDM_RATE, &desc->flags)); | 1163 | test_bit(ENTRY_TXD_OFDM_RATE, &txdesc->flags)); |
1181 | rt2x00_set_field32(&word, TXD_W0_CIPHER_OWNER, 1); | 1164 | rt2x00_set_field32(&word, TXD_W0_CIPHER_OWNER, 1); |
1182 | rt2x00_set_field32(&word, TXD_W0_IFS, desc->ifs); | 1165 | rt2x00_set_field32(&word, TXD_W0_IFS, txdesc->ifs); |
1183 | rt2x00_set_field32(&word, TXD_W0_RETRY_MODE, | 1166 | rt2x00_set_field32(&word, TXD_W0_RETRY_MODE, |
1184 | !!(control->flags & | 1167 | !!(control->flags & |
1185 | IEEE80211_TXCTL_LONG_RETRY_LIMIT)); | 1168 | IEEE80211_TXCTL_LONG_RETRY_LIMIT)); |
@@ -1192,13 +1175,15 @@ static void rt2500pci_write_tx_desc(struct rt2x00_dev *rt2x00dev, | |||
1192 | * TX data initialization | 1175 | * TX data initialization |
1193 | */ | 1176 | */ |
1194 | static void rt2500pci_kick_tx_queue(struct rt2x00_dev *rt2x00dev, | 1177 | static void rt2500pci_kick_tx_queue(struct rt2x00_dev *rt2x00dev, |
1195 | unsigned int queue) | 1178 | const unsigned int queue) |
1196 | { | 1179 | { |
1197 | u32 reg; | 1180 | u32 reg; |
1198 | 1181 | ||
1199 | if (queue == IEEE80211_TX_QUEUE_BEACON) { | 1182 | if (queue == RT2X00_BCN_QUEUE_BEACON) { |
1200 | rt2x00pci_register_read(rt2x00dev, CSR14, ®); | 1183 | rt2x00pci_register_read(rt2x00dev, CSR14, ®); |
1201 | if (!rt2x00_get_field32(reg, CSR14_BEACON_GEN)) { | 1184 | if (!rt2x00_get_field32(reg, CSR14_BEACON_GEN)) { |
1185 | rt2x00_set_field32(®, CSR14_TSF_COUNT, 1); | ||
1186 | rt2x00_set_field32(®, CSR14_TBCN, 1); | ||
1202 | rt2x00_set_field32(®, CSR14_BEACON_GEN, 1); | 1187 | rt2x00_set_field32(®, CSR14_BEACON_GEN, 1); |
1203 | rt2x00pci_register_write(rt2x00dev, CSR14, reg); | 1188 | rt2x00pci_register_write(rt2x00dev, CSR14, reg); |
1204 | } | 1189 | } |
@@ -1211,53 +1196,60 @@ static void rt2500pci_kick_tx_queue(struct rt2x00_dev *rt2x00dev, | |||
1211 | rt2x00_set_field32(®, TXCSR0_KICK_TX, | 1196 | rt2x00_set_field32(®, TXCSR0_KICK_TX, |
1212 | (queue == IEEE80211_TX_QUEUE_DATA1)); | 1197 | (queue == IEEE80211_TX_QUEUE_DATA1)); |
1213 | rt2x00_set_field32(®, TXCSR0_KICK_ATIM, | 1198 | rt2x00_set_field32(®, TXCSR0_KICK_ATIM, |
1214 | (queue == IEEE80211_TX_QUEUE_AFTER_BEACON)); | 1199 | (queue == RT2X00_BCN_QUEUE_ATIM)); |
1215 | rt2x00pci_register_write(rt2x00dev, TXCSR0, reg); | 1200 | rt2x00pci_register_write(rt2x00dev, TXCSR0, reg); |
1216 | } | 1201 | } |
1217 | 1202 | ||
1218 | /* | 1203 | /* |
1219 | * RX control handlers | 1204 | * RX control handlers |
1220 | */ | 1205 | */ |
1221 | static void rt2500pci_fill_rxdone(struct data_entry *entry, | 1206 | static void rt2500pci_fill_rxdone(struct queue_entry *entry, |
1222 | struct rxdata_entry_desc *desc) | 1207 | struct rxdone_entry_desc *rxdesc) |
1223 | { | 1208 | { |
1224 | __le32 *rxd = entry->priv; | 1209 | struct queue_entry_priv_pci_rx *priv_rx = entry->priv_data; |
1225 | u32 word0; | 1210 | u32 word0; |
1226 | u32 word2; | 1211 | u32 word2; |
1227 | 1212 | ||
1228 | rt2x00_desc_read(rxd, 0, &word0); | 1213 | rt2x00_desc_read(priv_rx->desc, 0, &word0); |
1229 | rt2x00_desc_read(rxd, 2, &word2); | 1214 | rt2x00_desc_read(priv_rx->desc, 2, &word2); |
1230 | 1215 | ||
1231 | desc->flags = 0; | 1216 | rxdesc->flags = 0; |
1232 | if (rt2x00_get_field32(word0, RXD_W0_CRC_ERROR)) | 1217 | if (rt2x00_get_field32(word0, RXD_W0_CRC_ERROR)) |
1233 | desc->flags |= RX_FLAG_FAILED_FCS_CRC; | 1218 | rxdesc->flags |= RX_FLAG_FAILED_FCS_CRC; |
1234 | if (rt2x00_get_field32(word0, RXD_W0_PHYSICAL_ERROR)) | 1219 | if (rt2x00_get_field32(word0, RXD_W0_PHYSICAL_ERROR)) |
1235 | desc->flags |= RX_FLAG_FAILED_PLCP_CRC; | 1220 | rxdesc->flags |= RX_FLAG_FAILED_PLCP_CRC; |
1236 | 1221 | ||
1237 | desc->signal = rt2x00_get_field32(word2, RXD_W2_SIGNAL); | 1222 | /* |
1238 | desc->rssi = rt2x00_get_field32(word2, RXD_W2_RSSI) - | 1223 | * Obtain the status about this packet. |
1239 | entry->ring->rt2x00dev->rssi_offset; | 1224 | * When frame was received with an OFDM bitrate, |
1240 | desc->ofdm = rt2x00_get_field32(word0, RXD_W0_OFDM); | 1225 | * the signal is the PLCP value. If it was received with |
1241 | desc->size = rt2x00_get_field32(word0, RXD_W0_DATABYTE_COUNT); | 1226 | * a CCK bitrate the signal is the rate in 100kbit/s. |
1242 | desc->my_bss = !!rt2x00_get_field32(word0, RXD_W0_MY_BSS); | 1227 | */ |
1228 | rxdesc->ofdm = rt2x00_get_field32(word0, RXD_W0_OFDM); | ||
1229 | rxdesc->signal = rt2x00_get_field32(word2, RXD_W2_SIGNAL); | ||
1230 | rxdesc->signal_plcp = rxdesc->ofdm; | ||
1231 | rxdesc->rssi = rt2x00_get_field32(word2, RXD_W2_RSSI) - | ||
1232 | entry->queue->rt2x00dev->rssi_offset; | ||
1233 | rxdesc->size = rt2x00_get_field32(word0, RXD_W0_DATABYTE_COUNT); | ||
1234 | rxdesc->my_bss = !!rt2x00_get_field32(word0, RXD_W0_MY_BSS); | ||
1243 | } | 1235 | } |
1244 | 1236 | ||
1245 | /* | 1237 | /* |
1246 | * Interrupt functions. | 1238 | * Interrupt functions. |
1247 | */ | 1239 | */ |
1248 | static void rt2500pci_txdone(struct rt2x00_dev *rt2x00dev, const int queue) | 1240 | static void rt2500pci_txdone(struct rt2x00_dev *rt2x00dev, |
1241 | const enum ieee80211_tx_queue queue_idx) | ||
1249 | { | 1242 | { |
1250 | struct data_ring *ring = rt2x00lib_get_ring(rt2x00dev, queue); | 1243 | struct data_queue *queue = rt2x00queue_get_queue(rt2x00dev, queue_idx); |
1251 | struct data_entry *entry; | 1244 | struct queue_entry_priv_pci_tx *priv_tx; |
1252 | __le32 *txd; | 1245 | struct queue_entry *entry; |
1246 | struct txdone_entry_desc txdesc; | ||
1253 | u32 word; | 1247 | u32 word; |
1254 | int tx_status; | ||
1255 | int retry; | ||
1256 | 1248 | ||
1257 | while (!rt2x00_ring_empty(ring)) { | 1249 | while (!rt2x00queue_empty(queue)) { |
1258 | entry = rt2x00_get_data_entry_done(ring); | 1250 | entry = rt2x00queue_get_entry(queue, Q_INDEX_DONE); |
1259 | txd = entry->priv; | 1251 | priv_tx = entry->priv_data; |
1260 | rt2x00_desc_read(txd, 0, &word); | 1252 | rt2x00_desc_read(priv_tx->desc, 0, &word); |
1261 | 1253 | ||
1262 | if (rt2x00_get_field32(word, TXD_W0_OWNER_NIC) || | 1254 | if (rt2x00_get_field32(word, TXD_W0_OWNER_NIC) || |
1263 | !rt2x00_get_field32(word, TXD_W0_VALID)) | 1255 | !rt2x00_get_field32(word, TXD_W0_VALID)) |
@@ -1266,10 +1258,10 @@ static void rt2500pci_txdone(struct rt2x00_dev *rt2x00dev, const int queue) | |||
1266 | /* | 1258 | /* |
1267 | * Obtain the status about this packet. | 1259 | * Obtain the status about this packet. |
1268 | */ | 1260 | */ |
1269 | tx_status = rt2x00_get_field32(word, TXD_W0_RESULT); | 1261 | txdesc.status = rt2x00_get_field32(word, TXD_W0_RESULT); |
1270 | retry = rt2x00_get_field32(word, TXD_W0_RETRY_COUNT); | 1262 | txdesc.retry = rt2x00_get_field32(word, TXD_W0_RETRY_COUNT); |
1271 | 1263 | ||
1272 | rt2x00pci_txdone(rt2x00dev, entry, tx_status, retry); | 1264 | rt2x00pci_txdone(rt2x00dev, entry, &txdesc); |
1273 | } | 1265 | } |
1274 | } | 1266 | } |
1275 | 1267 | ||
@@ -1313,7 +1305,7 @@ static irqreturn_t rt2500pci_interrupt(int irq, void *dev_instance) | |||
1313 | * 3 - Atim ring transmit done interrupt. | 1305 | * 3 - Atim ring transmit done interrupt. |
1314 | */ | 1306 | */ |
1315 | if (rt2x00_get_field32(reg, CSR7_TXDONE_ATIMRING)) | 1307 | if (rt2x00_get_field32(reg, CSR7_TXDONE_ATIMRING)) |
1316 | rt2500pci_txdone(rt2x00dev, IEEE80211_TX_QUEUE_AFTER_BEACON); | 1308 | rt2500pci_txdone(rt2x00dev, RT2X00_BCN_QUEUE_ATIM); |
1317 | 1309 | ||
1318 | /* | 1310 | /* |
1319 | * 4 - Priority ring transmit done interrupt. | 1311 | * 4 - Priority ring transmit done interrupt. |
@@ -1442,8 +1434,24 @@ static int rt2500pci_init_eeprom(struct rt2x00_dev *rt2x00dev) | |||
1442 | /* | 1434 | /* |
1443 | * Store led mode, for correct led behaviour. | 1435 | * Store led mode, for correct led behaviour. |
1444 | */ | 1436 | */ |
1445 | rt2x00dev->led_mode = | 1437 | #ifdef CONFIG_RT2500PCI_LEDS |
1446 | rt2x00_get_field16(eeprom, EEPROM_ANTENNA_LED_MODE); | 1438 | value = rt2x00_get_field16(eeprom, EEPROM_ANTENNA_LED_MODE); |
1439 | |||
1440 | switch (value) { | ||
1441 | case LED_MODE_ASUS: | ||
1442 | case LED_MODE_ALPHA: | ||
1443 | case LED_MODE_DEFAULT: | ||
1444 | rt2x00dev->led_flags = LED_SUPPORT_RADIO; | ||
1445 | break; | ||
1446 | case LED_MODE_TXRX_ACTIVITY: | ||
1447 | rt2x00dev->led_flags = | ||
1448 | LED_SUPPORT_RADIO | LED_SUPPORT_ACTIVITY; | ||
1449 | break; | ||
1450 | case LED_MODE_SIGNAL_STRENGTH: | ||
1451 | rt2x00dev->led_flags = LED_SUPPORT_RADIO; | ||
1452 | break; | ||
1453 | } | ||
1454 | #endif /* CONFIG_RT2500PCI_LEDS */ | ||
1447 | 1455 | ||
1448 | /* | 1456 | /* |
1449 | * Detect if this device has an hardware controlled radio. | 1457 | * Detect if this device has an hardware controlled radio. |
@@ -1656,8 +1664,8 @@ static void rt2500pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev) | |||
1656 | /* | 1664 | /* |
1657 | * Initialize hw_mode information. | 1665 | * Initialize hw_mode information. |
1658 | */ | 1666 | */ |
1659 | spec->num_modes = 2; | 1667 | spec->supported_bands = SUPPORT_BAND_2GHZ; |
1660 | spec->num_rates = 12; | 1668 | spec->supported_rates = SUPPORT_RATE_CCK | SUPPORT_RATE_OFDM; |
1661 | spec->tx_power_a = NULL; | 1669 | spec->tx_power_a = NULL; |
1662 | spec->tx_power_bg = txpower; | 1670 | spec->tx_power_bg = txpower; |
1663 | spec->tx_power_default = DEFAULT_TXPOWER; | 1671 | spec->tx_power_default = DEFAULT_TXPOWER; |
@@ -1678,9 +1686,9 @@ static void rt2500pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev) | |||
1678 | spec->num_channels = ARRAY_SIZE(rf_vals_bg_2525e); | 1686 | spec->num_channels = ARRAY_SIZE(rf_vals_bg_2525e); |
1679 | spec->channels = rf_vals_bg_2525e; | 1687 | spec->channels = rf_vals_bg_2525e; |
1680 | } else if (rt2x00_rf(&rt2x00dev->chip, RF5222)) { | 1688 | } else if (rt2x00_rf(&rt2x00dev->chip, RF5222)) { |
1689 | spec->supported_bands |= SUPPORT_BAND_5GHZ; | ||
1681 | spec->num_channels = ARRAY_SIZE(rf_vals_5222); | 1690 | spec->num_channels = ARRAY_SIZE(rf_vals_5222); |
1682 | spec->channels = rf_vals_5222; | 1691 | spec->channels = rf_vals_5222; |
1683 | spec->num_modes = 3; | ||
1684 | } | 1692 | } |
1685 | } | 1693 | } |
1686 | 1694 | ||
@@ -1705,9 +1713,9 @@ static int rt2500pci_probe_hw(struct rt2x00_dev *rt2x00dev) | |||
1705 | rt2500pci_probe_hw_mode(rt2x00dev); | 1713 | rt2500pci_probe_hw_mode(rt2x00dev); |
1706 | 1714 | ||
1707 | /* | 1715 | /* |
1708 | * This device requires the beacon ring | 1716 | * This device requires the atim queue |
1709 | */ | 1717 | */ |
1710 | __set_bit(DRIVER_REQUIRE_BEACON_RING, &rt2x00dev->flags); | 1718 | __set_bit(DRIVER_REQUIRE_ATIM_QUEUE, &rt2x00dev->flags); |
1711 | 1719 | ||
1712 | /* | 1720 | /* |
1713 | * Set the rssi offset. | 1721 | * Set the rssi offset. |
@@ -1811,12 +1819,59 @@ static u64 rt2500pci_get_tsf(struct ieee80211_hw *hw) | |||
1811 | return tsf; | 1819 | return tsf; |
1812 | } | 1820 | } |
1813 | 1821 | ||
1814 | static void rt2500pci_reset_tsf(struct ieee80211_hw *hw) | 1822 | static int rt2500pci_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb, |
1823 | struct ieee80211_tx_control *control) | ||
1815 | { | 1824 | { |
1816 | struct rt2x00_dev *rt2x00dev = hw->priv; | 1825 | struct rt2x00_dev *rt2x00dev = hw->priv; |
1826 | struct rt2x00_intf *intf = vif_to_intf(control->vif); | ||
1827 | struct queue_entry_priv_pci_tx *priv_tx; | ||
1828 | struct skb_frame_desc *skbdesc; | ||
1829 | u32 reg; | ||
1817 | 1830 | ||
1818 | rt2x00pci_register_write(rt2x00dev, CSR16, 0); | 1831 | if (unlikely(!intf->beacon)) |
1819 | rt2x00pci_register_write(rt2x00dev, CSR17, 0); | 1832 | return -ENOBUFS; |
1833 | |||
1834 | priv_tx = intf->beacon->priv_data; | ||
1835 | |||
1836 | /* | ||
1837 | * Fill in skb descriptor | ||
1838 | */ | ||
1839 | skbdesc = get_skb_frame_desc(skb); | ||
1840 | memset(skbdesc, 0, sizeof(*skbdesc)); | ||
1841 | skbdesc->flags |= FRAME_DESC_DRIVER_GENERATED; | ||
1842 | skbdesc->data = skb->data; | ||
1843 | skbdesc->data_len = skb->len; | ||
1844 | skbdesc->desc = priv_tx->desc; | ||
1845 | skbdesc->desc_len = intf->beacon->queue->desc_size; | ||
1846 | skbdesc->entry = intf->beacon; | ||
1847 | |||
1848 | /* | ||
1849 | * Disable beaconing while we are reloading the beacon data, | ||
1850 | * otherwise we might be sending out invalid data. | ||
1851 | */ | ||
1852 | rt2x00pci_register_read(rt2x00dev, CSR14, ®); | ||
1853 | rt2x00_set_field32(®, CSR14_TSF_COUNT, 0); | ||
1854 | rt2x00_set_field32(®, CSR14_TBCN, 0); | ||
1855 | rt2x00_set_field32(®, CSR14_BEACON_GEN, 0); | ||
1856 | rt2x00pci_register_write(rt2x00dev, CSR14, reg); | ||
1857 | |||
1858 | /* | ||
1859 | * mac80211 doesn't provide the control->queue variable | ||
1860 | * for beacons. Set our own queue identification so | ||
1861 | * it can be used during descriptor initialization. | ||
1862 | */ | ||
1863 | control->queue = RT2X00_BCN_QUEUE_BEACON; | ||
1864 | rt2x00lib_write_tx_desc(rt2x00dev, skb, control); | ||
1865 | |||
1866 | /* | ||
1867 | * Enable beacon generation. | ||
1868 | * Write entire beacon with descriptor to register, | ||
1869 | * and kick the beacon generator. | ||
1870 | */ | ||
1871 | memcpy(priv_tx->data, skb->data, skb->len); | ||
1872 | rt2x00dev->ops->lib->kick_tx_queue(rt2x00dev, control->queue); | ||
1873 | |||
1874 | return 0; | ||
1820 | } | 1875 | } |
1821 | 1876 | ||
1822 | static int rt2500pci_tx_last_beacon(struct ieee80211_hw *hw) | 1877 | static int rt2500pci_tx_last_beacon(struct ieee80211_hw *hw) |
@@ -1843,8 +1898,7 @@ static const struct ieee80211_ops rt2500pci_mac80211_ops = { | |||
1843 | .conf_tx = rt2x00mac_conf_tx, | 1898 | .conf_tx = rt2x00mac_conf_tx, |
1844 | .get_tx_stats = rt2x00mac_get_tx_stats, | 1899 | .get_tx_stats = rt2x00mac_get_tx_stats, |
1845 | .get_tsf = rt2500pci_get_tsf, | 1900 | .get_tsf = rt2500pci_get_tsf, |
1846 | .reset_tsf = rt2500pci_reset_tsf, | 1901 | .beacon_update = rt2500pci_beacon_update, |
1847 | .beacon_update = rt2x00pci_beacon_update, | ||
1848 | .tx_last_beacon = rt2500pci_tx_last_beacon, | 1902 | .tx_last_beacon = rt2500pci_tx_last_beacon, |
1849 | }; | 1903 | }; |
1850 | 1904 | ||
@@ -1860,23 +1914,54 @@ static const struct rt2x00lib_ops rt2500pci_rt2x00_ops = { | |||
1860 | .link_stats = rt2500pci_link_stats, | 1914 | .link_stats = rt2500pci_link_stats, |
1861 | .reset_tuner = rt2500pci_reset_tuner, | 1915 | .reset_tuner = rt2500pci_reset_tuner, |
1862 | .link_tuner = rt2500pci_link_tuner, | 1916 | .link_tuner = rt2500pci_link_tuner, |
1917 | .led_brightness = rt2500pci_led_brightness, | ||
1863 | .write_tx_desc = rt2500pci_write_tx_desc, | 1918 | .write_tx_desc = rt2500pci_write_tx_desc, |
1864 | .write_tx_data = rt2x00pci_write_tx_data, | 1919 | .write_tx_data = rt2x00pci_write_tx_data, |
1865 | .kick_tx_queue = rt2500pci_kick_tx_queue, | 1920 | .kick_tx_queue = rt2500pci_kick_tx_queue, |
1866 | .fill_rxdone = rt2500pci_fill_rxdone, | 1921 | .fill_rxdone = rt2500pci_fill_rxdone, |
1867 | .config_mac_addr = rt2500pci_config_mac_addr, | 1922 | .config_intf = rt2500pci_config_intf, |
1868 | .config_bssid = rt2500pci_config_bssid, | 1923 | .config_erp = rt2500pci_config_erp, |
1869 | .config_type = rt2500pci_config_type, | ||
1870 | .config_preamble = rt2500pci_config_preamble, | ||
1871 | .config = rt2500pci_config, | 1924 | .config = rt2500pci_config, |
1872 | }; | 1925 | }; |
1873 | 1926 | ||
1927 | static const struct data_queue_desc rt2500pci_queue_rx = { | ||
1928 | .entry_num = RX_ENTRIES, | ||
1929 | .data_size = DATA_FRAME_SIZE, | ||
1930 | .desc_size = RXD_DESC_SIZE, | ||
1931 | .priv_size = sizeof(struct queue_entry_priv_pci_rx), | ||
1932 | }; | ||
1933 | |||
1934 | static const struct data_queue_desc rt2500pci_queue_tx = { | ||
1935 | .entry_num = TX_ENTRIES, | ||
1936 | .data_size = DATA_FRAME_SIZE, | ||
1937 | .desc_size = TXD_DESC_SIZE, | ||
1938 | .priv_size = sizeof(struct queue_entry_priv_pci_tx), | ||
1939 | }; | ||
1940 | |||
1941 | static const struct data_queue_desc rt2500pci_queue_bcn = { | ||
1942 | .entry_num = BEACON_ENTRIES, | ||
1943 | .data_size = MGMT_FRAME_SIZE, | ||
1944 | .desc_size = TXD_DESC_SIZE, | ||
1945 | .priv_size = sizeof(struct queue_entry_priv_pci_tx), | ||
1946 | }; | ||
1947 | |||
1948 | static const struct data_queue_desc rt2500pci_queue_atim = { | ||
1949 | .entry_num = ATIM_ENTRIES, | ||
1950 | .data_size = DATA_FRAME_SIZE, | ||
1951 | .desc_size = TXD_DESC_SIZE, | ||
1952 | .priv_size = sizeof(struct queue_entry_priv_pci_tx), | ||
1953 | }; | ||
1954 | |||
1874 | static const struct rt2x00_ops rt2500pci_ops = { | 1955 | static const struct rt2x00_ops rt2500pci_ops = { |
1875 | .name = KBUILD_MODNAME, | 1956 | .name = KBUILD_MODNAME, |
1876 | .rxd_size = RXD_DESC_SIZE, | 1957 | .max_sta_intf = 1, |
1877 | .txd_size = TXD_DESC_SIZE, | 1958 | .max_ap_intf = 1, |
1878 | .eeprom_size = EEPROM_SIZE, | 1959 | .eeprom_size = EEPROM_SIZE, |
1879 | .rf_size = RF_SIZE, | 1960 | .rf_size = RF_SIZE, |
1961 | .rx = &rt2500pci_queue_rx, | ||
1962 | .tx = &rt2500pci_queue_tx, | ||
1963 | .bcn = &rt2500pci_queue_bcn, | ||
1964 | .atim = &rt2500pci_queue_atim, | ||
1880 | .lib = &rt2500pci_rt2x00_ops, | 1965 | .lib = &rt2500pci_rt2x00_ops, |
1881 | .hw = &rt2500pci_mac80211_ops, | 1966 | .hw = &rt2500pci_mac80211_ops, |
1882 | #ifdef CONFIG_RT2X00_LIB_DEBUGFS | 1967 | #ifdef CONFIG_RT2X00_LIB_DEBUGFS |