blob: e6255833a2582e7f4deeed9b138b9390ea726095 [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 Holtmann40ce72b2014-12-20 16:05:14 +010079static int features_show(struct seq_file *f, void *ptr)
80{
81 struct hci_dev *hdev = f->private;
82 u8 p;
83
84 hci_dev_lock(hdev);
85 for (p = 0; p < HCI_MAX_PAGES && p <= hdev->max_page; p++) {
86 seq_printf(f, "%2u: 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x "
87 "0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x\n", p,
88 hdev->features[p][0], hdev->features[p][1],
89 hdev->features[p][2], hdev->features[p][3],
90 hdev->features[p][4], hdev->features[p][5],
91 hdev->features[p][6], hdev->features[p][7]);
92 }
93 if (lmp_le_capable(hdev))
94 seq_printf(f, "LE: 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x "
95 "0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x\n",
96 hdev->le_features[0], hdev->le_features[1],
97 hdev->le_features[2], hdev->le_features[3],
98 hdev->le_features[4], hdev->le_features[5],
99 hdev->le_features[6], hdev->le_features[7]);
100 hci_dev_unlock(hdev);
101
102 return 0;
103}
104
105static int features_open(struct inode *inode, struct file *file)
106{
107 return single_open(file, features_show, inode->i_private);
108}
109
110static const struct file_operations features_fops = {
111 .open = features_open,
112 .read = seq_read,
113 .llseek = seq_lseek,
114 .release = single_release,
115};
116
117static int device_list_show(struct seq_file *f, void *ptr)
118{
119 struct hci_dev *hdev = f->private;
120 struct hci_conn_params *p;
121 struct bdaddr_list *b;
122
123 hci_dev_lock(hdev);
124 list_for_each_entry(b, &hdev->whitelist, list)
125 seq_printf(f, "%pMR (type %u)\n", &b->bdaddr, b->bdaddr_type);
126 list_for_each_entry(p, &hdev->le_conn_params, list) {
127 seq_printf(f, "%pMR (type %u) %u\n", &p->addr, p->addr_type,
128 p->auto_connect);
129 }
130 hci_dev_unlock(hdev);
131
132 return 0;
133}
134
135static int device_list_open(struct inode *inode, struct file *file)
136{
137 return single_open(file, device_list_show, inode->i_private);
138}
139
140static const struct file_operations device_list_fops = {
141 .open = device_list_open,
142 .read = seq_read,
143 .llseek = seq_lseek,
144 .release = single_release,
145};
146
147static int blacklist_show(struct seq_file *f, void *p)
148{
149 struct hci_dev *hdev = f->private;
150 struct bdaddr_list *b;
151
152 hci_dev_lock(hdev);
153 list_for_each_entry(b, &hdev->blacklist, list)
154 seq_printf(f, "%pMR (type %u)\n", &b->bdaddr, b->bdaddr_type);
155 hci_dev_unlock(hdev);
156
157 return 0;
158}
159
160static int blacklist_open(struct inode *inode, struct file *file)
161{
162 return single_open(file, blacklist_show, inode->i_private);
163}
164
165static const struct file_operations blacklist_fops = {
166 .open = blacklist_open,
167 .read = seq_read,
168 .llseek = seq_lseek,
169 .release = single_release,
170};
171
172static int uuids_show(struct seq_file *f, void *p)
173{
174 struct hci_dev *hdev = f->private;
175 struct bt_uuid *uuid;
176
177 hci_dev_lock(hdev);
178 list_for_each_entry(uuid, &hdev->uuids, list) {
179 u8 i, val[16];
180
181 /* The Bluetooth UUID values are stored in big endian,
182 * but with reversed byte order. So convert them into
183 * the right order for the %pUb modifier.
184 */
185 for (i = 0; i < 16; i++)
186 val[i] = uuid->uuid[15 - i];
187
188 seq_printf(f, "%pUb\n", val);
189 }
190 hci_dev_unlock(hdev);
191
192 return 0;
193}
194
195static int uuids_open(struct inode *inode, struct file *file)
196{
197 return single_open(file, uuids_show, inode->i_private);
198}
199
200static const struct file_operations uuids_fops = {
201 .open = uuids_open,
202 .read = seq_read,
203 .llseek = seq_lseek,
204 .release = single_release,
205};
206
Marcel Holtmann6858bcd2015-01-31 21:01:07 -0800207static int remote_oob_show(struct seq_file *f, void *ptr)
208{
209 struct hci_dev *hdev = f->private;
210 struct oob_data *data;
211
212 hci_dev_lock(hdev);
213 list_for_each_entry(data, &hdev->remote_oob_data, list) {
214 seq_printf(f, "%pMR (type %u) %u %*phN %*phN %*phN %*phN\n",
215 &data->bdaddr, data->bdaddr_type, data->present,
216 16, data->hash192, 16, data->rand192,
Marcel Holtmannb880ab82015-03-16 12:34:58 -0700217 16, data->hash256, 16, data->rand256);
Marcel Holtmann6858bcd2015-01-31 21:01:07 -0800218 }
219 hci_dev_unlock(hdev);
220
221 return 0;
222}
223
224static int remote_oob_open(struct inode *inode, struct file *file)
225{
226 return single_open(file, remote_oob_show, inode->i_private);
227}
228
229static const struct file_operations remote_oob_fops = {
230 .open = remote_oob_open,
231 .read = seq_read,
232 .llseek = seq_lseek,
233 .release = single_release,
234};
235
Marcel Holtmann40ce72b2014-12-20 16:05:14 +0100236static int conn_info_min_age_set(void *data, u64 val)
237{
238 struct hci_dev *hdev = data;
239
240 if (val == 0 || val > hdev->conn_info_max_age)
241 return -EINVAL;
242
243 hci_dev_lock(hdev);
244 hdev->conn_info_min_age = val;
245 hci_dev_unlock(hdev);
246
247 return 0;
248}
249
250static int conn_info_min_age_get(void *data, u64 *val)
251{
252 struct hci_dev *hdev = data;
253
254 hci_dev_lock(hdev);
255 *val = hdev->conn_info_min_age;
256 hci_dev_unlock(hdev);
257
258 return 0;
259}
260
261DEFINE_SIMPLE_ATTRIBUTE(conn_info_min_age_fops, conn_info_min_age_get,
262 conn_info_min_age_set, "%llu\n");
263
264static int conn_info_max_age_set(void *data, u64 val)
265{
266 struct hci_dev *hdev = data;
267
268 if (val == 0 || val < hdev->conn_info_min_age)
269 return -EINVAL;
270
271 hci_dev_lock(hdev);
272 hdev->conn_info_max_age = val;
273 hci_dev_unlock(hdev);
274
275 return 0;
276}
277
278static int conn_info_max_age_get(void *data, u64 *val)
279{
280 struct hci_dev *hdev = data;
281
282 hci_dev_lock(hdev);
283 *val = hdev->conn_info_max_age;
284 hci_dev_unlock(hdev);
285
286 return 0;
287}
288
289DEFINE_SIMPLE_ATTRIBUTE(conn_info_max_age_fops, conn_info_max_age_get,
290 conn_info_max_age_set, "%llu\n");
291
Marcel Holtmann0886aea2015-01-31 15:12:06 -0800292static ssize_t use_debug_keys_read(struct file *file, char __user *user_buf,
293 size_t count, loff_t *ppos)
294{
295 struct hci_dev *hdev = file->private_data;
296 char buf[3];
297
Marcel Holtmannd7a5a112015-03-13 02:11:00 -0700298 buf[0] = hci_dev_test_flag(hdev, HCI_USE_DEBUG_KEYS) ? 'Y': 'N';
Marcel Holtmann0886aea2015-01-31 15:12:06 -0800299 buf[1] = '\n';
300 buf[2] = '\0';
301 return simple_read_from_buffer(user_buf, count, ppos, buf, 2);
302}
303
304static const struct file_operations use_debug_keys_fops = {
305 .open = simple_open,
306 .read = use_debug_keys_read,
307 .llseek = default_llseek,
308};
309
Marcel Holtmanncb0d2fa2014-12-31 14:43:19 -0800310static ssize_t sc_only_mode_read(struct file *file, char __user *user_buf,
311 size_t count, loff_t *ppos)
312{
313 struct hci_dev *hdev = file->private_data;
314 char buf[3];
315
Marcel Holtmannd7a5a112015-03-13 02:11:00 -0700316 buf[0] = hci_dev_test_flag(hdev, HCI_SC_ONLY) ? 'Y': 'N';
Marcel Holtmanncb0d2fa2014-12-31 14:43:19 -0800317 buf[1] = '\n';
318 buf[2] = '\0';
319 return simple_read_from_buffer(user_buf, count, ppos, buf, 2);
320}
321
322static const struct file_operations sc_only_mode_fops = {
323 .open = simple_open,
324 .read = sc_only_mode_read,
325 .llseek = default_llseek,
326};
327
Marcel Holtmann60c5f5f2014-12-20 16:05:13 +0100328void hci_debugfs_create_common(struct hci_dev *hdev)
329{
Marcel Holtmann40ce72b2014-12-20 16:05:14 +0100330 debugfs_create_file("features", 0444, hdev->debugfs, hdev,
331 &features_fops);
332 debugfs_create_u16("manufacturer", 0444, hdev->debugfs,
333 &hdev->manufacturer);
334 debugfs_create_u8("hci_version", 0444, hdev->debugfs, &hdev->hci_ver);
335 debugfs_create_u16("hci_revision", 0444, hdev->debugfs, &hdev->hci_rev);
Marcel Holtmann5789f372015-01-31 19:54:39 -0800336 debugfs_create_u8("hardware_error", 0444, hdev->debugfs,
337 &hdev->hw_error_code);
338
Marcel Holtmann40ce72b2014-12-20 16:05:14 +0100339 debugfs_create_file("device_list", 0444, hdev->debugfs, hdev,
340 &device_list_fops);
341 debugfs_create_file("blacklist", 0444, hdev->debugfs, hdev,
342 &blacklist_fops);
343 debugfs_create_file("uuids", 0444, hdev->debugfs, hdev, &uuids_fops);
Marcel Holtmann6858bcd2015-01-31 21:01:07 -0800344 debugfs_create_file("remote_oob", 0400, hdev->debugfs, hdev,
345 &remote_oob_fops);
Marcel Holtmann40ce72b2014-12-20 16:05:14 +0100346
347 debugfs_create_file("conn_info_min_age", 0644, hdev->debugfs, hdev,
348 &conn_info_min_age_fops);
349 debugfs_create_file("conn_info_max_age", 0644, hdev->debugfs, hdev,
350 &conn_info_max_age_fops);
Marcel Holtmanncb0d2fa2014-12-31 14:43:19 -0800351
Marcel Holtmann0886aea2015-01-31 15:12:06 -0800352 if (lmp_ssp_capable(hdev) || lmp_le_capable(hdev))
353 debugfs_create_file("use_debug_keys", 0444, hdev->debugfs,
354 hdev, &use_debug_keys_fops);
355
Marcel Holtmanncb0d2fa2014-12-31 14:43:19 -0800356 if (lmp_sc_capable(hdev) || lmp_le_capable(hdev))
357 debugfs_create_file("sc_only_mode", 0444, hdev->debugfs,
358 hdev, &sc_only_mode_fops);
Marcel Holtmann60c5f5f2014-12-20 16:05:13 +0100359}
360
Marcel Holtmann71c3b602014-12-20 16:05:15 +0100361static int inquiry_cache_show(struct seq_file *f, void *p)
362{
363 struct hci_dev *hdev = f->private;
364 struct discovery_state *cache = &hdev->discovery;
365 struct inquiry_entry *e;
366
367 hci_dev_lock(hdev);
368
369 list_for_each_entry(e, &cache->all, all) {
370 struct inquiry_data *data = &e->data;
371 seq_printf(f, "%pMR %d %d %d 0x%.2x%.2x%.2x 0x%.4x %d %d %u\n",
372 &data->bdaddr,
373 data->pscan_rep_mode, data->pscan_period_mode,
374 data->pscan_mode, data->dev_class[2],
375 data->dev_class[1], data->dev_class[0],
376 __le16_to_cpu(data->clock_offset),
377 data->rssi, data->ssp_mode, e->timestamp);
378 }
379
380 hci_dev_unlock(hdev);
381
382 return 0;
383}
384
385static int inquiry_cache_open(struct inode *inode, struct file *file)
386{
387 return single_open(file, inquiry_cache_show, inode->i_private);
388}
389
390static const struct file_operations inquiry_cache_fops = {
391 .open = inquiry_cache_open,
392 .read = seq_read,
393 .llseek = seq_lseek,
394 .release = single_release,
395};
396
397static int link_keys_show(struct seq_file *f, void *ptr)
398{
399 struct hci_dev *hdev = f->private;
400 struct link_key *key;
401
402 rcu_read_lock();
403 list_for_each_entry_rcu(key, &hdev->link_keys, list)
404 seq_printf(f, "%pMR %u %*phN %u\n", &key->bdaddr, key->type,
405 HCI_LINK_KEY_SIZE, key->val, key->pin_len);
406 rcu_read_unlock();
407
408 return 0;
409}
410
411static int link_keys_open(struct inode *inode, struct file *file)
412{
413 return single_open(file, link_keys_show, inode->i_private);
414}
415
416static const struct file_operations link_keys_fops = {
417 .open = link_keys_open,
418 .read = seq_read,
419 .llseek = seq_lseek,
420 .release = single_release,
421};
422
423static int dev_class_show(struct seq_file *f, void *ptr)
424{
425 struct hci_dev *hdev = f->private;
426
427 hci_dev_lock(hdev);
428 seq_printf(f, "0x%.2x%.2x%.2x\n", hdev->dev_class[2],
429 hdev->dev_class[1], hdev->dev_class[0]);
430 hci_dev_unlock(hdev);
431
432 return 0;
433}
434
435static int dev_class_open(struct inode *inode, struct file *file)
436{
437 return single_open(file, dev_class_show, inode->i_private);
438}
439
440static const struct file_operations dev_class_fops = {
441 .open = dev_class_open,
442 .read = seq_read,
443 .llseek = seq_lseek,
444 .release = single_release,
445};
446
447static int voice_setting_get(void *data, u64 *val)
448{
449 struct hci_dev *hdev = data;
450
451 hci_dev_lock(hdev);
452 *val = hdev->voice_setting;
453 hci_dev_unlock(hdev);
454
455 return 0;
456}
457
458DEFINE_SIMPLE_ATTRIBUTE(voice_setting_fops, voice_setting_get,
459 NULL, "0x%4.4llx\n");
460
Marcel Holtmann6e072312015-01-31 15:07:51 -0800461static ssize_t ssp_debug_mode_read(struct file *file, char __user *user_buf,
462 size_t count, loff_t *ppos)
463{
464 struct hci_dev *hdev = file->private_data;
465 char buf[3];
466
467 buf[0] = hdev->ssp_debug_mode ? 'Y': 'N';
468 buf[1] = '\n';
469 buf[2] = '\0';
470 return simple_read_from_buffer(user_buf, count, ppos, buf, 2);
471}
472
473static const struct file_operations ssp_debug_mode_fops = {
474 .open = simple_open,
475 .read = ssp_debug_mode_read,
476 .llseek = default_llseek,
477};
478
Marcel Holtmann71c3b602014-12-20 16:05:15 +0100479static int auto_accept_delay_set(void *data, u64 val)
480{
481 struct hci_dev *hdev = data;
482
483 hci_dev_lock(hdev);
484 hdev->auto_accept_delay = val;
485 hci_dev_unlock(hdev);
486
487 return 0;
488}
489
490static int auto_accept_delay_get(void *data, u64 *val)
491{
492 struct hci_dev *hdev = data;
493
494 hci_dev_lock(hdev);
495 *val = hdev->auto_accept_delay;
496 hci_dev_unlock(hdev);
497
498 return 0;
499}
500
501DEFINE_SIMPLE_ATTRIBUTE(auto_accept_delay_fops, auto_accept_delay_get,
502 auto_accept_delay_set, "%llu\n");
503
Marcel Holtmann71c3b602014-12-20 16:05:15 +0100504static int idle_timeout_set(void *data, u64 val)
505{
506 struct hci_dev *hdev = data;
507
508 if (val != 0 && (val < 500 || val > 3600000))
509 return -EINVAL;
510
511 hci_dev_lock(hdev);
512 hdev->idle_timeout = val;
513 hci_dev_unlock(hdev);
514
515 return 0;
516}
517
518static int idle_timeout_get(void *data, u64 *val)
519{
520 struct hci_dev *hdev = data;
521
522 hci_dev_lock(hdev);
523 *val = hdev->idle_timeout;
524 hci_dev_unlock(hdev);
525
526 return 0;
527}
528
529DEFINE_SIMPLE_ATTRIBUTE(idle_timeout_fops, idle_timeout_get,
530 idle_timeout_set, "%llu\n");
531
532static int sniff_min_interval_set(void *data, u64 val)
533{
534 struct hci_dev *hdev = data;
535
536 if (val == 0 || val % 2 || val > hdev->sniff_max_interval)
537 return -EINVAL;
538
539 hci_dev_lock(hdev);
540 hdev->sniff_min_interval = val;
541 hci_dev_unlock(hdev);
542
543 return 0;
544}
545
546static int sniff_min_interval_get(void *data, u64 *val)
547{
548 struct hci_dev *hdev = data;
549
550 hci_dev_lock(hdev);
551 *val = hdev->sniff_min_interval;
552 hci_dev_unlock(hdev);
553
554 return 0;
555}
556
557DEFINE_SIMPLE_ATTRIBUTE(sniff_min_interval_fops, sniff_min_interval_get,
558 sniff_min_interval_set, "%llu\n");
559
560static int sniff_max_interval_set(void *data, u64 val)
561{
562 struct hci_dev *hdev = data;
563
564 if (val == 0 || val % 2 || val < hdev->sniff_min_interval)
565 return -EINVAL;
566
567 hci_dev_lock(hdev);
568 hdev->sniff_max_interval = val;
569 hci_dev_unlock(hdev);
570
571 return 0;
572}
573
574static int sniff_max_interval_get(void *data, u64 *val)
575{
576 struct hci_dev *hdev = data;
577
578 hci_dev_lock(hdev);
579 *val = hdev->sniff_max_interval;
580 hci_dev_unlock(hdev);
581
582 return 0;
583}
584
585DEFINE_SIMPLE_ATTRIBUTE(sniff_max_interval_fops, sniff_max_interval_get,
586 sniff_max_interval_set, "%llu\n");
587
Marcel Holtmann60c5f5f2014-12-20 16:05:13 +0100588void hci_debugfs_create_bredr(struct hci_dev *hdev)
589{
Marcel Holtmann71c3b602014-12-20 16:05:15 +0100590 debugfs_create_file("inquiry_cache", 0444, hdev->debugfs, hdev,
591 &inquiry_cache_fops);
592 debugfs_create_file("link_keys", 0400, hdev->debugfs, hdev,
593 &link_keys_fops);
594 debugfs_create_file("dev_class", 0444, hdev->debugfs, hdev,
595 &dev_class_fops);
596 debugfs_create_file("voice_setting", 0444, hdev->debugfs, hdev,
597 &voice_setting_fops);
598
Marcel Holtmann6e072312015-01-31 15:07:51 -0800599 if (lmp_ssp_capable(hdev)) {
600 debugfs_create_file("ssp_debug_mode", 0444, hdev->debugfs,
601 hdev, &ssp_debug_mode_fops);
Marcel Holtmann71c3b602014-12-20 16:05:15 +0100602 debugfs_create_file("auto_accept_delay", 0644, hdev->debugfs,
603 hdev, &auto_accept_delay_fops);
Marcel Holtmann6e072312015-01-31 15:07:51 -0800604 }
Marcel Holtmann71c3b602014-12-20 16:05:15 +0100605
606 if (lmp_sniff_capable(hdev)) {
607 debugfs_create_file("idle_timeout", 0644, hdev->debugfs,
608 hdev, &idle_timeout_fops);
609 debugfs_create_file("sniff_min_interval", 0644, hdev->debugfs,
610 hdev, &sniff_min_interval_fops);
611 debugfs_create_file("sniff_max_interval", 0644, hdev->debugfs,
612 hdev, &sniff_max_interval_fops);
613 }
Marcel Holtmann60c5f5f2014-12-20 16:05:13 +0100614}
615
Marcel Holtmann3a5c82b2014-12-20 16:05:16 +0100616static int identity_show(struct seq_file *f, void *p)
617{
618 struct hci_dev *hdev = f->private;
619 bdaddr_t addr;
620 u8 addr_type;
621
622 hci_dev_lock(hdev);
623
624 hci_copy_identity_address(hdev, &addr, &addr_type);
625
626 seq_printf(f, "%pMR (type %u) %*phN %pMR\n", &addr, addr_type,
627 16, hdev->irk, &hdev->rpa);
628
629 hci_dev_unlock(hdev);
630
631 return 0;
632}
633
634static int identity_open(struct inode *inode, struct file *file)
635{
636 return single_open(file, identity_show, inode->i_private);
637}
638
639static const struct file_operations identity_fops = {
640 .open = identity_open,
641 .read = seq_read,
642 .llseek = seq_lseek,
643 .release = single_release,
644};
645
646static int rpa_timeout_set(void *data, u64 val)
647{
648 struct hci_dev *hdev = data;
649
650 /* Require the RPA timeout to be at least 30 seconds and at most
651 * 24 hours.
652 */
653 if (val < 30 || val > (60 * 60 * 24))
654 return -EINVAL;
655
656 hci_dev_lock(hdev);
657 hdev->rpa_timeout = val;
658 hci_dev_unlock(hdev);
659
660 return 0;
661}
662
663static int rpa_timeout_get(void *data, u64 *val)
664{
665 struct hci_dev *hdev = data;
666
667 hci_dev_lock(hdev);
668 *val = hdev->rpa_timeout;
669 hci_dev_unlock(hdev);
670
671 return 0;
672}
673
674DEFINE_SIMPLE_ATTRIBUTE(rpa_timeout_fops, rpa_timeout_get,
675 rpa_timeout_set, "%llu\n");
676
677static int random_address_show(struct seq_file *f, void *p)
678{
679 struct hci_dev *hdev = f->private;
680
681 hci_dev_lock(hdev);
682 seq_printf(f, "%pMR\n", &hdev->random_addr);
683 hci_dev_unlock(hdev);
684
685 return 0;
686}
687
688static int random_address_open(struct inode *inode, struct file *file)
689{
690 return single_open(file, random_address_show, inode->i_private);
691}
692
693static const struct file_operations random_address_fops = {
694 .open = random_address_open,
695 .read = seq_read,
696 .llseek = seq_lseek,
697 .release = single_release,
698};
699
700static int static_address_show(struct seq_file *f, void *p)
701{
702 struct hci_dev *hdev = f->private;
703
704 hci_dev_lock(hdev);
705 seq_printf(f, "%pMR\n", &hdev->static_addr);
706 hci_dev_unlock(hdev);
707
708 return 0;
709}
710
711static int static_address_open(struct inode *inode, struct file *file)
712{
713 return single_open(file, static_address_show, inode->i_private);
714}
715
716static const struct file_operations static_address_fops = {
717 .open = static_address_open,
718 .read = seq_read,
719 .llseek = seq_lseek,
720 .release = single_release,
721};
722
723static ssize_t force_static_address_read(struct file *file,
724 char __user *user_buf,
725 size_t count, loff_t *ppos)
726{
727 struct hci_dev *hdev = file->private_data;
728 char buf[3];
729
Marcel Holtmannb7cb93e2015-03-13 10:20:35 -0700730 buf[0] = hci_dev_test_flag(hdev, HCI_FORCE_STATIC_ADDR) ? 'Y': 'N';
Marcel Holtmann3a5c82b2014-12-20 16:05:16 +0100731 buf[1] = '\n';
732 buf[2] = '\0';
733 return simple_read_from_buffer(user_buf, count, ppos, buf, 2);
734}
735
736static ssize_t force_static_address_write(struct file *file,
737 const char __user *user_buf,
738 size_t count, loff_t *ppos)
739{
740 struct hci_dev *hdev = file->private_data;
741 char buf[32];
742 size_t buf_size = min(count, (sizeof(buf)-1));
743 bool enable;
744
745 if (test_bit(HCI_UP, &hdev->flags))
746 return -EBUSY;
747
748 if (copy_from_user(buf, user_buf, buf_size))
749 return -EFAULT;
750
751 buf[buf_size] = '\0';
752 if (strtobool(buf, &enable))
753 return -EINVAL;
754
Marcel Holtmannb7cb93e2015-03-13 10:20:35 -0700755 if (enable == hci_dev_test_flag(hdev, HCI_FORCE_STATIC_ADDR))
Marcel Holtmann3a5c82b2014-12-20 16:05:16 +0100756 return -EALREADY;
757
Marcel Holtmannb7cb93e2015-03-13 10:20:35 -0700758 hci_dev_change_flag(hdev, HCI_FORCE_STATIC_ADDR);
Marcel Holtmann3a5c82b2014-12-20 16:05:16 +0100759
760 return count;
761}
762
763static const struct file_operations force_static_address_fops = {
764 .open = simple_open,
765 .read = force_static_address_read,
766 .write = force_static_address_write,
767 .llseek = default_llseek,
768};
769
770static int white_list_show(struct seq_file *f, void *ptr)
771{
772 struct hci_dev *hdev = f->private;
773 struct bdaddr_list *b;
774
775 hci_dev_lock(hdev);
776 list_for_each_entry(b, &hdev->le_white_list, list)
777 seq_printf(f, "%pMR (type %u)\n", &b->bdaddr, b->bdaddr_type);
778 hci_dev_unlock(hdev);
779
780 return 0;
781}
782
783static int white_list_open(struct inode *inode, struct file *file)
784{
785 return single_open(file, white_list_show, inode->i_private);
786}
787
788static const struct file_operations white_list_fops = {
789 .open = white_list_open,
790 .read = seq_read,
791 .llseek = seq_lseek,
792 .release = single_release,
793};
794
795static int identity_resolving_keys_show(struct seq_file *f, void *ptr)
796{
797 struct hci_dev *hdev = f->private;
798 struct smp_irk *irk;
799
800 rcu_read_lock();
801 list_for_each_entry_rcu(irk, &hdev->identity_resolving_keys, list) {
802 seq_printf(f, "%pMR (type %u) %*phN %pMR\n",
803 &irk->bdaddr, irk->addr_type,
804 16, irk->val, &irk->rpa);
805 }
806 rcu_read_unlock();
807
808 return 0;
809}
810
811static int identity_resolving_keys_open(struct inode *inode, struct file *file)
812{
813 return single_open(file, identity_resolving_keys_show,
814 inode->i_private);
815}
816
817static const struct file_operations identity_resolving_keys_fops = {
818 .open = identity_resolving_keys_open,
819 .read = seq_read,
820 .llseek = seq_lseek,
821 .release = single_release,
822};
823
824static int long_term_keys_show(struct seq_file *f, void *ptr)
825{
826 struct hci_dev *hdev = f->private;
827 struct smp_ltk *ltk;
828
829 rcu_read_lock();
830 list_for_each_entry_rcu(ltk, &hdev->long_term_keys, list)
831 seq_printf(f, "%pMR (type %u) %u 0x%02x %u %.4x %.16llx %*phN\n",
832 &ltk->bdaddr, ltk->bdaddr_type, ltk->authenticated,
833 ltk->type, ltk->enc_size, __le16_to_cpu(ltk->ediv),
834 __le64_to_cpu(ltk->rand), 16, ltk->val);
835 rcu_read_unlock();
836
837 return 0;
838}
839
840static int long_term_keys_open(struct inode *inode, struct file *file)
841{
842 return single_open(file, long_term_keys_show, inode->i_private);
843}
844
845static const struct file_operations long_term_keys_fops = {
846 .open = long_term_keys_open,
847 .read = seq_read,
848 .llseek = seq_lseek,
849 .release = single_release,
850};
851
852static int conn_min_interval_set(void *data, u64 val)
853{
854 struct hci_dev *hdev = data;
855
856 if (val < 0x0006 || val > 0x0c80 || val > hdev->le_conn_max_interval)
857 return -EINVAL;
858
859 hci_dev_lock(hdev);
860 hdev->le_conn_min_interval = val;
861 hci_dev_unlock(hdev);
862
863 return 0;
864}
865
866static int conn_min_interval_get(void *data, u64 *val)
867{
868 struct hci_dev *hdev = data;
869
870 hci_dev_lock(hdev);
871 *val = hdev->le_conn_min_interval;
872 hci_dev_unlock(hdev);
873
874 return 0;
875}
876
877DEFINE_SIMPLE_ATTRIBUTE(conn_min_interval_fops, conn_min_interval_get,
878 conn_min_interval_set, "%llu\n");
879
880static int conn_max_interval_set(void *data, u64 val)
881{
882 struct hci_dev *hdev = data;
883
884 if (val < 0x0006 || val > 0x0c80 || val < hdev->le_conn_min_interval)
885 return -EINVAL;
886
887 hci_dev_lock(hdev);
888 hdev->le_conn_max_interval = val;
889 hci_dev_unlock(hdev);
890
891 return 0;
892}
893
894static int conn_max_interval_get(void *data, u64 *val)
895{
896 struct hci_dev *hdev = data;
897
898 hci_dev_lock(hdev);
899 *val = hdev->le_conn_max_interval;
900 hci_dev_unlock(hdev);
901
902 return 0;
903}
904
905DEFINE_SIMPLE_ATTRIBUTE(conn_max_interval_fops, conn_max_interval_get,
906 conn_max_interval_set, "%llu\n");
907
908static int conn_latency_set(void *data, u64 val)
909{
910 struct hci_dev *hdev = data;
911
912 if (val > 0x01f3)
913 return -EINVAL;
914
915 hci_dev_lock(hdev);
916 hdev->le_conn_latency = val;
917 hci_dev_unlock(hdev);
918
919 return 0;
920}
921
922static int conn_latency_get(void *data, u64 *val)
923{
924 struct hci_dev *hdev = data;
925
926 hci_dev_lock(hdev);
927 *val = hdev->le_conn_latency;
928 hci_dev_unlock(hdev);
929
930 return 0;
931}
932
933DEFINE_SIMPLE_ATTRIBUTE(conn_latency_fops, conn_latency_get,
934 conn_latency_set, "%llu\n");
935
936static int supervision_timeout_set(void *data, u64 val)
937{
938 struct hci_dev *hdev = data;
939
940 if (val < 0x000a || val > 0x0c80)
941 return -EINVAL;
942
943 hci_dev_lock(hdev);
944 hdev->le_supv_timeout = val;
945 hci_dev_unlock(hdev);
946
947 return 0;
948}
949
950static int supervision_timeout_get(void *data, u64 *val)
951{
952 struct hci_dev *hdev = data;
953
954 hci_dev_lock(hdev);
955 *val = hdev->le_supv_timeout;
956 hci_dev_unlock(hdev);
957
958 return 0;
959}
960
961DEFINE_SIMPLE_ATTRIBUTE(supervision_timeout_fops, supervision_timeout_get,
962 supervision_timeout_set, "%llu\n");
963
964static int adv_channel_map_set(void *data, u64 val)
965{
966 struct hci_dev *hdev = data;
967
968 if (val < 0x01 || val > 0x07)
969 return -EINVAL;
970
971 hci_dev_lock(hdev);
972 hdev->le_adv_channel_map = val;
973 hci_dev_unlock(hdev);
974
975 return 0;
976}
977
978static int adv_channel_map_get(void *data, u64 *val)
979{
980 struct hci_dev *hdev = data;
981
982 hci_dev_lock(hdev);
983 *val = hdev->le_adv_channel_map;
984 hci_dev_unlock(hdev);
985
986 return 0;
987}
988
989DEFINE_SIMPLE_ATTRIBUTE(adv_channel_map_fops, adv_channel_map_get,
990 adv_channel_map_set, "%llu\n");
991
992static int adv_min_interval_set(void *data, u64 val)
993{
994 struct hci_dev *hdev = data;
995
996 if (val < 0x0020 || val > 0x4000 || val > hdev->le_adv_max_interval)
997 return -EINVAL;
998
999 hci_dev_lock(hdev);
1000 hdev->le_adv_min_interval = val;
1001 hci_dev_unlock(hdev);
1002
1003 return 0;
1004}
1005
1006static int adv_min_interval_get(void *data, u64 *val)
1007{
1008 struct hci_dev *hdev = data;
1009
1010 hci_dev_lock(hdev);
1011 *val = hdev->le_adv_min_interval;
1012 hci_dev_unlock(hdev);
1013
1014 return 0;
1015}
1016
1017DEFINE_SIMPLE_ATTRIBUTE(adv_min_interval_fops, adv_min_interval_get,
1018 adv_min_interval_set, "%llu\n");
1019
1020static int adv_max_interval_set(void *data, u64 val)
1021{
1022 struct hci_dev *hdev = data;
1023
1024 if (val < 0x0020 || val > 0x4000 || val < hdev->le_adv_min_interval)
1025 return -EINVAL;
1026
1027 hci_dev_lock(hdev);
1028 hdev->le_adv_max_interval = val;
1029 hci_dev_unlock(hdev);
1030
1031 return 0;
1032}
1033
1034static int adv_max_interval_get(void *data, u64 *val)
1035{
1036 struct hci_dev *hdev = data;
1037
1038 hci_dev_lock(hdev);
1039 *val = hdev->le_adv_max_interval;
1040 hci_dev_unlock(hdev);
1041
1042 return 0;
1043}
1044
1045DEFINE_SIMPLE_ATTRIBUTE(adv_max_interval_fops, adv_max_interval_get,
1046 adv_max_interval_set, "%llu\n");
1047
Jakub Pawlowskib55d1ab2015-03-20 11:14:50 -07001048DEFINE_QUIRK_ATTRIBUTE(quirk_strict_duplicate_filter,
1049 HCI_QUIRK_STRICT_DUPLICATE_FILTER);
1050DEFINE_QUIRK_ATTRIBUTE(quirk_simultaneous_discovery,
1051 HCI_QUIRK_SIMULTANEOUS_DISCOVERY);
1052
Marcel Holtmann60c5f5f2014-12-20 16:05:13 +01001053void hci_debugfs_create_le(struct hci_dev *hdev)
1054{
Marcel Holtmann3a5c82b2014-12-20 16:05:16 +01001055 debugfs_create_file("identity", 0400, hdev->debugfs, hdev,
1056 &identity_fops);
1057 debugfs_create_file("rpa_timeout", 0644, hdev->debugfs, hdev,
1058 &rpa_timeout_fops);
1059 debugfs_create_file("random_address", 0444, hdev->debugfs, hdev,
1060 &random_address_fops);
1061 debugfs_create_file("static_address", 0444, hdev->debugfs, hdev,
1062 &static_address_fops);
1063
1064 /* For controllers with a public address, provide a debug
1065 * option to force the usage of the configured static
1066 * address. By default the public address is used.
1067 */
1068 if (bacmp(&hdev->bdaddr, BDADDR_ANY))
1069 debugfs_create_file("force_static_address", 0644,
1070 hdev->debugfs, hdev,
1071 &force_static_address_fops);
1072
1073 debugfs_create_u8("white_list_size", 0444, hdev->debugfs,
1074 &hdev->le_white_list_size);
1075 debugfs_create_file("white_list", 0444, hdev->debugfs, hdev,
1076 &white_list_fops);
1077 debugfs_create_file("identity_resolving_keys", 0400, hdev->debugfs,
1078 hdev, &identity_resolving_keys_fops);
1079 debugfs_create_file("long_term_keys", 0400, hdev->debugfs, hdev,
1080 &long_term_keys_fops);
1081 debugfs_create_file("conn_min_interval", 0644, hdev->debugfs, hdev,
1082 &conn_min_interval_fops);
1083 debugfs_create_file("conn_max_interval", 0644, hdev->debugfs, hdev,
1084 &conn_max_interval_fops);
1085 debugfs_create_file("conn_latency", 0644, hdev->debugfs, hdev,
1086 &conn_latency_fops);
1087 debugfs_create_file("supervision_timeout", 0644, hdev->debugfs, hdev,
1088 &supervision_timeout_fops);
1089 debugfs_create_file("adv_channel_map", 0644, hdev->debugfs, hdev,
1090 &adv_channel_map_fops);
1091 debugfs_create_file("adv_min_interval", 0644, hdev->debugfs, hdev,
1092 &adv_min_interval_fops);
1093 debugfs_create_file("adv_max_interval", 0644, hdev->debugfs, hdev,
1094 &adv_max_interval_fops);
1095 debugfs_create_u16("discov_interleaved_timeout", 0644, hdev->debugfs,
1096 &hdev->discov_interleaved_timeout);
Jakub Pawlowskib55d1ab2015-03-20 11:14:50 -07001097
1098 debugfs_create_file("quirk_strict_duplicate_filter", 0644,
1099 hdev->debugfs, hdev,
1100 &quirk_strict_duplicate_filter_fops);
1101 debugfs_create_file("quirk_simultaneous_discovery", 0644,
1102 hdev->debugfs, hdev,
1103 &quirk_simultaneous_discovery_fops);
Marcel Holtmann60c5f5f2014-12-20 16:05:13 +01001104}
Marcel Holtmann23b9ceb2014-12-20 17:13:41 +01001105
1106void hci_debugfs_create_conn(struct hci_conn *conn)
1107{
1108 struct hci_dev *hdev = conn->hdev;
1109 char name[6];
1110
1111 if (IS_ERR_OR_NULL(hdev->debugfs))
1112 return;
1113
1114 snprintf(name, sizeof(name), "%u", conn->handle);
1115 conn->debugfs = debugfs_create_dir(name, hdev->debugfs);
1116}