@@ -429,38 +429,28 @@ int iwl_acpi_get_eckv(struct iwl_fw_runtime *fwrt, u32 *extl_clk)
429
429
return ret ;
430
430
}
431
431
432
- static int iwl_acpi_sar_set_profile ( union acpi_object * table ,
433
- struct iwl_sar_profile * profile ,
434
- bool enabled , u8 num_chains ,
435
- u8 num_sub_bands )
432
+ static int
433
+ iwl_acpi_parse_chains_table ( union acpi_object * table ,
434
+ struct iwl_sar_profile_chain * chains ,
435
+ u8 num_chains , u8 num_sub_bands )
436
436
{
437
- int i , j , idx = 0 ;
438
-
439
- /*
440
- * The table from ACPI is flat, but we store it in a
441
- * structured array.
442
- */
443
- for (i = 0 ; i < BIOS_SAR_MAX_CHAINS_PER_PROFILE ; i ++ ) {
444
- for (j = 0 ; j < BIOS_SAR_MAX_SUB_BANDS_NUM ; j ++ ) {
437
+ for (u8 chain = 0 ; chain < num_chains ; chain ++ ) {
438
+ for (u8 subband = 0 ; subband < BIOS_SAR_MAX_SUB_BANDS_NUM ;
439
+ subband ++ ) {
445
440
/* if we don't have the values, use the default */
446
- if (i >= num_chains || j >= num_sub_bands ) {
447
- profile -> chains [i ].subbands [j ] = 0 ;
441
+ if (subband >= num_sub_bands ) {
442
+ chains [chain ].subbands [subband ] = 0 ;
443
+ } else if (table -> type != ACPI_TYPE_INTEGER ||
444
+ table -> integer .value > U8_MAX ) {
445
+ return - EINVAL ;
448
446
} else {
449
- if (table [idx ].type != ACPI_TYPE_INTEGER ||
450
- table [idx ].integer .value > U8_MAX )
451
- return - EINVAL ;
452
-
453
- profile -> chains [i ].subbands [j ] =
454
- table [idx ].integer .value ;
455
-
456
- idx ++ ;
447
+ chains [chain ].subbands [subband ] =
448
+ table -> integer .value ;
449
+ table ++ ;
457
450
}
458
451
}
459
452
}
460
453
461
- /* Only if all values were valid can the profile be enabled */
462
- profile -> enabled = enabled ;
463
-
464
454
return 0 ;
465
455
}
466
456
@@ -543,9 +533,11 @@ int iwl_acpi_get_wrds_table(struct iwl_fw_runtime *fwrt)
543
533
/* The profile from WRDS is officially profile 1, but goes
544
534
* into sar_profiles[0] (because we don't have a profile 0).
545
535
*/
546
- ret = iwl_acpi_sar_set_profile (table , & fwrt -> sar_profiles [0 ],
547
- flags & IWL_SAR_ENABLE_MSK ,
548
- num_chains , num_sub_bands );
536
+ ret = iwl_acpi_parse_chains_table (table , fwrt -> sar_profiles [0 ].chains ,
537
+ num_chains , num_sub_bands );
538
+ if (!ret && flags & IWL_SAR_ENABLE_MSK )
539
+ fwrt -> sar_profiles [0 ].enabled = true;
540
+
549
541
out_free :
550
542
kfree (data );
551
543
return ret ;
@@ -557,7 +549,7 @@ int iwl_acpi_get_ewrd_table(struct iwl_fw_runtime *fwrt)
557
549
bool enabled ;
558
550
int i , n_profiles , tbl_rev , pos ;
559
551
int ret = 0 ;
560
- u8 num_chains , num_sub_bands ;
552
+ u8 num_sub_bands ;
561
553
562
554
data = iwl_acpi_get_object (fwrt -> dev , ACPI_EWRD_METHOD );
563
555
if (IS_ERR (data ))
@@ -573,7 +565,6 @@ int iwl_acpi_get_ewrd_table(struct iwl_fw_runtime *fwrt)
573
565
goto out_free ;
574
566
}
575
567
576
- num_chains = ACPI_SAR_NUM_CHAINS_REV2 ;
577
568
num_sub_bands = ACPI_SAR_NUM_SUB_BANDS_REV2 ;
578
569
579
570
goto read_table ;
@@ -589,7 +580,6 @@ int iwl_acpi_get_ewrd_table(struct iwl_fw_runtime *fwrt)
589
580
goto out_free ;
590
581
}
591
582
592
- num_chains = ACPI_SAR_NUM_CHAINS_REV1 ;
593
583
num_sub_bands = ACPI_SAR_NUM_SUB_BANDS_REV1 ;
594
584
595
585
goto read_table ;
@@ -605,7 +595,6 @@ int iwl_acpi_get_ewrd_table(struct iwl_fw_runtime *fwrt)
605
595
goto out_free ;
606
596
}
607
597
608
- num_chains = ACPI_SAR_NUM_CHAINS_REV0 ;
609
598
num_sub_bands = ACPI_SAR_NUM_SUB_BANDS_REV0 ;
610
599
611
600
goto read_table ;
@@ -637,23 +626,54 @@ int iwl_acpi_get_ewrd_table(struct iwl_fw_runtime *fwrt)
637
626
/* the tables start at element 3 */
638
627
pos = 3 ;
639
628
629
+ BUILD_BUG_ON (ACPI_SAR_NUM_CHAINS_REV0 != ACPI_SAR_NUM_CHAINS_REV1 );
630
+ BUILD_BUG_ON (ACPI_SAR_NUM_CHAINS_REV2 != 2 * ACPI_SAR_NUM_CHAINS_REV0 );
631
+
632
+ /* parse non-cdb chains for all profiles */
640
633
for (i = 0 ; i < n_profiles ; i ++ ) {
641
634
union acpi_object * table = & wifi_pkg -> package .elements [pos ];
635
+
642
636
/* The EWRD profiles officially go from 2 to 4, but we
643
637
* save them in sar_profiles[1-3] (because we don't
644
638
* have profile 0). So in the array we start from 1.
645
639
*/
646
- ret = iwl_acpi_sar_set_profile (table ,
647
- & fwrt -> sar_profiles [i + 1 ],
648
- enabled , num_chains ,
649
- num_sub_bands );
640
+ ret = iwl_acpi_parse_chains_table (table ,
641
+ fwrt -> sar_profiles [i + 1 ]. chains ,
642
+ ACPI_SAR_NUM_CHAINS_REV0 ,
643
+ num_sub_bands );
650
644
if (ret < 0 )
651
- break ;
645
+ goto out_free ;
652
646
653
647
/* go to the next table */
654
- pos += num_chains * num_sub_bands ;
648
+ pos += ACPI_SAR_NUM_CHAINS_REV0 * num_sub_bands ;
655
649
}
656
650
651
+ /* non-cdb table revisions */
652
+ if (tbl_rev < 2 )
653
+ goto set_enabled ;
654
+
655
+ /* parse cdb chains for all profiles */
656
+ for (i = 0 ; i < n_profiles ; i ++ ) {
657
+ struct iwl_sar_profile_chain * chains ;
658
+ union acpi_object * table ;
659
+
660
+ table = & wifi_pkg -> package .elements [pos ];
661
+ chains = & fwrt -> sar_profiles [i + 1 ].chains [ACPI_SAR_NUM_CHAINS_REV0 ];
662
+ ret = iwl_acpi_parse_chains_table (table ,
663
+ chains ,
664
+ ACPI_SAR_NUM_CHAINS_REV0 ,
665
+ num_sub_bands );
666
+ if (ret < 0 )
667
+ goto out_free ;
668
+
669
+ /* go to the next table */
670
+ pos += ACPI_SAR_NUM_CHAINS_REV0 * num_sub_bands ;
671
+ }
672
+
673
+ set_enabled :
674
+ for (i = 0 ; i < n_profiles ; i ++ )
675
+ fwrt -> sar_profiles [i + 1 ].enabled = enabled ;
676
+
657
677
out_free :
658
678
kfree (data );
659
679
return ret ;
0 commit comments