Linux Kernel
3.7.1
Main Page
Related Pages
Modules
Namespaces
Data Structures
Files
File List
Globals
All
Data Structures
Namespaces
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Macros
Groups
Pages
drivers
staging
rtl8192u
ieee80211
dot11d.c
Go to the documentation of this file.
1
//-----------------------------------------------------------------------------
2
// File:
3
// Dot11d.c
4
//
5
// Description:
6
// Implement 802.11d.
7
//
8
//-----------------------------------------------------------------------------
9
10
#include "
dot11d.h
"
11
12
void
13
Dot11d_Init
(
struct
ieee80211_device
*ieee)
14
{
15
PRT_DOT11D_INFO
pDot11dInfo =
GET_DOT11D_INFO
(ieee);
16
17
pDot11dInfo->
bEnabled
= 0;
18
19
pDot11dInfo->
State
=
DOT11D_STATE_NONE
;
20
pDot11dInfo->
CountryIeLen
= 0;
21
memset
(pDot11dInfo->
channel_map
, 0,
MAX_CHANNEL_NUMBER
+1);
22
memset
(pDot11dInfo->
MaxTxPwrDbmList
, 0xFF,
MAX_CHANNEL_NUMBER
+1);
23
RESET_CIE_WATCHDOG
(ieee);
24
25
printk
(
"Dot11d_Init()\n"
);
26
}
27
28
//
29
// Description:
30
// Reset to the state as we are just entering a regulatory domain.
31
//
32
void
33
Dot11d_Reset
(
struct
ieee80211_device
*ieee)
34
{
35
u32
i
;
36
PRT_DOT11D_INFO
pDot11dInfo =
GET_DOT11D_INFO
(ieee);
37
// Clear old channel map
38
memset
(pDot11dInfo->
channel_map
, 0,
MAX_CHANNEL_NUMBER
+1);
39
memset
(pDot11dInfo->
MaxTxPwrDbmList
, 0xFF,
MAX_CHANNEL_NUMBER
+1);
40
// Set new channel map
41
for
(i=1; i<=11; i++) {
42
(pDot11dInfo->
channel_map
)[i] = 1;
43
}
44
for
(i=12; i<=14; i++) {
45
(pDot11dInfo->
channel_map
)[i] = 2;
46
}
47
48
pDot11dInfo->
State
=
DOT11D_STATE_NONE
;
49
pDot11dInfo->
CountryIeLen
= 0;
50
RESET_CIE_WATCHDOG
(ieee);
51
52
//printk("Dot11d_Reset()\n");
53
}
54
55
//
56
// Description:
57
// Update country IE from Beacon or Probe Resopnse
58
// and configure PHY for operation in the regulatory domain.
59
//
60
// TODO:
61
// Configure Tx power.
62
//
63
// Assumption:
64
// 1. IS_DOT11D_ENABLE() is TRUE.
65
// 2. Input IE is an valid one.
66
//
67
void
68
Dot11d_UpdateCountryIe
(
69
struct
ieee80211_device
*
dev
,
70
u8
* pTaddr,
71
u16
CoutryIeLen,
72
u8
* pCoutryIe
73
)
74
{
75
PRT_DOT11D_INFO
pDot11dInfo =
GET_DOT11D_INFO
(dev);
76
u8
i
,
j
, NumTriples, MaxChnlNum;
77
PCHNL_TXPOWER_TRIPLE
pTriple;
78
79
memset
(pDot11dInfo->
channel_map
, 0,
MAX_CHANNEL_NUMBER
+1);
80
memset
(pDot11dInfo->
MaxTxPwrDbmList
, 0xFF,
MAX_CHANNEL_NUMBER
+1);
81
MaxChnlNum = 0;
82
NumTriples = (CoutryIeLen - 3) / 3;
// skip 3-byte country string.
83
pTriple = (
PCHNL_TXPOWER_TRIPLE
)(pCoutryIe + 3);
84
for
(i = 0; i < NumTriples; i++)
85
{
86
if
(MaxChnlNum >= pTriple->
FirstChnl
)
87
{
// It is not in a monotonically increasing order, so stop processing.
88
printk
(
"Dot11d_UpdateCountryIe(): Invalid country IE, skip it........1\n"
);
89
return
;
90
}
91
if
(
MAX_CHANNEL_NUMBER
< (pTriple->
FirstChnl
+ pTriple->
NumChnls
))
92
{
// It is not a valid set of channel id, so stop processing.
93
printk
(
"Dot11d_UpdateCountryIe(): Invalid country IE, skip it........2\n"
);
94
return
;
95
}
96
97
for
(j = 0 ; j < pTriple->
NumChnls
; j++)
98
{
99
pDot11dInfo->
channel_map
[pTriple->
FirstChnl
+
j
] = 1;
100
pDot11dInfo->
MaxTxPwrDbmList
[pTriple->
FirstChnl
+
j
] = pTriple->
MaxTxPowerInDbm
;
101
MaxChnlNum = pTriple->
FirstChnl
+
j
;
102
}
103
104
pTriple = (
PCHNL_TXPOWER_TRIPLE
)((
u8
*)pTriple + 3);
105
}
106
//printk("Dot11d_UpdateCountryIe(): Channel List:\n");
107
printk
(
"Channel List:"
);
108
for
(i=1; i<=
MAX_CHANNEL_NUMBER
; i++)
109
if
(pDot11dInfo->
channel_map
[i] > 0)
110
printk
(
" %d"
, i);
111
printk
(
"\n"
);
112
113
UPDATE_CIE_SRC
(dev, pTaddr);
114
115
pDot11dInfo->
CountryIeLen
= CoutryIeLen;
116
memcpy
(pDot11dInfo->
CountryIeBuf
, pCoutryIe,CoutryIeLen);
117
pDot11dInfo->
State
=
DOT11D_STATE_LEARNED
;
118
}
119
120
121
u8
122
DOT11D_GetMaxTxPwrInDbm
(
123
struct
ieee80211_device
*
dev
,
124
u8
Channel
125
)
126
{
127
PRT_DOT11D_INFO
pDot11dInfo =
GET_DOT11D_INFO
(dev);
128
u8
MaxTxPwrInDbm = 255;
129
130
if
(
MAX_CHANNEL_NUMBER
< Channel)
131
{
132
printk
(
"DOT11D_GetMaxTxPwrInDbm(): Invalid Channel\n"
);
133
return
MaxTxPwrInDbm;
134
}
135
if
(pDot11dInfo->
channel_map
[Channel])
136
{
137
MaxTxPwrInDbm = pDot11dInfo->
MaxTxPwrDbmList
[
Channel
];
138
}
139
140
return
MaxTxPwrInDbm;
141
}
142
143
144
void
145
DOT11D_ScanComplete
(
146
struct
ieee80211_device
*
dev
147
)
148
{
149
PRT_DOT11D_INFO
pDot11dInfo =
GET_DOT11D_INFO
(dev);
150
151
switch
(pDot11dInfo->
State
)
152
{
153
case
DOT11D_STATE_LEARNED
:
154
pDot11dInfo->
State
=
DOT11D_STATE_DONE
;
155
break
;
156
157
case
DOT11D_STATE_DONE
:
158
if
(
GET_CIE_WATCHDOG
(dev) == 0 )
159
{
// Reset country IE if previous one is gone.
160
Dot11d_Reset
(dev);
161
}
162
break
;
163
case
DOT11D_STATE_NONE
:
164
break
;
165
}
166
}
167
168
int
IsLegalChannel
(
169
struct
ieee80211_device
*
dev
,
170
u8
channel
171
)
172
{
173
PRT_DOT11D_INFO
pDot11dInfo =
GET_DOT11D_INFO
(dev);
174
175
if
(
MAX_CHANNEL_NUMBER
< channel)
176
{
177
printk
(
"IsLegalChannel(): Invalid Channel\n"
);
178
return
0;
179
}
180
if
(pDot11dInfo->
channel_map
[channel] > 0)
181
return
1;
182
return
0;
183
}
184
185
int
ToLegalChannel
(
186
struct
ieee80211_device
*
dev
,
187
u8
channel
188
)
189
{
190
PRT_DOT11D_INFO
pDot11dInfo =
GET_DOT11D_INFO
(dev);
191
u8
default_chn = 0;
192
u32
i
= 0;
193
194
for
(i=1; i<=
MAX_CHANNEL_NUMBER
; i++)
195
{
196
if
(pDot11dInfo->
channel_map
[i] > 0)
197
{
198
default_chn =
i
;
199
break
;
200
}
201
}
202
203
if
(
MAX_CHANNEL_NUMBER
< channel)
204
{
205
printk
(
"IsLegalChannel(): Invalid Channel\n"
);
206
return
default_chn;
207
}
208
209
if
(pDot11dInfo->
channel_map
[channel] > 0)
210
return
channel
;
211
212
return
default_chn;
213
}
214
EXPORT_SYMBOL
(
Dot11d_Init
);
215
EXPORT_SYMBOL
(
Dot11d_Reset
);
216
EXPORT_SYMBOL
(
Dot11d_UpdateCountryIe
);
217
EXPORT_SYMBOL
(
DOT11D_GetMaxTxPwrInDbm
);
218
EXPORT_SYMBOL
(
DOT11D_ScanComplete
);
219
EXPORT_SYMBOL
(
IsLegalChannel
);
220
EXPORT_SYMBOL
(
ToLegalChannel
);
221
Generated on Thu Jan 10 2013 14:30:19 for Linux Kernel by
1.8.2