diff options
Diffstat (limited to 'drivers/net/wireless/rt2x00/rt2x00dev.c')
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2x00dev.c | 226 |
1 files changed, 41 insertions, 185 deletions
diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c index 3a49c256789f..69e233610c94 100644 --- a/drivers/net/wireless/rt2x00/rt2x00dev.c +++ b/drivers/net/wireless/rt2x00/rt2x00dev.c | |||
@@ -28,7 +28,6 @@ | |||
28 | 28 | ||
29 | #include "rt2x00.h" | 29 | #include "rt2x00.h" |
30 | #include "rt2x00lib.h" | 30 | #include "rt2x00lib.h" |
31 | #include "rt2x00dump.h" | ||
32 | 31 | ||
33 | /* | 32 | /* |
34 | * Link tuning handlers | 33 | * Link tuning handlers |
@@ -126,7 +125,7 @@ int rt2x00lib_enable_radio(struct rt2x00_dev *rt2x00dev) | |||
126 | /* | 125 | /* |
127 | * Start the TX queues. | 126 | * Start the TX queues. |
128 | */ | 127 | */ |
129 | ieee80211_start_queues(rt2x00dev->hw); | 128 | ieee80211_wake_queues(rt2x00dev->hw); |
130 | 129 | ||
131 | return 0; | 130 | return 0; |
132 | } | 131 | } |
@@ -416,7 +415,6 @@ static void rt2x00lib_intf_scheduled_iter(void *data, u8 *mac, | |||
416 | struct rt2x00_dev *rt2x00dev = data; | 415 | struct rt2x00_dev *rt2x00dev = data; |
417 | struct rt2x00_intf *intf = vif_to_intf(vif); | 416 | struct rt2x00_intf *intf = vif_to_intf(vif); |
418 | struct sk_buff *skb; | 417 | struct sk_buff *skb; |
419 | struct ieee80211_tx_control control; | ||
420 | struct ieee80211_bss_conf conf; | 418 | struct ieee80211_bss_conf conf; |
421 | int delayed_flags; | 419 | int delayed_flags; |
422 | 420 | ||
@@ -434,9 +432,9 @@ static void rt2x00lib_intf_scheduled_iter(void *data, u8 *mac, | |||
434 | spin_unlock(&intf->lock); | 432 | spin_unlock(&intf->lock); |
435 | 433 | ||
436 | if (delayed_flags & DELAYED_UPDATE_BEACON) { | 434 | if (delayed_flags & DELAYED_UPDATE_BEACON) { |
437 | skb = ieee80211_beacon_get(rt2x00dev->hw, vif, &control); | 435 | skb = ieee80211_beacon_get(rt2x00dev->hw, vif); |
438 | if (skb && rt2x00dev->ops->hw->beacon_update(rt2x00dev->hw, | 436 | if (skb && |
439 | skb, &control)) | 437 | rt2x00dev->ops->hw->beacon_update(rt2x00dev->hw, skb)) |
440 | dev_kfree_skb(skb); | 438 | dev_kfree_skb(skb); |
441 | } | 439 | } |
442 | 440 | ||
@@ -495,61 +493,55 @@ void rt2x00lib_txdone(struct queue_entry *entry, | |||
495 | struct txdone_entry_desc *txdesc) | 493 | struct txdone_entry_desc *txdesc) |
496 | { | 494 | { |
497 | struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; | 495 | struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; |
498 | struct skb_frame_desc *skbdesc; | 496 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(entry->skb); |
499 | struct ieee80211_tx_status tx_status; | 497 | |
500 | int success = !!(txdesc->status == TX_SUCCESS || | 498 | /* |
501 | txdesc->status == TX_SUCCESS_RETRY); | 499 | * Send frame to debugfs immediately, after this call is completed |
502 | int fail = !!(txdesc->status == TX_FAIL_RETRY || | 500 | * we are going to overwrite the skb->cb array. |
503 | txdesc->status == TX_FAIL_INVALID || | 501 | */ |
504 | txdesc->status == TX_FAIL_OTHER); | 502 | rt2x00debug_dump_frame(rt2x00dev, DUMP_FRAME_TXDONE, entry->skb); |
505 | 503 | ||
506 | /* | 504 | /* |
507 | * Update TX statistics. | 505 | * Update TX statistics. |
508 | */ | 506 | */ |
509 | rt2x00dev->link.qual.tx_success += success; | 507 | rt2x00dev->link.qual.tx_success += |
510 | rt2x00dev->link.qual.tx_failed += txdesc->retry + fail; | 508 | test_bit(TXDONE_SUCCESS, &txdesc->flags); |
509 | rt2x00dev->link.qual.tx_failed += | ||
510 | txdesc->retry + !!test_bit(TXDONE_FAILURE, &txdesc->flags); | ||
511 | 511 | ||
512 | /* | 512 | /* |
513 | * Initialize TX status | 513 | * Initialize TX status |
514 | */ | 514 | */ |
515 | tx_status.flags = 0; | 515 | memset(&tx_info->status, 0, sizeof(tx_info->status)); |
516 | tx_status.ack_signal = 0; | 516 | tx_info->status.ack_signal = 0; |
517 | tx_status.excessive_retries = (txdesc->status == TX_FAIL_RETRY); | 517 | tx_info->status.excessive_retries = |
518 | tx_status.retry_count = txdesc->retry; | 518 | test_bit(TXDONE_EXCESSIVE_RETRY, &txdesc->flags); |
519 | memcpy(&tx_status.control, txdesc->control, sizeof(*txdesc->control)); | 519 | tx_info->status.retry_count = txdesc->retry; |
520 | 520 | ||
521 | if (!(tx_status.control.flags & IEEE80211_TXCTL_NO_ACK)) { | 521 | if (!(tx_info->flags & IEEE80211_TX_CTL_NO_ACK)) { |
522 | if (success) | 522 | if (test_bit(TXDONE_SUCCESS, &txdesc->flags)) |
523 | tx_status.flags |= IEEE80211_TX_STATUS_ACK; | 523 | tx_info->flags |= IEEE80211_TX_STAT_ACK; |
524 | else | 524 | else if (test_bit(TXDONE_FAILURE, &txdesc->flags)) |
525 | rt2x00dev->low_level_stats.dot11ACKFailureCount++; | 525 | rt2x00dev->low_level_stats.dot11ACKFailureCount++; |
526 | } | 526 | } |
527 | 527 | ||
528 | if (tx_status.control.flags & IEEE80211_TXCTL_USE_RTS_CTS) { | 528 | if (tx_info->flags & IEEE80211_TX_CTL_USE_RTS_CTS) { |
529 | if (success) | 529 | if (test_bit(TXDONE_SUCCESS, &txdesc->flags)) |
530 | rt2x00dev->low_level_stats.dot11RTSSuccessCount++; | 530 | rt2x00dev->low_level_stats.dot11RTSSuccessCount++; |
531 | else | 531 | else if (test_bit(TXDONE_FAILURE, &txdesc->flags)) |
532 | rt2x00dev->low_level_stats.dot11RTSFailureCount++; | 532 | rt2x00dev->low_level_stats.dot11RTSFailureCount++; |
533 | } | 533 | } |
534 | 534 | ||
535 | /* | 535 | /* |
536 | * Send the tx_status to debugfs. Only send the status report | 536 | * Only send the status report to mac80211 when TX status was |
537 | * to mac80211 when the frame originated from there. If this was | 537 | * requested by it. If this was a extra frame coming through |
538 | * a extra frame coming through a mac80211 library call (RTS/CTS) | 538 | * a mac80211 library call (RTS/CTS) then we should not send the |
539 | * then we should not send the status report back. | 539 | * status report back. |
540 | * If send to mac80211, mac80211 will clean up the skb structure, | ||
541 | * otherwise we have to do it ourself. | ||
542 | */ | 540 | */ |
543 | skbdesc = get_skb_frame_desc(entry->skb); | 541 | if (tx_info->flags & IEEE80211_TX_CTL_REQ_TX_STATUS) |
544 | skbdesc->frame_type = DUMP_FRAME_TXDONE; | 542 | ieee80211_tx_status_irqsafe(rt2x00dev->hw, entry->skb); |
545 | |||
546 | rt2x00debug_dump_frame(rt2x00dev, entry->skb); | ||
547 | |||
548 | if (!(skbdesc->flags & FRAME_DESC_DRIVER_GENERATED)) | ||
549 | ieee80211_tx_status_irqsafe(rt2x00dev->hw, | ||
550 | entry->skb, &tx_status); | ||
551 | else | 543 | else |
552 | dev_kfree_skb(entry->skb); | 544 | dev_kfree_skb_irq(entry->skb); |
553 | entry->skb = NULL; | 545 | entry->skb = NULL; |
554 | } | 546 | } |
555 | EXPORT_SYMBOL_GPL(rt2x00lib_txdone); | 547 | EXPORT_SYMBOL_GPL(rt2x00lib_txdone); |
@@ -610,154 +602,13 @@ void rt2x00lib_rxdone(struct queue_entry *entry, | |||
610 | * Send frame to mac80211 & debugfs. | 602 | * Send frame to mac80211 & debugfs. |
611 | * mac80211 will clean up the skb structure. | 603 | * mac80211 will clean up the skb structure. |
612 | */ | 604 | */ |
613 | get_skb_frame_desc(entry->skb)->frame_type = DUMP_FRAME_RXDONE; | 605 | rt2x00debug_dump_frame(rt2x00dev, DUMP_FRAME_RXDONE, entry->skb); |
614 | rt2x00debug_dump_frame(rt2x00dev, entry->skb); | ||
615 | ieee80211_rx_irqsafe(rt2x00dev->hw, entry->skb, rx_status); | 606 | ieee80211_rx_irqsafe(rt2x00dev->hw, entry->skb, rx_status); |
616 | entry->skb = NULL; | 607 | entry->skb = NULL; |
617 | } | 608 | } |
618 | EXPORT_SYMBOL_GPL(rt2x00lib_rxdone); | 609 | EXPORT_SYMBOL_GPL(rt2x00lib_rxdone); |
619 | 610 | ||
620 | /* | 611 | /* |
621 | * TX descriptor initializer | ||
622 | */ | ||
623 | void rt2x00lib_write_tx_desc(struct rt2x00_dev *rt2x00dev, | ||
624 | struct sk_buff *skb, | ||
625 | struct ieee80211_tx_control *control) | ||
626 | { | ||
627 | struct txentry_desc txdesc; | ||
628 | struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb); | ||
629 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skbdesc->data; | ||
630 | const struct rt2x00_rate *rate; | ||
631 | int tx_rate; | ||
632 | int length; | ||
633 | int duration; | ||
634 | int residual; | ||
635 | u16 frame_control; | ||
636 | u16 seq_ctrl; | ||
637 | |||
638 | memset(&txdesc, 0, sizeof(txdesc)); | ||
639 | |||
640 | txdesc.queue = skbdesc->entry->queue->qid; | ||
641 | txdesc.cw_min = skbdesc->entry->queue->cw_min; | ||
642 | txdesc.cw_max = skbdesc->entry->queue->cw_max; | ||
643 | txdesc.aifs = skbdesc->entry->queue->aifs; | ||
644 | |||
645 | /* | ||
646 | * Read required fields from ieee80211 header. | ||
647 | */ | ||
648 | frame_control = le16_to_cpu(hdr->frame_control); | ||
649 | seq_ctrl = le16_to_cpu(hdr->seq_ctrl); | ||
650 | |||
651 | tx_rate = control->tx_rate->hw_value; | ||
652 | |||
653 | /* | ||
654 | * Check whether this frame is to be acked | ||
655 | */ | ||
656 | if (!(control->flags & IEEE80211_TXCTL_NO_ACK)) | ||
657 | __set_bit(ENTRY_TXD_ACK, &txdesc.flags); | ||
658 | |||
659 | /* | ||
660 | * Check if this is a RTS/CTS frame | ||
661 | */ | ||
662 | if (is_rts_frame(frame_control) || is_cts_frame(frame_control)) { | ||
663 | __set_bit(ENTRY_TXD_BURST, &txdesc.flags); | ||
664 | if (is_rts_frame(frame_control)) { | ||
665 | __set_bit(ENTRY_TXD_RTS_FRAME, &txdesc.flags); | ||
666 | __set_bit(ENTRY_TXD_ACK, &txdesc.flags); | ||
667 | } else | ||
668 | __clear_bit(ENTRY_TXD_ACK, &txdesc.flags); | ||
669 | if (control->rts_cts_rate) | ||
670 | tx_rate = control->rts_cts_rate->hw_value; | ||
671 | } | ||
672 | |||
673 | rate = rt2x00_get_rate(tx_rate); | ||
674 | |||
675 | /* | ||
676 | * Check if more fragments are pending | ||
677 | */ | ||
678 | if (ieee80211_get_morefrag(hdr)) { | ||
679 | __set_bit(ENTRY_TXD_BURST, &txdesc.flags); | ||
680 | __set_bit(ENTRY_TXD_MORE_FRAG, &txdesc.flags); | ||
681 | } | ||
682 | |||
683 | /* | ||
684 | * Beacons and probe responses require the tsf timestamp | ||
685 | * to be inserted into the frame. | ||
686 | */ | ||
687 | if (txdesc.queue == QID_BEACON || is_probe_resp(frame_control)) | ||
688 | __set_bit(ENTRY_TXD_REQ_TIMESTAMP, &txdesc.flags); | ||
689 | |||
690 | /* | ||
691 | * Determine with what IFS priority this frame should be send. | ||
692 | * Set ifs to IFS_SIFS when the this is not the first fragment, | ||
693 | * or this fragment came after RTS/CTS. | ||
694 | */ | ||
695 | if ((seq_ctrl & IEEE80211_SCTL_FRAG) > 0 || | ||
696 | test_bit(ENTRY_TXD_RTS_FRAME, &txdesc.flags)) | ||
697 | txdesc.ifs = IFS_SIFS; | ||
698 | else | ||
699 | txdesc.ifs = IFS_BACKOFF; | ||
700 | |||
701 | /* | ||
702 | * PLCP setup | ||
703 | * Length calculation depends on OFDM/CCK rate. | ||
704 | */ | ||
705 | txdesc.signal = rate->plcp; | ||
706 | txdesc.service = 0x04; | ||
707 | |||
708 | length = skbdesc->data_len + FCS_LEN; | ||
709 | if (rate->flags & DEV_RATE_OFDM) { | ||
710 | __set_bit(ENTRY_TXD_OFDM_RATE, &txdesc.flags); | ||
711 | |||
712 | txdesc.length_high = (length >> 6) & 0x3f; | ||
713 | txdesc.length_low = length & 0x3f; | ||
714 | } else { | ||
715 | /* | ||
716 | * Convert length to microseconds. | ||
717 | */ | ||
718 | residual = get_duration_res(length, rate->bitrate); | ||
719 | duration = get_duration(length, rate->bitrate); | ||
720 | |||
721 | if (residual != 0) { | ||
722 | duration++; | ||
723 | |||
724 | /* | ||
725 | * Check if we need to set the Length Extension | ||
726 | */ | ||
727 | if (rate->bitrate == 110 && residual <= 30) | ||
728 | txdesc.service |= 0x80; | ||
729 | } | ||
730 | |||
731 | txdesc.length_high = (duration >> 8) & 0xff; | ||
732 | txdesc.length_low = duration & 0xff; | ||
733 | |||
734 | /* | ||
735 | * When preamble is enabled we should set the | ||
736 | * preamble bit for the signal. | ||
737 | */ | ||
738 | if (rt2x00_get_rate_preamble(tx_rate)) | ||
739 | txdesc.signal |= 0x08; | ||
740 | } | ||
741 | |||
742 | rt2x00dev->ops->lib->write_tx_desc(rt2x00dev, skb, &txdesc, control); | ||
743 | |||
744 | /* | ||
745 | * Update queue entry. | ||
746 | */ | ||
747 | skbdesc->entry->skb = skb; | ||
748 | |||
749 | /* | ||
750 | * The frame has been completely initialized and ready | ||
751 | * for sending to the device. The caller will push the | ||
752 | * frame to the device, but we are going to push the | ||
753 | * frame to debugfs here. | ||
754 | */ | ||
755 | skbdesc->frame_type = DUMP_FRAME_TX; | ||
756 | rt2x00debug_dump_frame(rt2x00dev, skb); | ||
757 | } | ||
758 | EXPORT_SYMBOL_GPL(rt2x00lib_write_tx_desc); | ||
759 | |||
760 | /* | ||
761 | * Driver initialization handlers. | 612 | * Driver initialization handlers. |
762 | */ | 613 | */ |
763 | const struct rt2x00_rate rt2x00_supported_rates[12] = { | 614 | const struct rt2x00_rate rt2x00_supported_rates[12] = { |
@@ -973,6 +824,11 @@ static int rt2x00lib_probe_hw(struct rt2x00_dev *rt2x00dev) | |||
973 | return status; | 824 | return status; |
974 | 825 | ||
975 | /* | 826 | /* |
827 | * Initialize HW fields. | ||
828 | */ | ||
829 | rt2x00dev->hw->queues = rt2x00dev->ops->tx_queues; | ||
830 | |||
831 | /* | ||
976 | * Register HW. | 832 | * Register HW. |
977 | */ | 833 | */ |
978 | status = ieee80211_register_hw(rt2x00dev->hw); | 834 | status = ieee80211_register_hw(rt2x00dev->hw); |
@@ -1327,7 +1183,7 @@ int rt2x00lib_resume(struct rt2x00_dev *rt2x00dev) | |||
1327 | * In that case we have disabled the TX queue and should | 1183 | * In that case we have disabled the TX queue and should |
1328 | * now enable it again | 1184 | * now enable it again |
1329 | */ | 1185 | */ |
1330 | ieee80211_start_queues(rt2x00dev->hw); | 1186 | ieee80211_wake_queues(rt2x00dev->hw); |
1331 | 1187 | ||
1332 | /* | 1188 | /* |
1333 | * During interface iteration we might have changed the | 1189 | * During interface iteration we might have changed the |