11da177e4SLinus Torvalds /*
21da177e4SLinus Torvalds BlueZ - Bluetooth protocol stack for Linux
31da177e4SLinus Torvalds Copyright (C) 2000-2001 Qualcomm Incorporated
4590051deSGustavo F. Padovan Copyright (C) 2011 ProFUSION Embedded Systems
51da177e4SLinus Torvalds
61da177e4SLinus Torvalds Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
71da177e4SLinus Torvalds
81da177e4SLinus Torvalds This program is free software; you can redistribute it and/or modify
91da177e4SLinus Torvalds it under the terms of the GNU General Public License version 2 as
101da177e4SLinus Torvalds published by the Free Software Foundation;
111da177e4SLinus Torvalds
121da177e4SLinus Torvalds THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
131da177e4SLinus Torvalds OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
141da177e4SLinus Torvalds FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
151da177e4SLinus Torvalds IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
161da177e4SLinus Torvalds CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
171da177e4SLinus Torvalds WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
181da177e4SLinus Torvalds ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
191da177e4SLinus Torvalds OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
201da177e4SLinus Torvalds
211da177e4SLinus Torvalds ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
221da177e4SLinus Torvalds COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
231da177e4SLinus Torvalds SOFTWARE IS DISCLAIMED.
241da177e4SLinus Torvalds */
251da177e4SLinus Torvalds
261da177e4SLinus Torvalds /* Bluetooth HCI core. */
271da177e4SLinus Torvalds
288c520a59SGustavo Padovan #include <linux/export.h>
29611b30f7SMarcel Holtmann #include <linux/rfkill.h>
30baf27f6eSMarcel Holtmann #include <linux/debugfs.h>
3199780a7bSJohan Hedberg #include <linux/crypto.h>
329f30de9eSTamas Koczka #include <linux/kcov.h>
337a0e5b15SMatthias Kaehlcke #include <linux/property.h>
349952d90eSAbhishek Pandit-Subedi #include <linux/suspend.h>
359952d90eSAbhishek Pandit-Subedi #include <linux/wait.h>
3647219839SMarcel Holtmann #include <asm/unaligned.h>
371da177e4SLinus Torvalds
381da177e4SLinus Torvalds #include <net/bluetooth/bluetooth.h>
391da177e4SLinus Torvalds #include <net/bluetooth/hci_core.h>
404bc58f51SJohan Hedberg #include <net/bluetooth/l2cap.h>
41af58925cSMarcel Holtmann #include <net/bluetooth/mgmt.h>
421da177e4SLinus Torvalds
430857dd3bSJohan Hedberg #include "hci_request.h"
4460c5f5fbSMarcel Holtmann #include "hci_debugfs.h"
45970c4e46SJohan Hedberg #include "smp.h"
466d5d2ee6SHeiner Kallweit #include "leds.h"
47145373cbSMiao-chen Chou #include "msft.h"
48f67743f9SMarcel Holtmann #include "aosp.h"
498961987fSKiran K #include "hci_codec.h"
50970c4e46SJohan Hedberg
51b78752ccSMarcel Holtmann static void hci_rx_work(struct work_struct *work);
52c347b765SGustavo F. Padovan static void hci_cmd_work(struct work_struct *work);
533eff45eaSGustavo F. Padovan static void hci_tx_work(struct work_struct *work);
541da177e4SLinus Torvalds
551da177e4SLinus Torvalds /* HCI device list */
561da177e4SLinus Torvalds LIST_HEAD(hci_dev_list);
571da177e4SLinus Torvalds DEFINE_RWLOCK(hci_dev_list_lock);
581da177e4SLinus Torvalds
591da177e4SLinus Torvalds /* HCI callback list */
601da177e4SLinus Torvalds LIST_HEAD(hci_cb_list);
61*5e8ce74fSLuiz Augusto von Dentz DEFINE_MUTEX(hci_cb_list_lock);
621da177e4SLinus Torvalds
633df92b31SSasha Levin /* HCI ID Numbering */
643df92b31SSasha Levin static DEFINE_IDA(hci_index_ida);
653df92b31SSasha Levin
661da177e4SLinus Torvalds /* Get HCI device by index.
hci_dev_get(int index)671da177e4SLinus Torvalds * Device is held on return. */
681da177e4SLinus Torvalds struct hci_dev *hci_dev_get(int index)
691da177e4SLinus Torvalds {
708035ded4SLuiz Augusto von Dentz struct hci_dev *hdev = NULL, *d;
711da177e4SLinus Torvalds
721da177e4SLinus Torvalds BT_DBG("%d", index);
731da177e4SLinus Torvalds
741da177e4SLinus Torvalds if (index < 0)
751da177e4SLinus Torvalds return NULL;
761da177e4SLinus Torvalds
771da177e4SLinus Torvalds read_lock(&hci_dev_list_lock);
788035ded4SLuiz Augusto von Dentz list_for_each_entry(d, &hci_dev_list, list) {
791da177e4SLinus Torvalds if (d->id == index) {
801da177e4SLinus Torvalds hdev = hci_dev_hold(d);
811da177e4SLinus Torvalds break;
821da177e4SLinus Torvalds }
831da177e4SLinus Torvalds }
841da177e4SLinus Torvalds read_unlock(&hci_dev_list_lock);
851da177e4SLinus Torvalds return hdev;
861da177e4SLinus Torvalds }
871da177e4SLinus Torvalds
881da177e4SLinus Torvalds /* ---- Inquiry support ---- */
hci_discovery_active(struct hci_dev * hdev)89ff9ef578SJohan Hedberg
9030dc78e1SJohan Hedberg bool hci_discovery_active(struct hci_dev *hdev)
9130dc78e1SJohan Hedberg {
9230dc78e1SJohan Hedberg struct discovery_state *discov = &hdev->discovery;
9330dc78e1SJohan Hedberg
946fbe195dSAndre Guedes switch (discov->state) {
95343f935bSAndre Guedes case DISCOVERY_FINDING:
966fbe195dSAndre Guedes case DISCOVERY_RESOLVING:
9730dc78e1SJohan Hedberg return true;
9830dc78e1SJohan Hedberg
996fbe195dSAndre Guedes default:
10030dc78e1SJohan Hedberg return false;
10130dc78e1SJohan Hedberg }
1026fbe195dSAndre Guedes }
hci_discovery_set_state(struct hci_dev * hdev,int state)10330dc78e1SJohan Hedberg
104ff9ef578SJohan Hedberg void hci_discovery_set_state(struct hci_dev *hdev, int state)
105ff9ef578SJohan Hedberg {
106bb3e0a33SJohan Hedberg int old_state = hdev->discovery.state;
107bb3e0a33SJohan Hedberg
108ff9ef578SJohan Hedberg BT_DBG("%s state %u -> %u", hdev->name, hdev->discovery.state, state);
109ff9ef578SJohan Hedberg
110bb3e0a33SJohan Hedberg if (old_state == state)
111ff9ef578SJohan Hedberg return;
112ff9ef578SJohan Hedberg
113bb3e0a33SJohan Hedberg hdev->discovery.state = state;
114bb3e0a33SJohan Hedberg
115ff9ef578SJohan Hedberg switch (state) {
116ff9ef578SJohan Hedberg case DISCOVERY_STOPPED:
1175bee2fd6SLuiz Augusto von Dentz hci_update_passive_scan(hdev);
118c54c3860SAndre Guedes
119bb3e0a33SJohan Hedberg if (old_state != DISCOVERY_STARTING)
120ff9ef578SJohan Hedberg mgmt_discovering(hdev, 0);
121ff9ef578SJohan Hedberg break;
122ff9ef578SJohan Hedberg case DISCOVERY_STARTING:
123ff9ef578SJohan Hedberg break;
124343f935bSAndre Guedes case DISCOVERY_FINDING:
125ff9ef578SJohan Hedberg mgmt_discovering(hdev, 1);
126ff9ef578SJohan Hedberg break;
12730dc78e1SJohan Hedberg case DISCOVERY_RESOLVING:
12830dc78e1SJohan Hedberg break;
129ff9ef578SJohan Hedberg case DISCOVERY_STOPPING:
130ff9ef578SJohan Hedberg break;
131ff9ef578SJohan Hedberg }
132ff9ef578SJohan Hedberg }
hci_inquiry_cache_flush(struct hci_dev * hdev)133ff9ef578SJohan Hedberg
1341f9b9a5dSAndre Guedes void hci_inquiry_cache_flush(struct hci_dev *hdev)
1351da177e4SLinus Torvalds {
13630883512SJohan Hedberg struct discovery_state *cache = &hdev->discovery;
137b57c1a56SJohan Hedberg struct inquiry_entry *p, *n;
1381da177e4SLinus Torvalds
139561aafbcSJohan Hedberg list_for_each_entry_safe(p, n, &cache->all, all) {
140561aafbcSJohan Hedberg list_del(&p->all);
141b57c1a56SJohan Hedberg kfree(p);
1421da177e4SLinus Torvalds }
143561aafbcSJohan Hedberg
144561aafbcSJohan Hedberg INIT_LIST_HEAD(&cache->unknown);
145561aafbcSJohan Hedberg INIT_LIST_HEAD(&cache->resolve);
1461da177e4SLinus Torvalds }
hci_inquiry_cache_lookup(struct hci_dev * hdev,bdaddr_t * bdaddr)1471da177e4SLinus Torvalds
148a8c5fb1aSGustavo Padovan struct inquiry_entry *hci_inquiry_cache_lookup(struct hci_dev *hdev,
149a8c5fb1aSGustavo Padovan bdaddr_t *bdaddr)
1501da177e4SLinus Torvalds {
15130883512SJohan Hedberg struct discovery_state *cache = &hdev->discovery;
1521da177e4SLinus Torvalds struct inquiry_entry *e;
1531da177e4SLinus Torvalds
1546ed93dc6SAndrei Emeltchenko BT_DBG("cache %p, %pMR", cache, bdaddr);
1551da177e4SLinus Torvalds
156561aafbcSJohan Hedberg list_for_each_entry(e, &cache->all, all) {
1571da177e4SLinus Torvalds if (!bacmp(&e->data.bdaddr, bdaddr))
1581da177e4SLinus Torvalds return e;
1591da177e4SLinus Torvalds }
1601da177e4SLinus Torvalds
161b57c1a56SJohan Hedberg return NULL;
162b57c1a56SJohan Hedberg }
hci_inquiry_cache_lookup_unknown(struct hci_dev * hdev,bdaddr_t * bdaddr)163b57c1a56SJohan Hedberg
164561aafbcSJohan Hedberg struct inquiry_entry *hci_inquiry_cache_lookup_unknown(struct hci_dev *hdev,
165561aafbcSJohan Hedberg bdaddr_t *bdaddr)
166561aafbcSJohan Hedberg {
16730883512SJohan Hedberg struct discovery_state *cache = &hdev->discovery;
168561aafbcSJohan Hedberg struct inquiry_entry *e;
169561aafbcSJohan Hedberg
1706ed93dc6SAndrei Emeltchenko BT_DBG("cache %p, %pMR", cache, bdaddr);
171561aafbcSJohan Hedberg
172561aafbcSJohan Hedberg list_for_each_entry(e, &cache->unknown, list) {
173561aafbcSJohan Hedberg if (!bacmp(&e->data.bdaddr, bdaddr))
174561aafbcSJohan Hedberg return e;
175561aafbcSJohan Hedberg }
176561aafbcSJohan Hedberg
177561aafbcSJohan Hedberg return NULL;
178561aafbcSJohan Hedberg }
hci_inquiry_cache_lookup_resolve(struct hci_dev * hdev,bdaddr_t * bdaddr,int state)179561aafbcSJohan Hedberg
18030dc78e1SJohan Hedberg struct inquiry_entry *hci_inquiry_cache_lookup_resolve(struct hci_dev *hdev,
18130dc78e1SJohan Hedberg bdaddr_t *bdaddr,
18230dc78e1SJohan Hedberg int state)
18330dc78e1SJohan Hedberg {
18430dc78e1SJohan Hedberg struct discovery_state *cache = &hdev->discovery;
18530dc78e1SJohan Hedberg struct inquiry_entry *e;
18630dc78e1SJohan Hedberg
1876ed93dc6SAndrei Emeltchenko BT_DBG("cache %p bdaddr %pMR state %d", cache, bdaddr, state);
18830dc78e1SJohan Hedberg
18930dc78e1SJohan Hedberg list_for_each_entry(e, &cache->resolve, list) {
19030dc78e1SJohan Hedberg if (!bacmp(bdaddr, BDADDR_ANY) && e->name_state == state)
19130dc78e1SJohan Hedberg return e;
19230dc78e1SJohan Hedberg if (!bacmp(&e->data.bdaddr, bdaddr))
19330dc78e1SJohan Hedberg return e;
19430dc78e1SJohan Hedberg }
19530dc78e1SJohan Hedberg
19630dc78e1SJohan Hedberg return NULL;
19730dc78e1SJohan Hedberg }
hci_inquiry_cache_update_resolve(struct hci_dev * hdev,struct inquiry_entry * ie)19830dc78e1SJohan Hedberg
199a3d4e20aSJohan Hedberg void hci_inquiry_cache_update_resolve(struct hci_dev *hdev,
200a3d4e20aSJohan Hedberg struct inquiry_entry *ie)
201a3d4e20aSJohan Hedberg {
202a3d4e20aSJohan Hedberg struct discovery_state *cache = &hdev->discovery;
203a3d4e20aSJohan Hedberg struct list_head *pos = &cache->resolve;
204a3d4e20aSJohan Hedberg struct inquiry_entry *p;
205a3d4e20aSJohan Hedberg
206a3d4e20aSJohan Hedberg list_del(&ie->list);
207a3d4e20aSJohan Hedberg
208a3d4e20aSJohan Hedberg list_for_each_entry(p, &cache->resolve, list) {
209a3d4e20aSJohan Hedberg if (p->name_state != NAME_PENDING &&
210a3d4e20aSJohan Hedberg abs(p->data.rssi) >= abs(ie->data.rssi))
211a3d4e20aSJohan Hedberg break;
212a3d4e20aSJohan Hedberg pos = &p->list;
213a3d4e20aSJohan Hedberg }
214a3d4e20aSJohan Hedberg
215a3d4e20aSJohan Hedberg list_add(&ie->list, pos);
216a3d4e20aSJohan Hedberg }
hci_inquiry_cache_update(struct hci_dev * hdev,struct inquiry_data * data,bool name_known)217a3d4e20aSJohan Hedberg
218af58925cSMarcel Holtmann u32 hci_inquiry_cache_update(struct hci_dev *hdev, struct inquiry_data *data,
219af58925cSMarcel Holtmann bool name_known)
2201da177e4SLinus Torvalds {
22130883512SJohan Hedberg struct discovery_state *cache = &hdev->discovery;
22270f23020SAndrei Emeltchenko struct inquiry_entry *ie;
223af58925cSMarcel Holtmann u32 flags = 0;
2241da177e4SLinus Torvalds
2256ed93dc6SAndrei Emeltchenko BT_DBG("cache %p, %pMR", cache, &data->bdaddr);
2261da177e4SLinus Torvalds
2276928a924SJohan Hedberg hci_remove_remote_oob_data(hdev, &data->bdaddr, BDADDR_BREDR);
2282b2fec4dSSzymon Janc
229af58925cSMarcel Holtmann if (!data->ssp_mode)
230af58925cSMarcel Holtmann flags |= MGMT_DEV_FOUND_LEGACY_PAIRING;
231388fc8faSJohan Hedberg
23270f23020SAndrei Emeltchenko ie = hci_inquiry_cache_lookup(hdev, &data->bdaddr);
233a3d4e20aSJohan Hedberg if (ie) {
234af58925cSMarcel Holtmann if (!ie->data.ssp_mode)
235af58925cSMarcel Holtmann flags |= MGMT_DEV_FOUND_LEGACY_PAIRING;
236388fc8faSJohan Hedberg
237a3d4e20aSJohan Hedberg if (ie->name_state == NAME_NEEDED &&
238a3d4e20aSJohan Hedberg data->rssi != ie->data.rssi) {
239a3d4e20aSJohan Hedberg ie->data.rssi = data->rssi;
240a3d4e20aSJohan Hedberg hci_inquiry_cache_update_resolve(hdev, ie);
241a3d4e20aSJohan Hedberg }
242a3d4e20aSJohan Hedberg
243561aafbcSJohan Hedberg goto update;
244a3d4e20aSJohan Hedberg }
245561aafbcSJohan Hedberg
2461da177e4SLinus Torvalds /* Entry not in the cache. Add new one. */
24727f70f3eSJohan Hedberg ie = kzalloc(sizeof(*ie), GFP_KERNEL);
248af58925cSMarcel Holtmann if (!ie) {
249af58925cSMarcel Holtmann flags |= MGMT_DEV_FOUND_CONFIRM_NAME;
250af58925cSMarcel Holtmann goto done;
251af58925cSMarcel Holtmann }
25270f23020SAndrei Emeltchenko
253561aafbcSJohan Hedberg list_add(&ie->all, &cache->all);
254561aafbcSJohan Hedberg
255561aafbcSJohan Hedberg if (name_known) {
256561aafbcSJohan Hedberg ie->name_state = NAME_KNOWN;
257561aafbcSJohan Hedberg } else {
258561aafbcSJohan Hedberg ie->name_state = NAME_NOT_KNOWN;
259561aafbcSJohan Hedberg list_add(&ie->list, &cache->unknown);
260561aafbcSJohan Hedberg }
261561aafbcSJohan Hedberg
262561aafbcSJohan Hedberg update:
263561aafbcSJohan Hedberg if (name_known && ie->name_state != NAME_KNOWN &&
264561aafbcSJohan Hedberg ie->name_state != NAME_PENDING) {
265561aafbcSJohan Hedberg ie->name_state = NAME_KNOWN;
266561aafbcSJohan Hedberg list_del(&ie->list);
2671da177e4SLinus Torvalds }
2681da177e4SLinus Torvalds
26970f23020SAndrei Emeltchenko memcpy(&ie->data, data, sizeof(*data));
27070f23020SAndrei Emeltchenko ie->timestamp = jiffies;
2711da177e4SLinus Torvalds cache->timestamp = jiffies;
2723175405bSJohan Hedberg
2733175405bSJohan Hedberg if (ie->name_state == NAME_NOT_KNOWN)
274af58925cSMarcel Holtmann flags |= MGMT_DEV_FOUND_CONFIRM_NAME;
2753175405bSJohan Hedberg
276af58925cSMarcel Holtmann done:
277af58925cSMarcel Holtmann return flags;
2781da177e4SLinus Torvalds }
inquiry_cache_dump(struct hci_dev * hdev,int num,__u8 * buf)2791da177e4SLinus Torvalds
2801da177e4SLinus Torvalds static int inquiry_cache_dump(struct hci_dev *hdev, int num, __u8 *buf)
2811da177e4SLinus Torvalds {
28230883512SJohan Hedberg struct discovery_state *cache = &hdev->discovery;
2831da177e4SLinus Torvalds struct inquiry_info *info = (struct inquiry_info *) buf;
2841da177e4SLinus Torvalds struct inquiry_entry *e;
2851da177e4SLinus Torvalds int copied = 0;
2861da177e4SLinus Torvalds
287561aafbcSJohan Hedberg list_for_each_entry(e, &cache->all, all) {
2881da177e4SLinus Torvalds struct inquiry_data *data = &e->data;
289b57c1a56SJohan Hedberg
290b57c1a56SJohan Hedberg if (copied >= num)
291b57c1a56SJohan Hedberg break;
292b57c1a56SJohan Hedberg
2931da177e4SLinus Torvalds bacpy(&info->bdaddr, &data->bdaddr);
2941da177e4SLinus Torvalds info->pscan_rep_mode = data->pscan_rep_mode;
2951da177e4SLinus Torvalds info->pscan_period_mode = data->pscan_period_mode;
2961da177e4SLinus Torvalds info->pscan_mode = data->pscan_mode;
2971da177e4SLinus Torvalds memcpy(info->dev_class, data->dev_class, 3);
2981da177e4SLinus Torvalds info->clock_offset = data->clock_offset;
299b57c1a56SJohan Hedberg
3001da177e4SLinus Torvalds info++;
301b57c1a56SJohan Hedberg copied++;
3021da177e4SLinus Torvalds }
3031da177e4SLinus Torvalds
3041da177e4SLinus Torvalds BT_DBG("cache %p, copied %d", cache, copied);
3051da177e4SLinus Torvalds return copied;
3061da177e4SLinus Torvalds }
hci_inq_req(struct hci_request * req,unsigned long opt)3071da177e4SLinus Torvalds
308a1d01db1SJohan Hedberg static int hci_inq_req(struct hci_request *req, unsigned long opt)
3091da177e4SLinus Torvalds {
3101da177e4SLinus Torvalds struct hci_inquiry_req *ir = (struct hci_inquiry_req *) opt;
31142c6b129SJohan Hedberg struct hci_dev *hdev = req->hdev;
3121da177e4SLinus Torvalds struct hci_cp_inquiry cp;
3131da177e4SLinus Torvalds
3141da177e4SLinus Torvalds BT_DBG("%s", hdev->name);
3151da177e4SLinus Torvalds
3161da177e4SLinus Torvalds if (test_bit(HCI_INQUIRY, &hdev->flags))
317a1d01db1SJohan Hedberg return 0;
3181da177e4SLinus Torvalds
3191da177e4SLinus Torvalds /* Start Inquiry */
3201da177e4SLinus Torvalds memcpy(&cp.lap, &ir->lap, 3);
3211da177e4SLinus Torvalds cp.length = ir->length;
3221da177e4SLinus Torvalds cp.num_rsp = ir->num_rsp;
32342c6b129SJohan Hedberg hci_req_add(req, HCI_OP_INQUIRY, sizeof(cp), &cp);
324a1d01db1SJohan Hedberg
325a1d01db1SJohan Hedberg return 0;
3261da177e4SLinus Torvalds }
hci_inquiry(void __user * arg)3271da177e4SLinus Torvalds
3281da177e4SLinus Torvalds int hci_inquiry(void __user *arg)
3291da177e4SLinus Torvalds {
3301da177e4SLinus Torvalds __u8 __user *ptr = arg;
3311da177e4SLinus Torvalds struct hci_inquiry_req ir;
3321da177e4SLinus Torvalds struct hci_dev *hdev;
3331da177e4SLinus Torvalds int err = 0, do_inquiry = 0, max_rsp;
3341da177e4SLinus Torvalds long timeo;
3351da177e4SLinus Torvalds __u8 *buf;
3361da177e4SLinus Torvalds
3371da177e4SLinus Torvalds if (copy_from_user(&ir, ptr, sizeof(ir)))
3381da177e4SLinus Torvalds return -EFAULT;
3391da177e4SLinus Torvalds
3405a08ecceSAndrei Emeltchenko hdev = hci_dev_get(ir.dev_id);
3415a08ecceSAndrei Emeltchenko if (!hdev)
3421da177e4SLinus Torvalds return -ENODEV;
3431da177e4SLinus Torvalds
344d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_USER_CHANNEL)) {
3450736cfa8SMarcel Holtmann err = -EBUSY;
3460736cfa8SMarcel Holtmann goto done;
3470736cfa8SMarcel Holtmann }
3480736cfa8SMarcel Holtmann
349d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_UNCONFIGURED)) {
350fee746b0SMarcel Holtmann err = -EOPNOTSUPP;
351fee746b0SMarcel Holtmann goto done;
352fee746b0SMarcel Holtmann }
353fee746b0SMarcel Holtmann
354d7a5a11dSMarcel Holtmann if (!hci_dev_test_flag(hdev, HCI_BREDR_ENABLED)) {
35556f87901SJohan Hedberg err = -EOPNOTSUPP;
35656f87901SJohan Hedberg goto done;
35756f87901SJohan Hedberg }
35856f87901SJohan Hedberg
359f41a4b2bSPavel Skripkin /* Restrict maximum inquiry length to 60 seconds */
360f41a4b2bSPavel Skripkin if (ir.length > 60) {
361f41a4b2bSPavel Skripkin err = -EINVAL;
362f41a4b2bSPavel Skripkin goto done;
363f41a4b2bSPavel Skripkin }
364f41a4b2bSPavel Skripkin
36509fd0de5SGustavo F. Padovan hci_dev_lock(hdev);
3661da177e4SLinus Torvalds if (inquiry_cache_age(hdev) > INQUIRY_CACHE_AGE_MAX ||
367a8c5fb1aSGustavo Padovan inquiry_cache_empty(hdev) || ir.flags & IREQ_CACHE_FLUSH) {
3681f9b9a5dSAndre Guedes hci_inquiry_cache_flush(hdev);
3691da177e4SLinus Torvalds do_inquiry = 1;
3701da177e4SLinus Torvalds }
37109fd0de5SGustavo F. Padovan hci_dev_unlock(hdev);
3721da177e4SLinus Torvalds
37304837f64SMarcel Holtmann timeo = ir.length * msecs_to_jiffies(2000);
37470f23020SAndrei Emeltchenko
37570f23020SAndrei Emeltchenko if (do_inquiry) {
37601178cd4SJohan Hedberg err = hci_req_sync(hdev, hci_inq_req, (unsigned long) &ir,
3774ebeee2dSJohan Hedberg timeo, NULL);
37870f23020SAndrei Emeltchenko if (err < 0)
3791da177e4SLinus Torvalds goto done;
3803e13fa1eSAndre Guedes
3813e13fa1eSAndre Guedes /* Wait until Inquiry procedure finishes (HCI_INQUIRY flag is
3823e13fa1eSAndre Guedes * cleared). If it is interrupted by a signal, return -EINTR.
3833e13fa1eSAndre Guedes */
38474316201SNeilBrown if (wait_on_bit(&hdev->flags, HCI_INQUIRY,
38528a758c8SPan Bian TASK_INTERRUPTIBLE)) {
38628a758c8SPan Bian err = -EINTR;
38728a758c8SPan Bian goto done;
38828a758c8SPan Bian }
38970f23020SAndrei Emeltchenko }
3901da177e4SLinus Torvalds
3918fc9ced3SGustavo Padovan /* for unlimited number of responses we will use buffer with
3928fc9ced3SGustavo Padovan * 255 entries
3938fc9ced3SGustavo Padovan */
3941da177e4SLinus Torvalds max_rsp = (ir.num_rsp == 0) ? 255 : ir.num_rsp;
3951da177e4SLinus Torvalds
3961da177e4SLinus Torvalds /* cache_dump can't sleep. Therefore we allocate temp buffer and then
3971da177e4SLinus Torvalds * copy it to the user space.
3981da177e4SLinus Torvalds */
3996da2ec56SKees Cook buf = kmalloc_array(max_rsp, sizeof(struct inquiry_info), GFP_KERNEL);
40070f23020SAndrei Emeltchenko if (!buf) {
4011da177e4SLinus Torvalds err = -ENOMEM;
4021da177e4SLinus Torvalds goto done;
4031da177e4SLinus Torvalds }
4041da177e4SLinus Torvalds
40509fd0de5SGustavo F. Padovan hci_dev_lock(hdev);
4061da177e4SLinus Torvalds ir.num_rsp = inquiry_cache_dump(hdev, max_rsp, buf);
40709fd0de5SGustavo F. Padovan hci_dev_unlock(hdev);
4081da177e4SLinus Torvalds
4091da177e4SLinus Torvalds BT_DBG("num_rsp %d", ir.num_rsp);
4101da177e4SLinus Torvalds
4111da177e4SLinus Torvalds if (!copy_to_user(ptr, &ir, sizeof(ir))) {
4121da177e4SLinus Torvalds ptr += sizeof(ir);
4131da177e4SLinus Torvalds if (copy_to_user(ptr, buf, sizeof(struct inquiry_info) *
4141da177e4SLinus Torvalds ir.num_rsp))
4151da177e4SLinus Torvalds err = -EFAULT;
4161da177e4SLinus Torvalds } else
4171da177e4SLinus Torvalds err = -EFAULT;
4181da177e4SLinus Torvalds
4191da177e4SLinus Torvalds kfree(buf);
4201da177e4SLinus Torvalds
4211da177e4SLinus Torvalds done:
4221da177e4SLinus Torvalds hci_dev_put(hdev);
4231da177e4SLinus Torvalds return err;
4241da177e4SLinus Torvalds }
hci_dev_do_open(struct hci_dev * hdev)4251da177e4SLinus Torvalds
426cf75ad8bSLuiz Augusto von Dentz static int hci_dev_do_open(struct hci_dev *hdev)
427cf75ad8bSLuiz Augusto von Dentz {
428cf75ad8bSLuiz Augusto von Dentz int ret = 0;
429cf75ad8bSLuiz Augusto von Dentz
430cf75ad8bSLuiz Augusto von Dentz BT_DBG("%s %p", hdev->name, hdev);
431cf75ad8bSLuiz Augusto von Dentz
432cf75ad8bSLuiz Augusto von Dentz hci_req_sync_lock(hdev);
433cf75ad8bSLuiz Augusto von Dentz
434cf75ad8bSLuiz Augusto von Dentz ret = hci_dev_open_sync(hdev);
435cf75ad8bSLuiz Augusto von Dentz
436b504430cSJohan Hedberg hci_req_sync_unlock(hdev);
4371da177e4SLinus Torvalds return ret;
4381da177e4SLinus Torvalds }
4391da177e4SLinus Torvalds
440cbed0ca1SJohan Hedberg /* ---- HCI ioctl helpers ---- */
hci_dev_open(__u16 dev)441cbed0ca1SJohan Hedberg
442cbed0ca1SJohan Hedberg int hci_dev_open(__u16 dev)
443cbed0ca1SJohan Hedberg {
444cbed0ca1SJohan Hedberg struct hci_dev *hdev;
445cbed0ca1SJohan Hedberg int err;
446cbed0ca1SJohan Hedberg
447cbed0ca1SJohan Hedberg hdev = hci_dev_get(dev);
448cbed0ca1SJohan Hedberg if (!hdev)
449cbed0ca1SJohan Hedberg return -ENODEV;
450cbed0ca1SJohan Hedberg
4514a964404SMarcel Holtmann /* Devices that are marked as unconfigured can only be powered
452fee746b0SMarcel Holtmann * up as user channel. Trying to bring them up as normal devices
453fee746b0SMarcel Holtmann * will result into a failure. Only user channel operation is
454fee746b0SMarcel Holtmann * possible.
455fee746b0SMarcel Holtmann *
456fee746b0SMarcel Holtmann * When this function is called for a user channel, the flag
457fee746b0SMarcel Holtmann * HCI_USER_CHANNEL will be set first before attempting to
458fee746b0SMarcel Holtmann * open the device.
459fee746b0SMarcel Holtmann */
460d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_UNCONFIGURED) &&
461d7a5a11dSMarcel Holtmann !hci_dev_test_flag(hdev, HCI_USER_CHANNEL)) {
462fee746b0SMarcel Holtmann err = -EOPNOTSUPP;
463fee746b0SMarcel Holtmann goto done;
464fee746b0SMarcel Holtmann }
465fee746b0SMarcel Holtmann
466e1d08f40SJohan Hedberg /* We need to ensure that no other power on/off work is pending
467e1d08f40SJohan Hedberg * before proceeding to call hci_dev_do_open. This is
468e1d08f40SJohan Hedberg * particularly important if the setup procedure has not yet
469e1d08f40SJohan Hedberg * completed.
470e1d08f40SJohan Hedberg */
471a69d8927SMarcel Holtmann if (hci_dev_test_and_clear_flag(hdev, HCI_AUTO_OFF))
472e1d08f40SJohan Hedberg cancel_delayed_work(&hdev->power_off);
473e1d08f40SJohan Hedberg
474a5c8f270SMarcel Holtmann /* After this call it is guaranteed that the setup procedure
475a5c8f270SMarcel Holtmann * has finished. This means that error conditions like RFKILL
476a5c8f270SMarcel Holtmann * or no valid public or static random address apply.
477a5c8f270SMarcel Holtmann */
478e1d08f40SJohan Hedberg flush_workqueue(hdev->req_workqueue);
479e1d08f40SJohan Hedberg
48012aa4f0aSMarcel Holtmann /* For controllers not using the management interface and that
481b6ae8457SJohan Hedberg * are brought up using legacy ioctl, set the HCI_BONDABLE bit
48212aa4f0aSMarcel Holtmann * so that pairing works for them. Once the management interface
48312aa4f0aSMarcel Holtmann * is in use this bit will be cleared again and userspace has
48412aa4f0aSMarcel Holtmann * to explicitly enable it.
48512aa4f0aSMarcel Holtmann */
486d7a5a11dSMarcel Holtmann if (!hci_dev_test_flag(hdev, HCI_USER_CHANNEL) &&
487d7a5a11dSMarcel Holtmann !hci_dev_test_flag(hdev, HCI_MGMT))
488a1536da2SMarcel Holtmann hci_dev_set_flag(hdev, HCI_BONDABLE);
48912aa4f0aSMarcel Holtmann
490cbed0ca1SJohan Hedberg err = hci_dev_do_open(hdev);
491cbed0ca1SJohan Hedberg
492fee746b0SMarcel Holtmann done:
493cbed0ca1SJohan Hedberg hci_dev_put(hdev);
494cbed0ca1SJohan Hedberg return err;
495cbed0ca1SJohan Hedberg }
hci_dev_do_close(struct hci_dev * hdev)496cbed0ca1SJohan Hedberg
497cf75ad8bSLuiz Augusto von Dentz int hci_dev_do_close(struct hci_dev *hdev)
498cf75ad8bSLuiz Augusto von Dentz {
499cf75ad8bSLuiz Augusto von Dentz int err;
500cf75ad8bSLuiz Augusto von Dentz
501cf75ad8bSLuiz Augusto von Dentz BT_DBG("%s %p", hdev->name, hdev);
502cf75ad8bSLuiz Augusto von Dentz
503cf75ad8bSLuiz Augusto von Dentz hci_req_sync_lock(hdev);
504cf75ad8bSLuiz Augusto von Dentz
505cf75ad8bSLuiz Augusto von Dentz err = hci_dev_close_sync(hdev);
506cf75ad8bSLuiz Augusto von Dentz
507b504430cSJohan Hedberg hci_req_sync_unlock(hdev);
5081da177e4SLinus Torvalds
50961969ef8SKangmin Park return err;
5101da177e4SLinus Torvalds }
hci_dev_close(__u16 dev)5111da177e4SLinus Torvalds
5121da177e4SLinus Torvalds int hci_dev_close(__u16 dev)
5131da177e4SLinus Torvalds {
5141da177e4SLinus Torvalds struct hci_dev *hdev;
5151da177e4SLinus Torvalds int err;
5161da177e4SLinus Torvalds
51770f23020SAndrei Emeltchenko hdev = hci_dev_get(dev);
51870f23020SAndrei Emeltchenko if (!hdev)
5191da177e4SLinus Torvalds return -ENODEV;
5208ee56540SMarcel Holtmann
521d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_USER_CHANNEL)) {
5220736cfa8SMarcel Holtmann err = -EBUSY;
5230736cfa8SMarcel Holtmann goto done;
5240736cfa8SMarcel Holtmann }
5250736cfa8SMarcel Holtmann
526e36bea6eSVasyl Vavrychuk cancel_work_sync(&hdev->power_on);
527a69d8927SMarcel Holtmann if (hci_dev_test_and_clear_flag(hdev, HCI_AUTO_OFF))
5288ee56540SMarcel Holtmann cancel_delayed_work(&hdev->power_off);
5298ee56540SMarcel Holtmann
5301da177e4SLinus Torvalds err = hci_dev_do_close(hdev);
5318ee56540SMarcel Holtmann
5320736cfa8SMarcel Holtmann done:
5331da177e4SLinus Torvalds hci_dev_put(hdev);
5341da177e4SLinus Torvalds return err;
5351da177e4SLinus Torvalds }
hci_dev_do_reset(struct hci_dev * hdev)5361da177e4SLinus Torvalds
5375c912495SMarcel Holtmann static int hci_dev_do_reset(struct hci_dev *hdev)
5381da177e4SLinus Torvalds {
5395c912495SMarcel Holtmann int ret;
5401da177e4SLinus Torvalds
5415c912495SMarcel Holtmann BT_DBG("%s %p", hdev->name, hdev);
5421da177e4SLinus Torvalds
543b504430cSJohan Hedberg hci_req_sync_lock(hdev);
5441da177e4SLinus Torvalds
5451da177e4SLinus Torvalds /* Drop queues */
5461da177e4SLinus Torvalds skb_queue_purge(&hdev->rx_q);
5471da177e4SLinus Torvalds skb_queue_purge(&hdev->cmd_q);
5481da177e4SLinus Torvalds
549877afadaSSchspa Shi /* Cancel these to avoid queueing non-chained pending work */
550877afadaSSchspa Shi hci_dev_set_flag(hdev, HCI_CMD_DRAIN_WORKQUEUE);
551deee93d1STetsuo Handa /* Wait for
552deee93d1STetsuo Handa *
553deee93d1STetsuo Handa * if (!hci_dev_test_flag(hdev, HCI_CMD_DRAIN_WORKQUEUE))
554deee93d1STetsuo Handa * queue_delayed_work(&hdev->{cmd,ncmd}_timer)
555deee93d1STetsuo Handa *
556deee93d1STetsuo Handa * inside RCU section to see the flag or complete scheduling.
557deee93d1STetsuo Handa */
558deee93d1STetsuo Handa synchronize_rcu();
559deee93d1STetsuo Handa /* Explicitly cancel works in case scheduled after setting the flag. */
560877afadaSSchspa Shi cancel_delayed_work(&hdev->cmd_timer);
561877afadaSSchspa Shi cancel_delayed_work(&hdev->ncmd_timer);
562877afadaSSchspa Shi
56376727c02SJohan Hedberg /* Avoid potential lockdep warnings from the *_flush() calls by
56476727c02SJohan Hedberg * ensuring the workqueue is empty up front.
56576727c02SJohan Hedberg */
56676727c02SJohan Hedberg drain_workqueue(hdev->workqueue);
56776727c02SJohan Hedberg
56809fd0de5SGustavo F. Padovan hci_dev_lock(hdev);
5691f9b9a5dSAndre Guedes hci_inquiry_cache_flush(hdev);
5701da177e4SLinus Torvalds hci_conn_hash_flush(hdev);
57109fd0de5SGustavo F. Padovan hci_dev_unlock(hdev);
5721da177e4SLinus Torvalds
5731da177e4SLinus Torvalds if (hdev->flush)
5741da177e4SLinus Torvalds hdev->flush(hdev);
5751da177e4SLinus Torvalds
576877afadaSSchspa Shi hci_dev_clear_flag(hdev, HCI_CMD_DRAIN_WORKQUEUE);
577877afadaSSchspa Shi
5781da177e4SLinus Torvalds atomic_set(&hdev->cmd_cnt, 1);
57926afbd82SLuiz Augusto von Dentz hdev->acl_cnt = 0;
58026afbd82SLuiz Augusto von Dentz hdev->sco_cnt = 0;
58126afbd82SLuiz Augusto von Dentz hdev->le_cnt = 0;
58226afbd82SLuiz Augusto von Dentz hdev->iso_cnt = 0;
5831da177e4SLinus Torvalds
584d0b13706SLuiz Augusto von Dentz ret = hci_reset_sync(hdev);
5851da177e4SLinus Torvalds
586b504430cSJohan Hedberg hci_req_sync_unlock(hdev);
5871da177e4SLinus Torvalds return ret;
5881da177e4SLinus Torvalds }
hci_dev_reset(__u16 dev)5891da177e4SLinus Torvalds
5905c912495SMarcel Holtmann int hci_dev_reset(__u16 dev)
5915c912495SMarcel Holtmann {
5925c912495SMarcel Holtmann struct hci_dev *hdev;
5935c912495SMarcel Holtmann int err;
5945c912495SMarcel Holtmann
5955c912495SMarcel Holtmann hdev = hci_dev_get(dev);
5965c912495SMarcel Holtmann if (!hdev)
5975c912495SMarcel Holtmann return -ENODEV;
5985c912495SMarcel Holtmann
5995c912495SMarcel Holtmann if (!test_bit(HCI_UP, &hdev->flags)) {
6005c912495SMarcel Holtmann err = -ENETDOWN;
6015c912495SMarcel Holtmann goto done;
6025c912495SMarcel Holtmann }
6035c912495SMarcel Holtmann
604d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_USER_CHANNEL)) {
6055c912495SMarcel Holtmann err = -EBUSY;
6065c912495SMarcel Holtmann goto done;
6075c912495SMarcel Holtmann }
6085c912495SMarcel Holtmann
609d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_UNCONFIGURED)) {
6105c912495SMarcel Holtmann err = -EOPNOTSUPP;
6115c912495SMarcel Holtmann goto done;
6125c912495SMarcel Holtmann }
6135c912495SMarcel Holtmann
6145c912495SMarcel Holtmann err = hci_dev_do_reset(hdev);
6155c912495SMarcel Holtmann
6165c912495SMarcel Holtmann done:
6175c912495SMarcel Holtmann hci_dev_put(hdev);
6185c912495SMarcel Holtmann return err;
6195c912495SMarcel Holtmann }
hci_dev_reset_stat(__u16 dev)6205c912495SMarcel Holtmann
6211da177e4SLinus Torvalds int hci_dev_reset_stat(__u16 dev)
6221da177e4SLinus Torvalds {
6231da177e4SLinus Torvalds struct hci_dev *hdev;
6241da177e4SLinus Torvalds int ret = 0;
6251da177e4SLinus Torvalds
62670f23020SAndrei Emeltchenko hdev = hci_dev_get(dev);
62770f23020SAndrei Emeltchenko if (!hdev)
6281da177e4SLinus Torvalds return -ENODEV;
6291da177e4SLinus Torvalds
630d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_USER_CHANNEL)) {
6310736cfa8SMarcel Holtmann ret = -EBUSY;
6320736cfa8SMarcel Holtmann goto done;
6330736cfa8SMarcel Holtmann }
6340736cfa8SMarcel Holtmann
635d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_UNCONFIGURED)) {
636fee746b0SMarcel Holtmann ret = -EOPNOTSUPP;
637fee746b0SMarcel Holtmann goto done;
638fee746b0SMarcel Holtmann }
639fee746b0SMarcel Holtmann
6401da177e4SLinus Torvalds memset(&hdev->stat, 0, sizeof(struct hci_dev_stats));
6411da177e4SLinus Torvalds
6420736cfa8SMarcel Holtmann done:
6431da177e4SLinus Torvalds hci_dev_put(hdev);
6441da177e4SLinus Torvalds return ret;
6451da177e4SLinus Torvalds }
hci_update_passive_scan_state(struct hci_dev * hdev,u8 scan)6461da177e4SLinus Torvalds
6475bee2fd6SLuiz Augusto von Dentz static void hci_update_passive_scan_state(struct hci_dev *hdev, u8 scan)
648123abc08SJohan Hedberg {
649bc6d2d04SJohan Hedberg bool conn_changed, discov_changed;
650123abc08SJohan Hedberg
651123abc08SJohan Hedberg BT_DBG("%s scan 0x%02x", hdev->name, scan);
652123abc08SJohan Hedberg
653123abc08SJohan Hedberg if ((scan & SCAN_PAGE))
654238be788SMarcel Holtmann conn_changed = !hci_dev_test_and_set_flag(hdev,
655238be788SMarcel Holtmann HCI_CONNECTABLE);
656123abc08SJohan Hedberg else
657a69d8927SMarcel Holtmann conn_changed = hci_dev_test_and_clear_flag(hdev,
658a69d8927SMarcel Holtmann HCI_CONNECTABLE);
659123abc08SJohan Hedberg
660bc6d2d04SJohan Hedberg if ((scan & SCAN_INQUIRY)) {
661238be788SMarcel Holtmann discov_changed = !hci_dev_test_and_set_flag(hdev,
662238be788SMarcel Holtmann HCI_DISCOVERABLE);
663bc6d2d04SJohan Hedberg } else {
664a358dc11SMarcel Holtmann hci_dev_clear_flag(hdev, HCI_LIMITED_DISCOVERABLE);
665a69d8927SMarcel Holtmann discov_changed = hci_dev_test_and_clear_flag(hdev,
666a69d8927SMarcel Holtmann HCI_DISCOVERABLE);
667bc6d2d04SJohan Hedberg }
668bc6d2d04SJohan Hedberg
669d7a5a11dSMarcel Holtmann if (!hci_dev_test_flag(hdev, HCI_MGMT))
670123abc08SJohan Hedberg return;
671123abc08SJohan Hedberg
672bc6d2d04SJohan Hedberg if (conn_changed || discov_changed) {
673bc6d2d04SJohan Hedberg /* In case this was disabled through mgmt */
674a1536da2SMarcel Holtmann hci_dev_set_flag(hdev, HCI_BREDR_ENABLED);
675bc6d2d04SJohan Hedberg
676d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_LE_ENABLED))
677651cd3d6SBrian Gix hci_update_adv_data(hdev, hdev->cur_adv_instance);
678bc6d2d04SJohan Hedberg
679123abc08SJohan Hedberg mgmt_new_settings(hdev);
680123abc08SJohan Hedberg }
681bc6d2d04SJohan Hedberg }
hci_dev_cmd(unsigned int cmd,void __user * arg)682123abc08SJohan Hedberg
6831da177e4SLinus Torvalds int hci_dev_cmd(unsigned int cmd, void __user *arg)
6841da177e4SLinus Torvalds {
6851da177e4SLinus Torvalds struct hci_dev *hdev;
6861da177e4SLinus Torvalds struct hci_dev_req dr;
687b0fc1bd2SLuiz Augusto von Dentz __le16 policy;
6881da177e4SLinus Torvalds int err = 0;
6891da177e4SLinus Torvalds
6901da177e4SLinus Torvalds if (copy_from_user(&dr, arg, sizeof(dr)))
6911da177e4SLinus Torvalds return -EFAULT;
6921da177e4SLinus Torvalds
69370f23020SAndrei Emeltchenko hdev = hci_dev_get(dr.dev_id);
69470f23020SAndrei Emeltchenko if (!hdev)
6951da177e4SLinus Torvalds return -ENODEV;
6961da177e4SLinus Torvalds
697d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_USER_CHANNEL)) {
6980736cfa8SMarcel Holtmann err = -EBUSY;
6990736cfa8SMarcel Holtmann goto done;
7000736cfa8SMarcel Holtmann }
7010736cfa8SMarcel Holtmann
702d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_UNCONFIGURED)) {
703fee746b0SMarcel Holtmann err = -EOPNOTSUPP;
704fee746b0SMarcel Holtmann goto done;
705fee746b0SMarcel Holtmann }
706fee746b0SMarcel Holtmann
707d7a5a11dSMarcel Holtmann if (!hci_dev_test_flag(hdev, HCI_BREDR_ENABLED)) {
70856f87901SJohan Hedberg err = -EOPNOTSUPP;
70956f87901SJohan Hedberg goto done;
71056f87901SJohan Hedberg }
71156f87901SJohan Hedberg
7121da177e4SLinus Torvalds switch (cmd) {
7131da177e4SLinus Torvalds case HCISETAUTH:
7145f77c8e8SLuiz Augusto von Dentz err = hci_cmd_sync_status(hdev, HCI_OP_WRITE_AUTH_ENABLE,
715b0fc1bd2SLuiz Augusto von Dentz 1, &dr.dev_opt, HCI_CMD_TIMEOUT);
7161da177e4SLinus Torvalds break;
7171da177e4SLinus Torvalds
7181da177e4SLinus Torvalds case HCISETENCRYPT:
7191da177e4SLinus Torvalds if (!lmp_encrypt_capable(hdev)) {
7201da177e4SLinus Torvalds err = -EOPNOTSUPP;
7211da177e4SLinus Torvalds break;
7221da177e4SLinus Torvalds }
7231da177e4SLinus Torvalds
7241da177e4SLinus Torvalds if (!test_bit(HCI_AUTH, &hdev->flags)) {
7251da177e4SLinus Torvalds /* Auth must be enabled first */
7265f77c8e8SLuiz Augusto von Dentz err = hci_cmd_sync_status(hdev,
727b0fc1bd2SLuiz Augusto von Dentz HCI_OP_WRITE_AUTH_ENABLE,
728b0fc1bd2SLuiz Augusto von Dentz 1, &dr.dev_opt,
729b0fc1bd2SLuiz Augusto von Dentz HCI_CMD_TIMEOUT);
7301da177e4SLinus Torvalds if (err)
7311da177e4SLinus Torvalds break;
7321da177e4SLinus Torvalds }
7331da177e4SLinus Torvalds
7345f77c8e8SLuiz Augusto von Dentz err = hci_cmd_sync_status(hdev, HCI_OP_WRITE_ENCRYPT_MODE,
7355f77c8e8SLuiz Augusto von Dentz 1, &dr.dev_opt, HCI_CMD_TIMEOUT);
7361da177e4SLinus Torvalds break;
7371da177e4SLinus Torvalds
7381da177e4SLinus Torvalds case HCISETSCAN:
7395f77c8e8SLuiz Augusto von Dentz err = hci_cmd_sync_status(hdev, HCI_OP_WRITE_SCAN_ENABLE,
7405f77c8e8SLuiz Augusto von Dentz 1, &dr.dev_opt, HCI_CMD_TIMEOUT);
74191a668b0SJohan Hedberg
742bc6d2d04SJohan Hedberg /* Ensure that the connectable and discoverable states
743bc6d2d04SJohan Hedberg * get correctly modified as this was a non-mgmt change.
74491a668b0SJohan Hedberg */
745123abc08SJohan Hedberg if (!err)
7465bee2fd6SLuiz Augusto von Dentz hci_update_passive_scan_state(hdev, dr.dev_opt);
7471da177e4SLinus Torvalds break;
7481da177e4SLinus Torvalds
7491da177e4SLinus Torvalds case HCISETLINKPOL:
750b0fc1bd2SLuiz Augusto von Dentz policy = cpu_to_le16(dr.dev_opt);
751b0fc1bd2SLuiz Augusto von Dentz
7525f77c8e8SLuiz Augusto von Dentz err = hci_cmd_sync_status(hdev, HCI_OP_WRITE_DEF_LINK_POLICY,
7535f77c8e8SLuiz Augusto von Dentz 2, &policy, HCI_CMD_TIMEOUT);
7541da177e4SLinus Torvalds break;
7551da177e4SLinus Torvalds
7561da177e4SLinus Torvalds case HCISETLINKMODE:
757e4e8e37cSMarcel Holtmann hdev->link_mode = ((__u16) dr.dev_opt) &
758e4e8e37cSMarcel Holtmann (HCI_LM_MASTER | HCI_LM_ACCEPT);
759e4e8e37cSMarcel Holtmann break;
760e4e8e37cSMarcel Holtmann
761e4e8e37cSMarcel Holtmann case HCISETPTYPE:
762b7c23df8SJaganath Kanakkassery if (hdev->pkt_type == (__u16) dr.dev_opt)
763b7c23df8SJaganath Kanakkassery break;
764b7c23df8SJaganath Kanakkassery
765e4e8e37cSMarcel Holtmann hdev->pkt_type = (__u16) dr.dev_opt;
766b7c23df8SJaganath Kanakkassery mgmt_phy_configuration_changed(hdev, NULL);
7671da177e4SLinus Torvalds break;
7681da177e4SLinus Torvalds
7691da177e4SLinus Torvalds case HCISETACLMTU:
7701da177e4SLinus Torvalds hdev->acl_mtu = *((__u16 *) &dr.dev_opt + 1);
7711da177e4SLinus Torvalds hdev->acl_pkts = *((__u16 *) &dr.dev_opt + 0);
7721da177e4SLinus Torvalds break;
7731da177e4SLinus Torvalds
7741da177e4SLinus Torvalds case HCISETSCOMTU:
7751da177e4SLinus Torvalds hdev->sco_mtu = *((__u16 *) &dr.dev_opt + 1);
7761da177e4SLinus Torvalds hdev->sco_pkts = *((__u16 *) &dr.dev_opt + 0);
7771da177e4SLinus Torvalds break;
7781da177e4SLinus Torvalds
7791da177e4SLinus Torvalds default:
7801da177e4SLinus Torvalds err = -EINVAL;
7811da177e4SLinus Torvalds break;
7821da177e4SLinus Torvalds }
783e4e8e37cSMarcel Holtmann
7840736cfa8SMarcel Holtmann done:
7851da177e4SLinus Torvalds hci_dev_put(hdev);
7861da177e4SLinus Torvalds return err;
7871da177e4SLinus Torvalds }
hci_get_dev_list(void __user * arg)7881da177e4SLinus Torvalds
7891da177e4SLinus Torvalds int hci_get_dev_list(void __user *arg)
7901da177e4SLinus Torvalds {
7918035ded4SLuiz Augusto von Dentz struct hci_dev *hdev;
7921da177e4SLinus Torvalds struct hci_dev_list_req *dl;
7931da177e4SLinus Torvalds struct hci_dev_req *dr;
7941da177e4SLinus Torvalds int n = 0, size, err;
7951da177e4SLinus Torvalds __u16 dev_num;
7961da177e4SLinus Torvalds
7971da177e4SLinus Torvalds if (get_user(dev_num, (__u16 __user *) arg))
7981da177e4SLinus Torvalds return -EFAULT;
7991da177e4SLinus Torvalds
8001da177e4SLinus Torvalds if (!dev_num || dev_num > (PAGE_SIZE * 2) / sizeof(*dr))
8011da177e4SLinus Torvalds return -EINVAL;
8021da177e4SLinus Torvalds
8031da177e4SLinus Torvalds size = sizeof(*dl) + dev_num * sizeof(*dr);
8041da177e4SLinus Torvalds
80570f23020SAndrei Emeltchenko dl = kzalloc(size, GFP_KERNEL);
80670f23020SAndrei Emeltchenko if (!dl)
8071da177e4SLinus Torvalds return -ENOMEM;
8081da177e4SLinus Torvalds
8091da177e4SLinus Torvalds dr = dl->dev_req;
8101da177e4SLinus Torvalds
811f20d09d5SGustavo F. Padovan read_lock(&hci_dev_list_lock);
8128035ded4SLuiz Augusto von Dentz list_for_each_entry(hdev, &hci_dev_list, list) {
8132e84d8dbSMarcel Holtmann unsigned long flags = hdev->flags;
814c542a06cSJohan Hedberg
8152e84d8dbSMarcel Holtmann /* When the auto-off is configured it means the transport
8162e84d8dbSMarcel Holtmann * is running, but in that case still indicate that the
8172e84d8dbSMarcel Holtmann * device is actually down.
8182e84d8dbSMarcel Holtmann */
819d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_AUTO_OFF))
8202e84d8dbSMarcel Holtmann flags &= ~BIT(HCI_UP);
821c542a06cSJohan Hedberg
8221da177e4SLinus Torvalds (dr + n)->dev_id = hdev->id;
8232e84d8dbSMarcel Holtmann (dr + n)->dev_opt = flags;
824c542a06cSJohan Hedberg
8251da177e4SLinus Torvalds if (++n >= dev_num)
8261da177e4SLinus Torvalds break;
8271da177e4SLinus Torvalds }
828f20d09d5SGustavo F. Padovan read_unlock(&hci_dev_list_lock);
8291da177e4SLinus Torvalds
8301da177e4SLinus Torvalds dl->dev_num = n;
8311da177e4SLinus Torvalds size = sizeof(*dl) + n * sizeof(*dr);
8321da177e4SLinus Torvalds
8331da177e4SLinus Torvalds err = copy_to_user(arg, dl, size);
8341da177e4SLinus Torvalds kfree(dl);
8351da177e4SLinus Torvalds
8361da177e4SLinus Torvalds return err ? -EFAULT : 0;
8371da177e4SLinus Torvalds }
hci_get_dev_info(void __user * arg)8381da177e4SLinus Torvalds
8391da177e4SLinus Torvalds int hci_get_dev_info(void __user *arg)
8401da177e4SLinus Torvalds {
8411da177e4SLinus Torvalds struct hci_dev *hdev;
8421da177e4SLinus Torvalds struct hci_dev_info di;
8432e84d8dbSMarcel Holtmann unsigned long flags;
8441da177e4SLinus Torvalds int err = 0;
8451da177e4SLinus Torvalds
8461da177e4SLinus Torvalds if (copy_from_user(&di, arg, sizeof(di)))
8471da177e4SLinus Torvalds return -EFAULT;
8481da177e4SLinus Torvalds
84970f23020SAndrei Emeltchenko hdev = hci_dev_get(di.dev_id);
85070f23020SAndrei Emeltchenko if (!hdev)
8511da177e4SLinus Torvalds return -ENODEV;
8521da177e4SLinus Torvalds
8532e84d8dbSMarcel Holtmann /* When the auto-off is configured it means the transport
8542e84d8dbSMarcel Holtmann * is running, but in that case still indicate that the
8552e84d8dbSMarcel Holtmann * device is actually down.
8562e84d8dbSMarcel Holtmann */
857d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_AUTO_OFF))
8582e84d8dbSMarcel Holtmann flags = hdev->flags & ~BIT(HCI_UP);
8592e84d8dbSMarcel Holtmann else
8602e84d8dbSMarcel Holtmann flags = hdev->flags;
861c542a06cSJohan Hedberg
862a41c8efeSLuiz Augusto von Dentz strscpy(di.name, hdev->name, sizeof(di.name));
8631da177e4SLinus Torvalds di.bdaddr = hdev->bdaddr;
8645af2e235SLuiz Augusto von Dentz di.type = (hdev->bus & 0x0f);
8652e84d8dbSMarcel Holtmann di.flags = flags;
8661da177e4SLinus Torvalds di.pkt_type = hdev->pkt_type;
867572c7f84SJohan Hedberg if (lmp_bredr_capable(hdev)) {
8681da177e4SLinus Torvalds di.acl_mtu = hdev->acl_mtu;
8691da177e4SLinus Torvalds di.acl_pkts = hdev->acl_pkts;
8701da177e4SLinus Torvalds di.sco_mtu = hdev->sco_mtu;
8711da177e4SLinus Torvalds di.sco_pkts = hdev->sco_pkts;
872572c7f84SJohan Hedberg } else {
873572c7f84SJohan Hedberg di.acl_mtu = hdev->le_mtu;
874572c7f84SJohan Hedberg di.acl_pkts = hdev->le_pkts;
875572c7f84SJohan Hedberg di.sco_mtu = 0;
876572c7f84SJohan Hedberg di.sco_pkts = 0;
877572c7f84SJohan Hedberg }
8781da177e4SLinus Torvalds di.link_policy = hdev->link_policy;
8791da177e4SLinus Torvalds di.link_mode = hdev->link_mode;
8801da177e4SLinus Torvalds
8811da177e4SLinus Torvalds memcpy(&di.stat, &hdev->stat, sizeof(di.stat));
8821da177e4SLinus Torvalds memcpy(&di.features, &hdev->features, sizeof(di.features));
8831da177e4SLinus Torvalds
8841da177e4SLinus Torvalds if (copy_to_user(arg, &di, sizeof(di)))
8851da177e4SLinus Torvalds err = -EFAULT;
8861da177e4SLinus Torvalds
8871da177e4SLinus Torvalds hci_dev_put(hdev);
8881da177e4SLinus Torvalds
8891da177e4SLinus Torvalds return err;
8901da177e4SLinus Torvalds }
8911da177e4SLinus Torvalds
8921da177e4SLinus Torvalds /* ---- Interface to HCI drivers ---- */
hci_rfkill_set_block(void * data,bool blocked)8931da177e4SLinus Torvalds
894611b30f7SMarcel Holtmann static int hci_rfkill_set_block(void *data, bool blocked)
895611b30f7SMarcel Holtmann {
896611b30f7SMarcel Holtmann struct hci_dev *hdev = data;
897611b30f7SMarcel Holtmann
898611b30f7SMarcel Holtmann BT_DBG("%p name %s blocked %d", hdev, hdev->name, blocked);
899611b30f7SMarcel Holtmann
900d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_USER_CHANNEL))
9010736cfa8SMarcel Holtmann return -EBUSY;
9020736cfa8SMarcel Holtmann
9035e130367SJohan Hedberg if (blocked) {
904a1536da2SMarcel Holtmann hci_dev_set_flag(hdev, HCI_RFKILLED);
905d7a5a11dSMarcel Holtmann if (!hci_dev_test_flag(hdev, HCI_SETUP) &&
906d7a5a11dSMarcel Holtmann !hci_dev_test_flag(hdev, HCI_CONFIG))
907611b30f7SMarcel Holtmann hci_dev_do_close(hdev);
9085e130367SJohan Hedberg } else {
909a358dc11SMarcel Holtmann hci_dev_clear_flag(hdev, HCI_RFKILLED);
9105e130367SJohan Hedberg }
911611b30f7SMarcel Holtmann
912611b30f7SMarcel Holtmann return 0;
913611b30f7SMarcel Holtmann }
914611b30f7SMarcel Holtmann
915611b30f7SMarcel Holtmann static const struct rfkill_ops hci_rfkill_ops = {
916611b30f7SMarcel Holtmann .set_block = hci_rfkill_set_block,
917611b30f7SMarcel Holtmann };
hci_power_on(struct work_struct * work)918611b30f7SMarcel Holtmann
919ab81cbf9SJohan Hedberg static void hci_power_on(struct work_struct *work)
920ab81cbf9SJohan Hedberg {
921ab81cbf9SJohan Hedberg struct hci_dev *hdev = container_of(work, struct hci_dev, power_on);
92296570ffcSJohan Hedberg int err;
923ab81cbf9SJohan Hedberg
924ab81cbf9SJohan Hedberg BT_DBG("%s", hdev->name);
925ab81cbf9SJohan Hedberg
9262ff13894SJohan Hedberg if (test_bit(HCI_UP, &hdev->flags) &&
9272ff13894SJohan Hedberg hci_dev_test_flag(hdev, HCI_MGMT) &&
9282ff13894SJohan Hedberg hci_dev_test_and_clear_flag(hdev, HCI_AUTO_OFF)) {
929d82142a8SWei-Ning Huang cancel_delayed_work(&hdev->power_off);
930cf75ad8bSLuiz Augusto von Dentz err = hci_powered_update_sync(hdev);
9312ff13894SJohan Hedberg mgmt_power_on(hdev, err);
9322ff13894SJohan Hedberg return;
9332ff13894SJohan Hedberg }
9342ff13894SJohan Hedberg
935cbed0ca1SJohan Hedberg err = hci_dev_do_open(hdev);
93696570ffcSJohan Hedberg if (err < 0) {
9373ad67582SJaganath Kanakkassery hci_dev_lock(hdev);
93896570ffcSJohan Hedberg mgmt_set_powered_failed(hdev, err);
9393ad67582SJaganath Kanakkassery hci_dev_unlock(hdev);
940ab81cbf9SJohan Hedberg return;
94196570ffcSJohan Hedberg }
942ab81cbf9SJohan Hedberg
943a5c8f270SMarcel Holtmann /* During the HCI setup phase, a few error conditions are
944a5c8f270SMarcel Holtmann * ignored and they need to be checked now. If they are still
945a5c8f270SMarcel Holtmann * valid, it is important to turn the device back off.
946a5c8f270SMarcel Holtmann */
947d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_RFKILLED) ||
948d7a5a11dSMarcel Holtmann hci_dev_test_flag(hdev, HCI_UNCONFIGURED) ||
9495af2e235SLuiz Augusto von Dentz (!bacmp(&hdev->bdaddr, BDADDR_ANY) &&
950a5c8f270SMarcel Holtmann !bacmp(&hdev->static_addr, BDADDR_ANY))) {
951a358dc11SMarcel Holtmann hci_dev_clear_flag(hdev, HCI_AUTO_OFF);
952bf543036SJohan Hedberg hci_dev_do_close(hdev);
953d7a5a11dSMarcel Holtmann } else if (hci_dev_test_flag(hdev, HCI_AUTO_OFF)) {
95419202573SJohan Hedberg queue_delayed_work(hdev->req_workqueue, &hdev->power_off,
95519202573SJohan Hedberg HCI_AUTO_OFF_TIMEOUT);
956bf543036SJohan Hedberg }
957ab81cbf9SJohan Hedberg
958a69d8927SMarcel Holtmann if (hci_dev_test_and_clear_flag(hdev, HCI_SETUP)) {
9594a964404SMarcel Holtmann /* For unconfigured devices, set the HCI_RAW flag
9604a964404SMarcel Holtmann * so that userspace can easily identify them.
9614a964404SMarcel Holtmann */
962d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_UNCONFIGURED))
9634a964404SMarcel Holtmann set_bit(HCI_RAW, &hdev->flags);
9640602a8adSMarcel Holtmann
9650602a8adSMarcel Holtmann /* For fully configured devices, this will send
9660602a8adSMarcel Holtmann * the Index Added event. For unconfigured devices,
9670602a8adSMarcel Holtmann * it will send Unconfigued Index Added event.
9680602a8adSMarcel Holtmann *
9690602a8adSMarcel Holtmann * Devices with HCI_QUIRK_RAW_DEVICE are ignored
9700602a8adSMarcel Holtmann * and no event will be send.
9710602a8adSMarcel Holtmann */
972744cf19eSJohan Hedberg mgmt_index_added(hdev);
973a69d8927SMarcel Holtmann } else if (hci_dev_test_and_clear_flag(hdev, HCI_CONFIG)) {
9745ea234d3SMarcel Holtmann /* When the controller is now configured, then it
9755ea234d3SMarcel Holtmann * is important to clear the HCI_RAW flag.
9765ea234d3SMarcel Holtmann */
977d7a5a11dSMarcel Holtmann if (!hci_dev_test_flag(hdev, HCI_UNCONFIGURED))
9785ea234d3SMarcel Holtmann clear_bit(HCI_RAW, &hdev->flags);
9795ea234d3SMarcel Holtmann
980d603b76bSMarcel Holtmann /* Powering on the controller with HCI_CONFIG set only
981d603b76bSMarcel Holtmann * happens with the transition from unconfigured to
982d603b76bSMarcel Holtmann * configured. This will send the Index Added event.
983d603b76bSMarcel Holtmann */
984d603b76bSMarcel Holtmann mgmt_index_added(hdev);
985ab81cbf9SJohan Hedberg }
986ab81cbf9SJohan Hedberg }
hci_power_off(struct work_struct * work)987ab81cbf9SJohan Hedberg
988ab81cbf9SJohan Hedberg static void hci_power_off(struct work_struct *work)
989ab81cbf9SJohan Hedberg {
9903243553fSJohan Hedberg struct hci_dev *hdev = container_of(work, struct hci_dev,
9913243553fSJohan Hedberg power_off.work);
992ab81cbf9SJohan Hedberg
993ab81cbf9SJohan Hedberg BT_DBG("%s", hdev->name);
994ab81cbf9SJohan Hedberg
9958ee56540SMarcel Holtmann hci_dev_do_close(hdev);
996ab81cbf9SJohan Hedberg }
hci_error_reset(struct work_struct * work)997ab81cbf9SJohan Hedberg
998c7741d16SMarcel Holtmann static void hci_error_reset(struct work_struct *work)
999c7741d16SMarcel Holtmann {
1000c7741d16SMarcel Holtmann struct hci_dev *hdev = container_of(work, struct hci_dev, error_reset);
1001c7741d16SMarcel Holtmann
10022ab9a19dSYing Hsu hci_dev_hold(hdev);
1003c7741d16SMarcel Holtmann BT_DBG("%s", hdev->name);
1004c7741d16SMarcel Holtmann
1005c7741d16SMarcel Holtmann if (hdev->hw_error)
1006c7741d16SMarcel Holtmann hdev->hw_error(hdev, hdev->hw_error_code);
1007c7741d16SMarcel Holtmann else
10082064ee33SMarcel Holtmann bt_dev_err(hdev, "hardware error 0x%2.2x", hdev->hw_error_code);
1009c7741d16SMarcel Holtmann
10102ab9a19dSYing Hsu if (!hci_dev_do_close(hdev))
1011c7741d16SMarcel Holtmann hci_dev_do_open(hdev);
10122ab9a19dSYing Hsu
10132ab9a19dSYing Hsu hci_dev_put(hdev);
1014c7741d16SMarcel Holtmann }
hci_uuids_clear(struct hci_dev * hdev)1015c7741d16SMarcel Holtmann
101635f7498aSJohan Hedberg void hci_uuids_clear(struct hci_dev *hdev)
10172aeb9a1aSJohan Hedberg {
10184821002cSJohan Hedberg struct bt_uuid *uuid, *tmp;
10192aeb9a1aSJohan Hedberg
10204821002cSJohan Hedberg list_for_each_entry_safe(uuid, tmp, &hdev->uuids, list) {
10214821002cSJohan Hedberg list_del(&uuid->list);
10222aeb9a1aSJohan Hedberg kfree(uuid);
10232aeb9a1aSJohan Hedberg }
10242aeb9a1aSJohan Hedberg }
hci_link_keys_clear(struct hci_dev * hdev)10252aeb9a1aSJohan Hedberg
102635f7498aSJohan Hedberg void hci_link_keys_clear(struct hci_dev *hdev)
102755ed8ca1SJohan Hedberg {
10283673952cSMin Li struct link_key *key, *tmp;
102955ed8ca1SJohan Hedberg
10303673952cSMin Li list_for_each_entry_safe(key, tmp, &hdev->link_keys, list) {
10310378b597SJohan Hedberg list_del_rcu(&key->list);
10320378b597SJohan Hedberg kfree_rcu(key, rcu);
103355ed8ca1SJohan Hedberg }
103455ed8ca1SJohan Hedberg }
hci_smp_ltks_clear(struct hci_dev * hdev)103555ed8ca1SJohan Hedberg
103635f7498aSJohan Hedberg void hci_smp_ltks_clear(struct hci_dev *hdev)
1037b899efafSVinicius Costa Gomes {
10383673952cSMin Li struct smp_ltk *k, *tmp;
1039b899efafSVinicius Costa Gomes
10403673952cSMin Li list_for_each_entry_safe(k, tmp, &hdev->long_term_keys, list) {
1041970d0f1bSJohan Hedberg list_del_rcu(&k->list);
1042970d0f1bSJohan Hedberg kfree_rcu(k, rcu);
1043b899efafSVinicius Costa Gomes }
1044b899efafSVinicius Costa Gomes }
hci_smp_irks_clear(struct hci_dev * hdev)1045b899efafSVinicius Costa Gomes
1046970c4e46SJohan Hedberg void hci_smp_irks_clear(struct hci_dev *hdev)
1047970c4e46SJohan Hedberg {
10483673952cSMin Li struct smp_irk *k, *tmp;
1049970c4e46SJohan Hedberg
10503673952cSMin Li list_for_each_entry_safe(k, tmp, &hdev->identity_resolving_keys, list) {
1051adae20cbSJohan Hedberg list_del_rcu(&k->list);
1052adae20cbSJohan Hedberg kfree_rcu(k, rcu);
1053970c4e46SJohan Hedberg }
1054970c4e46SJohan Hedberg }
hci_blocked_keys_clear(struct hci_dev * hdev)1055970c4e46SJohan Hedberg
1056600a8749SAlain Michaud void hci_blocked_keys_clear(struct hci_dev *hdev)
1057600a8749SAlain Michaud {
10583673952cSMin Li struct blocked_key *b, *tmp;
1059600a8749SAlain Michaud
10603673952cSMin Li list_for_each_entry_safe(b, tmp, &hdev->blocked_keys, list) {
1061600a8749SAlain Michaud list_del_rcu(&b->list);
1062600a8749SAlain Michaud kfree_rcu(b, rcu);
1063600a8749SAlain Michaud }
1064600a8749SAlain Michaud }
hci_is_blocked_key(struct hci_dev * hdev,u8 type,u8 val[16])1065600a8749SAlain Michaud
1066600a8749SAlain Michaud bool hci_is_blocked_key(struct hci_dev *hdev, u8 type, u8 val[16])
1067600a8749SAlain Michaud {
1068600a8749SAlain Michaud bool blocked = false;
1069600a8749SAlain Michaud struct blocked_key *b;
1070600a8749SAlain Michaud
1071600a8749SAlain Michaud rcu_read_lock();
10720c2ac7d4SMadhuparna Bhowmik list_for_each_entry_rcu(b, &hdev->blocked_keys, list) {
1073600a8749SAlain Michaud if (b->type == type && !memcmp(b->val, val, sizeof(b->val))) {
1074600a8749SAlain Michaud blocked = true;
1075600a8749SAlain Michaud break;
1076600a8749SAlain Michaud }
1077600a8749SAlain Michaud }
1078600a8749SAlain Michaud
1079600a8749SAlain Michaud rcu_read_unlock();
1080600a8749SAlain Michaud return blocked;
1081600a8749SAlain Michaud }
hci_find_link_key(struct hci_dev * hdev,bdaddr_t * bdaddr)1082600a8749SAlain Michaud
108355ed8ca1SJohan Hedberg struct link_key *hci_find_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr)
108455ed8ca1SJohan Hedberg {
108555ed8ca1SJohan Hedberg struct link_key *k;
108655ed8ca1SJohan Hedberg
10870378b597SJohan Hedberg rcu_read_lock();
10880378b597SJohan Hedberg list_for_each_entry_rcu(k, &hdev->link_keys, list) {
10890378b597SJohan Hedberg if (bacmp(bdaddr, &k->bdaddr) == 0) {
10900378b597SJohan Hedberg rcu_read_unlock();
1091600a8749SAlain Michaud
1092600a8749SAlain Michaud if (hci_is_blocked_key(hdev,
1093600a8749SAlain Michaud HCI_BLOCKED_KEY_TYPE_LINKKEY,
1094600a8749SAlain Michaud k->val)) {
1095600a8749SAlain Michaud bt_dev_warn_ratelimited(hdev,
1096600a8749SAlain Michaud "Link key blocked for %pMR",
1097600a8749SAlain Michaud &k->bdaddr);
1098600a8749SAlain Michaud return NULL;
1099600a8749SAlain Michaud }
1100600a8749SAlain Michaud
110155ed8ca1SJohan Hedberg return k;
11020378b597SJohan Hedberg }
11030378b597SJohan Hedberg }
11040378b597SJohan Hedberg rcu_read_unlock();
110555ed8ca1SJohan Hedberg
110655ed8ca1SJohan Hedberg return NULL;
110755ed8ca1SJohan Hedberg }
hci_persistent_key(struct hci_dev * hdev,struct hci_conn * conn,u8 key_type,u8 old_key_type)110855ed8ca1SJohan Hedberg
1109745c0ce3SVishal Agarwal static bool hci_persistent_key(struct hci_dev *hdev, struct hci_conn *conn,
1110d25e28abSJohan Hedberg u8 key_type, u8 old_key_type)
1111d25e28abSJohan Hedberg {
1112d25e28abSJohan Hedberg /* Legacy key */
1113d25e28abSJohan Hedberg if (key_type < 0x03)
1114745c0ce3SVishal Agarwal return true;
1115d25e28abSJohan Hedberg
1116d25e28abSJohan Hedberg /* Debug keys are insecure so don't store them persistently */
1117d25e28abSJohan Hedberg if (key_type == HCI_LK_DEBUG_COMBINATION)
1118745c0ce3SVishal Agarwal return false;
1119d25e28abSJohan Hedberg
1120d25e28abSJohan Hedberg /* Changed combination key and there's no previous one */
1121d25e28abSJohan Hedberg if (key_type == HCI_LK_CHANGED_COMBINATION && old_key_type == 0xff)
1122745c0ce3SVishal Agarwal return false;
1123d25e28abSJohan Hedberg
1124d25e28abSJohan Hedberg /* Security mode 3 case */
1125d25e28abSJohan Hedberg if (!conn)
1126745c0ce3SVishal Agarwal return true;
1127d25e28abSJohan Hedberg
1128e3befab9SJohan Hedberg /* BR/EDR key derived using SC from an LE link */
1129e3befab9SJohan Hedberg if (conn->type == LE_LINK)
1130e3befab9SJohan Hedberg return true;
1131e3befab9SJohan Hedberg
1132d25e28abSJohan Hedberg /* Neither local nor remote side had no-bonding as requirement */
1133d25e28abSJohan Hedberg if (conn->auth_type > 0x01 && conn->remote_auth > 0x01)
1134745c0ce3SVishal Agarwal return true;
1135d25e28abSJohan Hedberg
1136d25e28abSJohan Hedberg /* Local side had dedicated bonding as requirement */
1137d25e28abSJohan Hedberg if (conn->auth_type == 0x02 || conn->auth_type == 0x03)
1138745c0ce3SVishal Agarwal return true;
1139d25e28abSJohan Hedberg
1140d25e28abSJohan Hedberg /* Remote side had dedicated bonding as requirement */
1141d25e28abSJohan Hedberg if (conn->remote_auth == 0x02 || conn->remote_auth == 0x03)
1142745c0ce3SVishal Agarwal return true;
1143d25e28abSJohan Hedberg
1144d25e28abSJohan Hedberg /* If none of the above criteria match, then don't store the key
1145d25e28abSJohan Hedberg * persistently */
1146745c0ce3SVishal Agarwal return false;
1147d25e28abSJohan Hedberg }
ltk_role(u8 type)1148d25e28abSJohan Hedberg
1149e804d25dSJohan Hedberg static u8 ltk_role(u8 type)
115098a0b845SJohan Hedberg {
1151e804d25dSJohan Hedberg if (type == SMP_LTK)
1152e804d25dSJohan Hedberg return HCI_ROLE_MASTER;
115398a0b845SJohan Hedberg
1154e804d25dSJohan Hedberg return HCI_ROLE_SLAVE;
115598a0b845SJohan Hedberg }
hci_find_ltk(struct hci_dev * hdev,bdaddr_t * bdaddr,u8 addr_type,u8 role)115698a0b845SJohan Hedberg
1157f3a73d97SJohan Hedberg struct smp_ltk *hci_find_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr,
1158e804d25dSJohan Hedberg u8 addr_type, u8 role)
115975d262c2SVinicius Costa Gomes {
1160c9839a11SVinicius Costa Gomes struct smp_ltk *k;
116175d262c2SVinicius Costa Gomes
1162970d0f1bSJohan Hedberg rcu_read_lock();
1163970d0f1bSJohan Hedberg list_for_each_entry_rcu(k, &hdev->long_term_keys, list) {
11645378bc56SJohan Hedberg if (addr_type != k->bdaddr_type || bacmp(bdaddr, &k->bdaddr))
11655378bc56SJohan Hedberg continue;
11665378bc56SJohan Hedberg
1167923e2414SJohan Hedberg if (smp_ltk_is_sc(k) || ltk_role(k->type) == role) {
1168970d0f1bSJohan Hedberg rcu_read_unlock();
1169600a8749SAlain Michaud
1170600a8749SAlain Michaud if (hci_is_blocked_key(hdev, HCI_BLOCKED_KEY_TYPE_LTK,
1171600a8749SAlain Michaud k->val)) {
1172600a8749SAlain Michaud bt_dev_warn_ratelimited(hdev,
1173600a8749SAlain Michaud "LTK blocked for %pMR",
1174600a8749SAlain Michaud &k->bdaddr);
1175600a8749SAlain Michaud return NULL;
1176600a8749SAlain Michaud }
1177600a8749SAlain Michaud
117875d262c2SVinicius Costa Gomes return k;
1179970d0f1bSJohan Hedberg }
1180970d0f1bSJohan Hedberg }
1181970d0f1bSJohan Hedberg rcu_read_unlock();
118275d262c2SVinicius Costa Gomes
118375d262c2SVinicius Costa Gomes return NULL;
118475d262c2SVinicius Costa Gomes }
hci_find_irk_by_rpa(struct hci_dev * hdev,bdaddr_t * rpa)118575d262c2SVinicius Costa Gomes
1186970c4e46SJohan Hedberg struct smp_irk *hci_find_irk_by_rpa(struct hci_dev *hdev, bdaddr_t *rpa)
1187970c4e46SJohan Hedberg {
1188600a8749SAlain Michaud struct smp_irk *irk_to_return = NULL;
1189970c4e46SJohan Hedberg struct smp_irk *irk;
1190970c4e46SJohan Hedberg
1191adae20cbSJohan Hedberg rcu_read_lock();
1192adae20cbSJohan Hedberg list_for_each_entry_rcu(irk, &hdev->identity_resolving_keys, list) {
1193adae20cbSJohan Hedberg if (!bacmp(&irk->rpa, rpa)) {
1194600a8749SAlain Michaud irk_to_return = irk;
1195600a8749SAlain Michaud goto done;
1196970c4e46SJohan Hedberg }
1197adae20cbSJohan Hedberg }
1198970c4e46SJohan Hedberg
1199adae20cbSJohan Hedberg list_for_each_entry_rcu(irk, &hdev->identity_resolving_keys, list) {
1200defce9e8SJohan Hedberg if (smp_irk_matches(hdev, irk->val, rpa)) {
1201970c4e46SJohan Hedberg bacpy(&irk->rpa, rpa);
1202600a8749SAlain Michaud irk_to_return = irk;
1203600a8749SAlain Michaud goto done;
1204970c4e46SJohan Hedberg }
1205970c4e46SJohan Hedberg }
1206600a8749SAlain Michaud
1207600a8749SAlain Michaud done:
1208600a8749SAlain Michaud if (irk_to_return && hci_is_blocked_key(hdev, HCI_BLOCKED_KEY_TYPE_IRK,
1209600a8749SAlain Michaud irk_to_return->val)) {
1210600a8749SAlain Michaud bt_dev_warn_ratelimited(hdev, "Identity key blocked for %pMR",
1211600a8749SAlain Michaud &irk_to_return->bdaddr);
1212600a8749SAlain Michaud irk_to_return = NULL;
1213600a8749SAlain Michaud }
1214600a8749SAlain Michaud
1215adae20cbSJohan Hedberg rcu_read_unlock();
1216970c4e46SJohan Hedberg
1217600a8749SAlain Michaud return irk_to_return;
1218970c4e46SJohan Hedberg }
hci_find_irk_by_addr(struct hci_dev * hdev,bdaddr_t * bdaddr,u8 addr_type)1219970c4e46SJohan Hedberg
1220970c4e46SJohan Hedberg struct smp_irk *hci_find_irk_by_addr(struct hci_dev *hdev, bdaddr_t *bdaddr,
1221970c4e46SJohan Hedberg u8 addr_type)
1222970c4e46SJohan Hedberg {
1223600a8749SAlain Michaud struct smp_irk *irk_to_return = NULL;
1224970c4e46SJohan Hedberg struct smp_irk *irk;
1225970c4e46SJohan Hedberg
12266cfc9988SJohan Hedberg /* Identity Address must be public or static random */
12276cfc9988SJohan Hedberg if (addr_type == ADDR_LE_DEV_RANDOM && (bdaddr->b[5] & 0xc0) != 0xc0)
12286cfc9988SJohan Hedberg return NULL;
12296cfc9988SJohan Hedberg
1230adae20cbSJohan Hedberg rcu_read_lock();
1231adae20cbSJohan Hedberg list_for_each_entry_rcu(irk, &hdev->identity_resolving_keys, list) {
1232970c4e46SJohan Hedberg if (addr_type == irk->addr_type &&
1233adae20cbSJohan Hedberg bacmp(bdaddr, &irk->bdaddr) == 0) {
1234600a8749SAlain Michaud irk_to_return = irk;
1235600a8749SAlain Michaud goto done;
1236970c4e46SJohan Hedberg }
1237adae20cbSJohan Hedberg }
1238600a8749SAlain Michaud
1239600a8749SAlain Michaud done:
1240600a8749SAlain Michaud
1241600a8749SAlain Michaud if (irk_to_return && hci_is_blocked_key(hdev, HCI_BLOCKED_KEY_TYPE_IRK,
1242600a8749SAlain Michaud irk_to_return->val)) {
1243600a8749SAlain Michaud bt_dev_warn_ratelimited(hdev, "Identity key blocked for %pMR",
1244600a8749SAlain Michaud &irk_to_return->bdaddr);
1245600a8749SAlain Michaud irk_to_return = NULL;
1246600a8749SAlain Michaud }
1247600a8749SAlain Michaud
1248adae20cbSJohan Hedberg rcu_read_unlock();
1249970c4e46SJohan Hedberg
1250600a8749SAlain Michaud return irk_to_return;
1251970c4e46SJohan Hedberg }
hci_add_link_key(struct hci_dev * hdev,struct hci_conn * conn,bdaddr_t * bdaddr,u8 * val,u8 type,u8 pin_len,bool * persistent)1252970c4e46SJohan Hedberg
1253567fa2aaSJohan Hedberg struct link_key *hci_add_link_key(struct hci_dev *hdev, struct hci_conn *conn,
12547652ff6aSJohan Hedberg bdaddr_t *bdaddr, u8 *val, u8 type,
12557652ff6aSJohan Hedberg u8 pin_len, bool *persistent)
125655ed8ca1SJohan Hedberg {
125755ed8ca1SJohan Hedberg struct link_key *key, *old_key;
1258745c0ce3SVishal Agarwal u8 old_key_type;
125955ed8ca1SJohan Hedberg
126055ed8ca1SJohan Hedberg old_key = hci_find_link_key(hdev, bdaddr);
126155ed8ca1SJohan Hedberg if (old_key) {
126255ed8ca1SJohan Hedberg old_key_type = old_key->type;
126355ed8ca1SJohan Hedberg key = old_key;
126455ed8ca1SJohan Hedberg } else {
126512adcf3aSJohan Hedberg old_key_type = conn ? conn->key_type : 0xff;
12660a14ab41SJohan Hedberg key = kzalloc(sizeof(*key), GFP_KERNEL);
126755ed8ca1SJohan Hedberg if (!key)
1268567fa2aaSJohan Hedberg return NULL;
12690378b597SJohan Hedberg list_add_rcu(&key->list, &hdev->link_keys);
127055ed8ca1SJohan Hedberg }
127155ed8ca1SJohan Hedberg
12726ed93dc6SAndrei Emeltchenko BT_DBG("%s key for %pMR type %u", hdev->name, bdaddr, type);
127355ed8ca1SJohan Hedberg
1274d25e28abSJohan Hedberg /* Some buggy controller combinations generate a changed
1275d25e28abSJohan Hedberg * combination key for legacy pairing even when there's no
1276d25e28abSJohan Hedberg * previous key */
1277d25e28abSJohan Hedberg if (type == HCI_LK_CHANGED_COMBINATION &&
1278a8c5fb1aSGustavo Padovan (!conn || conn->remote_auth == 0xff) && old_key_type == 0xff) {
1279d25e28abSJohan Hedberg type = HCI_LK_COMBINATION;
1280655fe6ecSJohan Hedberg if (conn)
1281655fe6ecSJohan Hedberg conn->key_type = type;
1282655fe6ecSJohan Hedberg }
1283d25e28abSJohan Hedberg
128455ed8ca1SJohan Hedberg bacpy(&key->bdaddr, bdaddr);
12859b3b4460SAndrei Emeltchenko memcpy(key->val, val, HCI_LINK_KEY_SIZE);
128655ed8ca1SJohan Hedberg key->pin_len = pin_len;
128755ed8ca1SJohan Hedberg
1288b6020ba0SWaldemar Rymarkiewicz if (type == HCI_LK_CHANGED_COMBINATION)
128955ed8ca1SJohan Hedberg key->type = old_key_type;
12904748fed2SJohan Hedberg else
12914748fed2SJohan Hedberg key->type = type;
12924748fed2SJohan Hedberg
12937652ff6aSJohan Hedberg if (persistent)
12947652ff6aSJohan Hedberg *persistent = hci_persistent_key(hdev, conn, type,
12957652ff6aSJohan Hedberg old_key_type);
12964df378a1SJohan Hedberg
1297567fa2aaSJohan Hedberg return key;
129855ed8ca1SJohan Hedberg }
hci_add_ltk(struct hci_dev * hdev,bdaddr_t * bdaddr,u8 addr_type,u8 type,u8 authenticated,u8 tk[16],u8 enc_size,__le16 ediv,__le64 rand)129955ed8ca1SJohan Hedberg
1300ca9142b8SJohan Hedberg struct smp_ltk *hci_add_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr,
130135d70271SJohan Hedberg u8 addr_type, u8 type, u8 authenticated,
1302fe39c7b2SMarcel Holtmann u8 tk[16], u8 enc_size, __le16 ediv, __le64 rand)
130375d262c2SVinicius Costa Gomes {
1304c9839a11SVinicius Costa Gomes struct smp_ltk *key, *old_key;
1305e804d25dSJohan Hedberg u8 role = ltk_role(type);
130675d262c2SVinicius Costa Gomes
1307f3a73d97SJohan Hedberg old_key = hci_find_ltk(hdev, bdaddr, addr_type, role);
1308c9839a11SVinicius Costa Gomes if (old_key)
130975d262c2SVinicius Costa Gomes key = old_key;
1310c9839a11SVinicius Costa Gomes else {
13110a14ab41SJohan Hedberg key = kzalloc(sizeof(*key), GFP_KERNEL);
131275d262c2SVinicius Costa Gomes if (!key)
1313ca9142b8SJohan Hedberg return NULL;
1314970d0f1bSJohan Hedberg list_add_rcu(&key->list, &hdev->long_term_keys);
131575d262c2SVinicius Costa Gomes }
131675d262c2SVinicius Costa Gomes
131775d262c2SVinicius Costa Gomes bacpy(&key->bdaddr, bdaddr);
1318c9839a11SVinicius Costa Gomes key->bdaddr_type = addr_type;
1319c9839a11SVinicius Costa Gomes memcpy(key->val, tk, sizeof(key->val));
1320c9839a11SVinicius Costa Gomes key->authenticated = authenticated;
1321c9839a11SVinicius Costa Gomes key->ediv = ediv;
1322fe39c7b2SMarcel Holtmann key->rand = rand;
1323c9839a11SVinicius Costa Gomes key->enc_size = enc_size;
1324c9839a11SVinicius Costa Gomes key->type = type;
132575d262c2SVinicius Costa Gomes
1326ca9142b8SJohan Hedberg return key;
132775d262c2SVinicius Costa Gomes }
hci_add_irk(struct hci_dev * hdev,bdaddr_t * bdaddr,u8 addr_type,u8 val[16],bdaddr_t * rpa)132875d262c2SVinicius Costa Gomes
1329ca9142b8SJohan Hedberg struct smp_irk *hci_add_irk(struct hci_dev *hdev, bdaddr_t *bdaddr,
1330ca9142b8SJohan Hedberg u8 addr_type, u8 val[16], bdaddr_t *rpa)
1331970c4e46SJohan Hedberg {
1332970c4e46SJohan Hedberg struct smp_irk *irk;
1333970c4e46SJohan Hedberg
1334970c4e46SJohan Hedberg irk = hci_find_irk_by_addr(hdev, bdaddr, addr_type);
1335970c4e46SJohan Hedberg if (!irk) {
1336970c4e46SJohan Hedberg irk = kzalloc(sizeof(*irk), GFP_KERNEL);
1337970c4e46SJohan Hedberg if (!irk)
1338ca9142b8SJohan Hedberg return NULL;
1339970c4e46SJohan Hedberg
1340970c4e46SJohan Hedberg bacpy(&irk->bdaddr, bdaddr);
1341970c4e46SJohan Hedberg irk->addr_type = addr_type;
1342970c4e46SJohan Hedberg
1343adae20cbSJohan Hedberg list_add_rcu(&irk->list, &hdev->identity_resolving_keys);
1344970c4e46SJohan Hedberg }
1345970c4e46SJohan Hedberg
1346970c4e46SJohan Hedberg memcpy(irk->val, val, 16);
1347970c4e46SJohan Hedberg bacpy(&irk->rpa, rpa);
1348970c4e46SJohan Hedberg
1349ca9142b8SJohan Hedberg return irk;
1350970c4e46SJohan Hedberg }
hci_remove_link_key(struct hci_dev * hdev,bdaddr_t * bdaddr)1351970c4e46SJohan Hedberg
135255ed8ca1SJohan Hedberg int hci_remove_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr)
135355ed8ca1SJohan Hedberg {
135455ed8ca1SJohan Hedberg struct link_key *key;
135555ed8ca1SJohan Hedberg
135655ed8ca1SJohan Hedberg key = hci_find_link_key(hdev, bdaddr);
135755ed8ca1SJohan Hedberg if (!key)
135855ed8ca1SJohan Hedberg return -ENOENT;
135955ed8ca1SJohan Hedberg
13606ed93dc6SAndrei Emeltchenko BT_DBG("%s removing %pMR", hdev->name, bdaddr);
136155ed8ca1SJohan Hedberg
13620378b597SJohan Hedberg list_del_rcu(&key->list);
13630378b597SJohan Hedberg kfree_rcu(key, rcu);
136455ed8ca1SJohan Hedberg
136555ed8ca1SJohan Hedberg return 0;
136655ed8ca1SJohan Hedberg }
hci_remove_ltk(struct hci_dev * hdev,bdaddr_t * bdaddr,u8 bdaddr_type)136755ed8ca1SJohan Hedberg
1368e0b2b27eSJohan Hedberg int hci_remove_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 bdaddr_type)
1369b899efafSVinicius Costa Gomes {
1370c5d2b6faSLuiz Augusto von Dentz struct smp_ltk *k, *tmp;
1371c51ffa0bSJohan Hedberg int removed = 0;
1372b899efafSVinicius Costa Gomes
1373c5d2b6faSLuiz Augusto von Dentz list_for_each_entry_safe(k, tmp, &hdev->long_term_keys, list) {
1374e0b2b27eSJohan Hedberg if (bacmp(bdaddr, &k->bdaddr) || k->bdaddr_type != bdaddr_type)
1375b899efafSVinicius Costa Gomes continue;
1376b899efafSVinicius Costa Gomes
13776ed93dc6SAndrei Emeltchenko BT_DBG("%s removing %pMR", hdev->name, bdaddr);
1378b899efafSVinicius Costa Gomes
1379970d0f1bSJohan Hedberg list_del_rcu(&k->list);
1380970d0f1bSJohan Hedberg kfree_rcu(k, rcu);
1381c51ffa0bSJohan Hedberg removed++;
1382b899efafSVinicius Costa Gomes }
1383b899efafSVinicius Costa Gomes
1384c51ffa0bSJohan Hedberg return removed ? 0 : -ENOENT;
1385b899efafSVinicius Costa Gomes }
hci_remove_irk(struct hci_dev * hdev,bdaddr_t * bdaddr,u8 addr_type)1386b899efafSVinicius Costa Gomes
1387a7ec7338SJohan Hedberg void hci_remove_irk(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 addr_type)
1388a7ec7338SJohan Hedberg {
1389c5d2b6faSLuiz Augusto von Dentz struct smp_irk *k, *tmp;
1390a7ec7338SJohan Hedberg
1391c5d2b6faSLuiz Augusto von Dentz list_for_each_entry_safe(k, tmp, &hdev->identity_resolving_keys, list) {
1392a7ec7338SJohan Hedberg if (bacmp(bdaddr, &k->bdaddr) || k->addr_type != addr_type)
1393a7ec7338SJohan Hedberg continue;
1394a7ec7338SJohan Hedberg
1395a7ec7338SJohan Hedberg BT_DBG("%s removing %pMR", hdev->name, bdaddr);
1396a7ec7338SJohan Hedberg
1397adae20cbSJohan Hedberg list_del_rcu(&k->list);
1398adae20cbSJohan Hedberg kfree_rcu(k, rcu);
1399a7ec7338SJohan Hedberg }
1400a7ec7338SJohan Hedberg }
hci_bdaddr_is_paired(struct hci_dev * hdev,bdaddr_t * bdaddr,u8 type)1401a7ec7338SJohan Hedberg
140255e76b38SJohan Hedberg bool hci_bdaddr_is_paired(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type)
140355e76b38SJohan Hedberg {
140455e76b38SJohan Hedberg struct smp_ltk *k;
14054ba9faf3SJohan Hedberg struct smp_irk *irk;
140655e76b38SJohan Hedberg u8 addr_type;
140755e76b38SJohan Hedberg
140855e76b38SJohan Hedberg if (type == BDADDR_BREDR) {
140955e76b38SJohan Hedberg if (hci_find_link_key(hdev, bdaddr))
141055e76b38SJohan Hedberg return true;
141155e76b38SJohan Hedberg return false;
141255e76b38SJohan Hedberg }
141355e76b38SJohan Hedberg
141455e76b38SJohan Hedberg /* Convert to HCI addr type which struct smp_ltk uses */
141555e76b38SJohan Hedberg if (type == BDADDR_LE_PUBLIC)
141655e76b38SJohan Hedberg addr_type = ADDR_LE_DEV_PUBLIC;
141755e76b38SJohan Hedberg else
141855e76b38SJohan Hedberg addr_type = ADDR_LE_DEV_RANDOM;
141955e76b38SJohan Hedberg
14204ba9faf3SJohan Hedberg irk = hci_get_irk(hdev, bdaddr, addr_type);
14214ba9faf3SJohan Hedberg if (irk) {
14224ba9faf3SJohan Hedberg bdaddr = &irk->bdaddr;
14234ba9faf3SJohan Hedberg addr_type = irk->addr_type;
14244ba9faf3SJohan Hedberg }
14254ba9faf3SJohan Hedberg
142655e76b38SJohan Hedberg rcu_read_lock();
142755e76b38SJohan Hedberg list_for_each_entry_rcu(k, &hdev->long_term_keys, list) {
142887c8b28dSJohan Hedberg if (k->bdaddr_type == addr_type && !bacmp(bdaddr, &k->bdaddr)) {
142987c8b28dSJohan Hedberg rcu_read_unlock();
143055e76b38SJohan Hedberg return true;
143155e76b38SJohan Hedberg }
143287c8b28dSJohan Hedberg }
143355e76b38SJohan Hedberg rcu_read_unlock();
143455e76b38SJohan Hedberg
143555e76b38SJohan Hedberg return false;
143655e76b38SJohan Hedberg }
143755e76b38SJohan Hedberg
hci_cmd_timeout(struct work_struct * work)14386bd32326SVille Tervo /* HCI command timer function */
143965cc2b49SMarcel Holtmann static void hci_cmd_timeout(struct work_struct *work)
14406bd32326SVille Tervo {
144165cc2b49SMarcel Holtmann struct hci_dev *hdev = container_of(work, struct hci_dev,
144265cc2b49SMarcel Holtmann cmd_timer.work);
14436bd32326SVille Tervo
14442af7aa66SLuiz Augusto von Dentz if (hdev->req_skb) {
14452af7aa66SLuiz Augusto von Dentz u16 opcode = hci_skb_opcode(hdev->req_skb);
1446bda4f23aSAndrei Emeltchenko
14472064ee33SMarcel Holtmann bt_dev_err(hdev, "command 0x%4.4x tx timeout", opcode);
14480ce1229cSLuiz Augusto von Dentz
14490ce1229cSLuiz Augusto von Dentz hci_cmd_sync_cancel_sync(hdev, ETIMEDOUT);
1450bda4f23aSAndrei Emeltchenko } else {
14512064ee33SMarcel Holtmann bt_dev_err(hdev, "command tx timeout");
1452bda4f23aSAndrei Emeltchenko }
1453bda4f23aSAndrei Emeltchenko
1454e2bef384SRajat Jain if (hdev->cmd_timeout)
1455e2bef384SRajat Jain hdev->cmd_timeout(hdev);
1456e2bef384SRajat Jain
14576bd32326SVille Tervo atomic_set(&hdev->cmd_cnt, 1);
1458c347b765SGustavo F. Padovan queue_work(hdev->workqueue, &hdev->cmd_work);
14596bd32326SVille Tervo }
14606bd32326SVille Tervo
hci_ncmd_timeout(struct work_struct * work)1461de75cd0dSManish Mandlik /* HCI ncmd timer function */
1462de75cd0dSManish Mandlik static void hci_ncmd_timeout(struct work_struct *work)
1463de75cd0dSManish Mandlik {
1464de75cd0dSManish Mandlik struct hci_dev *hdev = container_of(work, struct hci_dev,
1465de75cd0dSManish Mandlik ncmd_timer.work);
1466de75cd0dSManish Mandlik
1467de75cd0dSManish Mandlik bt_dev_err(hdev, "Controller not accepting commands anymore: ncmd = 0");
1468de75cd0dSManish Mandlik
1469de75cd0dSManish Mandlik /* During HCI_INIT phase no events can be injected if the ncmd timer
1470de75cd0dSManish Mandlik * triggers since the procedure has its own timeout handling.
1471de75cd0dSManish Mandlik */
1472de75cd0dSManish Mandlik if (test_bit(HCI_INIT, &hdev->flags))
1473de75cd0dSManish Mandlik return;
1474de75cd0dSManish Mandlik
1475de75cd0dSManish Mandlik /* This is an irrecoverable state, inject hardware error event */
1476de75cd0dSManish Mandlik hci_reset_dev(hdev);
1477de75cd0dSManish Mandlik }
hci_find_remote_oob_data(struct hci_dev * hdev,bdaddr_t * bdaddr,u8 bdaddr_type)1478de75cd0dSManish Mandlik
14792763eda6SSzymon Janc struct oob_data *hci_find_remote_oob_data(struct hci_dev *hdev,
14806928a924SJohan Hedberg bdaddr_t *bdaddr, u8 bdaddr_type)
14812763eda6SSzymon Janc {
14822763eda6SSzymon Janc struct oob_data *data;
14832763eda6SSzymon Janc
14846928a924SJohan Hedberg list_for_each_entry(data, &hdev->remote_oob_data, list) {
14856928a924SJohan Hedberg if (bacmp(bdaddr, &data->bdaddr) != 0)
14866928a924SJohan Hedberg continue;
14876928a924SJohan Hedberg if (data->bdaddr_type != bdaddr_type)
14886928a924SJohan Hedberg continue;
14892763eda6SSzymon Janc return data;
14906928a924SJohan Hedberg }
14912763eda6SSzymon Janc
14922763eda6SSzymon Janc return NULL;
14932763eda6SSzymon Janc }
hci_remove_remote_oob_data(struct hci_dev * hdev,bdaddr_t * bdaddr,u8 bdaddr_type)14942763eda6SSzymon Janc
14956928a924SJohan Hedberg int hci_remove_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr,
14966928a924SJohan Hedberg u8 bdaddr_type)
14972763eda6SSzymon Janc {
14982763eda6SSzymon Janc struct oob_data *data;
14992763eda6SSzymon Janc
15006928a924SJohan Hedberg data = hci_find_remote_oob_data(hdev, bdaddr, bdaddr_type);
15012763eda6SSzymon Janc if (!data)
15022763eda6SSzymon Janc return -ENOENT;
15032763eda6SSzymon Janc
15046928a924SJohan Hedberg BT_DBG("%s removing %pMR (%u)", hdev->name, bdaddr, bdaddr_type);
15052763eda6SSzymon Janc
15062763eda6SSzymon Janc list_del(&data->list);
15072763eda6SSzymon Janc kfree(data);
15082763eda6SSzymon Janc
15092763eda6SSzymon Janc return 0;
15102763eda6SSzymon Janc }
hci_remote_oob_data_clear(struct hci_dev * hdev)15112763eda6SSzymon Janc
151235f7498aSJohan Hedberg void hci_remote_oob_data_clear(struct hci_dev *hdev)
15132763eda6SSzymon Janc {
15142763eda6SSzymon Janc struct oob_data *data, *n;
15152763eda6SSzymon Janc
15162763eda6SSzymon Janc list_for_each_entry_safe(data, n, &hdev->remote_oob_data, list) {
15172763eda6SSzymon Janc list_del(&data->list);
15182763eda6SSzymon Janc kfree(data);
15192763eda6SSzymon Janc }
15202763eda6SSzymon Janc }
hci_add_remote_oob_data(struct hci_dev * hdev,bdaddr_t * bdaddr,u8 bdaddr_type,u8 * hash192,u8 * rand192,u8 * hash256,u8 * rand256)15212763eda6SSzymon Janc
15220798872eSMarcel Holtmann int hci_add_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr,
15236928a924SJohan Hedberg u8 bdaddr_type, u8 *hash192, u8 *rand192,
152438da1703SJohan Hedberg u8 *hash256, u8 *rand256)
15250798872eSMarcel Holtmann {
15260798872eSMarcel Holtmann struct oob_data *data;
15270798872eSMarcel Holtmann
15286928a924SJohan Hedberg data = hci_find_remote_oob_data(hdev, bdaddr, bdaddr_type);
15290798872eSMarcel Holtmann if (!data) {
15300a14ab41SJohan Hedberg data = kmalloc(sizeof(*data), GFP_KERNEL);
15310798872eSMarcel Holtmann if (!data)
15320798872eSMarcel Holtmann return -ENOMEM;
15330798872eSMarcel Holtmann
15340798872eSMarcel Holtmann bacpy(&data->bdaddr, bdaddr);
15356928a924SJohan Hedberg data->bdaddr_type = bdaddr_type;
15360798872eSMarcel Holtmann list_add(&data->list, &hdev->remote_oob_data);
15370798872eSMarcel Holtmann }
15380798872eSMarcel Holtmann
153981328d5cSJohan Hedberg if (hash192 && rand192) {
15400798872eSMarcel Holtmann memcpy(data->hash192, hash192, sizeof(data->hash192));
154138da1703SJohan Hedberg memcpy(data->rand192, rand192, sizeof(data->rand192));
1542f7697b16SMarcel Holtmann if (hash256 && rand256)
1543f7697b16SMarcel Holtmann data->present = 0x03;
154481328d5cSJohan Hedberg } else {
154581328d5cSJohan Hedberg memset(data->hash192, 0, sizeof(data->hash192));
154681328d5cSJohan Hedberg memset(data->rand192, 0, sizeof(data->rand192));
1547f7697b16SMarcel Holtmann if (hash256 && rand256)
1548f7697b16SMarcel Holtmann data->present = 0x02;
1549f7697b16SMarcel Holtmann else
1550f7697b16SMarcel Holtmann data->present = 0x00;
155181328d5cSJohan Hedberg }
15520798872eSMarcel Holtmann
155381328d5cSJohan Hedberg if (hash256 && rand256) {
15540798872eSMarcel Holtmann memcpy(data->hash256, hash256, sizeof(data->hash256));
155538da1703SJohan Hedberg memcpy(data->rand256, rand256, sizeof(data->rand256));
155681328d5cSJohan Hedberg } else {
155781328d5cSJohan Hedberg memset(data->hash256, 0, sizeof(data->hash256));
155881328d5cSJohan Hedberg memset(data->rand256, 0, sizeof(data->rand256));
1559f7697b16SMarcel Holtmann if (hash192 && rand192)
1560f7697b16SMarcel Holtmann data->present = 0x01;
156181328d5cSJohan Hedberg }
15620798872eSMarcel Holtmann
15636ed93dc6SAndrei Emeltchenko BT_DBG("%s for %pMR", hdev->name, bdaddr);
15642763eda6SSzymon Janc
15652763eda6SSzymon Janc return 0;
15662763eda6SSzymon Janc }
15672763eda6SSzymon Janc
hci_find_adv_instance(struct hci_dev * hdev,u8 instance)1568d2609b34SFlorian Grandel /* This function requires the caller holds hdev->lock */
1569d2609b34SFlorian Grandel struct adv_info *hci_find_adv_instance(struct hci_dev *hdev, u8 instance)
1570d2609b34SFlorian Grandel {
1571d2609b34SFlorian Grandel struct adv_info *adv_instance;
1572d2609b34SFlorian Grandel
1573d2609b34SFlorian Grandel list_for_each_entry(adv_instance, &hdev->adv_instances, list) {
1574d2609b34SFlorian Grandel if (adv_instance->instance == instance)
1575d2609b34SFlorian Grandel return adv_instance;
1576d2609b34SFlorian Grandel }
1577d2609b34SFlorian Grandel
1578d2609b34SFlorian Grandel return NULL;
1579d2609b34SFlorian Grandel }
1580d2609b34SFlorian Grandel
hci_get_next_instance(struct hci_dev * hdev,u8 instance)1581d2609b34SFlorian Grandel /* This function requires the caller holds hdev->lock */
158274b93e9fSPrasanna Karthik struct adv_info *hci_get_next_instance(struct hci_dev *hdev, u8 instance)
158374b93e9fSPrasanna Karthik {
1584d2609b34SFlorian Grandel struct adv_info *cur_instance;
1585d2609b34SFlorian Grandel
1586d2609b34SFlorian Grandel cur_instance = hci_find_adv_instance(hdev, instance);
1587d2609b34SFlorian Grandel if (!cur_instance)
1588d2609b34SFlorian Grandel return NULL;
1589d2609b34SFlorian Grandel
1590d2609b34SFlorian Grandel if (cur_instance == list_last_entry(&hdev->adv_instances,
1591d2609b34SFlorian Grandel struct adv_info, list))
1592d2609b34SFlorian Grandel return list_first_entry(&hdev->adv_instances,
1593d2609b34SFlorian Grandel struct adv_info, list);
1594d2609b34SFlorian Grandel else
1595d2609b34SFlorian Grandel return list_next_entry(cur_instance, list);
1596d2609b34SFlorian Grandel }
1597d2609b34SFlorian Grandel
hci_remove_adv_instance(struct hci_dev * hdev,u8 instance)1598d2609b34SFlorian Grandel /* This function requires the caller holds hdev->lock */
1599d2609b34SFlorian Grandel int hci_remove_adv_instance(struct hci_dev *hdev, u8 instance)
1600d2609b34SFlorian Grandel {
1601d2609b34SFlorian Grandel struct adv_info *adv_instance;
1602d2609b34SFlorian Grandel
1603d2609b34SFlorian Grandel adv_instance = hci_find_adv_instance(hdev, instance);
1604d2609b34SFlorian Grandel if (!adv_instance)
1605d2609b34SFlorian Grandel return -ENOENT;
1606d2609b34SFlorian Grandel
1607d2609b34SFlorian Grandel BT_DBG("%s removing %dMR", hdev->name, instance);
1608d2609b34SFlorian Grandel
1609cab054abSJohan Hedberg if (hdev->cur_adv_instance == instance) {
1610cab054abSJohan Hedberg if (hdev->adv_instance_timeout) {
16115d900e46SFlorian Grandel cancel_delayed_work(&hdev->adv_instance_expire);
16125d900e46SFlorian Grandel hdev->adv_instance_timeout = 0;
16135d900e46SFlorian Grandel }
1614cab054abSJohan Hedberg hdev->cur_adv_instance = 0x00;
1615cab054abSJohan Hedberg }
16165d900e46SFlorian Grandel
1617a73c046aSJaganath Kanakkassery cancel_delayed_work_sync(&adv_instance->rpa_expired_cb);
1618a73c046aSJaganath Kanakkassery
1619d2609b34SFlorian Grandel list_del(&adv_instance->list);
1620d2609b34SFlorian Grandel kfree(adv_instance);
1621d2609b34SFlorian Grandel
1622d2609b34SFlorian Grandel hdev->adv_instance_cnt--;
1623d2609b34SFlorian Grandel
1624d2609b34SFlorian Grandel return 0;
1625d2609b34SFlorian Grandel }
hci_adv_instances_set_rpa_expired(struct hci_dev * hdev,bool rpa_expired)1626d2609b34SFlorian Grandel
1627a73c046aSJaganath Kanakkassery void hci_adv_instances_set_rpa_expired(struct hci_dev *hdev, bool rpa_expired)
1628a73c046aSJaganath Kanakkassery {
1629a73c046aSJaganath Kanakkassery struct adv_info *adv_instance, *n;
1630a73c046aSJaganath Kanakkassery
1631a73c046aSJaganath Kanakkassery list_for_each_entry_safe(adv_instance, n, &hdev->adv_instances, list)
1632a73c046aSJaganath Kanakkassery adv_instance->rpa_expired = rpa_expired;
1633a73c046aSJaganath Kanakkassery }
1634a73c046aSJaganath Kanakkassery
hci_adv_instances_clear(struct hci_dev * hdev)1635d2609b34SFlorian Grandel /* This function requires the caller holds hdev->lock */
1636d2609b34SFlorian Grandel void hci_adv_instances_clear(struct hci_dev *hdev)
1637d2609b34SFlorian Grandel {
1638d2609b34SFlorian Grandel struct adv_info *adv_instance, *n;
1639d2609b34SFlorian Grandel
16405d900e46SFlorian Grandel if (hdev->adv_instance_timeout) {
16415d900e46SFlorian Grandel cancel_delayed_work(&hdev->adv_instance_expire);
16425d900e46SFlorian Grandel hdev->adv_instance_timeout = 0;
16435d900e46SFlorian Grandel }
16445d900e46SFlorian Grandel
1645d2609b34SFlorian Grandel list_for_each_entry_safe(adv_instance, n, &hdev->adv_instances, list) {
1646a73c046aSJaganath Kanakkassery cancel_delayed_work_sync(&adv_instance->rpa_expired_cb);
1647d2609b34SFlorian Grandel list_del(&adv_instance->list);
1648d2609b34SFlorian Grandel kfree(adv_instance);
1649d2609b34SFlorian Grandel }
1650d2609b34SFlorian Grandel
1651d2609b34SFlorian Grandel hdev->adv_instance_cnt = 0;
1652cab054abSJohan Hedberg hdev->cur_adv_instance = 0x00;
1653d2609b34SFlorian Grandel }
adv_instance_rpa_expired(struct work_struct * work)1654d2609b34SFlorian Grandel
1655a73c046aSJaganath Kanakkassery static void adv_instance_rpa_expired(struct work_struct *work)
1656a73c046aSJaganath Kanakkassery {
1657a73c046aSJaganath Kanakkassery struct adv_info *adv_instance = container_of(work, struct adv_info,
1658a73c046aSJaganath Kanakkassery rpa_expired_cb.work);
1659a73c046aSJaganath Kanakkassery
1660a73c046aSJaganath Kanakkassery BT_DBG("");
1661a73c046aSJaganath Kanakkassery
1662a73c046aSJaganath Kanakkassery adv_instance->rpa_expired = true;
1663a73c046aSJaganath Kanakkassery }
1664a73c046aSJaganath Kanakkassery
hci_add_adv_instance(struct hci_dev * hdev,u8 instance,u32 flags,u16 adv_data_len,u8 * adv_data,u16 scan_rsp_len,u8 * scan_rsp_data,u16 timeout,u16 duration,s8 tx_power,u32 min_interval,u32 max_interval,u8 mesh_handle)1665d2609b34SFlorian Grandel /* This function requires the caller holds hdev->lock */
1666eca0ae4aSLuiz Augusto von Dentz struct adv_info *hci_add_adv_instance(struct hci_dev *hdev, u8 instance,
1667eca0ae4aSLuiz Augusto von Dentz u32 flags, u16 adv_data_len, u8 *adv_data,
1668d2609b34SFlorian Grandel u16 scan_rsp_len, u8 *scan_rsp_data,
16699bf9f4b6SDaniel Winkler u16 timeout, u16 duration, s8 tx_power,
1670b338d917SBrian Gix u32 min_interval, u32 max_interval,
1671b338d917SBrian Gix u8 mesh_handle)
1672d2609b34SFlorian Grandel {
1673eca0ae4aSLuiz Augusto von Dentz struct adv_info *adv;
1674d2609b34SFlorian Grandel
1675eca0ae4aSLuiz Augusto von Dentz adv = hci_find_adv_instance(hdev, instance);
1676eca0ae4aSLuiz Augusto von Dentz if (adv) {
1677eca0ae4aSLuiz Augusto von Dentz memset(adv->adv_data, 0, sizeof(adv->adv_data));
1678eca0ae4aSLuiz Augusto von Dentz memset(adv->scan_rsp_data, 0, sizeof(adv->scan_rsp_data));
1679eca0ae4aSLuiz Augusto von Dentz memset(adv->per_adv_data, 0, sizeof(adv->per_adv_data));
1680d2609b34SFlorian Grandel } else {
16811d0fac2cSLuiz Augusto von Dentz if (hdev->adv_instance_cnt >= hdev->le_num_of_adv_sets ||
1682b338d917SBrian Gix instance < 1 || instance > hdev->le_num_of_adv_sets + 1)
1683eca0ae4aSLuiz Augusto von Dentz return ERR_PTR(-EOVERFLOW);
1684d2609b34SFlorian Grandel
1685eca0ae4aSLuiz Augusto von Dentz adv = kzalloc(sizeof(*adv), GFP_KERNEL);
1686eca0ae4aSLuiz Augusto von Dentz if (!adv)
1687eca0ae4aSLuiz Augusto von Dentz return ERR_PTR(-ENOMEM);
1688d2609b34SFlorian Grandel
1689eca0ae4aSLuiz Augusto von Dentz adv->pending = true;
1690eca0ae4aSLuiz Augusto von Dentz adv->instance = instance;
1691eca0ae4aSLuiz Augusto von Dentz list_add(&adv->list, &hdev->adv_instances);
1692d2609b34SFlorian Grandel hdev->adv_instance_cnt++;
1693d2609b34SFlorian Grandel }
1694d2609b34SFlorian Grandel
1695eca0ae4aSLuiz Augusto von Dentz adv->flags = flags;
1696eca0ae4aSLuiz Augusto von Dentz adv->min_interval = min_interval;
1697eca0ae4aSLuiz Augusto von Dentz adv->max_interval = max_interval;
1698eca0ae4aSLuiz Augusto von Dentz adv->tx_power = tx_power;
1699b338d917SBrian Gix /* Defining a mesh_handle changes the timing units to ms,
1700b338d917SBrian Gix * rather than seconds, and ties the instance to the requested
1701b338d917SBrian Gix * mesh_tx queue.
1702b338d917SBrian Gix */
1703b338d917SBrian Gix adv->mesh = mesh_handle;
1704d2609b34SFlorian Grandel
170534a718bcSLuiz Augusto von Dentz hci_set_adv_instance_data(hdev, instance, adv_data_len, adv_data,
170634a718bcSLuiz Augusto von Dentz scan_rsp_len, scan_rsp_data);
1707d2609b34SFlorian Grandel
1708eca0ae4aSLuiz Augusto von Dentz adv->timeout = timeout;
1709eca0ae4aSLuiz Augusto von Dentz adv->remaining_time = timeout;
1710d2609b34SFlorian Grandel
1711d2609b34SFlorian Grandel if (duration == 0)
1712eca0ae4aSLuiz Augusto von Dentz adv->duration = hdev->def_multi_adv_rotation_duration;
1713d2609b34SFlorian Grandel else
1714eca0ae4aSLuiz Augusto von Dentz adv->duration = duration;
1715d2609b34SFlorian Grandel
1716eca0ae4aSLuiz Augusto von Dentz INIT_DELAYED_WORK(&adv->rpa_expired_cb, adv_instance_rpa_expired);
1717a73c046aSJaganath Kanakkassery
1718d2609b34SFlorian Grandel BT_DBG("%s for %dMR", hdev->name, instance);
1719d2609b34SFlorian Grandel
1720eca0ae4aSLuiz Augusto von Dentz return adv;
1721eca0ae4aSLuiz Augusto von Dentz }
1722eca0ae4aSLuiz Augusto von Dentz
hci_add_per_instance(struct hci_dev * hdev,u8 instance,u32 flags,u8 data_len,u8 * data,u32 min_interval,u32 max_interval)1723eca0ae4aSLuiz Augusto von Dentz /* This function requires the caller holds hdev->lock */
1724eca0ae4aSLuiz Augusto von Dentz struct adv_info *hci_add_per_instance(struct hci_dev *hdev, u8 instance,
1725eca0ae4aSLuiz Augusto von Dentz u32 flags, u8 data_len, u8 *data,
1726eca0ae4aSLuiz Augusto von Dentz u32 min_interval, u32 max_interval)
1727eca0ae4aSLuiz Augusto von Dentz {
1728eca0ae4aSLuiz Augusto von Dentz struct adv_info *adv;
1729eca0ae4aSLuiz Augusto von Dentz
1730eca0ae4aSLuiz Augusto von Dentz adv = hci_add_adv_instance(hdev, instance, flags, 0, NULL, 0, NULL,
1731eca0ae4aSLuiz Augusto von Dentz 0, 0, HCI_ADV_TX_POWER_NO_PREFERENCE,
1732b338d917SBrian Gix min_interval, max_interval, 0);
1733eca0ae4aSLuiz Augusto von Dentz if (IS_ERR(adv))
1734eca0ae4aSLuiz Augusto von Dentz return adv;
1735eca0ae4aSLuiz Augusto von Dentz
1736eca0ae4aSLuiz Augusto von Dentz adv->periodic = true;
1737eca0ae4aSLuiz Augusto von Dentz adv->per_adv_data_len = data_len;
1738eca0ae4aSLuiz Augusto von Dentz
1739eca0ae4aSLuiz Augusto von Dentz if (data)
1740eca0ae4aSLuiz Augusto von Dentz memcpy(adv->per_adv_data, data, data_len);
1741eca0ae4aSLuiz Augusto von Dentz
1742eca0ae4aSLuiz Augusto von Dentz return adv;
1743d2609b34SFlorian Grandel }
1744d2609b34SFlorian Grandel
hci_set_adv_instance_data(struct hci_dev * hdev,u8 instance,u16 adv_data_len,u8 * adv_data,u16 scan_rsp_len,u8 * scan_rsp_data)1745e5e1e7fdSMiao-chen Chou /* This function requires the caller holds hdev->lock */
174631aab5c2SDaniel Winkler int hci_set_adv_instance_data(struct hci_dev *hdev, u8 instance,
174731aab5c2SDaniel Winkler u16 adv_data_len, u8 *adv_data,
174831aab5c2SDaniel Winkler u16 scan_rsp_len, u8 *scan_rsp_data)
174931aab5c2SDaniel Winkler {
175034a718bcSLuiz Augusto von Dentz struct adv_info *adv;
175131aab5c2SDaniel Winkler
175234a718bcSLuiz Augusto von Dentz adv = hci_find_adv_instance(hdev, instance);
175331aab5c2SDaniel Winkler
175431aab5c2SDaniel Winkler /* If advertisement doesn't exist, we can't modify its data */
175534a718bcSLuiz Augusto von Dentz if (!adv)
175631aab5c2SDaniel Winkler return -ENOENT;
175731aab5c2SDaniel Winkler
175834a718bcSLuiz Augusto von Dentz if (adv_data_len && ADV_DATA_CMP(adv, adv_data, adv_data_len)) {
175934a718bcSLuiz Augusto von Dentz memset(adv->adv_data, 0, sizeof(adv->adv_data));
176034a718bcSLuiz Augusto von Dentz memcpy(adv->adv_data, adv_data, adv_data_len);
176134a718bcSLuiz Augusto von Dentz adv->adv_data_len = adv_data_len;
176234a718bcSLuiz Augusto von Dentz adv->adv_data_changed = true;
176331aab5c2SDaniel Winkler }
176431aab5c2SDaniel Winkler
176534a718bcSLuiz Augusto von Dentz if (scan_rsp_len && SCAN_RSP_CMP(adv, scan_rsp_data, scan_rsp_len)) {
176634a718bcSLuiz Augusto von Dentz memset(adv->scan_rsp_data, 0, sizeof(adv->scan_rsp_data));
176734a718bcSLuiz Augusto von Dentz memcpy(adv->scan_rsp_data, scan_rsp_data, scan_rsp_len);
176834a718bcSLuiz Augusto von Dentz adv->scan_rsp_len = scan_rsp_len;
176934a718bcSLuiz Augusto von Dentz adv->scan_rsp_changed = true;
177031aab5c2SDaniel Winkler }
177131aab5c2SDaniel Winkler
177234a718bcSLuiz Augusto von Dentz /* Mark as changed if there are flags which would affect it */
177334a718bcSLuiz Augusto von Dentz if (((adv->flags & MGMT_ADV_FLAG_APPEARANCE) && hdev->appearance) ||
177434a718bcSLuiz Augusto von Dentz adv->flags & MGMT_ADV_FLAG_LOCAL_NAME)
177534a718bcSLuiz Augusto von Dentz adv->scan_rsp_changed = true;
177634a718bcSLuiz Augusto von Dentz
177731aab5c2SDaniel Winkler return 0;
177831aab5c2SDaniel Winkler }
177931aab5c2SDaniel Winkler
hci_adv_instance_flags(struct hci_dev * hdev,u8 instance)178031aab5c2SDaniel Winkler /* This function requires the caller holds hdev->lock */
178101ce70b0SLuiz Augusto von Dentz u32 hci_adv_instance_flags(struct hci_dev *hdev, u8 instance)
178201ce70b0SLuiz Augusto von Dentz {
178301ce70b0SLuiz Augusto von Dentz u32 flags;
178401ce70b0SLuiz Augusto von Dentz struct adv_info *adv;
178501ce70b0SLuiz Augusto von Dentz
178601ce70b0SLuiz Augusto von Dentz if (instance == 0x00) {
178701ce70b0SLuiz Augusto von Dentz /* Instance 0 always manages the "Tx Power" and "Flags"
178801ce70b0SLuiz Augusto von Dentz * fields
178901ce70b0SLuiz Augusto von Dentz */
179001ce70b0SLuiz Augusto von Dentz flags = MGMT_ADV_FLAG_TX_POWER | MGMT_ADV_FLAG_MANAGED_FLAGS;
179101ce70b0SLuiz Augusto von Dentz
179201ce70b0SLuiz Augusto von Dentz /* For instance 0, the HCI_ADVERTISING_CONNECTABLE setting
179301ce70b0SLuiz Augusto von Dentz * corresponds to the "connectable" instance flag.
179401ce70b0SLuiz Augusto von Dentz */
179501ce70b0SLuiz Augusto von Dentz if (hci_dev_test_flag(hdev, HCI_ADVERTISING_CONNECTABLE))
179601ce70b0SLuiz Augusto von Dentz flags |= MGMT_ADV_FLAG_CONNECTABLE;
179701ce70b0SLuiz Augusto von Dentz
179801ce70b0SLuiz Augusto von Dentz if (hci_dev_test_flag(hdev, HCI_LIMITED_DISCOVERABLE))
179901ce70b0SLuiz Augusto von Dentz flags |= MGMT_ADV_FLAG_LIMITED_DISCOV;
180001ce70b0SLuiz Augusto von Dentz else if (hci_dev_test_flag(hdev, HCI_DISCOVERABLE))
180101ce70b0SLuiz Augusto von Dentz flags |= MGMT_ADV_FLAG_DISCOV;
180201ce70b0SLuiz Augusto von Dentz
180301ce70b0SLuiz Augusto von Dentz return flags;
180401ce70b0SLuiz Augusto von Dentz }
180501ce70b0SLuiz Augusto von Dentz
180601ce70b0SLuiz Augusto von Dentz adv = hci_find_adv_instance(hdev, instance);
180701ce70b0SLuiz Augusto von Dentz
180801ce70b0SLuiz Augusto von Dentz /* Return 0 when we got an invalid instance identifier. */
180901ce70b0SLuiz Augusto von Dentz if (!adv)
181001ce70b0SLuiz Augusto von Dentz return 0;
181101ce70b0SLuiz Augusto von Dentz
181201ce70b0SLuiz Augusto von Dentz return adv->flags;
181301ce70b0SLuiz Augusto von Dentz }
hci_adv_instance_is_scannable(struct hci_dev * hdev,u8 instance)181401ce70b0SLuiz Augusto von Dentz
181501ce70b0SLuiz Augusto von Dentz bool hci_adv_instance_is_scannable(struct hci_dev *hdev, u8 instance)
181601ce70b0SLuiz Augusto von Dentz {
181701ce70b0SLuiz Augusto von Dentz struct adv_info *adv;
181801ce70b0SLuiz Augusto von Dentz
181901ce70b0SLuiz Augusto von Dentz /* Instance 0x00 always set local name */
182001ce70b0SLuiz Augusto von Dentz if (instance == 0x00)
182101ce70b0SLuiz Augusto von Dentz return true;
182201ce70b0SLuiz Augusto von Dentz
182301ce70b0SLuiz Augusto von Dentz adv = hci_find_adv_instance(hdev, instance);
182401ce70b0SLuiz Augusto von Dentz if (!adv)
182501ce70b0SLuiz Augusto von Dentz return false;
182601ce70b0SLuiz Augusto von Dentz
182701ce70b0SLuiz Augusto von Dentz if (adv->flags & MGMT_ADV_FLAG_APPEARANCE ||
182801ce70b0SLuiz Augusto von Dentz adv->flags & MGMT_ADV_FLAG_LOCAL_NAME)
182901ce70b0SLuiz Augusto von Dentz return true;
183001ce70b0SLuiz Augusto von Dentz
183101ce70b0SLuiz Augusto von Dentz return adv->scan_rsp_len ? true : false;
183201ce70b0SLuiz Augusto von Dentz }
183301ce70b0SLuiz Augusto von Dentz
hci_adv_monitors_clear(struct hci_dev * hdev)183401ce70b0SLuiz Augusto von Dentz /* This function requires the caller holds hdev->lock */
1835e5e1e7fdSMiao-chen Chou void hci_adv_monitors_clear(struct hci_dev *hdev)
1836e5e1e7fdSMiao-chen Chou {
1837b139553dSMiao-chen Chou struct adv_monitor *monitor;
1838b139553dSMiao-chen Chou int handle;
1839b139553dSMiao-chen Chou
1840b139553dSMiao-chen Chou idr_for_each_entry(&hdev->adv_monitors_idr, monitor, handle)
184166bd095aSArchie Pusaka hci_free_adv_monitor(hdev, monitor);
1842b139553dSMiao-chen Chou
1843e5e1e7fdSMiao-chen Chou idr_destroy(&hdev->adv_monitors_idr);
1844e5e1e7fdSMiao-chen Chou }
1845e5e1e7fdSMiao-chen Chou
184666bd095aSArchie Pusaka /* Frees the monitor structure and do some bookkeepings.
184766bd095aSArchie Pusaka * This function requires the caller holds hdev->lock.
hci_free_adv_monitor(struct hci_dev * hdev,struct adv_monitor * monitor)184866bd095aSArchie Pusaka */
184966bd095aSArchie Pusaka void hci_free_adv_monitor(struct hci_dev *hdev, struct adv_monitor *monitor)
1850b139553dSMiao-chen Chou {
1851b139553dSMiao-chen Chou struct adv_pattern *pattern;
1852b139553dSMiao-chen Chou struct adv_pattern *tmp;
1853b139553dSMiao-chen Chou
1854b139553dSMiao-chen Chou if (!monitor)
1855b139553dSMiao-chen Chou return;
1856b139553dSMiao-chen Chou
185766bd095aSArchie Pusaka list_for_each_entry_safe(pattern, tmp, &monitor->patterns, list) {
185866bd095aSArchie Pusaka list_del(&pattern->list);
1859b139553dSMiao-chen Chou kfree(pattern);
186066bd095aSArchie Pusaka }
186166bd095aSArchie Pusaka
186266bd095aSArchie Pusaka if (monitor->handle)
186366bd095aSArchie Pusaka idr_remove(&hdev->adv_monitors_idr, monitor->handle);
186466bd095aSArchie Pusaka
186566bd095aSArchie Pusaka if (monitor->state != ADV_MONITOR_STATE_NOT_REGISTERED) {
186666bd095aSArchie Pusaka hdev->adv_monitors_cnt--;
186766bd095aSArchie Pusaka mgmt_adv_monitor_removed(hdev, monitor->handle);
186866bd095aSArchie Pusaka }
1869b139553dSMiao-chen Chou
1870b139553dSMiao-chen Chou kfree(monitor);
1871b139553dSMiao-chen Chou }
1872b139553dSMiao-chen Chou
1873a2a4dedfSArchie Pusaka /* Assigns handle to a monitor, and if offloading is supported and power is on,
1874a2a4dedfSArchie Pusaka * also attempts to forward the request to the controller.
1875b747a836SManish Mandlik * This function requires the caller holds hci_req_sync_lock.
hci_add_adv_monitor(struct hci_dev * hdev,struct adv_monitor * monitor)1876a2a4dedfSArchie Pusaka */
1877b747a836SManish Mandlik int hci_add_adv_monitor(struct hci_dev *hdev, struct adv_monitor *monitor)
1878b139553dSMiao-chen Chou {
1879b139553dSMiao-chen Chou int min, max, handle;
1880b747a836SManish Mandlik int status = 0;
1881b139553dSMiao-chen Chou
1882b747a836SManish Mandlik if (!monitor)
1883b747a836SManish Mandlik return -EINVAL;
1884a2a4dedfSArchie Pusaka
1885b747a836SManish Mandlik hci_dev_lock(hdev);
1886b139553dSMiao-chen Chou
1887b139553dSMiao-chen Chou min = HCI_MIN_ADV_MONITOR_HANDLE;
1888b139553dSMiao-chen Chou max = HCI_MIN_ADV_MONITOR_HANDLE + HCI_MAX_ADV_MONITOR_NUM_HANDLES;
1889b139553dSMiao-chen Chou handle = idr_alloc(&hdev->adv_monitors_idr, monitor, min, max,
1890b139553dSMiao-chen Chou GFP_KERNEL);
1891b747a836SManish Mandlik
1892b747a836SManish Mandlik hci_dev_unlock(hdev);
1893b747a836SManish Mandlik
1894b747a836SManish Mandlik if (handle < 0)
1895b747a836SManish Mandlik return handle;
1896b139553dSMiao-chen Chou
1897b139553dSMiao-chen Chou monitor->handle = handle;
18988208f5a9SMiao-chen Chou
1899a2a4dedfSArchie Pusaka if (!hdev_is_powered(hdev))
1900b747a836SManish Mandlik return status;
19018208f5a9SMiao-chen Chou
1902a2a4dedfSArchie Pusaka switch (hci_get_adv_monitor_offload_ext(hdev)) {
1903a2a4dedfSArchie Pusaka case HCI_ADV_MONITOR_EXT_NONE:
19046f55eea1SDouglas Anderson bt_dev_dbg(hdev, "add monitor %d status %d",
1905b747a836SManish Mandlik monitor->handle, status);
1906a2a4dedfSArchie Pusaka /* Message was not forwarded to controller - not an error */
1907b747a836SManish Mandlik break;
1908b747a836SManish Mandlik
1909a2a4dedfSArchie Pusaka case HCI_ADV_MONITOR_EXT_MSFT:
1910b747a836SManish Mandlik status = msft_add_monitor_pattern(hdev, monitor);
19116f55eea1SDouglas Anderson bt_dev_dbg(hdev, "add monitor %d msft status %d",
1912a2bcd2b6SManish Mandlik handle, status);
1913a2a4dedfSArchie Pusaka break;
1914a2a4dedfSArchie Pusaka }
1915a2a4dedfSArchie Pusaka
1916b747a836SManish Mandlik return status;
1917b139553dSMiao-chen Chou }
1918b139553dSMiao-chen Chou
191966bd095aSArchie Pusaka /* Attempts to tell the controller and free the monitor. If somehow the
192066bd095aSArchie Pusaka * controller doesn't have a corresponding handle, remove anyway.
19217cf5c297SManish Mandlik * This function requires the caller holds hci_req_sync_lock.
hci_remove_adv_monitor(struct hci_dev * hdev,struct adv_monitor * monitor)192266bd095aSArchie Pusaka */
19237cf5c297SManish Mandlik static int hci_remove_adv_monitor(struct hci_dev *hdev,
19247cf5c297SManish Mandlik struct adv_monitor *monitor)
1925bd2fbc6cSMiao-chen Chou {
19267cf5c297SManish Mandlik int status = 0;
1927de6dfcefSDouglas Anderson int handle;
1928bd2fbc6cSMiao-chen Chou
192966bd095aSArchie Pusaka switch (hci_get_adv_monitor_offload_ext(hdev)) {
193066bd095aSArchie Pusaka case HCI_ADV_MONITOR_EXT_NONE: /* also goes here when powered off */
19316f55eea1SDouglas Anderson bt_dev_dbg(hdev, "remove monitor %d status %d",
19327cf5c297SManish Mandlik monitor->handle, status);
193366bd095aSArchie Pusaka goto free_monitor;
19347cf5c297SManish Mandlik
193566bd095aSArchie Pusaka case HCI_ADV_MONITOR_EXT_MSFT:
1936de6dfcefSDouglas Anderson handle = monitor->handle;
19377cf5c297SManish Mandlik status = msft_remove_monitor(hdev, monitor);
19386f55eea1SDouglas Anderson bt_dev_dbg(hdev, "remove monitor %d msft status %d",
19396f55eea1SDouglas Anderson handle, status);
194066bd095aSArchie Pusaka break;
1941bd2fbc6cSMiao-chen Chou }
1942bd2fbc6cSMiao-chen Chou
194366bd095aSArchie Pusaka /* In case no matching handle registered, just free the monitor */
19447cf5c297SManish Mandlik if (status == -ENOENT)
194566bd095aSArchie Pusaka goto free_monitor;
1946bd2fbc6cSMiao-chen Chou
19477cf5c297SManish Mandlik return status;
1948bd2fbc6cSMiao-chen Chou
194966bd095aSArchie Pusaka free_monitor:
19507cf5c297SManish Mandlik if (status == -ENOENT)
195166bd095aSArchie Pusaka bt_dev_warn(hdev, "Removing monitor with no matching handle %d",
195266bd095aSArchie Pusaka monitor->handle);
195366bd095aSArchie Pusaka hci_free_adv_monitor(hdev, monitor);
195466bd095aSArchie Pusaka
19557cf5c297SManish Mandlik return status;
1956bd2fbc6cSMiao-chen Chou }
1957bd2fbc6cSMiao-chen Chou
hci_remove_single_adv_monitor(struct hci_dev * hdev,u16 handle)19587cf5c297SManish Mandlik /* This function requires the caller holds hci_req_sync_lock */
19597cf5c297SManish Mandlik int hci_remove_single_adv_monitor(struct hci_dev *hdev, u16 handle)
196066bd095aSArchie Pusaka {
196166bd095aSArchie Pusaka struct adv_monitor *monitor = idr_find(&hdev->adv_monitors_idr, handle);
196266bd095aSArchie Pusaka
19637cf5c297SManish Mandlik if (!monitor)
19647cf5c297SManish Mandlik return -EINVAL;
19657cf5c297SManish Mandlik
19667cf5c297SManish Mandlik return hci_remove_adv_monitor(hdev, monitor);
196766bd095aSArchie Pusaka }
196866bd095aSArchie Pusaka
hci_remove_all_adv_monitor(struct hci_dev * hdev)19697cf5c297SManish Mandlik /* This function requires the caller holds hci_req_sync_lock */
19707cf5c297SManish Mandlik int hci_remove_all_adv_monitor(struct hci_dev *hdev)
197166bd095aSArchie Pusaka {
197266bd095aSArchie Pusaka struct adv_monitor *monitor;
197366bd095aSArchie Pusaka int idr_next_id = 0;
19747cf5c297SManish Mandlik int status = 0;
197566bd095aSArchie Pusaka
19767cf5c297SManish Mandlik while (1) {
197766bd095aSArchie Pusaka monitor = idr_get_next(&hdev->adv_monitors_idr, &idr_next_id);
197866bd095aSArchie Pusaka if (!monitor)
197966bd095aSArchie Pusaka break;
198066bd095aSArchie Pusaka
19817cf5c297SManish Mandlik status = hci_remove_adv_monitor(hdev, monitor);
19827cf5c297SManish Mandlik if (status)
19837cf5c297SManish Mandlik return status;
198466bd095aSArchie Pusaka
19857cf5c297SManish Mandlik idr_next_id++;
198666bd095aSArchie Pusaka }
198766bd095aSArchie Pusaka
19887cf5c297SManish Mandlik return status;
1989bd2fbc6cSMiao-chen Chou }
1990bd2fbc6cSMiao-chen Chou
hci_is_adv_monitoring(struct hci_dev * hdev)19918208f5a9SMiao-chen Chou /* This function requires the caller holds hdev->lock */
19928208f5a9SMiao-chen Chou bool hci_is_adv_monitoring(struct hci_dev *hdev)
19938208f5a9SMiao-chen Chou {
19948208f5a9SMiao-chen Chou return !idr_is_empty(&hdev->adv_monitors_idr);
19958208f5a9SMiao-chen Chou }
hci_get_adv_monitor_offload_ext(struct hci_dev * hdev)19968208f5a9SMiao-chen Chou
1997a2a4dedfSArchie Pusaka int hci_get_adv_monitor_offload_ext(struct hci_dev *hdev)
1998a2a4dedfSArchie Pusaka {
1999a2a4dedfSArchie Pusaka if (msft_monitor_supported(hdev))
2000a2a4dedfSArchie Pusaka return HCI_ADV_MONITOR_EXT_MSFT;
2001a2a4dedfSArchie Pusaka
2002a2a4dedfSArchie Pusaka return HCI_ADV_MONITOR_EXT_NONE;
2003a2a4dedfSArchie Pusaka }
hci_bdaddr_list_lookup(struct list_head * bdaddr_list,bdaddr_t * bdaddr,u8 type)2004a2a4dedfSArchie Pusaka
2005dcc36c16SJohan Hedberg struct bdaddr_list *hci_bdaddr_list_lookup(struct list_head *bdaddr_list,
2006b9ee0a78SMarcel Holtmann bdaddr_t *bdaddr, u8 type)
2007b2a66aadSAntti Julku {
2008b2a66aadSAntti Julku struct bdaddr_list *b;
2009b2a66aadSAntti Julku
2010dcc36c16SJohan Hedberg list_for_each_entry(b, bdaddr_list, list) {
2011b9ee0a78SMarcel Holtmann if (!bacmp(&b->bdaddr, bdaddr) && b->bdaddr_type == type)
2012b2a66aadSAntti Julku return b;
2013b9ee0a78SMarcel Holtmann }
2014b2a66aadSAntti Julku
2015b2a66aadSAntti Julku return NULL;
2016b2a66aadSAntti Julku }
hci_bdaddr_list_lookup_with_irk(struct list_head * bdaddr_list,bdaddr_t * bdaddr,u8 type)2017b2a66aadSAntti Julku
2018b950aa88SAnkit Navik struct bdaddr_list_with_irk *hci_bdaddr_list_lookup_with_irk(
2019b950aa88SAnkit Navik struct list_head *bdaddr_list, bdaddr_t *bdaddr,
2020b950aa88SAnkit Navik u8 type)
2021b950aa88SAnkit Navik {
2022b950aa88SAnkit Navik struct bdaddr_list_with_irk *b;
2023b950aa88SAnkit Navik
2024b950aa88SAnkit Navik list_for_each_entry(b, bdaddr_list, list) {
2025b950aa88SAnkit Navik if (!bacmp(&b->bdaddr, bdaddr) && b->bdaddr_type == type)
2026b950aa88SAnkit Navik return b;
2027b950aa88SAnkit Navik }
2028b950aa88SAnkit Navik
2029b950aa88SAnkit Navik return NULL;
2030b950aa88SAnkit Navik }
2031b950aa88SAnkit Navik
hci_bdaddr_list_lookup_with_flags(struct list_head * bdaddr_list,bdaddr_t * bdaddr,u8 type)20328baaa403SAbhishek Pandit-Subedi struct bdaddr_list_with_flags *
20338baaa403SAbhishek Pandit-Subedi hci_bdaddr_list_lookup_with_flags(struct list_head *bdaddr_list,
20348baaa403SAbhishek Pandit-Subedi bdaddr_t *bdaddr, u8 type)
20358baaa403SAbhishek Pandit-Subedi {
20368baaa403SAbhishek Pandit-Subedi struct bdaddr_list_with_flags *b;
20378baaa403SAbhishek Pandit-Subedi
20388baaa403SAbhishek Pandit-Subedi list_for_each_entry(b, bdaddr_list, list) {
20398baaa403SAbhishek Pandit-Subedi if (!bacmp(&b->bdaddr, bdaddr) && b->bdaddr_type == type)
20408baaa403SAbhishek Pandit-Subedi return b;
20418baaa403SAbhishek Pandit-Subedi }
20428baaa403SAbhishek Pandit-Subedi
20438baaa403SAbhishek Pandit-Subedi return NULL;
20448baaa403SAbhishek Pandit-Subedi }
hci_bdaddr_list_clear(struct list_head * bdaddr_list)20458baaa403SAbhishek Pandit-Subedi
2046dcc36c16SJohan Hedberg void hci_bdaddr_list_clear(struct list_head *bdaddr_list)
2047b2a66aadSAntti Julku {
20487eb7404fSGeliang Tang struct bdaddr_list *b, *n;
2049b2a66aadSAntti Julku
20507eb7404fSGeliang Tang list_for_each_entry_safe(b, n, bdaddr_list, list) {
20517eb7404fSGeliang Tang list_del(&b->list);
2052b2a66aadSAntti Julku kfree(b);
2053b2a66aadSAntti Julku }
2054b2a66aadSAntti Julku }
hci_bdaddr_list_add(struct list_head * list,bdaddr_t * bdaddr,u8 type)2055b2a66aadSAntti Julku
2056dcc36c16SJohan Hedberg int hci_bdaddr_list_add(struct list_head *list, bdaddr_t *bdaddr, u8 type)
2057b2a66aadSAntti Julku {
2058b2a66aadSAntti Julku struct bdaddr_list *entry;
2059b2a66aadSAntti Julku
2060b9ee0a78SMarcel Holtmann if (!bacmp(bdaddr, BDADDR_ANY))
2061b2a66aadSAntti Julku return -EBADF;
2062b2a66aadSAntti Julku
2063dcc36c16SJohan Hedberg if (hci_bdaddr_list_lookup(list, bdaddr, type))
20645e762444SAntti Julku return -EEXIST;
2065b2a66aadSAntti Julku
206627f70f3eSJohan Hedberg entry = kzalloc(sizeof(*entry), GFP_KERNEL);
20675e762444SAntti Julku if (!entry)
20685e762444SAntti Julku return -ENOMEM;
2069b2a66aadSAntti Julku
2070b2a66aadSAntti Julku bacpy(&entry->bdaddr, bdaddr);
2071b9ee0a78SMarcel Holtmann entry->bdaddr_type = type;
2072b2a66aadSAntti Julku
2073dcc36c16SJohan Hedberg list_add(&entry->list, list);
2074b2a66aadSAntti Julku
20752a8357f2SJohan Hedberg return 0;
2076b2a66aadSAntti Julku }
hci_bdaddr_list_add_with_irk(struct list_head * list,bdaddr_t * bdaddr,u8 type,u8 * peer_irk,u8 * local_irk)2077b2a66aadSAntti Julku
2078b950aa88SAnkit Navik int hci_bdaddr_list_add_with_irk(struct list_head *list, bdaddr_t *bdaddr,
2079b950aa88SAnkit Navik u8 type, u8 *peer_irk, u8 *local_irk)
2080b950aa88SAnkit Navik {
2081b950aa88SAnkit Navik struct bdaddr_list_with_irk *entry;
2082b950aa88SAnkit Navik
2083b950aa88SAnkit Navik if (!bacmp(bdaddr, BDADDR_ANY))
2084b950aa88SAnkit Navik return -EBADF;
2085b950aa88SAnkit Navik
2086b950aa88SAnkit Navik if (hci_bdaddr_list_lookup(list, bdaddr, type))
2087b950aa88SAnkit Navik return -EEXIST;
2088b950aa88SAnkit Navik
2089b950aa88SAnkit Navik entry = kzalloc(sizeof(*entry), GFP_KERNEL);
2090b950aa88SAnkit Navik if (!entry)
2091b950aa88SAnkit Navik return -ENOMEM;
2092b950aa88SAnkit Navik
2093b950aa88SAnkit Navik bacpy(&entry->bdaddr, bdaddr);
2094b950aa88SAnkit Navik entry->bdaddr_type = type;
2095b950aa88SAnkit Navik
2096b950aa88SAnkit Navik if (peer_irk)
2097b950aa88SAnkit Navik memcpy(entry->peer_irk, peer_irk, 16);
2098b950aa88SAnkit Navik
2099b950aa88SAnkit Navik if (local_irk)
2100b950aa88SAnkit Navik memcpy(entry->local_irk, local_irk, 16);
2101b950aa88SAnkit Navik
2102b950aa88SAnkit Navik list_add(&entry->list, list);
2103b950aa88SAnkit Navik
2104b950aa88SAnkit Navik return 0;
2105b950aa88SAnkit Navik }
hci_bdaddr_list_add_with_flags(struct list_head * list,bdaddr_t * bdaddr,u8 type,u32 flags)2106b950aa88SAnkit Navik
21078baaa403SAbhishek Pandit-Subedi int hci_bdaddr_list_add_with_flags(struct list_head *list, bdaddr_t *bdaddr,
21088baaa403SAbhishek Pandit-Subedi u8 type, u32 flags)
21098baaa403SAbhishek Pandit-Subedi {
21108baaa403SAbhishek Pandit-Subedi struct bdaddr_list_with_flags *entry;
21118baaa403SAbhishek Pandit-Subedi
21128baaa403SAbhishek Pandit-Subedi if (!bacmp(bdaddr, BDADDR_ANY))
21138baaa403SAbhishek Pandit-Subedi return -EBADF;
21148baaa403SAbhishek Pandit-Subedi
21158baaa403SAbhishek Pandit-Subedi if (hci_bdaddr_list_lookup(list, bdaddr, type))
21168baaa403SAbhishek Pandit-Subedi return -EEXIST;
21178baaa403SAbhishek Pandit-Subedi
21188baaa403SAbhishek Pandit-Subedi entry = kzalloc(sizeof(*entry), GFP_KERNEL);
21198baaa403SAbhishek Pandit-Subedi if (!entry)
21208baaa403SAbhishek Pandit-Subedi return -ENOMEM;
21218baaa403SAbhishek Pandit-Subedi
21228baaa403SAbhishek Pandit-Subedi bacpy(&entry->bdaddr, bdaddr);
21238baaa403SAbhishek Pandit-Subedi entry->bdaddr_type = type;
2124e1cff700SLinus Torvalds entry->flags = flags;
21258baaa403SAbhishek Pandit-Subedi
21268baaa403SAbhishek Pandit-Subedi list_add(&entry->list, list);
21278baaa403SAbhishek Pandit-Subedi
21288baaa403SAbhishek Pandit-Subedi return 0;
21298baaa403SAbhishek Pandit-Subedi }
hci_bdaddr_list_del(struct list_head * list,bdaddr_t * bdaddr,u8 type)21308baaa403SAbhishek Pandit-Subedi
2131dcc36c16SJohan Hedberg int hci_bdaddr_list_del(struct list_head *list, bdaddr_t *bdaddr, u8 type)
2132b2a66aadSAntti Julku {
2133b2a66aadSAntti Julku struct bdaddr_list *entry;
2134b2a66aadSAntti Julku
213535f7498aSJohan Hedberg if (!bacmp(bdaddr, BDADDR_ANY)) {
2136dcc36c16SJohan Hedberg hci_bdaddr_list_clear(list);
213735f7498aSJohan Hedberg return 0;
213835f7498aSJohan Hedberg }
2139b2a66aadSAntti Julku
2140dcc36c16SJohan Hedberg entry = hci_bdaddr_list_lookup(list, bdaddr, type);
2141d2ab0ac1SMarcel Holtmann if (!entry)
2142d2ab0ac1SMarcel Holtmann return -ENOENT;
2143d2ab0ac1SMarcel Holtmann
2144d2ab0ac1SMarcel Holtmann list_del(&entry->list);
2145d2ab0ac1SMarcel Holtmann kfree(entry);
2146d2ab0ac1SMarcel Holtmann
2147d2ab0ac1SMarcel Holtmann return 0;
2148d2ab0ac1SMarcel Holtmann }
hci_bdaddr_list_del_with_irk(struct list_head * list,bdaddr_t * bdaddr,u8 type)2149d2ab0ac1SMarcel Holtmann
2150b950aa88SAnkit Navik int hci_bdaddr_list_del_with_irk(struct list_head *list, bdaddr_t *bdaddr,
2151b950aa88SAnkit Navik u8 type)
2152b950aa88SAnkit Navik {
2153b950aa88SAnkit Navik struct bdaddr_list_with_irk *entry;
2154b950aa88SAnkit Navik
2155b950aa88SAnkit Navik if (!bacmp(bdaddr, BDADDR_ANY)) {
2156b950aa88SAnkit Navik hci_bdaddr_list_clear(list);
2157b950aa88SAnkit Navik return 0;
2158b950aa88SAnkit Navik }
2159b950aa88SAnkit Navik
2160b950aa88SAnkit Navik entry = hci_bdaddr_list_lookup_with_irk(list, bdaddr, type);
2161b950aa88SAnkit Navik if (!entry)
2162b950aa88SAnkit Navik return -ENOENT;
2163b950aa88SAnkit Navik
2164b950aa88SAnkit Navik list_del(&entry->list);
2165b950aa88SAnkit Navik kfree(entry);
2166b950aa88SAnkit Navik
2167b950aa88SAnkit Navik return 0;
2168b950aa88SAnkit Navik }
hci_bdaddr_list_del_with_flags(struct list_head * list,bdaddr_t * bdaddr,u8 type)2169b950aa88SAnkit Navik
21708baaa403SAbhishek Pandit-Subedi int hci_bdaddr_list_del_with_flags(struct list_head *list, bdaddr_t *bdaddr,
21718baaa403SAbhishek Pandit-Subedi u8 type)
21728baaa403SAbhishek Pandit-Subedi {
21738baaa403SAbhishek Pandit-Subedi struct bdaddr_list_with_flags *entry;
21748baaa403SAbhishek Pandit-Subedi
21758baaa403SAbhishek Pandit-Subedi if (!bacmp(bdaddr, BDADDR_ANY)) {
21768baaa403SAbhishek Pandit-Subedi hci_bdaddr_list_clear(list);
21778baaa403SAbhishek Pandit-Subedi return 0;
21788baaa403SAbhishek Pandit-Subedi }
21798baaa403SAbhishek Pandit-Subedi
21808baaa403SAbhishek Pandit-Subedi entry = hci_bdaddr_list_lookup_with_flags(list, bdaddr, type);
21818baaa403SAbhishek Pandit-Subedi if (!entry)
21828baaa403SAbhishek Pandit-Subedi return -ENOENT;
21838baaa403SAbhishek Pandit-Subedi
21848baaa403SAbhishek Pandit-Subedi list_del(&entry->list);
21858baaa403SAbhishek Pandit-Subedi kfree(entry);
21868baaa403SAbhishek Pandit-Subedi
21878baaa403SAbhishek Pandit-Subedi return 0;
21888baaa403SAbhishek Pandit-Subedi }
21898baaa403SAbhishek Pandit-Subedi
hci_conn_params_lookup(struct hci_dev * hdev,bdaddr_t * addr,u8 addr_type)219015819a70SAndre Guedes /* This function requires the caller holds hdev->lock */
219115819a70SAndre Guedes struct hci_conn_params *hci_conn_params_lookup(struct hci_dev *hdev,
219215819a70SAndre Guedes bdaddr_t *addr, u8 addr_type)
219315819a70SAndre Guedes {
219415819a70SAndre Guedes struct hci_conn_params *params;
219515819a70SAndre Guedes
219615819a70SAndre Guedes list_for_each_entry(params, &hdev->le_conn_params, list) {
219715819a70SAndre Guedes if (bacmp(¶ms->addr, addr) == 0 &&
219815819a70SAndre Guedes params->addr_type == addr_type) {
219915819a70SAndre Guedes return params;
220015819a70SAndre Guedes }
220115819a70SAndre Guedes }
220215819a70SAndre Guedes
220315819a70SAndre Guedes return NULL;
220415819a70SAndre Guedes }
220515819a70SAndre Guedes
hci_pend_le_action_lookup(struct list_head * list,bdaddr_t * addr,u8 addr_type)2206195ef75eSPauli Virtanen /* This function requires the caller holds hdev->lock or rcu_read_lock */
2207501f8827SJohan Hedberg struct hci_conn_params *hci_pend_le_action_lookup(struct list_head *list,
22084b10966fSMarcel Holtmann bdaddr_t *addr, u8 addr_type)
2209a9b0a04cSAndre Guedes {
2210912b42efSJohan Hedberg struct hci_conn_params *param;
2211a9b0a04cSAndre Guedes
2212195ef75eSPauli Virtanen rcu_read_lock();
2213195ef75eSPauli Virtanen
2214195ef75eSPauli Virtanen list_for_each_entry_rcu(param, list, action) {
2215912b42efSJohan Hedberg if (bacmp(¶m->addr, addr) == 0 &&
2216195ef75eSPauli Virtanen param->addr_type == addr_type) {
2217195ef75eSPauli Virtanen rcu_read_unlock();
2218912b42efSJohan Hedberg return param;
22194b10966fSMarcel Holtmann }
2220195ef75eSPauli Virtanen }
2221195ef75eSPauli Virtanen
2222195ef75eSPauli Virtanen rcu_read_unlock();
22234b10966fSMarcel Holtmann
22244b10966fSMarcel Holtmann return NULL;
2225a9b0a04cSAndre Guedes }
2226a9b0a04cSAndre Guedes
hci_pend_le_list_del_init(struct hci_conn_params * param)222715819a70SAndre Guedes /* This function requires the caller holds hdev->lock */
2228195ef75eSPauli Virtanen void hci_pend_le_list_del_init(struct hci_conn_params *param)
2229195ef75eSPauli Virtanen {
2230195ef75eSPauli Virtanen if (list_empty(¶m->action))
2231195ef75eSPauli Virtanen return;
2232195ef75eSPauli Virtanen
2233195ef75eSPauli Virtanen list_del_rcu(¶m->action);
2234195ef75eSPauli Virtanen synchronize_rcu();
2235195ef75eSPauli Virtanen INIT_LIST_HEAD(¶m->action);
2236195ef75eSPauli Virtanen }
2237195ef75eSPauli Virtanen
hci_pend_le_list_add(struct hci_conn_params * param,struct list_head * list)2238195ef75eSPauli Virtanen /* This function requires the caller holds hdev->lock */
2239195ef75eSPauli Virtanen void hci_pend_le_list_add(struct hci_conn_params *param,
2240195ef75eSPauli Virtanen struct list_head *list)
2241195ef75eSPauli Virtanen {
2242195ef75eSPauli Virtanen list_add_rcu(¶m->action, list);
2243195ef75eSPauli Virtanen }
2244195ef75eSPauli Virtanen
hci_conn_params_add(struct hci_dev * hdev,bdaddr_t * addr,u8 addr_type)2245195ef75eSPauli Virtanen /* This function requires the caller holds hdev->lock */
224651d167c0SMarcel Holtmann struct hci_conn_params *hci_conn_params_add(struct hci_dev *hdev,
224751d167c0SMarcel Holtmann bdaddr_t *addr, u8 addr_type)
224815819a70SAndre Guedes {
224915819a70SAndre Guedes struct hci_conn_params *params;
225015819a70SAndre Guedes
225115819a70SAndre Guedes params = hci_conn_params_lookup(hdev, addr, addr_type);
2252cef952ceSAndre Guedes if (params)
225351d167c0SMarcel Holtmann return params;
225415819a70SAndre Guedes
225515819a70SAndre Guedes params = kzalloc(sizeof(*params), GFP_KERNEL);
225615819a70SAndre Guedes if (!params) {
22572064ee33SMarcel Holtmann bt_dev_err(hdev, "out of memory");
225851d167c0SMarcel Holtmann return NULL;
225915819a70SAndre Guedes }
226015819a70SAndre Guedes
226115819a70SAndre Guedes bacpy(¶ms->addr, addr);
226215819a70SAndre Guedes params->addr_type = addr_type;
2263cef952ceSAndre Guedes
2264cef952ceSAndre Guedes list_add(¶ms->list, &hdev->le_conn_params);
226593450c75SJohan Hedberg INIT_LIST_HEAD(¶ms->action);
2266cef952ceSAndre Guedes
2267bf5b3c8bSMarcel Holtmann params->conn_min_interval = hdev->le_conn_min_interval;
2268bf5b3c8bSMarcel Holtmann params->conn_max_interval = hdev->le_conn_max_interval;
2269bf5b3c8bSMarcel Holtmann params->conn_latency = hdev->le_conn_latency;
2270bf5b3c8bSMarcel Holtmann params->supervision_timeout = hdev->le_supv_timeout;
2271bf5b3c8bSMarcel Holtmann params->auto_connect = HCI_AUTO_CONN_DISABLED;
2272bf5b3c8bSMarcel Holtmann
2273bf5b3c8bSMarcel Holtmann BT_DBG("addr %pMR (type %u)", addr, addr_type);
2274bf5b3c8bSMarcel Holtmann
227551d167c0SMarcel Holtmann return params;
2276bf5b3c8bSMarcel Holtmann }
hci_conn_params_free(struct hci_conn_params * params)2277bf5b3c8bSMarcel Holtmann
2278195ef75eSPauli Virtanen void hci_conn_params_free(struct hci_conn_params *params)
2279f6c63249SJohan Hedberg {
2280195ef75eSPauli Virtanen hci_pend_le_list_del_init(params);
2281195ef75eSPauli Virtanen
2282f6c63249SJohan Hedberg if (params->conn) {
2283f6c63249SJohan Hedberg hci_conn_drop(params->conn);
2284f6c63249SJohan Hedberg hci_conn_put(params->conn);
2285f6c63249SJohan Hedberg }
2286f6c63249SJohan Hedberg
2287f6c63249SJohan Hedberg list_del(¶ms->list);
2288f6c63249SJohan Hedberg kfree(params);
2289f6c63249SJohan Hedberg }
2290f6c63249SJohan Hedberg
hci_conn_params_del(struct hci_dev * hdev,bdaddr_t * addr,u8 addr_type)229115819a70SAndre Guedes /* This function requires the caller holds hdev->lock */
229215819a70SAndre Guedes void hci_conn_params_del(struct hci_dev *hdev, bdaddr_t *addr, u8 addr_type)
229315819a70SAndre Guedes {
229415819a70SAndre Guedes struct hci_conn_params *params;
229515819a70SAndre Guedes
229615819a70SAndre Guedes params = hci_conn_params_lookup(hdev, addr, addr_type);
229715819a70SAndre Guedes if (!params)
229815819a70SAndre Guedes return;
229915819a70SAndre Guedes
2300f6c63249SJohan Hedberg hci_conn_params_free(params);
230115819a70SAndre Guedes
23025bee2fd6SLuiz Augusto von Dentz hci_update_passive_scan(hdev);
230395305baaSJohan Hedberg
230415819a70SAndre Guedes BT_DBG("addr %pMR (type %u)", addr, addr_type);
230515819a70SAndre Guedes }
230615819a70SAndre Guedes
hci_conn_params_clear_disabled(struct hci_dev * hdev)230715819a70SAndre Guedes /* This function requires the caller holds hdev->lock */
230855af49a8SJohan Hedberg void hci_conn_params_clear_disabled(struct hci_dev *hdev)
230915819a70SAndre Guedes {
231015819a70SAndre Guedes struct hci_conn_params *params, *tmp;
231115819a70SAndre Guedes
231215819a70SAndre Guedes list_for_each_entry_safe(params, tmp, &hdev->le_conn_params, list) {
231355af49a8SJohan Hedberg if (params->auto_connect != HCI_AUTO_CONN_DISABLED)
231455af49a8SJohan Hedberg continue;
2315f75113a2SJakub Pawlowski
231691641b79SZheng Yongjun /* If trying to establish one time connection to disabled
2317f75113a2SJakub Pawlowski * device, leave the params, but mark them as just once.
2318f75113a2SJakub Pawlowski */
2319f75113a2SJakub Pawlowski if (params->explicit_connect) {
2320f75113a2SJakub Pawlowski params->auto_connect = HCI_AUTO_CONN_EXPLICIT;
2321f75113a2SJakub Pawlowski continue;
2322f75113a2SJakub Pawlowski }
2323f75113a2SJakub Pawlowski
2324195ef75eSPauli Virtanen hci_conn_params_free(params);
232515819a70SAndre Guedes }
232615819a70SAndre Guedes
232755af49a8SJohan Hedberg BT_DBG("All LE disabled connection parameters were removed");
232855af49a8SJohan Hedberg }
232955af49a8SJohan Hedberg
hci_conn_params_clear_all(struct hci_dev * hdev)233055af49a8SJohan Hedberg /* This function requires the caller holds hdev->lock */
2331030e7f81SJohan Hedberg static void hci_conn_params_clear_all(struct hci_dev *hdev)
233215819a70SAndre Guedes {
233315819a70SAndre Guedes struct hci_conn_params *params, *tmp;
233415819a70SAndre Guedes
2335f6c63249SJohan Hedberg list_for_each_entry_safe(params, tmp, &hdev->le_conn_params, list)
2336f6c63249SJohan Hedberg hci_conn_params_free(params);
233715819a70SAndre Guedes
233815819a70SAndre Guedes BT_DBG("All LE connection parameters were removed");
233915819a70SAndre Guedes }
234015819a70SAndre Guedes
2341a1f4c318SJohan Hedberg /* Copy the Identity Address of the controller.
2342a1f4c318SJohan Hedberg *
2343a1f4c318SJohan Hedberg * If the controller has a public BD_ADDR, then by default use that one.
2344a1f4c318SJohan Hedberg * If this is a LE only controller without a public address, default to
2345a1f4c318SJohan Hedberg * the static random address.
2346a1f4c318SJohan Hedberg *
2347a1f4c318SJohan Hedberg * For debugging purposes it is possible to force controllers with a
2348a1f4c318SJohan Hedberg * public address to use the static random address instead.
234950b5b952SMarcel Holtmann *
235050b5b952SMarcel Holtmann * In case BR/EDR has been disabled on a dual-mode controller and
235150b5b952SMarcel Holtmann * userspace has configured a static address, then that address
235250b5b952SMarcel Holtmann * becomes the identity address instead of the public BR/EDR address.
hci_copy_identity_address(struct hci_dev * hdev,bdaddr_t * bdaddr,u8 * bdaddr_type)2353a1f4c318SJohan Hedberg */
2354a1f4c318SJohan Hedberg void hci_copy_identity_address(struct hci_dev *hdev, bdaddr_t *bdaddr,
2355a1f4c318SJohan Hedberg u8 *bdaddr_type)
2356a1f4c318SJohan Hedberg {
2357b7cb93e5SMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_FORCE_STATIC_ADDR) ||
235850b5b952SMarcel Holtmann !bacmp(&hdev->bdaddr, BDADDR_ANY) ||
2359d7a5a11dSMarcel Holtmann (!hci_dev_test_flag(hdev, HCI_BREDR_ENABLED) &&
236050b5b952SMarcel Holtmann bacmp(&hdev->static_addr, BDADDR_ANY))) {
2361a1f4c318SJohan Hedberg bacpy(bdaddr, &hdev->static_addr);
2362a1f4c318SJohan Hedberg *bdaddr_type = ADDR_LE_DEV_RANDOM;
2363a1f4c318SJohan Hedberg } else {
2364a1f4c318SJohan Hedberg bacpy(bdaddr, &hdev->bdaddr);
2365a1f4c318SJohan Hedberg *bdaddr_type = ADDR_LE_DEV_PUBLIC;
2366a1f4c318SJohan Hedberg }
2367a1f4c318SJohan Hedberg }
hci_clear_wake_reason(struct hci_dev * hdev)2368a1f4c318SJohan Hedberg
23692f20216cSAbhishek Pandit-Subedi static void hci_clear_wake_reason(struct hci_dev *hdev)
23702f20216cSAbhishek Pandit-Subedi {
23712f20216cSAbhishek Pandit-Subedi hci_dev_lock(hdev);
23722f20216cSAbhishek Pandit-Subedi
23732f20216cSAbhishek Pandit-Subedi hdev->wake_reason = 0;
23742f20216cSAbhishek Pandit-Subedi bacpy(&hdev->wake_addr, BDADDR_ANY);
23752f20216cSAbhishek Pandit-Subedi hdev->wake_addr_type = 0;
23762f20216cSAbhishek Pandit-Subedi
23772f20216cSAbhishek Pandit-Subedi hci_dev_unlock(hdev);
23782f20216cSAbhishek Pandit-Subedi }
hci_suspend_notifier(struct notifier_block * nb,unsigned long action,void * data)23792f20216cSAbhishek Pandit-Subedi
23809952d90eSAbhishek Pandit-Subedi static int hci_suspend_notifier(struct notifier_block *nb, unsigned long action,
23819952d90eSAbhishek Pandit-Subedi void *data)
23829952d90eSAbhishek Pandit-Subedi {
23839952d90eSAbhishek Pandit-Subedi struct hci_dev *hdev =
23849952d90eSAbhishek Pandit-Subedi container_of(nb, struct hci_dev, suspend_notifier);
23859952d90eSAbhishek Pandit-Subedi int ret = 0;
23869952d90eSAbhishek Pandit-Subedi
23874b8af331SAbhishek Pandit-Subedi /* Userspace has full control of this device. Do nothing. */
23884b8af331SAbhishek Pandit-Subedi if (hci_dev_test_flag(hdev, HCI_USER_CHANNEL))
23894b8af331SAbhishek Pandit-Subedi return NOTIFY_DONE;
23904b8af331SAbhishek Pandit-Subedi
2391573ebae1SYing Hsu /* To avoid a potential race with hci_unregister_dev. */
2392573ebae1SYing Hsu hci_dev_hold(hdev);
2393573ebae1SYing Hsu
2394c8525821SLuiz Augusto von Dentz switch (action) {
2395c8525821SLuiz Augusto von Dentz case PM_HIBERNATION_PREPARE:
2396c8525821SLuiz Augusto von Dentz case PM_SUSPEND_PREPARE:
2397e1b77d68SLuiz Augusto von Dentz ret = hci_suspend_dev(hdev);
2398c8525821SLuiz Augusto von Dentz break;
2399c8525821SLuiz Augusto von Dentz case PM_POST_HIBERNATION:
2400c8525821SLuiz Augusto von Dentz case PM_POST_SUSPEND:
2401e1b77d68SLuiz Augusto von Dentz ret = hci_resume_dev(hdev);
2402c8525821SLuiz Augusto von Dentz break;
2403c8525821SLuiz Augusto von Dentz }
24049952d90eSAbhishek Pandit-Subedi
2405a9ec8423SAbhishek Pandit-Subedi if (ret)
2406a9ec8423SAbhishek Pandit-Subedi bt_dev_err(hdev, "Suspend notifier action (%lu) failed: %d",
2407a9ec8423SAbhishek Pandit-Subedi action, ret);
2408a9ec8423SAbhishek Pandit-Subedi
2409573ebae1SYing Hsu hci_dev_put(hdev);
241024b06572SMax Chou return NOTIFY_DONE;
24119952d90eSAbhishek Pandit-Subedi }
24128731840aSAbhishek Pandit-Subedi
hci_alloc_dev_priv(int sizeof_priv)24139be0dab7SDavid Herrmann /* Alloc HCI device */
24146ec56613STedd Ho-Jeong An struct hci_dev *hci_alloc_dev_priv(int sizeof_priv)
24159be0dab7SDavid Herrmann {
24169be0dab7SDavid Herrmann struct hci_dev *hdev;
24176ec56613STedd Ho-Jeong An unsigned int alloc_size;
24189be0dab7SDavid Herrmann
24196ec56613STedd Ho-Jeong An alloc_size = sizeof(*hdev);
24206ec56613STedd Ho-Jeong An if (sizeof_priv) {
24216ec56613STedd Ho-Jeong An /* Fixme: May need ALIGN-ment? */
24226ec56613STedd Ho-Jeong An alloc_size += sizeof_priv;
24236ec56613STedd Ho-Jeong An }
24246ec56613STedd Ho-Jeong An
24256ec56613STedd Ho-Jeong An hdev = kzalloc(alloc_size, GFP_KERNEL);
24269be0dab7SDavid Herrmann if (!hdev)
24279be0dab7SDavid Herrmann return NULL;
24289be0dab7SDavid Herrmann
2429b1b813d4SDavid Herrmann hdev->pkt_type = (HCI_DM1 | HCI_DH1 | HCI_HV1);
2430b1b813d4SDavid Herrmann hdev->esco_type = (ESCO_HV1);
2431b1b813d4SDavid Herrmann hdev->link_mode = (HCI_LM_ACCEPT);
2432b4cb9fb2SMarcel Holtmann hdev->num_iac = 0x01; /* One IAC support is mandatory */
2433b1b813d4SDavid Herrmann hdev->io_capability = 0x03; /* No Input No Output */
243496c2103aSMarcel Holtmann hdev->manufacturer = 0xffff; /* Default to internal use */
2435bbaf444aSJohan Hedberg hdev->inq_tx_power = HCI_TX_POWER_INVALID;
2436bbaf444aSJohan Hedberg hdev->adv_tx_power = HCI_TX_POWER_INVALID;
2437d2609b34SFlorian Grandel hdev->adv_instance_cnt = 0;
2438d2609b34SFlorian Grandel hdev->cur_adv_instance = 0x00;
24395d900e46SFlorian Grandel hdev->adv_instance_timeout = 0;
2440b1b813d4SDavid Herrmann
2441c4f1f408SHoward Chung hdev->advmon_allowlist_duration = 300;
2442c4f1f408SHoward Chung hdev->advmon_no_filter_duration = 500;
244380af16a3SHoward Chung hdev->enable_advmon_interleave_scan = 0x00; /* Default to disable */
2444c4f1f408SHoward Chung
2445b1b813d4SDavid Herrmann hdev->sniff_max_interval = 800;
2446b1b813d4SDavid Herrmann hdev->sniff_min_interval = 80;
2447b1b813d4SDavid Herrmann
24483f959d46SMarcel Holtmann hdev->le_adv_channel_map = 0x07;
2449628531c9SGeorg Lukas hdev->le_adv_min_interval = 0x0800;
2450628531c9SGeorg Lukas hdev->le_adv_max_interval = 0x0800;
2451bef64738SMarcel Holtmann hdev->le_scan_interval = 0x0060;
2452bef64738SMarcel Holtmann hdev->le_scan_window = 0x0030;
245310873f99SAlain Michaud hdev->le_scan_int_suspend = 0x0400;
245410873f99SAlain Michaud hdev->le_scan_window_suspend = 0x0012;
245510873f99SAlain Michaud hdev->le_scan_int_discovery = DISCOV_LE_SCAN_INT;
245610873f99SAlain Michaud hdev->le_scan_window_discovery = DISCOV_LE_SCAN_WIN;
2457ba29d036SMarcel Holtmann hdev->le_scan_int_adv_monitor = 0x0060;
2458ba29d036SMarcel Holtmann hdev->le_scan_window_adv_monitor = 0x0030;
245910873f99SAlain Michaud hdev->le_scan_int_connect = 0x0060;
246010873f99SAlain Michaud hdev->le_scan_window_connect = 0x0060;
2461b48c3b59SJonas Holmberg hdev->le_conn_min_interval = 0x0018;
2462b48c3b59SJonas Holmberg hdev->le_conn_max_interval = 0x0028;
246304fb7d90SMarcel Holtmann hdev->le_conn_latency = 0x0000;
246404fb7d90SMarcel Holtmann hdev->le_supv_timeout = 0x002a;
2465a8e1bfaaSMarcel Holtmann hdev->le_def_tx_len = 0x001b;
2466a8e1bfaaSMarcel Holtmann hdev->le_def_tx_time = 0x0148;
2467a8e1bfaaSMarcel Holtmann hdev->le_max_tx_len = 0x001b;
2468a8e1bfaaSMarcel Holtmann hdev->le_max_tx_time = 0x0148;
2469a8e1bfaaSMarcel Holtmann hdev->le_max_rx_len = 0x001b;
2470a8e1bfaaSMarcel Holtmann hdev->le_max_rx_time = 0x0148;
247130d65e08SMatias Karhumaa hdev->le_max_key_size = SMP_MAX_ENC_KEY_SIZE;
247230d65e08SMatias Karhumaa hdev->le_min_key_size = SMP_MIN_ENC_KEY_SIZE;
24736decb5b4SJaganath Kanakkassery hdev->le_tx_def_phys = HCI_LE_SET_PHY_1M;
24746decb5b4SJaganath Kanakkassery hdev->le_rx_def_phys = HCI_LE_SET_PHY_1M;
24751d0fac2cSLuiz Augusto von Dentz hdev->le_num_of_adv_sets = HCI_MAX_ADV_INSTANCES;
247610873f99SAlain Michaud hdev->def_multi_adv_rotation_duration = HCI_DEFAULT_ADV_DURATION;
247749b020c1SAlain Michaud hdev->def_le_autoconnect_timeout = HCI_LE_AUTOCONN_TIMEOUT;
24787c395ea5SDaniel Winkler hdev->min_le_tx_power = HCI_TX_POWER_INVALID;
24797c395ea5SDaniel Winkler hdev->max_le_tx_power = HCI_TX_POWER_INVALID;
2480bef64738SMarcel Holtmann
2481d6bfd59cSJohan Hedberg hdev->rpa_timeout = HCI_DEFAULT_RPA_TIMEOUT;
2482b9a7a61eSLukasz Rymanowski hdev->discov_interleaved_timeout = DISCOV_INTERLEAVED_TIMEOUT;
248331ad1691SAndrzej Kaczmarek hdev->conn_info_min_age = DEFAULT_CONN_INFO_MIN_AGE;
248431ad1691SAndrzej Kaczmarek hdev->conn_info_max_age = DEFAULT_CONN_INFO_MAX_AGE;
2485302975cbSSpoorthi Ravishankar Koppad hdev->auth_payload_timeout = DEFAULT_AUTH_PAYLOAD_TIMEOUT;
248658a96fc3SMarcel Holtmann hdev->min_enc_key_size = HCI_MIN_ENC_KEY_SIZE;
2487d6bfd59cSJohan Hedberg
248810873f99SAlain Michaud /* default 1.28 sec page scan */
248910873f99SAlain Michaud hdev->def_page_scan_type = PAGE_SCAN_TYPE_STANDARD;
249010873f99SAlain Michaud hdev->def_page_scan_int = 0x0800;
249110873f99SAlain Michaud hdev->def_page_scan_window = 0x0012;
249210873f99SAlain Michaud
2493b1b813d4SDavid Herrmann mutex_init(&hdev->lock);
2494b1b813d4SDavid Herrmann mutex_init(&hdev->req_lock);
2495b1b813d4SDavid Herrmann
249684cb0143SZiyang Xuan ida_init(&hdev->unset_handle_ida);
249784cb0143SZiyang Xuan
2498b338d917SBrian Gix INIT_LIST_HEAD(&hdev->mesh_pending);
2499b1b813d4SDavid Herrmann INIT_LIST_HEAD(&hdev->mgmt_pending);
25003d4f9c00SArchie Pusaka INIT_LIST_HEAD(&hdev->reject_list);
25013d4f9c00SArchie Pusaka INIT_LIST_HEAD(&hdev->accept_list);
2502b1b813d4SDavid Herrmann INIT_LIST_HEAD(&hdev->uuids);
2503b1b813d4SDavid Herrmann INIT_LIST_HEAD(&hdev->link_keys);
2504b1b813d4SDavid Herrmann INIT_LIST_HEAD(&hdev->long_term_keys);
2505970c4e46SJohan Hedberg INIT_LIST_HEAD(&hdev->identity_resolving_keys);
2506b1b813d4SDavid Herrmann INIT_LIST_HEAD(&hdev->remote_oob_data);
25073d4f9c00SArchie Pusaka INIT_LIST_HEAD(&hdev->le_accept_list);
2508cfdb0c2dSAnkit Navik INIT_LIST_HEAD(&hdev->le_resolv_list);
250915819a70SAndre Guedes INIT_LIST_HEAD(&hdev->le_conn_params);
251077a77a30SAndre Guedes INIT_LIST_HEAD(&hdev->pend_le_conns);
251166f8455aSJohan Hedberg INIT_LIST_HEAD(&hdev->pend_le_reports);
25126b536b5eSAndrei Emeltchenko INIT_LIST_HEAD(&hdev->conn_hash.list);
2513d2609b34SFlorian Grandel INIT_LIST_HEAD(&hdev->adv_instances);
2514600a8749SAlain Michaud INIT_LIST_HEAD(&hdev->blocked_keys);
25153368aa35SManish Mandlik INIT_LIST_HEAD(&hdev->monitored_devices);
2516b1b813d4SDavid Herrmann
25178961987fSKiran K INIT_LIST_HEAD(&hdev->local_codecs);
2518b1b813d4SDavid Herrmann INIT_WORK(&hdev->rx_work, hci_rx_work);
2519b1b813d4SDavid Herrmann INIT_WORK(&hdev->cmd_work, hci_cmd_work);
2520b1b813d4SDavid Herrmann INIT_WORK(&hdev->tx_work, hci_tx_work);
2521b1b813d4SDavid Herrmann INIT_WORK(&hdev->power_on, hci_power_on);
2522c7741d16SMarcel Holtmann INIT_WORK(&hdev->error_reset, hci_error_reset);
2523b1b813d4SDavid Herrmann
25246a98e383SMarcel Holtmann hci_cmd_sync_init(hdev);
25256a98e383SMarcel Holtmann
2526b1b813d4SDavid Herrmann INIT_DELAYED_WORK(&hdev->power_off, hci_power_off);
2527b1b813d4SDavid Herrmann
2528b1b813d4SDavid Herrmann skb_queue_head_init(&hdev->rx_q);
2529b1b813d4SDavid Herrmann skb_queue_head_init(&hdev->cmd_q);
2530b1b813d4SDavid Herrmann skb_queue_head_init(&hdev->raw_q);
2531b1b813d4SDavid Herrmann
2532b1b813d4SDavid Herrmann init_waitqueue_head(&hdev->req_wait_q);
2533b1b813d4SDavid Herrmann
253465cc2b49SMarcel Holtmann INIT_DELAYED_WORK(&hdev->cmd_timer, hci_cmd_timeout);
2535de75cd0dSManish Mandlik INIT_DELAYED_WORK(&hdev->ncmd_timer, hci_ncmd_timeout);
2536b1b813d4SDavid Herrmann
25379695ef87SAbhishek Pandit-Subedi hci_devcd_setup(hdev);
25385fc16cc4SJohan Hedberg hci_request_setup(hdev);
25395fc16cc4SJohan Hedberg
2540b1b813d4SDavid Herrmann hci_init_sysfs(hdev);
2541b1b813d4SDavid Herrmann discovery_init(hdev);
25429be0dab7SDavid Herrmann
25439be0dab7SDavid Herrmann return hdev;
25449be0dab7SDavid Herrmann }
25456ec56613STedd Ho-Jeong An EXPORT_SYMBOL(hci_alloc_dev_priv);
25469be0dab7SDavid Herrmann
hci_free_dev(struct hci_dev * hdev)25479be0dab7SDavid Herrmann /* Free HCI device */
25489be0dab7SDavid Herrmann void hci_free_dev(struct hci_dev *hdev)
25499be0dab7SDavid Herrmann {
25509be0dab7SDavid Herrmann /* will free via device release */
25519be0dab7SDavid Herrmann put_device(&hdev->dev);
25529be0dab7SDavid Herrmann }
25539be0dab7SDavid Herrmann EXPORT_SYMBOL(hci_free_dev);
25549be0dab7SDavid Herrmann
hci_register_dev(struct hci_dev * hdev)25551da177e4SLinus Torvalds /* Register HCI device */
25561da177e4SLinus Torvalds int hci_register_dev(struct hci_dev *hdev)
25571da177e4SLinus Torvalds {
2558b1b813d4SDavid Herrmann int id, error;
25591da177e4SLinus Torvalds
256074292d5aSMarcel Holtmann if (!hdev->open || !hdev->close || !hdev->send)
25611da177e4SLinus Torvalds return -EINVAL;
25621da177e4SLinus Torvalds
25630a8af30aSChristophe JAILLET id = ida_alloc_max(&hci_index_ida, HCI_MAX_ID - 1, GFP_KERNEL);
25643df92b31SSasha Levin if (id < 0)
25653df92b31SSasha Levin return id;
25663df92b31SSasha Levin
2567dcda1657SLuiz Augusto von Dentz error = dev_set_name(&hdev->dev, "hci%u", id);
2568dcda1657SLuiz Augusto von Dentz if (error)
2569dcda1657SLuiz Augusto von Dentz return error;
2570dcda1657SLuiz Augusto von Dentz
2571dcda1657SLuiz Augusto von Dentz hdev->name = dev_name(&hdev->dev);
25721da177e4SLinus Torvalds hdev->id = id;
25732d8b3a11SAndrei Emeltchenko
25742d8b3a11SAndrei Emeltchenko BT_DBG("%p name %s bus %d", hdev, hdev->name, hdev->bus);
25752d8b3a11SAndrei Emeltchenko
257629e2dd0dSTejun Heo hdev->workqueue = alloc_ordered_workqueue("%s", WQ_HIGHPRI, hdev->name);
257733ca954dSDavid Herrmann if (!hdev->workqueue) {
257833ca954dSDavid Herrmann error = -ENOMEM;
257933ca954dSDavid Herrmann goto err;
258033ca954dSDavid Herrmann }
2581f48fd9c8SMarcel Holtmann
258229e2dd0dSTejun Heo hdev->req_workqueue = alloc_ordered_workqueue("%s", WQ_HIGHPRI,
258329e2dd0dSTejun Heo hdev->name);
25846ead1bbcSJohan Hedberg if (!hdev->req_workqueue) {
25856ead1bbcSJohan Hedberg destroy_workqueue(hdev->workqueue);
25866ead1bbcSJohan Hedberg error = -ENOMEM;
25876ead1bbcSJohan Hedberg goto err;
25886ead1bbcSJohan Hedberg }
25896ead1bbcSJohan Hedberg
25900153e2ecSMarcel Holtmann if (!IS_ERR_OR_NULL(bt_debugfs))
25910153e2ecSMarcel Holtmann hdev->debugfs = debugfs_create_dir(hdev->name, bt_debugfs);
25920153e2ecSMarcel Holtmann
2593bdc3e0f1SMarcel Holtmann error = device_add(&hdev->dev);
259433ca954dSDavid Herrmann if (error < 0)
259554506918SJohan Hedberg goto err_wqueue;
25961da177e4SLinus Torvalds
25976d5d2ee6SHeiner Kallweit hci_leds_init(hdev);
25986d5d2ee6SHeiner Kallweit
2599611b30f7SMarcel Holtmann hdev->rfkill = rfkill_alloc(hdev->name, &hdev->dev,
2600a8c5fb1aSGustavo Padovan RFKILL_TYPE_BLUETOOTH, &hci_rfkill_ops,
2601a8c5fb1aSGustavo Padovan hdev);
2602611b30f7SMarcel Holtmann if (hdev->rfkill) {
2603611b30f7SMarcel Holtmann if (rfkill_register(hdev->rfkill) < 0) {
2604611b30f7SMarcel Holtmann rfkill_destroy(hdev->rfkill);
2605611b30f7SMarcel Holtmann hdev->rfkill = NULL;
2606611b30f7SMarcel Holtmann }
2607611b30f7SMarcel Holtmann }
2608611b30f7SMarcel Holtmann
26095e130367SJohan Hedberg if (hdev->rfkill && rfkill_blocked(hdev->rfkill))
2610a1536da2SMarcel Holtmann hci_dev_set_flag(hdev, HCI_RFKILLED);
26115e130367SJohan Hedberg
2612a1536da2SMarcel Holtmann hci_dev_set_flag(hdev, HCI_SETUP);
2613a1536da2SMarcel Holtmann hci_dev_set_flag(hdev, HCI_AUTO_OFF);
2614ce2be9acSAndrei Emeltchenko
261556f87901SJohan Hedberg /* Assume BR/EDR support until proven otherwise (such as
261656f87901SJohan Hedberg * through reading supported features during init.
261756f87901SJohan Hedberg */
2618a1536da2SMarcel Holtmann hci_dev_set_flag(hdev, HCI_BREDR_ENABLED);
2619ce2be9acSAndrei Emeltchenko
2620fcee3377SGustavo Padovan write_lock(&hci_dev_list_lock);
2621fcee3377SGustavo Padovan list_add(&hdev->list, &hci_dev_list);
2622fcee3377SGustavo Padovan write_unlock(&hci_dev_list_lock);
2623fcee3377SGustavo Padovan
26244a964404SMarcel Holtmann /* Devices that are marked for raw-only usage are unconfigured
26254a964404SMarcel Holtmann * and should not be included in normal operation.
2626fee746b0SMarcel Holtmann */
2627fee746b0SMarcel Holtmann if (test_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks))
2628a1536da2SMarcel Holtmann hci_dev_set_flag(hdev, HCI_UNCONFIGURED);
2629fee746b0SMarcel Holtmann
2630fe92ee64SLuiz Augusto von Dentz /* Mark Remote Wakeup connection flag as supported if driver has wakeup
2631fe92ee64SLuiz Augusto von Dentz * callback.
2632fe92ee64SLuiz Augusto von Dentz */
2633fe92ee64SLuiz Augusto von Dentz if (hdev->wakeup)
2634e1cff700SLinus Torvalds hdev->conn_flags |= HCI_CONN_FLAG_REMOTE_WAKEUP;
2635fe92ee64SLuiz Augusto von Dentz
263605fcd4c4SMarcel Holtmann hci_sock_dev_event(hdev, HCI_DEV_REG);
2637dc946bd8SDavid Herrmann hci_dev_hold(hdev);
26381da177e4SLinus Torvalds
263991117864SDan Carpenter error = hci_register_suspend_notifier(hdev);
264091117864SDan Carpenter if (error)
26410d75da38SYang Yingliang BT_WARN("register suspend notifier failed error:%d\n", error);
26429952d90eSAbhishek Pandit-Subedi
264319202573SJohan Hedberg queue_work(hdev->req_workqueue, &hdev->power_on);
2644fbe96d6fSMarcel Holtmann
2645e5e1e7fdSMiao-chen Chou idr_init(&hdev->adv_monitors_idr);
26465031ffccSMiao-chen Chou msft_register(hdev);
2647e5e1e7fdSMiao-chen Chou
26481da177e4SLinus Torvalds return id;
2649f48fd9c8SMarcel Holtmann
265033ca954dSDavid Herrmann err_wqueue:
26515a4bb6a8SWei Yongjun debugfs_remove_recursive(hdev->debugfs);
265233ca954dSDavid Herrmann destroy_workqueue(hdev->workqueue);
26536ead1bbcSJohan Hedberg destroy_workqueue(hdev->req_workqueue);
265433ca954dSDavid Herrmann err:
26550a8af30aSChristophe JAILLET ida_free(&hci_index_ida, hdev->id);
2656f48fd9c8SMarcel Holtmann
265733ca954dSDavid Herrmann return error;
26581da177e4SLinus Torvalds }
26591da177e4SLinus Torvalds EXPORT_SYMBOL(hci_register_dev);
26601da177e4SLinus Torvalds
hci_unregister_dev(struct hci_dev * hdev)26611da177e4SLinus Torvalds /* Unregister HCI device */
266259735631SDavid Herrmann void hci_unregister_dev(struct hci_dev *hdev)
26631da177e4SLinus Torvalds {
2664c13854ceSMarcel Holtmann BT_DBG("%p name %s bus %d", hdev, hdev->name, hdev->bus);
26651da177e4SLinus Torvalds
26661857c199SZhengping Jiang mutex_lock(&hdev->unregister_lock);
2667a1536da2SMarcel Holtmann hci_dev_set_flag(hdev, HCI_UNREGISTER);
26681857c199SZhengping Jiang mutex_unlock(&hdev->unregister_lock);
266994324962SJohan Hovold
2670f20d09d5SGustavo F. Padovan write_lock(&hci_dev_list_lock);
26711da177e4SLinus Torvalds list_del(&hdev->list);
2672f20d09d5SGustavo F. Padovan write_unlock(&hci_dev_list_lock);
26731da177e4SLinus Torvalds
2674d6cbce18STetsuo Handa cancel_work_sync(&hdev->rx_work);
2675d6cbce18STetsuo Handa cancel_work_sync(&hdev->cmd_work);
2676d6cbce18STetsuo Handa cancel_work_sync(&hdev->tx_work);
2677e36bea6eSVasyl Vavrychuk cancel_work_sync(&hdev->power_on);
2678d6cbce18STetsuo Handa cancel_work_sync(&hdev->error_reset);
2679e36bea6eSVasyl Vavrychuk
26806a98e383SMarcel Holtmann hci_cmd_sync_clear(hdev);
26816a98e383SMarcel Holtmann
2682359ee4f8SAbhishek Pandit-Subedi hci_unregister_suspend_notifier(hdev);
26834e8c36c3SAbhishek Pandit-Subedi
26844e8c36c3SAbhishek Pandit-Subedi hci_dev_do_close(hdev);
26859952d90eSAbhishek Pandit-Subedi
2686ab81cbf9SJohan Hedberg if (!test_bit(HCI_INIT, &hdev->flags) &&
2687d7a5a11dSMarcel Holtmann !hci_dev_test_flag(hdev, HCI_SETUP) &&
2688d7a5a11dSMarcel Holtmann !hci_dev_test_flag(hdev, HCI_CONFIG)) {
268909fd0de5SGustavo F. Padovan hci_dev_lock(hdev);
2690744cf19eSJohan Hedberg mgmt_index_removed(hdev);
269109fd0de5SGustavo F. Padovan hci_dev_unlock(hdev);
269256e5cb86SJohan Hedberg }
2693ab81cbf9SJohan Hedberg
26942e58ef3eSJohan Hedberg /* mgmt_index_removed should take care of emptying the
26952e58ef3eSJohan Hedberg * pending list */
26962e58ef3eSJohan Hedberg BUG_ON(!list_empty(&hdev->mgmt_pending));
26972e58ef3eSJohan Hedberg
269805fcd4c4SMarcel Holtmann hci_sock_dev_event(hdev, HCI_DEV_UNREG);
26991da177e4SLinus Torvalds
2700611b30f7SMarcel Holtmann if (hdev->rfkill) {
2701611b30f7SMarcel Holtmann rfkill_unregister(hdev->rfkill);
2702611b30f7SMarcel Holtmann rfkill_destroy(hdev->rfkill);
2703611b30f7SMarcel Holtmann }
2704611b30f7SMarcel Holtmann
2705bdc3e0f1SMarcel Holtmann device_del(&hdev->dev);
2706e61fbee7SDavid S. Miller /* Actual cleanup is deferred until hci_release_dev(). */
2707e0448092STetsuo Handa hci_dev_put(hdev);
2708e0448092STetsuo Handa }
2709e0448092STetsuo Handa EXPORT_SYMBOL(hci_unregister_dev);
2710147e2d59SDave Young
hci_release_dev(struct hci_dev * hdev)271158ce6d5bSTetsuo Handa /* Release HCI device */
271258ce6d5bSTetsuo Handa void hci_release_dev(struct hci_dev *hdev)
2713e0448092STetsuo Handa {
27140153e2ecSMarcel Holtmann debugfs_remove_recursive(hdev->debugfs);
27155177a838SMarcel Holtmann kfree_const(hdev->hw_info);
27165177a838SMarcel Holtmann kfree_const(hdev->fw_info);
27170153e2ecSMarcel Holtmann
2718f48fd9c8SMarcel Holtmann destroy_workqueue(hdev->workqueue);
27196ead1bbcSJohan Hedberg destroy_workqueue(hdev->req_workqueue);
2720f48fd9c8SMarcel Holtmann
272109fd0de5SGustavo F. Padovan hci_dev_lock(hdev);
27223d4f9c00SArchie Pusaka hci_bdaddr_list_clear(&hdev->reject_list);
27233d4f9c00SArchie Pusaka hci_bdaddr_list_clear(&hdev->accept_list);
27242aeb9a1aSJohan Hedberg hci_uuids_clear(hdev);
272555ed8ca1SJohan Hedberg hci_link_keys_clear(hdev);
2726b899efafSVinicius Costa Gomes hci_smp_ltks_clear(hdev);
2727970c4e46SJohan Hedberg hci_smp_irks_clear(hdev);
27282763eda6SSzymon Janc hci_remote_oob_data_clear(hdev);
2729d2609b34SFlorian Grandel hci_adv_instances_clear(hdev);
2730e5e1e7fdSMiao-chen Chou hci_adv_monitors_clear(hdev);
27313d4f9c00SArchie Pusaka hci_bdaddr_list_clear(&hdev->le_accept_list);
2732cfdb0c2dSAnkit Navik hci_bdaddr_list_clear(&hdev->le_resolv_list);
2733373110c5SJohan Hedberg hci_conn_params_clear_all(hdev);
273422078800SMarcel Holtmann hci_discovery_filter_clear(hdev);
2735600a8749SAlain Michaud hci_blocked_keys_clear(hdev);
2736b938790eSLuiz Augusto von Dentz hci_codec_list_clear(&hdev->local_codecs);
2737a85a60e6SSungwoo Kim msft_release(hdev);
273809fd0de5SGustavo F. Padovan hci_dev_unlock(hdev);
2739e2e0cacbSJohan Hedberg
274084cb0143SZiyang Xuan ida_destroy(&hdev->unset_handle_ida);
27410a8af30aSChristophe JAILLET ida_free(&hci_index_ida, hdev->id);
2742dd3b1dc3SLuiz Augusto von Dentz kfree_skb(hdev->sent_cmd);
27432af7aa66SLuiz Augusto von Dentz kfree_skb(hdev->req_skb);
2744dfe6d5c3SLuiz Augusto von Dentz kfree_skb(hdev->recv_event);
274558ce6d5bSTetsuo Handa kfree(hdev);
27461da177e4SLinus Torvalds }
274758ce6d5bSTetsuo Handa EXPORT_SYMBOL(hci_release_dev);
hci_register_suspend_notifier(struct hci_dev * hdev)27481da177e4SLinus Torvalds
2749359ee4f8SAbhishek Pandit-Subedi int hci_register_suspend_notifier(struct hci_dev *hdev)
2750359ee4f8SAbhishek Pandit-Subedi {
2751359ee4f8SAbhishek Pandit-Subedi int ret = 0;
2752359ee4f8SAbhishek Pandit-Subedi
2753b5ca3387SLuiz Augusto von Dentz if (!hdev->suspend_notifier.notifier_call &&
2754b5ca3387SLuiz Augusto von Dentz !test_bit(HCI_QUIRK_NO_SUSPEND_NOTIFIER, &hdev->quirks)) {
2755359ee4f8SAbhishek Pandit-Subedi hdev->suspend_notifier.notifier_call = hci_suspend_notifier;
2756359ee4f8SAbhishek Pandit-Subedi ret = register_pm_notifier(&hdev->suspend_notifier);
2757359ee4f8SAbhishek Pandit-Subedi }
2758359ee4f8SAbhishek Pandit-Subedi
2759359ee4f8SAbhishek Pandit-Subedi return ret;
2760359ee4f8SAbhishek Pandit-Subedi }
hci_unregister_suspend_notifier(struct hci_dev * hdev)2761359ee4f8SAbhishek Pandit-Subedi
2762359ee4f8SAbhishek Pandit-Subedi int hci_unregister_suspend_notifier(struct hci_dev *hdev)
2763359ee4f8SAbhishek Pandit-Subedi {
2764359ee4f8SAbhishek Pandit-Subedi int ret = 0;
2765359ee4f8SAbhishek Pandit-Subedi
2766b5ca3387SLuiz Augusto von Dentz if (hdev->suspend_notifier.notifier_call) {
2767359ee4f8SAbhishek Pandit-Subedi ret = unregister_pm_notifier(&hdev->suspend_notifier);
2768b5ca3387SLuiz Augusto von Dentz if (!ret)
2769b5ca3387SLuiz Augusto von Dentz hdev->suspend_notifier.notifier_call = NULL;
2770b5ca3387SLuiz Augusto von Dentz }
2771359ee4f8SAbhishek Pandit-Subedi
2772359ee4f8SAbhishek Pandit-Subedi return ret;
2773359ee4f8SAbhishek Pandit-Subedi }
2774359ee4f8SAbhishek Pandit-Subedi
27750ce1229cSLuiz Augusto von Dentz /* Cancel ongoing command synchronously:
27760ce1229cSLuiz Augusto von Dentz *
27770ce1229cSLuiz Augusto von Dentz * - Cancel command timer
27780ce1229cSLuiz Augusto von Dentz * - Reset command counter
27790ce1229cSLuiz Augusto von Dentz * - Cancel command request
hci_cancel_cmd_sync(struct hci_dev * hdev,int err)27800ce1229cSLuiz Augusto von Dentz */
27810ce1229cSLuiz Augusto von Dentz static void hci_cancel_cmd_sync(struct hci_dev *hdev, int err)
27820ce1229cSLuiz Augusto von Dentz {
27830ce1229cSLuiz Augusto von Dentz bt_dev_dbg(hdev, "err 0x%2.2x", err);
27840ce1229cSLuiz Augusto von Dentz
27850ce1229cSLuiz Augusto von Dentz cancel_delayed_work_sync(&hdev->cmd_timer);
27860ce1229cSLuiz Augusto von Dentz cancel_delayed_work_sync(&hdev->ncmd_timer);
27870ce1229cSLuiz Augusto von Dentz atomic_set(&hdev->cmd_cnt, 1);
27880ce1229cSLuiz Augusto von Dentz
27899ae3954dSLuiz Augusto von Dentz hci_cmd_sync_cancel_sync(hdev, err);
27900ce1229cSLuiz Augusto von Dentz }
27910ce1229cSLuiz Augusto von Dentz
hci_suspend_dev(struct hci_dev * hdev)27921da177e4SLinus Torvalds /* Suspend HCI device */
27931da177e4SLinus Torvalds int hci_suspend_dev(struct hci_dev *hdev)
27941da177e4SLinus Torvalds {
2795e1b77d68SLuiz Augusto von Dentz int ret;
2796e1b77d68SLuiz Augusto von Dentz
2797e1b77d68SLuiz Augusto von Dentz bt_dev_dbg(hdev, "");
2798e1b77d68SLuiz Augusto von Dentz
2799e1b77d68SLuiz Augusto von Dentz /* Suspend should only act on when powered. */
2800e1b77d68SLuiz Augusto von Dentz if (!hdev_is_powered(hdev) ||
2801e1b77d68SLuiz Augusto von Dentz hci_dev_test_flag(hdev, HCI_UNREGISTER))
28021da177e4SLinus Torvalds return 0;
2803e1b77d68SLuiz Augusto von Dentz
2804182ee45dSLuiz Augusto von Dentz /* If powering down don't attempt to suspend */
2805182ee45dSLuiz Augusto von Dentz if (mgmt_powering_down(hdev))
2806182ee45dSLuiz Augusto von Dentz return 0;
2807e1b77d68SLuiz Augusto von Dentz
2808f4198635SArchie Pusaka /* Cancel potentially blocking sync operation before suspend */
28099ae3954dSLuiz Augusto von Dentz hci_cancel_cmd_sync(hdev, EHOSTDOWN);
2810f4198635SArchie Pusaka
2811182ee45dSLuiz Augusto von Dentz hci_req_sync_lock(hdev);
2812182ee45dSLuiz Augusto von Dentz ret = hci_suspend_sync(hdev);
2813182ee45dSLuiz Augusto von Dentz hci_req_sync_unlock(hdev);
28144539ca67SLuiz Augusto von Dentz
2815e1b77d68SLuiz Augusto von Dentz hci_clear_wake_reason(hdev);
2816182ee45dSLuiz Augusto von Dentz mgmt_suspending(hdev, hdev->suspend_state);
2817e1b77d68SLuiz Augusto von Dentz
2818e1b77d68SLuiz Augusto von Dentz hci_sock_dev_event(hdev, HCI_DEV_SUSPEND);
2819e1b77d68SLuiz Augusto von Dentz return ret;
28201da177e4SLinus Torvalds }
28211da177e4SLinus Torvalds EXPORT_SYMBOL(hci_suspend_dev);
28221da177e4SLinus Torvalds
hci_resume_dev(struct hci_dev * hdev)28231da177e4SLinus Torvalds /* Resume HCI device */
28241da177e4SLinus Torvalds int hci_resume_dev(struct hci_dev *hdev)
28251da177e4SLinus Torvalds {
2826e1b77d68SLuiz Augusto von Dentz int ret;
2827e1b77d68SLuiz Augusto von Dentz
2828e1b77d68SLuiz Augusto von Dentz bt_dev_dbg(hdev, "");
2829e1b77d68SLuiz Augusto von Dentz
2830e1b77d68SLuiz Augusto von Dentz /* Resume should only act on when powered. */
2831e1b77d68SLuiz Augusto von Dentz if (!hdev_is_powered(hdev) ||
2832e1b77d68SLuiz Augusto von Dentz hci_dev_test_flag(hdev, HCI_UNREGISTER))
28331da177e4SLinus Torvalds return 0;
2834e1b77d68SLuiz Augusto von Dentz
2835e1b77d68SLuiz Augusto von Dentz /* If powering down don't attempt to resume */
2836e1b77d68SLuiz Augusto von Dentz if (mgmt_powering_down(hdev))
2837e1b77d68SLuiz Augusto von Dentz return 0;
2838e1b77d68SLuiz Augusto von Dentz
2839182ee45dSLuiz Augusto von Dentz hci_req_sync_lock(hdev);
2840182ee45dSLuiz Augusto von Dentz ret = hci_resume_sync(hdev);
2841182ee45dSLuiz Augusto von Dentz hci_req_sync_unlock(hdev);
2842e1b77d68SLuiz Augusto von Dentz
2843e1b77d68SLuiz Augusto von Dentz mgmt_resuming(hdev, hdev->wake_reason, &hdev->wake_addr,
2844e1b77d68SLuiz Augusto von Dentz hdev->wake_addr_type);
2845e1b77d68SLuiz Augusto von Dentz
2846e1b77d68SLuiz Augusto von Dentz hci_sock_dev_event(hdev, HCI_DEV_RESUME);
2847e1b77d68SLuiz Augusto von Dentz return ret;
28481da177e4SLinus Torvalds }
28491da177e4SLinus Torvalds EXPORT_SYMBOL(hci_resume_dev);
28501da177e4SLinus Torvalds
hci_reset_dev(struct hci_dev * hdev)285175e0569fSMarcel Holtmann /* Reset HCI device */
285275e0569fSMarcel Holtmann int hci_reset_dev(struct hci_dev *hdev)
285375e0569fSMarcel Holtmann {
28541e4b6e91SColin Ian King static const u8 hw_err[] = { HCI_EV_HARDWARE_ERROR, 0x01, 0x00 };
285575e0569fSMarcel Holtmann struct sk_buff *skb;
285675e0569fSMarcel Holtmann
285775e0569fSMarcel Holtmann skb = bt_skb_alloc(3, GFP_ATOMIC);
285875e0569fSMarcel Holtmann if (!skb)
285975e0569fSMarcel Holtmann return -ENOMEM;
286075e0569fSMarcel Holtmann
2861d79f34e3SMarcel Holtmann hci_skb_pkt_type(skb) = HCI_EVENT_PKT;
286259ae1d12SJohannes Berg skb_put_data(skb, hw_err, 3);
286375e0569fSMarcel Holtmann
2864de75cd0dSManish Mandlik bt_dev_err(hdev, "Injecting HCI hardware error event");
2865de75cd0dSManish Mandlik
286675e0569fSMarcel Holtmann /* Send Hardware Error to upper stack */
286775e0569fSMarcel Holtmann return hci_recv_frame(hdev, skb);
286875e0569fSMarcel Holtmann }
286975e0569fSMarcel Holtmann EXPORT_SYMBOL(hci_reset_dev);
287075e0569fSMarcel Holtmann
hci_recv_frame(struct hci_dev * hdev,struct sk_buff * skb)287176bca880SMarcel Holtmann /* Receive frame from HCI drivers */
2872e1a26170SMarcel Holtmann int hci_recv_frame(struct hci_dev *hdev, struct sk_buff *skb)
287376bca880SMarcel Holtmann {
287476bca880SMarcel Holtmann if (!hdev || (!test_bit(HCI_UP, &hdev->flags)
287576bca880SMarcel Holtmann && !test_bit(HCI_INIT, &hdev->flags))) {
287676bca880SMarcel Holtmann kfree_skb(skb);
287776bca880SMarcel Holtmann return -ENXIO;
287876bca880SMarcel Holtmann }
287976bca880SMarcel Holtmann
2880876e7810SLuiz Augusto von Dentz switch (hci_skb_pkt_type(skb)) {
2881876e7810SLuiz Augusto von Dentz case HCI_EVENT_PKT:
2882876e7810SLuiz Augusto von Dentz break;
2883876e7810SLuiz Augusto von Dentz case HCI_ACLDATA_PKT:
2884876e7810SLuiz Augusto von Dentz /* Detect if ISO packet has been sent as ACL */
2885876e7810SLuiz Augusto von Dentz if (hci_conn_num(hdev, ISO_LINK)) {
2886876e7810SLuiz Augusto von Dentz __u16 handle = __le16_to_cpu(hci_acl_hdr(skb)->handle);
2887876e7810SLuiz Augusto von Dentz __u8 type;
2888876e7810SLuiz Augusto von Dentz
2889876e7810SLuiz Augusto von Dentz type = hci_conn_lookup_type(hdev, hci_handle(handle));
2890876e7810SLuiz Augusto von Dentz if (type == ISO_LINK)
2891876e7810SLuiz Augusto von Dentz hci_skb_pkt_type(skb) = HCI_ISODATA_PKT;
2892876e7810SLuiz Augusto von Dentz }
2893876e7810SLuiz Augusto von Dentz break;
2894876e7810SLuiz Augusto von Dentz case HCI_SCODATA_PKT:
2895876e7810SLuiz Augusto von Dentz break;
2896876e7810SLuiz Augusto von Dentz case HCI_ISODATA_PKT:
2897876e7810SLuiz Augusto von Dentz break;
2898876e7810SLuiz Augusto von Dentz default:
2899fe806dceSMarcel Holtmann kfree_skb(skb);
2900fe806dceSMarcel Holtmann return -EINVAL;
2901fe806dceSMarcel Holtmann }
2902fe806dceSMarcel Holtmann
2903d82603c6SJorrit Schippers /* Incoming skb */
290476bca880SMarcel Holtmann bt_cb(skb)->incoming = 1;
290576bca880SMarcel Holtmann
290676bca880SMarcel Holtmann /* Time stamp */
290776bca880SMarcel Holtmann __net_timestamp(skb);
290876bca880SMarcel Holtmann
290976bca880SMarcel Holtmann skb_queue_tail(&hdev->rx_q, skb);
2910b78752ccSMarcel Holtmann queue_work(hdev->workqueue, &hdev->rx_work);
2911c78ae283SMarcel Holtmann
291276bca880SMarcel Holtmann return 0;
291376bca880SMarcel Holtmann }
291476bca880SMarcel Holtmann EXPORT_SYMBOL(hci_recv_frame);
291576bca880SMarcel Holtmann
hci_recv_diag(struct hci_dev * hdev,struct sk_buff * skb)2916e875ff84SMarcel Holtmann /* Receive diagnostic message from HCI drivers */
2917e875ff84SMarcel Holtmann int hci_recv_diag(struct hci_dev *hdev, struct sk_buff *skb)
2918e875ff84SMarcel Holtmann {
2919581d6fd6SMarcel Holtmann /* Mark as diagnostic packet */
2920d79f34e3SMarcel Holtmann hci_skb_pkt_type(skb) = HCI_DIAG_PKT;
2921581d6fd6SMarcel Holtmann
2922e875ff84SMarcel Holtmann /* Time stamp */
2923e875ff84SMarcel Holtmann __net_timestamp(skb);
2924e875ff84SMarcel Holtmann
2925581d6fd6SMarcel Holtmann skb_queue_tail(&hdev->rx_q, skb);
2926581d6fd6SMarcel Holtmann queue_work(hdev->workqueue, &hdev->rx_work);
2927e875ff84SMarcel Holtmann
2928e875ff84SMarcel Holtmann return 0;
2929e875ff84SMarcel Holtmann }
2930e875ff84SMarcel Holtmann EXPORT_SYMBOL(hci_recv_diag);
hci_set_hw_info(struct hci_dev * hdev,const char * fmt,...)2931e875ff84SMarcel Holtmann
29325177a838SMarcel Holtmann void hci_set_hw_info(struct hci_dev *hdev, const char *fmt, ...)
29335177a838SMarcel Holtmann {
29345177a838SMarcel Holtmann va_list vargs;
29355177a838SMarcel Holtmann
29365177a838SMarcel Holtmann va_start(vargs, fmt);
29375177a838SMarcel Holtmann kfree_const(hdev->hw_info);
29385177a838SMarcel Holtmann hdev->hw_info = kvasprintf_const(GFP_KERNEL, fmt, vargs);
29395177a838SMarcel Holtmann va_end(vargs);
29405177a838SMarcel Holtmann }
29415177a838SMarcel Holtmann EXPORT_SYMBOL(hci_set_hw_info);
hci_set_fw_info(struct hci_dev * hdev,const char * fmt,...)29425177a838SMarcel Holtmann
29435177a838SMarcel Holtmann void hci_set_fw_info(struct hci_dev *hdev, const char *fmt, ...)
29445177a838SMarcel Holtmann {
29455177a838SMarcel Holtmann va_list vargs;
29465177a838SMarcel Holtmann
29475177a838SMarcel Holtmann va_start(vargs, fmt);
29485177a838SMarcel Holtmann kfree_const(hdev->fw_info);
29495177a838SMarcel Holtmann hdev->fw_info = kvasprintf_const(GFP_KERNEL, fmt, vargs);
29505177a838SMarcel Holtmann va_end(vargs);
29515177a838SMarcel Holtmann }
29525177a838SMarcel Holtmann EXPORT_SYMBOL(hci_set_fw_info);
29535177a838SMarcel Holtmann
29541da177e4SLinus Torvalds /* ---- Interface to upper protocols ---- */
hci_register_cb(struct hci_cb * cb)29551da177e4SLinus Torvalds
29561da177e4SLinus Torvalds int hci_register_cb(struct hci_cb *cb)
29571da177e4SLinus Torvalds {
29581da177e4SLinus Torvalds BT_DBG("%p name %s", cb, cb->name);
29591da177e4SLinus Torvalds
2960*5e8ce74fSLuiz Augusto von Dentz mutex_lock(&hci_cb_list_lock);
2961*5e8ce74fSLuiz Augusto von Dentz list_add_tail(&cb->list, &hci_cb_list);
2962*5e8ce74fSLuiz Augusto von Dentz mutex_unlock(&hci_cb_list_lock);
29631da177e4SLinus Torvalds
29641da177e4SLinus Torvalds return 0;
29651da177e4SLinus Torvalds }
29661da177e4SLinus Torvalds EXPORT_SYMBOL(hci_register_cb);
29671da177e4SLinus Torvalds
29681da177e4SLinus Torvalds int hci_unregister_cb(struct hci_cb *cb)
29691da177e4SLinus Torvalds {
29701da177e4SLinus Torvalds BT_DBG("%p name %s", cb, cb->name);
29711da177e4SLinus Torvalds
2972*5e8ce74fSLuiz Augusto von Dentz mutex_lock(&hci_cb_list_lock);
2973*5e8ce74fSLuiz Augusto von Dentz list_del(&cb->list);
2974*5e8ce74fSLuiz Augusto von Dentz mutex_unlock(&hci_cb_list_lock);
29751da177e4SLinus Torvalds
hci_send_frame(struct hci_dev * hdev,struct sk_buff * skb)29761da177e4SLinus Torvalds return 0;
29771da177e4SLinus Torvalds }
29781da177e4SLinus Torvalds EXPORT_SYMBOL(hci_unregister_cb);
29791da177e4SLinus Torvalds
29802250abadSBenjamin Berg static int hci_send_frame(struct hci_dev *hdev, struct sk_buff *skb)
29811da177e4SLinus Torvalds {
2982cdc52faaSMarcel Holtmann int err;
2983cdc52faaSMarcel Holtmann
2984d79f34e3SMarcel Holtmann BT_DBG("%s type %d len %d", hdev->name, hci_skb_pkt_type(skb),
2985d79f34e3SMarcel Holtmann skb->len);
29861da177e4SLinus Torvalds
29871da177e4SLinus Torvalds /* Time stamp */
2988a61bbcf2SPatrick McHardy __net_timestamp(skb);
29891da177e4SLinus Torvalds
2990cd82e61cSMarcel Holtmann /* Send copy to monitor */
2991cd82e61cSMarcel Holtmann hci_send_to_monitor(hdev, skb);
2992cd82e61cSMarcel Holtmann
2993cd82e61cSMarcel Holtmann if (atomic_read(&hdev->promisc)) {
2994cd82e61cSMarcel Holtmann /* Send copy to the sockets */
2995470fe1b5SMarcel Holtmann hci_send_to_sock(hdev, skb);
29961da177e4SLinus Torvalds }
29971da177e4SLinus Torvalds
29981da177e4SLinus Torvalds /* Get rid of skb owner, prior to sending to the driver. */
29991da177e4SLinus Torvalds skb_orphan(skb);
30001da177e4SLinus Torvalds
300173d0d3c8SMarcel Holtmann if (!test_bit(HCI_RUNNING, &hdev->flags)) {
300273d0d3c8SMarcel Holtmann kfree_skb(skb);
30032250abadSBenjamin Berg return -EINVAL;
300473d0d3c8SMarcel Holtmann }
300573d0d3c8SMarcel Holtmann
3006cdc52faaSMarcel Holtmann err = hdev->send(hdev, skb);
3007cdc52faaSMarcel Holtmann if (err < 0) {
30082064ee33SMarcel Holtmann bt_dev_err(hdev, "sending frame failed (%d)", err);
3009cdc52faaSMarcel Holtmann kfree_skb(skb);
30102250abadSBenjamin Berg return err;
3011cdc52faaSMarcel Holtmann }
30122250abadSBenjamin Berg
hci_send_cmd(struct hci_dev * hdev,__u16 opcode,__u32 plen,const void * param)30132250abadSBenjamin Berg return 0;
30141da177e4SLinus Torvalds }
30151da177e4SLinus Torvalds
30161ca3a9d0SJohan Hedberg /* Send HCI command */
301707dc93ddSJohan Hedberg int hci_send_cmd(struct hci_dev *hdev, __u16 opcode, __u32 plen,
301807dc93ddSJohan Hedberg const void *param)
30191ca3a9d0SJohan Hedberg {
30201ca3a9d0SJohan Hedberg struct sk_buff *skb;
30211ca3a9d0SJohan Hedberg
30221ca3a9d0SJohan Hedberg BT_DBG("%s opcode 0x%4.4x plen %d", hdev->name, opcode, plen);
30231ca3a9d0SJohan Hedberg
30241ca3a9d0SJohan Hedberg skb = hci_prepare_cmd(hdev, opcode, plen, param);
30251ca3a9d0SJohan Hedberg if (!skb) {
30262064ee33SMarcel Holtmann bt_dev_err(hdev, "no memory for command");
30271ca3a9d0SJohan Hedberg return -ENOMEM;
30281ca3a9d0SJohan Hedberg }
30291ca3a9d0SJohan Hedberg
303049c922bbSStephen Hemminger /* Stand-alone HCI commands must be flagged as
303111714b3dSJohan Hedberg * single-command requests.
303211714b3dSJohan Hedberg */
303344d27137SJohan Hedberg bt_cb(skb)->hci.req_flags |= HCI_REQ_START;
303411714b3dSJohan Hedberg
30351da177e4SLinus Torvalds skb_queue_tail(&hdev->cmd_q, skb);
3036c347b765SGustavo F. Padovan queue_work(hdev->workqueue, &hdev->cmd_work);
__hci_cmd_send(struct hci_dev * hdev,u16 opcode,u32 plen,const void * param)30371da177e4SLinus Torvalds
30381da177e4SLinus Torvalds return 0;
30391da177e4SLinus Torvalds }
30401da177e4SLinus Torvalds
3041d6ee6ad7SLoic Poulain int __hci_cmd_send(struct hci_dev *hdev, u16 opcode, u32 plen,
3042d6ee6ad7SLoic Poulain const void *param)
3043d6ee6ad7SLoic Poulain {
3044d6ee6ad7SLoic Poulain struct sk_buff *skb;
3045d6ee6ad7SLoic Poulain
3046d6ee6ad7SLoic Poulain if (hci_opcode_ogf(opcode) != 0x3f) {
3047d6ee6ad7SLoic Poulain /* A controller receiving a command shall respond with either
3048d6ee6ad7SLoic Poulain * a Command Status Event or a Command Complete Event.
3049d6ee6ad7SLoic Poulain * Therefore, all standard HCI commands must be sent via the
3050d6ee6ad7SLoic Poulain * standard API, using hci_send_cmd or hci_cmd_sync helpers.
3051d6ee6ad7SLoic Poulain * Some vendors do not comply with this rule for vendor-specific
3052d6ee6ad7SLoic Poulain * commands and do not return any event. We want to support
3053d6ee6ad7SLoic Poulain * unresponded commands for such cases only.
3054d6ee6ad7SLoic Poulain */
3055d6ee6ad7SLoic Poulain bt_dev_err(hdev, "unresponded command not supported");
3056d6ee6ad7SLoic Poulain return -EINVAL;
3057d6ee6ad7SLoic Poulain }
3058d6ee6ad7SLoic Poulain
3059d6ee6ad7SLoic Poulain skb = hci_prepare_cmd(hdev, opcode, plen, param);
3060d6ee6ad7SLoic Poulain if (!skb) {
3061d6ee6ad7SLoic Poulain bt_dev_err(hdev, "no memory for command (opcode 0x%4.4x)",
3062d6ee6ad7SLoic Poulain opcode);
3063d6ee6ad7SLoic Poulain return -ENOMEM;
3064d6ee6ad7SLoic Poulain }
3065d6ee6ad7SLoic Poulain
3066d6ee6ad7SLoic Poulain hci_send_frame(hdev, skb);
3067d6ee6ad7SLoic Poulain
3068d6ee6ad7SLoic Poulain return 0;
hci_cmd_data(struct sk_buff * skb,__u16 opcode)3069d6ee6ad7SLoic Poulain }
3070d6ee6ad7SLoic Poulain EXPORT_SYMBOL(__hci_cmd_send);
3071d6ee6ad7SLoic Poulain
30721da177e4SLinus Torvalds /* Get data from the previously sent command */
30732af7aa66SLuiz Augusto von Dentz static void *hci_cmd_data(struct sk_buff *skb, __u16 opcode)
30741da177e4SLinus Torvalds {
30751da177e4SLinus Torvalds struct hci_command_hdr *hdr;
30761da177e4SLinus Torvalds
30772af7aa66SLuiz Augusto von Dentz if (!skb || skb->len < HCI_COMMAND_HDR_SIZE)
30781da177e4SLinus Torvalds return NULL;
30791da177e4SLinus Torvalds
30802af7aa66SLuiz Augusto von Dentz hdr = (void *)skb->data;
30811da177e4SLinus Torvalds
3082a9de9248SMarcel Holtmann if (hdr->opcode != cpu_to_le16(opcode))
30831da177e4SLinus Torvalds return NULL;
30841da177e4SLinus Torvalds
hci_sent_cmd_data(struct hci_dev * hdev,__u16 opcode)30852af7aa66SLuiz Augusto von Dentz return skb->data + HCI_COMMAND_HDR_SIZE;
30862af7aa66SLuiz Augusto von Dentz }
30871da177e4SLinus Torvalds
30882af7aa66SLuiz Augusto von Dentz /* Get data from the previously sent command */
30892af7aa66SLuiz Augusto von Dentz void *hci_sent_cmd_data(struct hci_dev *hdev, __u16 opcode)
30902af7aa66SLuiz Augusto von Dentz {
30912af7aa66SLuiz Augusto von Dentz void *data;
30922af7aa66SLuiz Augusto von Dentz
30932af7aa66SLuiz Augusto von Dentz /* Check if opcode matches last sent command */
30942af7aa66SLuiz Augusto von Dentz data = hci_cmd_data(hdev->sent_cmd, opcode);
30952af7aa66SLuiz Augusto von Dentz if (!data)
30962af7aa66SLuiz Augusto von Dentz /* Check if opcode matches last request */
30972af7aa66SLuiz Augusto von Dentz data = hci_cmd_data(hdev->req_skb, opcode);
30982af7aa66SLuiz Augusto von Dentz
hci_recv_event_data(struct hci_dev * hdev,__u8 event)30992af7aa66SLuiz Augusto von Dentz return data;
31001da177e4SLinus Torvalds }
31011da177e4SLinus Torvalds
3102dfe6d5c3SLuiz Augusto von Dentz /* Get data from last received event */
3103dfe6d5c3SLuiz Augusto von Dentz void *hci_recv_event_data(struct hci_dev *hdev, __u8 event)
3104dfe6d5c3SLuiz Augusto von Dentz {
3105dfe6d5c3SLuiz Augusto von Dentz struct hci_event_hdr *hdr;
3106dfe6d5c3SLuiz Augusto von Dentz int offset;
3107dfe6d5c3SLuiz Augusto von Dentz
3108dfe6d5c3SLuiz Augusto von Dentz if (!hdev->recv_event)
3109dfe6d5c3SLuiz Augusto von Dentz return NULL;
3110dfe6d5c3SLuiz Augusto von Dentz
3111dfe6d5c3SLuiz Augusto von Dentz hdr = (void *)hdev->recv_event->data;
3112dfe6d5c3SLuiz Augusto von Dentz offset = sizeof(*hdr);
3113dfe6d5c3SLuiz Augusto von Dentz
3114dfe6d5c3SLuiz Augusto von Dentz if (hdr->evt != event) {
3115dfe6d5c3SLuiz Augusto von Dentz /* In case of LE metaevent check the subevent match */
3116dfe6d5c3SLuiz Augusto von Dentz if (hdr->evt == HCI_EV_LE_META) {
3117dfe6d5c3SLuiz Augusto von Dentz struct hci_ev_le_meta *ev;
3118dfe6d5c3SLuiz Augusto von Dentz
3119dfe6d5c3SLuiz Augusto von Dentz ev = (void *)hdev->recv_event->data + offset;
3120dfe6d5c3SLuiz Augusto von Dentz offset += sizeof(*ev);
3121dfe6d5c3SLuiz Augusto von Dentz if (ev->subevent == event)
3122dfe6d5c3SLuiz Augusto von Dentz goto found;
3123dfe6d5c3SLuiz Augusto von Dentz }
3124dfe6d5c3SLuiz Augusto von Dentz return NULL;
3125dfe6d5c3SLuiz Augusto von Dentz }
3126dfe6d5c3SLuiz Augusto von Dentz
3127dfe6d5c3SLuiz Augusto von Dentz found:
3128dfe6d5c3SLuiz Augusto von Dentz bt_dev_dbg(hdev, "event 0x%2.2x", event);
3129dfe6d5c3SLuiz Augusto von Dentz
hci_add_acl_hdr(struct sk_buff * skb,__u16 handle,__u16 flags)3130dfe6d5c3SLuiz Augusto von Dentz return hdev->recv_event->data + offset;
3131dfe6d5c3SLuiz Augusto von Dentz }
3132dfe6d5c3SLuiz Augusto von Dentz
31331da177e4SLinus Torvalds /* Send ACL data */
31341da177e4SLinus Torvalds static void hci_add_acl_hdr(struct sk_buff *skb, __u16 handle, __u16 flags)
31351da177e4SLinus Torvalds {
31361da177e4SLinus Torvalds struct hci_acl_hdr *hdr;
31371da177e4SLinus Torvalds int len = skb->len;
31381da177e4SLinus Torvalds
3139badff6d0SArnaldo Carvalho de Melo skb_push(skb, HCI_ACL_HDR_SIZE);
3140badff6d0SArnaldo Carvalho de Melo skb_reset_transport_header(skb);
31419c70220bSArnaldo Carvalho de Melo hdr = (struct hci_acl_hdr *)skb_transport_header(skb);
hci_queue_acl(struct hci_chan * chan,struct sk_buff_head * queue,struct sk_buff * skb,__u16 flags)3142aca3192cSYOSHIFUJI Hideaki hdr->handle = cpu_to_le16(hci_handle_pack(handle, flags));
3143aca3192cSYOSHIFUJI Hideaki hdr->dlen = cpu_to_le16(len);
31441da177e4SLinus Torvalds }
31451da177e4SLinus Torvalds
3146ee22be7eSAndrei Emeltchenko static void hci_queue_acl(struct hci_chan *chan, struct sk_buff_head *queue,
314773d80debSLuiz Augusto von Dentz struct sk_buff *skb, __u16 flags)
31481da177e4SLinus Torvalds {
3149ee22be7eSAndrei Emeltchenko struct hci_conn *conn = chan->conn;
31501da177e4SLinus Torvalds struct hci_dev *hdev = conn->hdev;
31511da177e4SLinus Torvalds struct sk_buff *list;
31521da177e4SLinus Torvalds
3153087bfd99SGustavo Padovan skb->len = skb_headlen(skb);
3154087bfd99SGustavo Padovan skb->data_len = 0;
3155087bfd99SGustavo Padovan
3156d79f34e3SMarcel Holtmann hci_skb_pkt_type(skb) = HCI_ACLDATA_PKT;
3157204a6e54SAndrei Emeltchenko
3158087bfd99SGustavo Padovan hci_add_acl_hdr(skb, conn->handle, flags);
3159087bfd99SGustavo Padovan
316070f23020SAndrei Emeltchenko list = skb_shinfo(skb)->frag_list;
316170f23020SAndrei Emeltchenko if (!list) {
31621da177e4SLinus Torvalds /* Non fragmented */
31631da177e4SLinus Torvalds BT_DBG("%s nonfrag skb %p len %d", hdev->name, skb, skb->len);
31641da177e4SLinus Torvalds
316573d80debSLuiz Augusto von Dentz skb_queue_tail(queue, skb);
31661da177e4SLinus Torvalds } else {
31671da177e4SLinus Torvalds /* Fragmented */
31681da177e4SLinus Torvalds BT_DBG("%s frag %p len %d", hdev->name, skb, skb->len);
31691da177e4SLinus Torvalds
31701da177e4SLinus Torvalds skb_shinfo(skb)->frag_list = NULL;
31711da177e4SLinus Torvalds
31729cfd5a23SJukka Rissanen /* Queue all fragments atomically. We need to use spin_lock_bh
31739cfd5a23SJukka Rissanen * here because of 6LoWPAN links, as there this function is
31749cfd5a23SJukka Rissanen * called from softirq and using normal spin lock could cause
31759cfd5a23SJukka Rissanen * deadlocks.
31769cfd5a23SJukka Rissanen */
31779cfd5a23SJukka Rissanen spin_lock_bh(&queue->lock);
31781da177e4SLinus Torvalds
317973d80debSLuiz Augusto von Dentz __skb_queue_tail(queue, skb);
3180e702112fSAndrei Emeltchenko
3181e702112fSAndrei Emeltchenko flags &= ~ACL_START;
3182e702112fSAndrei Emeltchenko flags |= ACL_CONT;
31831da177e4SLinus Torvalds do {
31841da177e4SLinus Torvalds skb = list; list = list->next;
31851da177e4SLinus Torvalds
3186d79f34e3SMarcel Holtmann hci_skb_pkt_type(skb) = HCI_ACLDATA_PKT;
3187e702112fSAndrei Emeltchenko hci_add_acl_hdr(skb, conn->handle, flags);
31881da177e4SLinus Torvalds
31891da177e4SLinus Torvalds BT_DBG("%s frag %p len %d", hdev->name, skb, skb->len);
31901da177e4SLinus Torvalds
319173d80debSLuiz Augusto von Dentz __skb_queue_tail(queue, skb);
31921da177e4SLinus Torvalds } while (list);
31931da177e4SLinus Torvalds
hci_send_acl(struct hci_chan * chan,struct sk_buff * skb,__u16 flags)31949cfd5a23SJukka Rissanen spin_unlock_bh(&queue->lock);
31951da177e4SLinus Torvalds }
319673d80debSLuiz Augusto von Dentz }
319773d80debSLuiz Augusto von Dentz
319873d80debSLuiz Augusto von Dentz void hci_send_acl(struct hci_chan *chan, struct sk_buff *skb, __u16 flags)
319973d80debSLuiz Augusto von Dentz {
3200ee22be7eSAndrei Emeltchenko struct hci_dev *hdev = chan->conn->hdev;
320173d80debSLuiz Augusto von Dentz
3202f0e09510SAndrei Emeltchenko BT_DBG("%s chan %p flags 0x%4.4x", hdev->name, chan, flags);
320373d80debSLuiz Augusto von Dentz
3204ee22be7eSAndrei Emeltchenko hci_queue_acl(chan, &chan->data_q, skb, flags);
32051da177e4SLinus Torvalds
hci_send_sco(struct hci_conn * conn,struct sk_buff * skb)32063eff45eaSGustavo F. Padovan queue_work(hdev->workqueue, &hdev->tx_work);
32071da177e4SLinus Torvalds }
32081da177e4SLinus Torvalds
32091da177e4SLinus Torvalds /* Send SCO data */
32100d861d8bSGustavo F. Padovan void hci_send_sco(struct hci_conn *conn, struct sk_buff *skb)
32111da177e4SLinus Torvalds {
32121da177e4SLinus Torvalds struct hci_dev *hdev = conn->hdev;
32131da177e4SLinus Torvalds struct hci_sco_hdr hdr;
32141da177e4SLinus Torvalds
32151da177e4SLinus Torvalds BT_DBG("%s len %d", hdev->name, skb->len);
32161da177e4SLinus Torvalds
3217aca3192cSYOSHIFUJI Hideaki hdr.handle = cpu_to_le16(conn->handle);
32181da177e4SLinus Torvalds hdr.dlen = skb->len;
32191da177e4SLinus Torvalds
3220badff6d0SArnaldo Carvalho de Melo skb_push(skb, HCI_SCO_HDR_SIZE);
3221badff6d0SArnaldo Carvalho de Melo skb_reset_transport_header(skb);
32229c70220bSArnaldo Carvalho de Melo memcpy(skb_transport_header(skb), &hdr, HCI_SCO_HDR_SIZE);
32231da177e4SLinus Torvalds
3224d79f34e3SMarcel Holtmann hci_skb_pkt_type(skb) = HCI_SCODATA_PKT;
3225c78ae283SMarcel Holtmann
32261da177e4SLinus Torvalds skb_queue_tail(&conn->data_q, skb);
hci_add_iso_hdr(struct sk_buff * skb,__u16 handle,__u8 flags)32273eff45eaSGustavo F. Padovan queue_work(hdev->workqueue, &hdev->tx_work);
32281da177e4SLinus Torvalds }
32291da177e4SLinus Torvalds
323026afbd82SLuiz Augusto von Dentz /* Send ISO data */
323126afbd82SLuiz Augusto von Dentz static void hci_add_iso_hdr(struct sk_buff *skb, __u16 handle, __u8 flags)
323226afbd82SLuiz Augusto von Dentz {
323326afbd82SLuiz Augusto von Dentz struct hci_iso_hdr *hdr;
323426afbd82SLuiz Augusto von Dentz int len = skb->len;
323526afbd82SLuiz Augusto von Dentz
323626afbd82SLuiz Augusto von Dentz skb_push(skb, HCI_ISO_HDR_SIZE);
323726afbd82SLuiz Augusto von Dentz skb_reset_transport_header(skb);
323826afbd82SLuiz Augusto von Dentz hdr = (struct hci_iso_hdr *)skb_transport_header(skb);
hci_queue_iso(struct hci_conn * conn,struct sk_buff_head * queue,struct sk_buff * skb)323926afbd82SLuiz Augusto von Dentz hdr->handle = cpu_to_le16(hci_handle_pack(handle, flags));
324026afbd82SLuiz Augusto von Dentz hdr->dlen = cpu_to_le16(len);
324126afbd82SLuiz Augusto von Dentz }
324226afbd82SLuiz Augusto von Dentz
324326afbd82SLuiz Augusto von Dentz static void hci_queue_iso(struct hci_conn *conn, struct sk_buff_head *queue,
324426afbd82SLuiz Augusto von Dentz struct sk_buff *skb)
324526afbd82SLuiz Augusto von Dentz {
324626afbd82SLuiz Augusto von Dentz struct hci_dev *hdev = conn->hdev;
324726afbd82SLuiz Augusto von Dentz struct sk_buff *list;
324826afbd82SLuiz Augusto von Dentz __u16 flags;
324926afbd82SLuiz Augusto von Dentz
325026afbd82SLuiz Augusto von Dentz skb->len = skb_headlen(skb);
325126afbd82SLuiz Augusto von Dentz skb->data_len = 0;
325226afbd82SLuiz Augusto von Dentz
325326afbd82SLuiz Augusto von Dentz hci_skb_pkt_type(skb) = HCI_ISODATA_PKT;
325426afbd82SLuiz Augusto von Dentz
325526afbd82SLuiz Augusto von Dentz list = skb_shinfo(skb)->frag_list;
325626afbd82SLuiz Augusto von Dentz
325726afbd82SLuiz Augusto von Dentz flags = hci_iso_flags_pack(list ? ISO_START : ISO_SINGLE, 0x00);
325826afbd82SLuiz Augusto von Dentz hci_add_iso_hdr(skb, conn->handle, flags);
325926afbd82SLuiz Augusto von Dentz
326026afbd82SLuiz Augusto von Dentz if (!list) {
326126afbd82SLuiz Augusto von Dentz /* Non fragmented */
326226afbd82SLuiz Augusto von Dentz BT_DBG("%s nonfrag skb %p len %d", hdev->name, skb, skb->len);
326326afbd82SLuiz Augusto von Dentz
326426afbd82SLuiz Augusto von Dentz skb_queue_tail(queue, skb);
326526afbd82SLuiz Augusto von Dentz } else {
326626afbd82SLuiz Augusto von Dentz /* Fragmented */
326726afbd82SLuiz Augusto von Dentz BT_DBG("%s frag %p len %d", hdev->name, skb, skb->len);
326826afbd82SLuiz Augusto von Dentz
326926afbd82SLuiz Augusto von Dentz skb_shinfo(skb)->frag_list = NULL;
327026afbd82SLuiz Augusto von Dentz
327126afbd82SLuiz Augusto von Dentz __skb_queue_tail(queue, skb);
327226afbd82SLuiz Augusto von Dentz
327326afbd82SLuiz Augusto von Dentz do {
327426afbd82SLuiz Augusto von Dentz skb = list; list = list->next;
327526afbd82SLuiz Augusto von Dentz
327626afbd82SLuiz Augusto von Dentz hci_skb_pkt_type(skb) = HCI_ISODATA_PKT;
327726afbd82SLuiz Augusto von Dentz flags = hci_iso_flags_pack(list ? ISO_CONT : ISO_END,
327826afbd82SLuiz Augusto von Dentz 0x00);
327926afbd82SLuiz Augusto von Dentz hci_add_iso_hdr(skb, conn->handle, flags);
328026afbd82SLuiz Augusto von Dentz
328126afbd82SLuiz Augusto von Dentz BT_DBG("%s frag %p len %d", hdev->name, skb, skb->len);
328226afbd82SLuiz Augusto von Dentz
328326afbd82SLuiz Augusto von Dentz __skb_queue_tail(queue, skb);
hci_send_iso(struct hci_conn * conn,struct sk_buff * skb)328426afbd82SLuiz Augusto von Dentz } while (list);
328526afbd82SLuiz Augusto von Dentz }
328626afbd82SLuiz Augusto von Dentz }
328726afbd82SLuiz Augusto von Dentz
328826afbd82SLuiz Augusto von Dentz void hci_send_iso(struct hci_conn *conn, struct sk_buff *skb)
328926afbd82SLuiz Augusto von Dentz {
329026afbd82SLuiz Augusto von Dentz struct hci_dev *hdev = conn->hdev;
329126afbd82SLuiz Augusto von Dentz
329226afbd82SLuiz Augusto von Dentz BT_DBG("%s len %d", hdev->name, skb->len);
329326afbd82SLuiz Augusto von Dentz
329426afbd82SLuiz Augusto von Dentz hci_queue_iso(conn, &conn->data_q, skb);
329526afbd82SLuiz Augusto von Dentz
329626afbd82SLuiz Augusto von Dentz queue_work(hdev->workqueue, &hdev->tx_work);
329726afbd82SLuiz Augusto von Dentz }
hci_quote_sent(struct hci_conn * conn,int num,int * quote)329826afbd82SLuiz Augusto von Dentz
32991da177e4SLinus Torvalds /* ---- HCI TX task (outgoing data) ---- */
33001da177e4SLinus Torvalds
33011da177e4SLinus Torvalds /* HCI Connection scheduler */
330226afbd82SLuiz Augusto von Dentz static inline void hci_quote_sent(struct hci_conn *conn, int num, int *quote)
330326afbd82SLuiz Augusto von Dentz {
330426afbd82SLuiz Augusto von Dentz struct hci_dev *hdev;
330526afbd82SLuiz Augusto von Dentz int cnt, q;
330626afbd82SLuiz Augusto von Dentz
330726afbd82SLuiz Augusto von Dentz if (!conn) {
330826afbd82SLuiz Augusto von Dentz *quote = 0;
330926afbd82SLuiz Augusto von Dentz return;
331026afbd82SLuiz Augusto von Dentz }
331126afbd82SLuiz Augusto von Dentz
331226afbd82SLuiz Augusto von Dentz hdev = conn->hdev;
331326afbd82SLuiz Augusto von Dentz
331426afbd82SLuiz Augusto von Dentz switch (conn->type) {
331526afbd82SLuiz Augusto von Dentz case ACL_LINK:
331626afbd82SLuiz Augusto von Dentz cnt = hdev->acl_cnt;
331726afbd82SLuiz Augusto von Dentz break;
331826afbd82SLuiz Augusto von Dentz case SCO_LINK:
331926afbd82SLuiz Augusto von Dentz case ESCO_LINK:
332026afbd82SLuiz Augusto von Dentz cnt = hdev->sco_cnt;
332126afbd82SLuiz Augusto von Dentz break;
332226afbd82SLuiz Augusto von Dentz case LE_LINK:
332326afbd82SLuiz Augusto von Dentz cnt = hdev->le_mtu ? hdev->le_cnt : hdev->acl_cnt;
332426afbd82SLuiz Augusto von Dentz break;
332526afbd82SLuiz Augusto von Dentz case ISO_LINK:
332626afbd82SLuiz Augusto von Dentz cnt = hdev->iso_mtu ? hdev->iso_cnt :
332726afbd82SLuiz Augusto von Dentz hdev->le_mtu ? hdev->le_cnt : hdev->acl_cnt;
332826afbd82SLuiz Augusto von Dentz break;
332926afbd82SLuiz Augusto von Dentz default:
333026afbd82SLuiz Augusto von Dentz cnt = 0;
333126afbd82SLuiz Augusto von Dentz bt_dev_err(hdev, "unknown link type %d", conn->type);
333226afbd82SLuiz Augusto von Dentz }
333326afbd82SLuiz Augusto von Dentz
333426afbd82SLuiz Augusto von Dentz q = cnt / num;
333526afbd82SLuiz Augusto von Dentz *quote = q ? q : 1;
333626afbd82SLuiz Augusto von Dentz }
333726afbd82SLuiz Augusto von Dentz
33386039aa73SGustavo Padovan static struct hci_conn *hci_low_sent(struct hci_dev *hdev, __u8 type,
3339a8c5fb1aSGustavo Padovan int *quote)
33401da177e4SLinus Torvalds {
33411da177e4SLinus Torvalds struct hci_conn_hash *h = &hdev->conn_hash;
33428035ded4SLuiz Augusto von Dentz struct hci_conn *conn = NULL, *c;
3343abc5de8fSMikel Astiz unsigned int num = 0, min = ~0;
33441da177e4SLinus Torvalds
33451da177e4SLinus Torvalds /* We don't have to lock device here. Connections are always
33461da177e4SLinus Torvalds * added and removed with TX task disabled. */
3347bf4c6325SGustavo F. Padovan
3348bf4c6325SGustavo F. Padovan rcu_read_lock();
3349bf4c6325SGustavo F. Padovan
3350bf4c6325SGustavo F. Padovan list_for_each_entry_rcu(c, &h->list, list) {
3351769be974SMarcel Holtmann if (c->type != type || skb_queue_empty(&c->data_q))
33521da177e4SLinus Torvalds continue;
3353769be974SMarcel Holtmann
3354769be974SMarcel Holtmann if (c->state != BT_CONNECTED && c->state != BT_CONFIG)
3355769be974SMarcel Holtmann continue;
3356769be974SMarcel Holtmann
33571da177e4SLinus Torvalds num++;
33581da177e4SLinus Torvalds
33591da177e4SLinus Torvalds if (c->sent < min) {
33601da177e4SLinus Torvalds min = c->sent;
33611da177e4SLinus Torvalds conn = c;
33621da177e4SLinus Torvalds }
336352087a79SLuiz Augusto von Dentz
336452087a79SLuiz Augusto von Dentz if (hci_conn_num(hdev, type) == num)
336552087a79SLuiz Augusto von Dentz break;
33661da177e4SLinus Torvalds }
33671da177e4SLinus Torvalds
3368bf4c6325SGustavo F. Padovan rcu_read_unlock();
3369bf4c6325SGustavo F. Padovan
337026afbd82SLuiz Augusto von Dentz hci_quote_sent(conn, num, quote);
33711da177e4SLinus Torvalds
hci_link_tx_to(struct hci_dev * hdev,__u8 type)33721da177e4SLinus Torvalds BT_DBG("conn %p quote %d", conn, *quote);
33731da177e4SLinus Torvalds return conn;
33741da177e4SLinus Torvalds }
33751da177e4SLinus Torvalds
33766039aa73SGustavo Padovan static void hci_link_tx_to(struct hci_dev *hdev, __u8 type)
33771da177e4SLinus Torvalds {
33781da177e4SLinus Torvalds struct hci_conn_hash *h = &hdev->conn_hash;
33791da177e4SLinus Torvalds struct hci_conn *c;
33801da177e4SLinus Torvalds
33812064ee33SMarcel Holtmann bt_dev_err(hdev, "link tx timeout");
33821da177e4SLinus Torvalds
3383bf4c6325SGustavo F. Padovan rcu_read_lock();
3384bf4c6325SGustavo F. Padovan
33851da177e4SLinus Torvalds /* Kill stalled connections */
3386bf4c6325SGustavo F. Padovan list_for_each_entry_rcu(c, &h->list, list) {
3387bae1f5d9SVille Tervo if (c->type == type && c->sent) {
33882064ee33SMarcel Holtmann bt_dev_err(hdev, "killing stalled connection %pMR",
33892064ee33SMarcel Holtmann &c->dst);
3390c7eaf80bSYing Hsu /* hci_disconnect might sleep, so, we have to release
3391c7eaf80bSYing Hsu * the RCU read lock before calling it.
3392c7eaf80bSYing Hsu */
3393c7eaf80bSYing Hsu rcu_read_unlock();
3394bed71748SAndre Guedes hci_disconnect(c, HCI_ERROR_REMOTE_USER_TERM);
3395c7eaf80bSYing Hsu rcu_read_lock();
33961da177e4SLinus Torvalds }
33971da177e4SLinus Torvalds }
hci_chan_sent(struct hci_dev * hdev,__u8 type,int * quote)3398bf4c6325SGustavo F. Padovan
3399bf4c6325SGustavo F. Padovan rcu_read_unlock();
34001da177e4SLinus Torvalds }
34011da177e4SLinus Torvalds
34026039aa73SGustavo Padovan static struct hci_chan *hci_chan_sent(struct hci_dev *hdev, __u8 type,
340373d80debSLuiz Augusto von Dentz int *quote)
340473d80debSLuiz Augusto von Dentz {
340573d80debSLuiz Augusto von Dentz struct hci_conn_hash *h = &hdev->conn_hash;
340673d80debSLuiz Augusto von Dentz struct hci_chan *chan = NULL;
3407abc5de8fSMikel Astiz unsigned int num = 0, min = ~0, cur_prio = 0;
340873d80debSLuiz Augusto von Dentz struct hci_conn *conn;
340926afbd82SLuiz Augusto von Dentz int conn_num = 0;
341073d80debSLuiz Augusto von Dentz
341173d80debSLuiz Augusto von Dentz BT_DBG("%s", hdev->name);
341273d80debSLuiz Augusto von Dentz
3413bf4c6325SGustavo F. Padovan rcu_read_lock();
3414bf4c6325SGustavo F. Padovan
3415bf4c6325SGustavo F. Padovan list_for_each_entry_rcu(conn, &h->list, list) {
341673d80debSLuiz Augusto von Dentz struct hci_chan *tmp;
341773d80debSLuiz Augusto von Dentz
341873d80debSLuiz Augusto von Dentz if (conn->type != type)
341973d80debSLuiz Augusto von Dentz continue;
342073d80debSLuiz Augusto von Dentz
342173d80debSLuiz Augusto von Dentz if (conn->state != BT_CONNECTED && conn->state != BT_CONFIG)
342273d80debSLuiz Augusto von Dentz continue;
342373d80debSLuiz Augusto von Dentz
342473d80debSLuiz Augusto von Dentz conn_num++;
342573d80debSLuiz Augusto von Dentz
34268192edefSGustavo F. Padovan list_for_each_entry_rcu(tmp, &conn->chan_list, list) {
342773d80debSLuiz Augusto von Dentz struct sk_buff *skb;
342873d80debSLuiz Augusto von Dentz
342973d80debSLuiz Augusto von Dentz if (skb_queue_empty(&tmp->data_q))
343073d80debSLuiz Augusto von Dentz continue;
343173d80debSLuiz Augusto von Dentz
343273d80debSLuiz Augusto von Dentz skb = skb_peek(&tmp->data_q);
343373d80debSLuiz Augusto von Dentz if (skb->priority < cur_prio)
343473d80debSLuiz Augusto von Dentz continue;
343573d80debSLuiz Augusto von Dentz
343673d80debSLuiz Augusto von Dentz if (skb->priority > cur_prio) {
343773d80debSLuiz Augusto von Dentz num = 0;
343873d80debSLuiz Augusto von Dentz min = ~0;
343973d80debSLuiz Augusto von Dentz cur_prio = skb->priority;
344073d80debSLuiz Augusto von Dentz }
344173d80debSLuiz Augusto von Dentz
344273d80debSLuiz Augusto von Dentz num++;
344373d80debSLuiz Augusto von Dentz
344473d80debSLuiz Augusto von Dentz if (conn->sent < min) {
344573d80debSLuiz Augusto von Dentz min = conn->sent;
344673d80debSLuiz Augusto von Dentz chan = tmp;
344773d80debSLuiz Augusto von Dentz }
344873d80debSLuiz Augusto von Dentz }
344973d80debSLuiz Augusto von Dentz
345073d80debSLuiz Augusto von Dentz if (hci_conn_num(hdev, type) == conn_num)
345173d80debSLuiz Augusto von Dentz break;
345273d80debSLuiz Augusto von Dentz }
345373d80debSLuiz Augusto von Dentz
3454bf4c6325SGustavo F. Padovan rcu_read_unlock();
3455bf4c6325SGustavo F. Padovan
345673d80debSLuiz Augusto von Dentz if (!chan)
345773d80debSLuiz Augusto von Dentz return NULL;
345873d80debSLuiz Augusto von Dentz
345926afbd82SLuiz Augusto von Dentz hci_quote_sent(chan->conn, num, quote);
346073d80debSLuiz Augusto von Dentz
hci_prio_recalculate(struct hci_dev * hdev,__u8 type)346173d80debSLuiz Augusto von Dentz BT_DBG("chan %p quote %d", chan, *quote);
346273d80debSLuiz Augusto von Dentz return chan;
346373d80debSLuiz Augusto von Dentz }
346473d80debSLuiz Augusto von Dentz
346502b20f0bSLuiz Augusto von Dentz static void hci_prio_recalculate(struct hci_dev *hdev, __u8 type)
346602b20f0bSLuiz Augusto von Dentz {
346702b20f0bSLuiz Augusto von Dentz struct hci_conn_hash *h = &hdev->conn_hash;
346802b20f0bSLuiz Augusto von Dentz struct hci_conn *conn;
346902b20f0bSLuiz Augusto von Dentz int num = 0;
347002b20f0bSLuiz Augusto von Dentz
347102b20f0bSLuiz Augusto von Dentz BT_DBG("%s", hdev->name);
347202b20f0bSLuiz Augusto von Dentz
3473bf4c6325SGustavo F. Padovan rcu_read_lock();
3474bf4c6325SGustavo F. Padovan
3475bf4c6325SGustavo F. Padovan list_for_each_entry_rcu(conn, &h->list, list) {
347602b20f0bSLuiz Augusto von Dentz struct hci_chan *chan;
347702b20f0bSLuiz Augusto von Dentz
347802b20f0bSLuiz Augusto von Dentz if (conn->type != type)
347902b20f0bSLuiz Augusto von Dentz continue;
348002b20f0bSLuiz Augusto von Dentz
348102b20f0bSLuiz Augusto von Dentz if (conn->state != BT_CONNECTED && conn->state != BT_CONFIG)
348202b20f0bSLuiz Augusto von Dentz continue;
348302b20f0bSLuiz Augusto von Dentz
348402b20f0bSLuiz Augusto von Dentz num++;
348502b20f0bSLuiz Augusto von Dentz
34868192edefSGustavo F. Padovan list_for_each_entry_rcu(chan, &conn->chan_list, list) {
348702b20f0bSLuiz Augusto von Dentz struct sk_buff *skb;
348802b20f0bSLuiz Augusto von Dentz
348902b20f0bSLuiz Augusto von Dentz if (chan->sent) {
349002b20f0bSLuiz Augusto von Dentz chan->sent = 0;
349102b20f0bSLuiz Augusto von Dentz continue;
349202b20f0bSLuiz Augusto von Dentz }
349302b20f0bSLuiz Augusto von Dentz
349402b20f0bSLuiz Augusto von Dentz if (skb_queue_empty(&chan->data_q))
349502b20f0bSLuiz Augusto von Dentz continue;
349602b20f0bSLuiz Augusto von Dentz
349702b20f0bSLuiz Augusto von Dentz skb = skb_peek(&chan->data_q);
349802b20f0bSLuiz Augusto von Dentz if (skb->priority >= HCI_PRIO_MAX - 1)
349902b20f0bSLuiz Augusto von Dentz continue;
350002b20f0bSLuiz Augusto von Dentz
350102b20f0bSLuiz Augusto von Dentz skb->priority = HCI_PRIO_MAX - 1;
350202b20f0bSLuiz Augusto von Dentz
350302b20f0bSLuiz Augusto von Dentz BT_DBG("chan %p skb %p promoted to %d", chan, skb,
350402b20f0bSLuiz Augusto von Dentz skb->priority);
350502b20f0bSLuiz Augusto von Dentz }
350602b20f0bSLuiz Augusto von Dentz
350702b20f0bSLuiz Augusto von Dentz if (hci_conn_num(hdev, type) == num)
350802b20f0bSLuiz Augusto von Dentz break;
350902b20f0bSLuiz Augusto von Dentz }
3510bf4c6325SGustavo F. Padovan
__check_timeout(struct hci_dev * hdev,unsigned int cnt,u8 type)3511bf4c6325SGustavo F. Padovan rcu_read_unlock();
3512bf4c6325SGustavo F. Padovan
351302b20f0bSLuiz Augusto von Dentz }
351402b20f0bSLuiz Augusto von Dentz
3515116523c8SLuiz Augusto von Dentz static void __check_timeout(struct hci_dev *hdev, unsigned int cnt, u8 type)
35161da177e4SLinus Torvalds {
3517116523c8SLuiz Augusto von Dentz unsigned long last_tx;
3518116523c8SLuiz Augusto von Dentz
3519116523c8SLuiz Augusto von Dentz if (hci_dev_test_flag(hdev, HCI_UNCONFIGURED))
3520116523c8SLuiz Augusto von Dentz return;
3521116523c8SLuiz Augusto von Dentz
3522116523c8SLuiz Augusto von Dentz switch (type) {
3523116523c8SLuiz Augusto von Dentz case LE_LINK:
3524116523c8SLuiz Augusto von Dentz last_tx = hdev->le_last_tx;
3525116523c8SLuiz Augusto von Dentz break;
3526116523c8SLuiz Augusto von Dentz default:
3527116523c8SLuiz Augusto von Dentz last_tx = hdev->acl_last_tx;
3528116523c8SLuiz Augusto von Dentz break;
35291da177e4SLinus Torvalds }
3530116523c8SLuiz Augusto von Dentz
3531116523c8SLuiz Augusto von Dentz /* tx timeout must be longer than maximum link supervision timeout
3532116523c8SLuiz Augusto von Dentz * (40.9 seconds)
3533116523c8SLuiz Augusto von Dentz */
3534116523c8SLuiz Augusto von Dentz if (!cnt && time_after(jiffies, last_tx + HCI_ACL_TX_TIMEOUT))
hci_sched_sco(struct hci_dev * hdev)3535116523c8SLuiz Augusto von Dentz hci_link_tx_to(hdev, type);
353663d2bc1bSAndrei Emeltchenko }
35371da177e4SLinus Torvalds
35387fedd3bbSAbhishek Pandit-Subedi /* Schedule SCO */
35397fedd3bbSAbhishek Pandit-Subedi static void hci_sched_sco(struct hci_dev *hdev)
35407fedd3bbSAbhishek Pandit-Subedi {
35417fedd3bbSAbhishek Pandit-Subedi struct hci_conn *conn;
35427fedd3bbSAbhishek Pandit-Subedi struct sk_buff *skb;
35437fedd3bbSAbhishek Pandit-Subedi int quote;
35447fedd3bbSAbhishek Pandit-Subedi
35457fedd3bbSAbhishek Pandit-Subedi BT_DBG("%s", hdev->name);
35467fedd3bbSAbhishek Pandit-Subedi
35477fedd3bbSAbhishek Pandit-Subedi if (!hci_conn_num(hdev, SCO_LINK))
35487fedd3bbSAbhishek Pandit-Subedi return;
35497fedd3bbSAbhishek Pandit-Subedi
35507fedd3bbSAbhishek Pandit-Subedi while (hdev->sco_cnt && (conn = hci_low_sent(hdev, SCO_LINK, "e))) {
35517fedd3bbSAbhishek Pandit-Subedi while (quote-- && (skb = skb_dequeue(&conn->data_q))) {
35527fedd3bbSAbhishek Pandit-Subedi BT_DBG("skb %p len %d", skb, skb->len);
35537fedd3bbSAbhishek Pandit-Subedi hci_send_frame(hdev, skb);
35547fedd3bbSAbhishek Pandit-Subedi
35557fedd3bbSAbhishek Pandit-Subedi conn->sent++;
35567fedd3bbSAbhishek Pandit-Subedi if (conn->sent == ~0)
35577fedd3bbSAbhishek Pandit-Subedi conn->sent = 0;
hci_sched_esco(struct hci_dev * hdev)35587fedd3bbSAbhishek Pandit-Subedi }
35597fedd3bbSAbhishek Pandit-Subedi }
35607fedd3bbSAbhishek Pandit-Subedi }
35617fedd3bbSAbhishek Pandit-Subedi
35627fedd3bbSAbhishek Pandit-Subedi static void hci_sched_esco(struct hci_dev *hdev)
35637fedd3bbSAbhishek Pandit-Subedi {
35647fedd3bbSAbhishek Pandit-Subedi struct hci_conn *conn;
35657fedd3bbSAbhishek Pandit-Subedi struct sk_buff *skb;
35667fedd3bbSAbhishek Pandit-Subedi int quote;
35677fedd3bbSAbhishek Pandit-Subedi
35687fedd3bbSAbhishek Pandit-Subedi BT_DBG("%s", hdev->name);
35697fedd3bbSAbhishek Pandit-Subedi
35707fedd3bbSAbhishek Pandit-Subedi if (!hci_conn_num(hdev, ESCO_LINK))
35717fedd3bbSAbhishek Pandit-Subedi return;
35727fedd3bbSAbhishek Pandit-Subedi
35737fedd3bbSAbhishek Pandit-Subedi while (hdev->sco_cnt && (conn = hci_low_sent(hdev, ESCO_LINK,
35747fedd3bbSAbhishek Pandit-Subedi "e))) {
35757fedd3bbSAbhishek Pandit-Subedi while (quote-- && (skb = skb_dequeue(&conn->data_q))) {
35767fedd3bbSAbhishek Pandit-Subedi BT_DBG("skb %p len %d", skb, skb->len);
35777fedd3bbSAbhishek Pandit-Subedi hci_send_frame(hdev, skb);
35787fedd3bbSAbhishek Pandit-Subedi
35797fedd3bbSAbhishek Pandit-Subedi conn->sent++;
35807fedd3bbSAbhishek Pandit-Subedi if (conn->sent == ~0)
35817fedd3bbSAbhishek Pandit-Subedi conn->sent = 0;
35827fedd3bbSAbhishek Pandit-Subedi }
35837fedd3bbSAbhishek Pandit-Subedi }
35847fedd3bbSAbhishek Pandit-Subedi }
35857fedd3bbSAbhishek Pandit-Subedi
35866039aa73SGustavo Padovan static void hci_sched_acl_pkt(struct hci_dev *hdev)
358763d2bc1bSAndrei Emeltchenko {
358863d2bc1bSAndrei Emeltchenko unsigned int cnt = hdev->acl_cnt;
358963d2bc1bSAndrei Emeltchenko struct hci_chan *chan;
359063d2bc1bSAndrei Emeltchenko struct sk_buff *skb;
359163d2bc1bSAndrei Emeltchenko int quote;
359263d2bc1bSAndrei Emeltchenko
3593116523c8SLuiz Augusto von Dentz __check_timeout(hdev, cnt, ACL_LINK);
359404837f64SMarcel Holtmann
359573d80debSLuiz Augusto von Dentz while (hdev->acl_cnt &&
359673d80debSLuiz Augusto von Dentz (chan = hci_chan_sent(hdev, ACL_LINK, "e))) {
3597ec1cce24SLuiz Augusto von Dentz u32 priority = (skb_peek(&chan->data_q))->priority;
3598ec1cce24SLuiz Augusto von Dentz while (quote-- && (skb = skb_peek(&chan->data_q))) {
359973d80debSLuiz Augusto von Dentz BT_DBG("chan %p skb %p len %d priority %u", chan, skb,
360073d80debSLuiz Augusto von Dentz skb->len, skb->priority);
360173d80debSLuiz Augusto von Dentz
3602ec1cce24SLuiz Augusto von Dentz /* Stop if priority has changed */
3603ec1cce24SLuiz Augusto von Dentz if (skb->priority < priority)
3604ec1cce24SLuiz Augusto von Dentz break;
3605ec1cce24SLuiz Augusto von Dentz
3606ec1cce24SLuiz Augusto von Dentz skb = skb_dequeue(&chan->data_q);
3607ec1cce24SLuiz Augusto von Dentz
360873d80debSLuiz Augusto von Dentz hci_conn_enter_active_mode(chan->conn,
360973d80debSLuiz Augusto von Dentz bt_cb(skb)->force_active);
361004837f64SMarcel Holtmann
361157d17d70SMarcel Holtmann hci_send_frame(hdev, skb);
36121da177e4SLinus Torvalds hdev->acl_last_tx = jiffies;
36131da177e4SLinus Torvalds
36141da177e4SLinus Torvalds hdev->acl_cnt--;
361573d80debSLuiz Augusto von Dentz chan->sent++;
361673d80debSLuiz Augusto von Dentz chan->conn->sent++;
36177fedd3bbSAbhishek Pandit-Subedi
36187fedd3bbSAbhishek Pandit-Subedi /* Send pending SCO packets right away */
36197fedd3bbSAbhishek Pandit-Subedi hci_sched_sco(hdev);
36207fedd3bbSAbhishek Pandit-Subedi hci_sched_esco(hdev);
36211da177e4SLinus Torvalds }
36221da177e4SLinus Torvalds }
362302b20f0bSLuiz Augusto von Dentz
hci_sched_acl(struct hci_dev * hdev)362402b20f0bSLuiz Augusto von Dentz if (cnt != hdev->acl_cnt)
362502b20f0bSLuiz Augusto von Dentz hci_prio_recalculate(hdev, ACL_LINK);
36261da177e4SLinus Torvalds }
36271da177e4SLinus Torvalds
36286039aa73SGustavo Padovan static void hci_sched_acl(struct hci_dev *hdev)
3629b71d385aSAndrei Emeltchenko {
3630b71d385aSAndrei Emeltchenko BT_DBG("%s", hdev->name);
3631b71d385aSAndrei Emeltchenko
3632bd1eb66bSAndrei Emeltchenko /* No ACL link over BR/EDR controller */
36335af2e235SLuiz Augusto von Dentz if (!hci_conn_num(hdev, ACL_LINK))
3634bd1eb66bSAndrei Emeltchenko return;
hci_sched_le(struct hci_dev * hdev)3635bd1eb66bSAndrei Emeltchenko
3636b71d385aSAndrei Emeltchenko hci_sched_acl_pkt(hdev);
3637b71d385aSAndrei Emeltchenko }
3638b71d385aSAndrei Emeltchenko
36396039aa73SGustavo Padovan static void hci_sched_le(struct hci_dev *hdev)
36406ed58ec5SVille Tervo {
364173d80debSLuiz Augusto von Dentz struct hci_chan *chan;
36426ed58ec5SVille Tervo struct sk_buff *skb;
364350ce4911SLuiz Augusto von Dentz int quote, *cnt, tmp;
36446ed58ec5SVille Tervo
36456ed58ec5SVille Tervo BT_DBG("%s", hdev->name);
36466ed58ec5SVille Tervo
364752087a79SLuiz Augusto von Dentz if (!hci_conn_num(hdev, LE_LINK))
364852087a79SLuiz Augusto von Dentz return;
364952087a79SLuiz Augusto von Dentz
365050ce4911SLuiz Augusto von Dentz cnt = hdev->le_pkts ? &hdev->le_cnt : &hdev->acl_cnt;
36511b1d29e5SLuiz Augusto von Dentz
365250ce4911SLuiz Augusto von Dentz __check_timeout(hdev, *cnt, LE_LINK);
36531b1d29e5SLuiz Augusto von Dentz
365450ce4911SLuiz Augusto von Dentz tmp = *cnt;
365550ce4911SLuiz Augusto von Dentz while (*cnt && (chan = hci_chan_sent(hdev, LE_LINK, "e))) {
3656ec1cce24SLuiz Augusto von Dentz u32 priority = (skb_peek(&chan->data_q))->priority;
3657ec1cce24SLuiz Augusto von Dentz while (quote-- && (skb = skb_peek(&chan->data_q))) {
365873d80debSLuiz Augusto von Dentz BT_DBG("chan %p skb %p len %d priority %u", chan, skb,
365973d80debSLuiz Augusto von Dentz skb->len, skb->priority);
36606ed58ec5SVille Tervo
3661ec1cce24SLuiz Augusto von Dentz /* Stop if priority has changed */
3662ec1cce24SLuiz Augusto von Dentz if (skb->priority < priority)
3663ec1cce24SLuiz Augusto von Dentz break;
3664ec1cce24SLuiz Augusto von Dentz
3665ec1cce24SLuiz Augusto von Dentz skb = skb_dequeue(&chan->data_q);
3666ec1cce24SLuiz Augusto von Dentz
366757d17d70SMarcel Holtmann hci_send_frame(hdev, skb);
36686ed58ec5SVille Tervo hdev->le_last_tx = jiffies;
36696ed58ec5SVille Tervo
367050ce4911SLuiz Augusto von Dentz (*cnt)--;
367173d80debSLuiz Augusto von Dentz chan->sent++;
367273d80debSLuiz Augusto von Dentz chan->conn->sent++;
36737fedd3bbSAbhishek Pandit-Subedi
36747fedd3bbSAbhishek Pandit-Subedi /* Send pending SCO packets right away */
36757fedd3bbSAbhishek Pandit-Subedi hci_sched_sco(hdev);
36767fedd3bbSAbhishek Pandit-Subedi hci_sched_esco(hdev);
36776ed58ec5SVille Tervo }
36786ed58ec5SVille Tervo }
367973d80debSLuiz Augusto von Dentz
368050ce4911SLuiz Augusto von Dentz if (*cnt != tmp)
hci_sched_iso(struct hci_dev * hdev)368102b20f0bSLuiz Augusto von Dentz hci_prio_recalculate(hdev, LE_LINK);
36826ed58ec5SVille Tervo }
36836ed58ec5SVille Tervo
368426afbd82SLuiz Augusto von Dentz /* Schedule CIS */
368526afbd82SLuiz Augusto von Dentz static void hci_sched_iso(struct hci_dev *hdev)
368626afbd82SLuiz Augusto von Dentz {
368726afbd82SLuiz Augusto von Dentz struct hci_conn *conn;
368826afbd82SLuiz Augusto von Dentz struct sk_buff *skb;
368926afbd82SLuiz Augusto von Dentz int quote, *cnt;
369026afbd82SLuiz Augusto von Dentz
369126afbd82SLuiz Augusto von Dentz BT_DBG("%s", hdev->name);
369226afbd82SLuiz Augusto von Dentz
369326afbd82SLuiz Augusto von Dentz if (!hci_conn_num(hdev, ISO_LINK))
369426afbd82SLuiz Augusto von Dentz return;
369526afbd82SLuiz Augusto von Dentz
369626afbd82SLuiz Augusto von Dentz cnt = hdev->iso_pkts ? &hdev->iso_cnt :
369726afbd82SLuiz Augusto von Dentz hdev->le_pkts ? &hdev->le_cnt : &hdev->acl_cnt;
369826afbd82SLuiz Augusto von Dentz while (*cnt && (conn = hci_low_sent(hdev, ISO_LINK, "e))) {
369926afbd82SLuiz Augusto von Dentz while (quote-- && (skb = skb_dequeue(&conn->data_q))) {
370026afbd82SLuiz Augusto von Dentz BT_DBG("skb %p len %d", skb, skb->len);
370126afbd82SLuiz Augusto von Dentz hci_send_frame(hdev, skb);
370226afbd82SLuiz Augusto von Dentz
370326afbd82SLuiz Augusto von Dentz conn->sent++;
370426afbd82SLuiz Augusto von Dentz if (conn->sent == ~0)
370526afbd82SLuiz Augusto von Dentz conn->sent = 0;
370626afbd82SLuiz Augusto von Dentz (*cnt)--;
hci_tx_work(struct work_struct * work)370726afbd82SLuiz Augusto von Dentz }
370826afbd82SLuiz Augusto von Dentz }
370926afbd82SLuiz Augusto von Dentz }
371026afbd82SLuiz Augusto von Dentz
37113eff45eaSGustavo F. Padovan static void hci_tx_work(struct work_struct *work)
37121da177e4SLinus Torvalds {
37133eff45eaSGustavo F. Padovan struct hci_dev *hdev = container_of(work, struct hci_dev, tx_work);
37141da177e4SLinus Torvalds struct sk_buff *skb;
37151da177e4SLinus Torvalds
371626afbd82SLuiz Augusto von Dentz BT_DBG("%s acl %d sco %d le %d iso %d", hdev->name, hdev->acl_cnt,
371726afbd82SLuiz Augusto von Dentz hdev->sco_cnt, hdev->le_cnt, hdev->iso_cnt);
37181da177e4SLinus Torvalds
3719d7a5a11dSMarcel Holtmann if (!hci_dev_test_flag(hdev, HCI_USER_CHANNEL)) {
37201da177e4SLinus Torvalds /* Schedule queues and send stuff to HCI driver */
37211da177e4SLinus Torvalds hci_sched_sco(hdev);
3722b6a0dc82SMarcel Holtmann hci_sched_esco(hdev);
372326afbd82SLuiz Augusto von Dentz hci_sched_iso(hdev);
37247fedd3bbSAbhishek Pandit-Subedi hci_sched_acl(hdev);
37256ed58ec5SVille Tervo hci_sched_le(hdev);
372652de599eSMarcel Holtmann }
37276ed58ec5SVille Tervo
37281da177e4SLinus Torvalds /* Send next queued raw (unknown type) packet */
37291da177e4SLinus Torvalds while ((skb = skb_dequeue(&hdev->raw_q)))
373057d17d70SMarcel Holtmann hci_send_frame(hdev, skb);
37311da177e4SLinus Torvalds }
hci_acldata_packet(struct hci_dev * hdev,struct sk_buff * skb)37321da177e4SLinus Torvalds
373325985edcSLucas De Marchi /* ----- HCI RX task (incoming data processing) ----- */
37341da177e4SLinus Torvalds
37351da177e4SLinus Torvalds /* ACL data packet */
37366039aa73SGustavo Padovan static void hci_acldata_packet(struct hci_dev *hdev, struct sk_buff *skb)
37371da177e4SLinus Torvalds {
37385e50d12cSLuiz Augusto von Dentz struct hci_acl_hdr *hdr;
37391da177e4SLinus Torvalds struct hci_conn *conn;
37401da177e4SLinus Torvalds __u16 handle, flags;
37411da177e4SLinus Torvalds
37425e50d12cSLuiz Augusto von Dentz hdr = skb_pull_data(skb, sizeof(*hdr));
37435e50d12cSLuiz Augusto von Dentz if (!hdr) {
37445e50d12cSLuiz Augusto von Dentz bt_dev_err(hdev, "ACL packet too small");
37455e50d12cSLuiz Augusto von Dentz goto drop;
37465e50d12cSLuiz Augusto von Dentz }
37471da177e4SLinus Torvalds
37481da177e4SLinus Torvalds handle = __le16_to_cpu(hdr->handle);
37491da177e4SLinus Torvalds flags = hci_flags(handle);
37501da177e4SLinus Torvalds handle = hci_handle(handle);
37511da177e4SLinus Torvalds
37525e50d12cSLuiz Augusto von Dentz bt_dev_dbg(hdev, "len %d handle 0x%4.4x flags 0x%4.4x", skb->len,
3753a8c5fb1aSGustavo Padovan handle, flags);
37541da177e4SLinus Torvalds
37551da177e4SLinus Torvalds hdev->stat.acl_rx++;
37561da177e4SLinus Torvalds
37571da177e4SLinus Torvalds hci_dev_lock(hdev);
37581da177e4SLinus Torvalds conn = hci_conn_hash_lookup_handle(hdev, handle);
37591da177e4SLinus Torvalds hci_dev_unlock(hdev);
37601da177e4SLinus Torvalds
37611da177e4SLinus Torvalds if (conn) {
376265983fc7SMat Martineau hci_conn_enter_active_mode(conn, BT_POWER_FORCE_ACTIVE_OFF);
376304837f64SMarcel Holtmann
37641da177e4SLinus Torvalds /* Send to upper protocol */
3765686ebf28SUlisses Furquim l2cap_recv_acldata(conn, skb, flags);
37661da177e4SLinus Torvalds return;
37671da177e4SLinus Torvalds } else {
37682064ee33SMarcel Holtmann bt_dev_err(hdev, "ACL packet for unknown connection handle %d",
37692064ee33SMarcel Holtmann handle);
37701da177e4SLinus Torvalds }
37711da177e4SLinus Torvalds
37725e50d12cSLuiz Augusto von Dentz drop:
37731da177e4SLinus Torvalds kfree_skb(skb);
37741da177e4SLinus Torvalds }
37751da177e4SLinus Torvalds
37761da177e4SLinus Torvalds /* SCO data packet */
37776039aa73SGustavo Padovan static void hci_scodata_packet(struct hci_dev *hdev, struct sk_buff *skb)
37781da177e4SLinus Torvalds {
37791da177e4SLinus Torvalds struct hci_sco_hdr *hdr = (void *) skb->data;
37801da177e4SLinus Torvalds struct hci_conn *conn;
3781debdedf2SMarcel Holtmann __u16 handle, flags;
37821da177e4SLinus Torvalds
37831da177e4SLinus Torvalds skb_pull(skb, HCI_SCO_HDR_SIZE);
37841da177e4SLinus Torvalds
37851da177e4SLinus Torvalds handle = __le16_to_cpu(hdr->handle);
3786debdedf2SMarcel Holtmann flags = hci_flags(handle);
3787debdedf2SMarcel Holtmann handle = hci_handle(handle);
37881da177e4SLinus Torvalds
3789debdedf2SMarcel Holtmann BT_DBG("%s len %d handle 0x%4.4x flags 0x%4.4x", hdev->name, skb->len,
3790debdedf2SMarcel Holtmann handle, flags);
37911da177e4SLinus Torvalds
37921da177e4SLinus Torvalds hdev->stat.sco_rx++;
37931da177e4SLinus Torvalds
37941da177e4SLinus Torvalds hci_dev_lock(hdev);
37951da177e4SLinus Torvalds conn = hci_conn_hash_lookup_handle(hdev, handle);
37961da177e4SLinus Torvalds hci_dev_unlock(hdev);
37971da177e4SLinus Torvalds
37981da177e4SLinus Torvalds if (conn) {
37991da177e4SLinus Torvalds /* Send to upper protocol */
38003f19ffb2SLuiz Augusto von Dentz hci_skb_pkt_status(skb) = flags & 0x03;
3801686ebf28SUlisses Furquim sco_recv_scodata(conn, skb);
38021da177e4SLinus Torvalds return;
38031da177e4SLinus Torvalds } else {
38042d4b37b6SLuiz Augusto von Dentz bt_dev_err_ratelimited(hdev, "SCO packet for unknown connection handle %d",
38052064ee33SMarcel Holtmann handle);
38061da177e4SLinus Torvalds }
hci_isodata_packet(struct hci_dev * hdev,struct sk_buff * skb)38071da177e4SLinus Torvalds
38081da177e4SLinus Torvalds kfree_skb(skb);
38091da177e4SLinus Torvalds }
38101da177e4SLinus Torvalds
381126afbd82SLuiz Augusto von Dentz static void hci_isodata_packet(struct hci_dev *hdev, struct sk_buff *skb)
381226afbd82SLuiz Augusto von Dentz {
381326afbd82SLuiz Augusto von Dentz struct hci_iso_hdr *hdr;
381426afbd82SLuiz Augusto von Dentz struct hci_conn *conn;
381526afbd82SLuiz Augusto von Dentz __u16 handle, flags;
381626afbd82SLuiz Augusto von Dentz
381726afbd82SLuiz Augusto von Dentz hdr = skb_pull_data(skb, sizeof(*hdr));
381826afbd82SLuiz Augusto von Dentz if (!hdr) {
381926afbd82SLuiz Augusto von Dentz bt_dev_err(hdev, "ISO packet too small");
382026afbd82SLuiz Augusto von Dentz goto drop;
382126afbd82SLuiz Augusto von Dentz }
382226afbd82SLuiz Augusto von Dentz
382326afbd82SLuiz Augusto von Dentz handle = __le16_to_cpu(hdr->handle);
382426afbd82SLuiz Augusto von Dentz flags = hci_flags(handle);
382526afbd82SLuiz Augusto von Dentz handle = hci_handle(handle);
382626afbd82SLuiz Augusto von Dentz
382726afbd82SLuiz Augusto von Dentz bt_dev_dbg(hdev, "len %d handle 0x%4.4x flags 0x%4.4x", skb->len,
382826afbd82SLuiz Augusto von Dentz handle, flags);
382926afbd82SLuiz Augusto von Dentz
383026afbd82SLuiz Augusto von Dentz hci_dev_lock(hdev);
383126afbd82SLuiz Augusto von Dentz conn = hci_conn_hash_lookup_handle(hdev, handle);
383226afbd82SLuiz Augusto von Dentz hci_dev_unlock(hdev);
383326afbd82SLuiz Augusto von Dentz
383426afbd82SLuiz Augusto von Dentz if (!conn) {
383526afbd82SLuiz Augusto von Dentz bt_dev_err(hdev, "ISO packet for unknown connection handle %d",
383626afbd82SLuiz Augusto von Dentz handle);
3837ccf74f23SLuiz Augusto von Dentz goto drop;
383826afbd82SLuiz Augusto von Dentz }
383926afbd82SLuiz Augusto von Dentz
3840ccf74f23SLuiz Augusto von Dentz /* Send to upper protocol */
3841ccf74f23SLuiz Augusto von Dentz iso_recv(conn, skb, flags);
3842ccf74f23SLuiz Augusto von Dentz return;
3843ccf74f23SLuiz Augusto von Dentz
hci_req_is_complete(struct hci_dev * hdev)384426afbd82SLuiz Augusto von Dentz drop:
384526afbd82SLuiz Augusto von Dentz kfree_skb(skb);
384626afbd82SLuiz Augusto von Dentz }
384726afbd82SLuiz Augusto von Dentz
38489238f36aSJohan Hedberg static bool hci_req_is_complete(struct hci_dev *hdev)
38499238f36aSJohan Hedberg {
38509238f36aSJohan Hedberg struct sk_buff *skb;
38519238f36aSJohan Hedberg
38529238f36aSJohan Hedberg skb = skb_peek(&hdev->cmd_q);
38539238f36aSJohan Hedberg if (!skb)
38549238f36aSJohan Hedberg return true;
hci_resend_last(struct hci_dev * hdev)38559238f36aSJohan Hedberg
385644d27137SJohan Hedberg return (bt_cb(skb)->hci.req_flags & HCI_REQ_START);
38579238f36aSJohan Hedberg }
38589238f36aSJohan Hedberg
385942c6b129SJohan Hedberg static void hci_resend_last(struct hci_dev *hdev)
386042c6b129SJohan Hedberg {
386142c6b129SJohan Hedberg struct hci_command_hdr *sent;
386242c6b129SJohan Hedberg struct sk_buff *skb;
386342c6b129SJohan Hedberg u16 opcode;
386442c6b129SJohan Hedberg
386542c6b129SJohan Hedberg if (!hdev->sent_cmd)
386642c6b129SJohan Hedberg return;
386742c6b129SJohan Hedberg
386842c6b129SJohan Hedberg sent = (void *) hdev->sent_cmd->data;
386942c6b129SJohan Hedberg opcode = __le16_to_cpu(sent->opcode);
387042c6b129SJohan Hedberg if (opcode == HCI_OP_RESET)
387142c6b129SJohan Hedberg return;
387242c6b129SJohan Hedberg
387342c6b129SJohan Hedberg skb = skb_clone(hdev->sent_cmd, GFP_KERNEL);
387442c6b129SJohan Hedberg if (!skb)
387542c6b129SJohan Hedberg return;
387642c6b129SJohan Hedberg
hci_req_cmd_complete(struct hci_dev * hdev,u16 opcode,u8 status,hci_req_complete_t * req_complete,hci_req_complete_skb_t * req_complete_skb)387742c6b129SJohan Hedberg skb_queue_head(&hdev->cmd_q, skb);
387842c6b129SJohan Hedberg queue_work(hdev->workqueue, &hdev->cmd_work);
387942c6b129SJohan Hedberg }
388042c6b129SJohan Hedberg
3881e6214487SJohan Hedberg void hci_req_cmd_complete(struct hci_dev *hdev, u16 opcode, u8 status,
3882e6214487SJohan Hedberg hci_req_complete_t *req_complete,
3883e6214487SJohan Hedberg hci_req_complete_skb_t *req_complete_skb)
38849238f36aSJohan Hedberg {
38859238f36aSJohan Hedberg struct sk_buff *skb;
38869238f36aSJohan Hedberg unsigned long flags;
38879238f36aSJohan Hedberg
38889238f36aSJohan Hedberg BT_DBG("opcode 0x%04x status 0x%02x", opcode, status);
38899238f36aSJohan Hedberg
389042c6b129SJohan Hedberg /* If the completed command doesn't match the last one that was
389142c6b129SJohan Hedberg * sent we need to do special handling of it.
38929238f36aSJohan Hedberg */
389342c6b129SJohan Hedberg if (!hci_sent_cmd_data(hdev, opcode)) {
389442c6b129SJohan Hedberg /* Some CSR based controllers generate a spontaneous
389542c6b129SJohan Hedberg * reset complete event during init and any pending
389642c6b129SJohan Hedberg * command will never be completed. In such a case we
389742c6b129SJohan Hedberg * need to resend whatever was the last sent
389842c6b129SJohan Hedberg * command.
389942c6b129SJohan Hedberg */
390042c6b129SJohan Hedberg if (test_bit(HCI_INIT, &hdev->flags) && opcode == HCI_OP_RESET)
390142c6b129SJohan Hedberg hci_resend_last(hdev);
390242c6b129SJohan Hedberg
39039238f36aSJohan Hedberg return;
390442c6b129SJohan Hedberg }
39059238f36aSJohan Hedberg
3906f80c5dadSJoão Paulo Rechi Vita /* If we reach this point this event matches the last command sent */
3907f80c5dadSJoão Paulo Rechi Vita hci_dev_clear_flag(hdev, HCI_CMD_PENDING);
3908f80c5dadSJoão Paulo Rechi Vita
39099238f36aSJohan Hedberg /* If the command succeeded and there's still more commands in
39109238f36aSJohan Hedberg * this request the request is not yet complete.
39119238f36aSJohan Hedberg */
39129238f36aSJohan Hedberg if (!status && !hci_req_is_complete(hdev))
39139238f36aSJohan Hedberg return;
39149238f36aSJohan Hedberg
39152af7aa66SLuiz Augusto von Dentz skb = hdev->req_skb;
39162af7aa66SLuiz Augusto von Dentz
39179238f36aSJohan Hedberg /* If this was the last command in a request the complete
39182af7aa66SLuiz Augusto von Dentz * callback would be found in hdev->req_skb instead of the
39199238f36aSJohan Hedberg * command queue (hdev->cmd_q).
39209238f36aSJohan Hedberg */
39212af7aa66SLuiz Augusto von Dentz if (skb && bt_cb(skb)->hci.req_flags & HCI_REQ_SKB) {
39222af7aa66SLuiz Augusto von Dentz *req_complete_skb = bt_cb(skb)->hci.req_complete_skb;
3923e6214487SJohan Hedberg return;
39249238f36aSJohan Hedberg }
3925e6214487SJohan Hedberg
39262af7aa66SLuiz Augusto von Dentz if (skb && bt_cb(skb)->hci.req_complete) {
39272af7aa66SLuiz Augusto von Dentz *req_complete = bt_cb(skb)->hci.req_complete;
3928e6214487SJohan Hedberg return;
392953e21fbcSJohan Hedberg }
39309238f36aSJohan Hedberg
39319238f36aSJohan Hedberg /* Remove all pending commands belonging to this request */
39329238f36aSJohan Hedberg spin_lock_irqsave(&hdev->cmd_q.lock, flags);
39339238f36aSJohan Hedberg while ((skb = __skb_dequeue(&hdev->cmd_q))) {
393444d27137SJohan Hedberg if (bt_cb(skb)->hci.req_flags & HCI_REQ_START) {
39359238f36aSJohan Hedberg __skb_queue_head(&hdev->cmd_q, skb);
39369238f36aSJohan Hedberg break;
39379238f36aSJohan Hedberg }
39389238f36aSJohan Hedberg
39393bd7594eSDouglas Anderson if (bt_cb(skb)->hci.req_flags & HCI_REQ_SKB)
3940242c0ebdSMarcel Holtmann *req_complete_skb = bt_cb(skb)->hci.req_complete_skb;
39413bd7594eSDouglas Anderson else
39423bd7594eSDouglas Anderson *req_complete = bt_cb(skb)->hci.req_complete;
394339c1eb6fSYang Yingliang dev_kfree_skb_irq(skb);
hci_rx_work(struct work_struct * work)39449238f36aSJohan Hedberg }
39459238f36aSJohan Hedberg spin_unlock_irqrestore(&hdev->cmd_q.lock, flags);
39469238f36aSJohan Hedberg }
39479238f36aSJohan Hedberg
3948b78752ccSMarcel Holtmann static void hci_rx_work(struct work_struct *work)
39491da177e4SLinus Torvalds {
3950b78752ccSMarcel Holtmann struct hci_dev *hdev = container_of(work, struct hci_dev, rx_work);
39511da177e4SLinus Torvalds struct sk_buff *skb;
39521da177e4SLinus Torvalds
39531da177e4SLinus Torvalds BT_DBG("%s", hdev->name);
39541da177e4SLinus Torvalds
39559f30de9eSTamas Koczka /* The kcov_remote functions used for collecting packet parsing
39569f30de9eSTamas Koczka * coverage information from this background thread and associate
39579f30de9eSTamas Koczka * the coverage with the syscall's thread which originally injected
39589f30de9eSTamas Koczka * the packet. This helps fuzzing the kernel.
39599f30de9eSTamas Koczka */
39609f30de9eSTamas Koczka for (; (skb = skb_dequeue(&hdev->rx_q)); kcov_remote_stop()) {
39619f30de9eSTamas Koczka kcov_remote_start_common(skb_get_kcov_handle(skb));
39629f30de9eSTamas Koczka
3963cd82e61cSMarcel Holtmann /* Send copy to monitor */
3964cd82e61cSMarcel Holtmann hci_send_to_monitor(hdev, skb);
3965cd82e61cSMarcel Holtmann
39661da177e4SLinus Torvalds if (atomic_read(&hdev->promisc)) {
39671da177e4SLinus Torvalds /* Send copy to the sockets */
3968470fe1b5SMarcel Holtmann hci_send_to_sock(hdev, skb);
39691da177e4SLinus Torvalds }
39701da177e4SLinus Torvalds
3971eb8c101eSMattijs Korpershoek /* If the device has been opened in HCI_USER_CHANNEL,
3972eb8c101eSMattijs Korpershoek * the userspace has exclusive access to device.
3973eb8c101eSMattijs Korpershoek * When device is HCI_INIT, we still need to process
3974eb8c101eSMattijs Korpershoek * the data packets to the driver in order
3975eb8c101eSMattijs Korpershoek * to complete its setup().
3976eb8c101eSMattijs Korpershoek */
3977eb8c101eSMattijs Korpershoek if (hci_dev_test_flag(hdev, HCI_USER_CHANNEL) &&
3978eb8c101eSMattijs Korpershoek !test_bit(HCI_INIT, &hdev->flags)) {
39791da177e4SLinus Torvalds kfree_skb(skb);
39801da177e4SLinus Torvalds continue;
39811da177e4SLinus Torvalds }
39821da177e4SLinus Torvalds
39831da177e4SLinus Torvalds if (test_bit(HCI_INIT, &hdev->flags)) {
39841da177e4SLinus Torvalds /* Don't process data packets in this states. */
3985d79f34e3SMarcel Holtmann switch (hci_skb_pkt_type(skb)) {
39861da177e4SLinus Torvalds case HCI_ACLDATA_PKT:
39871da177e4SLinus Torvalds case HCI_SCODATA_PKT:
3988cc974003SMarcel Holtmann case HCI_ISODATA_PKT:
39891da177e4SLinus Torvalds kfree_skb(skb);
39901da177e4SLinus Torvalds continue;
39913ff50b79SStephen Hemminger }
39921da177e4SLinus Torvalds }
39931da177e4SLinus Torvalds
39941da177e4SLinus Torvalds /* Process frame */
3995d79f34e3SMarcel Holtmann switch (hci_skb_pkt_type(skb)) {
39961da177e4SLinus Torvalds case HCI_EVENT_PKT:
3997b78752ccSMarcel Holtmann BT_DBG("%s Event packet", hdev->name);
39981da177e4SLinus Torvalds hci_event_packet(hdev, skb);
39991da177e4SLinus Torvalds break;
40001da177e4SLinus Torvalds
40011da177e4SLinus Torvalds case HCI_ACLDATA_PKT:
40021da177e4SLinus Torvalds BT_DBG("%s ACL data packet", hdev->name);
40031da177e4SLinus Torvalds hci_acldata_packet(hdev, skb);
40041da177e4SLinus Torvalds break;
40051da177e4SLinus Torvalds
40061da177e4SLinus Torvalds case HCI_SCODATA_PKT:
40071da177e4SLinus Torvalds BT_DBG("%s SCO data packet", hdev->name);
40081da177e4SLinus Torvalds hci_scodata_packet(hdev, skb);
40091da177e4SLinus Torvalds break;
40101da177e4SLinus Torvalds
401126afbd82SLuiz Augusto von Dentz case HCI_ISODATA_PKT:
401226afbd82SLuiz Augusto von Dentz BT_DBG("%s ISO data packet", hdev->name);
401326afbd82SLuiz Augusto von Dentz hci_isodata_packet(hdev, skb);
401426afbd82SLuiz Augusto von Dentz break;
401526afbd82SLuiz Augusto von Dentz
40161da177e4SLinus Torvalds default:
40171da177e4SLinus Torvalds kfree_skb(skb);
40181da177e4SLinus Torvalds break;
hci_send_cmd_sync(struct hci_dev * hdev,struct sk_buff * skb)40191da177e4SLinus Torvalds }
40201da177e4SLinus Torvalds }
40211da177e4SLinus Torvalds }
40221da177e4SLinus Torvalds
40230ce1229cSLuiz Augusto von Dentz static void hci_send_cmd_sync(struct hci_dev *hdev, struct sk_buff *skb)
40240ce1229cSLuiz Augusto von Dentz {
40250ce1229cSLuiz Augusto von Dentz int err;
40260ce1229cSLuiz Augusto von Dentz
40270ce1229cSLuiz Augusto von Dentz bt_dev_dbg(hdev, "skb %p", skb);
40280ce1229cSLuiz Augusto von Dentz
40290ce1229cSLuiz Augusto von Dentz kfree_skb(hdev->sent_cmd);
40300ce1229cSLuiz Augusto von Dentz
40310ce1229cSLuiz Augusto von Dentz hdev->sent_cmd = skb_clone(skb, GFP_KERNEL);
40320ce1229cSLuiz Augusto von Dentz if (!hdev->sent_cmd) {
40330ce1229cSLuiz Augusto von Dentz skb_queue_head(&hdev->cmd_q, skb);
40340ce1229cSLuiz Augusto von Dentz queue_work(hdev->workqueue, &hdev->cmd_work);
40350ce1229cSLuiz Augusto von Dentz return;
40360ce1229cSLuiz Augusto von Dentz }
40370ce1229cSLuiz Augusto von Dentz
40380ce1229cSLuiz Augusto von Dentz err = hci_send_frame(hdev, skb);
40390ce1229cSLuiz Augusto von Dentz if (err < 0) {
40409ae3954dSLuiz Augusto von Dentz hci_cmd_sync_cancel_sync(hdev, -err);
40410ce1229cSLuiz Augusto von Dentz return;
40420ce1229cSLuiz Augusto von Dentz }
40430ce1229cSLuiz Augusto von Dentz
40442af7aa66SLuiz Augusto von Dentz if (hci_req_status_pend(hdev) &&
40452af7aa66SLuiz Augusto von Dentz !hci_dev_test_and_set_flag(hdev, HCI_CMD_PENDING)) {
40462af7aa66SLuiz Augusto von Dentz kfree_skb(hdev->req_skb);
4047a2354605SPauli Virtanen hdev->req_skb = skb_clone(hdev->sent_cmd, GFP_KERNEL);
40482af7aa66SLuiz Augusto von Dentz }
40490ce1229cSLuiz Augusto von Dentz
40500ce1229cSLuiz Augusto von Dentz atomic_dec(&hdev->cmd_cnt);
40510ce1229cSLuiz Augusto von Dentz }
40520ce1229cSLuiz Augusto von Dentz
4053c347b765SGustavo F. Padovan static void hci_cmd_work(struct work_struct *work)
40541da177e4SLinus Torvalds {
4055c347b765SGustavo F. Padovan struct hci_dev *hdev = container_of(work, struct hci_dev, cmd_work);
40561da177e4SLinus Torvalds struct sk_buff *skb;
40571da177e4SLinus Torvalds
40582104786bSAndrei Emeltchenko BT_DBG("%s cmd_cnt %d cmd queued %d", hdev->name,
40592104786bSAndrei Emeltchenko atomic_read(&hdev->cmd_cnt), skb_queue_len(&hdev->cmd_q));
40601da177e4SLinus Torvalds
40611da177e4SLinus Torvalds /* Send queued commands */
40625a08ecceSAndrei Emeltchenko if (atomic_read(&hdev->cmd_cnt)) {
40635a08ecceSAndrei Emeltchenko skb = skb_dequeue(&hdev->cmd_q);
40645a08ecceSAndrei Emeltchenko if (!skb)
40655a08ecceSAndrei Emeltchenko return;
40665a08ecceSAndrei Emeltchenko
40670ce1229cSLuiz Augusto von Dentz hci_send_cmd_sync(hdev, skb);
40682250abadSBenjamin Berg
4069deee93d1STetsuo Handa rcu_read_lock();
4070877afadaSSchspa Shi if (test_bit(HCI_RESET, &hdev->flags) ||
4071877afadaSSchspa Shi hci_dev_test_flag(hdev, HCI_CMD_DRAIN_WORKQUEUE))
407265cc2b49SMarcel Holtmann cancel_delayed_work(&hdev->cmd_timer);
40737bdb8a5cSSzymon Janc else
4074deee93d1STetsuo Handa queue_delayed_work(hdev->workqueue, &hdev->cmd_timer,
407565cc2b49SMarcel Holtmann HCI_CMD_TIMEOUT);
4076deee93d1STetsuo Handa rcu_read_unlock();
40771da177e4SLinus Torvalds }
40781da177e4SLinus Torvalds }
4079