diff options
author | Ivo van Doorn <ivdoorn@gmail.com> | 2008-02-03 09:50:40 -0500 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2008-02-29 15:19:38 -0500 |
commit | 70e2fed4ec14df84ed72554d573794714b15a078 (patch) | |
tree | 6e8d63a357fb1c45d950f292bf330e8af718b85a /drivers/net/wireless/rt2x00/rt2x00dev.c | |
parent | e71c9fac316221a4594f3bd58c2d30ada0cabaf6 (diff) |
rt2x00: Rate structure overhaul
Recent changes to the rate structure registration broke rt2x00,
the hw_value was reduced from 32bits to 16bits while rt2x00 used
the full 32bits. However the way rt2x00 used the value was inflexible
and needed to be changed anyway.
This patch creates a array containing information for each rate,
the hw_value passed to mac80211 is the index value for that array
including a field to indicate if short preamble should be enabled.
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 | 173 |
1 files changed, 107 insertions, 66 deletions
diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c index 83a72ae36638..f0ba481c51e6 100644 --- a/drivers/net/wireless/rt2x00/rt2x00dev.c +++ b/drivers/net/wireless/rt2x00/rt2x00dev.c | |||
@@ -551,10 +551,10 @@ void rt2x00lib_rxdone(struct queue_entry *entry, | |||
551 | struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; | 551 | struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; |
552 | struct ieee80211_rx_status *rx_status = &rt2x00dev->rx_status; | 552 | struct ieee80211_rx_status *rx_status = &rt2x00dev->rx_status; |
553 | struct ieee80211_supported_band *sband; | 553 | struct ieee80211_supported_band *sband; |
554 | struct ieee80211_rate *rate; | ||
555 | struct ieee80211_hdr *hdr; | 554 | struct ieee80211_hdr *hdr; |
555 | const struct rt2x00_rate *rate; | ||
556 | unsigned int i; | 556 | unsigned int i; |
557 | int val = 0, idx = -1; | 557 | int idx = -1; |
558 | u16 fc; | 558 | u16 fc; |
559 | 559 | ||
560 | /* | 560 | /* |
@@ -562,19 +562,15 @@ void rt2x00lib_rxdone(struct queue_entry *entry, | |||
562 | */ | 562 | */ |
563 | sband = &rt2x00dev->bands[rt2x00dev->curr_band]; | 563 | sband = &rt2x00dev->bands[rt2x00dev->curr_band]; |
564 | for (i = 0; i < sband->n_bitrates; i++) { | 564 | for (i = 0; i < sband->n_bitrates; i++) { |
565 | rate = &sband->bitrates[i]; | 565 | rate = rt2x00_get_rate(sband->bitrates[i].hw_value); |
566 | 566 | ||
567 | /* | 567 | /* |
568 | * When frame was received with an OFDM bitrate, | 568 | * When frame was received with an OFDM bitrate, |
569 | * the signal is the PLCP value. If it was received with | 569 | * the signal is the PLCP value. If it was received with |
570 | * a CCK bitrate the signal is the rate in 0.5kbit/s. | 570 | * a CCK bitrate the signal is the rate in 100kbit/s. |
571 | */ | 571 | */ |
572 | if (!rxdesc->ofdm) | 572 | if ((rxdesc->ofdm && rate->plcp == rxdesc->signal) || |
573 | val = DEVICE_GET_RATE_FIELD(rate->hw_value, RATE); | 573 | (!rxdesc->ofdm && rate->bitrate == rxdesc->signal)) { |
574 | else | ||
575 | val = DEVICE_GET_RATE_FIELD(rate->hw_value, PLCP); | ||
576 | |||
577 | if (val == rxdesc->signal) { | ||
578 | idx = i; | 574 | idx = i; |
579 | break; | 575 | break; |
580 | } | 576 | } |
@@ -583,7 +579,7 @@ void rt2x00lib_rxdone(struct queue_entry *entry, | |||
583 | /* | 579 | /* |
584 | * Only update link status if this is a beacon frame carrying our bssid. | 580 | * Only update link status if this is a beacon frame carrying our bssid. |
585 | */ | 581 | */ |
586 | hdr = (struct ieee80211_hdr*)entry->skb->data; | 582 | hdr = (struct ieee80211_hdr *)entry->skb->data; |
587 | fc = le16_to_cpu(hdr->frame_control); | 583 | fc = le16_to_cpu(hdr->frame_control); |
588 | if (is_beacon(fc) && rxdesc->my_bss) | 584 | if (is_beacon(fc) && rxdesc->my_bss) |
589 | rt2x00lib_update_link_stats(&rt2x00dev->link, rxdesc->rssi); | 585 | rt2x00lib_update_link_stats(&rt2x00dev->link, rxdesc->rssi); |
@@ -617,9 +613,9 @@ void rt2x00lib_write_tx_desc(struct rt2x00_dev *rt2x00dev, | |||
617 | { | 613 | { |
618 | struct txentry_desc txdesc; | 614 | struct txentry_desc txdesc; |
619 | struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb); | 615 | struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb); |
620 | struct ieee80211_hdr *ieee80211hdr = (struct ieee80211_hdr *)skb->data; | 616 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; |
617 | const struct rt2x00_rate *rate; | ||
621 | int tx_rate; | 618 | int tx_rate; |
622 | int bitrate; | ||
623 | int length; | 619 | int length; |
624 | int duration; | 620 | int duration; |
625 | int residual; | 621 | int residual; |
@@ -636,8 +632,8 @@ void rt2x00lib_write_tx_desc(struct rt2x00_dev *rt2x00dev, | |||
636 | /* | 632 | /* |
637 | * Read required fields from ieee80211 header. | 633 | * Read required fields from ieee80211 header. |
638 | */ | 634 | */ |
639 | frame_control = le16_to_cpu(ieee80211hdr->frame_control); | 635 | frame_control = le16_to_cpu(hdr->frame_control); |
640 | seq_ctrl = le16_to_cpu(ieee80211hdr->seq_ctrl); | 636 | seq_ctrl = le16_to_cpu(hdr->seq_ctrl); |
641 | 637 | ||
642 | tx_rate = control->tx_rate->hw_value; | 638 | tx_rate = control->tx_rate->hw_value; |
643 | 639 | ||
@@ -661,16 +657,12 @@ void rt2x00lib_write_tx_desc(struct rt2x00_dev *rt2x00dev, | |||
661 | tx_rate = control->rts_cts_rate->hw_value; | 657 | tx_rate = control->rts_cts_rate->hw_value; |
662 | } | 658 | } |
663 | 659 | ||
664 | /* | 660 | rate = rt2x00_get_rate(tx_rate); |
665 | * Check for OFDM | ||
666 | */ | ||
667 | if (DEVICE_GET_RATE_FIELD(tx_rate, RATEMASK) & DEV_OFDM_RATEMASK) | ||
668 | __set_bit(ENTRY_TXD_OFDM_RATE, &txdesc.flags); | ||
669 | 661 | ||
670 | /* | 662 | /* |
671 | * Check if more fragments are pending | 663 | * Check if more fragments are pending |
672 | */ | 664 | */ |
673 | if (ieee80211_get_morefrag(ieee80211hdr)) { | 665 | if (ieee80211_get_morefrag(hdr)) { |
674 | __set_bit(ENTRY_TXD_BURST, &txdesc.flags); | 666 | __set_bit(ENTRY_TXD_BURST, &txdesc.flags); |
675 | __set_bit(ENTRY_TXD_MORE_FRAG, &txdesc.flags); | 667 | __set_bit(ENTRY_TXD_MORE_FRAG, &txdesc.flags); |
676 | } | 668 | } |
@@ -698,21 +690,21 @@ void rt2x00lib_write_tx_desc(struct rt2x00_dev *rt2x00dev, | |||
698 | * PLCP setup | 690 | * PLCP setup |
699 | * Length calculation depends on OFDM/CCK rate. | 691 | * Length calculation depends on OFDM/CCK rate. |
700 | */ | 692 | */ |
701 | txdesc.signal = DEVICE_GET_RATE_FIELD(tx_rate, PLCP); | 693 | txdesc.signal = rate->plcp; |
702 | txdesc.service = 0x04; | 694 | txdesc.service = 0x04; |
703 | 695 | ||
704 | length = skb->len + FCS_LEN; | 696 | length = skb->len + FCS_LEN; |
705 | if (test_bit(ENTRY_TXD_OFDM_RATE, &txdesc.flags)) { | 697 | if (rate->flags & DEV_RATE_OFDM) { |
698 | __set_bit(ENTRY_TXD_OFDM_RATE, &txdesc.flags); | ||
699 | |||
706 | txdesc.length_high = (length >> 6) & 0x3f; | 700 | txdesc.length_high = (length >> 6) & 0x3f; |
707 | txdesc.length_low = length & 0x3f; | 701 | txdesc.length_low = length & 0x3f; |
708 | } else { | 702 | } else { |
709 | bitrate = DEVICE_GET_RATE_FIELD(tx_rate, RATE); | ||
710 | |||
711 | /* | 703 | /* |
712 | * Convert length to microseconds. | 704 | * Convert length to microseconds. |
713 | */ | 705 | */ |
714 | residual = get_duration_res(length, bitrate); | 706 | residual = get_duration_res(length, rate->bitrate); |
715 | duration = get_duration(length, bitrate); | 707 | duration = get_duration(length, rate->bitrate); |
716 | 708 | ||
717 | if (residual != 0) { | 709 | if (residual != 0) { |
718 | duration++; | 710 | duration++; |
@@ -720,7 +712,7 @@ void rt2x00lib_write_tx_desc(struct rt2x00_dev *rt2x00dev, | |||
720 | /* | 712 | /* |
721 | * Check if we need to set the Length Extension | 713 | * Check if we need to set the Length Extension |
722 | */ | 714 | */ |
723 | if (bitrate == 110 && residual <= 30) | 715 | if (rate->bitrate == 110 && residual <= 30) |
724 | txdesc.service |= 0x80; | 716 | txdesc.service |= 0x80; |
725 | } | 717 | } |
726 | 718 | ||
@@ -731,7 +723,7 @@ void rt2x00lib_write_tx_desc(struct rt2x00_dev *rt2x00dev, | |||
731 | * When preamble is enabled we should set the | 723 | * When preamble is enabled we should set the |
732 | * preamble bit for the signal. | 724 | * preamble bit for the signal. |
733 | */ | 725 | */ |
734 | if (DEVICE_GET_RATE_FIELD(tx_rate, PREAMBLE)) | 726 | if (rt2x00_get_rate_preamble(tx_rate)) |
735 | txdesc.signal |= 0x08; | 727 | txdesc.signal |= 0x08; |
736 | } | 728 | } |
737 | 729 | ||
@@ -756,6 +748,81 @@ EXPORT_SYMBOL_GPL(rt2x00lib_write_tx_desc); | |||
756 | /* | 748 | /* |
757 | * Driver initialization handlers. | 749 | * Driver initialization handlers. |
758 | */ | 750 | */ |
751 | const struct rt2x00_rate rt2x00_supported_rates[12] = { | ||
752 | { | ||
753 | .flags = 0, | ||
754 | .bitrate = 10, | ||
755 | .ratemask = DEV_RATEMASK_1MB, | ||
756 | .plcp = 0x00, | ||
757 | }, | ||
758 | { | ||
759 | .flags = DEV_RATE_SHORT_PREAMBLE, | ||
760 | .bitrate = 20, | ||
761 | .ratemask = DEV_RATEMASK_2MB, | ||
762 | .plcp = 0x01, | ||
763 | }, | ||
764 | { | ||
765 | .flags = DEV_RATE_SHORT_PREAMBLE, | ||
766 | .bitrate = 55, | ||
767 | .ratemask = DEV_RATEMASK_5_5MB, | ||
768 | .plcp = 0x02, | ||
769 | }, | ||
770 | { | ||
771 | .flags = DEV_RATE_SHORT_PREAMBLE, | ||
772 | .bitrate = 110, | ||
773 | .ratemask = DEV_RATEMASK_11MB, | ||
774 | .plcp = 0x03, | ||
775 | }, | ||
776 | { | ||
777 | .flags = DEV_RATE_OFDM, | ||
778 | .bitrate = 60, | ||
779 | .ratemask = DEV_RATEMASK_6MB, | ||
780 | .plcp = 0x0b, | ||
781 | }, | ||
782 | { | ||
783 | .flags = DEV_RATE_OFDM, | ||
784 | .bitrate = 90, | ||
785 | .ratemask = DEV_RATEMASK_9MB, | ||
786 | .plcp = 0x0f, | ||
787 | }, | ||
788 | { | ||
789 | .flags = DEV_RATE_OFDM, | ||
790 | .bitrate = 120, | ||
791 | .ratemask = DEV_RATEMASK_12MB, | ||
792 | .plcp = 0x0a, | ||
793 | }, | ||
794 | { | ||
795 | .flags = DEV_RATE_OFDM, | ||
796 | .bitrate = 180, | ||
797 | .ratemask = DEV_RATEMASK_18MB, | ||
798 | .plcp = 0x0e, | ||
799 | }, | ||
800 | { | ||
801 | .flags = DEV_RATE_OFDM, | ||
802 | .bitrate = 240, | ||
803 | .ratemask = DEV_RATEMASK_24MB, | ||
804 | .plcp = 0x09, | ||
805 | }, | ||
806 | { | ||
807 | .flags = DEV_RATE_OFDM, | ||
808 | .bitrate = 360, | ||
809 | .ratemask = DEV_RATEMASK_36MB, | ||
810 | .plcp = 0x0d, | ||
811 | }, | ||
812 | { | ||
813 | .flags = DEV_RATE_OFDM, | ||
814 | .bitrate = 480, | ||
815 | .ratemask = DEV_RATEMASK_48MB, | ||
816 | .plcp = 0x08, | ||
817 | }, | ||
818 | { | ||
819 | .flags = DEV_RATE_OFDM, | ||
820 | .bitrate = 540, | ||
821 | .ratemask = DEV_RATEMASK_54MB, | ||
822 | .plcp = 0x0c, | ||
823 | }, | ||
824 | }; | ||
825 | |||
759 | static void rt2x00lib_channel(struct ieee80211_channel *entry, | 826 | static void rt2x00lib_channel(struct ieee80211_channel *entry, |
760 | const int channel, const int tx_power, | 827 | const int channel, const int tx_power, |
761 | const int value) | 828 | const int value) |
@@ -770,18 +837,17 @@ static void rt2x00lib_channel(struct ieee80211_channel *entry, | |||
770 | } | 837 | } |
771 | 838 | ||
772 | static void rt2x00lib_rate(struct ieee80211_rate *entry, | 839 | static void rt2x00lib_rate(struct ieee80211_rate *entry, |
773 | const int rate, const int mask, | 840 | const u16 index, const struct rt2x00_rate *rate) |
774 | const int plcp, const int flags) | ||
775 | { | 841 | { |
776 | entry->bitrate = rate; | 842 | entry->flags = 0; |
777 | entry->hw_value = | 843 | entry->bitrate = rate->bitrate; |
778 | DEVICE_SET_RATE_FIELD(rate, RATE) | | 844 | entry->hw_value = rt2x00_create_rate_hw_value(index, 0); |
779 | DEVICE_SET_RATE_FIELD(mask, RATEMASK) | | ||
780 | DEVICE_SET_RATE_FIELD(plcp, PLCP); | ||
781 | entry->flags = flags; | ||
782 | entry->hw_value_short = entry->hw_value; | 845 | entry->hw_value_short = entry->hw_value; |
783 | if (entry->flags & IEEE80211_RATE_SHORT_PREAMBLE) | 846 | |
784 | entry->hw_value_short |= DEVICE_SET_RATE_FIELD(1, PREAMBLE); | 847 | if (rate->flags & DEV_RATE_SHORT_PREAMBLE) { |
848 | entry->flags |= IEEE80211_RATE_SHORT_PREAMBLE; | ||
849 | entry->hw_value_short |= rt2x00_create_rate_hw_value(index, 1); | ||
850 | } | ||
785 | } | 851 | } |
786 | 852 | ||
787 | static int rt2x00lib_probe_hw_modes(struct rt2x00_dev *rt2x00dev, | 853 | static int rt2x00lib_probe_hw_modes(struct rt2x00_dev *rt2x00dev, |
@@ -807,33 +873,8 @@ static int rt2x00lib_probe_hw_modes(struct rt2x00_dev *rt2x00dev, | |||
807 | /* | 873 | /* |
808 | * Initialize Rate list. | 874 | * Initialize Rate list. |
809 | */ | 875 | */ |
810 | rt2x00lib_rate(&rates[0], 10, DEV_RATEMASK_1MB, | 876 | for (i = 0; i < spec->num_rates; i++) |
811 | 0x00, 0); | 877 | rt2x00lib_rate(&rates[0], i, rt2x00_get_rate(i)); |
812 | rt2x00lib_rate(&rates[1], 20, DEV_RATEMASK_2MB, | ||
813 | 0x01, IEEE80211_RATE_SHORT_PREAMBLE); | ||
814 | rt2x00lib_rate(&rates[2], 55, DEV_RATEMASK_5_5MB, | ||
815 | 0x02, IEEE80211_RATE_SHORT_PREAMBLE); | ||
816 | rt2x00lib_rate(&rates[3], 110, DEV_RATEMASK_11MB, | ||
817 | 0x03, IEEE80211_RATE_SHORT_PREAMBLE); | ||
818 | |||
819 | if (spec->num_rates > 4) { | ||
820 | rt2x00lib_rate(&rates[4], 60, DEV_RATEMASK_6MB, | ||
821 | 0x0b, 0); | ||
822 | rt2x00lib_rate(&rates[5], 90, DEV_RATEMASK_9MB, | ||
823 | 0x0f, 0); | ||
824 | rt2x00lib_rate(&rates[6], 120, DEV_RATEMASK_12MB, | ||
825 | 0x0a, 0); | ||
826 | rt2x00lib_rate(&rates[7], 180, DEV_RATEMASK_18MB, | ||
827 | 0x0e, 0); | ||
828 | rt2x00lib_rate(&rates[8], 240, DEV_RATEMASK_24MB, | ||
829 | 0x09, 0); | ||
830 | rt2x00lib_rate(&rates[9], 360, DEV_RATEMASK_36MB, | ||
831 | 0x0d, 0); | ||
832 | rt2x00lib_rate(&rates[10], 480, DEV_RATEMASK_48MB, | ||
833 | 0x08, 0); | ||
834 | rt2x00lib_rate(&rates[11], 540, DEV_RATEMASK_54MB, | ||
835 | 0x0c, 0); | ||
836 | } | ||
837 | 878 | ||
838 | /* | 879 | /* |
839 | * Initialize Channel list. | 880 | * Initialize Channel list. |