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