netfilter: remove unnecessary goto statement for error recovery
[cascardo/linux.git] / drivers / net / wireless / brcm80211 / brcmsmac / channel.c
1 /*
2  * Copyright (c) 2010 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
17 #include <linux/types.h>
18 #include <net/cfg80211.h>
19 #include <net/mac80211.h>
20 #include <net/regulatory.h>
21
22 #include <defs.h>
23 #include "pub.h"
24 #include "phy/phy_hal.h"
25 #include "main.h"
26 #include "stf.h"
27 #include "channel.h"
28 #include "mac80211_if.h"
29
30 /* QDB() macro takes a dB value and converts to a quarter dB value */
31 #define QDB(n) ((n) * BRCMS_TXPWR_DB_FACTOR)
32
33 #define LOCALE_MIMO_IDX_bn              0
34 #define LOCALE_MIMO_IDX_11n             0
35
36 /* max of BAND_5G_PWR_LVLS and 14 for 2.4 GHz */
37 #define BRCMS_MAXPWR_MIMO_TBL_SIZE      14
38
39 /* maxpwr mapping to 5GHz band channels:
40  * maxpwr[0] - channels [34-48]
41  * maxpwr[1] - channels [52-60]
42  * maxpwr[2] - channels [62-64]
43  * maxpwr[3] - channels [100-140]
44  * maxpwr[4] - channels [149-165]
45  */
46 #define BAND_5G_PWR_LVLS        5       /* 5 power levels for 5G */
47
48 #define LC(id)  LOCALE_MIMO_IDX_ ## id
49
50 #define LOCALES(mimo2, mimo5) \
51                 {LC(mimo2), LC(mimo5)}
52
53 /* macro to get 5 GHz channel group index for tx power */
54 #define CHANNEL_POWER_IDX_5G(c) (((c) < 52) ? 0 : \
55                                  (((c) < 62) ? 1 : \
56                                  (((c) < 100) ? 2 : \
57                                  (((c) < 149) ? 3 : 4))))
58
59 #define BRCM_2GHZ_2412_2462     REG_RULE(2412-10, 2462+10, 40, 0, 19, 0)
60 #define BRCM_2GHZ_2467_2472     REG_RULE(2467-10, 2472+10, 20, 0, 19, \
61                                          NL80211_RRF_PASSIVE_SCAN | \
62                                          NL80211_RRF_NO_IBSS)
63
64 #define BRCM_5GHZ_5180_5240     REG_RULE(5180-10, 5240+10, 40, 0, 21, \
65                                          NL80211_RRF_PASSIVE_SCAN | \
66                                          NL80211_RRF_NO_IBSS)
67 #define BRCM_5GHZ_5260_5320     REG_RULE(5260-10, 5320+10, 40, 0, 21, \
68                                          NL80211_RRF_PASSIVE_SCAN | \
69                                          NL80211_RRF_DFS | \
70                                          NL80211_RRF_NO_IBSS)
71 #define BRCM_5GHZ_5500_5700     REG_RULE(5500-10, 5700+10, 40, 0, 21, \
72                                          NL80211_RRF_PASSIVE_SCAN | \
73                                          NL80211_RRF_DFS | \
74                                          NL80211_RRF_NO_IBSS)
75 #define BRCM_5GHZ_5745_5825     REG_RULE(5745-10, 5825+10, 40, 0, 21, \
76                                          NL80211_RRF_PASSIVE_SCAN | \
77                                          NL80211_RRF_NO_IBSS)
78
79 static const struct ieee80211_regdomain brcms_regdom_x2 = {
80         .n_reg_rules = 7,
81         .alpha2 = "X2",
82         .reg_rules = {
83                 BRCM_2GHZ_2412_2462,
84                 BRCM_2GHZ_2467_2472,
85                 BRCM_5GHZ_5180_5240,
86                 BRCM_5GHZ_5260_5320,
87                 BRCM_5GHZ_5500_5700,
88                 BRCM_5GHZ_5745_5825,
89         }
90 };
91
92  /* locale per-channel tx power limits for MIMO frames
93   * maxpwr arrays are index by channel for 2.4 GHz limits, and
94   * by sub-band for 5 GHz limits using CHANNEL_POWER_IDX_5G(channel)
95   */
96 struct locale_mimo_info {
97         /* tx 20 MHz power limits, qdBm units */
98         s8 maxpwr20[BRCMS_MAXPWR_MIMO_TBL_SIZE];
99         /* tx 40 MHz power limits, qdBm units */
100         s8 maxpwr40[BRCMS_MAXPWR_MIMO_TBL_SIZE];
101 };
102
103 /* Country names and abbreviations with locale defined from ISO 3166 */
104 struct country_info {
105         const u8 locale_mimo_2G;        /* 2.4G mimo info */
106         const u8 locale_mimo_5G;        /* 5G mimo info */
107 };
108
109 struct brcms_regd {
110         struct country_info country;
111         const struct ieee80211_regdomain *regdomain;
112 };
113
114 struct brcms_cm_info {
115         struct brcms_pub *pub;
116         struct brcms_c_info *wlc;
117         const struct brcms_regd *world_regd;
118 };
119
120 /*
121  * MIMO Locale Definitions - 2.4 GHz
122  */
123 static const struct locale_mimo_info locale_bn = {
124         {QDB(13), QDB(13), QDB(13), QDB(13), QDB(13),
125          QDB(13), QDB(13), QDB(13), QDB(13), QDB(13),
126          QDB(13), QDB(13), QDB(13)},
127         {0, 0, QDB(13), QDB(13), QDB(13),
128          QDB(13), QDB(13), QDB(13), QDB(13), QDB(13),
129          QDB(13), 0, 0},
130 };
131
132 static const struct locale_mimo_info *g_mimo_2g_table[] = {
133         &locale_bn
134 };
135
136 /*
137  * MIMO Locale Definitions - 5 GHz
138  */
139 static const struct locale_mimo_info locale_11n = {
140         { /* 12.5 dBm */ 50, 50, 50, QDB(15), QDB(15)},
141         {QDB(14), QDB(15), QDB(15), QDB(15), QDB(15)},
142 };
143
144 static const struct locale_mimo_info *g_mimo_5g_table[] = {
145         &locale_11n
146 };
147
148 static const struct brcms_regd cntry_locales[] = {
149         /* Worldwide RoW 2, must always be at index 0 */
150         {
151                 .country = LOCALES(bn, 11n),
152                 .regdomain = &brcms_regdom_x2,
153         },
154 };
155
156 static const struct locale_mimo_info *brcms_c_get_mimo_2g(u8 locale_idx)
157 {
158         if (locale_idx >= ARRAY_SIZE(g_mimo_2g_table))
159                 return NULL;
160
161         return g_mimo_2g_table[locale_idx];
162 }
163
164 static const struct locale_mimo_info *brcms_c_get_mimo_5g(u8 locale_idx)
165 {
166         if (locale_idx >= ARRAY_SIZE(g_mimo_5g_table))
167                 return NULL;
168
169         return g_mimo_5g_table[locale_idx];
170 }
171
172 /*
173  * Indicates whether the country provided is valid to pass
174  * to cfg80211 or not.
175  *
176  * returns true if valid; false if not.
177  */
178 static bool brcms_c_country_valid(const char *ccode)
179 {
180         /*
181          * only allow ascii alpha uppercase for the first 2
182          * chars.
183          */
184         if (!((0x80 & ccode[0]) == 0 && ccode[0] >= 0x41 && ccode[0] <= 0x5A &&
185               (0x80 & ccode[1]) == 0 && ccode[1] >= 0x41 && ccode[1] <= 0x5A &&
186               ccode[2] == '\0'))
187                 return false;
188
189         /*
190          * do not match ISO 3166-1 user assigned country codes
191          * that may be in the driver table
192          */
193         if (!strcmp("AA", ccode) ||        /* AA */
194             !strcmp("ZZ", ccode) ||        /* ZZ */
195             ccode[0] == 'X' ||             /* XA - XZ */
196             (ccode[0] == 'Q' &&            /* QM - QZ */
197              (ccode[1] >= 'M' && ccode[1] <= 'Z')))
198                 return false;
199
200         if (!strcmp("NA", ccode))
201                 return false;
202
203         return true;
204 }
205
206 static const struct brcms_regd *brcms_world_regd(const char *regdom, int len)
207 {
208         const struct brcms_regd *regd = NULL;
209         int i;
210
211         for (i = 0; i < ARRAY_SIZE(cntry_locales); i++) {
212                 if (!strncmp(regdom, cntry_locales[i].regdomain->alpha2, len)) {
213                         regd = &cntry_locales[i];
214                         break;
215                 }
216         }
217
218         return regd;
219 }
220
221 static const struct brcms_regd *brcms_default_world_regd(void)
222 {
223         return &cntry_locales[0];
224 }
225
226 /* JP, J1 - J10 are Japan ccodes */
227 static bool brcms_c_japan_ccode(const char *ccode)
228 {
229         return (ccode[0] == 'J' &&
230                 (ccode[1] == 'P' || (ccode[1] >= '1' && ccode[1] <= '9')));
231 }
232
233 static void
234 brcms_c_channel_min_txpower_limits_with_local_constraint(
235                 struct brcms_cm_info *wlc_cm, struct txpwr_limits *txpwr,
236                 u8 local_constraint_qdbm)
237 {
238         int j;
239
240         /* CCK Rates */
241         for (j = 0; j < WL_TX_POWER_CCK_NUM; j++)
242                 txpwr->cck[j] = min(txpwr->cck[j], local_constraint_qdbm);
243
244         /* 20 MHz Legacy OFDM SISO */
245         for (j = 0; j < WL_TX_POWER_OFDM_NUM; j++)
246                 txpwr->ofdm[j] = min(txpwr->ofdm[j], local_constraint_qdbm);
247
248         /* 20 MHz Legacy OFDM CDD */
249         for (j = 0; j < BRCMS_NUM_RATES_OFDM; j++)
250                 txpwr->ofdm_cdd[j] =
251                     min(txpwr->ofdm_cdd[j], local_constraint_qdbm);
252
253         /* 40 MHz Legacy OFDM SISO */
254         for (j = 0; j < BRCMS_NUM_RATES_OFDM; j++)
255                 txpwr->ofdm_40_siso[j] =
256                     min(txpwr->ofdm_40_siso[j], local_constraint_qdbm);
257
258         /* 40 MHz Legacy OFDM CDD */
259         for (j = 0; j < BRCMS_NUM_RATES_OFDM; j++)
260                 txpwr->ofdm_40_cdd[j] =
261                     min(txpwr->ofdm_40_cdd[j], local_constraint_qdbm);
262
263         /* 20MHz MCS 0-7 SISO */
264         for (j = 0; j < BRCMS_NUM_RATES_MCS_1_STREAM; j++)
265                 txpwr->mcs_20_siso[j] =
266                     min(txpwr->mcs_20_siso[j], local_constraint_qdbm);
267
268         /* 20MHz MCS 0-7 CDD */
269         for (j = 0; j < BRCMS_NUM_RATES_MCS_1_STREAM; j++)
270                 txpwr->mcs_20_cdd[j] =
271                     min(txpwr->mcs_20_cdd[j], local_constraint_qdbm);
272
273         /* 20MHz MCS 0-7 STBC */
274         for (j = 0; j < BRCMS_NUM_RATES_MCS_1_STREAM; j++)
275                 txpwr->mcs_20_stbc[j] =
276                     min(txpwr->mcs_20_stbc[j], local_constraint_qdbm);
277
278         /* 20MHz MCS 8-15 MIMO */
279         for (j = 0; j < BRCMS_NUM_RATES_MCS_2_STREAM; j++)
280                 txpwr->mcs_20_mimo[j] =
281                     min(txpwr->mcs_20_mimo[j], local_constraint_qdbm);
282
283         /* 40MHz MCS 0-7 SISO */
284         for (j = 0; j < BRCMS_NUM_RATES_MCS_1_STREAM; j++)
285                 txpwr->mcs_40_siso[j] =
286                     min(txpwr->mcs_40_siso[j], local_constraint_qdbm);
287
288         /* 40MHz MCS 0-7 CDD */
289         for (j = 0; j < BRCMS_NUM_RATES_MCS_1_STREAM; j++)
290                 txpwr->mcs_40_cdd[j] =
291                     min(txpwr->mcs_40_cdd[j], local_constraint_qdbm);
292
293         /* 40MHz MCS 0-7 STBC */
294         for (j = 0; j < BRCMS_NUM_RATES_MCS_1_STREAM; j++)
295                 txpwr->mcs_40_stbc[j] =
296                     min(txpwr->mcs_40_stbc[j], local_constraint_qdbm);
297
298         /* 40MHz MCS 8-15 MIMO */
299         for (j = 0; j < BRCMS_NUM_RATES_MCS_2_STREAM; j++)
300                 txpwr->mcs_40_mimo[j] =
301                     min(txpwr->mcs_40_mimo[j], local_constraint_qdbm);
302
303         /* 40MHz MCS 32 */
304         txpwr->mcs32 = min(txpwr->mcs32, local_constraint_qdbm);
305
306 }
307
308 /*
309  * set the driver's current country and regulatory information
310  * using a country code as the source. Look up built in country
311  * information found with the country code.
312  */
313 static void
314 brcms_c_set_country(struct brcms_cm_info *wlc_cm,
315                     const struct brcms_regd *regd)
316 {
317         struct brcms_c_info *wlc = wlc_cm->wlc;
318
319         if ((wlc->pub->_n_enab & SUPPORT_11N) !=
320             wlc->protection->nmode_user)
321                 brcms_c_set_nmode(wlc);
322
323         brcms_c_stf_ss_update(wlc, wlc->bandstate[BAND_2G_INDEX]);
324         brcms_c_stf_ss_update(wlc, wlc->bandstate[BAND_5G_INDEX]);
325
326         brcms_c_set_gmode(wlc, wlc->protection->gmode_user, false);
327
328         return;
329 }
330
331 struct brcms_cm_info *brcms_c_channel_mgr_attach(struct brcms_c_info *wlc)
332 {
333         struct brcms_cm_info *wlc_cm;
334         struct brcms_pub *pub = wlc->pub;
335         struct ssb_sprom *sprom = &wlc->hw->d11core->bus->sprom;
336         const char *ccode = sprom->alpha2;
337         int ccode_len = sizeof(sprom->alpha2);
338
339         BCMMSG(wlc->wiphy, "wl%d\n", wlc->pub->unit);
340
341         wlc_cm = kzalloc(sizeof(struct brcms_cm_info), GFP_ATOMIC);
342         if (wlc_cm == NULL)
343                 return NULL;
344         wlc_cm->pub = pub;
345         wlc_cm->wlc = wlc;
346         wlc->cmi = wlc_cm;
347
348         /* store the country code for passing up as a regulatory hint */
349         wlc_cm->world_regd = brcms_world_regd(ccode, ccode_len);
350         if (brcms_c_country_valid(ccode))
351                 strncpy(wlc->pub->srom_ccode, ccode, ccode_len);
352
353         /*
354          * If no custom world domain is found in the SROM, use the
355          * default "X2" domain.
356          */
357         if (!wlc_cm->world_regd) {
358                 wlc_cm->world_regd = brcms_default_world_regd();
359                 ccode = wlc_cm->world_regd->regdomain->alpha2;
360                 ccode_len = BRCM_CNTRY_BUF_SZ - 1;
361         }
362
363         /* save default country for exiting 11d regulatory mode */
364         strncpy(wlc->country_default, ccode, ccode_len);
365
366         /* initialize autocountry_default to driver default */
367         strncpy(wlc->autocountry_default, ccode, ccode_len);
368
369         brcms_c_set_country(wlc_cm, wlc_cm->world_regd);
370
371         return wlc_cm;
372 }
373
374 void brcms_c_channel_mgr_detach(struct brcms_cm_info *wlc_cm)
375 {
376         kfree(wlc_cm);
377 }
378
379 void
380 brcms_c_channel_set_chanspec(struct brcms_cm_info *wlc_cm, u16 chanspec,
381                          u8 local_constraint_qdbm)
382 {
383         struct brcms_c_info *wlc = wlc_cm->wlc;
384         struct ieee80211_channel *ch = wlc->pub->ieee_hw->conf.channel;
385         const struct ieee80211_reg_rule *reg_rule;
386         struct txpwr_limits txpwr;
387         int ret;
388
389         brcms_c_channel_reg_limits(wlc_cm, chanspec, &txpwr);
390
391         brcms_c_channel_min_txpower_limits_with_local_constraint(
392                 wlc_cm, &txpwr, local_constraint_qdbm
393         );
394
395         /* set or restore gmode as required by regulatory */
396         ret = freq_reg_info(wlc->wiphy, ch->center_freq, 0, &reg_rule);
397         if (!ret && (reg_rule->flags & NL80211_RRF_NO_OFDM))
398                 brcms_c_set_gmode(wlc, GMODE_LEGACY_B, false);
399         else
400                 brcms_c_set_gmode(wlc, wlc->protection->gmode_user, false);
401
402         brcms_b_set_chanspec(wlc->hw, chanspec,
403                               !!(ch->flags & IEEE80211_CHAN_PASSIVE_SCAN),
404                               &txpwr);
405 }
406
407 void
408 brcms_c_channel_reg_limits(struct brcms_cm_info *wlc_cm, u16 chanspec,
409                        struct txpwr_limits *txpwr)
410 {
411         struct brcms_c_info *wlc = wlc_cm->wlc;
412         struct ieee80211_channel *ch = wlc->pub->ieee_hw->conf.channel;
413         uint i;
414         uint chan;
415         int maxpwr;
416         int delta;
417         const struct country_info *country;
418         struct brcms_band *band;
419         int conducted_max = BRCMS_TXPWR_MAX;
420         const struct locale_mimo_info *li_mimo;
421         int maxpwr20, maxpwr40;
422         int maxpwr_idx;
423         uint j;
424
425         memset(txpwr, 0, sizeof(struct txpwr_limits));
426
427         if (WARN_ON(!ch))
428                 return;
429
430         country = &wlc_cm->world_regd->country;
431
432         chan = CHSPEC_CHANNEL(chanspec);
433         band = wlc->bandstate[chspec_bandunit(chanspec)];
434         li_mimo = (band->bandtype == BRCM_BAND_5G) ?
435             brcms_c_get_mimo_5g(country->locale_mimo_5G) :
436             brcms_c_get_mimo_2g(country->locale_mimo_2G);
437
438         delta = band->antgain;
439
440         if (band->bandtype == BRCM_BAND_2G)
441                 conducted_max = QDB(22);
442
443         maxpwr = QDB(ch->max_power) - delta;
444         maxpwr = max(maxpwr, 0);
445         maxpwr = min(maxpwr, conducted_max);
446
447         /* CCK txpwr limits for 2.4G band */
448         if (band->bandtype == BRCM_BAND_2G) {
449                 for (i = 0; i < BRCMS_NUM_RATES_CCK; i++)
450                         txpwr->cck[i] = (u8) maxpwr;
451         }
452
453         for (i = 0; i < BRCMS_NUM_RATES_OFDM; i++) {
454                 txpwr->ofdm[i] = (u8) maxpwr;
455
456                 /*
457                  * OFDM 40 MHz SISO has the same power as the corresponding
458                  * MCS0-7 rate unless overriden by the locale specific code.
459                  * We set this value to 0 as a flag (presumably 0 dBm isn't
460                  * a possibility) and then copy the MCS0-7 value to the 40 MHz
461                  * value if it wasn't explicitly set.
462                  */
463                 txpwr->ofdm_40_siso[i] = 0;
464
465                 txpwr->ofdm_cdd[i] = (u8) maxpwr;
466
467                 txpwr->ofdm_40_cdd[i] = 0;
468         }
469
470         delta = 0;
471         if (band->antgain > QDB(6))
472                 delta = band->antgain - QDB(6); /* Excess over 6 dB */
473
474         if (band->bandtype == BRCM_BAND_2G)
475                 maxpwr_idx = (chan - 1);
476         else
477                 maxpwr_idx = CHANNEL_POWER_IDX_5G(chan);
478
479         maxpwr20 = li_mimo->maxpwr20[maxpwr_idx];
480         maxpwr40 = li_mimo->maxpwr40[maxpwr_idx];
481
482         maxpwr20 = maxpwr20 - delta;
483         maxpwr20 = max(maxpwr20, 0);
484         maxpwr40 = maxpwr40 - delta;
485         maxpwr40 = max(maxpwr40, 0);
486
487         /* Fill in the MCS 0-7 (SISO) rates */
488         for (i = 0; i < BRCMS_NUM_RATES_MCS_1_STREAM; i++) {
489
490                 /*
491                  * 20 MHz has the same power as the corresponding OFDM rate
492                  * unless overriden by the locale specific code.
493                  */
494                 txpwr->mcs_20_siso[i] = txpwr->ofdm[i];
495                 txpwr->mcs_40_siso[i] = 0;
496         }
497
498         /* Fill in the MCS 0-7 CDD rates */
499         for (i = 0; i < BRCMS_NUM_RATES_MCS_1_STREAM; i++) {
500                 txpwr->mcs_20_cdd[i] = (u8) maxpwr20;
501                 txpwr->mcs_40_cdd[i] = (u8) maxpwr40;
502         }
503
504         /*
505          * These locales have SISO expressed in the
506          * table and override CDD later
507          */
508         if (li_mimo == &locale_bn) {
509                 if (li_mimo == &locale_bn) {
510                         maxpwr20 = QDB(16);
511                         maxpwr40 = 0;
512
513                         if (chan >= 3 && chan <= 11)
514                                 maxpwr40 = QDB(16);
515                 }
516
517                 for (i = 0; i < BRCMS_NUM_RATES_MCS_1_STREAM; i++) {
518                         txpwr->mcs_20_siso[i] = (u8) maxpwr20;
519                         txpwr->mcs_40_siso[i] = (u8) maxpwr40;
520                 }
521         }
522
523         /* Fill in the MCS 0-7 STBC rates */
524         for (i = 0; i < BRCMS_NUM_RATES_MCS_1_STREAM; i++) {
525                 txpwr->mcs_20_stbc[i] = 0;
526                 txpwr->mcs_40_stbc[i] = 0;
527         }
528
529         /* Fill in the MCS 8-15 SDM rates */
530         for (i = 0; i < BRCMS_NUM_RATES_MCS_2_STREAM; i++) {
531                 txpwr->mcs_20_mimo[i] = (u8) maxpwr20;
532                 txpwr->mcs_40_mimo[i] = (u8) maxpwr40;
533         }
534
535         /* Fill in MCS32 */
536         txpwr->mcs32 = (u8) maxpwr40;
537
538         for (i = 0, j = 0; i < BRCMS_NUM_RATES_OFDM; i++, j++) {
539                 if (txpwr->ofdm_40_cdd[i] == 0)
540                         txpwr->ofdm_40_cdd[i] = txpwr->mcs_40_cdd[j];
541                 if (i == 0) {
542                         i = i + 1;
543                         if (txpwr->ofdm_40_cdd[i] == 0)
544                                 txpwr->ofdm_40_cdd[i] = txpwr->mcs_40_cdd[j];
545                 }
546         }
547
548         /*
549          * Copy the 40 MHZ MCS 0-7 CDD value to the 40 MHZ MCS 0-7 SISO
550          * value if it wasn't provided explicitly.
551          */
552         for (i = 0; i < BRCMS_NUM_RATES_MCS_1_STREAM; i++) {
553                 if (txpwr->mcs_40_siso[i] == 0)
554                         txpwr->mcs_40_siso[i] = txpwr->mcs_40_cdd[i];
555         }
556
557         for (i = 0, j = 0; i < BRCMS_NUM_RATES_OFDM; i++, j++) {
558                 if (txpwr->ofdm_40_siso[i] == 0)
559                         txpwr->ofdm_40_siso[i] = txpwr->mcs_40_siso[j];
560                 if (i == 0) {
561                         i = i + 1;
562                         if (txpwr->ofdm_40_siso[i] == 0)
563                                 txpwr->ofdm_40_siso[i] = txpwr->mcs_40_siso[j];
564                 }
565         }
566
567         /*
568          * Copy the 20 and 40 MHz MCS0-7 CDD values to the corresponding
569          * STBC values if they weren't provided explicitly.
570          */
571         for (i = 0; i < BRCMS_NUM_RATES_MCS_1_STREAM; i++) {
572                 if (txpwr->mcs_20_stbc[i] == 0)
573                         txpwr->mcs_20_stbc[i] = txpwr->mcs_20_cdd[i];
574
575                 if (txpwr->mcs_40_stbc[i] == 0)
576                         txpwr->mcs_40_stbc[i] = txpwr->mcs_40_cdd[i];
577         }
578
579         return;
580 }
581
582 /*
583  * Verify the chanspec is using a legal set of parameters, i.e. that the
584  * chanspec specified a band, bw, ctl_sb and channel and that the
585  * combination could be legal given any set of circumstances.
586  * RETURNS: true is the chanspec is malformed, false if it looks good.
587  */
588 static bool brcms_c_chspec_malformed(u16 chanspec)
589 {
590         /* must be 2G or 5G band */
591         if (!CHSPEC_IS5G(chanspec) && !CHSPEC_IS2G(chanspec))
592                 return true;
593         /* must be 20 or 40 bandwidth */
594         if (!CHSPEC_IS40(chanspec) && !CHSPEC_IS20(chanspec))
595                 return true;
596
597         /* 20MHZ b/w must have no ctl sb, 40 must have a ctl sb */
598         if (CHSPEC_IS20(chanspec)) {
599                 if (!CHSPEC_SB_NONE(chanspec))
600                         return true;
601         } else if (!CHSPEC_SB_UPPER(chanspec) && !CHSPEC_SB_LOWER(chanspec)) {
602                 return true;
603         }
604
605         return false;
606 }
607
608 /*
609  * Validate the chanspec for this locale, for 40MHZ we need to also
610  * check that the sidebands are valid 20MZH channels in this locale
611  * and they are also a legal HT combination
612  */
613 static bool
614 brcms_c_valid_chanspec_ext(struct brcms_cm_info *wlc_cm, u16 chspec)
615 {
616         struct brcms_c_info *wlc = wlc_cm->wlc;
617         u8 channel = CHSPEC_CHANNEL(chspec);
618
619         /* check the chanspec */
620         if (brcms_c_chspec_malformed(chspec)) {
621                 wiphy_err(wlc->wiphy, "wl%d: malformed chanspec 0x%x\n",
622                         wlc->pub->unit, chspec);
623                 return false;
624         }
625
626         if (CHANNEL_BANDUNIT(wlc_cm->wlc, channel) !=
627             chspec_bandunit(chspec))
628                 return false;
629
630         return true;
631 }
632
633 bool brcms_c_valid_chanspec_db(struct brcms_cm_info *wlc_cm, u16 chspec)
634 {
635         return brcms_c_valid_chanspec_ext(wlc_cm, chspec);
636 }
637
638 static bool brcms_is_radar_freq(u16 center_freq)
639 {
640         return center_freq >= 5260 && center_freq <= 5700;
641 }
642
643 static void brcms_reg_apply_radar_flags(struct wiphy *wiphy)
644 {
645         struct ieee80211_supported_band *sband;
646         struct ieee80211_channel *ch;
647         int i;
648
649         sband = wiphy->bands[IEEE80211_BAND_5GHZ];
650         if (!sband)
651                 return;
652
653         for (i = 0; i < sband->n_channels; i++) {
654                 ch = &sband->channels[i];
655
656                 if (!brcms_is_radar_freq(ch->center_freq))
657                         continue;
658
659                 /*
660                  * All channels in this range should be passive and have
661                  * DFS enabled.
662                  */
663                 if (!(ch->flags & IEEE80211_CHAN_DISABLED))
664                         ch->flags |= IEEE80211_CHAN_RADAR |
665                                      IEEE80211_CHAN_NO_IBSS |
666                                      IEEE80211_CHAN_PASSIVE_SCAN;
667         }
668 }
669
670 static void
671 brcms_reg_apply_beaconing_flags(struct wiphy *wiphy,
672                                 enum nl80211_reg_initiator initiator)
673 {
674         struct ieee80211_supported_band *sband;
675         struct ieee80211_channel *ch;
676         const struct ieee80211_reg_rule *rule;
677         int band, i, ret;
678
679         for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
680                 sband = wiphy->bands[band];
681                 if (!sband)
682                         continue;
683
684                 for (i = 0; i < sband->n_channels; i++) {
685                         ch = &sband->channels[i];
686
687                         if (ch->flags &
688                             (IEEE80211_CHAN_DISABLED | IEEE80211_CHAN_RADAR))
689                                 continue;
690
691                         if (initiator == NL80211_REGDOM_SET_BY_COUNTRY_IE) {
692                                 ret = freq_reg_info(wiphy, ch->center_freq,
693                                                     0, &rule);
694                                 if (ret)
695                                         continue;
696
697                                 if (!(rule->flags & NL80211_RRF_NO_IBSS))
698                                         ch->flags &= ~IEEE80211_CHAN_NO_IBSS;
699                                 if (!(rule->flags & NL80211_RRF_PASSIVE_SCAN))
700                                         ch->flags &=
701                                                 ~IEEE80211_CHAN_PASSIVE_SCAN;
702                         } else if (ch->beacon_found) {
703                                 ch->flags &= ~(IEEE80211_CHAN_NO_IBSS |
704                                                IEEE80211_CHAN_PASSIVE_SCAN);
705                         }
706                 }
707         }
708 }
709
710 static int brcms_reg_notifier(struct wiphy *wiphy,
711                               struct regulatory_request *request)
712 {
713         struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
714         struct brcms_info *wl = hw->priv;
715         struct brcms_c_info *wlc = wl->wlc;
716         struct ieee80211_supported_band *sband;
717         struct ieee80211_channel *ch;
718         int band, i;
719         bool ch_found = false;
720
721         brcms_reg_apply_radar_flags(wiphy);
722
723         if (request->initiator == NL80211_REGDOM_SET_BY_COUNTRY_IE)
724                 brcms_reg_apply_beaconing_flags(wiphy, request->initiator);
725
726         /* Disable radio if all channels disallowed by regulatory */
727         for (band = 0; !ch_found && band < IEEE80211_NUM_BANDS; band++) {
728                 sband = wiphy->bands[band];
729                 if (!sband)
730                         continue;
731
732                 for (i = 0; !ch_found && i < sband->n_channels; i++) {
733                         ch = &sband->channels[i];
734
735                         if (!(ch->flags & IEEE80211_CHAN_DISABLED))
736                                 ch_found = true;
737                 }
738         }
739
740         if (ch_found) {
741                 mboolclr(wlc->pub->radio_disabled, WL_RADIO_COUNTRY_DISABLE);
742         } else {
743                 mboolset(wlc->pub->radio_disabled, WL_RADIO_COUNTRY_DISABLE);
744                 wiphy_err(wlc->wiphy, "wl%d: %s: no valid channel for \"%s\"\n",
745                           wlc->pub->unit, __func__, request->alpha2);
746         }
747
748         if (wlc->pub->_nbands > 1 || wlc->band->bandtype == BRCM_BAND_2G)
749                 wlc_phy_chanspec_ch14_widefilter_set(wlc->band->pi,
750                                         brcms_c_japan_ccode(request->alpha2));
751
752         return 0;
753 }
754
755 void brcms_c_regd_init(struct brcms_c_info *wlc)
756 {
757         struct wiphy *wiphy = wlc->wiphy;
758         const struct brcms_regd *regd = wlc->cmi->world_regd;
759         struct ieee80211_supported_band *sband;
760         struct ieee80211_channel *ch;
761         struct brcms_chanvec sup_chan;
762         struct brcms_band *band;
763         int band_idx, i;
764
765         /* Disable any channels not supported by the phy */
766         for (band_idx = 0; band_idx < wlc->pub->_nbands; band_idx++) {
767                 band = wlc->bandstate[band_idx];
768
769                 wlc_phy_chanspec_band_validch(band->pi, band->bandtype,
770                                               &sup_chan);
771
772                 if (band_idx == BAND_2G_INDEX)
773                         sband = wiphy->bands[IEEE80211_BAND_2GHZ];
774                 else
775                         sband = wiphy->bands[IEEE80211_BAND_5GHZ];
776
777                 for (i = 0; i < sband->n_channels; i++) {
778                         ch = &sband->channels[i];
779                         if (!isset(sup_chan.vec, ch->hw_value))
780                                 ch->flags |= IEEE80211_CHAN_DISABLED;
781                 }
782         }
783
784         wlc->wiphy->reg_notifier = brcms_reg_notifier;
785         wlc->wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY |
786                              WIPHY_FLAG_STRICT_REGULATORY;
787         wiphy_apply_custom_regulatory(wlc->wiphy, regd->regdomain);
788         brcms_reg_apply_beaconing_flags(wiphy, NL80211_REGDOM_SET_BY_DRIVER);
789 }