d0fde05e8b17740b7f27f9650bf406470abcd2a4
[platform/adaptation/renesas_rcar/renesas_kernel.git] / net / bluetooth / a2mp.c
1 /*
2    Copyright (c) 2010,2011 Code Aurora Forum.  All rights reserved.
3    Copyright (c) 2011,2012 Intel Corp.
4
5    This program is free software; you can redistribute it and/or modify
6    it under the terms of the GNU General Public License version 2 and
7    only version 2 as published by the Free Software Foundation.
8
9    This program is distributed in the hope that it will be useful,
10    but WITHOUT ANY WARRANTY; without even the implied warranty of
11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12    GNU General Public License for more details.
13 */
14
15 #include <net/bluetooth/bluetooth.h>
16 #include <net/bluetooth/hci_core.h>
17 #include <net/bluetooth/l2cap.h>
18 #include <net/bluetooth/a2mp.h>
19 #include <net/bluetooth/amp.h>
20
21 /* Global AMP Manager list */
22 LIST_HEAD(amp_mgr_list);
23 DEFINE_MUTEX(amp_mgr_list_lock);
24
25 /* A2MP build & send command helper functions */
26 static struct a2mp_cmd *__a2mp_build(u8 code, u8 ident, u16 len, void *data)
27 {
28         struct a2mp_cmd *cmd;
29         int plen;
30
31         plen = sizeof(*cmd) + len;
32         cmd = kzalloc(plen, GFP_KERNEL);
33         if (!cmd)
34                 return NULL;
35
36         cmd->code = code;
37         cmd->ident = ident;
38         cmd->len = cpu_to_le16(len);
39
40         memcpy(cmd->data, data, len);
41
42         return cmd;
43 }
44
45 void a2mp_send(struct amp_mgr *mgr, u8 code, u8 ident, u16 len, void *data)
46 {
47         struct l2cap_chan *chan = mgr->a2mp_chan;
48         struct a2mp_cmd *cmd;
49         u16 total_len = len + sizeof(*cmd);
50         struct kvec iv;
51         struct msghdr msg;
52
53         cmd = __a2mp_build(code, ident, len, data);
54         if (!cmd)
55                 return;
56
57         iv.iov_base = cmd;
58         iv.iov_len = total_len;
59
60         memset(&msg, 0, sizeof(msg));
61
62         msg.msg_iov = (struct iovec *) &iv;
63         msg.msg_iovlen = 1;
64
65         l2cap_chan_send(chan, &msg, total_len, 0);
66
67         kfree(cmd);
68 }
69
70 static u8 __next_ident(struct amp_mgr *mgr)
71 {
72         if (++mgr->ident == 0)
73                 mgr->ident = 1;
74
75         return mgr->ident;
76 }
77
78 static inline void __a2mp_cl_bredr(struct a2mp_cl *cl)
79 {
80         cl->id = 0;
81         cl->type = 0;
82         cl->status = 1;
83 }
84
85 /* hci_dev_list shall be locked */
86 static void __a2mp_add_cl(struct amp_mgr *mgr, struct a2mp_cl *cl, u8 num_ctrl)
87 {
88         int i = 0;
89         struct hci_dev *hdev;
90
91         __a2mp_cl_bredr(cl);
92
93         list_for_each_entry(hdev, &hci_dev_list, list) {
94                 /* Iterate through AMP controllers */
95                 if (hdev->id == HCI_BREDR_ID)
96                         continue;
97
98                 /* Starting from second entry */
99                 if (++i >= num_ctrl)
100                         return;
101
102                 cl[i].id = hdev->id;
103                 cl[i].type = hdev->amp_type;
104                 cl[i].status = hdev->amp_status;
105         }
106 }
107
108 /* Processing A2MP messages */
109 static int a2mp_command_rej(struct amp_mgr *mgr, struct sk_buff *skb,
110                             struct a2mp_cmd *hdr)
111 {
112         struct a2mp_cmd_rej *rej = (void *) skb->data;
113
114         if (le16_to_cpu(hdr->len) < sizeof(*rej))
115                 return -EINVAL;
116
117         BT_DBG("ident %d reason %d", hdr->ident, le16_to_cpu(rej->reason));
118
119         skb_pull(skb, sizeof(*rej));
120
121         return 0;
122 }
123
124 static int a2mp_discover_req(struct amp_mgr *mgr, struct sk_buff *skb,
125                              struct a2mp_cmd *hdr)
126 {
127         struct a2mp_discov_req *req = (void *) skb->data;
128         u16 len = le16_to_cpu(hdr->len);
129         struct a2mp_discov_rsp *rsp;
130         u16 ext_feat;
131         u8 num_ctrl;
132
133         if (len < sizeof(*req))
134                 return -EINVAL;
135
136         skb_pull(skb, sizeof(*req));
137
138         ext_feat = le16_to_cpu(req->ext_feat);
139
140         BT_DBG("mtu %d efm 0x%4.4x", le16_to_cpu(req->mtu), ext_feat);
141
142         /* check that packet is not broken for now */
143         while (ext_feat & A2MP_FEAT_EXT) {
144                 if (len < sizeof(ext_feat))
145                         return -EINVAL;
146
147                 ext_feat = get_unaligned_le16(skb->data);
148                 BT_DBG("efm 0x%4.4x", ext_feat);
149                 len -= sizeof(ext_feat);
150                 skb_pull(skb, sizeof(ext_feat));
151         }
152
153         read_lock(&hci_dev_list_lock);
154
155         num_ctrl = __hci_num_ctrl();
156         len = num_ctrl * sizeof(struct a2mp_cl) + sizeof(*rsp);
157         rsp = kmalloc(len, GFP_ATOMIC);
158         if (!rsp) {
159                 read_unlock(&hci_dev_list_lock);
160                 return -ENOMEM;
161         }
162
163         rsp->mtu = __constant_cpu_to_le16(L2CAP_A2MP_DEFAULT_MTU);
164         rsp->ext_feat = 0;
165
166         __a2mp_add_cl(mgr, rsp->cl, num_ctrl);
167
168         read_unlock(&hci_dev_list_lock);
169
170         a2mp_send(mgr, A2MP_DISCOVER_RSP, hdr->ident, len, rsp);
171
172         kfree(rsp);
173         return 0;
174 }
175
176 static int a2mp_discover_rsp(struct amp_mgr *mgr, struct sk_buff *skb,
177                              struct a2mp_cmd *hdr)
178 {
179         struct a2mp_discov_rsp *rsp = (void *) skb->data;
180         u16 len = le16_to_cpu(hdr->len);
181         struct a2mp_cl *cl;
182         u16 ext_feat;
183
184         if (len < sizeof(*rsp))
185                 return -EINVAL;
186
187         len -= sizeof(*rsp);
188         skb_pull(skb, sizeof(*rsp));
189
190         ext_feat = le16_to_cpu(rsp->ext_feat);
191
192         BT_DBG("mtu %d efm 0x%4.4x", le16_to_cpu(rsp->mtu), ext_feat);
193
194         /* check that packet is not broken for now */
195         while (ext_feat & A2MP_FEAT_EXT) {
196                 if (len < sizeof(ext_feat))
197                         return -EINVAL;
198
199                 ext_feat = get_unaligned_le16(skb->data);
200                 BT_DBG("efm 0x%4.4x", ext_feat);
201                 len -= sizeof(ext_feat);
202                 skb_pull(skb, sizeof(ext_feat));
203         }
204
205         cl = (void *) skb->data;
206         while (len >= sizeof(*cl)) {
207                 BT_DBG("Remote AMP id %d type %d status %d", cl->id, cl->type,
208                        cl->status);
209
210                 if (cl->id != HCI_BREDR_ID && cl->type == HCI_AMP) {
211                         struct a2mp_info_req req;
212
213                         req.id = cl->id;
214                         a2mp_send(mgr, A2MP_GETINFO_REQ, __next_ident(mgr),
215                                   sizeof(req), &req);
216                 }
217
218                 len -= sizeof(*cl);
219                 cl = (void *) skb_pull(skb, sizeof(*cl));
220         }
221
222         return 0;
223 }
224
225 static int a2mp_change_notify(struct amp_mgr *mgr, struct sk_buff *skb,
226                               struct a2mp_cmd *hdr)
227 {
228         struct a2mp_cl *cl = (void *) skb->data;
229
230         while (skb->len >= sizeof(*cl)) {
231                 BT_DBG("Controller id %d type %d status %d", cl->id, cl->type,
232                        cl->status);
233                 cl = (struct a2mp_cl *) skb_pull(skb, sizeof(*cl));
234         }
235
236         /* TODO send A2MP_CHANGE_RSP */
237
238         return 0;
239 }
240
241 static int a2mp_getinfo_req(struct amp_mgr *mgr, struct sk_buff *skb,
242                             struct a2mp_cmd *hdr)
243 {
244         struct a2mp_info_req *req  = (void *) skb->data;
245         struct hci_dev *hdev;
246
247         if (le16_to_cpu(hdr->len) < sizeof(*req))
248                 return -EINVAL;
249
250         BT_DBG("id %d", req->id);
251
252         hdev = hci_dev_get(req->id);
253         if (!hdev) {
254                 struct a2mp_info_rsp rsp;
255
256                 rsp.id = req->id;
257                 rsp.status = A2MP_STATUS_INVALID_CTRL_ID;
258
259                 a2mp_send(mgr, A2MP_GETINFO_RSP, hdr->ident, sizeof(rsp),
260                           &rsp);
261         }
262
263         if (hdev->dev_type != HCI_BREDR) {
264                 mgr->state = READ_LOC_AMP_INFO;
265                 hci_send_cmd(hdev, HCI_OP_READ_LOCAL_AMP_INFO, 0, NULL);
266         }
267
268         hci_dev_put(hdev);
269
270         skb_pull(skb, sizeof(*req));
271         return 0;
272 }
273
274 static int a2mp_getinfo_rsp(struct amp_mgr *mgr, struct sk_buff *skb,
275                             struct a2mp_cmd *hdr)
276 {
277         struct a2mp_info_rsp *rsp = (struct a2mp_info_rsp *) skb->data;
278         struct a2mp_amp_assoc_req req;
279         struct amp_ctrl *ctrl;
280
281         if (le16_to_cpu(hdr->len) < sizeof(*rsp))
282                 return -EINVAL;
283
284         BT_DBG("id %d status 0x%2.2x", rsp->id, rsp->status);
285
286         if (rsp->status)
287                 return -EINVAL;
288
289         ctrl = amp_ctrl_add(mgr);
290         if (!ctrl)
291                 return -ENOMEM;
292
293         ctrl->id = rsp->id;
294
295         req.id = rsp->id;
296         a2mp_send(mgr, A2MP_GETAMPASSOC_REQ, __next_ident(mgr), sizeof(req),
297                   &req);
298
299         skb_pull(skb, sizeof(*rsp));
300         return 0;
301 }
302
303 static int a2mp_getampassoc_req(struct amp_mgr *mgr, struct sk_buff *skb,
304                                 struct a2mp_cmd *hdr)
305 {
306         struct a2mp_amp_assoc_req *req = (void *) skb->data;
307         struct hci_dev *hdev;
308         struct amp_mgr *tmp;
309
310         if (le16_to_cpu(hdr->len) < sizeof(*req))
311                 return -EINVAL;
312
313         BT_DBG("id %d", req->id);
314
315         /* Make sure that other request is not processed */
316         tmp = amp_mgr_lookup_by_state(READ_LOC_AMP_ASSOC);
317
318         hdev = hci_dev_get(req->id);
319         if (!hdev || hdev->amp_type == HCI_BREDR || tmp) {
320                 struct a2mp_amp_assoc_rsp rsp;
321                 rsp.id = req->id;
322
323                 if (tmp) {
324                         rsp.status = A2MP_STATUS_COLLISION_OCCURED;
325                         amp_mgr_put(tmp);
326                 } else {
327                         rsp.status = A2MP_STATUS_INVALID_CTRL_ID;
328                 }
329
330                 a2mp_send(mgr, A2MP_GETAMPASSOC_RSP, hdr->ident, sizeof(rsp),
331                           &rsp);
332
333                 goto done;
334         }
335
336         amp_read_loc_assoc(hdev, mgr);
337
338 done:
339         if (hdev)
340                 hci_dev_put(hdev);
341
342         skb_pull(skb, sizeof(*req));
343         return 0;
344 }
345
346 static int a2mp_getampassoc_rsp(struct amp_mgr *mgr, struct sk_buff *skb,
347                                 struct a2mp_cmd *hdr)
348 {
349         struct a2mp_amp_assoc_rsp *rsp = (void *) skb->data;
350         u16 len = le16_to_cpu(hdr->len);
351         struct hci_dev *hdev;
352         struct amp_ctrl *ctrl;
353         struct hci_conn *hcon;
354
355         if (len < sizeof(*rsp))
356                 return -EINVAL;
357
358         BT_DBG("id %d status 0x%2.2x assoc len %u", rsp->id, rsp->status,
359                len - sizeof(*rsp));
360
361         if (rsp->status)
362                 return -EINVAL;
363
364         /* Save remote ASSOC data */
365         ctrl = amp_ctrl_lookup(mgr, rsp->id);
366         if (ctrl) {
367                 u8 *assoc, assoc_len = len - sizeof(*rsp);
368
369                 assoc = kzalloc(assoc_len, GFP_KERNEL);
370                 if (!assoc) {
371                         amp_ctrl_put(ctrl);
372                         return -ENOMEM;
373                 }
374
375                 memcpy(assoc, rsp->amp_assoc, assoc_len);
376                 ctrl->assoc = assoc;
377                 ctrl->assoc_len = assoc_len;
378                 ctrl->assoc_rem_len = assoc_len;
379                 ctrl->assoc_len_so_far = 0;
380
381                 amp_ctrl_put(ctrl);
382         }
383
384         /* Create Phys Link */
385         hdev = hci_dev_get(rsp->id);
386         if (!hdev)
387                 return -EINVAL;
388
389         hcon = phylink_add(hdev, mgr, rsp->id);
390         if (!hcon)
391                 goto done;
392
393         BT_DBG("Created hcon %p: loc:%d -> rem:%d", hcon, hdev->id, rsp->id);
394
395 done:
396         hci_dev_put(hdev);
397         skb_pull(skb, len);
398         return 0;
399 }
400
401 static int a2mp_createphyslink_req(struct amp_mgr *mgr, struct sk_buff *skb,
402                                    struct a2mp_cmd *hdr)
403 {
404         struct a2mp_physlink_req *req = (void *) skb->data;
405
406         struct a2mp_physlink_rsp rsp;
407         struct hci_dev *hdev;
408         struct hci_conn *hcon;
409
410         if (le16_to_cpu(hdr->len) < sizeof(*req))
411                 return -EINVAL;
412
413         BT_DBG("local_id %d, remote_id %d", req->local_id, req->remote_id);
414
415         rsp.local_id = req->remote_id;
416         rsp.remote_id = req->local_id;
417
418         hdev = hci_dev_get(req->remote_id);
419         if (!hdev || hdev->amp_type != HCI_AMP) {
420                 rsp.status = A2MP_STATUS_INVALID_CTRL_ID;
421                 goto send_rsp;
422         }
423
424         /* TODO process physlink create */
425
426         hcon = phylink_add(hdev, mgr, req->local_id);
427         if (hcon) {
428                 BT_DBG("hcon %p", hcon);
429
430                 rsp.status = A2MP_STATUS_SUCCESS;
431         } else {
432                 rsp.status = A2MP_STATUS_UNABLE_START_LINK_CREATION;
433         }
434
435 send_rsp:
436         if (hdev)
437                 hci_dev_put(hdev);
438
439         a2mp_send(mgr, A2MP_CREATEPHYSLINK_RSP, hdr->ident, sizeof(rsp),
440                   &rsp);
441
442         skb_pull(skb, le16_to_cpu(hdr->len));
443         return 0;
444 }
445
446 static int a2mp_discphyslink_req(struct amp_mgr *mgr, struct sk_buff *skb,
447                                  struct a2mp_cmd *hdr)
448 {
449         struct a2mp_physlink_req *req = (void *) skb->data;
450         struct a2mp_physlink_rsp rsp;
451         struct hci_dev *hdev;
452         struct hci_conn *hcon;
453
454         if (le16_to_cpu(hdr->len) < sizeof(*req))
455                 return -EINVAL;
456
457         BT_DBG("local_id %d remote_id %d", req->local_id, req->remote_id);
458
459         rsp.local_id = req->remote_id;
460         rsp.remote_id = req->local_id;
461         rsp.status = A2MP_STATUS_SUCCESS;
462
463         hdev = hci_dev_get(req->remote_id);
464         if (!hdev) {
465                 rsp.status = A2MP_STATUS_INVALID_CTRL_ID;
466                 goto send_rsp;
467         }
468
469         hcon = hci_conn_hash_lookup_ba(hdev, AMP_LINK, mgr->l2cap_conn->dst);
470         if (!hcon) {
471                 BT_ERR("No phys link exist");
472                 rsp.status = A2MP_STATUS_NO_PHYSICAL_LINK_EXISTS;
473                 goto clean;
474         }
475
476         /* TODO Disconnect Phys Link here */
477
478 clean:
479         hci_dev_put(hdev);
480
481 send_rsp:
482         a2mp_send(mgr, A2MP_DISCONNPHYSLINK_RSP, hdr->ident, sizeof(rsp), &rsp);
483
484         skb_pull(skb, sizeof(*req));
485         return 0;
486 }
487
488 static inline int a2mp_cmd_rsp(struct amp_mgr *mgr, struct sk_buff *skb,
489                                struct a2mp_cmd *hdr)
490 {
491         BT_DBG("ident %d code 0x%2.2x", hdr->ident, hdr->code);
492
493         skb_pull(skb, le16_to_cpu(hdr->len));
494         return 0;
495 }
496
497 /* Handle A2MP signalling */
498 static int a2mp_chan_recv_cb(struct l2cap_chan *chan, struct sk_buff *skb)
499 {
500         struct a2mp_cmd *hdr;
501         struct amp_mgr *mgr = chan->data;
502         int err = 0;
503
504         amp_mgr_get(mgr);
505
506         while (skb->len >= sizeof(*hdr)) {
507                 u16 len;
508
509                 hdr = (void *) skb->data;
510                 len = le16_to_cpu(hdr->len);
511
512                 BT_DBG("code 0x%2.2x id %d len %u", hdr->code, hdr->ident, len);
513
514                 skb_pull(skb, sizeof(*hdr));
515
516                 if (len > skb->len || !hdr->ident) {
517                         err = -EINVAL;
518                         break;
519                 }
520
521                 mgr->ident = hdr->ident;
522
523                 switch (hdr->code) {
524                 case A2MP_COMMAND_REJ:
525                         a2mp_command_rej(mgr, skb, hdr);
526                         break;
527
528                 case A2MP_DISCOVER_REQ:
529                         err = a2mp_discover_req(mgr, skb, hdr);
530                         break;
531
532                 case A2MP_CHANGE_NOTIFY:
533                         err = a2mp_change_notify(mgr, skb, hdr);
534                         break;
535
536                 case A2MP_GETINFO_REQ:
537                         err = a2mp_getinfo_req(mgr, skb, hdr);
538                         break;
539
540                 case A2MP_GETAMPASSOC_REQ:
541                         err = a2mp_getampassoc_req(mgr, skb, hdr);
542                         break;
543
544                 case A2MP_CREATEPHYSLINK_REQ:
545                         err = a2mp_createphyslink_req(mgr, skb, hdr);
546                         break;
547
548                 case A2MP_DISCONNPHYSLINK_REQ:
549                         err = a2mp_discphyslink_req(mgr, skb, hdr);
550                         break;
551
552                 case A2MP_DISCOVER_RSP:
553                         err = a2mp_discover_rsp(mgr, skb, hdr);
554                         break;
555
556                 case A2MP_GETINFO_RSP:
557                         err = a2mp_getinfo_rsp(mgr, skb, hdr);
558                         break;
559
560                 case A2MP_GETAMPASSOC_RSP:
561                         err = a2mp_getampassoc_rsp(mgr, skb, hdr);
562                         break;
563
564                 case A2MP_CHANGE_RSP:
565                 case A2MP_CREATEPHYSLINK_RSP:
566                 case A2MP_DISCONNPHYSLINK_RSP:
567                         err = a2mp_cmd_rsp(mgr, skb, hdr);
568                         break;
569
570                 default:
571                         BT_ERR("Unknown A2MP sig cmd 0x%2.2x", hdr->code);
572                         err = -EINVAL;
573                         break;
574                 }
575         }
576
577         if (err) {
578                 struct a2mp_cmd_rej rej;
579
580                 rej.reason = __constant_cpu_to_le16(0);
581                 hdr = (void *) skb->data;
582
583                 BT_DBG("Send A2MP Rej: cmd 0x%2.2x err %d", hdr->code, err);
584
585                 a2mp_send(mgr, A2MP_COMMAND_REJ, hdr->ident, sizeof(rej),
586                           &rej);
587         }
588
589         /* Always free skb and return success error code to prevent
590            from sending L2CAP Disconnect over A2MP channel */
591         kfree_skb(skb);
592
593         amp_mgr_put(mgr);
594
595         return 0;
596 }
597
598 static void a2mp_chan_close_cb(struct l2cap_chan *chan)
599 {
600         l2cap_chan_put(chan);
601 }
602
603 static void a2mp_chan_state_change_cb(struct l2cap_chan *chan, int state)
604 {
605         struct amp_mgr *mgr = chan->data;
606
607         if (!mgr)
608                 return;
609
610         BT_DBG("chan %p state %s", chan, state_to_string(state));
611
612         chan->state = state;
613
614         switch (state) {
615         case BT_CLOSED:
616                 if (mgr)
617                         amp_mgr_put(mgr);
618                 break;
619         }
620 }
621
622 static struct sk_buff *a2mp_chan_alloc_skb_cb(struct l2cap_chan *chan,
623                                               unsigned long len, int nb)
624 {
625         return bt_skb_alloc(len, GFP_KERNEL);
626 }
627
628 static struct l2cap_ops a2mp_chan_ops = {
629         .name = "L2CAP A2MP channel",
630         .recv = a2mp_chan_recv_cb,
631         .close = a2mp_chan_close_cb,
632         .state_change = a2mp_chan_state_change_cb,
633         .alloc_skb = a2mp_chan_alloc_skb_cb,
634
635         /* Not implemented for A2MP */
636         .new_connection = l2cap_chan_no_new_connection,
637         .teardown = l2cap_chan_no_teardown,
638         .ready = l2cap_chan_no_ready,
639 };
640
641 static struct l2cap_chan *a2mp_chan_open(struct l2cap_conn *conn)
642 {
643         struct l2cap_chan *chan;
644         int err;
645
646         chan = l2cap_chan_create();
647         if (!chan)
648                 return NULL;
649
650         BT_DBG("chan %p", chan);
651
652         chan->chan_type = L2CAP_CHAN_CONN_FIX_A2MP;
653         chan->flush_to = L2CAP_DEFAULT_FLUSH_TO;
654
655         chan->ops = &a2mp_chan_ops;
656
657         l2cap_chan_set_defaults(chan);
658         chan->remote_max_tx = chan->max_tx;
659         chan->remote_tx_win = chan->tx_win;
660
661         chan->retrans_timeout = L2CAP_DEFAULT_RETRANS_TO;
662         chan->monitor_timeout = L2CAP_DEFAULT_MONITOR_TO;
663
664         skb_queue_head_init(&chan->tx_q);
665
666         chan->mode = L2CAP_MODE_ERTM;
667
668         err = l2cap_ertm_init(chan);
669         if (err < 0) {
670                 l2cap_chan_del(chan, 0);
671                 return NULL;
672         }
673
674         chan->conf_state = 0;
675
676         l2cap_chan_add(conn, chan);
677
678         chan->remote_mps = chan->omtu;
679         chan->mps = chan->omtu;
680
681         chan->state = BT_CONNECTED;
682
683         return chan;
684 }
685
686 /* AMP Manager functions */
687 void amp_mgr_get(struct amp_mgr *mgr)
688 {
689         BT_DBG("mgr %p orig refcnt %d", mgr, atomic_read(&mgr->kref.refcount));
690
691         kref_get(&mgr->kref);
692 }
693
694 static void amp_mgr_destroy(struct kref *kref)
695 {
696         struct amp_mgr *mgr = container_of(kref, struct amp_mgr, kref);
697
698         BT_DBG("mgr %p", mgr);
699
700         mutex_lock(&amp_mgr_list_lock);
701         list_del(&mgr->list);
702         mutex_unlock(&amp_mgr_list_lock);
703
704         amp_ctrl_list_flush(mgr);
705         kfree(mgr);
706 }
707
708 int amp_mgr_put(struct amp_mgr *mgr)
709 {
710         BT_DBG("mgr %p orig refcnt %d", mgr, atomic_read(&mgr->kref.refcount));
711
712         return kref_put(&mgr->kref, &amp_mgr_destroy);
713 }
714
715 static struct amp_mgr *amp_mgr_create(struct l2cap_conn *conn)
716 {
717         struct amp_mgr *mgr;
718         struct l2cap_chan *chan;
719
720         mgr = kzalloc(sizeof(*mgr), GFP_KERNEL);
721         if (!mgr)
722                 return NULL;
723
724         BT_DBG("conn %p mgr %p", conn, mgr);
725
726         mgr->l2cap_conn = conn;
727
728         chan = a2mp_chan_open(conn);
729         if (!chan) {
730                 kfree(mgr);
731                 return NULL;
732         }
733
734         mgr->a2mp_chan = chan;
735         chan->data = mgr;
736
737         conn->hcon->amp_mgr = mgr;
738
739         kref_init(&mgr->kref);
740
741         /* Remote AMP ctrl list initialization */
742         INIT_LIST_HEAD(&mgr->amp_ctrls);
743         mutex_init(&mgr->amp_ctrls_lock);
744
745         mutex_lock(&amp_mgr_list_lock);
746         list_add(&mgr->list, &amp_mgr_list);
747         mutex_unlock(&amp_mgr_list_lock);
748
749         return mgr;
750 }
751
752 struct l2cap_chan *a2mp_channel_create(struct l2cap_conn *conn,
753                                        struct sk_buff *skb)
754 {
755         struct amp_mgr *mgr;
756
757         mgr = amp_mgr_create(conn);
758         if (!mgr) {
759                 BT_ERR("Could not create AMP manager");
760                 return NULL;
761         }
762
763         BT_DBG("mgr: %p chan %p", mgr, mgr->a2mp_chan);
764
765         return mgr->a2mp_chan;
766 }
767
768 struct amp_mgr *amp_mgr_lookup_by_state(u8 state)
769 {
770         struct amp_mgr *mgr;
771
772         mutex_lock(&amp_mgr_list_lock);
773         list_for_each_entry(mgr, &amp_mgr_list, list) {
774                 if (mgr->state == state) {
775                         amp_mgr_get(mgr);
776                         mutex_unlock(&amp_mgr_list_lock);
777                         return mgr;
778                 }
779         }
780         mutex_unlock(&amp_mgr_list_lock);
781
782         return NULL;
783 }
784
785 void a2mp_send_getinfo_rsp(struct hci_dev *hdev)
786 {
787         struct amp_mgr *mgr;
788         struct a2mp_info_rsp rsp;
789
790         mgr = amp_mgr_lookup_by_state(READ_LOC_AMP_INFO);
791         if (!mgr)
792                 return;
793
794         BT_DBG("%s mgr %p", hdev->name, mgr);
795
796         rsp.id = hdev->id;
797         rsp.status = A2MP_STATUS_INVALID_CTRL_ID;
798
799         if (hdev->amp_type != HCI_BREDR) {
800                 rsp.status = 0;
801                 rsp.total_bw = cpu_to_le32(hdev->amp_total_bw);
802                 rsp.max_bw = cpu_to_le32(hdev->amp_max_bw);
803                 rsp.min_latency = cpu_to_le32(hdev->amp_min_latency);
804                 rsp.pal_cap = cpu_to_le16(hdev->amp_pal_cap);
805                 rsp.assoc_size = cpu_to_le16(hdev->amp_assoc_size);
806         }
807
808         a2mp_send(mgr, A2MP_GETINFO_RSP, mgr->ident, sizeof(rsp), &rsp);
809         amp_mgr_put(mgr);
810 }
811
812 void a2mp_send_getampassoc_rsp(struct hci_dev *hdev, u8 status)
813 {
814         struct amp_mgr *mgr;
815         struct amp_assoc *loc_assoc = &hdev->loc_assoc;
816         struct a2mp_amp_assoc_rsp *rsp;
817         size_t len;
818
819         mgr = amp_mgr_lookup_by_state(READ_LOC_AMP_ASSOC);
820         if (!mgr)
821                 return;
822
823         BT_DBG("%s mgr %p", hdev->name, mgr);
824
825         len = sizeof(struct a2mp_amp_assoc_rsp) + loc_assoc->len;
826         rsp = kzalloc(len, GFP_KERNEL);
827         if (!rsp) {
828                 amp_mgr_put(mgr);
829                 return;
830         }
831
832         rsp->id = hdev->id;
833
834         if (status) {
835                 rsp->status = A2MP_STATUS_INVALID_CTRL_ID;
836         } else {
837                 rsp->status = A2MP_STATUS_SUCCESS;
838                 memcpy(rsp->amp_assoc, loc_assoc->data, loc_assoc->len);
839         }
840
841         a2mp_send(mgr, A2MP_GETAMPASSOC_RSP, mgr->ident, len, rsp);
842         amp_mgr_put(mgr);
843         kfree(rsp);
844 }