diff options
author | Ivo van Doorn <IvDoorn@gmail.com> | 2008-02-05 16:42:23 -0500 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2008-02-29 15:19:27 -0500 |
commit | 181d6902b6bad978d157e69479c95cc0ff213a76 (patch) | |
tree | 7a90b8a949a50bc8db6b7b5b2d76d5671fb9a89e /drivers/net/wireless/rt2x00/rt2x00dev.c | |
parent | 811aa9cad1bd927999888ab56ed9592519d2fef6 (diff) |
rt2x00: Queue handling overhaul
This introduces a big queue handling overhaul, this also
renames "ring" to "queues".
Move queue handling into rt2x00queue.c and the matching header,
use Kerneldoc to improve rt2x00 library documentation.
Access to the queues is now protected under a spinlock, this
to prevent race conditions which could corrupt the indexing
system of the queue.
Each queue entry allocates x bytes for driver/device specific data,
this cleans up the queue structure significantly and improves
code readability.
rt2500usb no longer needs 2 entries in the beacon queue to correctly
send out the guardian byte. This is now handled in the entry specific
structure.
rt61 and rt73 now use the correct descriptor size for beacon frames,
since this data is written into the registers not the entire TXD
descriptor was used but instead of a subset of it named TXINFO.
Finally this also fixes numerous other bugs related to incorrect
beacon handling or beacon related code.
Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/rt2x00/rt2x00dev.c')
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2x00dev.c | 403 |
1 files changed, 97 insertions, 306 deletions
diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c index 57355077fb7c..7620427887b6 100644 --- a/drivers/net/wireless/rt2x00/rt2x00dev.c +++ b/drivers/net/wireless/rt2x00/rt2x00dev.c | |||
@@ -31,34 +31,6 @@ | |||
31 | #include "rt2x00dump.h" | 31 | #include "rt2x00dump.h" |
32 | 32 | ||
33 | /* | 33 | /* |
34 | * Ring handler. | ||
35 | */ | ||
36 | struct data_ring *rt2x00lib_get_ring(struct rt2x00_dev *rt2x00dev, | ||
37 | const unsigned int queue) | ||
38 | { | ||
39 | int beacon = test_bit(DRIVER_REQUIRE_BEACON_RING, &rt2x00dev->flags); | ||
40 | |||
41 | /* | ||
42 | * Check if we are requesting a reqular TX ring, | ||
43 | * or if we are requesting a Beacon or Atim ring. | ||
44 | * For Atim rings, we should check if it is supported. | ||
45 | */ | ||
46 | if (queue < rt2x00dev->hw->queues && rt2x00dev->tx) | ||
47 | return &rt2x00dev->tx[queue]; | ||
48 | |||
49 | if (!rt2x00dev->bcn || !beacon) | ||
50 | return NULL; | ||
51 | |||
52 | if (queue == IEEE80211_TX_QUEUE_BEACON) | ||
53 | return &rt2x00dev->bcn[0]; | ||
54 | else if (queue == IEEE80211_TX_QUEUE_AFTER_BEACON) | ||
55 | return &rt2x00dev->bcn[1]; | ||
56 | |||
57 | return NULL; | ||
58 | } | ||
59 | EXPORT_SYMBOL_GPL(rt2x00lib_get_ring); | ||
60 | |||
61 | /* | ||
62 | * Link tuning handlers | 34 | * Link tuning handlers |
63 | */ | 35 | */ |
64 | void rt2x00lib_reset_link_tuner(struct rt2x00_dev *rt2x00dev) | 36 | void rt2x00lib_reset_link_tuner(struct rt2x00_dev *rt2x00dev) |
@@ -113,46 +85,6 @@ static void rt2x00lib_stop_link_tuner(struct rt2x00_dev *rt2x00dev) | |||
113 | } | 85 | } |
114 | 86 | ||
115 | /* | 87 | /* |
116 | * Ring initialization | ||
117 | */ | ||
118 | static void rt2x00lib_init_rxrings(struct rt2x00_dev *rt2x00dev) | ||
119 | { | ||
120 | struct data_ring *ring = rt2x00dev->rx; | ||
121 | unsigned int i; | ||
122 | |||
123 | if (!rt2x00dev->ops->lib->init_rxentry) | ||
124 | return; | ||
125 | |||
126 | if (ring->data_addr) | ||
127 | memset(ring->data_addr, 0, rt2x00_get_ring_size(ring)); | ||
128 | |||
129 | for (i = 0; i < ring->stats.limit; i++) | ||
130 | rt2x00dev->ops->lib->init_rxentry(rt2x00dev, &ring->entry[i]); | ||
131 | |||
132 | rt2x00_ring_index_clear(ring); | ||
133 | } | ||
134 | |||
135 | static void rt2x00lib_init_txrings(struct rt2x00_dev *rt2x00dev) | ||
136 | { | ||
137 | struct data_ring *ring; | ||
138 | unsigned int i; | ||
139 | |||
140 | if (!rt2x00dev->ops->lib->init_txentry) | ||
141 | return; | ||
142 | |||
143 | txringall_for_each(rt2x00dev, ring) { | ||
144 | if (ring->data_addr) | ||
145 | memset(ring->data_addr, 0, rt2x00_get_ring_size(ring)); | ||
146 | |||
147 | for (i = 0; i < ring->stats.limit; i++) | ||
148 | rt2x00dev->ops->lib->init_txentry(rt2x00dev, | ||
149 | &ring->entry[i]); | ||
150 | |||
151 | rt2x00_ring_index_clear(ring); | ||
152 | } | ||
153 | } | ||
154 | |||
155 | /* | ||
156 | * Radio control handlers. | 88 | * Radio control handlers. |
157 | */ | 89 | */ |
158 | int rt2x00lib_enable_radio(struct rt2x00_dev *rt2x00dev) | 90 | int rt2x00lib_enable_radio(struct rt2x00_dev *rt2x00dev) |
@@ -168,10 +100,10 @@ int rt2x00lib_enable_radio(struct rt2x00_dev *rt2x00dev) | |||
168 | return 0; | 100 | return 0; |
169 | 101 | ||
170 | /* | 102 | /* |
171 | * Initialize all data rings. | 103 | * Initialize all data queues. |
172 | */ | 104 | */ |
173 | rt2x00lib_init_rxrings(rt2x00dev); | 105 | rt2x00queue_init_rx(rt2x00dev); |
174 | rt2x00lib_init_txrings(rt2x00dev); | 106 | rt2x00queue_init_tx(rt2x00dev); |
175 | 107 | ||
176 | /* | 108 | /* |
177 | * Enable radio. | 109 | * Enable radio. |
@@ -504,19 +436,15 @@ static void rt2x00lib_beacondone_scheduled(struct work_struct *work) | |||
504 | { | 436 | { |
505 | struct rt2x00_dev *rt2x00dev = | 437 | struct rt2x00_dev *rt2x00dev = |
506 | container_of(work, struct rt2x00_dev, beacon_work); | 438 | container_of(work, struct rt2x00_dev, beacon_work); |
507 | struct data_ring *ring = | 439 | struct ieee80211_tx_control control; |
508 | rt2x00lib_get_ring(rt2x00dev, IEEE80211_TX_QUEUE_BEACON); | ||
509 | struct data_entry *entry = rt2x00_get_data_entry(ring); | ||
510 | struct sk_buff *skb; | 440 | struct sk_buff *skb; |
511 | 441 | ||
512 | skb = ieee80211_beacon_get(rt2x00dev->hw, | 442 | skb = ieee80211_beacon_get(rt2x00dev->hw, |
513 | rt2x00dev->interface.id, | 443 | rt2x00dev->interface.id, &control); |
514 | &entry->tx_status.control); | ||
515 | if (!skb) | 444 | if (!skb) |
516 | return; | 445 | return; |
517 | 446 | ||
518 | rt2x00dev->ops->hw->beacon_update(rt2x00dev->hw, skb, | 447 | rt2x00dev->ops->hw->beacon_update(rt2x00dev->hw, skb, &control); |
519 | &entry->tx_status.control); | ||
520 | 448 | ||
521 | dev_kfree_skb(skb); | 449 | dev_kfree_skb(skb); |
522 | } | 450 | } |
@@ -530,58 +458,64 @@ void rt2x00lib_beacondone(struct rt2x00_dev *rt2x00dev) | |||
530 | } | 458 | } |
531 | EXPORT_SYMBOL_GPL(rt2x00lib_beacondone); | 459 | EXPORT_SYMBOL_GPL(rt2x00lib_beacondone); |
532 | 460 | ||
533 | void rt2x00lib_txdone(struct data_entry *entry, | 461 | void rt2x00lib_txdone(struct queue_entry *entry, |
534 | const int status, const int retry) | 462 | struct txdone_entry_desc *txdesc) |
535 | { | 463 | { |
536 | struct rt2x00_dev *rt2x00dev = entry->ring->rt2x00dev; | 464 | struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; |
537 | struct ieee80211_tx_status *tx_status = &entry->tx_status; | 465 | struct ieee80211_tx_status tx_status; |
538 | struct ieee80211_low_level_stats *stats = &rt2x00dev->low_level_stats; | 466 | int success = !!(txdesc->status == TX_SUCCESS || |
539 | int success = !!(status == TX_SUCCESS || status == TX_SUCCESS_RETRY); | 467 | txdesc->status == TX_SUCCESS_RETRY); |
540 | int fail = !!(status == TX_FAIL_RETRY || status == TX_FAIL_INVALID || | 468 | int fail = !!(txdesc->status == TX_FAIL_RETRY || |
541 | status == TX_FAIL_OTHER); | 469 | txdesc->status == TX_FAIL_INVALID || |
470 | txdesc->status == TX_FAIL_OTHER); | ||
542 | 471 | ||
543 | /* | 472 | /* |
544 | * Update TX statistics. | 473 | * Update TX statistics. |
545 | */ | 474 | */ |
546 | tx_status->flags = 0; | ||
547 | tx_status->ack_signal = 0; | ||
548 | tx_status->excessive_retries = (status == TX_FAIL_RETRY); | ||
549 | tx_status->retry_count = retry; | ||
550 | rt2x00dev->link.qual.tx_success += success; | 475 | rt2x00dev->link.qual.tx_success += success; |
551 | rt2x00dev->link.qual.tx_failed += retry + fail; | 476 | rt2x00dev->link.qual.tx_failed += txdesc->retry + fail; |
552 | 477 | ||
553 | if (!(tx_status->control.flags & IEEE80211_TXCTL_NO_ACK)) { | 478 | /* |
479 | * Initialize TX status | ||
480 | */ | ||
481 | tx_status.flags = 0; | ||
482 | tx_status.ack_signal = 0; | ||
483 | tx_status.excessive_retries = (txdesc->status == TX_FAIL_RETRY); | ||
484 | tx_status.retry_count = txdesc->retry; | ||
485 | memcpy(&tx_status.control, txdesc->control, sizeof(txdesc->control)); | ||
486 | |||
487 | if (!(tx_status.control.flags & IEEE80211_TXCTL_NO_ACK)) { | ||
554 | if (success) | 488 | if (success) |
555 | tx_status->flags |= IEEE80211_TX_STATUS_ACK; | 489 | tx_status.flags |= IEEE80211_TX_STATUS_ACK; |
556 | else | 490 | else |
557 | stats->dot11ACKFailureCount++; | 491 | rt2x00dev->low_level_stats.dot11ACKFailureCount++; |
558 | } | 492 | } |
559 | 493 | ||
560 | tx_status->queue_length = entry->ring->stats.limit; | 494 | tx_status.queue_length = entry->queue->limit; |
561 | tx_status->queue_number = tx_status->control.queue; | 495 | tx_status.queue_number = tx_status.control.queue; |
562 | 496 | ||
563 | if (tx_status->control.flags & IEEE80211_TXCTL_USE_RTS_CTS) { | 497 | if (tx_status.control.flags & IEEE80211_TXCTL_USE_RTS_CTS) { |
564 | if (success) | 498 | if (success) |
565 | stats->dot11RTSSuccessCount++; | 499 | rt2x00dev->low_level_stats.dot11RTSSuccessCount++; |
566 | else | 500 | else |
567 | stats->dot11RTSFailureCount++; | 501 | rt2x00dev->low_level_stats.dot11RTSFailureCount++; |
568 | } | 502 | } |
569 | 503 | ||
570 | /* | 504 | /* |
571 | * Send the tx_status to mac80211 & debugfs. | 505 | * Send the tx_status to mac80211 & debugfs. |
572 | * mac80211 will clean up the skb structure. | 506 | * mac80211 will clean up the skb structure. |
573 | */ | 507 | */ |
574 | get_skb_desc(entry->skb)->frame_type = DUMP_FRAME_TXDONE; | 508 | get_skb_frame_desc(entry->skb)->frame_type = DUMP_FRAME_TXDONE; |
575 | rt2x00debug_dump_frame(rt2x00dev, entry->skb); | 509 | rt2x00debug_dump_frame(rt2x00dev, entry->skb); |
576 | ieee80211_tx_status_irqsafe(rt2x00dev->hw, entry->skb, tx_status); | 510 | ieee80211_tx_status_irqsafe(rt2x00dev->hw, entry->skb, &tx_status); |
577 | entry->skb = NULL; | 511 | entry->skb = NULL; |
578 | } | 512 | } |
579 | EXPORT_SYMBOL_GPL(rt2x00lib_txdone); | 513 | EXPORT_SYMBOL_GPL(rt2x00lib_txdone); |
580 | 514 | ||
581 | void rt2x00lib_rxdone(struct data_entry *entry, struct sk_buff *skb, | 515 | void rt2x00lib_rxdone(struct queue_entry *entry, |
582 | struct rxdata_entry_desc *desc) | 516 | struct rxdone_entry_desc *rxdesc) |
583 | { | 517 | { |
584 | struct rt2x00_dev *rt2x00dev = entry->ring->rt2x00dev; | 518 | struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; |
585 | struct ieee80211_rx_status *rx_status = &rt2x00dev->rx_status; | 519 | struct ieee80211_rx_status *rx_status = &rt2x00dev->rx_status; |
586 | struct ieee80211_hw_mode *mode; | 520 | struct ieee80211_hw_mode *mode; |
587 | struct ieee80211_rate *rate; | 521 | struct ieee80211_rate *rate; |
@@ -602,12 +536,12 @@ void rt2x00lib_rxdone(struct data_entry *entry, struct sk_buff *skb, | |||
602 | * the signal is the PLCP value. If it was received with | 536 | * the signal is the PLCP value. If it was received with |
603 | * a CCK bitrate the signal is the rate in 0.5kbit/s. | 537 | * a CCK bitrate the signal is the rate in 0.5kbit/s. |
604 | */ | 538 | */ |
605 | if (!desc->ofdm) | 539 | if (!rxdesc->ofdm) |
606 | val = DEVICE_GET_RATE_FIELD(rate->val, RATE); | 540 | val = DEVICE_GET_RATE_FIELD(rate->val, RATE); |
607 | else | 541 | else |
608 | val = DEVICE_GET_RATE_FIELD(rate->val, PLCP); | 542 | val = DEVICE_GET_RATE_FIELD(rate->val, PLCP); |
609 | 543 | ||
610 | if (val == desc->signal) { | 544 | if (val == rxdesc->signal) { |
611 | val = rate->val; | 545 | val = rate->val; |
612 | break; | 546 | break; |
613 | } | 547 | } |
@@ -616,26 +550,28 @@ void rt2x00lib_rxdone(struct data_entry *entry, struct sk_buff *skb, | |||
616 | /* | 550 | /* |
617 | * Only update link status if this is a beacon frame carrying our bssid. | 551 | * Only update link status if this is a beacon frame carrying our bssid. |
618 | */ | 552 | */ |
619 | hdr = (struct ieee80211_hdr*)skb->data; | 553 | hdr = (struct ieee80211_hdr*)entry->skb->data; |
620 | fc = le16_to_cpu(hdr->frame_control); | 554 | fc = le16_to_cpu(hdr->frame_control); |
621 | if (is_beacon(fc) && desc->my_bss) | 555 | if (is_beacon(fc) && rxdesc->my_bss) |
622 | rt2x00lib_update_link_stats(&rt2x00dev->link, desc->rssi); | 556 | rt2x00lib_update_link_stats(&rt2x00dev->link, rxdesc->rssi); |
623 | 557 | ||
624 | rt2x00dev->link.qual.rx_success++; | 558 | rt2x00dev->link.qual.rx_success++; |
625 | 559 | ||
626 | rx_status->rate = val; | 560 | rx_status->rate = val; |
627 | rx_status->signal = | 561 | rx_status->signal = |
628 | rt2x00lib_calculate_link_signal(rt2x00dev, desc->rssi); | 562 | rt2x00lib_calculate_link_signal(rt2x00dev, rxdesc->rssi); |
629 | rx_status->ssi = desc->rssi; | 563 | rx_status->ssi = rxdesc->rssi; |
630 | rx_status->flag = desc->flags; | 564 | rx_status->flag = rxdesc->flags; |
631 | rx_status->antenna = rt2x00dev->link.ant.active.rx; | 565 | rx_status->antenna = rt2x00dev->link.ant.active.rx; |
632 | 566 | ||
633 | /* | 567 | /* |
634 | * Send frame to mac80211 & debugfs | 568 | * Send frame to mac80211 & debugfs. |
569 | * mac80211 will clean up the skb structure. | ||
635 | */ | 570 | */ |
636 | get_skb_desc(skb)->frame_type = DUMP_FRAME_RXDONE; | 571 | get_skb_frame_desc(entry->skb)->frame_type = DUMP_FRAME_RXDONE; |
637 | rt2x00debug_dump_frame(rt2x00dev, skb); | 572 | rt2x00debug_dump_frame(rt2x00dev, entry->skb); |
638 | ieee80211_rx_irqsafe(rt2x00dev->hw, skb, rx_status); | 573 | ieee80211_rx_irqsafe(rt2x00dev->hw, entry->skb, rx_status); |
574 | entry->skb = NULL; | ||
639 | } | 575 | } |
640 | EXPORT_SYMBOL_GPL(rt2x00lib_rxdone); | 576 | EXPORT_SYMBOL_GPL(rt2x00lib_rxdone); |
641 | 577 | ||
@@ -646,9 +582,9 @@ void rt2x00lib_write_tx_desc(struct rt2x00_dev *rt2x00dev, | |||
646 | struct sk_buff *skb, | 582 | struct sk_buff *skb, |
647 | struct ieee80211_tx_control *control) | 583 | struct ieee80211_tx_control *control) |
648 | { | 584 | { |
649 | struct txdata_entry_desc desc; | 585 | struct txentry_desc txdesc; |
650 | struct skb_desc *skbdesc = get_skb_desc(skb); | 586 | struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb); |
651 | struct ieee80211_hdr *ieee80211hdr = skbdesc->data; | 587 | struct ieee80211_hdr *ieee80211hdr = (struct ieee80211_hdr *)skb->data; |
652 | int tx_rate; | 588 | int tx_rate; |
653 | int bitrate; | 589 | int bitrate; |
654 | int length; | 590 | int length; |
@@ -657,22 +593,22 @@ void rt2x00lib_write_tx_desc(struct rt2x00_dev *rt2x00dev, | |||
657 | u16 frame_control; | 593 | u16 frame_control; |
658 | u16 seq_ctrl; | 594 | u16 seq_ctrl; |
659 | 595 | ||
660 | memset(&desc, 0, sizeof(desc)); | 596 | memset(&txdesc, 0, sizeof(txdesc)); |
661 | 597 | ||
662 | desc.cw_min = skbdesc->ring->tx_params.cw_min; | 598 | txdesc.cw_min = skbdesc->entry->queue->cw_min; |
663 | desc.cw_max = skbdesc->ring->tx_params.cw_max; | 599 | txdesc.cw_max = skbdesc->entry->queue->cw_max; |
664 | desc.aifs = skbdesc->ring->tx_params.aifs; | 600 | txdesc.aifs = skbdesc->entry->queue->aifs; |
665 | 601 | ||
666 | /* | 602 | /* |
667 | * Identify queue | 603 | * Identify queue |
668 | */ | 604 | */ |
669 | if (control->queue < rt2x00dev->hw->queues) | 605 | if (control->queue < rt2x00dev->hw->queues) |
670 | desc.queue = control->queue; | 606 | txdesc.queue = control->queue; |
671 | else if (control->queue == IEEE80211_TX_QUEUE_BEACON || | 607 | else if (control->queue == IEEE80211_TX_QUEUE_BEACON || |
672 | control->queue == IEEE80211_TX_QUEUE_AFTER_BEACON) | 608 | control->queue == IEEE80211_TX_QUEUE_AFTER_BEACON) |
673 | desc.queue = QUEUE_MGMT; | 609 | txdesc.queue = QID_MGMT; |
674 | else | 610 | else |
675 | desc.queue = QUEUE_OTHER; | 611 | txdesc.queue = QID_OTHER; |
676 | 612 | ||
677 | /* | 613 | /* |
678 | * Read required fields from ieee80211 header. | 614 | * Read required fields from ieee80211 header. |
@@ -686,18 +622,18 @@ void rt2x00lib_write_tx_desc(struct rt2x00_dev *rt2x00dev, | |||
686 | * Check whether this frame is to be acked | 622 | * Check whether this frame is to be acked |
687 | */ | 623 | */ |
688 | if (!(control->flags & IEEE80211_TXCTL_NO_ACK)) | 624 | if (!(control->flags & IEEE80211_TXCTL_NO_ACK)) |
689 | __set_bit(ENTRY_TXD_ACK, &desc.flags); | 625 | __set_bit(ENTRY_TXD_ACK, &txdesc.flags); |
690 | 626 | ||
691 | /* | 627 | /* |
692 | * Check if this is a RTS/CTS frame | 628 | * Check if this is a RTS/CTS frame |
693 | */ | 629 | */ |
694 | if (is_rts_frame(frame_control) || is_cts_frame(frame_control)) { | 630 | if (is_rts_frame(frame_control) || is_cts_frame(frame_control)) { |
695 | __set_bit(ENTRY_TXD_BURST, &desc.flags); | 631 | __set_bit(ENTRY_TXD_BURST, &txdesc.flags); |
696 | if (is_rts_frame(frame_control)) { | 632 | if (is_rts_frame(frame_control)) { |
697 | __set_bit(ENTRY_TXD_RTS_FRAME, &desc.flags); | 633 | __set_bit(ENTRY_TXD_RTS_FRAME, &txdesc.flags); |
698 | __set_bit(ENTRY_TXD_ACK, &desc.flags); | 634 | __set_bit(ENTRY_TXD_ACK, &txdesc.flags); |
699 | } else | 635 | } else |
700 | __clear_bit(ENTRY_TXD_ACK, &desc.flags); | 636 | __clear_bit(ENTRY_TXD_ACK, &txdesc.flags); |
701 | if (control->rts_cts_rate) | 637 | if (control->rts_cts_rate) |
702 | tx_rate = control->rts_cts_rate; | 638 | tx_rate = control->rts_cts_rate; |
703 | } | 639 | } |
@@ -706,14 +642,14 @@ void rt2x00lib_write_tx_desc(struct rt2x00_dev *rt2x00dev, | |||
706 | * Check for OFDM | 642 | * Check for OFDM |
707 | */ | 643 | */ |
708 | if (DEVICE_GET_RATE_FIELD(tx_rate, RATEMASK) & DEV_OFDM_RATEMASK) | 644 | if (DEVICE_GET_RATE_FIELD(tx_rate, RATEMASK) & DEV_OFDM_RATEMASK) |
709 | __set_bit(ENTRY_TXD_OFDM_RATE, &desc.flags); | 645 | __set_bit(ENTRY_TXD_OFDM_RATE, &txdesc.flags); |
710 | 646 | ||
711 | /* | 647 | /* |
712 | * Check if more fragments are pending | 648 | * Check if more fragments are pending |
713 | */ | 649 | */ |
714 | if (ieee80211_get_morefrag(ieee80211hdr)) { | 650 | if (ieee80211_get_morefrag(ieee80211hdr)) { |
715 | __set_bit(ENTRY_TXD_BURST, &desc.flags); | 651 | __set_bit(ENTRY_TXD_BURST, &txdesc.flags); |
716 | __set_bit(ENTRY_TXD_MORE_FRAG, &desc.flags); | 652 | __set_bit(ENTRY_TXD_MORE_FRAG, &txdesc.flags); |
717 | } | 653 | } |
718 | 654 | ||
719 | /* | 655 | /* |
@@ -722,7 +658,7 @@ void rt2x00lib_write_tx_desc(struct rt2x00_dev *rt2x00dev, | |||
722 | */ | 658 | */ |
723 | if (control->queue == IEEE80211_TX_QUEUE_BEACON || | 659 | if (control->queue == IEEE80211_TX_QUEUE_BEACON || |
724 | is_probe_resp(frame_control)) | 660 | is_probe_resp(frame_control)) |
725 | __set_bit(ENTRY_TXD_REQ_TIMESTAMP, &desc.flags); | 661 | __set_bit(ENTRY_TXD_REQ_TIMESTAMP, &txdesc.flags); |
726 | 662 | ||
727 | /* | 663 | /* |
728 | * Determine with what IFS priority this frame should be send. | 664 | * Determine with what IFS priority this frame should be send. |
@@ -730,22 +666,22 @@ void rt2x00lib_write_tx_desc(struct rt2x00_dev *rt2x00dev, | |||
730 | * or this fragment came after RTS/CTS. | 666 | * or this fragment came after RTS/CTS. |
731 | */ | 667 | */ |
732 | if ((seq_ctrl & IEEE80211_SCTL_FRAG) > 0 || | 668 | if ((seq_ctrl & IEEE80211_SCTL_FRAG) > 0 || |
733 | test_bit(ENTRY_TXD_RTS_FRAME, &desc.flags)) | 669 | test_bit(ENTRY_TXD_RTS_FRAME, &txdesc.flags)) |
734 | desc.ifs = IFS_SIFS; | 670 | txdesc.ifs = IFS_SIFS; |
735 | else | 671 | else |
736 | desc.ifs = IFS_BACKOFF; | 672 | txdesc.ifs = IFS_BACKOFF; |
737 | 673 | ||
738 | /* | 674 | /* |
739 | * PLCP setup | 675 | * PLCP setup |
740 | * Length calculation depends on OFDM/CCK rate. | 676 | * Length calculation depends on OFDM/CCK rate. |
741 | */ | 677 | */ |
742 | desc.signal = DEVICE_GET_RATE_FIELD(tx_rate, PLCP); | 678 | txdesc.signal = DEVICE_GET_RATE_FIELD(tx_rate, PLCP); |
743 | desc.service = 0x04; | 679 | txdesc.service = 0x04; |
744 | 680 | ||
745 | length = skbdesc->data_len + FCS_LEN; | 681 | length = skb->len + FCS_LEN; |
746 | if (test_bit(ENTRY_TXD_OFDM_RATE, &desc.flags)) { | 682 | if (test_bit(ENTRY_TXD_OFDM_RATE, &txdesc.flags)) { |
747 | desc.length_high = (length >> 6) & 0x3f; | 683 | txdesc.length_high = (length >> 6) & 0x3f; |
748 | desc.length_low = length & 0x3f; | 684 | txdesc.length_low = length & 0x3f; |
749 | } else { | 685 | } else { |
750 | bitrate = DEVICE_GET_RATE_FIELD(tx_rate, RATE); | 686 | bitrate = DEVICE_GET_RATE_FIELD(tx_rate, RATE); |
751 | 687 | ||
@@ -762,27 +698,26 @@ void rt2x00lib_write_tx_desc(struct rt2x00_dev *rt2x00dev, | |||
762 | * Check if we need to set the Length Extension | 698 | * Check if we need to set the Length Extension |
763 | */ | 699 | */ |
764 | if (bitrate == 110 && residual <= 30) | 700 | if (bitrate == 110 && residual <= 30) |
765 | desc.service |= 0x80; | 701 | txdesc.service |= 0x80; |
766 | } | 702 | } |
767 | 703 | ||
768 | desc.length_high = (duration >> 8) & 0xff; | 704 | txdesc.length_high = (duration >> 8) & 0xff; |
769 | desc.length_low = duration & 0xff; | 705 | txdesc.length_low = duration & 0xff; |
770 | 706 | ||
771 | /* | 707 | /* |
772 | * When preamble is enabled we should set the | 708 | * When preamble is enabled we should set the |
773 | * preamble bit for the signal. | 709 | * preamble bit for the signal. |
774 | */ | 710 | */ |
775 | if (DEVICE_GET_RATE_FIELD(tx_rate, PREAMBLE)) | 711 | if (DEVICE_GET_RATE_FIELD(tx_rate, PREAMBLE)) |
776 | desc.signal |= 0x08; | 712 | txdesc.signal |= 0x08; |
777 | } | 713 | } |
778 | 714 | ||
779 | rt2x00dev->ops->lib->write_tx_desc(rt2x00dev, skb, &desc, control); | 715 | rt2x00dev->ops->lib->write_tx_desc(rt2x00dev, skb, &txdesc, control); |
780 | 716 | ||
781 | /* | 717 | /* |
782 | * Update ring entry. | 718 | * Update queue entry. |
783 | */ | 719 | */ |
784 | skbdesc->entry->skb = skb; | 720 | skbdesc->entry->skb = skb; |
785 | memcpy(&skbdesc->entry->tx_status.control, control, sizeof(*control)); | ||
786 | 721 | ||
787 | /* | 722 | /* |
788 | * The frame has been completely initialized and ready | 723 | * The frame has been completely initialized and ready |
@@ -1012,86 +947,6 @@ static int rt2x00lib_probe_hw(struct rt2x00_dev *rt2x00dev) | |||
1012 | /* | 947 | /* |
1013 | * Initialization/uninitialization handlers. | 948 | * Initialization/uninitialization handlers. |
1014 | */ | 949 | */ |
1015 | static int rt2x00lib_alloc_entries(struct data_ring *ring, | ||
1016 | const u16 max_entries, const u16 data_size, | ||
1017 | const u16 desc_size) | ||
1018 | { | ||
1019 | struct data_entry *entry; | ||
1020 | unsigned int i; | ||
1021 | |||
1022 | ring->stats.limit = max_entries; | ||
1023 | ring->data_size = data_size; | ||
1024 | ring->desc_size = desc_size; | ||
1025 | |||
1026 | /* | ||
1027 | * Allocate all ring entries. | ||
1028 | */ | ||
1029 | entry = kzalloc(ring->stats.limit * sizeof(*entry), GFP_KERNEL); | ||
1030 | if (!entry) | ||
1031 | return -ENOMEM; | ||
1032 | |||
1033 | for (i = 0; i < ring->stats.limit; i++) { | ||
1034 | entry[i].flags = 0; | ||
1035 | entry[i].ring = ring; | ||
1036 | entry[i].skb = NULL; | ||
1037 | entry[i].entry_idx = i; | ||
1038 | } | ||
1039 | |||
1040 | ring->entry = entry; | ||
1041 | |||
1042 | return 0; | ||
1043 | } | ||
1044 | |||
1045 | static int rt2x00lib_alloc_ring_entries(struct rt2x00_dev *rt2x00dev) | ||
1046 | { | ||
1047 | struct data_ring *ring; | ||
1048 | |||
1049 | /* | ||
1050 | * Allocate the RX ring. | ||
1051 | */ | ||
1052 | if (rt2x00lib_alloc_entries(rt2x00dev->rx, RX_ENTRIES, DATA_FRAME_SIZE, | ||
1053 | rt2x00dev->ops->rxd_size)) | ||
1054 | return -ENOMEM; | ||
1055 | |||
1056 | /* | ||
1057 | * First allocate the TX rings. | ||
1058 | */ | ||
1059 | txring_for_each(rt2x00dev, ring) { | ||
1060 | if (rt2x00lib_alloc_entries(ring, TX_ENTRIES, DATA_FRAME_SIZE, | ||
1061 | rt2x00dev->ops->txd_size)) | ||
1062 | return -ENOMEM; | ||
1063 | } | ||
1064 | |||
1065 | if (!test_bit(DRIVER_REQUIRE_BEACON_RING, &rt2x00dev->flags)) | ||
1066 | return 0; | ||
1067 | |||
1068 | /* | ||
1069 | * Allocate the BEACON ring. | ||
1070 | */ | ||
1071 | if (rt2x00lib_alloc_entries(&rt2x00dev->bcn[0], BEACON_ENTRIES, | ||
1072 | MGMT_FRAME_SIZE, rt2x00dev->ops->txd_size)) | ||
1073 | return -ENOMEM; | ||
1074 | |||
1075 | /* | ||
1076 | * Allocate the Atim ring. | ||
1077 | */ | ||
1078 | if (rt2x00lib_alloc_entries(&rt2x00dev->bcn[1], ATIM_ENTRIES, | ||
1079 | DATA_FRAME_SIZE, rt2x00dev->ops->txd_size)) | ||
1080 | return -ENOMEM; | ||
1081 | |||
1082 | return 0; | ||
1083 | } | ||
1084 | |||
1085 | static void rt2x00lib_free_ring_entries(struct rt2x00_dev *rt2x00dev) | ||
1086 | { | ||
1087 | struct data_ring *ring; | ||
1088 | |||
1089 | ring_for_each(rt2x00dev, ring) { | ||
1090 | kfree(ring->entry); | ||
1091 | ring->entry = NULL; | ||
1092 | } | ||
1093 | } | ||
1094 | |||
1095 | static void rt2x00lib_uninitialize(struct rt2x00_dev *rt2x00dev) | 950 | static void rt2x00lib_uninitialize(struct rt2x00_dev *rt2x00dev) |
1096 | { | 951 | { |
1097 | if (!__test_and_clear_bit(DEVICE_INITIALIZED, &rt2x00dev->flags)) | 952 | if (!__test_and_clear_bit(DEVICE_INITIALIZED, &rt2x00dev->flags)) |
@@ -1108,9 +963,9 @@ static void rt2x00lib_uninitialize(struct rt2x00_dev *rt2x00dev) | |||
1108 | rt2x00dev->ops->lib->uninitialize(rt2x00dev); | 963 | rt2x00dev->ops->lib->uninitialize(rt2x00dev); |
1109 | 964 | ||
1110 | /* | 965 | /* |
1111 | * Free allocated ring entries. | 966 | * Free allocated queue entries. |
1112 | */ | 967 | */ |
1113 | rt2x00lib_free_ring_entries(rt2x00dev); | 968 | rt2x00queue_uninitialize(rt2x00dev); |
1114 | } | 969 | } |
1115 | 970 | ||
1116 | static int rt2x00lib_initialize(struct rt2x00_dev *rt2x00dev) | 971 | static int rt2x00lib_initialize(struct rt2x00_dev *rt2x00dev) |
@@ -1121,13 +976,11 @@ static int rt2x00lib_initialize(struct rt2x00_dev *rt2x00dev) | |||
1121 | return 0; | 976 | return 0; |
1122 | 977 | ||
1123 | /* | 978 | /* |
1124 | * Allocate all ring entries. | 979 | * Allocate all queue entries. |
1125 | */ | 980 | */ |
1126 | status = rt2x00lib_alloc_ring_entries(rt2x00dev); | 981 | status = rt2x00queue_initialize(rt2x00dev); |
1127 | if (status) { | 982 | if (status) |
1128 | ERROR(rt2x00dev, "Ring entries allocation failed.\n"); | ||
1129 | return status; | 983 | return status; |
1130 | } | ||
1131 | 984 | ||
1132 | /* | 985 | /* |
1133 | * Initialize the device. | 986 | * Initialize the device. |
@@ -1143,15 +996,12 @@ static int rt2x00lib_initialize(struct rt2x00_dev *rt2x00dev) | |||
1143 | */ | 996 | */ |
1144 | status = rt2x00rfkill_register(rt2x00dev); | 997 | status = rt2x00rfkill_register(rt2x00dev); |
1145 | if (status) | 998 | if (status) |
1146 | goto exit_unitialize; | 999 | goto exit; |
1147 | 1000 | ||
1148 | return 0; | 1001 | return 0; |
1149 | 1002 | ||
1150 | exit_unitialize: | ||
1151 | rt2x00lib_uninitialize(rt2x00dev); | ||
1152 | |||
1153 | exit: | 1003 | exit: |
1154 | rt2x00lib_free_ring_entries(rt2x00dev); | 1004 | rt2x00lib_uninitialize(rt2x00dev); |
1155 | 1005 | ||
1156 | return status; | 1006 | return status; |
1157 | } | 1007 | } |
@@ -1211,65 +1061,6 @@ void rt2x00lib_stop(struct rt2x00_dev *rt2x00dev) | |||
1211 | /* | 1061 | /* |
1212 | * driver allocation handlers. | 1062 | * driver allocation handlers. |
1213 | */ | 1063 | */ |
1214 | static int rt2x00lib_alloc_rings(struct rt2x00_dev *rt2x00dev) | ||
1215 | { | ||
1216 | struct data_ring *ring; | ||
1217 | unsigned int index; | ||
1218 | |||
1219 | /* | ||
1220 | * We need the following rings: | ||
1221 | * RX: 1 | ||
1222 | * TX: hw->queues | ||
1223 | * Beacon: 1 (if required) | ||
1224 | * Atim: 1 (if required) | ||
1225 | */ | ||
1226 | rt2x00dev->data_rings = 1 + rt2x00dev->hw->queues + | ||
1227 | (2 * test_bit(DRIVER_REQUIRE_BEACON_RING, &rt2x00dev->flags)); | ||
1228 | |||
1229 | ring = kzalloc(rt2x00dev->data_rings * sizeof(*ring), GFP_KERNEL); | ||
1230 | if (!ring) { | ||
1231 | ERROR(rt2x00dev, "Ring allocation failed.\n"); | ||
1232 | return -ENOMEM; | ||
1233 | } | ||
1234 | |||
1235 | /* | ||
1236 | * Initialize pointers | ||
1237 | */ | ||
1238 | rt2x00dev->rx = ring; | ||
1239 | rt2x00dev->tx = &rt2x00dev->rx[1]; | ||
1240 | if (test_bit(DRIVER_REQUIRE_BEACON_RING, &rt2x00dev->flags)) | ||
1241 | rt2x00dev->bcn = &rt2x00dev->tx[rt2x00dev->hw->queues]; | ||
1242 | |||
1243 | /* | ||
1244 | * Initialize ring parameters. | ||
1245 | * RX: queue_idx = 0 | ||
1246 | * TX: queue_idx = IEEE80211_TX_QUEUE_DATA0 + index | ||
1247 | * TX: cw_min: 2^5 = 32. | ||
1248 | * TX: cw_max: 2^10 = 1024. | ||
1249 | */ | ||
1250 | rt2x00dev->rx->rt2x00dev = rt2x00dev; | ||
1251 | rt2x00dev->rx->queue_idx = 0; | ||
1252 | |||
1253 | index = IEEE80211_TX_QUEUE_DATA0; | ||
1254 | txring_for_each(rt2x00dev, ring) { | ||
1255 | ring->rt2x00dev = rt2x00dev; | ||
1256 | ring->queue_idx = index++; | ||
1257 | ring->tx_params.aifs = 2; | ||
1258 | ring->tx_params.cw_min = 5; | ||
1259 | ring->tx_params.cw_max = 10; | ||
1260 | } | ||
1261 | |||
1262 | return 0; | ||
1263 | } | ||
1264 | |||
1265 | static void rt2x00lib_free_rings(struct rt2x00_dev *rt2x00dev) | ||
1266 | { | ||
1267 | kfree(rt2x00dev->rx); | ||
1268 | rt2x00dev->rx = NULL; | ||
1269 | rt2x00dev->tx = NULL; | ||
1270 | rt2x00dev->bcn = NULL; | ||
1271 | } | ||
1272 | |||
1273 | int rt2x00lib_probe_dev(struct rt2x00_dev *rt2x00dev) | 1064 | int rt2x00lib_probe_dev(struct rt2x00_dev *rt2x00dev) |
1274 | { | 1065 | { |
1275 | int retval = -ENOMEM; | 1066 | int retval = -ENOMEM; |
@@ -1297,9 +1088,9 @@ int rt2x00lib_probe_dev(struct rt2x00_dev *rt2x00dev) | |||
1297 | rt2x00dev->interface.type = IEEE80211_IF_TYPE_INVALID; | 1088 | rt2x00dev->interface.type = IEEE80211_IF_TYPE_INVALID; |
1298 | 1089 | ||
1299 | /* | 1090 | /* |
1300 | * Allocate ring array. | 1091 | * Allocate queue array. |
1301 | */ | 1092 | */ |
1302 | retval = rt2x00lib_alloc_rings(rt2x00dev); | 1093 | retval = rt2x00queue_allocate(rt2x00dev); |
1303 | if (retval) | 1094 | if (retval) |
1304 | goto exit; | 1095 | goto exit; |
1305 | 1096 | ||
@@ -1370,9 +1161,9 @@ void rt2x00lib_remove_dev(struct rt2x00_dev *rt2x00dev) | |||
1370 | rt2x00lib_free_firmware(rt2x00dev); | 1161 | rt2x00lib_free_firmware(rt2x00dev); |
1371 | 1162 | ||
1372 | /* | 1163 | /* |
1373 | * Free ring structures. | 1164 | * Free queue structures. |
1374 | */ | 1165 | */ |
1375 | rt2x00lib_free_rings(rt2x00dev); | 1166 | rt2x00queue_free(rt2x00dev); |
1376 | } | 1167 | } |
1377 | EXPORT_SYMBOL_GPL(rt2x00lib_remove_dev); | 1168 | EXPORT_SYMBOL_GPL(rt2x00lib_remove_dev); |
1378 | 1169 | ||