Bluetooth: Expose hardware error code as debugfs entry
[deliverable/linux.git] / net / bluetooth / hci_debugfs.c
CommitLineData
60c5f5fb
MH
1/*
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
40ce72b1
MH
31static 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
0886aea6
MH
215static 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
cb0d2fae
MH
233static 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
60c5f5fb
MH
251void hci_debugfs_create_common(struct hci_dev *hdev)
252{
40ce72b1
MH
253 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);
5789f37c
MH
259 debugfs_create_u8("hardware_error", 0444, hdev->debugfs,
260 &hdev->hw_error_code);
261
40ce72b1
MH
262 debugfs_create_file("device_list", 0444, hdev->debugfs, hdev,
263 &device_list_fops);
264 debugfs_create_file("blacklist", 0444, hdev->debugfs, hdev,
265 &blacklist_fops);
266 debugfs_create_file("uuids", 0444, hdev->debugfs, hdev, &uuids_fops);
267
268 debugfs_create_file("conn_info_min_age", 0644, hdev->debugfs, hdev,
269 &conn_info_min_age_fops);
270 debugfs_create_file("conn_info_max_age", 0644, hdev->debugfs, hdev,
271 &conn_info_max_age_fops);
cb0d2fae 272
0886aea6
MH
273 if (lmp_ssp_capable(hdev) || lmp_le_capable(hdev))
274 debugfs_create_file("use_debug_keys", 0444, hdev->debugfs,
275 hdev, &use_debug_keys_fops);
276
cb0d2fae
MH
277 if (lmp_sc_capable(hdev) || lmp_le_capable(hdev))
278 debugfs_create_file("sc_only_mode", 0444, hdev->debugfs,
279 hdev, &sc_only_mode_fops);
60c5f5fb
MH
280}
281
71c3b60e
MH
282static int inquiry_cache_show(struct seq_file *f, void *p)
283{
284 struct hci_dev *hdev = f->private;
285 struct discovery_state *cache = &hdev->discovery;
286 struct inquiry_entry *e;
287
288 hci_dev_lock(hdev);
289
290 list_for_each_entry(e, &cache->all, all) {
291 struct inquiry_data *data = &e->data;
292 seq_printf(f, "%pMR %d %d %d 0x%.2x%.2x%.2x 0x%.4x %d %d %u\n",
293 &data->bdaddr,
294 data->pscan_rep_mode, data->pscan_period_mode,
295 data->pscan_mode, data->dev_class[2],
296 data->dev_class[1], data->dev_class[0],
297 __le16_to_cpu(data->clock_offset),
298 data->rssi, data->ssp_mode, e->timestamp);
299 }
300
301 hci_dev_unlock(hdev);
302
303 return 0;
304}
305
306static int inquiry_cache_open(struct inode *inode, struct file *file)
307{
308 return single_open(file, inquiry_cache_show, inode->i_private);
309}
310
311static const struct file_operations inquiry_cache_fops = {
312 .open = inquiry_cache_open,
313 .read = seq_read,
314 .llseek = seq_lseek,
315 .release = single_release,
316};
317
318static int link_keys_show(struct seq_file *f, void *ptr)
319{
320 struct hci_dev *hdev = f->private;
321 struct link_key *key;
322
323 rcu_read_lock();
324 list_for_each_entry_rcu(key, &hdev->link_keys, list)
325 seq_printf(f, "%pMR %u %*phN %u\n", &key->bdaddr, key->type,
326 HCI_LINK_KEY_SIZE, key->val, key->pin_len);
327 rcu_read_unlock();
328
329 return 0;
330}
331
332static int link_keys_open(struct inode *inode, struct file *file)
333{
334 return single_open(file, link_keys_show, inode->i_private);
335}
336
337static const struct file_operations link_keys_fops = {
338 .open = link_keys_open,
339 .read = seq_read,
340 .llseek = seq_lseek,
341 .release = single_release,
342};
343
344static int dev_class_show(struct seq_file *f, void *ptr)
345{
346 struct hci_dev *hdev = f->private;
347
348 hci_dev_lock(hdev);
349 seq_printf(f, "0x%.2x%.2x%.2x\n", hdev->dev_class[2],
350 hdev->dev_class[1], hdev->dev_class[0]);
351 hci_dev_unlock(hdev);
352
353 return 0;
354}
355
356static int dev_class_open(struct inode *inode, struct file *file)
357{
358 return single_open(file, dev_class_show, inode->i_private);
359}
360
361static const struct file_operations dev_class_fops = {
362 .open = dev_class_open,
363 .read = seq_read,
364 .llseek = seq_lseek,
365 .release = single_release,
366};
367
368static int voice_setting_get(void *data, u64 *val)
369{
370 struct hci_dev *hdev = data;
371
372 hci_dev_lock(hdev);
373 *val = hdev->voice_setting;
374 hci_dev_unlock(hdev);
375
376 return 0;
377}
378
379DEFINE_SIMPLE_ATTRIBUTE(voice_setting_fops, voice_setting_get,
380 NULL, "0x%4.4llx\n");
381
6e07231a
MH
382static ssize_t ssp_debug_mode_read(struct file *file, char __user *user_buf,
383 size_t count, loff_t *ppos)
384{
385 struct hci_dev *hdev = file->private_data;
386 char buf[3];
387
388 buf[0] = hdev->ssp_debug_mode ? 'Y': 'N';
389 buf[1] = '\n';
390 buf[2] = '\0';
391 return simple_read_from_buffer(user_buf, count, ppos, buf, 2);
392}
393
394static const struct file_operations ssp_debug_mode_fops = {
395 .open = simple_open,
396 .read = ssp_debug_mode_read,
397 .llseek = default_llseek,
398};
399
71c3b60e
MH
400static int auto_accept_delay_set(void *data, u64 val)
401{
402 struct hci_dev *hdev = data;
403
404 hci_dev_lock(hdev);
405 hdev->auto_accept_delay = val;
406 hci_dev_unlock(hdev);
407
408 return 0;
409}
410
411static int auto_accept_delay_get(void *data, u64 *val)
412{
413 struct hci_dev *hdev = data;
414
415 hci_dev_lock(hdev);
416 *val = hdev->auto_accept_delay;
417 hci_dev_unlock(hdev);
418
419 return 0;
420}
421
422DEFINE_SIMPLE_ATTRIBUTE(auto_accept_delay_fops, auto_accept_delay_get,
423 auto_accept_delay_set, "%llu\n");
424
71c3b60e
MH
425static int idle_timeout_set(void *data, u64 val)
426{
427 struct hci_dev *hdev = data;
428
429 if (val != 0 && (val < 500 || val > 3600000))
430 return -EINVAL;
431
432 hci_dev_lock(hdev);
433 hdev->idle_timeout = val;
434 hci_dev_unlock(hdev);
435
436 return 0;
437}
438
439static int idle_timeout_get(void *data, u64 *val)
440{
441 struct hci_dev *hdev = data;
442
443 hci_dev_lock(hdev);
444 *val = hdev->idle_timeout;
445 hci_dev_unlock(hdev);
446
447 return 0;
448}
449
450DEFINE_SIMPLE_ATTRIBUTE(idle_timeout_fops, idle_timeout_get,
451 idle_timeout_set, "%llu\n");
452
453static int sniff_min_interval_set(void *data, u64 val)
454{
455 struct hci_dev *hdev = data;
456
457 if (val == 0 || val % 2 || val > hdev->sniff_max_interval)
458 return -EINVAL;
459
460 hci_dev_lock(hdev);
461 hdev->sniff_min_interval = val;
462 hci_dev_unlock(hdev);
463
464 return 0;
465}
466
467static int sniff_min_interval_get(void *data, u64 *val)
468{
469 struct hci_dev *hdev = data;
470
471 hci_dev_lock(hdev);
472 *val = hdev->sniff_min_interval;
473 hci_dev_unlock(hdev);
474
475 return 0;
476}
477
478DEFINE_SIMPLE_ATTRIBUTE(sniff_min_interval_fops, sniff_min_interval_get,
479 sniff_min_interval_set, "%llu\n");
480
481static int sniff_max_interval_set(void *data, u64 val)
482{
483 struct hci_dev *hdev = data;
484
485 if (val == 0 || val % 2 || val < hdev->sniff_min_interval)
486 return -EINVAL;
487
488 hci_dev_lock(hdev);
489 hdev->sniff_max_interval = val;
490 hci_dev_unlock(hdev);
491
492 return 0;
493}
494
495static int sniff_max_interval_get(void *data, u64 *val)
496{
497 struct hci_dev *hdev = data;
498
499 hci_dev_lock(hdev);
500 *val = hdev->sniff_max_interval;
501 hci_dev_unlock(hdev);
502
503 return 0;
504}
505
506DEFINE_SIMPLE_ATTRIBUTE(sniff_max_interval_fops, sniff_max_interval_get,
507 sniff_max_interval_set, "%llu\n");
508
60c5f5fb
MH
509void hci_debugfs_create_bredr(struct hci_dev *hdev)
510{
71c3b60e
MH
511 debugfs_create_file("inquiry_cache", 0444, hdev->debugfs, hdev,
512 &inquiry_cache_fops);
513 debugfs_create_file("link_keys", 0400, hdev->debugfs, hdev,
514 &link_keys_fops);
515 debugfs_create_file("dev_class", 0444, hdev->debugfs, hdev,
516 &dev_class_fops);
517 debugfs_create_file("voice_setting", 0444, hdev->debugfs, hdev,
518 &voice_setting_fops);
519
6e07231a
MH
520 if (lmp_ssp_capable(hdev)) {
521 debugfs_create_file("ssp_debug_mode", 0444, hdev->debugfs,
522 hdev, &ssp_debug_mode_fops);
71c3b60e
MH
523 debugfs_create_file("auto_accept_delay", 0644, hdev->debugfs,
524 hdev, &auto_accept_delay_fops);
6e07231a 525 }
71c3b60e
MH
526
527 if (lmp_sniff_capable(hdev)) {
528 debugfs_create_file("idle_timeout", 0644, hdev->debugfs,
529 hdev, &idle_timeout_fops);
530 debugfs_create_file("sniff_min_interval", 0644, hdev->debugfs,
531 hdev, &sniff_min_interval_fops);
532 debugfs_create_file("sniff_max_interval", 0644, hdev->debugfs,
533 hdev, &sniff_max_interval_fops);
534 }
60c5f5fb
MH
535}
536
3a5c82b7
MH
537static int identity_show(struct seq_file *f, void *p)
538{
539 struct hci_dev *hdev = f->private;
540 bdaddr_t addr;
541 u8 addr_type;
542
543 hci_dev_lock(hdev);
544
545 hci_copy_identity_address(hdev, &addr, &addr_type);
546
547 seq_printf(f, "%pMR (type %u) %*phN %pMR\n", &addr, addr_type,
548 16, hdev->irk, &hdev->rpa);
549
550 hci_dev_unlock(hdev);
551
552 return 0;
553}
554
555static int identity_open(struct inode *inode, struct file *file)
556{
557 return single_open(file, identity_show, inode->i_private);
558}
559
560static const struct file_operations identity_fops = {
561 .open = identity_open,
562 .read = seq_read,
563 .llseek = seq_lseek,
564 .release = single_release,
565};
566
567static int rpa_timeout_set(void *data, u64 val)
568{
569 struct hci_dev *hdev = data;
570
571 /* Require the RPA timeout to be at least 30 seconds and at most
572 * 24 hours.
573 */
574 if (val < 30 || val > (60 * 60 * 24))
575 return -EINVAL;
576
577 hci_dev_lock(hdev);
578 hdev->rpa_timeout = val;
579 hci_dev_unlock(hdev);
580
581 return 0;
582}
583
584static int rpa_timeout_get(void *data, u64 *val)
585{
586 struct hci_dev *hdev = data;
587
588 hci_dev_lock(hdev);
589 *val = hdev->rpa_timeout;
590 hci_dev_unlock(hdev);
591
592 return 0;
593}
594
595DEFINE_SIMPLE_ATTRIBUTE(rpa_timeout_fops, rpa_timeout_get,
596 rpa_timeout_set, "%llu\n");
597
598static int random_address_show(struct seq_file *f, void *p)
599{
600 struct hci_dev *hdev = f->private;
601
602 hci_dev_lock(hdev);
603 seq_printf(f, "%pMR\n", &hdev->random_addr);
604 hci_dev_unlock(hdev);
605
606 return 0;
607}
608
609static int random_address_open(struct inode *inode, struct file *file)
610{
611 return single_open(file, random_address_show, inode->i_private);
612}
613
614static const struct file_operations random_address_fops = {
615 .open = random_address_open,
616 .read = seq_read,
617 .llseek = seq_lseek,
618 .release = single_release,
619};
620
621static int static_address_show(struct seq_file *f, void *p)
622{
623 struct hci_dev *hdev = f->private;
624
625 hci_dev_lock(hdev);
626 seq_printf(f, "%pMR\n", &hdev->static_addr);
627 hci_dev_unlock(hdev);
628
629 return 0;
630}
631
632static int static_address_open(struct inode *inode, struct file *file)
633{
634 return single_open(file, static_address_show, inode->i_private);
635}
636
637static const struct file_operations static_address_fops = {
638 .open = static_address_open,
639 .read = seq_read,
640 .llseek = seq_lseek,
641 .release = single_release,
642};
643
644static ssize_t force_static_address_read(struct file *file,
645 char __user *user_buf,
646 size_t count, loff_t *ppos)
647{
648 struct hci_dev *hdev = file->private_data;
649 char buf[3];
650
651 buf[0] = test_bit(HCI_FORCE_STATIC_ADDR, &hdev->dbg_flags) ? 'Y': 'N';
652 buf[1] = '\n';
653 buf[2] = '\0';
654 return simple_read_from_buffer(user_buf, count, ppos, buf, 2);
655}
656
657static ssize_t force_static_address_write(struct file *file,
658 const char __user *user_buf,
659 size_t count, loff_t *ppos)
660{
661 struct hci_dev *hdev = file->private_data;
662 char buf[32];
663 size_t buf_size = min(count, (sizeof(buf)-1));
664 bool enable;
665
666 if (test_bit(HCI_UP, &hdev->flags))
667 return -EBUSY;
668
669 if (copy_from_user(buf, user_buf, buf_size))
670 return -EFAULT;
671
672 buf[buf_size] = '\0';
673 if (strtobool(buf, &enable))
674 return -EINVAL;
675
676 if (enable == test_bit(HCI_FORCE_STATIC_ADDR, &hdev->dbg_flags))
677 return -EALREADY;
678
679 change_bit(HCI_FORCE_STATIC_ADDR, &hdev->dbg_flags);
680
681 return count;
682}
683
684static const struct file_operations force_static_address_fops = {
685 .open = simple_open,
686 .read = force_static_address_read,
687 .write = force_static_address_write,
688 .llseek = default_llseek,
689};
690
691static int white_list_show(struct seq_file *f, void *ptr)
692{
693 struct hci_dev *hdev = f->private;
694 struct bdaddr_list *b;
695
696 hci_dev_lock(hdev);
697 list_for_each_entry(b, &hdev->le_white_list, list)
698 seq_printf(f, "%pMR (type %u)\n", &b->bdaddr, b->bdaddr_type);
699 hci_dev_unlock(hdev);
700
701 return 0;
702}
703
704static int white_list_open(struct inode *inode, struct file *file)
705{
706 return single_open(file, white_list_show, inode->i_private);
707}
708
709static const struct file_operations white_list_fops = {
710 .open = white_list_open,
711 .read = seq_read,
712 .llseek = seq_lseek,
713 .release = single_release,
714};
715
716static int identity_resolving_keys_show(struct seq_file *f, void *ptr)
717{
718 struct hci_dev *hdev = f->private;
719 struct smp_irk *irk;
720
721 rcu_read_lock();
722 list_for_each_entry_rcu(irk, &hdev->identity_resolving_keys, list) {
723 seq_printf(f, "%pMR (type %u) %*phN %pMR\n",
724 &irk->bdaddr, irk->addr_type,
725 16, irk->val, &irk->rpa);
726 }
727 rcu_read_unlock();
728
729 return 0;
730}
731
732static int identity_resolving_keys_open(struct inode *inode, struct file *file)
733{
734 return single_open(file, identity_resolving_keys_show,
735 inode->i_private);
736}
737
738static const struct file_operations identity_resolving_keys_fops = {
739 .open = identity_resolving_keys_open,
740 .read = seq_read,
741 .llseek = seq_lseek,
742 .release = single_release,
743};
744
745static int long_term_keys_show(struct seq_file *f, void *ptr)
746{
747 struct hci_dev *hdev = f->private;
748 struct smp_ltk *ltk;
749
750 rcu_read_lock();
751 list_for_each_entry_rcu(ltk, &hdev->long_term_keys, list)
752 seq_printf(f, "%pMR (type %u) %u 0x%02x %u %.4x %.16llx %*phN\n",
753 &ltk->bdaddr, ltk->bdaddr_type, ltk->authenticated,
754 ltk->type, ltk->enc_size, __le16_to_cpu(ltk->ediv),
755 __le64_to_cpu(ltk->rand), 16, ltk->val);
756 rcu_read_unlock();
757
758 return 0;
759}
760
761static int long_term_keys_open(struct inode *inode, struct file *file)
762{
763 return single_open(file, long_term_keys_show, inode->i_private);
764}
765
766static const struct file_operations long_term_keys_fops = {
767 .open = long_term_keys_open,
768 .read = seq_read,
769 .llseek = seq_lseek,
770 .release = single_release,
771};
772
773static int conn_min_interval_set(void *data, u64 val)
774{
775 struct hci_dev *hdev = data;
776
777 if (val < 0x0006 || val > 0x0c80 || val > hdev->le_conn_max_interval)
778 return -EINVAL;
779
780 hci_dev_lock(hdev);
781 hdev->le_conn_min_interval = val;
782 hci_dev_unlock(hdev);
783
784 return 0;
785}
786
787static int conn_min_interval_get(void *data, u64 *val)
788{
789 struct hci_dev *hdev = data;
790
791 hci_dev_lock(hdev);
792 *val = hdev->le_conn_min_interval;
793 hci_dev_unlock(hdev);
794
795 return 0;
796}
797
798DEFINE_SIMPLE_ATTRIBUTE(conn_min_interval_fops, conn_min_interval_get,
799 conn_min_interval_set, "%llu\n");
800
801static int conn_max_interval_set(void *data, u64 val)
802{
803 struct hci_dev *hdev = data;
804
805 if (val < 0x0006 || val > 0x0c80 || val < hdev->le_conn_min_interval)
806 return -EINVAL;
807
808 hci_dev_lock(hdev);
809 hdev->le_conn_max_interval = val;
810 hci_dev_unlock(hdev);
811
812 return 0;
813}
814
815static int conn_max_interval_get(void *data, u64 *val)
816{
817 struct hci_dev *hdev = data;
818
819 hci_dev_lock(hdev);
820 *val = hdev->le_conn_max_interval;
821 hci_dev_unlock(hdev);
822
823 return 0;
824}
825
826DEFINE_SIMPLE_ATTRIBUTE(conn_max_interval_fops, conn_max_interval_get,
827 conn_max_interval_set, "%llu\n");
828
829static int conn_latency_set(void *data, u64 val)
830{
831 struct hci_dev *hdev = data;
832
833 if (val > 0x01f3)
834 return -EINVAL;
835
836 hci_dev_lock(hdev);
837 hdev->le_conn_latency = val;
838 hci_dev_unlock(hdev);
839
840 return 0;
841}
842
843static int conn_latency_get(void *data, u64 *val)
844{
845 struct hci_dev *hdev = data;
846
847 hci_dev_lock(hdev);
848 *val = hdev->le_conn_latency;
849 hci_dev_unlock(hdev);
850
851 return 0;
852}
853
854DEFINE_SIMPLE_ATTRIBUTE(conn_latency_fops, conn_latency_get,
855 conn_latency_set, "%llu\n");
856
857static int supervision_timeout_set(void *data, u64 val)
858{
859 struct hci_dev *hdev = data;
860
861 if (val < 0x000a || val > 0x0c80)
862 return -EINVAL;
863
864 hci_dev_lock(hdev);
865 hdev->le_supv_timeout = val;
866 hci_dev_unlock(hdev);
867
868 return 0;
869}
870
871static int supervision_timeout_get(void *data, u64 *val)
872{
873 struct hci_dev *hdev = data;
874
875 hci_dev_lock(hdev);
876 *val = hdev->le_supv_timeout;
877 hci_dev_unlock(hdev);
878
879 return 0;
880}
881
882DEFINE_SIMPLE_ATTRIBUTE(supervision_timeout_fops, supervision_timeout_get,
883 supervision_timeout_set, "%llu\n");
884
885static int adv_channel_map_set(void *data, u64 val)
886{
887 struct hci_dev *hdev = data;
888
889 if (val < 0x01 || val > 0x07)
890 return -EINVAL;
891
892 hci_dev_lock(hdev);
893 hdev->le_adv_channel_map = val;
894 hci_dev_unlock(hdev);
895
896 return 0;
897}
898
899static int adv_channel_map_get(void *data, u64 *val)
900{
901 struct hci_dev *hdev = data;
902
903 hci_dev_lock(hdev);
904 *val = hdev->le_adv_channel_map;
905 hci_dev_unlock(hdev);
906
907 return 0;
908}
909
910DEFINE_SIMPLE_ATTRIBUTE(adv_channel_map_fops, adv_channel_map_get,
911 adv_channel_map_set, "%llu\n");
912
913static int adv_min_interval_set(void *data, u64 val)
914{
915 struct hci_dev *hdev = data;
916
917 if (val < 0x0020 || val > 0x4000 || val > hdev->le_adv_max_interval)
918 return -EINVAL;
919
920 hci_dev_lock(hdev);
921 hdev->le_adv_min_interval = val;
922 hci_dev_unlock(hdev);
923
924 return 0;
925}
926
927static int adv_min_interval_get(void *data, u64 *val)
928{
929 struct hci_dev *hdev = data;
930
931 hci_dev_lock(hdev);
932 *val = hdev->le_adv_min_interval;
933 hci_dev_unlock(hdev);
934
935 return 0;
936}
937
938DEFINE_SIMPLE_ATTRIBUTE(adv_min_interval_fops, adv_min_interval_get,
939 adv_min_interval_set, "%llu\n");
940
941static int adv_max_interval_set(void *data, u64 val)
942{
943 struct hci_dev *hdev = data;
944
945 if (val < 0x0020 || val > 0x4000 || val < hdev->le_adv_min_interval)
946 return -EINVAL;
947
948 hci_dev_lock(hdev);
949 hdev->le_adv_max_interval = val;
950 hci_dev_unlock(hdev);
951
952 return 0;
953}
954
955static int adv_max_interval_get(void *data, u64 *val)
956{
957 struct hci_dev *hdev = data;
958
959 hci_dev_lock(hdev);
960 *val = hdev->le_adv_max_interval;
961 hci_dev_unlock(hdev);
962
963 return 0;
964}
965
966DEFINE_SIMPLE_ATTRIBUTE(adv_max_interval_fops, adv_max_interval_get,
967 adv_max_interval_set, "%llu\n");
968
60c5f5fb
MH
969void hci_debugfs_create_le(struct hci_dev *hdev)
970{
3a5c82b7
MH
971 debugfs_create_file("identity", 0400, hdev->debugfs, hdev,
972 &identity_fops);
973 debugfs_create_file("rpa_timeout", 0644, hdev->debugfs, hdev,
974 &rpa_timeout_fops);
975 debugfs_create_file("random_address", 0444, hdev->debugfs, hdev,
976 &random_address_fops);
977 debugfs_create_file("static_address", 0444, hdev->debugfs, hdev,
978 &static_address_fops);
979
980 /* For controllers with a public address, provide a debug
981 * option to force the usage of the configured static
982 * address. By default the public address is used.
983 */
984 if (bacmp(&hdev->bdaddr, BDADDR_ANY))
985 debugfs_create_file("force_static_address", 0644,
986 hdev->debugfs, hdev,
987 &force_static_address_fops);
988
989 debugfs_create_u8("white_list_size", 0444, hdev->debugfs,
990 &hdev->le_white_list_size);
991 debugfs_create_file("white_list", 0444, hdev->debugfs, hdev,
992 &white_list_fops);
993 debugfs_create_file("identity_resolving_keys", 0400, hdev->debugfs,
994 hdev, &identity_resolving_keys_fops);
995 debugfs_create_file("long_term_keys", 0400, hdev->debugfs, hdev,
996 &long_term_keys_fops);
997 debugfs_create_file("conn_min_interval", 0644, hdev->debugfs, hdev,
998 &conn_min_interval_fops);
999 debugfs_create_file("conn_max_interval", 0644, hdev->debugfs, hdev,
1000 &conn_max_interval_fops);
1001 debugfs_create_file("conn_latency", 0644, hdev->debugfs, hdev,
1002 &conn_latency_fops);
1003 debugfs_create_file("supervision_timeout", 0644, hdev->debugfs, hdev,
1004 &supervision_timeout_fops);
1005 debugfs_create_file("adv_channel_map", 0644, hdev->debugfs, hdev,
1006 &adv_channel_map_fops);
1007 debugfs_create_file("adv_min_interval", 0644, hdev->debugfs, hdev,
1008 &adv_min_interval_fops);
1009 debugfs_create_file("adv_max_interval", 0644, hdev->debugfs, hdev,
1010 &adv_max_interval_fops);
1011 debugfs_create_u16("discov_interleaved_timeout", 0644, hdev->debugfs,
1012 &hdev->discov_interleaved_timeout);
60c5f5fb 1013}
23b9ceb7
MH
1014
1015void hci_debugfs_create_conn(struct hci_conn *conn)
1016{
1017 struct hci_dev *hdev = conn->hdev;
1018 char name[6];
1019
1020 if (IS_ERR_OR_NULL(hdev->debugfs))
1021 return;
1022
1023 snprintf(name, sizeof(name), "%u", conn->handle);
1024 conn->debugfs = debugfs_create_dir(name, hdev->debugfs);
1025}
This page took 0.068806 seconds and 5 git commands to generate.