Skip to content

Commit 7c395ea

Browse files
dwinkler2Johan Hedberg
authored andcommitted
Bluetooth: Query LE tx power on startup
Queries tx power via HCI_LE_Read_Transmit_Power command when the hci device is initialized, and stores resulting min/max LE power in hdev struct. If command isn't available (< BT5 support), min/max values both default to HCI_TX_POWER_INVALID. This patch is manually verified by ensuring BT5 devices correctly query and receive controller tx power range. Reviewed-by: Sonny Sasaka <[email protected]> Signed-off-by: Daniel Winkler <[email protected]> Signed-off-by: Marcel Holtmann <[email protected]> Signed-off-by: Johan Hedberg <[email protected]>
1 parent 9bf9f4b commit 7c395ea

File tree

4 files changed

+35
-0
lines changed

4 files changed

+35
-0
lines changed

include/net/bluetooth/hci.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1797,6 +1797,13 @@ struct hci_cp_le_set_adv_set_rand_addr {
17971797
bdaddr_t bdaddr;
17981798
} __packed;
17991799

1800+
#define HCI_OP_LE_READ_TRANSMIT_POWER 0x204b
1801+
struct hci_rp_le_read_transmit_power {
1802+
__u8 status;
1803+
__s8 min_le_tx_power;
1804+
__s8 max_le_tx_power;
1805+
} __packed;
1806+
18001807
#define HCI_OP_LE_READ_BUFFER_SIZE_V2 0x2060
18011808
struct hci_rp_le_read_buffer_size_v2 {
18021809
__u8 status;

include/net/bluetooth/hci_core.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -384,6 +384,8 @@ struct hci_dev {
384384
__u16 def_page_timeout;
385385
__u16 def_multi_adv_rotation_duration;
386386
__u16 def_le_autoconnect_timeout;
387+
__s8 min_le_tx_power;
388+
__s8 max_le_tx_power;
387389

388390
__u16 pkt_type;
389391
__u16 esco_type;

net/bluetooth/hci_core.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -741,6 +741,12 @@ static int hci_init3_req(struct hci_request *req, unsigned long opt)
741741
hci_req_add(req, HCI_OP_LE_READ_ADV_TX_POWER, 0, NULL);
742742
}
743743

744+
if (hdev->commands[38] & 0x80) {
745+
/* Read LE Min/Max Tx Power*/
746+
hci_req_add(req, HCI_OP_LE_READ_TRANSMIT_POWER,
747+
0, NULL);
748+
}
749+
744750
if (hdev->commands[26] & 0x40) {
745751
/* Read LE White List Size */
746752
hci_req_add(req, HCI_OP_LE_READ_WHITE_LIST_SIZE,
@@ -3660,6 +3666,8 @@ struct hci_dev *hci_alloc_dev(void)
36603666
hdev->le_num_of_adv_sets = HCI_MAX_ADV_INSTANCES;
36613667
hdev->def_multi_adv_rotation_duration = HCI_DEFAULT_ADV_DURATION;
36623668
hdev->def_le_autoconnect_timeout = HCI_LE_AUTOCONN_TIMEOUT;
3669+
hdev->min_le_tx_power = HCI_TX_POWER_INVALID;
3670+
hdev->max_le_tx_power = HCI_TX_POWER_INVALID;
36633671

36643672
hdev->rpa_timeout = HCI_DEFAULT_RPA_TIMEOUT;
36653673
hdev->discov_interleaved_timeout = DISCOV_INTERLEAVED_TIMEOUT;

net/bluetooth/hci_event.c

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1202,6 +1202,20 @@ static void hci_cc_le_set_adv_set_random_addr(struct hci_dev *hdev,
12021202
hci_dev_unlock(hdev);
12031203
}
12041204

1205+
static void hci_cc_le_read_transmit_power(struct hci_dev *hdev,
1206+
struct sk_buff *skb)
1207+
{
1208+
struct hci_rp_le_read_transmit_power *rp = (void *)skb->data;
1209+
1210+
BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
1211+
1212+
if (rp->status)
1213+
return;
1214+
1215+
hdev->min_le_tx_power = rp->min_le_tx_power;
1216+
hdev->max_le_tx_power = rp->max_le_tx_power;
1217+
}
1218+
12051219
static void hci_cc_le_set_adv_enable(struct hci_dev *hdev, struct sk_buff *skb)
12061220
{
12071221
__u8 *sent, status = *((__u8 *) skb->data);
@@ -3582,6 +3596,10 @@ static void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *skb,
35823596
hci_cc_le_set_adv_set_random_addr(hdev, skb);
35833597
break;
35843598

3599+
case HCI_OP_LE_READ_TRANSMIT_POWER:
3600+
hci_cc_le_read_transmit_power(hdev, skb);
3601+
break;
3602+
35853603
default:
35863604
BT_DBG("%s opcode 0x%4.4x", hdev->name, *opcode);
35873605
break;

0 commit comments

Comments
 (0)