Add new API to set max power limits for mAFC

HAL API support for setting max permissible power on a range of
frequencies. Unspecified frequencies will get reverted to their
respective default values.

Also add capability flag for this new API.

Bug: 242917176
Test: make -j128
Test: Manually verified the framework can call the HAL API

Change-Id: I14ac494124b51ca0b85c394eefe6332c4b382d19
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/AvailableAfcFrequencyInfo.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/AvailableAfcFrequencyInfo.aidl
new file mode 100644
index 0000000..cbea5af
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/AvailableAfcFrequencyInfo.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+parcelable AvailableAfcFrequencyInfo {
+  int startFrequencyMhz;
+  int endFrequencyMhz;
+  int maxPsd;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/IWifiChip.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/IWifiChip.aidl
index 2ebe145..fd59888 100644
--- a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/IWifiChip.aidl
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/IWifiChip.aidl
@@ -61,6 +61,7 @@
   android.hardware.wifi.WifiRadioCombinationMatrix getSupportedRadioCombinationsMatrix();
   android.hardware.wifi.WifiChipCapabilities getWifiChipCapabilities();
   android.hardware.wifi.WifiUsableChannel[] getUsableChannels(in android.hardware.wifi.WifiBand band, in android.hardware.wifi.WifiIfaceMode ifaceModeMask, in android.hardware.wifi.IWifiChip.UsableChannelFilter filterMask);
+  void setAfcChannelAllowance(in android.hardware.wifi.AvailableAfcFrequencyInfo[] availableAfcFrequencyInfo);
   void registerEventCallback(in android.hardware.wifi.IWifiChipEventCallback callback);
   void removeApIface(in String ifname);
   void removeIfaceInstanceFromBridgedApIface(in String brIfaceName, in String ifaceInstanceName);
@@ -99,6 +100,7 @@
     SET_LATENCY_MODE = (1 << 12),
     P2P_RAND_MAC = (1 << 13),
     WIGIG = (1 << 14),
+    SET_AFC_CHANNEL_ALLOWANCE = (1 << 15),
   }
   @VintfStability
   parcelable ChipConcurrencyCombinationLimit {
diff --git a/wifi/aidl/android/hardware/wifi/AvailableAfcFrequencyInfo.aidl b/wifi/aidl/android/hardware/wifi/AvailableAfcFrequencyInfo.aidl
new file mode 100644
index 0000000..5de360c
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/AvailableAfcFrequencyInfo.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi;
+
+/**
+ * Defines the maximum permissible power spectral density on a range of
+ * frequencies to support 6Ghz with standard power for AFC.
+ * The format of the data follows spec from the Wi-Fi Alliance AFC System to
+ * AFC Device Interface Specification: AvailableFrequencyInfo object.
+ */
+@VintfStability
+parcelable AvailableAfcFrequencyInfo {
+    /**
+     * Defines the lowest frequency included in this 6Ghz frequency range.
+     */
+    int startFrequencyMhz;
+    /**
+     * Defines the highest frequency included in this 6Ghz frequency range.
+     */
+    int endFrequencyMhz;
+    /**
+     * The maximum permissible EIRP available in any one MHz bin within the
+     * frequency range specified. The limit is expressed as a power spectral
+     * density with units of dBm per MHz.
+     */
+    int maxPsd;
+}
diff --git a/wifi/aidl/android/hardware/wifi/IWifiChip.aidl b/wifi/aidl/android/hardware/wifi/IWifiChip.aidl
index 5ffea56..41ff7e6 100644
--- a/wifi/aidl/android/hardware/wifi/IWifiChip.aidl
+++ b/wifi/aidl/android/hardware/wifi/IWifiChip.aidl
@@ -16,6 +16,7 @@
 
 package android.hardware.wifi;
 
+import android.hardware.wifi.AvailableAfcFrequencyInfo;
 import android.hardware.wifi.IWifiApIface;
 import android.hardware.wifi.IWifiChipEventCallback;
 import android.hardware.wifi.IWifiNanIface;
@@ -105,6 +106,11 @@
          * Chip can operate in the 60GHz band (WiGig chip).
          */
         WIGIG = 1 << 14,
+        /**
+         * Chip supports setting allowed channels along with PSD in 6GHz band
+         * for AFC purposes.
+         */
+        SET_AFC_CHANNEL_ALLOWANCE = 1 << 15,
     }
 
     /**
@@ -835,6 +841,18 @@
     WifiUsableChannel[] getUsableChannels(
             in WifiBand band, in WifiIfaceMode ifaceModeMask, in UsableChannelFilter filterMask);
 
+    /*
+     * Set the max power level the chip is allowed to transmit on for 6Ghz AFC
+     * using an array of AvailableAfcFrequencyInfo. The max power for
+     * frequencies not included in the input frequency ranges will be reset to
+     * their respective default values.
+     * @param availableAfcFrequencyInfo The list of frequency ranges and
+     * corresponding max allowed power.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.ERROR_NOT_SUPPORTED|
+     */
+    void setAfcChannelAllowance(in AvailableAfcFrequencyInfo[] availableAfcFrequencyInfo);
+
     /**
      * Requests notifications of significant events on this chip. Multiple calls
      * to this must register multiple callbacks, each of which must receive all
diff --git a/wifi/aidl/default/wifi_chip.cpp b/wifi/aidl/default/wifi_chip.cpp
index 5597001..6f43e06 100644
--- a/wifi/aidl/default/wifi_chip.cpp
+++ b/wifi/aidl/default/wifi_chip.cpp
@@ -670,6 +670,12 @@
                            in_ifaceModeMask, in_filterMask);
 }
 
+ndk::ScopedAStatus WifiChip::setAfcChannelAllowance(
+        const std::vector<AvailableAfcFrequencyInfo>& availableAfcFrequencyInfo) {
+    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
+                           &WifiChip::setAfcChannelAllowanceInternal, availableAfcFrequencyInfo);
+}
+
 ndk::ScopedAStatus WifiChip::triggerSubsystemRestart() {
     return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
                            &WifiChip::triggerSubsystemRestartInternal);
@@ -1394,6 +1400,12 @@
     return {aidl_usable_channels, ndk::ScopedAStatus::ok()};
 }
 
+ndk::ScopedAStatus WifiChip::setAfcChannelAllowanceInternal(
+        const std::vector<AvailableAfcFrequencyInfo>& availableAfcFrequencyInfo) {
+    LOG(INFO) << "setAfcChannelAllowance is not yet supported " << availableAfcFrequencyInfo.size();
+    return createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED);
+}
+
 std::pair<WifiRadioCombinationMatrix, ndk::ScopedAStatus>
 WifiChip::getSupportedRadioCombinationsMatrixInternal() {
     legacy_hal::wifi_error legacy_status;
diff --git a/wifi/aidl/default/wifi_chip.h b/wifi/aidl/default/wifi_chip.h
index c69c7fe..b552c33 100644
--- a/wifi/aidl/default/wifi_chip.h
+++ b/wifi/aidl/default/wifi_chip.h
@@ -141,6 +141,8 @@
     ndk::ScopedAStatus getUsableChannels(WifiBand in_band, WifiIfaceMode in_ifaceModeMask,
                                          UsableChannelFilter in_filterMask,
                                          std::vector<WifiUsableChannel>* _aidl_return) override;
+    ndk::ScopedAStatus setAfcChannelAllowance(
+            const std::vector<AvailableAfcFrequencyInfo>& availableAfcFrequencyInfo) override;
     ndk::ScopedAStatus triggerSubsystemRestart() override;
     ndk::ScopedAStatus getSupportedRadioCombinationsMatrix(
             WifiRadioCombinationMatrix* _aidl_return) override;
@@ -218,6 +220,8 @@
             WifiBand band, WifiIfaceMode ifaceModeMask, UsableChannelFilter filterMask);
     ndk::ScopedAStatus enableStaChannelForPeerNetworkInternal(
             ChannelCategoryMask channelCategoryEnableFlag);
+    ndk::ScopedAStatus setAfcChannelAllowanceInternal(
+            const std::vector<AvailableAfcFrequencyInfo>& availableAfcFrequencyInfo);
     ndk::ScopedAStatus handleChipConfiguration(std::unique_lock<std::recursive_mutex>* lock,
                                                int32_t mode_id);
     ndk::ScopedAStatus registerDebugRingBufferCallback();