diff mbox series

[6/6] Bluetooth: Add MGMT command for controller capabilities

Message ID 20200916131430.6.I5068c01cae3cea674a96e103a0cf4d8c81425a4f@changeid
State Awaiting Upstream
Delegated to: David Miller
Headers show
Series [1/6] Bluetooth: Add helper to set adv data | expand

Commit Message

Daniel Winkler Sept. 16, 2020, 8:16 p.m. UTC
For advertising, we wish to know the LE tx power capabilities of the
controller in userspace, so this patch adds a new MGMT command to query
controller capabilities. The data returned is in TLV format, so it can
be easily used to convey any data determined to be useful in the future,
but for now it simply contains LE min and max tx power.

The change was tested by manually verifying that the new MGMT command
returns the tx power range as expected in userspace.

Reviewed-by: Sonny Sasaka <sonnysasaka@chromium.org>
Signed-off-by: Daniel Winkler <danielwinkler@google.com>
---

 include/net/bluetooth/mgmt.h |  9 +++++++++
 net/bluetooth/mgmt.c         | 39 ++++++++++++++++++++++++++++++++++++
 2 files changed, 48 insertions(+)

Comments

kernel test robot Sept. 17, 2020, 7:18 a.m. UTC | #1
Hi Daniel,

Thank you for the patch! Perhaps something to improve:

[auto build test WARNING on bluetooth-next/master]
[also build test WARNING on next-20200916]
[cannot apply to net-next/master net/master v5.9-rc5]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/0day-ci/linux/commits/Daniel-Winkler/Bluetooth-Add-new-MGMT-interface-for-advertising-add/20200917-042141
base:   https://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth-next.git master
config: x86_64-randconfig-s022-20200917 (attached as .config)
compiler: gcc-9 (Debian 9.3.0-15) 9.3.0
reproduce:
        # apt-get install sparse
        # sparse version: v0.6.2-201-g24bdaac6-dirty
        # save the attached .config to linux build tree
        make W=1 C=1 CF='-fdiagnostic-prefix -D__CHECK_ENDIAN__' ARCH=x86_64 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>


sparse warnings: (new ones prefixed by >>)

   net/bluetooth/mgmt.c:3647:29: sparse: sparse: restricted __le16 degrades to integer
   net/bluetooth/mgmt.c:4104:9: sparse: sparse: cast to restricted __le32
>> net/bluetooth/mgmt.c:4386:27: sparse: sparse: incorrect type in assignment (different base types) @@     expected restricted __le16 [usertype] type @@     got int @@
>> net/bluetooth/mgmt.c:4386:27: sparse:     expected restricted __le16 [usertype] type
>> net/bluetooth/mgmt.c:4386:27: sparse:     got int

# https://github.com/0day-ci/linux/commit/171d4465b1f2811c76267c2f0acbcd0f77b5e99a
git remote add linux-review https://github.com/0day-ci/linux
git fetch --no-tags linux-review Daniel-Winkler/Bluetooth-Add-new-MGMT-interface-for-advertising-add/20200917-042141
git checkout 171d4465b1f2811c76267c2f0acbcd0f77b5e99a
vim +4386 net/bluetooth/mgmt.c

  4360	
  4361	static int read_controller_cap(struct sock *sk, struct hci_dev *hdev,
  4362				       void *data, u16 len)
  4363	{
  4364		u8 i = 0;
  4365	
  4366		/* This command will return its data in TVL format. Currently we only
  4367		 * wish to include LE tx power parameters, so this struct can be given
  4368		 * a fixed size as data types are not changing.
  4369		 */
  4370		struct {
  4371			struct mgmt_tlv entry;
  4372			__s8 value;
  4373		} __packed cap[2];
  4374	
  4375		BT_DBG("request for %s", hdev->name);
  4376		memset(cap, 0, sizeof(cap));
  4377	
  4378		hci_dev_lock(hdev);
  4379	
  4380		/* Append LE tx power bounds */
  4381		cap[i].entry.type = MGMT_CAP_LE_TX_PWR_MIN;
  4382		cap[i].entry.length = sizeof(__s8);
  4383		cap[i].value = hdev->min_le_tx_power;
  4384		i++;
  4385	
> 4386		cap[i].entry.type = MGMT_CAP_LE_TX_PWR_MAX;
  4387		cap[i].entry.length = sizeof(__s8);
  4388		cap[i].value = hdev->max_le_tx_power;
  4389		i++;
  4390	
  4391		hci_dev_unlock(hdev);
  4392	
  4393		return mgmt_cmd_complete(sk, hdev->id, MGMT_OP_READ_CONTROLLER_CAP,
  4394					 MGMT_STATUS_SUCCESS, cap, sizeof(cap));
  4395	}
  4396	

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org
diff mbox series

