aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/zd1211rw/zd_mac.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/zd1211rw/zd_mac.c')
-rw-r--r--drivers/net/wireless/zd1211rw/zd_mac.c99
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 */
614static 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
635int zd_mac_set_mode(struct zd_mac *mac, u32 mode) 613int 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
740static int zd_calc_tx_length_us(u8 *service, u8 zd_rate, u16 tx_length) 718static 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
783enum {
784 R2M_SHORT_PREAMBLE = 0x01,
785 R2M_11A = 0x02,
786};
787
788static 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
809static void cs_set_modulation(struct zd_mac *mac, struct zd_ctrlset *cs, 766static 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
831static void cs_set_control(struct zd_mac *mac, struct zd_ctrlset *cs, 786static 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;