Go to the documentation of this file.00001 #include <linux/types.h>
00002
00003 #include "ath5k.h"
00004 #include "mac80211.h"
00005
00013 static inline int ath5k_is_erp_rate(unsigned int mode, int rate)
00014 {
00015 if (mode == AR5K_MODE_11G) {
00016 if (rate != 10 && rate != 20 &&
00017 rate != 55 && rate != 110)
00018 return 1;
00019 }
00020 return 0;
00021 }
00022
00023 int ath5k_get_hdrlen(u16 fc)
00024 {
00025 int hdrlen = 24;
00026
00027 switch (fc & IEEE80211_FCTL_FTYPE) {
00028 case IEEE80211_FTYPE_DATA:
00029 if ((fc & IEEE80211_FCTL_FROMDS) && (fc & IEEE80211_FCTL_TODS))
00030 hdrlen = 30;
00031
00032
00033
00034
00035
00036
00037
00038 hdrlen += (fc & IEEE80211_STYPE_QOS_DATA) >> 6;
00039 break;
00040 case IEEE80211_FTYPE_CTL:
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050 if ((fc & 0xE0) == 0xC0)
00051 hdrlen = 10;
00052 else
00053 hdrlen = 16;
00054 break;
00055 }
00056
00057 return hdrlen;
00058 }
00059
00060 int ath5k_get_hdrlen_from_skb(const struct sk_buff *skb)
00061 {
00062 const struct ieee80211_hdr *hdr = (const struct ieee80211_hdr *) skb->data;
00063 int hdrlen;
00064
00065 if (unlikely(skb->len < 10))
00066 return 0;
00067 hdrlen = ath5k_get_hdrlen(le16_to_cpu(hdr->frame_control));
00068 if (unlikely(hdrlen > skb->len))
00069 return 0;
00070 return hdrlen;
00071 }
00072
00073 int ath5k_frame_duration(unsigned int mode, size_t len,
00074 int rate, int erp, int short_preamble)
00075 {
00076 int dur;
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087 if (mode == AR5K_MODE_11A || erp) {
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101 dur = 16;
00102 dur += 16;
00103 dur += 4;
00104 dur += 4 * DIV_ROUND_UP((16 + 8 * (len + 4) + 6) * 10,
00105 4 * rate);
00106 } else {
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117 dur = 10;
00118 dur += short_preamble ? (72 + 24) : (144 + 48);
00119
00120 dur += DIV_ROUND_UP(8 * (len + 4) * 10, rate);
00121 }
00122
00123 return dur;
00124 }
00125
00126
00127 __le16 ath5k_generic_frame_duration(unsigned int mode,
00128 bool short_preamble,
00129 size_t frame_len, int rate)
00130 {
00131 u16 dur;
00132 int erp;
00133
00134 erp = ath5k_is_erp_rate(mode, rate);
00135 dur = ath5k_frame_duration(mode, frame_len, rate, erp, short_preamble);
00136
00137 return cpu_to_le16(dur);
00138 }
00139
00140 int ath5k_frequency_to_channel(int freq)
00141 {
00142 if (freq == 2484)
00143 return 14;
00144
00145 if (freq < 2484)
00146 return (freq - 2407) / 5;
00147
00148
00149 return freq/5 - 1000;
00150 }
00151