aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/rt2x00/rt2x00dev.c
diff options
context:
space:
mode:
authorIvo van Doorn <ivdoorn@gmail.com>2008-02-03 09:50:40 -0500
committerJohn W. Linville <linville@tuxdriver.com>2008-02-29 15:19:38 -0500
commit70e2fed4ec14df84ed72554d573794714b15a078 (patch)
tree6e8d63a357fb1c45d950f292bf330e8af718b85a /drivers/net/wireless/rt2x00/rt2x00dev.c
parente71c9fac316221a4594f3bd58c2d30ada0cabaf6 (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.c173
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 */
751const 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
759static void rt2x00lib_channel(struct ieee80211_channel *entry, 826static 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
772static void rt2x00lib_rate(struct ieee80211_rate *entry, 839static 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
787static int rt2x00lib_probe_hw_modes(struct rt2x00_dev *rt2x00dev, 853static 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.