RE: [PATCH v1] Bluetooth: btintel: Set Per Platform Antenna Gain(PPAG)

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi Luiz,

> -----Original Message-----
> From: Luiz Augusto von Dentz <luiz.dentz@xxxxxxxxx>
> Sent: Saturday, February 4, 2023 2:38 AM
> To: K, Kiran <kiran.k@xxxxxxxxx>
> Cc: linux-bluetooth@xxxxxxxxxxxxxxx; Srivatsa, Ravishankar
> <ravishankar.srivatsa@xxxxxxxxx>; Singh, Lokendra
> <lokendra.singh@xxxxxxxxx>; Tumkur Narayan, Chethan
> <chethan.tumkur.narayan@xxxxxxxxx>; Sreemantha, Seema
> <seema.sreemantha@xxxxxxxxx>
> Subject: Re: [PATCH v1] Bluetooth: btintel: Set Per Platform Antenna
> Gain(PPAG)
> 
> Hi Kiran, Seema,
> 
> On Fri, Feb 3, 2023 at 1:28 AM Kiran K <kiran.k@xxxxxxxxx> wrote:
> >
> > From: Seema Sreemantha <seema.sreemantha@xxxxxxxxx>
> >
> > Antenna gain is defined as the antenna’s ability to increase the Tx
> > power in a given direction. Intel is certifying its products with
> > fixed reference antenna peak gain values (3/5dBi). The feature takes
> > into account the actual antenna gain, and increases output power
> > values, which results in a performance improvement.
> >
> > After firmware download is completed, driver reads from ACPI table and
> > configures PPAG as required. ACPI table entry for PPAG is defined as
> > below.
> >
> > Name (PPAG, Package (0x02)
> > {
> >     0x00000001,
> >     Package (0x02)
> >     {
> >         0x00000012, /* Bluetooth Domain */
> >         0x00000001  /* 1 - Enable PPAG, 0 - Disable PPAG */
> >     }
> > })
> >
> > btmon log:
> >
> > < HCI Command: Vendor (0x3f|0x0219) plen 12
> >     00 00 00 00 00 00 00 00 00 00 00 00
> > > HCI Event: Command Complete (0x0e) plen 4
> >     Vendor (0x3f|0x0219) ncmd 1
> >     Status: Success (0x00)
> 
> It would have been better if you guys had added a decoder for it.

