at v3.19-rc4 1023 lines 22 kB view raw
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 19#include "a2mp.h" 20#include "amp.h" 21 22/* Global AMP Manager list */ 23LIST_HEAD(amp_mgr_list); 24DEFINE_MUTEX(amp_mgr_list_lock); 25 26/* A2MP build & send command helper functions */ 27static struct a2mp_cmd *__a2mp_build(u8 code, u8 ident, u16 len, void *data) 28{ 29 struct a2mp_cmd *cmd; 30 int plen; 31 32 plen = sizeof(*cmd) + len; 33 cmd = kzalloc(plen, GFP_KERNEL); 34 if (!cmd) 35 return NULL; 36 37 cmd->code = code; 38 cmd->ident = ident; 39 cmd->len = cpu_to_le16(len); 40 41 memcpy(cmd->data, data, len); 42 43 return cmd; 44} 45 46void a2mp_send(struct amp_mgr *mgr, u8 code, u8 ident, u16 len, void *data) 47{ 48 struct l2cap_chan *chan = mgr->a2mp_chan; 49 struct a2mp_cmd *cmd; 50 u16 total_len = len + sizeof(*cmd); 51 struct kvec iv; 52 struct msghdr msg; 53 54 cmd = __a2mp_build(code, ident, len, data); 55 if (!cmd) 56 return; 57 58 iv.iov_base = cmd; 59 iv.iov_len = total_len; 60 61 memset(&msg, 0, sizeof(msg)); 62 63 iov_iter_kvec(&msg.msg_iter, WRITE | ITER_KVEC, &iv, 1, total_len); 64 65 l2cap_chan_send(chan, &msg, total_len); 66 67 kfree(cmd); 68} 69 70u8 __next_ident(struct amp_mgr *mgr) 71{ 72 if (++mgr->ident == 0) 73 mgr->ident = 1; 74 75 return mgr->ident; 76} 77 78/* hci_dev_list shall be locked */ 79static void __a2mp_add_cl(struct amp_mgr *mgr, struct a2mp_cl *cl) 80{ 81 struct hci_dev *hdev; 82 int i = 1; 83 84 cl[0].id = AMP_ID_BREDR; 85 cl[0].type = AMP_TYPE_BREDR; 86 cl[0].status = AMP_STATUS_BLUETOOTH_ONLY; 87 88 list_for_each_entry(hdev, &hci_dev_list, list) { 89 if (hdev->dev_type == HCI_AMP) { 90 cl[i].id = hdev->id; 91 cl[i].type = hdev->amp_type; 92 if (test_bit(HCI_UP, &hdev->flags)) 93 cl[i].status = hdev->amp_status; 94 else 95 cl[i].status = AMP_STATUS_POWERED_DOWN; 96 i++; 97 } 98 } 99} 100 101/* Processing A2MP messages */ 102static int a2mp_command_rej(struct amp_mgr *mgr, struct sk_buff *skb, 103 struct a2mp_cmd *hdr) 104{ 105 struct a2mp_cmd_rej *rej = (void *) skb->data; 106 107 if (le16_to_cpu(hdr->len) < sizeof(*rej)) 108 return -EINVAL; 109 110 BT_DBG("ident %d reason %d", hdr->ident, le16_to_cpu(rej->reason)); 111 112 skb_pull(skb, sizeof(*rej)); 113 114 return 0; 115} 116 117static int a2mp_discover_req(struct amp_mgr *mgr, struct sk_buff *skb, 118 struct a2mp_cmd *hdr) 119{ 120 struct a2mp_discov_req *req = (void *) skb->data; 121 u16 len = le16_to_cpu(hdr->len); 122 struct a2mp_discov_rsp *rsp; 123 u16 ext_feat; 124 u8 num_ctrl; 125 struct hci_dev *hdev; 126 127 if (len < sizeof(*req)) 128 return -EINVAL; 129 130 skb_pull(skb, sizeof(*req)); 131 132 ext_feat = le16_to_cpu(req->ext_feat); 133 134 BT_DBG("mtu %d efm 0x%4.4x", le16_to_cpu(req->mtu), ext_feat); 135 136 /* check that packet is not broken for now */ 137 while (ext_feat & A2MP_FEAT_EXT) { 138 if (len < sizeof(ext_feat)) 139 return -EINVAL; 140 141 ext_feat = get_unaligned_le16(skb->data); 142 BT_DBG("efm 0x%4.4x", ext_feat); 143 len -= sizeof(ext_feat); 144 skb_pull(skb, sizeof(ext_feat)); 145 } 146 147 read_lock(&hci_dev_list_lock); 148 149 /* at minimum the BR/EDR needs to be listed */ 150 num_ctrl = 1; 151 152 list_for_each_entry(hdev, &hci_dev_list, list) { 153 if (hdev->dev_type == HCI_AMP) 154 num_ctrl++; 155 } 156 157 len = num_ctrl * sizeof(struct a2mp_cl) + sizeof(*rsp); 158 rsp = kmalloc(len, GFP_ATOMIC); 159 if (!rsp) { 160 read_unlock(&hci_dev_list_lock); 161 return -ENOMEM; 162 } 163 164 rsp->mtu = cpu_to_le16(L2CAP_A2MP_DEFAULT_MTU); 165 rsp->ext_feat = 0; 166 167 __a2mp_add_cl(mgr, rsp->cl); 168 169 read_unlock(&hci_dev_list_lock); 170 171 a2mp_send(mgr, A2MP_DISCOVER_RSP, hdr->ident, len, rsp); 172 173 kfree(rsp); 174 return 0; 175} 176 177static int a2mp_discover_rsp(struct amp_mgr *mgr, struct sk_buff *skb, 178 struct a2mp_cmd *hdr) 179{ 180 struct a2mp_discov_rsp *rsp = (void *) skb->data; 181 u16 len = le16_to_cpu(hdr->len); 182 struct a2mp_cl *cl; 183 u16 ext_feat; 184 bool found = false; 185 186 if (len < sizeof(*rsp)) 187 return -EINVAL; 188 189 len -= sizeof(*rsp); 190 skb_pull(skb, sizeof(*rsp)); 191 192 ext_feat = le16_to_cpu(rsp->ext_feat); 193 194 BT_DBG("mtu %d efm 0x%4.4x", le16_to_cpu(rsp->mtu), ext_feat); 195 196 /* check that packet is not broken for now */ 197 while (ext_feat & A2MP_FEAT_EXT) { 198 if (len < sizeof(ext_feat)) 199 return -EINVAL; 200 201 ext_feat = get_unaligned_le16(skb->data); 202 BT_DBG("efm 0x%4.4x", ext_feat); 203 len -= sizeof(ext_feat); 204 skb_pull(skb, sizeof(ext_feat)); 205 } 206 207 cl = (void *) skb->data; 208 while (len >= sizeof(*cl)) { 209 BT_DBG("Remote AMP id %d type %d status %d", cl->id, cl->type, 210 cl->status); 211 212 if (cl->id != AMP_ID_BREDR && cl->type != AMP_TYPE_BREDR) { 213 struct a2mp_info_req req; 214 215 found = true; 216 req.id = cl->id; 217 a2mp_send(mgr, A2MP_GETINFO_REQ, __next_ident(mgr), 218 sizeof(req), &req); 219 } 220 221 len -= sizeof(*cl); 222 cl = (void *) skb_pull(skb, sizeof(*cl)); 223 } 224 225 /* Fall back to L2CAP init sequence */ 226 if (!found) { 227 struct l2cap_conn *conn = mgr->l2cap_conn; 228 struct l2cap_chan *chan; 229 230 mutex_lock(&conn->chan_lock); 231 232 list_for_each_entry(chan, &conn->chan_l, list) { 233 234 BT_DBG("chan %p state %s", chan, 235 state_to_string(chan->state)); 236 237 if (chan->scid == L2CAP_CID_A2MP) 238 continue; 239 240 l2cap_chan_lock(chan); 241 242 if (chan->state == BT_CONNECT) 243 l2cap_send_conn_req(chan); 244 245 l2cap_chan_unlock(chan); 246 } 247 248 mutex_unlock(&conn->chan_lock); 249 } 250 251 return 0; 252} 253 254static int a2mp_change_notify(struct amp_mgr *mgr, struct sk_buff *skb, 255 struct a2mp_cmd *hdr) 256{ 257 struct a2mp_cl *cl = (void *) skb->data; 258 259 while (skb->len >= sizeof(*cl)) { 260 BT_DBG("Controller id %d type %d status %d", cl->id, cl->type, 261 cl->status); 262 cl = (struct a2mp_cl *) skb_pull(skb, sizeof(*cl)); 263 } 264 265 /* TODO send A2MP_CHANGE_RSP */ 266 267 return 0; 268} 269 270static int a2mp_getinfo_req(struct amp_mgr *mgr, struct sk_buff *skb, 271 struct a2mp_cmd *hdr) 272{ 273 struct a2mp_info_req *req = (void *) skb->data; 274 struct hci_dev *hdev; 275 276 if (le16_to_cpu(hdr->len) < sizeof(*req)) 277 return -EINVAL; 278 279 BT_DBG("id %d", req->id); 280 281 hdev = hci_dev_get(req->id); 282 if (!hdev || hdev->dev_type != HCI_AMP) { 283 struct a2mp_info_rsp rsp; 284 285 rsp.id = req->id; 286 rsp.status = A2MP_STATUS_INVALID_CTRL_ID; 287 288 a2mp_send(mgr, A2MP_GETINFO_RSP, hdr->ident, sizeof(rsp), 289 &rsp); 290 291 goto done; 292 } 293 294 set_bit(READ_LOC_AMP_INFO, &mgr->state); 295 hci_send_cmd(hdev, HCI_OP_READ_LOCAL_AMP_INFO, 0, NULL); 296 297done: 298 if (hdev) 299 hci_dev_put(hdev); 300 301 skb_pull(skb, sizeof(*req)); 302 return 0; 303} 304 305static int a2mp_getinfo_rsp(struct amp_mgr *mgr, struct sk_buff *skb, 306 struct a2mp_cmd *hdr) 307{ 308 struct a2mp_info_rsp *rsp = (struct a2mp_info_rsp *) skb->data; 309 struct a2mp_amp_assoc_req req; 310 struct amp_ctrl *ctrl; 311 312 if (le16_to_cpu(hdr->len) < sizeof(*rsp)) 313 return -EINVAL; 314 315 BT_DBG("id %d status 0x%2.2x", rsp->id, rsp->status); 316 317 if (rsp->status) 318 return -EINVAL; 319 320 ctrl = amp_ctrl_add(mgr, rsp->id); 321 if (!ctrl) 322 return -ENOMEM; 323 324 req.id = rsp->id; 325 a2mp_send(mgr, A2MP_GETAMPASSOC_REQ, __next_ident(mgr), sizeof(req), 326 &req); 327 328 skb_pull(skb, sizeof(*rsp)); 329 return 0; 330} 331 332static int a2mp_getampassoc_req(struct amp_mgr *mgr, struct sk_buff *skb, 333 struct a2mp_cmd *hdr) 334{ 335 struct a2mp_amp_assoc_req *req = (void *) skb->data; 336 struct hci_dev *hdev; 337 struct amp_mgr *tmp; 338 339 if (le16_to_cpu(hdr->len) < sizeof(*req)) 340 return -EINVAL; 341 342 BT_DBG("id %d", req->id); 343 344 /* Make sure that other request is not processed */ 345 tmp = amp_mgr_lookup_by_state(READ_LOC_AMP_ASSOC); 346 347 hdev = hci_dev_get(req->id); 348 if (!hdev || hdev->amp_type == AMP_TYPE_BREDR || tmp) { 349 struct a2mp_amp_assoc_rsp rsp; 350 rsp.id = req->id; 351 352 if (tmp) { 353 rsp.status = A2MP_STATUS_COLLISION_OCCURED; 354 amp_mgr_put(tmp); 355 } else { 356 rsp.status = A2MP_STATUS_INVALID_CTRL_ID; 357 } 358 359 a2mp_send(mgr, A2MP_GETAMPASSOC_RSP, hdr->ident, sizeof(rsp), 360 &rsp); 361 362 goto done; 363 } 364 365 amp_read_loc_assoc(hdev, mgr); 366 367done: 368 if (hdev) 369 hci_dev_put(hdev); 370 371 skb_pull(skb, sizeof(*req)); 372 return 0; 373} 374 375static int a2mp_getampassoc_rsp(struct amp_mgr *mgr, struct sk_buff *skb, 376 struct a2mp_cmd *hdr) 377{ 378 struct a2mp_amp_assoc_rsp *rsp = (void *) skb->data; 379 u16 len = le16_to_cpu(hdr->len); 380 struct hci_dev *hdev; 381 struct amp_ctrl *ctrl; 382 struct hci_conn *hcon; 383 size_t assoc_len; 384 385 if (len < sizeof(*rsp)) 386 return -EINVAL; 387 388 assoc_len = len - sizeof(*rsp); 389 390 BT_DBG("id %d status 0x%2.2x assoc len %zu", rsp->id, rsp->status, 391 assoc_len); 392 393 if (rsp->status) 394 return -EINVAL; 395 396 /* Save remote ASSOC data */ 397 ctrl = amp_ctrl_lookup(mgr, rsp->id); 398 if (ctrl) { 399 u8 *assoc; 400 401 assoc = kmemdup(rsp->amp_assoc, assoc_len, GFP_KERNEL); 402 if (!assoc) { 403 amp_ctrl_put(ctrl); 404 return -ENOMEM; 405 } 406 407 ctrl->assoc = assoc; 408 ctrl->assoc_len = assoc_len; 409 ctrl->assoc_rem_len = assoc_len; 410 ctrl->assoc_len_so_far = 0; 411 412 amp_ctrl_put(ctrl); 413 } 414 415 /* Create Phys Link */ 416 hdev = hci_dev_get(rsp->id); 417 if (!hdev) 418 return -EINVAL; 419 420 hcon = phylink_add(hdev, mgr, rsp->id, true); 421 if (!hcon) 422 goto done; 423 424 BT_DBG("Created hcon %p: loc:%d -> rem:%d", hcon, hdev->id, rsp->id); 425 426 mgr->bredr_chan->remote_amp_id = rsp->id; 427 428 amp_create_phylink(hdev, mgr, hcon); 429 430done: 431 hci_dev_put(hdev); 432 skb_pull(skb, len); 433 return 0; 434} 435 436static int a2mp_createphyslink_req(struct amp_mgr *mgr, struct sk_buff *skb, 437 struct a2mp_cmd *hdr) 438{ 439 struct a2mp_physlink_req *req = (void *) skb->data; 440 441 struct a2mp_physlink_rsp rsp; 442 struct hci_dev *hdev; 443 struct hci_conn *hcon; 444 struct amp_ctrl *ctrl; 445 446 if (le16_to_cpu(hdr->len) < sizeof(*req)) 447 return -EINVAL; 448 449 BT_DBG("local_id %d, remote_id %d", req->local_id, req->remote_id); 450 451 rsp.local_id = req->remote_id; 452 rsp.remote_id = req->local_id; 453 454 hdev = hci_dev_get(req->remote_id); 455 if (!hdev || hdev->amp_type == AMP_TYPE_BREDR) { 456 rsp.status = A2MP_STATUS_INVALID_CTRL_ID; 457 goto send_rsp; 458 } 459 460 ctrl = amp_ctrl_lookup(mgr, rsp.remote_id); 461 if (!ctrl) { 462 ctrl = amp_ctrl_add(mgr, rsp.remote_id); 463 if (ctrl) { 464 amp_ctrl_get(ctrl); 465 } else { 466 rsp.status = A2MP_STATUS_UNABLE_START_LINK_CREATION; 467 goto send_rsp; 468 } 469 } 470 471 if (ctrl) { 472 size_t assoc_len = le16_to_cpu(hdr->len) - sizeof(*req); 473 u8 *assoc; 474 475 assoc = kmemdup(req->amp_assoc, assoc_len, GFP_KERNEL); 476 if (!assoc) { 477 amp_ctrl_put(ctrl); 478 return -ENOMEM; 479 } 480 481 ctrl->assoc = assoc; 482 ctrl->assoc_len = assoc_len; 483 ctrl->assoc_rem_len = assoc_len; 484 ctrl->assoc_len_so_far = 0; 485 486 amp_ctrl_put(ctrl); 487 } 488 489 hcon = phylink_add(hdev, mgr, req->local_id, false); 490 if (hcon) { 491 amp_accept_phylink(hdev, mgr, hcon); 492 rsp.status = A2MP_STATUS_SUCCESS; 493 } else { 494 rsp.status = A2MP_STATUS_UNABLE_START_LINK_CREATION; 495 } 496 497send_rsp: 498 if (hdev) 499 hci_dev_put(hdev); 500 501 /* Reply error now and success after HCI Write Remote AMP Assoc 502 command complete with success status 503 */ 504 if (rsp.status != A2MP_STATUS_SUCCESS) { 505 a2mp_send(mgr, A2MP_CREATEPHYSLINK_RSP, hdr->ident, 506 sizeof(rsp), &rsp); 507 } else { 508 set_bit(WRITE_REMOTE_AMP_ASSOC, &mgr->state); 509 mgr->ident = hdr->ident; 510 } 511 512 skb_pull(skb, le16_to_cpu(hdr->len)); 513 return 0; 514} 515 516static int a2mp_discphyslink_req(struct amp_mgr *mgr, struct sk_buff *skb, 517 struct a2mp_cmd *hdr) 518{ 519 struct a2mp_physlink_req *req = (void *) skb->data; 520 struct a2mp_physlink_rsp rsp; 521 struct hci_dev *hdev; 522 struct hci_conn *hcon; 523 524 if (le16_to_cpu(hdr->len) < sizeof(*req)) 525 return -EINVAL; 526 527 BT_DBG("local_id %d remote_id %d", req->local_id, req->remote_id); 528 529 rsp.local_id = req->remote_id; 530 rsp.remote_id = req->local_id; 531 rsp.status = A2MP_STATUS_SUCCESS; 532 533 hdev = hci_dev_get(req->remote_id); 534 if (!hdev) { 535 rsp.status = A2MP_STATUS_INVALID_CTRL_ID; 536 goto send_rsp; 537 } 538 539 hcon = hci_conn_hash_lookup_ba(hdev, AMP_LINK, 540 &mgr->l2cap_conn->hcon->dst); 541 if (!hcon) { 542 BT_ERR("No phys link exist"); 543 rsp.status = A2MP_STATUS_NO_PHYSICAL_LINK_EXISTS; 544 goto clean; 545 } 546 547 /* TODO Disconnect Phys Link here */ 548 549clean: 550 hci_dev_put(hdev); 551 552send_rsp: 553 a2mp_send(mgr, A2MP_DISCONNPHYSLINK_RSP, hdr->ident, sizeof(rsp), &rsp); 554 555 skb_pull(skb, sizeof(*req)); 556 return 0; 557} 558 559static inline int a2mp_cmd_rsp(struct amp_mgr *mgr, struct sk_buff *skb, 560 struct a2mp_cmd *hdr) 561{ 562 BT_DBG("ident %d code 0x%2.2x", hdr->ident, hdr->code); 563 564 skb_pull(skb, le16_to_cpu(hdr->len)); 565 return 0; 566} 567 568/* Handle A2MP signalling */ 569static int a2mp_chan_recv_cb(struct l2cap_chan *chan, struct sk_buff *skb) 570{ 571 struct a2mp_cmd *hdr; 572 struct amp_mgr *mgr = chan->data; 573 int err = 0; 574 575 amp_mgr_get(mgr); 576 577 while (skb->len >= sizeof(*hdr)) { 578 u16 len; 579 580 hdr = (void *) skb->data; 581 len = le16_to_cpu(hdr->len); 582 583 BT_DBG("code 0x%2.2x id %d len %u", hdr->code, hdr->ident, len); 584 585 skb_pull(skb, sizeof(*hdr)); 586 587 if (len > skb->len || !hdr->ident) { 588 err = -EINVAL; 589 break; 590 } 591 592 mgr->ident = hdr->ident; 593 594 switch (hdr->code) { 595 case A2MP_COMMAND_REJ: 596 a2mp_command_rej(mgr, skb, hdr); 597 break; 598 599 case A2MP_DISCOVER_REQ: 600 err = a2mp_discover_req(mgr, skb, hdr); 601 break; 602 603 case A2MP_CHANGE_NOTIFY: 604 err = a2mp_change_notify(mgr, skb, hdr); 605 break; 606 607 case A2MP_GETINFO_REQ: 608 err = a2mp_getinfo_req(mgr, skb, hdr); 609 break; 610 611 case A2MP_GETAMPASSOC_REQ: 612 err = a2mp_getampassoc_req(mgr, skb, hdr); 613 break; 614 615 case A2MP_CREATEPHYSLINK_REQ: 616 err = a2mp_createphyslink_req(mgr, skb, hdr); 617 break; 618 619 case A2MP_DISCONNPHYSLINK_REQ: 620 err = a2mp_discphyslink_req(mgr, skb, hdr); 621 break; 622 623 case A2MP_DISCOVER_RSP: 624 err = a2mp_discover_rsp(mgr, skb, hdr); 625 break; 626 627 case A2MP_GETINFO_RSP: 628 err = a2mp_getinfo_rsp(mgr, skb, hdr); 629 break; 630 631 case A2MP_GETAMPASSOC_RSP: 632 err = a2mp_getampassoc_rsp(mgr, skb, hdr); 633 break; 634 635 case A2MP_CHANGE_RSP: 636 case A2MP_CREATEPHYSLINK_RSP: 637 case A2MP_DISCONNPHYSLINK_RSP: 638 err = a2mp_cmd_rsp(mgr, skb, hdr); 639 break; 640 641 default: 642 BT_ERR("Unknown A2MP sig cmd 0x%2.2x", hdr->code); 643 err = -EINVAL; 644 break; 645 } 646 } 647 648 if (err) { 649 struct a2mp_cmd_rej rej; 650 651 rej.reason = cpu_to_le16(0); 652 hdr = (void *) skb->data; 653 654 BT_DBG("Send A2MP Rej: cmd 0x%2.2x err %d", hdr->code, err); 655 656 a2mp_send(mgr, A2MP_COMMAND_REJ, hdr->ident, sizeof(rej), 657 &rej); 658 } 659 660 /* Always free skb and return success error code to prevent 661 from sending L2CAP Disconnect over A2MP channel */ 662 kfree_skb(skb); 663 664 amp_mgr_put(mgr); 665 666 return 0; 667} 668 669static void a2mp_chan_close_cb(struct l2cap_chan *chan) 670{ 671 l2cap_chan_put(chan); 672} 673 674static void a2mp_chan_state_change_cb(struct l2cap_chan *chan, int state, 675 int err) 676{ 677 struct amp_mgr *mgr = chan->data; 678 679 if (!mgr) 680 return; 681 682 BT_DBG("chan %p state %s", chan, state_to_string(state)); 683 684 chan->state = state; 685 686 switch (state) { 687 case BT_CLOSED: 688 if (mgr) 689 amp_mgr_put(mgr); 690 break; 691 } 692} 693 694static struct sk_buff *a2mp_chan_alloc_skb_cb(struct l2cap_chan *chan, 695 unsigned long hdr_len, 696 unsigned long len, int nb) 697{ 698 struct sk_buff *skb; 699 700 skb = bt_skb_alloc(hdr_len + len, GFP_KERNEL); 701 if (!skb) 702 return ERR_PTR(-ENOMEM); 703 704 return skb; 705} 706 707static const struct l2cap_ops a2mp_chan_ops = { 708 .name = "L2CAP A2MP channel", 709 .recv = a2mp_chan_recv_cb, 710 .close = a2mp_chan_close_cb, 711 .state_change = a2mp_chan_state_change_cb, 712 .alloc_skb = a2mp_chan_alloc_skb_cb, 713 714 /* Not implemented for A2MP */ 715 .new_connection = l2cap_chan_no_new_connection, 716 .teardown = l2cap_chan_no_teardown, 717 .ready = l2cap_chan_no_ready, 718 .defer = l2cap_chan_no_defer, 719 .resume = l2cap_chan_no_resume, 720 .set_shutdown = l2cap_chan_no_set_shutdown, 721 .get_sndtimeo = l2cap_chan_no_get_sndtimeo, 722}; 723 724static struct l2cap_chan *a2mp_chan_open(struct l2cap_conn *conn, bool locked) 725{ 726 struct l2cap_chan *chan; 727 int err; 728 729 chan = l2cap_chan_create(); 730 if (!chan) 731 return NULL; 732 733 BT_DBG("chan %p", chan); 734 735 chan->chan_type = L2CAP_CHAN_FIXED; 736 chan->scid = L2CAP_CID_A2MP; 737 chan->dcid = L2CAP_CID_A2MP; 738 chan->omtu = L2CAP_A2MP_DEFAULT_MTU; 739 chan->imtu = L2CAP_A2MP_DEFAULT_MTU; 740 chan->flush_to = L2CAP_DEFAULT_FLUSH_TO; 741 742 chan->ops = &a2mp_chan_ops; 743 744 l2cap_chan_set_defaults(chan); 745 chan->remote_max_tx = chan->max_tx; 746 chan->remote_tx_win = chan->tx_win; 747 748 chan->retrans_timeout = L2CAP_DEFAULT_RETRANS_TO; 749 chan->monitor_timeout = L2CAP_DEFAULT_MONITOR_TO; 750 751 skb_queue_head_init(&chan->tx_q); 752 753 chan->mode = L2CAP_MODE_ERTM; 754 755 err = l2cap_ertm_init(chan); 756 if (err < 0) { 757 l2cap_chan_del(chan, 0); 758 return NULL; 759 } 760 761 chan->conf_state = 0; 762 763 if (locked) 764 __l2cap_chan_add(conn, chan); 765 else 766 l2cap_chan_add(conn, chan); 767 768 chan->remote_mps = chan->omtu; 769 chan->mps = chan->omtu; 770 771 chan->state = BT_CONNECTED; 772 773 return chan; 774} 775 776/* AMP Manager functions */ 777struct amp_mgr *amp_mgr_get(struct amp_mgr *mgr) 778{ 779 BT_DBG("mgr %p orig refcnt %d", mgr, atomic_read(&mgr->kref.refcount)); 780 781 kref_get(&mgr->kref); 782 783 return mgr; 784} 785 786static void amp_mgr_destroy(struct kref *kref) 787{ 788 struct amp_mgr *mgr = container_of(kref, struct amp_mgr, kref); 789 790 BT_DBG("mgr %p", mgr); 791 792 mutex_lock(&amp_mgr_list_lock); 793 list_del(&mgr->list); 794 mutex_unlock(&amp_mgr_list_lock); 795 796 amp_ctrl_list_flush(mgr); 797 kfree(mgr); 798} 799 800int amp_mgr_put(struct amp_mgr *mgr) 801{ 802 BT_DBG("mgr %p orig refcnt %d", mgr, atomic_read(&mgr->kref.refcount)); 803 804 return kref_put(&mgr->kref, &amp_mgr_destroy); 805} 806 807static struct amp_mgr *amp_mgr_create(struct l2cap_conn *conn, bool locked) 808{ 809 struct amp_mgr *mgr; 810 struct l2cap_chan *chan; 811 812 mgr = kzalloc(sizeof(*mgr), GFP_KERNEL); 813 if (!mgr) 814 return NULL; 815 816 BT_DBG("conn %p mgr %p", conn, mgr); 817 818 mgr->l2cap_conn = conn; 819 820 chan = a2mp_chan_open(conn, locked); 821 if (!chan) { 822 kfree(mgr); 823 return NULL; 824 } 825 826 mgr->a2mp_chan = chan; 827 chan->data = mgr; 828 829 conn->hcon->amp_mgr = mgr; 830 831 kref_init(&mgr->kref); 832 833 /* Remote AMP ctrl list initialization */ 834 INIT_LIST_HEAD(&mgr->amp_ctrls); 835 mutex_init(&mgr->amp_ctrls_lock); 836 837 mutex_lock(&amp_mgr_list_lock); 838 list_add(&mgr->list, &amp_mgr_list); 839 mutex_unlock(&amp_mgr_list_lock); 840 841 return mgr; 842} 843 844struct l2cap_chan *a2mp_channel_create(struct l2cap_conn *conn, 845 struct sk_buff *skb) 846{ 847 struct amp_mgr *mgr; 848 849 if (conn->hcon->type != ACL_LINK) 850 return NULL; 851 852 mgr = amp_mgr_create(conn, false); 853 if (!mgr) { 854 BT_ERR("Could not create AMP manager"); 855 return NULL; 856 } 857 858 BT_DBG("mgr: %p chan %p", mgr, mgr->a2mp_chan); 859 860 return mgr->a2mp_chan; 861} 862 863struct amp_mgr *amp_mgr_lookup_by_state(u8 state) 864{ 865 struct amp_mgr *mgr; 866 867 mutex_lock(&amp_mgr_list_lock); 868 list_for_each_entry(mgr, &amp_mgr_list, list) { 869 if (test_and_clear_bit(state, &mgr->state)) { 870 amp_mgr_get(mgr); 871 mutex_unlock(&amp_mgr_list_lock); 872 return mgr; 873 } 874 } 875 mutex_unlock(&amp_mgr_list_lock); 876 877 return NULL; 878} 879 880void a2mp_send_getinfo_rsp(struct hci_dev *hdev) 881{ 882 struct amp_mgr *mgr; 883 struct a2mp_info_rsp rsp; 884 885 mgr = amp_mgr_lookup_by_state(READ_LOC_AMP_INFO); 886 if (!mgr) 887 return; 888 889 BT_DBG("%s mgr %p", hdev->name, mgr); 890 891 rsp.id = hdev->id; 892 rsp.status = A2MP_STATUS_INVALID_CTRL_ID; 893 894 if (hdev->amp_type != AMP_TYPE_BREDR) { 895 rsp.status = 0; 896 rsp.total_bw = cpu_to_le32(hdev->amp_total_bw); 897 rsp.max_bw = cpu_to_le32(hdev->amp_max_bw); 898 rsp.min_latency = cpu_to_le32(hdev->amp_min_latency); 899 rsp.pal_cap = cpu_to_le16(hdev->amp_pal_cap); 900 rsp.assoc_size = cpu_to_le16(hdev->amp_assoc_size); 901 } 902 903 a2mp_send(mgr, A2MP_GETINFO_RSP, mgr->ident, sizeof(rsp), &rsp); 904 amp_mgr_put(mgr); 905} 906 907void a2mp_send_getampassoc_rsp(struct hci_dev *hdev, u8 status) 908{ 909 struct amp_mgr *mgr; 910 struct amp_assoc *loc_assoc = &hdev->loc_assoc; 911 struct a2mp_amp_assoc_rsp *rsp; 912 size_t len; 913 914 mgr = amp_mgr_lookup_by_state(READ_LOC_AMP_ASSOC); 915 if (!mgr) 916 return; 917 918 BT_DBG("%s mgr %p", hdev->name, mgr); 919 920 len = sizeof(struct a2mp_amp_assoc_rsp) + loc_assoc->len; 921 rsp = kzalloc(len, GFP_KERNEL); 922 if (!rsp) { 923 amp_mgr_put(mgr); 924 return; 925 } 926 927 rsp->id = hdev->id; 928 929 if (status) { 930 rsp->status = A2MP_STATUS_INVALID_CTRL_ID; 931 } else { 932 rsp->status = A2MP_STATUS_SUCCESS; 933 memcpy(rsp->amp_assoc, loc_assoc->data, loc_assoc->len); 934 } 935 936 a2mp_send(mgr, A2MP_GETAMPASSOC_RSP, mgr->ident, len, rsp); 937 amp_mgr_put(mgr); 938 kfree(rsp); 939} 940 941void a2mp_send_create_phy_link_req(struct hci_dev *hdev, u8 status) 942{ 943 struct amp_mgr *mgr; 944 struct amp_assoc *loc_assoc = &hdev->loc_assoc; 945 struct a2mp_physlink_req *req; 946 struct l2cap_chan *bredr_chan; 947 size_t len; 948 949 mgr = amp_mgr_lookup_by_state(READ_LOC_AMP_ASSOC_FINAL); 950 if (!mgr) 951 return; 952 953 len = sizeof(*req) + loc_assoc->len; 954 955 BT_DBG("%s mgr %p assoc_len %zu", hdev->name, mgr, len); 956 957 req = kzalloc(len, GFP_KERNEL); 958 if (!req) { 959 amp_mgr_put(mgr); 960 return; 961 } 962 963 bredr_chan = mgr->bredr_chan; 964 if (!bredr_chan) 965 goto clean; 966 967 req->local_id = hdev->id; 968 req->remote_id = bredr_chan->remote_amp_id; 969 memcpy(req->amp_assoc, loc_assoc->data, loc_assoc->len); 970 971 a2mp_send(mgr, A2MP_CREATEPHYSLINK_REQ, __next_ident(mgr), len, req); 972 973clean: 974 amp_mgr_put(mgr); 975 kfree(req); 976} 977 978void a2mp_send_create_phy_link_rsp(struct hci_dev *hdev, u8 status) 979{ 980 struct amp_mgr *mgr; 981 struct a2mp_physlink_rsp rsp; 982 struct hci_conn *hs_hcon; 983 984 mgr = amp_mgr_lookup_by_state(WRITE_REMOTE_AMP_ASSOC); 985 if (!mgr) 986 return; 987 988 hs_hcon = hci_conn_hash_lookup_state(hdev, AMP_LINK, BT_CONNECT); 989 if (!hs_hcon) { 990 rsp.status = A2MP_STATUS_UNABLE_START_LINK_CREATION; 991 } else { 992 rsp.remote_id = hs_hcon->remote_id; 993 rsp.status = A2MP_STATUS_SUCCESS; 994 } 995 996 BT_DBG("%s mgr %p hs_hcon %p status %u", hdev->name, mgr, hs_hcon, 997 status); 998 999 rsp.local_id = hdev->id; 1000 a2mp_send(mgr, A2MP_CREATEPHYSLINK_RSP, mgr->ident, sizeof(rsp), &rsp); 1001 amp_mgr_put(mgr); 1002} 1003 1004void a2mp_discover_amp(struct l2cap_chan *chan) 1005{ 1006 struct l2cap_conn *conn = chan->conn; 1007 struct amp_mgr *mgr = conn->hcon->amp_mgr; 1008 struct a2mp_discov_req req; 1009 1010 BT_DBG("chan %p conn %p mgr %p", chan, conn, mgr); 1011 1012 if (!mgr) { 1013 mgr = amp_mgr_create(conn, true); 1014 if (!mgr) 1015 return; 1016 } 1017 1018 mgr->bredr_chan = chan; 1019 1020 req.mtu = cpu_to_le16(L2CAP_A2MP_DEFAULT_MTU); 1021 req.ext_feat = 0; 1022 a2mp_send(mgr, A2MP_DISCOVER_REQ, 1, sizeof(req), &req); 1023}