Patch

diff --git a/include/net/bluetooth/mgmt.h b/include/net/bluetooth/mgmt.h
index db64cf4747554c..9aa792e5efc8d0 100644
--- a/include/net/bluetooth/mgmt.h
+++ b/include/net/bluetooth/mgmt.h
@@ -815,6 +815,15 @@  struct mgmt_rp_add_ext_adv_data {
 	__u8	instance;
 } __packed;
 
+#define MGMT_CAP_LE_TX_PWR_MIN	0x0000
+#define MGMT_CAP_LE_TX_PWR_MAX	0x0001
+
+#define MGMT_OP_READ_CONTROLLER_CAP	0x0056
+#define MGMT_OP_READ_CONTROLLER_CAP_SIZE	0
+struct mgmt_rp_read_controller_cap {
+	__u8     capabilities[0];
+} __packed;
+
 #define MGMT_EV_CMD_COMPLETE		0x0001
 struct mgmt_ev_cmd_complete {
 	__le16	opcode;
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index b9347ff1a1e961..d2e5bc4b3ddb8f 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -124,6 +124,7 @@  static const u16 mgmt_commands[] = {
 	MGMT_OP_REMOVE_ADV_MONITOR,
 	MGMT_OP_ADD_EXT_ADV_PARAMS,
 	MGMT_OP_ADD_EXT_ADV_DATA,
+	MGMT_OP_READ_CONTROLLER_CAP,
 };
 
 static const u16 mgmt_events[] = {
@@ -181,6 +182,7 @@  static const u16 mgmt_untrusted_commands[] = {
 	MGMT_OP_READ_EXP_FEATURES_INFO,
 	MGMT_OP_READ_DEF_SYSTEM_CONFIG,
 	MGMT_OP_READ_DEF_RUNTIME_CONFIG,
+	MGMT_OP_READ_CONTROLLER_CAP,
 };
 
 static const u16 mgmt_untrusted_events[] = {
@@ -4356,6 +4358,42 @@  static int remove_adv_monitor(struct sock *sk, struct hci_dev *hdev,
 	return err;
 }
 
+static int read_controller_cap(struct sock *sk, struct hci_dev *hdev,
+			       void *data, u16 len)
+{
+	u8 i = 0;
+
+	/* This command will return its data in TVL format. Currently we only
+	 * wish to include LE tx power parameters, so this struct can be given
+	 * a fixed size as data types are not changing.
+	 */
+	struct {
+		struct mgmt_tlv entry;
+		__s8 value;
+	} __packed cap[2];
+
+	BT_DBG("request for %s", hdev->name);
+	memset(cap, 0, sizeof(cap));
+
+	hci_dev_lock(hdev);
+
+	/* Append LE tx power bounds */
+	cap[i].entry.type = MGMT_CAP_LE_TX_PWR_MIN;
+	cap[i].entry.length = sizeof(__s8);
+	cap[i].value = hdev->min_le_tx_power;
+	i++;
+
+	cap[i].entry.type = MGMT_CAP_LE_TX_PWR_MAX;
+	cap[i].entry.length = sizeof(__s8);
+	cap[i].value = hdev->max_le_tx_power;
+	i++;
+
+	hci_dev_unlock(hdev);
+
+	return mgmt_cmd_complete(sk, hdev->id, MGMT_OP_READ_CONTROLLER_CAP,
+				 MGMT_STATUS_SUCCESS, cap, sizeof(cap));
+}
+
 static void read_local_oob_data_complete(struct hci_dev *hdev, u8 status,
 				         u16 opcode, struct sk_buff *skb)
 {
@@ -8208,6 +8246,7 @@  static const struct hci_mgmt_handler mgmt_handlers[] = {
 						HCI_MGMT_VAR_LEN },
 	{ add_ext_adv_data,        MGMT_ADD_EXT_ADV_DATA_SIZE,
 						HCI_MGMT_VAR_LEN },
+	{ read_controller_cap,     MGMT_OP_READ_CONTROLLER_CAP_SIZE },
 };
 
 void mgmt_index_added(struct hci_dev *hdev)