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
;
86 static void brcmu_d11ac_encchspec(struct brcmu_chan
*ch
)
88 if (ch
->bw
== BRCMU_CHAN_BW_20
|| ch
->sb
== BRCMU_CHAN_SB_NONE
)
89 ch
->sb
= BRCMU_CHAN_SB_L
;
91 brcmu_maskset16(&ch
->chspec
, BRCMU_CHSPEC_CH_MASK
,
92 BRCMU_CHSPEC_CH_SHIFT
, ch
->chnum
);
93 brcmu_maskset16(&ch
->chspec
, BRCMU_CHSPEC_D11AC_SB_MASK
,
94 BRCMU_CHSPEC_D11AC_SB_SHIFT
, ch
->sb
);
95 brcmu_maskset16(&ch
->chspec
, BRCMU_CHSPEC_D11AC_BW_MASK
,
98 ch
->chspec
&= ~BRCMU_CHSPEC_D11AC_BND_MASK
;
99 if (ch
->chnum
<= CH_MAX_2G_CHANNEL
)
100 ch
->chspec
|= BRCMU_CHSPEC_D11AC_BND_2G
;
102 ch
->chspec
|= BRCMU_CHSPEC_D11AC_BND_5G
;
105 static void brcmu_d11n_decchspec(struct brcmu_chan
*ch
)
109 ch
->chnum
= (u8
)(ch
->chspec
& BRCMU_CHSPEC_CH_MASK
);
110 ch
->control_ch_num
= ch
->chnum
;
112 switch (ch
->chspec
& BRCMU_CHSPEC_D11N_BW_MASK
) {
113 case BRCMU_CHSPEC_D11N_BW_20
:
114 ch
->bw
= BRCMU_CHAN_BW_20
;
115 ch
->sb
= BRCMU_CHAN_SB_NONE
;
117 case BRCMU_CHSPEC_D11N_BW_40
:
118 ch
->bw
= BRCMU_CHAN_BW_40
;
119 val
= ch
->chspec
& BRCMU_CHSPEC_D11N_SB_MASK
;
120 if (val
== BRCMU_CHSPEC_D11N_SB_L
) {
121 ch
->sb
= BRCMU_CHAN_SB_L
;
122 ch
->control_ch_num
-= CH_10MHZ_APART
;
124 ch
->sb
= BRCMU_CHAN_SB_U
;
125 ch
->control_ch_num
+= CH_10MHZ_APART
;
133 switch (ch
->chspec
& BRCMU_CHSPEC_D11N_BND_MASK
) {
134 case BRCMU_CHSPEC_D11N_BND_5G
:
135 ch
->band
= BRCMU_CHAN_BAND_5G
;
137 case BRCMU_CHSPEC_D11N_BND_2G
:
138 ch
->band
= BRCMU_CHAN_BAND_2G
;
146 static void brcmu_d11ac_decchspec(struct brcmu_chan
*ch
)
150 ch
->chnum
= (u8
)(ch
->chspec
& BRCMU_CHSPEC_CH_MASK
);
151 ch
->control_ch_num
= ch
->chnum
;
153 switch (ch
->chspec
& BRCMU_CHSPEC_D11AC_BW_MASK
) {
154 case BRCMU_CHSPEC_D11AC_BW_20
:
155 ch
->bw
= BRCMU_CHAN_BW_20
;
156 ch
->sb
= BRCMU_CHAN_SB_NONE
;
158 case BRCMU_CHSPEC_D11AC_BW_40
:
159 ch
->bw
= BRCMU_CHAN_BW_40
;
160 val
= ch
->chspec
& BRCMU_CHSPEC_D11AC_SB_MASK
;
161 if (val
== BRCMU_CHSPEC_D11AC_SB_L
) {
162 ch
->sb
= BRCMU_CHAN_SB_L
;
163 ch
->control_ch_num
-= CH_10MHZ_APART
;
164 } else if (val
== BRCMU_CHSPEC_D11AC_SB_U
) {
165 ch
->sb
= BRCMU_CHAN_SB_U
;
166 ch
->control_ch_num
+= CH_10MHZ_APART
;
171 case BRCMU_CHSPEC_D11AC_BW_80
:
172 ch
->bw
= BRCMU_CHAN_BW_80
;
173 ch
->sb
= brcmu_maskget16(ch
->chspec
, BRCMU_CHSPEC_D11AC_SB_MASK
,
174 BRCMU_CHSPEC_D11AC_SB_SHIFT
);
176 case BRCMU_CHAN_SB_LL
:
177 ch
->control_ch_num
-= CH_30MHZ_APART
;
179 case BRCMU_CHAN_SB_LU
:
180 ch
->control_ch_num
-= CH_10MHZ_APART
;
182 case BRCMU_CHAN_SB_UL
:
183 ch
->control_ch_num
+= CH_10MHZ_APART
;
185 case BRCMU_CHAN_SB_UU
:
186 ch
->control_ch_num
+= CH_30MHZ_APART
;
193 case BRCMU_CHSPEC_D11AC_BW_8080
:
194 case BRCMU_CHSPEC_D11AC_BW_160
:
200 switch (ch
->chspec
& BRCMU_CHSPEC_D11AC_BND_MASK
) {
201 case BRCMU_CHSPEC_D11AC_BND_5G
:
202 ch
->band
= BRCMU_CHAN_BAND_5G
;
204 case BRCMU_CHSPEC_D11AC_BND_2G
:
205 ch
->band
= BRCMU_CHAN_BAND_2G
;
213 void brcmu_d11_attach(struct brcmu_d11inf
*d11inf
)
215 if (d11inf
->io_type
== BRCMU_D11N_IOTYPE
) {
216 d11inf
->encchspec
= brcmu_d11n_encchspec
;
217 d11inf
->decchspec
= brcmu_d11n_decchspec
;
219 d11inf
->encchspec
= brcmu_d11ac_encchspec
;
220 d11inf
->decchspec
= brcmu_d11ac_decchspec
;
223 EXPORT_SYMBOL(brcmu_d11_attach
);