Merge branch 'master' into net80211-update
[dragonfly.git] / sys / netproto / 802_11 / ieee80211_phy.h
1 /*-
2  * Copyright (c) 2007-2008 Sam Leffler, Errno Consulting
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
15  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
16  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
17  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
18  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
19  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
20  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
21  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
23  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24  *
25  * $FreeBSD: head/sys/net80211/ieee80211_phy.h 193072 2009-05-29 23:39:16Z sam $
26  * $DragonFly$
27  */
28
29 #ifndef _NET80211_IEEE80211_PHY_H_
30 #define _NET80211_IEEE80211_PHY_H_
31
32 #ifdef _KERNEL
33 /*
34  * IEEE 802.11 PHY-related definitions.
35  */
36
37 /*
38  * Contention window (slots).
39  */
40 #define IEEE80211_CW_MAX        1023    /* aCWmax */
41 #define IEEE80211_CW_MIN_0      31      /* DS/CCK aCWmin, ERP aCWmin(0) */
42 #define IEEE80211_CW_MIN_1      15      /* OFDM aCWmin, ERP aCWmin(1) */
43
44 /*
45  * SIFS (microseconds).
46  */
47 #define IEEE80211_DUR_SIFS      10      /* DS/CCK/ERP SIFS */
48 #define IEEE80211_DUR_OFDM_SIFS 16      /* OFDM SIFS */
49
50 /*
51  * Slot time (microseconds).
52  */
53 #define IEEE80211_DUR_SLOT      20      /* DS/CCK slottime, ERP long slottime */
54 #define IEEE80211_DUR_SHSLOT    9       /* ERP short slottime */
55 #define IEEE80211_DUR_OFDM_SLOT 9       /* OFDM slottime */
56
57 /*
58  * DIFS (microseconds).
59  */
60 #define IEEE80211_DUR_DIFS(sifs, slot)  ((sifs) + 2 * (slot))
61
62 struct ieee80211_channel;
63
64 struct ieee80211_rate_table {
65         int             rateCount;              /* NB: for proper padding */
66         uint8_t         rateCodeToIndex[256];   /* back mapping */
67         struct {
68                 uint8_t         phy;            /* CCK/OFDM/TURBO */
69                 uint32_t        rateKbps;       /* transfer rate in kbs */
70                 uint8_t         shortPreamble;  /* mask for enabling short
71                                                  * preamble in CCK rate code */
72                 uint8_t         dot11Rate;      /* value for supported rates
73                                                  * info element of MLME */
74                 uint8_t         ctlRateIndex;   /* index of next lower basic
75                                                  * rate; used for dur. calcs */
76                 uint16_t        lpAckDuration;  /* long preamble ACK dur. */
77                 uint16_t        spAckDuration;  /* short preamble ACK dur. */
78         } info[32];
79 };
80
81 const struct ieee80211_rate_table *ieee80211_get_ratetable(
82                         struct ieee80211_channel *);
83
84 static __inline__ uint8_t
85 ieee80211_ack_rate(const struct ieee80211_rate_table *rt, uint8_t rate)
86 {
87         uint8_t cix = rt->info[rt->rateCodeToIndex[rate]].ctlRateIndex;
88         KASSERT(cix != (uint8_t)-1, ("rate %d has no info", rate));
89         return rt->info[cix].dot11Rate;
90 }
91
92 static __inline__ uint8_t
93 ieee80211_ctl_rate(const struct ieee80211_rate_table *rt, uint8_t rate)
94 {
95         uint8_t cix = rt->info[rt->rateCodeToIndex[rate]].ctlRateIndex;
96         KASSERT(cix != (uint8_t)-1, ("rate %d has no info", rate));
97         return rt->info[cix].dot11Rate;
98 }
99
100 static __inline__ enum ieee80211_phytype
101 ieee80211_rate2phytype(const struct ieee80211_rate_table *rt, uint8_t rate)
102 {
103         uint8_t rix = rt->rateCodeToIndex[rate];
104         KASSERT(rix != (uint8_t)-1, ("rate %d has no info", rate));
105         return rt->info[rix].phy;
106 }
107
108 static __inline__ int
109 ieee80211_isratevalid(const struct ieee80211_rate_table *rt, uint8_t rate)
110 {
111         return rt->rateCodeToIndex[rate] != (uint8_t)-1;
112 }
113
114 /*
115  * Calculate ACK field for
116  * o  non-fragment data frames
117  * o  management frames
118  * sent using rate, phy and short preamble setting.
119  */
120 static __inline__ uint16_t
121 ieee80211_ack_duration(const struct ieee80211_rate_table *rt,
122     uint8_t rate, int isShortPreamble)
123 {
124         uint8_t rix = rt->rateCodeToIndex[rate];
125
126         KASSERT(rix != (uint8_t)-1, ("rate %d has no info", rate));
127         if (isShortPreamble) {
128                 KASSERT(rt->info[rix].spAckDuration != 0,
129                         ("shpreamble ack dur is not computed!\n"));
130                 return rt->info[rix].spAckDuration;
131         } else {
132                 KASSERT(rt->info[rix].lpAckDuration != 0,
133                         ("lgpreamble ack dur is not computed!\n"));
134                 return rt->info[rix].lpAckDuration;
135         }
136 }
137
138 /*
139  * Compute the time to transmit a frame of length frameLen bytes
140  * using the specified 802.11 rate code, phy, and short preamble
141  * setting.
142  *
143  * NB: SIFS is included.
144  */
145 uint16_t        ieee80211_compute_duration(const struct ieee80211_rate_table *,
146                         uint32_t frameLen, uint16_t rate, int isShortPreamble);
147 /*
148  * Convert PLCP signal/rate field to 802.11 rate code (.5Mbits/s)
149  */
150 uint8_t         ieee80211_plcp2rate(uint8_t, enum ieee80211_phytype);
151 /*
152  * Convert 802.11 rate code to PLCP signal.
153  */
154 uint8_t         ieee80211_rate2plcp(int, enum ieee80211_phytype);
155 #endif  /* _KERNEL */
156 #endif  /* !_NET80211_IEEE80211_PHY_H_ */