Ack. I will publish the patch for the same. 
> 
> > Signed-off-by: Kiran K <kiran.k@xxxxxxxxx>
> > Signed-off-by: Seema Sreemantha <seema.sreemantha@xxxxxxxxx>
> > ---
> >  drivers/bluetooth/btintel.c | 114
> > ++++++++++++++++++++++++++++++++++++
> >  drivers/bluetooth/btintel.h |  13 ++++
> >  2 files changed, 127 insertions(+)
> >
> > diff --git a/drivers/bluetooth/btintel.c b/drivers/bluetooth/btintel.c
> > index d4e2cb9a4eb4..4d6d0dc10caa 100644
> > --- a/drivers/bluetooth/btintel.c
> > +++ b/drivers/bluetooth/btintel.c
> > @@ -9,6 +9,7 @@
> >  #include <linux/module.h>
> >  #include <linux/firmware.h>
> >  #include <linux/regmap.h>
> > +#include <linux/acpi.h>
> >  #include <asm/unaligned.h>
> >
> >  #include <net/bluetooth/bluetooth.h>
> > @@ -24,6 +25,9 @@
> >  #define ECDSA_OFFSET           644
> >  #define ECDSA_HEADER_LEN       320
> >
> > +#define BTINTEL_PPAG_NAME   "PPAG"
> > +#define BTINTEL_PPAG_PREFIX "\\_SB_.PCI0.XHCI.RHUB"
> > +
> >  #define CMD_WRITE_BOOT_PARAMS  0xfc0e  struct
> cmd_write_boot_params {
> >         __le32 boot_addr;
> > @@ -1278,6 +1282,63 @@ static int btintel_read_debug_features(struct
> hci_dev *hdev,
> >         return 0;
> >  }
> >
> > +static acpi_status btintel_ppag_callback(acpi_handle handle, u32 lvl, void
> *data,
> > +                                        void **ret) {
> > +       acpi_status status;
> > +       size_t len;
> > +       struct btintel_ppag *ppag;
> 
> You can probably just assign ppag = data above;
> 
> > +       union acpi_object *p, *elements;
> > +       struct acpi_buffer string = {ACPI_ALLOCATE_BUFFER, NULL};
> > +       struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL};
> > +       struct hci_dev *hdev = ((struct btintel_ppag *)data)->hdev;
> 
> Then use hdev = ppga->hdev
> 
Ack.

> > +
> > +       status = acpi_get_name(handle, ACPI_FULL_PATHNAME, &string);
> > +       if (ACPI_FAILURE(status)) {
> > +               bt_dev_warn(hdev, "ACPI Failure: %s",
> acpi_format_exception(status));
> > +               return status;
> > +       }
> > +
> > +       if (strncmp(BTINTEL_PPAG_PREFIX, string.pointer,
> > +                   strlen(BTINTEL_PPAG_PREFIX))) {
> > +               kfree(string.pointer);
> > +               return AE_OK;
> > +       }
> > +
> > +       len = strlen(string.pointer);
> > +       if (strncmp((char *)string.pointer + len - 4, BTINTEL_PPAG_NAME, 4)) {
> > +               kfree(string.pointer);
> > +               return AE_OK;
> > +       }
> > +       kfree(string.pointer);
> > +
> > +       status = acpi_evaluate_object(handle, NULL, NULL, &buffer);
> > +       if (ACPI_FAILURE(status)) {
> > +               bt_dev_warn(hdev, "ACPI Failure: %s",
> acpi_format_exception(status));
> > +               return status;
> > +       }
> > +
> > +       p = buffer.pointer;
> > +       ppag = (struct btintel_ppag *)data;
> > +
> > +       if (p->type != ACPI_TYPE_PACKAGE || p->package.count != 2) {
> > +               kfree(buffer.pointer);
> > +               bt_dev_warn(hdev, "Invalid object type: %d or package count:
> %d",
> > +                           p->type, p->package.count);
> > +               return AE_ERROR;
> > +       }
> > +
> > +       elements = p->package.elements;
> > +
> > +       /* PPAG table is located at element[1] */
> > +       p = &elements[1];
> > +
> > +       ppag->domain = (u32)p->package.elements[0].integer.value;
> > +       ppag->mode = (u32)p->package.elements[1].integer.value;
> > +       kfree(buffer.pointer);
> > +       return AE_CTRL_TERMINATE;
> > +}
> > +
> >  static int btintel_set_debug_features(struct hci_dev *hdev,
> >                                const struct intel_debug_features
> > *features)  { @@ -2251,6 +2312,56 @@ static int
> > btintel_configure_offload(struct hci_dev *hdev)
> >         return err;
> >  }
> >
> > +static int btintel_set_ppag(struct hci_dev *hdev, struct
> > +intel_version_tlv *ver) {
> > +       acpi_status status;
> > +       struct btintel_ppag ppag;
> > +       struct sk_buff *skb;
> > +       struct btintel_loc_aware_reg ppag_cmd;
> > +
> > +    /* PPAG is not supported if CRF is HrP2, Jfp2, JfP1 */
> > +       switch (ver->cnvr_top & 0xFFF) {
> > +       case 0x504:     /* Hrp2 */
> > +       case 0x202:     /* Jfp2 */
> > +       case 0x201:     /* Jfp1 */
> > +               return 0;
> > +       }
> > +
> > +       memset(&ppag, 0, sizeof(ppag));
> > +
> > +       ppag.hdev = hdev;
> > +       status = acpi_walk_namespace(ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
> > +                                    ACPI_UINT32_MAX, NULL,
> > +                                    btintel_ppag_callback, &ppag,
> > + NULL);
> > +
> > +       if (ACPI_FAILURE(status)) {
> > +               bt_dev_warn(hdev, "PPAG: ACPI Failure: %s",
> > + acpi_format_exception(status));
> 
> Shouldn't we consider it ok if the ACPI doesn't have an entry? I mean it
> should be possible to plug a new controller in an old laptop that possibly
> doesn't have this entry, right?
> 
Ack. Older platform won't support this feature.
> > +               return -1;
> > +       }
> > +
> > +       if (ppag.domain != 0x12) {
> > +               bt_dev_warn(hdev, "PPAG-BT Domain disabled");
> > +               return -1;
> > +       }
> > +
> > +       /* PPAG mode, BIT0 = 0 Disabled, BIT0 = 1 Enabled */
> > +       if (!(ppag.mode & BIT(0))) {
> > +               bt_dev_dbg(hdev, "PPAG disabled");
> > +               return 0;
> > +       }
> > +
> > +       ppag_cmd.mcc = 0;
> > +       ppag_cmd.sel = 0; /* 0 - Operational, 1 - Disable, 2 - Testing mode */
> > +       ppag_cmd.delta = 0;
> > +       skb = __hci_cmd_sync(hdev, 0xfe19, sizeof(ppag_cmd), &ppag_cmd,
> HCI_CMD_TIMEOUT);
> > +       if (IS_ERR(skb)) {
> > +               bt_dev_warn(hdev, "Failed to send PPAG Enable (%ld)",
> PTR_ERR(skb));
> > +               return PTR_ERR(skb);
> > +       }
> > +       kfree_skb(skb);
> > +       return 0;
> > +}
> > +
> >  static int btintel_bootloader_setup_tlv(struct hci_dev *hdev,
> >                                         struct intel_version_tlv *ver)
> > { @@ -2297,6 +2408,9 @@ static int btintel_bootloader_setup_tlv(struct
> > hci_dev *hdev,
> >
> >         hci_dev_clear_flag(hdev, HCI_QUALITY_REPORT);
> >
> > +       /* Set PPAG feature */
> > +       btintel_set_ppag(hdev, ver);
> 
> Looks like you are not using the return above which I guess is fine since this
> step can be considered optional but I'd document it as such and probably
> make btintel_set_ppag return void as it shouldn't be considered as an error if
> it fails.
Ack. 
> 
> > +
....

Thanks,
Kiran





[Index of Archives]     [Bluez Devel]     [Linux Wireless Networking]     [Linux Wireless Personal Area Networking]     [Linux ATH6KL]     [Linux USB Devel]     [Linux Media Drivers]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Big List of Linux Books]

  Powered by Linux