]> Git Repo - J-linux.git/blob - drivers/net/wireless/intel/iwlwifi/fw/regulatory.c
Merge tag 'vfs-6.13-rc7.fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs
[J-linux.git] / drivers / net / wireless / intel / iwlwifi / fw / regulatory.c
1 // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
2 /*
3  * Copyright (C) 2023 Intel Corporation
4  */
5 #include <linux/dmi.h>
6 #include "iwl-drv.h"
7 #include "iwl-debug.h"
8 #include "regulatory.h"
9 #include "fw/runtime.h"
10 #include "fw/uefi.h"
11
12 #define GET_BIOS_TABLE(__name, ...)                                     \
13 do {                                                                    \
14         int ret = -ENOENT;                                              \
15         if (fwrt->uefi_tables_lock_status > UEFI_WIFI_GUID_UNLOCKED)    \
16                 ret = iwl_uefi_get_ ## __name(__VA_ARGS__);             \
17         if (ret < 0)                                                    \
18                 ret = iwl_acpi_get_ ## __name(__VA_ARGS__);             \
19         return ret;                                                     \
20 } while (0)
21
22 #define IWL_BIOS_TABLE_LOADER(__name)                                   \
23 int iwl_bios_get_ ## __name(struct iwl_fw_runtime *fwrt)                \
24 {GET_BIOS_TABLE(__name, fwrt); }                                        \
25 IWL_EXPORT_SYMBOL(iwl_bios_get_ ## __name)
26
27 #define IWL_BIOS_TABLE_LOADER_DATA(__name, data_type)                   \
28 int iwl_bios_get_ ## __name(struct iwl_fw_runtime *fwrt,                \
29                             data_type * data)                           \
30 {GET_BIOS_TABLE(__name, fwrt, data); }                                  \
31 IWL_EXPORT_SYMBOL(iwl_bios_get_ ## __name)
32
33 IWL_BIOS_TABLE_LOADER(wrds_table);
34 IWL_BIOS_TABLE_LOADER(ewrd_table);
35 IWL_BIOS_TABLE_LOADER(wgds_table);
36 IWL_BIOS_TABLE_LOADER(ppag_table);
37 IWL_BIOS_TABLE_LOADER_DATA(tas_table, struct iwl_tas_data);
38 IWL_BIOS_TABLE_LOADER_DATA(pwr_limit, u64);
39 IWL_BIOS_TABLE_LOADER_DATA(mcc, char);
40 IWL_BIOS_TABLE_LOADER_DATA(eckv, u32);
41 IWL_BIOS_TABLE_LOADER_DATA(wbem, u32);
42
43
44 static const struct dmi_system_id dmi_ppag_approved_list[] = {
45         { .ident = "HP",
46           .matches = {
47                         DMI_MATCH(DMI_SYS_VENDOR, "HP"),
48                 },
49         },
50         { .ident = "SAMSUNG",
51           .matches = {
52                         DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD"),
53                 },
54         },
55         { .ident = "MSFT",
56           .matches = {
57                         DMI_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"),
58                 },
59         },
60         { .ident = "ASUS",
61           .matches = {
62                         DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
63                 },
64         },
65         { .ident = "GOOGLE-HP",
66           .matches = {
67                         DMI_MATCH(DMI_SYS_VENDOR, "Google"),
68                         DMI_MATCH(DMI_BOARD_VENDOR, "HP"),
69                 },
70         },
71         { .ident = "GOOGLE-ASUS",
72           .matches = {
73                         DMI_MATCH(DMI_SYS_VENDOR, "Google"),
74                         DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTek COMPUTER INC."),
75                 },
76         },
77         { .ident = "GOOGLE-SAMSUNG",
78           .matches = {
79                         DMI_MATCH(DMI_SYS_VENDOR, "Google"),
80                         DMI_MATCH(DMI_BOARD_VENDOR, "SAMSUNG ELECTRONICS CO., LTD"),
81                 },
82         },
83         { .ident = "DELL",
84           .matches = {
85                         DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
86                 },
87         },
88         { .ident = "DELL",
89           .matches = {
90                         DMI_MATCH(DMI_SYS_VENDOR, "Alienware"),
91                 },
92         },
93         { .ident = "RAZER",
94           .matches = {
95                         DMI_MATCH(DMI_SYS_VENDOR, "Razer"),
96                 },
97         },
98         { .ident = "Honor",
99           .matches = {
100                         DMI_MATCH(DMI_SYS_VENDOR, "HONOR"),
101                 },
102         },
103         {}
104 };
105
106 static const struct dmi_system_id dmi_tas_approved_list[] = {
107         { .ident = "HP",
108           .matches = {
109                         DMI_MATCH(DMI_SYS_VENDOR, "HP"),
110                 },
111         },
112         { .ident = "SAMSUNG",
113           .matches = {
114                         DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD"),
115                 },
116         },
117                 { .ident = "LENOVO",
118           .matches = {
119                         DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
120                 },
121         },
122         { .ident = "DELL",
123           .matches = {
124                         DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
125                 },
126         },
127         { .ident = "MSFT",
128           .matches = {
129                         DMI_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"),
130                 },
131         },
132         { .ident = "Acer",
133           .matches = {
134                         DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
135                 },
136         },
137         { .ident = "ASUS",
138           .matches = {
139                         DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
140                 },
141         },
142         { .ident = "GOOGLE-HP",
143           .matches = {
144                         DMI_MATCH(DMI_SYS_VENDOR, "Google"),
145                         DMI_MATCH(DMI_BOARD_VENDOR, "HP"),
146                 },
147         },
148         { .ident = "MSI",
149           .matches = {
150                         DMI_MATCH(DMI_SYS_VENDOR, "Micro-Star International Co., Ltd."),
151                 },
152         },
153         { .ident = "Honor",
154           .matches = {
155                         DMI_MATCH(DMI_SYS_VENDOR, "HONOR"),
156                 },
157         },
158         /* keep last */
159         {}
160 };
161
162 bool iwl_sar_geo_support(struct iwl_fw_runtime *fwrt)
163 {
164         /*
165          * The PER_CHAIN_LIMIT_OFFSET_CMD command is not supported on
166          * earlier firmware versions.  Unfortunately, we don't have a
167          * TLV API flag to rely on, so rely on the major version which
168          * is in the first byte of ucode_ver.  This was implemented
169          * initially on version 38 and then backported to 17.  It was
170          * also backported to 29, but only for 7265D devices.  The
171          * intention was to have it in 36 as well, but not all 8000
172          * family got this feature enabled.  The 8000 family is the
173          * only one using version 36, so skip this version entirely.
174          */
175         return IWL_UCODE_SERIAL(fwrt->fw->ucode_ver) >= 38 ||
176                 (IWL_UCODE_SERIAL(fwrt->fw->ucode_ver) == 17 &&
177                  fwrt->trans->hw_rev != CSR_HW_REV_TYPE_3160) ||
178                 (IWL_UCODE_SERIAL(fwrt->fw->ucode_ver) == 29 &&
179                  ((fwrt->trans->hw_rev & CSR_HW_REV_TYPE_MSK) ==
180                   CSR_HW_REV_TYPE_7265D));
181 }
182 IWL_EXPORT_SYMBOL(iwl_sar_geo_support);
183
184 int iwl_sar_geo_fill_table(struct iwl_fw_runtime *fwrt,
185                            struct iwl_per_chain_offset *table,
186                            u32 n_bands, u32 n_profiles)
187 {
188         int i, j;
189
190         if (!fwrt->geo_enabled)
191                 return -ENODATA;
192
193         if (!iwl_sar_geo_support(fwrt))
194                 return -EOPNOTSUPP;
195
196         for (i = 0; i < n_profiles; i++) {
197                 for (j = 0; j < n_bands; j++) {
198                         struct iwl_per_chain_offset *chain =
199                                 &table[i * n_bands + j];
200
201                         chain->max_tx_power =
202                                 cpu_to_le16(fwrt->geo_profiles[i].bands[j].max);
203                         chain->chain_a =
204                                 fwrt->geo_profiles[i].bands[j].chains[0];
205                         chain->chain_b =
206                                 fwrt->geo_profiles[i].bands[j].chains[1];
207                         IWL_DEBUG_RADIO(fwrt,
208                                         "SAR geographic profile[%d] Band[%d]: chain A = %d chain B = %d max_tx_power = %d\n",
209                                         i, j,
210                                         fwrt->geo_profiles[i].bands[j].chains[0],
211                                         fwrt->geo_profiles[i].bands[j].chains[1],
212                                         fwrt->geo_profiles[i].bands[j].max);
213                 }
214         }
215
216         return 0;
217 }
218 IWL_EXPORT_SYMBOL(iwl_sar_geo_fill_table);
219
220 static int iwl_sar_fill_table(struct iwl_fw_runtime *fwrt,
221                               __le16 *per_chain, u32 n_subbands,
222                               int prof_a, int prof_b)
223 {
224         int profs[BIOS_SAR_NUM_CHAINS] = { prof_a, prof_b };
225         int i, j;
226
227         for (i = 0; i < BIOS_SAR_NUM_CHAINS; i++) {
228                 struct iwl_sar_profile *prof;
229
230                 /* don't allow SAR to be disabled (profile 0 means disable) */
231                 if (profs[i] == 0)
232                         return -EPERM;
233
234                 /* we are off by one, so allow up to BIOS_SAR_MAX_PROFILE_NUM */
235                 if (profs[i] > BIOS_SAR_MAX_PROFILE_NUM)
236                         return -EINVAL;
237
238                 /* profiles go from 1 to 4, so decrement to access the array */
239                 prof = &fwrt->sar_profiles[profs[i] - 1];
240
241                 /* if the profile is disabled, do nothing */
242                 if (!prof->enabled) {
243                         IWL_DEBUG_RADIO(fwrt, "SAR profile %d is disabled.\n",
244                                         profs[i]);
245                         /*
246                          * if one of the profiles is disabled, we
247                          * ignore all of them and return 1 to
248                          * differentiate disabled from other failures.
249                          */
250                         return 1;
251                 }
252
253                 IWL_DEBUG_INFO(fwrt,
254                                "SAR EWRD: chain %d profile index %d\n",
255                                i, profs[i]);
256                 IWL_DEBUG_RADIO(fwrt, "  Chain[%d]:\n", i);
257                 for (j = 0; j < n_subbands; j++) {
258                         per_chain[i * n_subbands + j] =
259                                 cpu_to_le16(prof->chains[i].subbands[j]);
260                         IWL_DEBUG_RADIO(fwrt, "    Band[%d] = %d * .125dBm\n",
261                                         j, prof->chains[i].subbands[j]);
262                 }
263         }
264
265         return 0;
266 }
267
268 int iwl_sar_fill_profile(struct iwl_fw_runtime *fwrt,
269                          __le16 *per_chain, u32 n_tables, u32 n_subbands,
270                          int prof_a, int prof_b)
271 {
272         int i, ret = 0;
273
274         for (i = 0; i < n_tables; i++) {
275                 ret = iwl_sar_fill_table(fwrt,
276                         &per_chain[i * n_subbands * BIOS_SAR_NUM_CHAINS],
277                         n_subbands, prof_a, prof_b);
278                 if (ret)
279                         break;
280         }
281
282         return ret;
283 }
284 IWL_EXPORT_SYMBOL(iwl_sar_fill_profile);
285
286 static bool iwl_ppag_value_valid(struct iwl_fw_runtime *fwrt, int chain,
287                                  int subband)
288 {
289         s8 ppag_val = fwrt->ppag_chains[chain].subbands[subband];
290
291         if ((subband == 0 &&
292              (ppag_val > IWL_PPAG_MAX_LB || ppag_val < IWL_PPAG_MIN_LB)) ||
293             (subband != 0 &&
294              (ppag_val > IWL_PPAG_MAX_HB || ppag_val < IWL_PPAG_MIN_HB))) {
295                 IWL_DEBUG_RADIO(fwrt, "Invalid PPAG value: %d\n", ppag_val);
296                 return false;
297         }
298         return true;
299 }
300
301 int iwl_fill_ppag_table(struct iwl_fw_runtime *fwrt,
302                         union iwl_ppag_table_cmd *cmd, int *cmd_size)
303 {
304         u8 cmd_ver;
305         int i, j, num_sub_bands;
306         s8 *gain;
307         bool send_ppag_always;
308
309         /* many firmware images for JF lie about this */
310         if (CSR_HW_RFID_TYPE(fwrt->trans->hw_rf_id) ==
311             CSR_HW_RFID_TYPE(CSR_HW_RF_ID_TYPE_JF))
312                 return -EOPNOTSUPP;
313
314         if (!fw_has_capa(&fwrt->fw->ucode_capa, IWL_UCODE_TLV_CAPA_SET_PPAG)) {
315                 IWL_DEBUG_RADIO(fwrt,
316                                 "PPAG capability not supported by FW, command not sent.\n");
317                 return -EINVAL;
318         }
319
320         cmd_ver = iwl_fw_lookup_cmd_ver(fwrt->fw,
321                                         WIDE_ID(PHY_OPS_GROUP,
322                                                 PER_PLATFORM_ANT_GAIN_CMD), 1);
323         /*
324          * Starting from ver 4, driver needs to send the PPAG CMD regardless
325          * if PPAG is enabled/disabled or valid/invalid.
326          */
327         send_ppag_always = cmd_ver > 3;
328
329         /* Don't send PPAG if it is disabled */
330         if (!send_ppag_always && !fwrt->ppag_flags) {
331                 IWL_DEBUG_RADIO(fwrt, "PPAG not enabled, command not sent.\n");
332                 return -EINVAL;
333         }
334
335         /* The 'flags' field is the same in v1 and in v2 so we can just
336          * use v1 to access it.
337          */
338         cmd->v1.flags = cpu_to_le32(fwrt->ppag_flags);
339
340         IWL_DEBUG_RADIO(fwrt, "PPAG cmd ver is %d\n", cmd_ver);
341         if (cmd_ver == 1) {
342                 num_sub_bands = IWL_NUM_SUB_BANDS_V1;
343                 gain = cmd->v1.gain[0];
344                 *cmd_size = sizeof(cmd->v1);
345                 if (fwrt->ppag_ver >= 1) {
346                         /* in this case FW supports revision 0 */
347                         IWL_DEBUG_RADIO(fwrt,
348                                         "PPAG table rev is %d, send truncated table\n",
349                                         fwrt->ppag_ver);
350                 }
351         } else if (cmd_ver >= 2 && cmd_ver <= 6) {
352                 num_sub_bands = IWL_NUM_SUB_BANDS_V2;
353                 gain = cmd->v2.gain[0];
354                 *cmd_size = sizeof(cmd->v2);
355                 if (fwrt->ppag_ver == 0) {
356                         /* in this case FW supports revisions 1,2 or 3 */
357                         IWL_DEBUG_RADIO(fwrt,
358                                         "PPAG table rev is 0, send padded table\n");
359                 }
360         } else {
361                 IWL_DEBUG_RADIO(fwrt, "Unsupported PPAG command version\n");
362                 return -EINVAL;
363         }
364
365         /* ppag mode */
366         IWL_DEBUG_RADIO(fwrt,
367                         "PPAG MODE bits were read from bios: %d\n",
368                         le32_to_cpu(cmd->v1.flags));
369
370         if (cmd_ver == 5)
371                 cmd->v1.flags &= cpu_to_le32(IWL_PPAG_CMD_V5_MASK);
372         else if (cmd_ver < 5)
373                 cmd->v1.flags &= cpu_to_le32(IWL_PPAG_CMD_V4_MASK);
374
375         if ((cmd_ver == 1 &&
376              !fw_has_capa(&fwrt->fw->ucode_capa,
377                           IWL_UCODE_TLV_CAPA_PPAG_CHINA_BIOS_SUPPORT)) ||
378             (cmd_ver == 2 && fwrt->ppag_ver >= 2)) {
379                 cmd->v1.flags &= cpu_to_le32(IWL_PPAG_ETSI_MASK);
380                 IWL_DEBUG_RADIO(fwrt, "masking ppag China bit\n");
381         } else {
382                 IWL_DEBUG_RADIO(fwrt, "isn't masking ppag China bit\n");
383         }
384
385         IWL_DEBUG_RADIO(fwrt,
386                         "PPAG MODE bits going to be sent: %d\n",
387                         le32_to_cpu(cmd->v1.flags));
388
389         for (i = 0; i < IWL_NUM_CHAIN_LIMITS; i++) {
390                 for (j = 0; j < num_sub_bands; j++) {
391                         if (!send_ppag_always &&
392                             !iwl_ppag_value_valid(fwrt, i, j))
393                                 return -EINVAL;
394
395                         gain[i * num_sub_bands + j] =
396                                 fwrt->ppag_chains[i].subbands[j];
397                         IWL_DEBUG_RADIO(fwrt,
398                                         "PPAG table: chain[%d] band[%d]: gain = %d\n",
399                                         i, j, gain[i * num_sub_bands + j]);
400                 }
401         }
402
403         return 0;
404 }
405 IWL_EXPORT_SYMBOL(iwl_fill_ppag_table);
406
407 bool iwl_is_ppag_approved(struct iwl_fw_runtime *fwrt)
408 {
409         if (!dmi_check_system(dmi_ppag_approved_list)) {
410                 IWL_DEBUG_RADIO(fwrt,
411                                 "System vendor '%s' is not in the approved list, disabling PPAG.\n",
412                                 dmi_get_system_info(DMI_SYS_VENDOR) ?: "<unknown>");
413                 fwrt->ppag_flags = 0;
414                 return false;
415         }
416
417         return true;
418 }
419 IWL_EXPORT_SYMBOL(iwl_is_ppag_approved);
420
421 bool iwl_is_tas_approved(void)
422 {
423         return dmi_check_system(dmi_tas_approved_list);
424 }
425 IWL_EXPORT_SYMBOL(iwl_is_tas_approved);
426
427 int iwl_parse_tas_selection(struct iwl_fw_runtime *fwrt,
428                             struct iwl_tas_data *tas_data,
429                             const u32 tas_selection)
430 {
431         u8 override_iec = u32_get_bits(tas_selection,
432                                        IWL_WTAS_OVERRIDE_IEC_MSK);
433         u8 enabled_iec = u32_get_bits(tas_selection, IWL_WTAS_ENABLE_IEC_MSK);
434         u8 usa_tas_uhb = u32_get_bits(tas_selection, IWL_WTAS_USA_UHB_MSK);
435         int enabled = tas_selection & IWL_WTAS_ENABLED_MSK;
436
437         IWL_DEBUG_RADIO(fwrt, "TAS selection as read from BIOS: 0x%x\n",
438                         tas_selection);
439
440         tas_data->usa_tas_uhb_allowed = usa_tas_uhb;
441         tas_data->override_tas_iec = override_iec;
442         tas_data->enable_tas_iec = enabled_iec;
443
444         return enabled;
445 }
446
447 static __le32 iwl_get_lari_config_bitmap(struct iwl_fw_runtime *fwrt)
448 {
449         int ret;
450         u32 val;
451         __le32 config_bitmap = 0;
452
453         switch (CSR_HW_RFID_TYPE(fwrt->trans->hw_rf_id)) {
454         case IWL_CFG_RF_TYPE_HR1:
455         case IWL_CFG_RF_TYPE_HR2:
456         case IWL_CFG_RF_TYPE_JF1:
457         case IWL_CFG_RF_TYPE_JF2:
458                 ret = iwl_bios_get_dsm(fwrt, DSM_FUNC_ENABLE_INDONESIA_5G2,
459                                        &val);
460
461                 if (!ret && val == DSM_VALUE_INDONESIA_ENABLE)
462                         config_bitmap |=
463                             cpu_to_le32(LARI_CONFIG_ENABLE_5G2_IN_INDONESIA_MSK);
464                 break;
465         default:
466                 break;
467         }
468
469         ret = iwl_bios_get_dsm(fwrt, DSM_FUNC_DISABLE_SRD, &val);
470         if (!ret) {
471                 if (val == DSM_VALUE_SRD_PASSIVE)
472                         config_bitmap |=
473                                 cpu_to_le32(LARI_CONFIG_CHANGE_ETSI_TO_PASSIVE_MSK);
474                 else if (val == DSM_VALUE_SRD_DISABLE)
475                         config_bitmap |=
476                                 cpu_to_le32(LARI_CONFIG_CHANGE_ETSI_TO_DISABLED_MSK);
477         }
478
479         if (fw_has_capa(&fwrt->fw->ucode_capa,
480                         IWL_UCODE_TLV_CAPA_CHINA_22_REG_SUPPORT)) {
481                 ret = iwl_bios_get_dsm(fwrt, DSM_FUNC_REGULATORY_CONFIG,
482                                        &val);
483                 /*
484                  * China 2022 enable if the BIOS object does not exist or
485                  * if it is enabled in BIOS.
486                  */
487                 if (ret < 0 || val & DSM_MASK_CHINA_22_REG)
488                         config_bitmap |=
489                                 cpu_to_le32(LARI_CONFIG_ENABLE_CHINA_22_REG_SUPPORT_MSK);
490         }
491
492         return config_bitmap;
493 }
494
495 static size_t iwl_get_lari_config_cmd_size(u8 cmd_ver)
496 {
497         size_t cmd_size;
498
499         switch (cmd_ver) {
500         case 12:
501         case 11:
502                 cmd_size = sizeof(struct iwl_lari_config_change_cmd);
503                 break;
504         case 10:
505                 cmd_size = sizeof(struct iwl_lari_config_change_cmd_v10);
506                 break;
507         case 9:
508         case 8:
509         case 7:
510                 cmd_size = sizeof(struct iwl_lari_config_change_cmd_v7);
511                 break;
512         case 6:
513                 cmd_size = sizeof(struct iwl_lari_config_change_cmd_v6);
514                 break;
515         case 5:
516                 cmd_size = sizeof(struct iwl_lari_config_change_cmd_v5);
517                 break;
518         case 4:
519                 cmd_size = sizeof(struct iwl_lari_config_change_cmd_v4);
520                 break;
521         case 3:
522                 cmd_size = sizeof(struct iwl_lari_config_change_cmd_v3);
523                 break;
524         case 2:
525                 cmd_size = sizeof(struct iwl_lari_config_change_cmd_v2);
526                 break;
527         default:
528                 cmd_size = sizeof(struct iwl_lari_config_change_cmd_v1);
529                 break;
530         }
531         return cmd_size;
532 }
533
534 int iwl_fill_lari_config(struct iwl_fw_runtime *fwrt,
535                          struct iwl_lari_config_change_cmd *cmd,
536                          size_t *cmd_size)
537 {
538         int ret;
539         u32 value;
540         u8 cmd_ver = iwl_fw_lookup_cmd_ver(fwrt->fw,
541                                            WIDE_ID(REGULATORY_AND_NVM_GROUP,
542                                                    LARI_CONFIG_CHANGE), 1);
543
544         memset(cmd, 0, sizeof(*cmd));
545         *cmd_size = iwl_get_lari_config_cmd_size(cmd_ver);
546
547         cmd->config_bitmap = iwl_get_lari_config_bitmap(fwrt);
548
549         ret = iwl_bios_get_dsm(fwrt, DSM_FUNC_11AX_ENABLEMENT, &value);
550         if (!ret)
551                 cmd->oem_11ax_allow_bitmap = cpu_to_le32(value);
552
553         ret = iwl_bios_get_dsm(fwrt, DSM_FUNC_ENABLE_UNII4_CHAN, &value);
554         if (!ret) {
555                 if (cmd_ver < 9)
556                         value &= DSM_UNII4_ALLOW_BITMAP_CMD_V8;
557                 else
558                         value &= DSM_UNII4_ALLOW_BITMAP;
559
560                 cmd->oem_unii4_allow_bitmap = cpu_to_le32(value);
561         }
562
563         ret = iwl_bios_get_dsm(fwrt, DSM_FUNC_ACTIVATE_CHANNEL, &value);
564         if (!ret) {
565                 if (cmd_ver < 8)
566                         value &= ~ACTIVATE_5G2_IN_WW_MASK;
567                 if (cmd_ver < 12)
568                         value &= CHAN_STATE_ACTIVE_BITMAP_CMD_V11;
569
570                 cmd->chan_state_active_bitmap = cpu_to_le32(value);
571         }
572
573         ret = iwl_bios_get_dsm(fwrt, DSM_FUNC_ENABLE_6E, &value);
574         if (!ret)
575                 cmd->oem_uhb_allow_bitmap = cpu_to_le32(value);
576
577         ret = iwl_bios_get_dsm(fwrt, DSM_FUNC_FORCE_DISABLE_CHANNELS, &value);
578         if (!ret)
579                 cmd->force_disable_channels_bitmap = cpu_to_le32(value);
580
581         ret = iwl_bios_get_dsm(fwrt, DSM_FUNC_ENERGY_DETECTION_THRESHOLD,
582                                &value);
583         if (!ret)
584                 cmd->edt_bitmap = cpu_to_le32(value);
585
586         ret = iwl_bios_get_wbem(fwrt, &value);
587         if (!ret)
588                 cmd->oem_320mhz_allow_bitmap = cpu_to_le32(value);
589
590         ret = iwl_bios_get_dsm(fwrt, DSM_FUNC_ENABLE_11BE, &value);
591         if (!ret)
592                 cmd->oem_11be_allow_bitmap = cpu_to_le32(value);
593
594         if (cmd->config_bitmap ||
595             cmd->oem_uhb_allow_bitmap ||
596             cmd->oem_11ax_allow_bitmap ||
597             cmd->oem_unii4_allow_bitmap ||
598             cmd->chan_state_active_bitmap ||
599             cmd->force_disable_channels_bitmap ||
600             cmd->edt_bitmap ||
601             cmd->oem_320mhz_allow_bitmap ||
602             cmd->oem_11be_allow_bitmap) {
603                 IWL_DEBUG_RADIO(fwrt,
604                                 "sending LARI_CONFIG_CHANGE, config_bitmap=0x%x, oem_11ax_allow_bitmap=0x%x\n",
605                                 le32_to_cpu(cmd->config_bitmap),
606                                 le32_to_cpu(cmd->oem_11ax_allow_bitmap));
607                 IWL_DEBUG_RADIO(fwrt,
608                                 "sending LARI_CONFIG_CHANGE, oem_unii4_allow_bitmap=0x%x, chan_state_active_bitmap=0x%x, cmd_ver=%d\n",
609                                 le32_to_cpu(cmd->oem_unii4_allow_bitmap),
610                                 le32_to_cpu(cmd->chan_state_active_bitmap),
611                                 cmd_ver);
612                 IWL_DEBUG_RADIO(fwrt,
613                                 "sending LARI_CONFIG_CHANGE, oem_uhb_allow_bitmap=0x%x, force_disable_channels_bitmap=0x%x\n",
614                                 le32_to_cpu(cmd->oem_uhb_allow_bitmap),
615                                 le32_to_cpu(cmd->force_disable_channels_bitmap));
616                 IWL_DEBUG_RADIO(fwrt,
617                                 "sending LARI_CONFIG_CHANGE, edt_bitmap=0x%x, oem_320mhz_allow_bitmap=0x%x\n",
618                                 le32_to_cpu(cmd->edt_bitmap),
619                                 le32_to_cpu(cmd->oem_320mhz_allow_bitmap));
620                 IWL_DEBUG_RADIO(fwrt,
621                                 "sending LARI_CONFIG_CHANGE, oem_11be_allow_bitmap=0x%x\n",
622                                 le32_to_cpu(cmd->oem_11be_allow_bitmap));
623         } else {
624                 return 1;
625         }
626
627         return 0;
628 }
629 IWL_EXPORT_SYMBOL(iwl_fill_lari_config);
630
631 int iwl_bios_get_dsm(struct iwl_fw_runtime *fwrt, enum iwl_dsm_funcs func,
632                      u32 *value)
633 {
634         GET_BIOS_TABLE(dsm, fwrt, func, value);
635 }
636 IWL_EXPORT_SYMBOL(iwl_bios_get_dsm);
637
638 bool iwl_puncturing_is_allowed_in_bios(u32 puncturing, u16 mcc)
639 {
640         /* Some kind of regulatory mess means we need to currently disallow
641          * puncturing in the US and Canada unless enabled in BIOS.
642          */
643         switch (mcc) {
644         case IWL_MCC_US:
645                 return puncturing & IWL_UEFI_CNV_PUNCTURING_USA_EN_MSK;
646         case IWL_MCC_CANADA:
647                 return puncturing & IWL_UEFI_CNV_PUNCTURING_CANADA_EN_MSK;
648         default:
649                 return true;
650         }
651 }
652 IWL_EXPORT_SYMBOL(iwl_puncturing_is_allowed_in_bios);
This page took 0.065922 seconds and 4 git commands to generate.