diff options
Diffstat (limited to 'drivers/net/wireless/zd1211rw/zd_mac.c')
-rw-r--r-- | drivers/net/wireless/zd1211rw/zd_mac.c | 99 |
1 files changed, 27 insertions, 72 deletions
diff --git a/drivers/net/wireless/zd1211rw/zd_mac.c b/drivers/net/wireless/zd1211rw/zd_mac.c index 7ec1fcf37fc3..451308d7095d 100644 --- a/drivers/net/wireless/zd1211rw/zd_mac.c +++ b/drivers/net/wireless/zd1211rw/zd_mac.c | |||
@@ -610,28 +610,6 @@ u8 zd_mac_get_channel(struct zd_mac *mac) | |||
610 | return channel; | 610 | return channel; |
611 | } | 611 | } |
612 | 612 | ||
613 | /* If wrong rate is given, we are falling back to the slowest rate: 1MBit/s */ | ||
614 | static u8 zd_rate_typed(u8 zd_rate) | ||
615 | { | ||
616 | static const u8 typed_rates[16] = { | ||
617 | [ZD_CCK_RATE_1M] = ZD_CS_CCK|ZD_CCK_RATE_1M, | ||
618 | [ZD_CCK_RATE_2M] = ZD_CS_CCK|ZD_CCK_RATE_2M, | ||
619 | [ZD_CCK_RATE_5_5M] = ZD_CS_CCK|ZD_CCK_RATE_5_5M, | ||
620 | [ZD_CCK_RATE_11M] = ZD_CS_CCK|ZD_CCK_RATE_11M, | ||
621 | [ZD_OFDM_RATE_6M] = ZD_CS_OFDM|ZD_OFDM_RATE_6M, | ||
622 | [ZD_OFDM_RATE_9M] = ZD_CS_OFDM|ZD_OFDM_RATE_9M, | ||
623 | [ZD_OFDM_RATE_12M] = ZD_CS_OFDM|ZD_OFDM_RATE_12M, | ||
624 | [ZD_OFDM_RATE_18M] = ZD_CS_OFDM|ZD_OFDM_RATE_18M, | ||
625 | [ZD_OFDM_RATE_24M] = ZD_CS_OFDM|ZD_OFDM_RATE_24M, | ||
626 | [ZD_OFDM_RATE_36M] = ZD_CS_OFDM|ZD_OFDM_RATE_36M, | ||
627 | [ZD_OFDM_RATE_48M] = ZD_CS_OFDM|ZD_OFDM_RATE_48M, | ||
628 | [ZD_OFDM_RATE_54M] = ZD_CS_OFDM|ZD_OFDM_RATE_54M, | ||
629 | }; | ||
630 | |||
631 | ZD_ASSERT(ZD_CS_RATE_MASK == 0x0f); | ||
632 | return typed_rates[zd_rate & ZD_CS_RATE_MASK]; | ||
633 | } | ||
634 | |||
635 | int zd_mac_set_mode(struct zd_mac *mac, u32 mode) | 613 | int zd_mac_set_mode(struct zd_mac *mac, u32 mode) |
636 | { | 614 | { |
637 | struct ieee80211_device *ieee; | 615 | struct ieee80211_device *ieee; |
@@ -739,25 +717,30 @@ int zd_mac_get_range(struct zd_mac *mac, struct iw_range *range) | |||
739 | 717 | ||
740 | static int zd_calc_tx_length_us(u8 *service, u8 zd_rate, u16 tx_length) | 718 | static int zd_calc_tx_length_us(u8 *service, u8 zd_rate, u16 tx_length) |
741 | { | 719 | { |
720 | /* ZD_PURE_RATE() must be used to remove the modulation type flag of | ||
721 | * the zd-rate values. */ | ||
742 | static const u8 rate_divisor[] = { | 722 | static const u8 rate_divisor[] = { |
743 | [ZD_CCK_RATE_1M] = 1, | 723 | [ZD_PURE_RATE(ZD_CCK_RATE_1M)] = 1, |
744 | [ZD_CCK_RATE_2M] = 2, | 724 | [ZD_PURE_RATE(ZD_CCK_RATE_2M)] = 2, |
745 | [ZD_CCK_RATE_5_5M] = 11, /* bits must be doubled */ | 725 | |
746 | [ZD_CCK_RATE_11M] = 11, | 726 | /* bits must be doubled */ |
747 | [ZD_OFDM_RATE_6M] = 6, | 727 | [ZD_PURE_RATE(ZD_CCK_RATE_5_5M)] = 11, |
748 | [ZD_OFDM_RATE_9M] = 9, | 728 | |
749 | [ZD_OFDM_RATE_12M] = 12, | 729 | [ZD_PURE_RATE(ZD_CCK_RATE_11M)] = 11, |
750 | [ZD_OFDM_RATE_18M] = 18, | 730 | [ZD_PURE_RATE(ZD_OFDM_RATE_6M)] = 6, |
751 | [ZD_OFDM_RATE_24M] = 24, | 731 | [ZD_PURE_RATE(ZD_OFDM_RATE_9M)] = 9, |
752 | [ZD_OFDM_RATE_36M] = 36, | 732 | [ZD_PURE_RATE(ZD_OFDM_RATE_12M)] = 12, |
753 | [ZD_OFDM_RATE_48M] = 48, | 733 | [ZD_PURE_RATE(ZD_OFDM_RATE_18M)] = 18, |
754 | [ZD_OFDM_RATE_54M] = 54, | 734 | [ZD_PURE_RATE(ZD_OFDM_RATE_24M)] = 24, |
735 | [ZD_PURE_RATE(ZD_OFDM_RATE_36M)] = 36, | ||
736 | [ZD_PURE_RATE(ZD_OFDM_RATE_48M)] = 48, | ||
737 | [ZD_PURE_RATE(ZD_OFDM_RATE_54M)] = 54, | ||
755 | }; | 738 | }; |
756 | 739 | ||
757 | u32 bits = (u32)tx_length * 8; | 740 | u32 bits = (u32)tx_length * 8; |
758 | u32 divisor; | 741 | u32 divisor; |
759 | 742 | ||
760 | divisor = rate_divisor[zd_rate]; | 743 | divisor = rate_divisor[ZD_PURE_RATE(zd_rate)]; |
761 | if (divisor == 0) | 744 | if (divisor == 0) |
762 | return -EINVAL; | 745 | return -EINVAL; |
763 | 746 | ||
@@ -780,52 +763,24 @@ static int zd_calc_tx_length_us(u8 *service, u8 zd_rate, u16 tx_length) | |||
780 | return bits/divisor; | 763 | return bits/divisor; |
781 | } | 764 | } |
782 | 765 | ||
783 | enum { | ||
784 | R2M_SHORT_PREAMBLE = 0x01, | ||
785 | R2M_11A = 0x02, | ||
786 | }; | ||
787 | |||
788 | static u8 zd_rate_to_modulation(u8 zd_rate, int flags) | ||
789 | { | ||
790 | u8 modulation; | ||
791 | |||
792 | modulation = zd_rate_typed(zd_rate); | ||
793 | if (flags & R2M_SHORT_PREAMBLE) { | ||
794 | switch (ZD_CS_RATE(modulation)) { | ||
795 | case ZD_CCK_RATE_2M: | ||
796 | case ZD_CCK_RATE_5_5M: | ||
797 | case ZD_CCK_RATE_11M: | ||
798 | modulation |= ZD_CS_CCK_PREA_SHORT; | ||
799 | return modulation; | ||
800 | } | ||
801 | } | ||
802 | if (flags & R2M_11A) { | ||
803 | if (ZD_CS_TYPE(modulation) == ZD_CS_OFDM) | ||
804 | modulation |= ZD_CS_OFDM_MODE_11A; | ||
805 | } | ||
806 | return modulation; | ||
807 | } | ||
808 | |||
809 | static void cs_set_modulation(struct zd_mac *mac, struct zd_ctrlset *cs, | 766 | static void cs_set_modulation(struct zd_mac *mac, struct zd_ctrlset *cs, |
810 | struct ieee80211_hdr_4addr *hdr) | 767 | struct ieee80211_hdr_4addr *hdr) |
811 | { | 768 | { |
812 | struct ieee80211softmac_device *softmac = ieee80211_priv(mac->netdev); | 769 | struct ieee80211softmac_device *softmac = ieee80211_priv(mac->netdev); |
813 | u16 ftype = WLAN_FC_GET_TYPE(le16_to_cpu(hdr->frame_ctl)); | 770 | u16 ftype = WLAN_FC_GET_TYPE(le16_to_cpu(hdr->frame_ctl)); |
814 | u8 rate, zd_rate; | 771 | u8 rate; |
815 | int is_mgt = (ftype == IEEE80211_FTYPE_MGMT) != 0; | 772 | int is_mgt = (ftype == IEEE80211_FTYPE_MGMT) != 0; |
816 | int is_multicast = is_multicast_ether_addr(hdr->addr1); | 773 | int is_multicast = is_multicast_ether_addr(hdr->addr1); |
817 | int short_preamble = ieee80211softmac_short_preamble_ok(softmac, | 774 | int short_preamble = ieee80211softmac_short_preamble_ok(softmac, |
818 | is_multicast, is_mgt); | 775 | is_multicast, is_mgt); |
819 | int flags = 0; | ||
820 | 776 | ||
821 | /* FIXME: 802.11a? */ | ||
822 | rate = ieee80211softmac_suggest_txrate(softmac, is_multicast, is_mgt); | 777 | rate = ieee80211softmac_suggest_txrate(softmac, is_multicast, is_mgt); |
778 | cs->modulation = rate_to_zd_rate(rate); | ||
823 | 779 | ||
824 | if (short_preamble) | 780 | /* Set short preamble bit when appropriate */ |
825 | flags |= R2M_SHORT_PREAMBLE; | 781 | if (short_preamble && ZD_MODULATION_TYPE(cs->modulation) == ZD_CCK |
826 | 782 | && cs->modulation != ZD_CCK_RATE_1M) | |
827 | zd_rate = rate_to_zd_rate(rate); | 783 | cs->modulation |= ZD_CCK_PREA_SHORT; |
828 | cs->modulation = zd_rate_to_modulation(zd_rate, flags); | ||
829 | } | 784 | } |
830 | 785 | ||
831 | static void cs_set_control(struct zd_mac *mac, struct zd_ctrlset *cs, | 786 | static void cs_set_control(struct zd_mac *mac, struct zd_ctrlset *cs, |
@@ -864,7 +819,7 @@ static void cs_set_control(struct zd_mac *mac, struct zd_ctrlset *cs, | |||
864 | cs->control |= ZD_CS_RTS; | 819 | cs->control |= ZD_CS_RTS; |
865 | 820 | ||
866 | /* Use CTS-to-self protection if required */ | 821 | /* Use CTS-to-self protection if required */ |
867 | if (ZD_CS_TYPE(cs->modulation) == ZD_CS_OFDM && | 822 | if (ZD_MODULATION_TYPE(cs->modulation) == ZD_OFDM && |
868 | ieee80211softmac_protection_needed(softmac)) { | 823 | ieee80211softmac_protection_needed(softmac)) { |
869 | /* FIXME: avoid sending RTS *and* self-CTS, is that correct? */ | 824 | /* FIXME: avoid sending RTS *and* self-CTS, is that correct? */ |
870 | cs->control &= ~ZD_CS_RTS; | 825 | cs->control &= ~ZD_CS_RTS; |
@@ -925,7 +880,7 @@ static int fill_ctrlset(struct zd_mac *mac, | |||
925 | * - see line 53 of zdinlinef.h | 880 | * - see line 53 of zdinlinef.h |
926 | */ | 881 | */ |
927 | cs->service = 0; | 882 | cs->service = 0; |
928 | r = zd_calc_tx_length_us(&cs->service, ZD_CS_RATE(cs->modulation), | 883 | r = zd_calc_tx_length_us(&cs->service, ZD_RATE(cs->modulation), |
929 | le16_to_cpu(cs->tx_length)); | 884 | le16_to_cpu(cs->tx_length)); |
930 | if (r < 0) | 885 | if (r < 0) |
931 | return r; | 886 | return r; |
@@ -934,7 +889,7 @@ static int fill_ctrlset(struct zd_mac *mac, | |||
934 | if (next_frag_len == 0) { | 889 | if (next_frag_len == 0) { |
935 | cs->next_frame_length = 0; | 890 | cs->next_frame_length = 0; |
936 | } else { | 891 | } else { |
937 | r = zd_calc_tx_length_us(NULL, ZD_CS_RATE(cs->modulation), | 892 | r = zd_calc_tx_length_us(NULL, ZD_RATE(cs->modulation), |
938 | next_frag_len); | 893 | next_frag_len); |
939 | if (r < 0) | 894 | if (r < 0) |
940 | return r; | 895 | return r; |