1 /* 2 * Copyright (c) 2005-2011 Atheros Communications Inc. 3 * Copyright (c) 2011-2013 Qualcomm Atheros, Inc. 4 * 5 * Permission to use, copy, modify, and/or distribute this software for any 6 * purpose with or without fee is hereby granted, provided that the above 7 * copyright notice and this permission notice appear in all copies. 8 * 9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16 */ 17 18 #include "core.h" 19 #include "hif.h" 20 #include "debug.h" 21 22 /********/ 23 /* Send */ 24 /********/ 25 26 static inline void ath10k_htc_send_complete_check(struct ath10k_htc_ep *ep, 27 int force) 28 { 29 /* 30 * Check whether HIF has any prior sends that have finished, 31 * have not had the post-processing done. 32 */ 33 ath10k_hif_send_complete_check(ep->htc->ar, ep->ul_pipe_id, force); 34 } 35 36 static void ath10k_htc_control_tx_complete(struct ath10k *ar, 37 struct sk_buff *skb) 38 { 39 kfree_skb(skb); 40 } 41 42 static struct sk_buff *ath10k_htc_build_tx_ctrl_skb(void *ar) 43 { 44 struct sk_buff *skb; 45 struct ath10k_skb_cb *skb_cb; 46 47 skb = dev_alloc_skb(ATH10K_HTC_CONTROL_BUFFER_SIZE); 48 if (!skb) { 49 ath10k_warn("Unable to allocate ctrl skb\n"); 50 return NULL; 51 } 52 53 skb_reserve(skb, 20); /* FIXME: why 20 bytes? */ 54 WARN_ONCE((unsigned long)skb->data & 3, "unaligned skb"); 55 56 skb_cb = ATH10K_SKB_CB(skb); 57 memset(skb_cb, 0, sizeof(*skb_cb)); 58 59 ath10k_dbg(ATH10K_DBG_HTC, "%s: skb %p\n", __func__, skb); 60 return skb; 61 } 62 63 static inline void ath10k_htc_restore_tx_skb(struct ath10k_htc *htc, 64 struct sk_buff *skb) 65 { 66 ath10k_skb_unmap(htc->ar->dev, skb); 67 skb_pull(skb, sizeof(struct ath10k_htc_hdr)); 68 } 69 70 static void ath10k_htc_notify_tx_completion(struct ath10k_htc_ep *ep, 71 struct sk_buff *skb) 72 { 73 ath10k_dbg(ATH10K_DBG_HTC, "%s: ep %d skb %p\n", __func__, 74 ep->eid, skb); 75 76 ath10k_htc_restore_tx_skb(ep->htc, skb); 77 78 if (!ep->ep_ops.ep_tx_complete) { 79 ath10k_warn("no tx handler for eid %d\n", ep->eid); 80 dev_kfree_skb_any(skb); 81 return; 82 } 83 84 ep->ep_ops.ep_tx_complete(ep->htc->ar, skb); 85 } 86 87 /* assumes tx_lock is held */ 88 static bool ath10k_htc_ep_need_credit_update(struct ath10k_htc_ep *ep) 89 { 90 if (!ep->tx_credit_flow_enabled) 91 return false; 92 if (ep->tx_credits >= ep->tx_credits_per_max_message) 93 return false; 94 95 ath10k_dbg(ATH10K_DBG_HTC, "HTC: endpoint %d needs credit update\n", 96 ep->eid); 97 return true; 98 } 99 100 static void ath10k_htc_prepare_tx_skb(struct ath10k_htc_ep *ep, 101 struct sk_buff *skb) 102 { 103 struct ath10k_htc_hdr *hdr; 104 105 hdr = (struct ath10k_htc_hdr *)skb->data; 106 memset(hdr, 0, sizeof(*hdr)); 107 108 hdr->eid = ep->eid; 109 hdr->len = __cpu_to_le16(skb->len - sizeof(*hdr)); 110 111 spin_lock_bh(&ep->htc->tx_lock); 112 hdr->seq_no = ep->seq_no++; 113 114 if (ath10k_htc_ep_need_credit_update(ep)) 115 hdr->flags |= ATH10K_HTC_FLAG_NEED_CREDIT_UPDATE; 116 117 spin_unlock_bh(&ep->htc->tx_lock); 118 } 119 120 static int ath10k_htc_issue_skb(struct ath10k_htc *htc, 121 struct ath10k_htc_ep *ep, 122 struct sk_buff *skb, 123 u8 credits) 124 { 125 struct ath10k_skb_cb *skb_cb = ATH10K_SKB_CB(skb); 126 int ret; 127 128 ath10k_dbg(ATH10K_DBG_HTC, "%s: ep %d skb %p\n", __func__, 129 ep->eid, skb); 130 131 ath10k_htc_prepare_tx_skb(ep, skb); 132 133 ret = ath10k_skb_map(htc->ar->dev, skb); 134 if (ret) 135 goto err; 136 137 ret = ath10k_hif_send_head(htc->ar, 138 ep->ul_pipe_id, 139 ep->eid, 140 skb->len, 141 skb); 142 if (unlikely(ret)) 143 goto err; 144 145 return 0; 146 err: 147 ath10k_warn("HTC issue failed: %d\n", ret); 148 149 spin_lock_bh(&htc->tx_lock); 150 ep->tx_credits += credits; 151 spin_unlock_bh(&htc->tx_lock); 152 153 /* this is the simplest way to handle out-of-resources for non-credit 154 * based endpoints. credit based endpoints can still get -ENOSR, but 155 * this is highly unlikely as credit reservation should prevent that */ 156 if (ret == -ENOSR) { 157 spin_lock_bh(&htc->tx_lock); 158 __skb_queue_head(&ep->tx_queue, skb); 159 spin_unlock_bh(&htc->tx_lock); 160 161 return ret; 162 } 163 164 skb_cb->is_aborted = true; 165 ath10k_htc_notify_tx_completion(ep, skb); 166 167 return ret; 168 } 169 170 static struct sk_buff *ath10k_htc_get_skb_credit_based(struct ath10k_htc *htc, 171 struct ath10k_htc_ep *ep, 172 u8 *credits) 173 { 174 struct sk_buff *skb; 175 struct ath10k_skb_cb *skb_cb; 176 int credits_required; 177 int remainder; 178 unsigned int transfer_len; 179 180 lockdep_assert_held(&htc->tx_lock); 181 182 skb = __skb_dequeue(&ep->tx_queue); 183 if (!skb) 184 return NULL; 185 186 skb_cb = ATH10K_SKB_CB(skb); 187 transfer_len = skb->len; 188 189 if (likely(transfer_len <= htc->target_credit_size)) { 190 credits_required = 1; 191 } else { 192 /* figure out how many credits this message requires */ 193 credits_required = transfer_len / htc->target_credit_size; 194 remainder = transfer_len % htc->target_credit_size; 195 196 if (remainder) 197 credits_required++; 198 } 199 200 ath10k_dbg(ATH10K_DBG_HTC, "Credits required %d got %d\n", 201 credits_required, ep->tx_credits); 202 203 if (ep->tx_credits < credits_required) { 204 __skb_queue_head(&ep->tx_queue, skb); 205 return NULL; 206 } 207 208 ep->tx_credits -= credits_required; 209 *credits = credits_required; 210 return skb; 211 } 212 213 static void ath10k_htc_send_work(struct work_struct *work) 214 { 215 struct ath10k_htc_ep *ep = container_of(work, 216 struct ath10k_htc_ep, send_work); 217 struct ath10k_htc *htc = ep->htc; 218 struct sk_buff *skb; 219 u8 credits = 0; 220 int ret; 221 222 while (true) { 223 if (ep->ul_is_polled) 224 ath10k_htc_send_complete_check(ep, 0); 225 226 spin_lock_bh(&htc->tx_lock); 227 if (ep->tx_credit_flow_enabled) 228 skb = ath10k_htc_get_skb_credit_based(htc, ep, 229 &credits); 230 else 231 skb = __skb_dequeue(&ep->tx_queue); 232 spin_unlock_bh(&htc->tx_lock); 233 234 if (!skb) 235 break; 236 237 ret = ath10k_htc_issue_skb(htc, ep, skb, credits); 238 if (ret == -ENOSR) 239 break; 240 } 241 } 242 243 int ath10k_htc_send(struct ath10k_htc *htc, 244 enum ath10k_htc_ep_id eid, 245 struct sk_buff *skb) 246 { 247 struct ath10k_htc_ep *ep = &htc->endpoint[eid]; 248 249 if (htc->ar->state == ATH10K_STATE_WEDGED) 250 return -ECOMM; 251 252 if (eid >= ATH10K_HTC_EP_COUNT) { 253 ath10k_warn("Invalid endpoint id: %d\n", eid); 254 return -ENOENT; 255 } 256 257 spin_lock_bh(&htc->tx_lock); 258 if (htc->stopped) { 259 spin_unlock_bh(&htc->tx_lock); 260 return -ESHUTDOWN; 261 } 262 263 __skb_queue_tail(&ep->tx_queue, skb); 264 skb_push(skb, sizeof(struct ath10k_htc_hdr)); 265 spin_unlock_bh(&htc->tx_lock); 266 267 queue_work(htc->ar->workqueue, &ep->send_work); 268 return 0; 269 } 270 271 static int ath10k_htc_tx_completion_handler(struct ath10k *ar, 272 struct sk_buff *skb, 273 unsigned int eid) 274 { 275 struct ath10k_htc *htc = &ar->htc; 276 struct ath10k_htc_ep *ep = &htc->endpoint[eid]; 277 278 ath10k_htc_notify_tx_completion(ep, skb); 279 /* the skb now belongs to the completion handler */ 280 281 /* note: when using TX credit flow, the re-checking of queues happens 282 * when credits flow back from the target. in the non-TX credit case, 283 * we recheck after the packet completes */ 284 spin_lock_bh(&htc->tx_lock); 285 if (!ep->tx_credit_flow_enabled && !htc->stopped) 286 queue_work(ar->workqueue, &ep->send_work); 287 spin_unlock_bh(&htc->tx_lock); 288 289 return 0; 290 } 291 292 /* flush endpoint TX queue */ 293 static void ath10k_htc_flush_endpoint_tx(struct ath10k_htc *htc, 294 struct ath10k_htc_ep *ep) 295 { 296 struct sk_buff *skb; 297 struct ath10k_skb_cb *skb_cb; 298 299 spin_lock_bh(&htc->tx_lock); 300 for (;;) { 301 skb = __skb_dequeue(&ep->tx_queue); 302 if (!skb) 303 break; 304 305 skb_cb = ATH10K_SKB_CB(skb); 306 skb_cb->is_aborted = true; 307 ath10k_htc_notify_tx_completion(ep, skb); 308 } 309 spin_unlock_bh(&htc->tx_lock); 310 311 cancel_work_sync(&ep->send_work); 312 } 313 314 /***********/ 315 /* Receive */ 316 /***********/ 317 318 static void 319 ath10k_htc_process_credit_report(struct ath10k_htc *htc, 320 const struct ath10k_htc_credit_report *report, 321 int len, 322 enum ath10k_htc_ep_id eid) 323 { 324 struct ath10k_htc_ep *ep; 325 int i, n_reports; 326 327 if (len % sizeof(*report)) 328 ath10k_warn("Uneven credit report len %d", len); 329 330 n_reports = len / sizeof(*report); 331 332 spin_lock_bh(&htc->tx_lock); 333 for (i = 0; i < n_reports; i++, report++) { 334 if (report->eid >= ATH10K_HTC_EP_COUNT) 335 break; 336 337 ath10k_dbg(ATH10K_DBG_HTC, "ep %d got %d credits\n", 338 report->eid, report->credits); 339 340 ep = &htc->endpoint[report->eid]; 341 ep->tx_credits += report->credits; 342 343 if (ep->tx_credits && !skb_queue_empty(&ep->tx_queue)) 344 queue_work(htc->ar->workqueue, &ep->send_work); 345 } 346 spin_unlock_bh(&htc->tx_lock); 347 } 348 349 static int ath10k_htc_process_trailer(struct ath10k_htc *htc, 350 u8 *buffer, 351 int length, 352 enum ath10k_htc_ep_id src_eid) 353 { 354 int status = 0; 355 struct ath10k_htc_record *record; 356 u8 *orig_buffer; 357 int orig_length; 358 size_t len; 359 360 orig_buffer = buffer; 361 orig_length = length; 362 363 while (length > 0) { 364 record = (struct ath10k_htc_record *)buffer; 365 366 if (length < sizeof(record->hdr)) { 367 status = -EINVAL; 368 break; 369 } 370 371 if (record->hdr.len > length) { 372 /* no room left in buffer for record */ 373 ath10k_warn("Invalid record length: %d\n", 374 record->hdr.len); 375 status = -EINVAL; 376 break; 377 } 378 379 switch (record->hdr.id) { 380 case ATH10K_HTC_RECORD_CREDITS: 381 len = sizeof(struct ath10k_htc_credit_report); 382 if (record->hdr.len < len) { 383 ath10k_warn("Credit report too long\n"); 384 status = -EINVAL; 385 break; 386 } 387 ath10k_htc_process_credit_report(htc, 388 record->credit_report, 389 record->hdr.len, 390 src_eid); 391 break; 392 default: 393 ath10k_warn("Unhandled record: id:%d length:%d\n", 394 record->hdr.id, record->hdr.len); 395 break; 396 } 397 398 if (status) 399 break; 400 401 /* multiple records may be present in a trailer */ 402 buffer += sizeof(record->hdr) + record->hdr.len; 403 length -= sizeof(record->hdr) + record->hdr.len; 404 } 405 406 if (status) 407 ath10k_dbg_dump(ATH10K_DBG_HTC, "htc rx bad trailer", "", 408 orig_buffer, orig_length); 409 410 return status; 411 } 412 413 static int ath10k_htc_rx_completion_handler(struct ath10k *ar, 414 struct sk_buff *skb, 415 u8 pipe_id) 416 { 417 int status = 0; 418 struct ath10k_htc *htc = &ar->htc; 419 struct ath10k_htc_hdr *hdr; 420 struct ath10k_htc_ep *ep; 421 u16 payload_len; 422 u32 trailer_len = 0; 423 size_t min_len; 424 u8 eid; 425 bool trailer_present; 426 427 hdr = (struct ath10k_htc_hdr *)skb->data; 428 skb_pull(skb, sizeof(*hdr)); 429 430 eid = hdr->eid; 431 432 if (eid >= ATH10K_HTC_EP_COUNT) { 433 ath10k_warn("HTC Rx: invalid eid %d\n", eid); 434 ath10k_dbg_dump(ATH10K_DBG_HTC, "htc bad header", "", 435 hdr, sizeof(*hdr)); 436 status = -EINVAL; 437 goto out; 438 } 439 440 ep = &htc->endpoint[eid]; 441 442 /* 443 * If this endpoint that received a message from the target has 444 * a to-target HIF pipe whose send completions are polled rather 445 * than interrupt-driven, this is a good point to ask HIF to check 446 * whether it has any completed sends to handle. 447 */ 448 if (ep->ul_is_polled) 449 ath10k_htc_send_complete_check(ep, 1); 450 451 payload_len = __le16_to_cpu(hdr->len); 452 453 if (payload_len + sizeof(*hdr) > ATH10K_HTC_MAX_LEN) { 454 ath10k_warn("HTC rx frame too long, len: %zu\n", 455 payload_len + sizeof(*hdr)); 456 ath10k_dbg_dump(ATH10K_DBG_HTC, "htc bad rx pkt len", "", 457 hdr, sizeof(*hdr)); 458 status = -EINVAL; 459 goto out; 460 } 461 462 if (skb->len < payload_len) { 463 ath10k_dbg(ATH10K_DBG_HTC, 464 "HTC Rx: insufficient length, got %d, expected %d\n", 465 skb->len, payload_len); 466 ath10k_dbg_dump(ATH10K_DBG_HTC, "htc bad rx pkt len", 467 "", hdr, sizeof(*hdr)); 468 status = -EINVAL; 469 goto out; 470 } 471 472 /* get flags to check for trailer */ 473 trailer_present = hdr->flags & ATH10K_HTC_FLAG_TRAILER_PRESENT; 474 if (trailer_present) { 475 u8 *trailer; 476 477 trailer_len = hdr->trailer_len; 478 min_len = sizeof(struct ath10k_ath10k_htc_record_hdr); 479 480 if ((trailer_len < min_len) || 481 (trailer_len > payload_len)) { 482 ath10k_warn("Invalid trailer length: %d\n", 483 trailer_len); 484 status = -EPROTO; 485 goto out; 486 } 487 488 trailer = (u8 *)hdr; 489 trailer += sizeof(*hdr); 490 trailer += payload_len; 491 trailer -= trailer_len; 492 status = ath10k_htc_process_trailer(htc, trailer, 493 trailer_len, hdr->eid); 494 if (status) 495 goto out; 496 497 skb_trim(skb, skb->len - trailer_len); 498 } 499 500 if (((int)payload_len - (int)trailer_len) <= 0) 501 /* zero length packet with trailer data, just drop these */ 502 goto out; 503 504 if (eid == ATH10K_HTC_EP_0) { 505 struct ath10k_htc_msg *msg = (struct ath10k_htc_msg *)skb->data; 506 507 switch (__le16_to_cpu(msg->hdr.message_id)) { 508 default: 509 /* handle HTC control message */ 510 if (completion_done(&htc->ctl_resp)) { 511 /* 512 * this is a fatal error, target should not be 513 * sending unsolicited messages on the ep 0 514 */ 515 ath10k_warn("HTC rx ctrl still processing\n"); 516 status = -EINVAL; 517 complete(&htc->ctl_resp); 518 goto out; 519 } 520 521 htc->control_resp_len = 522 min_t(int, skb->len, 523 ATH10K_HTC_MAX_CTRL_MSG_LEN); 524 525 memcpy(htc->control_resp_buffer, skb->data, 526 htc->control_resp_len); 527 528 complete(&htc->ctl_resp); 529 break; 530 case ATH10K_HTC_MSG_SEND_SUSPEND_COMPLETE: 531 htc->htc_ops.target_send_suspend_complete(ar); 532 } 533 goto out; 534 } 535 536 ath10k_dbg(ATH10K_DBG_HTC, "htc rx completion ep %d skb %p\n", 537 eid, skb); 538 ep->ep_ops.ep_rx_complete(ar, skb); 539 540 /* skb is now owned by the rx completion handler */ 541 skb = NULL; 542 out: 543 kfree_skb(skb); 544 545 return status; 546 } 547 548 static void ath10k_htc_control_rx_complete(struct ath10k *ar, 549 struct sk_buff *skb) 550 { 551 /* This is unexpected. FW is not supposed to send regular rx on this 552 * endpoint. */ 553 ath10k_warn("unexpected htc rx\n"); 554 kfree_skb(skb); 555 } 556 557 /***************/ 558 /* Init/Deinit */ 559 /***************/ 560 561 static const char *htc_service_name(enum ath10k_htc_svc_id id) 562 { 563 switch (id) { 564 case ATH10K_HTC_SVC_ID_RESERVED: 565 return "Reserved"; 566 case ATH10K_HTC_SVC_ID_RSVD_CTRL: 567 return "Control"; 568 case ATH10K_HTC_SVC_ID_WMI_CONTROL: 569 return "WMI"; 570 case ATH10K_HTC_SVC_ID_WMI_DATA_BE: 571 return "DATA BE"; 572 case ATH10K_HTC_SVC_ID_WMI_DATA_BK: 573 return "DATA BK"; 574 case ATH10K_HTC_SVC_ID_WMI_DATA_VI: 575 return "DATA VI"; 576 case ATH10K_HTC_SVC_ID_WMI_DATA_VO: 577 return "DATA VO"; 578 case ATH10K_HTC_SVC_ID_NMI_CONTROL: 579 return "NMI Control"; 580 case ATH10K_HTC_SVC_ID_NMI_DATA: 581 return "NMI Data"; 582 case ATH10K_HTC_SVC_ID_HTT_DATA_MSG: 583 return "HTT Data"; 584 case ATH10K_HTC_SVC_ID_TEST_RAW_STREAMS: 585 return "RAW"; 586 } 587 588 return "Unknown"; 589 } 590 591 static void ath10k_htc_reset_endpoint_states(struct ath10k_htc *htc) 592 { 593 struct ath10k_htc_ep *ep; 594 int i; 595 596 for (i = ATH10K_HTC_EP_0; i < ATH10K_HTC_EP_COUNT; i++) { 597 ep = &htc->endpoint[i]; 598 ep->service_id = ATH10K_HTC_SVC_ID_UNUSED; 599 ep->max_ep_message_len = 0; 600 ep->max_tx_queue_depth = 0; 601 ep->eid = i; 602 skb_queue_head_init(&ep->tx_queue); 603 ep->htc = htc; 604 ep->tx_credit_flow_enabled = true; 605 INIT_WORK(&ep->send_work, ath10k_htc_send_work); 606 } 607 } 608 609 static void ath10k_htc_setup_target_buffer_assignments(struct ath10k_htc *htc) 610 { 611 struct ath10k_htc_svc_tx_credits *entry; 612 613 entry = &htc->service_tx_alloc[0]; 614 615 /* 616 * for PCIE allocate all credists/HTC buffers to WMI. 617 * no buffers are used/required for data. data always 618 * remains on host. 619 */ 620 entry++; 621 entry->service_id = ATH10K_HTC_SVC_ID_WMI_CONTROL; 622 entry->credit_allocation = htc->total_transmit_credits; 623 } 624 625 static u8 ath10k_htc_get_credit_allocation(struct ath10k_htc *htc, 626 u16 service_id) 627 { 628 u8 allocation = 0; 629 int i; 630 631 for (i = 0; i < ATH10K_HTC_EP_COUNT; i++) { 632 if (htc->service_tx_alloc[i].service_id == service_id) 633 allocation = 634 htc->service_tx_alloc[i].credit_allocation; 635 } 636 637 return allocation; 638 } 639 640 int ath10k_htc_wait_target(struct ath10k_htc *htc) 641 { 642 int status = 0; 643 struct ath10k_htc_svc_conn_req conn_req; 644 struct ath10k_htc_svc_conn_resp conn_resp; 645 struct ath10k_htc_msg *msg; 646 u16 message_id; 647 u16 credit_count; 648 u16 credit_size; 649 650 INIT_COMPLETION(htc->ctl_resp); 651 652 status = ath10k_hif_start(htc->ar); 653 if (status) { 654 ath10k_err("could not start HIF (%d)\n", status); 655 goto err_start; 656 } 657 658 status = wait_for_completion_timeout(&htc->ctl_resp, 659 ATH10K_HTC_WAIT_TIMEOUT_HZ); 660 if (status <= 0) { 661 if (status == 0) 662 status = -ETIMEDOUT; 663 664 ath10k_err("ctl_resp never came in (%d)\n", status); 665 goto err_target; 666 } 667 668 if (htc->control_resp_len < sizeof(msg->hdr) + sizeof(msg->ready)) { 669 ath10k_err("Invalid HTC ready msg len:%d\n", 670 htc->control_resp_len); 671 672 status = -ECOMM; 673 goto err_target; 674 } 675 676 msg = (struct ath10k_htc_msg *)htc->control_resp_buffer; 677 message_id = __le16_to_cpu(msg->hdr.message_id); 678 credit_count = __le16_to_cpu(msg->ready.credit_count); 679 credit_size = __le16_to_cpu(msg->ready.credit_size); 680 681 if (message_id != ATH10K_HTC_MSG_READY_ID) { 682 ath10k_err("Invalid HTC ready msg: 0x%x\n", message_id); 683 status = -ECOMM; 684 goto err_target; 685 } 686 687 htc->total_transmit_credits = credit_count; 688 htc->target_credit_size = credit_size; 689 690 ath10k_dbg(ATH10K_DBG_HTC, 691 "Target ready! transmit resources: %d size:%d\n", 692 htc->total_transmit_credits, 693 htc->target_credit_size); 694 695 if ((htc->total_transmit_credits == 0) || 696 (htc->target_credit_size == 0)) { 697 status = -ECOMM; 698 ath10k_err("Invalid credit size received\n"); 699 goto err_target; 700 } 701 702 ath10k_htc_setup_target_buffer_assignments(htc); 703 704 /* setup our pseudo HTC control endpoint connection */ 705 memset(&conn_req, 0, sizeof(conn_req)); 706 memset(&conn_resp, 0, sizeof(conn_resp)); 707 conn_req.ep_ops.ep_tx_complete = ath10k_htc_control_tx_complete; 708 conn_req.ep_ops.ep_rx_complete = ath10k_htc_control_rx_complete; 709 conn_req.max_send_queue_depth = ATH10K_NUM_CONTROL_TX_BUFFERS; 710 conn_req.service_id = ATH10K_HTC_SVC_ID_RSVD_CTRL; 711 712 /* connect fake service */ 713 status = ath10k_htc_connect_service(htc, &conn_req, &conn_resp); 714 if (status) { 715 ath10k_err("could not connect to htc service (%d)\n", status); 716 goto err_target; 717 } 718 719 return 0; 720 err_target: 721 ath10k_hif_stop(htc->ar); 722 err_start: 723 return status; 724 } 725 726 int ath10k_htc_connect_service(struct ath10k_htc *htc, 727 struct ath10k_htc_svc_conn_req *conn_req, 728 struct ath10k_htc_svc_conn_resp *conn_resp) 729 { 730 struct ath10k_htc_msg *msg; 731 struct ath10k_htc_conn_svc *req_msg; 732 struct ath10k_htc_conn_svc_response resp_msg_dummy; 733 struct ath10k_htc_conn_svc_response *resp_msg = &resp_msg_dummy; 734 enum ath10k_htc_ep_id assigned_eid = ATH10K_HTC_EP_COUNT; 735 struct ath10k_htc_ep *ep; 736 struct sk_buff *skb; 737 unsigned int max_msg_size = 0; 738 int length, status; 739 bool disable_credit_flow_ctrl = false; 740 u16 message_id, service_id, flags = 0; 741 u8 tx_alloc = 0; 742 743 /* special case for HTC pseudo control service */ 744 if (conn_req->service_id == ATH10K_HTC_SVC_ID_RSVD_CTRL) { 745 disable_credit_flow_ctrl = true; 746 assigned_eid = ATH10K_HTC_EP_0; 747 max_msg_size = ATH10K_HTC_MAX_CTRL_MSG_LEN; 748 memset(&resp_msg_dummy, 0, sizeof(resp_msg_dummy)); 749 goto setup; 750 } 751 752 tx_alloc = ath10k_htc_get_credit_allocation(htc, 753 conn_req->service_id); 754 if (!tx_alloc) 755 ath10k_dbg(ATH10K_DBG_HTC, 756 "HTC Service %s does not allocate target credits\n", 757 htc_service_name(conn_req->service_id)); 758 759 skb = ath10k_htc_build_tx_ctrl_skb(htc->ar); 760 if (!skb) { 761 ath10k_err("Failed to allocate HTC packet\n"); 762 return -ENOMEM; 763 } 764 765 length = sizeof(msg->hdr) + sizeof(msg->connect_service); 766 skb_put(skb, length); 767 memset(skb->data, 0, length); 768 769 msg = (struct ath10k_htc_msg *)skb->data; 770 msg->hdr.message_id = 771 __cpu_to_le16(ATH10K_HTC_MSG_CONNECT_SERVICE_ID); 772 773 flags |= SM(tx_alloc, ATH10K_HTC_CONN_FLAGS_RECV_ALLOC); 774 775 req_msg = &msg->connect_service; 776 req_msg->flags = __cpu_to_le16(flags); 777 req_msg->service_id = __cpu_to_le16(conn_req->service_id); 778 779 /* Only enable credit flow control for WMI ctrl service */ 780 if (conn_req->service_id != ATH10K_HTC_SVC_ID_WMI_CONTROL) { 781 flags |= ATH10K_HTC_CONN_FLAGS_DISABLE_CREDIT_FLOW_CTRL; 782 disable_credit_flow_ctrl = true; 783 } 784 785 INIT_COMPLETION(htc->ctl_resp); 786 787 status = ath10k_htc_send(htc, ATH10K_HTC_EP_0, skb); 788 if (status) { 789 kfree_skb(skb); 790 return status; 791 } 792 793 /* wait for response */ 794 status = wait_for_completion_timeout(&htc->ctl_resp, 795 ATH10K_HTC_CONN_SVC_TIMEOUT_HZ); 796 if (status <= 0) { 797 if (status == 0) 798 status = -ETIMEDOUT; 799 ath10k_err("Service connect timeout: %d\n", status); 800 return status; 801 } 802 803 /* we controlled the buffer creation, it's aligned */ 804 msg = (struct ath10k_htc_msg *)htc->control_resp_buffer; 805 resp_msg = &msg->connect_service_response; 806 message_id = __le16_to_cpu(msg->hdr.message_id); 807 service_id = __le16_to_cpu(resp_msg->service_id); 808 809 if ((message_id != ATH10K_HTC_MSG_CONNECT_SERVICE_RESP_ID) || 810 (htc->control_resp_len < sizeof(msg->hdr) + 811 sizeof(msg->connect_service_response))) { 812 ath10k_err("Invalid resp message ID 0x%x", message_id); 813 return -EPROTO; 814 } 815 816 ath10k_dbg(ATH10K_DBG_HTC, 817 "HTC Service %s connect response: status: 0x%x, assigned ep: 0x%x\n", 818 htc_service_name(service_id), 819 resp_msg->status, resp_msg->eid); 820 821 conn_resp->connect_resp_code = resp_msg->status; 822 823 /* check response status */ 824 if (resp_msg->status != ATH10K_HTC_CONN_SVC_STATUS_SUCCESS) { 825 ath10k_err("HTC Service %s connect request failed: 0x%x)\n", 826 htc_service_name(service_id), 827 resp_msg->status); 828 return -EPROTO; 829 } 830 831 assigned_eid = (enum ath10k_htc_ep_id)resp_msg->eid; 832 max_msg_size = __le16_to_cpu(resp_msg->max_msg_size); 833 834 setup: 835 836 if (assigned_eid >= ATH10K_HTC_EP_COUNT) 837 return -EPROTO; 838 839 if (max_msg_size == 0) 840 return -EPROTO; 841 842 ep = &htc->endpoint[assigned_eid]; 843 ep->eid = assigned_eid; 844 845 if (ep->service_id != ATH10K_HTC_SVC_ID_UNUSED) 846 return -EPROTO; 847 848 /* return assigned endpoint to caller */ 849 conn_resp->eid = assigned_eid; 850 conn_resp->max_msg_len = __le16_to_cpu(resp_msg->max_msg_size); 851 852 /* setup the endpoint */ 853 ep->service_id = conn_req->service_id; 854 ep->max_tx_queue_depth = conn_req->max_send_queue_depth; 855 ep->max_ep_message_len = __le16_to_cpu(resp_msg->max_msg_size); 856 ep->tx_credits = tx_alloc; 857 ep->tx_credit_size = htc->target_credit_size; 858 ep->tx_credits_per_max_message = ep->max_ep_message_len / 859 htc->target_credit_size; 860 861 if (ep->max_ep_message_len % htc->target_credit_size) 862 ep->tx_credits_per_max_message++; 863 864 /* copy all the callbacks */ 865 ep->ep_ops = conn_req->ep_ops; 866 867 status = ath10k_hif_map_service_to_pipe(htc->ar, 868 ep->service_id, 869 &ep->ul_pipe_id, 870 &ep->dl_pipe_id, 871 &ep->ul_is_polled, 872 &ep->dl_is_polled); 873 if (status) 874 return status; 875 876 ath10k_dbg(ATH10K_DBG_HTC, 877 "HTC service: %s UL pipe: %d DL pipe: %d eid: %d ready\n", 878 htc_service_name(ep->service_id), ep->ul_pipe_id, 879 ep->dl_pipe_id, ep->eid); 880 881 ath10k_dbg(ATH10K_DBG_HTC, 882 "EP %d UL polled: %d, DL polled: %d\n", 883 ep->eid, ep->ul_is_polled, ep->dl_is_polled); 884 885 if (disable_credit_flow_ctrl && ep->tx_credit_flow_enabled) { 886 ep->tx_credit_flow_enabled = false; 887 ath10k_dbg(ATH10K_DBG_HTC, 888 "HTC service: %s eid: %d TX flow control disabled\n", 889 htc_service_name(ep->service_id), assigned_eid); 890 } 891 892 return status; 893 } 894 895 struct sk_buff *ath10k_htc_alloc_skb(int size) 896 { 897 struct sk_buff *skb; 898 899 skb = dev_alloc_skb(size + sizeof(struct ath10k_htc_hdr)); 900 if (!skb) { 901 ath10k_warn("could not allocate HTC tx skb\n"); 902 return NULL; 903 } 904 905 skb_reserve(skb, sizeof(struct ath10k_htc_hdr)); 906 907 /* FW/HTC requires 4-byte aligned streams */ 908 if (!IS_ALIGNED((unsigned long)skb->data, 4)) 909 ath10k_warn("Unaligned HTC tx skb\n"); 910 911 return skb; 912 } 913 914 int ath10k_htc_start(struct ath10k_htc *htc) 915 { 916 struct sk_buff *skb; 917 int status = 0; 918 struct ath10k_htc_msg *msg; 919 920 skb = ath10k_htc_build_tx_ctrl_skb(htc->ar); 921 if (!skb) 922 return -ENOMEM; 923 924 skb_put(skb, sizeof(msg->hdr) + sizeof(msg->setup_complete_ext)); 925 memset(skb->data, 0, skb->len); 926 927 msg = (struct ath10k_htc_msg *)skb->data; 928 msg->hdr.message_id = 929 __cpu_to_le16(ATH10K_HTC_MSG_SETUP_COMPLETE_EX_ID); 930 931 ath10k_dbg(ATH10K_DBG_HTC, "HTC is using TX credit flow control\n"); 932 933 status = ath10k_htc_send(htc, ATH10K_HTC_EP_0, skb); 934 if (status) { 935 kfree_skb(skb); 936 return status; 937 } 938 939 return 0; 940 } 941 942 /* 943 * stop HTC communications, i.e. stop interrupt reception, and flush all 944 * queued buffers 945 */ 946 void ath10k_htc_stop(struct ath10k_htc *htc) 947 { 948 int i; 949 struct ath10k_htc_ep *ep; 950 951 spin_lock_bh(&htc->tx_lock); 952 htc->stopped = true; 953 spin_unlock_bh(&htc->tx_lock); 954 955 for (i = ATH10K_HTC_EP_0; i < ATH10K_HTC_EP_COUNT; i++) { 956 ep = &htc->endpoint[i]; 957 ath10k_htc_flush_endpoint_tx(htc, ep); 958 } 959 960 ath10k_hif_stop(htc->ar); 961 } 962 963 /* registered target arrival callback from the HIF layer */ 964 int ath10k_htc_init(struct ath10k *ar) 965 { 966 struct ath10k_hif_cb htc_callbacks; 967 struct ath10k_htc_ep *ep = NULL; 968 struct ath10k_htc *htc = &ar->htc; 969 970 spin_lock_init(&htc->tx_lock); 971 972 htc->stopped = false; 973 ath10k_htc_reset_endpoint_states(htc); 974 975 /* setup HIF layer callbacks */ 976 htc_callbacks.rx_completion = ath10k_htc_rx_completion_handler; 977 htc_callbacks.tx_completion = ath10k_htc_tx_completion_handler; 978 htc->ar = ar; 979 980 /* Get HIF default pipe for HTC message exchange */ 981 ep = &htc->endpoint[ATH10K_HTC_EP_0]; 982 983 ath10k_hif_set_callbacks(ar, &htc_callbacks); 984 ath10k_hif_get_default_pipe(ar, &ep->ul_pipe_id, &ep->dl_pipe_id); 985 986 init_completion(&htc->ctl_resp); 987 988 return 0; 989 } 990