@@ -429,38 +429,28 @@ int iwl_acpi_get_eckv(struct iwl_fw_runtime *fwrt, u32 *extl_clk)
429429 return ret ;
430430}
431431
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 )
436436{
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 ++ ) {
445440 /* 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 ;
448446 } 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 ++ ;
457450 }
458451 }
459452 }
460453
461- /* Only if all values were valid can the profile be enabled */
462- profile -> enabled = enabled ;
463-
464454 return 0 ;
465455}
466456
@@ -543,9 +533,11 @@ int iwl_acpi_get_wrds_table(struct iwl_fw_runtime *fwrt)
543533 /* The profile from WRDS is officially profile 1, but goes
544534 * into sar_profiles[0] (because we don't have a profile 0).
545535 */
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+
549541out_free :
550542 kfree (data );
551543 return ret ;
@@ -557,7 +549,7 @@ int iwl_acpi_get_ewrd_table(struct iwl_fw_runtime *fwrt)
557549 bool enabled ;
558550 int i , n_profiles , tbl_rev , pos ;
559551 int ret = 0 ;
560- u8 num_chains , num_sub_bands ;
552+ u8 num_sub_bands ;
561553
562554 data = iwl_acpi_get_object (fwrt -> dev , ACPI_EWRD_METHOD );
563555 if (IS_ERR (data ))
@@ -573,7 +565,6 @@ int iwl_acpi_get_ewrd_table(struct iwl_fw_runtime *fwrt)
573565 goto out_free ;
574566 }
575567
576- num_chains = ACPI_SAR_NUM_CHAINS_REV2 ;
577568 num_sub_bands = ACPI_SAR_NUM_SUB_BANDS_REV2 ;
578569
579570 goto read_table ;
@@ -589,7 +580,6 @@ int iwl_acpi_get_ewrd_table(struct iwl_fw_runtime *fwrt)
589580 goto out_free ;
590581 }
591582
592- num_chains = ACPI_SAR_NUM_CHAINS_REV1 ;
593583 num_sub_bands = ACPI_SAR_NUM_SUB_BANDS_REV1 ;
594584
595585 goto read_table ;
@@ -605,7 +595,6 @@ int iwl_acpi_get_ewrd_table(struct iwl_fw_runtime *fwrt)
605595 goto out_free ;
606596 }
607597
608- num_chains = ACPI_SAR_NUM_CHAINS_REV0 ;
609598 num_sub_bands = ACPI_SAR_NUM_SUB_BANDS_REV0 ;
610599
611600 goto read_table ;
@@ -637,23 +626,54 @@ int iwl_acpi_get_ewrd_table(struct iwl_fw_runtime *fwrt)
637626 /* the tables start at element 3 */
638627 pos = 3 ;
639628
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 */
640633 for (i = 0 ; i < n_profiles ; i ++ ) {
641634 union acpi_object * table = & wifi_pkg -> package .elements [pos ];
635+
642636 /* The EWRD profiles officially go from 2 to 4, but we
643637 * save them in sar_profiles[1-3] (because we don't
644638 * have profile 0). So in the array we start from 1.
645639 */
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 );
650644 if (ret < 0 )
651- break ;
645+ goto out_free ;
652646
653647 /* go to the next table */
654- pos += num_chains * num_sub_bands ;
648+ pos += ACPI_SAR_NUM_CHAINS_REV0 * num_sub_bands ;
655649 }
656650
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+
657677out_free :
658678 kfree (data );
659679 return ret ;
0 commit comments