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
);
111 switch (ch
->chspec
& BRCMU_CHSPEC_D11N_BW_MASK
) {
112 case BRCMU_CHSPEC_D11N_BW_20
:
113 ch
->bw
= BRCMU_CHAN_BW_20
;
114 ch
->sb
= BRCMU_CHAN_SB_NONE
;
116 case BRCMU_CHSPEC_D11N_BW_40
:
117 ch
->bw
= BRCMU_CHAN_BW_40
;
118 val
= ch
->chspec
& BRCMU_CHSPEC_D11N_SB_MASK
;
119 if (val
== BRCMU_CHSPEC_D11N_SB_L
) {
120 ch
->sb
= BRCMU_CHAN_SB_L
;
121 ch
->chnum
-= CH_10MHZ_APART
;
123 ch
->sb
= BRCMU_CHAN_SB_U
;
124 ch
->chnum
+= CH_10MHZ_APART
;
132 switch (ch
->chspec
& BRCMU_CHSPEC_D11N_BND_MASK
) {
133 case BRCMU_CHSPEC_D11N_BND_5G
:
134 ch
->band
= BRCMU_CHAN_BAND_5G
;
136 case BRCMU_CHSPEC_D11N_BND_2G
:
137 ch
->band
= BRCMU_CHAN_BAND_2G
;
145 static void brcmu_d11ac_decchspec(struct brcmu_chan
*ch
)
149 ch
->chnum
= (u8
)(ch
->chspec
& BRCMU_CHSPEC_CH_MASK
);
151 switch (ch
->chspec
& BRCMU_CHSPEC_D11AC_BW_MASK
) {
152 case BRCMU_CHSPEC_D11AC_BW_20
:
153 ch
->bw
= BRCMU_CHAN_BW_20
;
154 ch
->sb
= BRCMU_CHAN_SB_NONE
;
156 case BRCMU_CHSPEC_D11AC_BW_40
:
157 ch
->bw
= BRCMU_CHAN_BW_40
;
158 val
= ch
->chspec
& BRCMU_CHSPEC_D11AC_SB_MASK
;
159 if (val
== BRCMU_CHSPEC_D11AC_SB_L
) {
160 ch
->sb
= BRCMU_CHAN_SB_L
;
161 ch
->chnum
-= CH_10MHZ_APART
;
162 } else if (val
== BRCMU_CHSPEC_D11AC_SB_U
) {
163 ch
->sb
= BRCMU_CHAN_SB_U
;
164 ch
->chnum
+= CH_10MHZ_APART
;
169 case BRCMU_CHSPEC_D11AC_BW_80
:
170 ch
->bw
= BRCMU_CHAN_BW_80
;
171 ch
->sb
= brcmu_maskget16(ch
->chspec
, BRCMU_CHSPEC_D11AC_SB_MASK
,
172 BRCMU_CHSPEC_D11AC_SB_SHIFT
);
174 case BRCMU_CHAN_SB_LL
:
175 ch
->chnum
-= CH_30MHZ_APART
;
177 case BRCMU_CHAN_SB_LU
:
178 ch
->chnum
-= CH_10MHZ_APART
;
180 case BRCMU_CHAN_SB_UL
:
181 ch
->chnum
+= CH_10MHZ_APART
;
183 case BRCMU_CHAN_SB_UU
:
184 ch
->chnum
+= CH_30MHZ_APART
;
191 case BRCMU_CHSPEC_D11AC_BW_8080
:
192 case BRCMU_CHSPEC_D11AC_BW_160
:
198 switch (ch
->chspec
& BRCMU_CHSPEC_D11AC_BND_MASK
) {
199 case BRCMU_CHSPEC_D11AC_BND_5G
:
200 ch
->band
= BRCMU_CHAN_BAND_5G
;
202 case BRCMU_CHSPEC_D11AC_BND_2G
:
203 ch
->band
= BRCMU_CHAN_BAND_2G
;
211 void brcmu_d11_attach(struct brcmu_d11inf
*d11inf
)
213 if (d11inf
->io_type
== BRCMU_D11N_IOTYPE
) {
214 d11inf
->encchspec
= brcmu_d11n_encchspec
;
215 d11inf
->decchspec
= brcmu_d11n_decchspec
;
217 d11inf
->encchspec
= brcmu_d11ac_encchspec
;
218 d11inf
->decchspec
= brcmu_d11ac_decchspec
;
221 EXPORT_SYMBOL(brcmu_d11_attach
);