blob: 418b76e557b0a58bf7903c830866a58b4b28147d [file] [log] [blame]
Marcel Holtmann60c5f5f2014-12-20 16:05:13 +01001/*
2 BlueZ - Bluetooth protocol stack for Linux
3
4 Copyright (C) 2014 Intel Corporation
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License version 2 as
8 published by the Free Software Foundation;
9
10 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
11 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
12 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
13 IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
14 CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
15 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18
19 ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
20 COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
21 SOFTWARE IS DISCLAIMED.
22*/
23
24#include <linux/debugfs.h>
25
26#include <net/bluetooth/bluetooth.h>
27#include <net/bluetooth/hci_core.h>
28
29#include "hci_debugfs.h"
30
Jakub Pawlowskib55d1ab2015-03-20 11:14:50 -070031#define DEFINE_QUIRK_ATTRIBUTE(__name, __quirk) \
32static ssize_t __name ## _read(struct file *file, \
33 char __user *user_buf, \
34 size_t count, loff_t *ppos) \
35{ \
36 struct hci_dev *hdev = file->private_data; \
37 char buf[3]; \
38 \
39 buf[0] = test_bit(__quirk, &hdev->quirks) ? 'Y' : 'N'; \
40 buf[1] = '\n'; \
41 buf[2] = '\0'; \
42 return simple_read_from_buffer(user_buf, count, ppos, buf, 2); \
43} \
44 \
45static ssize_t __name ## _write(struct file *file, \
46 const char __user *user_buf, \
47 size_t count, loff_t *ppos) \
48{ \
49 struct hci_dev *hdev = file->private_data; \
50 char buf[32]; \
51 size_t buf_size = min(count, (sizeof(buf) - 1)); \
52 bool enable; \
53 \
54 if (test_bit(HCI_UP, &hdev->flags)) \
55 return -EBUSY; \
56 \
57 if (copy_from_user(buf, user_buf, buf_size)) \
58 return -EFAULT; \
59 \
60 buf[buf_size] = '\0'; \
61 if (strtobool(buf, &enable)) \
62 return -EINVAL; \
63 \
64 if (enable == test_bit(__quirk, &hdev->quirks)) \
65 return -EALREADY; \
66 \
67 change_bit(__quirk, &hdev->quirks); \
68 \
69 return count; \
70} \
71 \
72static const struct file_operations __name ## _fops = { \
73 .open = simple_open, \
74 .read = __name ## _read, \
75 .write = __name ## _write, \
76 .llseek = default_llseek, \
77} \
78
Marcel Holtmann5177a832016-07-17 19:55:16 +020079#define DEFINE_INFO_ATTRIBUTE(__name, __field) \
80static int __name ## _show(struct seq_file *f, void *ptr) \
81{ \
82 struct hci_dev *hdev = f->private; \
83 \
84 hci_dev_lock(hdev); \
85 seq_printf(f, "%s\n", hdev->__field ? : ""); \
86 hci_dev_unlock(hdev); \
87 \
88 return 0; \
89} \
90 \
Andy Shevchenko22b371c2017-11-22 23:15:46 +020091DEFINE_SHOW_ATTRIBUTE(__name)
92
Marcel Holtmann40ce72b2014-12-20 16:05:14 +010093static int features_show(struct seq_file *f, void *ptr)
94{
95 struct hci_dev *hdev = f->private;
96 u8 p;
97
98 hci_dev_lock(hdev);
Andy Shevchenko8a9507942017-12-11 12:10:33 +020099 for (p = 0; p < HCI_MAX_PAGES && p <= hdev->max_page; p++)
100 seq_printf(f, "%2u: %8ph\n", p, hdev->features[p]);
Marcel Holtmann40ce72b2014-12-20 16:05:14 +0100101 if (lmp_le_capable(hdev))
Andy Shevchenko8a9507942017-12-11 12:10:33 +0200102 seq_printf(f, "LE: %8ph\n", hdev->le_features);
Marcel Holtmann40ce72b2014-12-20 16:05:14 +0100103 hci_dev_unlock(hdev);
104
105 return 0;
106}
107
Andy Shevchenko22b371c2017-11-22 23:15:46 +0200108DEFINE_SHOW_ATTRIBUTE(features);
Marcel Holtmann40ce72b2014-12-20 16:05:14 +0100109
Marcel Holtmannc3370de2015-04-01 13:21:37 -0700110static int device_id_show(struct seq_file *f, void *ptr)
111{
112 struct hci_dev *hdev = f->private;
113
114 hci_dev_lock(hdev);
115 seq_printf(f, "%4.4x:%4.4x:%4.4x:%4.4x\n", hdev->devid_source,
116 hdev->devid_vendor, hdev->devid_product, hdev->devid_version);
117 hci_dev_unlock(hdev);
118
119 return 0;
120}
121
Andy Shevchenko22b371c2017-11-22 23:15:46 +0200122DEFINE_SHOW_ATTRIBUTE(device_id);
Marcel Holtmannc3370de2015-04-01 13:21:37 -0700123
Marcel Holtmann40ce72b2014-12-20 16:05:14 +0100124static int device_list_show(struct seq_file *f, void *ptr)
125{
126 struct hci_dev *hdev = f->private;
127 struct hci_conn_params *p;
128 struct bdaddr_list *b;
129
130 hci_dev_lock(hdev);
131 list_for_each_entry(b, &hdev->whitelist, list)
132 seq_printf(f, "%pMR (type %u)\n", &b->bdaddr, b->bdaddr_type);
133 list_for_each_entry(p, &hdev->le_conn_params, list) {
134 seq_printf(f, "%pMR (type %u) %u\n", &p->addr, p->addr_type,
135 p->auto_connect);
136 }
137 hci_dev_unlock(hdev);
138
139 return 0;
140}
141
Andy Shevchenko22b371c2017-11-22 23:15:46 +0200142DEFINE_SHOW_ATTRIBUTE(device_list);
Marcel Holtmann40ce72b2014-12-20 16:05:14 +0100143
144static int blacklist_show(struct seq_file *f, void *p)
145{
146 struct hci_dev *hdev = f->private;
147 struct bdaddr_list *b;
148
149 hci_dev_lock(hdev);
150 list_for_each_entry(b, &hdev->blacklist, list)
151 seq_printf(f, "%pMR (type %u)\n", &b->bdaddr, b->bdaddr_type);
152 hci_dev_unlock(hdev);
153
154 return 0;
155}
156
Andy Shevchenko22b371c2017-11-22 23:15:46 +0200157DEFINE_SHOW_ATTRIBUTE(blacklist);
Marcel Holtmann40ce72b2014-12-20 16:05:14 +0100158
159static int uuids_show(struct seq_file *f, void *p)
160{
161 struct hci_dev *hdev = f->private;
162 struct bt_uuid *uuid;
163
164 hci_dev_lock(hdev);
165 list_for_each_entry(uuid, &hdev->uuids, list) {
166 u8 i, val[16];
167
168 /* The Bluetooth UUID values are stored in big endian,
169 * but with reversed byte order. So convert them into
170 * the right order for the %pUb modifier.
171 */
172 for (i = 0; i < 16; i++)
173 val[i] = uuid->uuid[15 - i];
174
175 seq_printf(f, "%pUb\n", val);
176 }
177 hci_dev_unlock(hdev);
178
179 return 0;
180}
181
Andy Shevchenko22b371c2017-11-22 23:15:46 +0200182DEFINE_SHOW_ATTRIBUTE(uuids);
Marcel Holtmann40ce72b2014-12-20 16:05:14 +0100183
Marcel Holtmann6858bcd2015-01-31 21:01:07 -0800184static int remote_oob_show(struct seq_file *f, void *ptr)
185{
186 struct hci_dev *hdev = f->private;
187 struct oob_data *data;
188
189 hci_dev_lock(hdev);
190 list_for_each_entry(data, &hdev->remote_oob_data, list) {
191 seq_printf(f, "%pMR (type %u) %u %*phN %*phN %*phN %*phN\n",
192 &data->bdaddr, data->bdaddr_type, data->present,
193 16, data->hash192, 16, data->rand192,
Marcel Holtmannb880ab82015-03-16 12:34:58 -0700194 16, data->hash256, 16, data->rand256);
Marcel Holtmann6858bcd2015-01-31 21:01:07 -0800195 }
196 hci_dev_unlock(hdev);
197
198 return 0;
199}
200
Andy Shevchenko22b371c2017-11-22 23:15:46 +0200201DEFINE_SHOW_ATTRIBUTE(remote_oob);
Marcel Holtmann6858bcd2015-01-31 21:01:07 -0800202
Marcel Holtmann40ce72b2014-12-20 16:05:14 +0100203static int conn_info_min_age_set(void *data, u64 val)
204{
205 struct hci_dev *hdev = data;
206
207 if (val == 0 || val > hdev->conn_info_max_age)
208 return -EINVAL;
209
210 hci_dev_lock(hdev);
211 hdev->conn_info_min_age = val;
212 hci_dev_unlock(hdev);
213
214 return 0;
215}
216
217static int conn_info_min_age_get(void *data, u64 *val)
218{
219 struct hci_dev *hdev = data;
220
221 hci_dev_lock(hdev);
222 *val = hdev->conn_info_min_age;
223 hci_dev_unlock(hdev);
224
225 return 0;
226}
227
228DEFINE_SIMPLE_ATTRIBUTE(conn_info_min_age_fops, conn_info_min_age_get,
229 conn_info_min_age_set, "%llu\n");
230
231static int conn_info_max_age_set(void *data, u64 val)
232{
233 struct hci_dev *hdev = data;
234
235 if (val == 0 || val < hdev->conn_info_min_age)
236 return -EINVAL;
237
238 hci_dev_lock(hdev);
239 hdev->conn_info_max_age = val;
240 hci_dev_unlock(hdev);
241
242 return 0;
243}
244
245static int conn_info_max_age_get(void *data, u64 *val)
246{
247 struct hci_dev *hdev = data;
248
249 hci_dev_lock(hdev);
250 *val = hdev->conn_info_max_age;
251 hci_dev_unlock(hdev);
252
253 return 0;
254}
255
256DEFINE_SIMPLE_ATTRIBUTE(conn_info_max_age_fops, conn_info_max_age_get,
257 conn_info_max_age_set, "%llu\n");
258
Marcel Holtmann0886aea2015-01-31 15:12:06 -0800259static ssize_t use_debug_keys_read(struct file *file, char __user *user_buf,
260 size_t count, loff_t *ppos)
261{
262 struct hci_dev *hdev = file->private_data;
263 char buf[3];
264
Marcel Holtmannd7a5a112015-03-13 02:11:00 -0700265 buf[0] = hci_dev_test_flag(hdev, HCI_USE_DEBUG_KEYS) ? 'Y': 'N';
Marcel Holtmann0886aea2015-01-31 15:12:06 -0800266 buf[1] = '\n';
267 buf[2] = '\0';
268 return simple_read_from_buffer(user_buf, count, ppos, buf, 2);
269}
270
271static const struct file_operations use_debug_keys_fops = {
272 .open = simple_open,
273 .read = use_debug_keys_read,
274 .llseek = default_llseek,
275};
276
Marcel Holtmanncb0d2fa2014-12-31 14:43:19 -0800277static ssize_t sc_only_mode_read(struct file *file, char __user *user_buf,
278 size_t count, loff_t *ppos)
279{
280 struct hci_dev *hdev = file->private_data;
281 char buf[3];
282
Marcel Holtmannd7a5a112015-03-13 02:11:00 -0700283 buf[0] = hci_dev_test_flag(hdev, HCI_SC_ONLY) ? 'Y': 'N';
Marcel Holtmanncb0d2fa2014-12-31 14:43:19 -0800284 buf[1] = '\n';
285 buf[2] = '\0';
286 return simple_read_from_buffer(user_buf, count, ppos, buf, 2);
287}
288
289static const struct file_operations sc_only_mode_fops = {
290 .open = simple_open,
291 .read = sc_only_mode_read,
292 .llseek = default_llseek,
293};
294
Marcel Holtmann5177a832016-07-17 19:55:16 +0200295DEFINE_INFO_ATTRIBUTE(hardware_info, hw_info);
296DEFINE_INFO_ATTRIBUTE(firmware_info, fw_info);
297
Marcel Holtmann60c5f5f2014-12-20 16:05:13 +0100298void hci_debugfs_create_common(struct hci_dev *hdev)
299{
Marcel Holtmann40ce72b2014-12-20 16:05:14 +0100300 debugfs_create_file("features", 0444, hdev->debugfs, hdev,
301 &features_fops);
302 debugfs_create_u16("manufacturer", 0444, hdev->debugfs,
303 &hdev->manufacturer);
304 debugfs_create_u8("hci_version", 0444, hdev->debugfs, &hdev->hci_ver);
305 debugfs_create_u16("hci_revision", 0444, hdev->debugfs, &hdev->hci_rev);
Marcel Holtmann5789f372015-01-31 19:54:39 -0800306 debugfs_create_u8("hardware_error", 0444, hdev->debugfs,
307 &hdev->hw_error_code);
Marcel Holtmannc3370de2015-04-01 13:21:37 -0700308 debugfs_create_file("device_id", 0444, hdev->debugfs, hdev,
309 &device_id_fops);
Marcel Holtmann5789f372015-01-31 19:54:39 -0800310
Marcel Holtmann40ce72b2014-12-20 16:05:14 +0100311 debugfs_create_file("device_list", 0444, hdev->debugfs, hdev,
312 &device_list_fops);
313 debugfs_create_file("blacklist", 0444, hdev->debugfs, hdev,
314 &blacklist_fops);
315 debugfs_create_file("uuids", 0444, hdev->debugfs, hdev, &uuids_fops);
Marcel Holtmann6858bcd2015-01-31 21:01:07 -0800316 debugfs_create_file("remote_oob", 0400, hdev->debugfs, hdev,
317 &remote_oob_fops);
Marcel Holtmann40ce72b2014-12-20 16:05:14 +0100318
319 debugfs_create_file("conn_info_min_age", 0644, hdev->debugfs, hdev,
320 &conn_info_min_age_fops);
321 debugfs_create_file("conn_info_max_age", 0644, hdev->debugfs, hdev,
322 &conn_info_max_age_fops);
Marcel Holtmanncb0d2fa2014-12-31 14:43:19 -0800323
Marcel Holtmann0886aea2015-01-31 15:12:06 -0800324 if (lmp_ssp_capable(hdev) || lmp_le_capable(hdev))
325 debugfs_create_file("use_debug_keys", 0444, hdev->debugfs,
326 hdev, &use_debug_keys_fops);
327
Marcel Holtmanncb0d2fa2014-12-31 14:43:19 -0800328 if (lmp_sc_capable(hdev) || lmp_le_capable(hdev))
329 debugfs_create_file("sc_only_mode", 0444, hdev->debugfs,
330 hdev, &sc_only_mode_fops);
Marcel Holtmann5177a832016-07-17 19:55:16 +0200331
332 if (hdev->hw_info)
333 debugfs_create_file("hardware_info", 0444, hdev->debugfs,
334 hdev, &hardware_info_fops);
335
336 if (hdev->fw_info)
337 debugfs_create_file("firmware_info", 0444, hdev->debugfs,
338 hdev, &firmware_info_fops);
Marcel Holtmann60c5f5f2014-12-20 16:05:13 +0100339}
340
Marcel Holtmann71c3b602014-12-20 16:05:15 +0100341static int inquiry_cache_show(struct seq_file *f, void *p)
342{
343 struct hci_dev *hdev = f->private;
344 struct discovery_state *cache = &hdev->discovery;
345 struct inquiry_entry *e;
346
347 hci_dev_lock(hdev);
348
349 list_for_each_entry(e, &cache->all, all) {
350 struct inquiry_data *data = &e->data;
351 seq_printf(f, "%pMR %d %d %d 0x%.2x%.2x%.2x 0x%.4x %d %d %u\n",
352 &data->bdaddr,
353 data->pscan_rep_mode, data->pscan_period_mode,
354 data->pscan_mode, data->dev_class[2],
355 data->dev_class[1], data->dev_class[0],
356 __le16_to_cpu(data->clock_offset),
357 data->rssi, data->ssp_mode, e->timestamp);
358 }
359
360 hci_dev_unlock(hdev);
361
362 return 0;
363}
364
Andy Shevchenko22b371c2017-11-22 23:15:46 +0200365DEFINE_SHOW_ATTRIBUTE(inquiry_cache);
Marcel Holtmann71c3b602014-12-20 16:05:15 +0100366
367static int link_keys_show(struct seq_file *f, void *ptr)
368{
369 struct hci_dev *hdev = f->private;
370 struct link_key *key;
371
372 rcu_read_lock();
373 list_for_each_entry_rcu(key, &hdev->link_keys, list)
374 seq_printf(f, "%pMR %u %*phN %u\n", &key->bdaddr, key->type,
375 HCI_LINK_KEY_SIZE, key->val, key->pin_len);
376 rcu_read_unlock();
377
378 return 0;
379}
380
Andy Shevchenko22b371c2017-11-22 23:15:46 +0200381DEFINE_SHOW_ATTRIBUTE(link_keys);
Marcel Holtmann71c3b602014-12-20 16:05:15 +0100382
383static int dev_class_show(struct seq_file *f, void *ptr)
384{
385 struct hci_dev *hdev = f->private;
386
387 hci_dev_lock(hdev);
388 seq_printf(f, "0x%.2x%.2x%.2x\n", hdev->dev_class[2],
389 hdev->dev_class[1], hdev->dev_class[0]);
390 hci_dev_unlock(hdev);
391
392 return 0;
393}
394
Andy Shevchenko22b371c2017-11-22 23:15:46 +0200395DEFINE_SHOW_ATTRIBUTE(dev_class);
Marcel Holtmann71c3b602014-12-20 16:05:15 +0100396
397static int voice_setting_get(void *data, u64 *val)
398{
399 struct hci_dev *hdev = data;
400
401 hci_dev_lock(hdev);
402 *val = hdev->voice_setting;
403 hci_dev_unlock(hdev);
404
405 return 0;
406}
407
408DEFINE_SIMPLE_ATTRIBUTE(voice_setting_fops, voice_setting_get,
409 NULL, "0x%4.4llx\n");
410
Marcel Holtmann6e072312015-01-31 15:07:51 -0800411static ssize_t ssp_debug_mode_read(struct file *file, char __user *user_buf,
412 size_t count, loff_t *ppos)
413{
414 struct hci_dev *hdev = file->private_data;
415 char buf[3];
416
417 buf[0] = hdev->ssp_debug_mode ? 'Y': 'N';
418 buf[1] = '\n';
419 buf[2] = '\0';
420 return simple_read_from_buffer(user_buf, count, ppos, buf, 2);
421}
422
423static const struct file_operations ssp_debug_mode_fops = {
424 .open = simple_open,
425 .read = ssp_debug_mode_read,
426 .llseek = default_llseek,
427};
428
Marcel Holtmann71c3b602014-12-20 16:05:15 +0100429static int auto_accept_delay_set(void *data, u64 val)
430{
431 struct hci_dev *hdev = data;
432
433 hci_dev_lock(hdev);
434 hdev->auto_accept_delay = val;
435 hci_dev_unlock(hdev);
436
437 return 0;
438}
439
440static int auto_accept_delay_get(void *data, u64 *val)
441{
442 struct hci_dev *hdev = data;
443
444 hci_dev_lock(hdev);
445 *val = hdev->auto_accept_delay;
446 hci_dev_unlock(hdev);
447
448 return 0;
449}
450
451DEFINE_SIMPLE_ATTRIBUTE(auto_accept_delay_fops, auto_accept_delay_get,
452 auto_accept_delay_set, "%llu\n");
453
Marcel Holtmann71c3b602014-12-20 16:05:15 +0100454static int idle_timeout_set(void *data, u64 val)
455{
456 struct hci_dev *hdev = data;
457
458 if (val != 0 && (val < 500 || val > 3600000))
459 return -EINVAL;
460
461 hci_dev_lock(hdev);
462 hdev->idle_timeout = val;
463 hci_dev_unlock(hdev);
464
465 return 0;
466}
467
468static int idle_timeout_get(void *data, u64 *val)
469{
470 struct hci_dev *hdev = data;
471
472 hci_dev_lock(hdev);
473 *val = hdev->idle_timeout;
474 hci_dev_unlock(hdev);
475
476 return 0;
477}
478
479DEFINE_SIMPLE_ATTRIBUTE(idle_timeout_fops, idle_timeout_get,
480 idle_timeout_set, "%llu\n");
481
482static int sniff_min_interval_set(void *data, u64 val)
483{
484 struct hci_dev *hdev = data;
485
486 if (val == 0 || val % 2 || val > hdev->sniff_max_interval)
487 return -EINVAL;
488
489 hci_dev_lock(hdev);
490 hdev->sniff_min_interval = val;
491 hci_dev_unlock(hdev);
492
493 return 0;
494}
495
496static int sniff_min_interval_get(void *data, u64 *val)
497{
498 struct hci_dev *hdev = data;
499
500 hci_dev_lock(hdev);
501 *val = hdev->sniff_min_interval;
502 hci_dev_unlock(hdev);
503
504 return 0;
505}
506
507DEFINE_SIMPLE_ATTRIBUTE(sniff_min_interval_fops, sniff_min_interval_get,
508 sniff_min_interval_set, "%llu\n");
509
510static int sniff_max_interval_set(void *data, u64 val)
511{
512 struct hci_dev *hdev = data;
513
514 if (val == 0 || val % 2 || val < hdev->sniff_min_interval)
515 return -EINVAL;
516
517 hci_dev_lock(hdev);
518 hdev->sniff_max_interval = val;
519 hci_dev_unlock(hdev);
520
521 return 0;
522}
523
524static int sniff_max_interval_get(void *data, u64 *val)
525{
526 struct hci_dev *hdev = data;
527
528 hci_dev_lock(hdev);
529 *val = hdev->sniff_max_interval;
530 hci_dev_unlock(hdev);
531
532 return 0;
533}
534
535DEFINE_SIMPLE_ATTRIBUTE(sniff_max_interval_fops, sniff_max_interval_get,
536 sniff_max_interval_set, "%llu\n");
537
Marcel Holtmann60c5f5f2014-12-20 16:05:13 +0100538void hci_debugfs_create_bredr(struct hci_dev *hdev)
539{
Marcel Holtmann71c3b602014-12-20 16:05:15 +0100540 debugfs_create_file("inquiry_cache", 0444, hdev->debugfs, hdev,
541 &inquiry_cache_fops);
542 debugfs_create_file("link_keys", 0400, hdev->debugfs, hdev,
543 &link_keys_fops);
544 debugfs_create_file("dev_class", 0444, hdev->debugfs, hdev,
545 &dev_class_fops);
546 debugfs_create_file("voice_setting", 0444, hdev->debugfs, hdev,
547 &voice_setting_fops);
548
Marcel Holtmann6e072312015-01-31 15:07:51 -0800549 if (lmp_ssp_capable(hdev)) {
550 debugfs_create_file("ssp_debug_mode", 0444, hdev->debugfs,
551 hdev, &ssp_debug_mode_fops);
Marcel Holtmann71c3b602014-12-20 16:05:15 +0100552 debugfs_create_file("auto_accept_delay", 0644, hdev->debugfs,
553 hdev, &auto_accept_delay_fops);
Marcel Holtmann6e072312015-01-31 15:07:51 -0800554 }
Marcel Holtmann71c3b602014-12-20 16:05:15 +0100555
556 if (lmp_sniff_capable(hdev)) {
557 debugfs_create_file("idle_timeout", 0644, hdev->debugfs,
558 hdev, &idle_timeout_fops);
559 debugfs_create_file("sniff_min_interval", 0644, hdev->debugfs,
560 hdev, &sniff_min_interval_fops);
561 debugfs_create_file("sniff_max_interval", 0644, hdev->debugfs,
562 hdev, &sniff_max_interval_fops);
563 }
Marcel Holtmann60c5f5f2014-12-20 16:05:13 +0100564}
565
Marcel Holtmann3a5c82b2014-12-20 16:05:16 +0100566static int identity_show(struct seq_file *f, void *p)
567{
568 struct hci_dev *hdev = f->private;
569 bdaddr_t addr;
570 u8 addr_type;
571
572 hci_dev_lock(hdev);
573
574 hci_copy_identity_address(hdev, &addr, &addr_type);
575
576 seq_printf(f, "%pMR (type %u) %*phN %pMR\n", &addr, addr_type,
577 16, hdev->irk, &hdev->rpa);
578
579 hci_dev_unlock(hdev);
580
581 return 0;
582}
583
Andy Shevchenko22b371c2017-11-22 23:15:46 +0200584DEFINE_SHOW_ATTRIBUTE(identity);
Marcel Holtmann3a5c82b2014-12-20 16:05:16 +0100585
586static int rpa_timeout_set(void *data, u64 val)
587{
588 struct hci_dev *hdev = data;
589
590 /* Require the RPA timeout to be at least 30 seconds and at most
591 * 24 hours.
592 */
593 if (val < 30 || val > (60 * 60 * 24))
594 return -EINVAL;
595
596 hci_dev_lock(hdev);
597 hdev->rpa_timeout = val;
598 hci_dev_unlock(hdev);
599
600 return 0;
601}
602
603static int rpa_timeout_get(void *data, u64 *val)
604{
605 struct hci_dev *hdev = data;
606
607 hci_dev_lock(hdev);
608 *val = hdev->rpa_timeout;
609 hci_dev_unlock(hdev);
610
611 return 0;
612}
613
614DEFINE_SIMPLE_ATTRIBUTE(rpa_timeout_fops, rpa_timeout_get,
615 rpa_timeout_set, "%llu\n");
616
617static int random_address_show(struct seq_file *f, void *p)
618{
619 struct hci_dev *hdev = f->private;
620
621 hci_dev_lock(hdev);
622 seq_printf(f, "%pMR\n", &hdev->random_addr);
623 hci_dev_unlock(hdev);
624
625 return 0;
626}
627
Andy Shevchenko22b371c2017-11-22 23:15:46 +0200628DEFINE_SHOW_ATTRIBUTE(random_address);
Marcel Holtmann3a5c82b2014-12-20 16:05:16 +0100629
630static int static_address_show(struct seq_file *f, void *p)
631{
632 struct hci_dev *hdev = f->private;
633
634 hci_dev_lock(hdev);
635 seq_printf(f, "%pMR\n", &hdev->static_addr);
636 hci_dev_unlock(hdev);
637
638 return 0;
639}
640
Andy Shevchenko22b371c2017-11-22 23:15:46 +0200641DEFINE_SHOW_ATTRIBUTE(static_address);
Marcel Holtmann3a5c82b2014-12-20 16:05:16 +0100642
643static ssize_t force_static_address_read(struct file *file,
644 char __user *user_buf,
645 size_t count, loff_t *ppos)
646{
647 struct hci_dev *hdev = file->private_data;
648 char buf[3];
649
Marcel Holtmannb7cb93e2015-03-13 10:20:35 -0700650 buf[0] = hci_dev_test_flag(hdev, HCI_FORCE_STATIC_ADDR) ? 'Y': 'N';
Marcel Holtmann3a5c82b2014-12-20 16:05:16 +0100651 buf[1] = '\n';
652 buf[2] = '\0';
653 return simple_read_from_buffer(user_buf, count, ppos, buf, 2);
654}
655
656static ssize_t force_static_address_write(struct file *file,
657 const char __user *user_buf,
658 size_t count, loff_t *ppos)
659{
660 struct hci_dev *hdev = file->private_data;
661 char buf[32];
662 size_t buf_size = min(count, (sizeof(buf)-1));
663 bool enable;
664
665 if (test_bit(HCI_UP, &hdev->flags))
666 return -EBUSY;
667
668 if (copy_from_user(buf, user_buf, buf_size))
669 return -EFAULT;
670
671 buf[buf_size] = '\0';
672 if (strtobool(buf, &enable))
673 return -EINVAL;
674
Marcel Holtmannb7cb93e2015-03-13 10:20:35 -0700675 if (enable == hci_dev_test_flag(hdev, HCI_FORCE_STATIC_ADDR))
Marcel Holtmann3a5c82b2014-12-20 16:05:16 +0100676 return -EALREADY;
677
Marcel Holtmannb7cb93e2015-03-13 10:20:35 -0700678 hci_dev_change_flag(hdev, HCI_FORCE_STATIC_ADDR);
Marcel Holtmann3a5c82b2014-12-20 16:05:16 +0100679
680 return count;
681}
682
683static const struct file_operations force_static_address_fops = {
684 .open = simple_open,
685 .read = force_static_address_read,
686 .write = force_static_address_write,
687 .llseek = default_llseek,
688};
689
690static int white_list_show(struct seq_file *f, void *ptr)
691{
692 struct hci_dev *hdev = f->private;
693 struct bdaddr_list *b;
694
695 hci_dev_lock(hdev);
696 list_for_each_entry(b, &hdev->le_white_list, list)
697 seq_printf(f, "%pMR (type %u)\n", &b->bdaddr, b->bdaddr_type);
698 hci_dev_unlock(hdev);
699
700 return 0;
701}
702
Andy Shevchenko22b371c2017-11-22 23:15:46 +0200703DEFINE_SHOW_ATTRIBUTE(white_list);
Marcel Holtmann3a5c82b2014-12-20 16:05:16 +0100704
705static int identity_resolving_keys_show(struct seq_file *f, void *ptr)
706{
707 struct hci_dev *hdev = f->private;
708 struct smp_irk *irk;
709
710 rcu_read_lock();
711 list_for_each_entry_rcu(irk, &hdev->identity_resolving_keys, list) {
712 seq_printf(f, "%pMR (type %u) %*phN %pMR\n",
713 &irk->bdaddr, irk->addr_type,
714 16, irk->val, &irk->rpa);
715 }
716 rcu_read_unlock();
717
718 return 0;
719}
720
Andy Shevchenko22b371c2017-11-22 23:15:46 +0200721DEFINE_SHOW_ATTRIBUTE(identity_resolving_keys);
Marcel Holtmann3a5c82b2014-12-20 16:05:16 +0100722
723static int long_term_keys_show(struct seq_file *f, void *ptr)
724{
725 struct hci_dev *hdev = f->private;
726 struct smp_ltk *ltk;
727
728 rcu_read_lock();
729 list_for_each_entry_rcu(ltk, &hdev->long_term_keys, list)
730 seq_printf(f, "%pMR (type %u) %u 0x%02x %u %.4x %.16llx %*phN\n",
731 &ltk->bdaddr, ltk->bdaddr_type, ltk->authenticated,
732 ltk->type, ltk->enc_size, __le16_to_cpu(ltk->ediv),
733 __le64_to_cpu(ltk->rand), 16, ltk->val);
734 rcu_read_unlock();
735
736 return 0;
737}
738
Andy Shevchenko22b371c2017-11-22 23:15:46 +0200739DEFINE_SHOW_ATTRIBUTE(long_term_keys);
Marcel Holtmann3a5c82b2014-12-20 16:05:16 +0100740
741static int conn_min_interval_set(void *data, u64 val)
742{
743 struct hci_dev *hdev = data;
744
745 if (val < 0x0006 || val > 0x0c80 || val > hdev->le_conn_max_interval)
746 return -EINVAL;
747
748 hci_dev_lock(hdev);
749 hdev->le_conn_min_interval = val;
750 hci_dev_unlock(hdev);
751
752 return 0;
753}
754
755static int conn_min_interval_get(void *data, u64 *val)
756{
757 struct hci_dev *hdev = data;
758
759 hci_dev_lock(hdev);
760 *val = hdev->le_conn_min_interval;
761 hci_dev_unlock(hdev);
762
763 return 0;
764}
765
766DEFINE_SIMPLE_ATTRIBUTE(conn_min_interval_fops, conn_min_interval_get,
767 conn_min_interval_set, "%llu\n");
768
769static int conn_max_interval_set(void *data, u64 val)
770{
771 struct hci_dev *hdev = data;
772
773 if (val < 0x0006 || val > 0x0c80 || val < hdev->le_conn_min_interval)
774 return -EINVAL;
775
776 hci_dev_lock(hdev);
777 hdev->le_conn_max_interval = val;
778 hci_dev_unlock(hdev);
779
780 return 0;
781}
782
783static int conn_max_interval_get(void *data, u64 *val)
784{
785 struct hci_dev *hdev = data;
786
787 hci_dev_lock(hdev);
788 *val = hdev->le_conn_max_interval;
789 hci_dev_unlock(hdev);
790
791 return 0;
792}
793
794DEFINE_SIMPLE_ATTRIBUTE(conn_max_interval_fops, conn_max_interval_get,
795 conn_max_interval_set, "%llu\n");
796
797static int conn_latency_set(void *data, u64 val)
798{
799 struct hci_dev *hdev = data;
800
801 if (val > 0x01f3)
802 return -EINVAL;
803
804 hci_dev_lock(hdev);
805 hdev->le_conn_latency = val;
806 hci_dev_unlock(hdev);
807
808 return 0;
809}
810
811static int conn_latency_get(void *data, u64 *val)
812{
813 struct hci_dev *hdev = data;
814
815 hci_dev_lock(hdev);
816 *val = hdev->le_conn_latency;
817 hci_dev_unlock(hdev);
818
819 return 0;
820}
821
822DEFINE_SIMPLE_ATTRIBUTE(conn_latency_fops, conn_latency_get,
823 conn_latency_set, "%llu\n");
824
825static int supervision_timeout_set(void *data, u64 val)
826{
827 struct hci_dev *hdev = data;
828
829 if (val < 0x000a || val > 0x0c80)
830 return -EINVAL;
831
832 hci_dev_lock(hdev);
833 hdev->le_supv_timeout = val;
834 hci_dev_unlock(hdev);
835
836 return 0;
837}
838
839static int supervision_timeout_get(void *data, u64 *val)
840{
841 struct hci_dev *hdev = data;
842
843 hci_dev_lock(hdev);
844 *val = hdev->le_supv_timeout;
845 hci_dev_unlock(hdev);
846
847 return 0;
848}
849
850DEFINE_SIMPLE_ATTRIBUTE(supervision_timeout_fops, supervision_timeout_get,
851 supervision_timeout_set, "%llu\n");
852
853static int adv_channel_map_set(void *data, u64 val)
854{
855 struct hci_dev *hdev = data;
856
857 if (val < 0x01 || val > 0x07)
858 return -EINVAL;
859
860 hci_dev_lock(hdev);
861 hdev->le_adv_channel_map = val;
862 hci_dev_unlock(hdev);
863
864 return 0;
865}
866
867static int adv_channel_map_get(void *data, u64 *val)
868{
869 struct hci_dev *hdev = data;
870
871 hci_dev_lock(hdev);
872 *val = hdev->le_adv_channel_map;
873 hci_dev_unlock(hdev);
874
875 return 0;
876}
877
878DEFINE_SIMPLE_ATTRIBUTE(adv_channel_map_fops, adv_channel_map_get,
879 adv_channel_map_set, "%llu\n");
880
881static int adv_min_interval_set(void *data, u64 val)
882{
883 struct hci_dev *hdev = data;
884
885 if (val < 0x0020 || val > 0x4000 || val > hdev->le_adv_max_interval)
886 return -EINVAL;
887
888 hci_dev_lock(hdev);
889 hdev->le_adv_min_interval = val;
890 hci_dev_unlock(hdev);
891
892 return 0;
893}
894
895static int adv_min_interval_get(void *data, u64 *val)
896{
897 struct hci_dev *hdev = data;
898
899 hci_dev_lock(hdev);
900 *val = hdev->le_adv_min_interval;
901 hci_dev_unlock(hdev);
902
903 return 0;
904}
905
906DEFINE_SIMPLE_ATTRIBUTE(adv_min_interval_fops, adv_min_interval_get,
907 adv_min_interval_set, "%llu\n");
908
909static int adv_max_interval_set(void *data, u64 val)
910{
911 struct hci_dev *hdev = data;
912
913 if (val < 0x0020 || val > 0x4000 || val < hdev->le_adv_min_interval)
914 return -EINVAL;
915
916 hci_dev_lock(hdev);
917 hdev->le_adv_max_interval = val;
918 hci_dev_unlock(hdev);
919
920 return 0;
921}
922
923static int adv_max_interval_get(void *data, u64 *val)
924{
925 struct hci_dev *hdev = data;
926
927 hci_dev_lock(hdev);
928 *val = hdev->le_adv_max_interval;
929 hci_dev_unlock(hdev);
930
931 return 0;
932}
933
934DEFINE_SIMPLE_ATTRIBUTE(adv_max_interval_fops, adv_max_interval_get,
935 adv_max_interval_set, "%llu\n");
936
Jakub Pawlowskib55d1ab2015-03-20 11:14:50 -0700937DEFINE_QUIRK_ATTRIBUTE(quirk_strict_duplicate_filter,
938 HCI_QUIRK_STRICT_DUPLICATE_FILTER);
939DEFINE_QUIRK_ATTRIBUTE(quirk_simultaneous_discovery,
940 HCI_QUIRK_SIMULTANEOUS_DISCOVERY);
941
Marcel Holtmann60c5f5f2014-12-20 16:05:13 +0100942void hci_debugfs_create_le(struct hci_dev *hdev)
943{
Marcel Holtmann3a5c82b2014-12-20 16:05:16 +0100944 debugfs_create_file("identity", 0400, hdev->debugfs, hdev,
945 &identity_fops);
946 debugfs_create_file("rpa_timeout", 0644, hdev->debugfs, hdev,
947 &rpa_timeout_fops);
948 debugfs_create_file("random_address", 0444, hdev->debugfs, hdev,
949 &random_address_fops);
950 debugfs_create_file("static_address", 0444, hdev->debugfs, hdev,
951 &static_address_fops);
952
953 /* For controllers with a public address, provide a debug
954 * option to force the usage of the configured static
955 * address. By default the public address is used.
956 */
957 if (bacmp(&hdev->bdaddr, BDADDR_ANY))
958 debugfs_create_file("force_static_address", 0644,
959 hdev->debugfs, hdev,
960 &force_static_address_fops);
961
962 debugfs_create_u8("white_list_size", 0444, hdev->debugfs,
963 &hdev->le_white_list_size);
964 debugfs_create_file("white_list", 0444, hdev->debugfs, hdev,
965 &white_list_fops);
966 debugfs_create_file("identity_resolving_keys", 0400, hdev->debugfs,
967 hdev, &identity_resolving_keys_fops);
968 debugfs_create_file("long_term_keys", 0400, hdev->debugfs, hdev,
969 &long_term_keys_fops);
970 debugfs_create_file("conn_min_interval", 0644, hdev->debugfs, hdev,
971 &conn_min_interval_fops);
972 debugfs_create_file("conn_max_interval", 0644, hdev->debugfs, hdev,
973 &conn_max_interval_fops);
974 debugfs_create_file("conn_latency", 0644, hdev->debugfs, hdev,
975 &conn_latency_fops);
976 debugfs_create_file("supervision_timeout", 0644, hdev->debugfs, hdev,
977 &supervision_timeout_fops);
978 debugfs_create_file("adv_channel_map", 0644, hdev->debugfs, hdev,
979 &adv_channel_map_fops);
980 debugfs_create_file("adv_min_interval", 0644, hdev->debugfs, hdev,
981 &adv_min_interval_fops);
982 debugfs_create_file("adv_max_interval", 0644, hdev->debugfs, hdev,
983 &adv_max_interval_fops);
984 debugfs_create_u16("discov_interleaved_timeout", 0644, hdev->debugfs,
985 &hdev->discov_interleaved_timeout);
Jakub Pawlowskib55d1ab2015-03-20 11:14:50 -0700986
987 debugfs_create_file("quirk_strict_duplicate_filter", 0644,
988 hdev->debugfs, hdev,
989 &quirk_strict_duplicate_filter_fops);
990 debugfs_create_file("quirk_simultaneous_discovery", 0644,
991 hdev->debugfs, hdev,
992 &quirk_simultaneous_discovery_fops);
Marcel Holtmann60c5f5f2014-12-20 16:05:13 +0100993}
Marcel Holtmann23b9ceb2014-12-20 17:13:41 +0100994
995void hci_debugfs_create_conn(struct hci_conn *conn)
996{
997 struct hci_dev *hdev = conn->hdev;
998 char name[6];
999
1000 if (IS_ERR_OR_NULL(hdev->debugfs))
1001 return;
1002
1003 snprintf(name, sizeof(name), "%u", conn->handle);
1004 conn->debugfs = debugfs_create_dir(name, hdev->debugfs);
1005}