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