Merge branch 'next' of git://git.infradead.org/users/pcmoore/selinux into next
[deliverable/linux.git] / drivers / net / wireless / brcm80211 / brcmutil / d11.c
1 /*
2 * Copyright (c) 2013 Broadcom Corporation
3 *
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.
7 *
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.
15 */
16 /*********************channel spec common functions*********************/
17
18 #include <linux/module.h>
19
20 #include <brcmu_utils.h>
21 #include <brcmu_wifi.h>
22 #include <brcmu_d11.h>
23
24 static u16 d11n_sb(enum brcmu_chan_sb sb)
25 {
26 switch (sb) {
27 case BRCMU_CHAN_SB_NONE:
28 return BRCMU_CHSPEC_D11N_SB_N;
29 case BRCMU_CHAN_SB_L:
30 return BRCMU_CHSPEC_D11N_SB_L;
31 case BRCMU_CHAN_SB_U:
32 return BRCMU_CHSPEC_D11N_SB_U;
33 default:
34 WARN_ON(1);
35 }
36 return 0;
37 }
38
39 static u16 d11n_bw(enum brcmu_chan_bw bw)
40 {
41 switch (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;
46 default:
47 WARN_ON(1);
48 }
49 return 0;
50 }
51
52 static void brcmu_d11n_encchspec(struct brcmu_chan *ch)
53 {
54 if (ch->bw == BRCMU_CHAN_BW_20)
55 ch->sb = BRCMU_CHAN_SB_NONE;
56
57 ch->chspec = 0;
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,
61 0, d11n_sb(ch->sb));
62 brcmu_maskset16(&ch->chspec, BRCMU_CHSPEC_D11N_BW_MASK,
63 0, d11n_bw(ch->bw));
64
65 if (ch->chnum <= CH_MAX_2G_CHANNEL)
66 ch->chspec |= BRCMU_CHSPEC_D11N_BND_2G;
67 else
68 ch->chspec |= BRCMU_CHSPEC_D11N_BND_5G;
69 }
70
71 static u16 d11ac_bw(enum brcmu_chan_bw bw)
72 {
73 switch (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 default:
81 WARN_ON(1);
82 }
83 return 0;
84 }
85
86 static void brcmu_d11ac_encchspec(struct brcmu_chan *ch)
87 {
88 if (ch->bw == BRCMU_CHAN_BW_20 || ch->sb == BRCMU_CHAN_SB_NONE)
89 ch->sb = BRCMU_CHAN_SB_L;
90
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,
96 0, d11ac_bw(ch->bw));
97
98 ch->chspec &= ~BRCMU_CHSPEC_D11AC_BND_MASK;
99 if (ch->chnum <= CH_MAX_2G_CHANNEL)
100 ch->chspec |= BRCMU_CHSPEC_D11AC_BND_2G;
101 else
102 ch->chspec |= BRCMU_CHSPEC_D11AC_BND_5G;
103 }
104
105 static void brcmu_d11n_decchspec(struct brcmu_chan *ch)
106 {
107 u16 val;
108
109 ch->chnum = (u8)(ch->chspec & BRCMU_CHSPEC_CH_MASK);
110
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;
115 break;
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;
122 } else {
123 ch->sb = BRCMU_CHAN_SB_U;
124 ch->chnum += CH_10MHZ_APART;
125 }
126 break;
127 default:
128 WARN_ON_ONCE(1);
129 break;
130 }
131
132 switch (ch->chspec & BRCMU_CHSPEC_D11N_BND_MASK) {
133 case BRCMU_CHSPEC_D11N_BND_5G:
134 ch->band = BRCMU_CHAN_BAND_5G;
135 break;
136 case BRCMU_CHSPEC_D11N_BND_2G:
137 ch->band = BRCMU_CHAN_BAND_2G;
138 break;
139 default:
140 WARN_ON_ONCE(1);
141 break;
142 }
143 }
144
145 static void brcmu_d11ac_decchspec(struct brcmu_chan *ch)
146 {
147 u16 val;
148
149 ch->chnum = (u8)(ch->chspec & BRCMU_CHSPEC_CH_MASK);
150
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;
155 break;
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;
165 } else {
166 WARN_ON_ONCE(1);
167 }
168 break;
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);
173 switch (ch->sb) {
174 case BRCMU_CHAN_SB_LL:
175 ch->chnum -= CH_30MHZ_APART;
176 break;
177 case BRCMU_CHAN_SB_LU:
178 ch->chnum -= CH_10MHZ_APART;
179 break;
180 case BRCMU_CHAN_SB_UL:
181 ch->chnum += CH_10MHZ_APART;
182 break;
183 case BRCMU_CHAN_SB_UU:
184 ch->chnum += CH_30MHZ_APART;
185 break;
186 default:
187 WARN_ON_ONCE(1);
188 break;
189 }
190 break;
191 case BRCMU_CHSPEC_D11AC_BW_8080:
192 case BRCMU_CHSPEC_D11AC_BW_160:
193 default:
194 WARN_ON_ONCE(1);
195 break;
196 }
197
198 switch (ch->chspec & BRCMU_CHSPEC_D11AC_BND_MASK) {
199 case BRCMU_CHSPEC_D11AC_BND_5G:
200 ch->band = BRCMU_CHAN_BAND_5G;
201 break;
202 case BRCMU_CHSPEC_D11AC_BND_2G:
203 ch->band = BRCMU_CHAN_BAND_2G;
204 break;
205 default:
206 WARN_ON_ONCE(1);
207 break;
208 }
209 }
210
211 void brcmu_d11_attach(struct brcmu_d11inf *d11inf)
212 {
213 if (d11inf->io_type == BRCMU_D11N_IOTYPE) {
214 d11inf->encchspec = brcmu_d11n_encchspec;
215 d11inf->decchspec = brcmu_d11n_decchspec;
216 } else {
217 d11inf->encchspec = brcmu_d11ac_encchspec;
218 d11inf->decchspec = brcmu_d11ac_decchspec;
219 }
220 }
221 EXPORT_SYMBOL(brcmu_d11_attach);
This page took 0.045653 seconds and 6 git commands to generate.