2 * Copyright (c) 2013 Broadcom Corporation
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16 /*********************channel spec common functions*********************/
18 #include <linux/module.h>
20 #include <brcmu_utils.h>
21 #include <brcmu_wifi.h>
22 #include <brcmu_d11.h>
24 static u16
d11n_sb(enum brcmu_chan_sb sb
)
27 case BRCMU_CHAN_SB_NONE
:
28 return BRCMU_CHSPEC_D11N_SB_N
;
30 return BRCMU_CHSPEC_D11N_SB_L
;
32 return BRCMU_CHSPEC_D11N_SB_U
;
39 static u16
d11n_bw(enum brcmu_chan_bw bw
)
42 case BRCMU_CHAN_BW_20
:
43 return BRCMU_CHSPEC_D11N_BW_20
;
44 case BRCMU_CHAN_BW_40
:
45 return BRCMU_CHSPEC_D11N_BW_40
;
52 static void brcmu_d11n_encchspec(struct brcmu_chan
*ch
)
54 if (ch
->bw
== BRCMU_CHAN_BW_20
)
55 ch
->sb
= BRCMU_CHAN_SB_NONE
;
58 brcmu_maskset16(&ch
->chspec
, BRCMU_CHSPEC_CH_MASK
,
59 BRCMU_CHSPEC_CH_SHIFT
, ch
->chnum
);
60 brcmu_maskset16(&ch
->chspec
, BRCMU_CHSPEC_D11N_SB_MASK
,
62 brcmu_maskset16(&ch
->chspec
, BRCMU_CHSPEC_D11N_BW_MASK
,
65 if (ch
->chnum
<= CH_MAX_2G_CHANNEL
)
66 ch
->chspec
|= BRCMU_CHSPEC_D11N_BND_2G
;
68 ch
->chspec
|= BRCMU_CHSPEC_D11N_BND_5G
;
71 static u16
d11ac_bw(enum brcmu_chan_bw bw
)
74 case BRCMU_CHAN_BW_20
:
75 return BRCMU_CHSPEC_D11AC_BW_20
;
76 case BRCMU_CHAN_BW_40
:
77 return BRCMU_CHSPEC_D11AC_BW_40
;
78 case BRCMU_CHAN_BW_80
:
79 return BRCMU_CHSPEC_D11AC_BW_80
;
80 case BRCMU_CHAN_BW_160
:
81 return BRCMU_CHSPEC_D11AC_BW_160
;
88 static void brcmu_d11ac_encchspec(struct brcmu_chan
*ch
)
90 if (ch
->bw
== BRCMU_CHAN_BW_20
|| ch
->sb
== BRCMU_CHAN_SB_NONE
)
91 ch
->sb
= BRCMU_CHAN_SB_L
;
93 brcmu_maskset16(&ch
->chspec
, BRCMU_CHSPEC_CH_MASK
,
94 BRCMU_CHSPEC_CH_SHIFT
, ch
->chnum
);
95 brcmu_maskset16(&ch
->chspec
, BRCMU_CHSPEC_D11AC_SB_MASK
,
96 BRCMU_CHSPEC_D11AC_SB_SHIFT
, ch
->sb
);
97 brcmu_maskset16(&ch
->chspec
, BRCMU_CHSPEC_D11AC_BW_MASK
,
100 ch
->chspec
&= ~BRCMU_CHSPEC_D11AC_BND_MASK
;
101 if (ch
->chnum
<= CH_MAX_2G_CHANNEL
)
102 ch
->chspec
|= BRCMU_CHSPEC_D11AC_BND_2G
;
104 ch
->chspec
|= BRCMU_CHSPEC_D11AC_BND_5G
;
107 static void brcmu_d11n_decchspec(struct brcmu_chan
*ch
)
111 ch
->chnum
= (u8
)(ch
->chspec
& BRCMU_CHSPEC_CH_MASK
);
112 ch
->control_ch_num
= ch
->chnum
;
114 switch (ch
->chspec
& BRCMU_CHSPEC_D11N_BW_MASK
) {
115 case BRCMU_CHSPEC_D11N_BW_20
:
116 ch
->bw
= BRCMU_CHAN_BW_20
;
117 ch
->sb
= BRCMU_CHAN_SB_NONE
;
119 case BRCMU_CHSPEC_D11N_BW_40
:
120 ch
->bw
= BRCMU_CHAN_BW_40
;
121 val
= ch
->chspec
& BRCMU_CHSPEC_D11N_SB_MASK
;
122 if (val
== BRCMU_CHSPEC_D11N_SB_L
) {
123 ch
->sb
= BRCMU_CHAN_SB_L
;
124 ch
->control_ch_num
-= CH_10MHZ_APART
;
126 ch
->sb
= BRCMU_CHAN_SB_U
;
127 ch
->control_ch_num
+= CH_10MHZ_APART
;
135 switch (ch
->chspec
& BRCMU_CHSPEC_D11N_BND_MASK
) {
136 case BRCMU_CHSPEC_D11N_BND_5G
:
137 ch
->band
= BRCMU_CHAN_BAND_5G
;
139 case BRCMU_CHSPEC_D11N_BND_2G
:
140 ch
->band
= BRCMU_CHAN_BAND_2G
;
148 static void brcmu_d11ac_decchspec(struct brcmu_chan
*ch
)
152 ch
->chnum
= (u8
)(ch
->chspec
& BRCMU_CHSPEC_CH_MASK
);
153 ch
->control_ch_num
= ch
->chnum
;
155 switch (ch
->chspec
& BRCMU_CHSPEC_D11AC_BW_MASK
) {
156 case BRCMU_CHSPEC_D11AC_BW_20
:
157 ch
->bw
= BRCMU_CHAN_BW_20
;
158 ch
->sb
= BRCMU_CHAN_SB_NONE
;
160 case BRCMU_CHSPEC_D11AC_BW_40
:
161 ch
->bw
= BRCMU_CHAN_BW_40
;
162 val
= ch
->chspec
& BRCMU_CHSPEC_D11AC_SB_MASK
;
163 if (val
== BRCMU_CHSPEC_D11AC_SB_L
) {
164 ch
->sb
= BRCMU_CHAN_SB_L
;
165 ch
->control_ch_num
-= CH_10MHZ_APART
;
166 } else if (val
== BRCMU_CHSPEC_D11AC_SB_U
) {
167 ch
->sb
= BRCMU_CHAN_SB_U
;
168 ch
->control_ch_num
+= CH_10MHZ_APART
;
173 case BRCMU_CHSPEC_D11AC_BW_80
:
174 ch
->bw
= BRCMU_CHAN_BW_80
;
175 ch
->sb
= brcmu_maskget16(ch
->chspec
, BRCMU_CHSPEC_D11AC_SB_MASK
,
176 BRCMU_CHSPEC_D11AC_SB_SHIFT
);
178 case BRCMU_CHAN_SB_LL
:
179 ch
->control_ch_num
-= CH_30MHZ_APART
;
181 case BRCMU_CHAN_SB_LU
:
182 ch
->control_ch_num
-= CH_10MHZ_APART
;
184 case BRCMU_CHAN_SB_UL
:
185 ch
->control_ch_num
+= CH_10MHZ_APART
;
187 case BRCMU_CHAN_SB_UU
:
188 ch
->control_ch_num
+= CH_30MHZ_APART
;
195 case BRCMU_CHSPEC_D11AC_BW_160
:
196 ch
->bw
= BRCMU_CHAN_BW_160
;
197 ch
->sb
= brcmu_maskget16(ch
->chspec
, BRCMU_CHSPEC_D11AC_SB_MASK
,
198 BRCMU_CHSPEC_D11AC_SB_SHIFT
);
200 case BRCMU_CHAN_SB_LLL
:
201 ch
->control_ch_num
-= CH_70MHZ_APART
;
203 case BRCMU_CHAN_SB_LLU
:
204 ch
->control_ch_num
-= CH_50MHZ_APART
;
206 case BRCMU_CHAN_SB_LUL
:
207 ch
->control_ch_num
-= CH_30MHZ_APART
;
209 case BRCMU_CHAN_SB_LUU
:
210 ch
->control_ch_num
-= CH_10MHZ_APART
;
212 case BRCMU_CHAN_SB_ULL
:
213 ch
->control_ch_num
+= CH_10MHZ_APART
;
215 case BRCMU_CHAN_SB_ULU
:
216 ch
->control_ch_num
+= CH_30MHZ_APART
;
218 case BRCMU_CHAN_SB_UUL
:
219 ch
->control_ch_num
+= CH_50MHZ_APART
;
221 case BRCMU_CHAN_SB_UUU
:
222 ch
->control_ch_num
+= CH_70MHZ_APART
;
229 case BRCMU_CHSPEC_D11AC_BW_8080
:
235 switch (ch
->chspec
& BRCMU_CHSPEC_D11AC_BND_MASK
) {
236 case BRCMU_CHSPEC_D11AC_BND_5G
:
237 ch
->band
= BRCMU_CHAN_BAND_5G
;
239 case BRCMU_CHSPEC_D11AC_BND_2G
:
240 ch
->band
= BRCMU_CHAN_BAND_2G
;
248 void brcmu_d11_attach(struct brcmu_d11inf
*d11inf
)
250 if (d11inf
->io_type
== BRCMU_D11N_IOTYPE
) {
251 d11inf
->encchspec
= brcmu_d11n_encchspec
;
252 d11inf
->decchspec
= brcmu_d11n_decchspec
;
254 d11inf
->encchspec
= brcmu_d11ac_encchspec
;
255 d11inf
->decchspec
= brcmu_d11ac_decchspec
;
258 EXPORT_SYMBOL(brcmu_d11_attach
);