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 (eid >= ATH10K_HTC_EP_COUNT) { 250 ath10k_warn("Invalid endpoint id: %d\n", eid); 251 return -ENOENT; 252 } 253 254 skb_push(skb, sizeof(struct ath10k_htc_hdr)); 255 256 spin_lock_bh(&htc->tx_lock); 257 __skb_queue_tail(&ep->tx_queue, skb); 258 spin_unlock_bh(&htc->tx_lock); 259 260 queue_work(htc->ar->workqueue, &ep->send_work); 261 return 0; 262 } 263 264 static int ath10k_htc_tx_completion_handler(struct ath10k *ar, 265 struct sk_buff *skb, 266 unsigned int eid) 267 { 268 struct ath10k_htc *htc = ar->htc; 269 struct ath10k_htc_ep *ep = &htc->endpoint[eid]; 270 bool stopping; 271 272 ath10k_htc_notify_tx_completion(ep, skb); 273 /* the skb now belongs to the completion handler */ 274 275 spin_lock_bh(&htc->tx_lock); 276 stopping = htc->stopping; 277 spin_unlock_bh(&htc->tx_lock); 278 279 if (!ep->tx_credit_flow_enabled && !stopping) 280 /* 281 * note: when using TX credit flow, the re-checking of 282 * queues happens when credits flow back from the target. 283 * in the non-TX credit case, we recheck after the packet 284 * completes 285 */ 286 queue_work(ar->workqueue, &ep->send_work); 287 288 return 0; 289 } 290 291 /* flush endpoint TX queue */ 292 static void ath10k_htc_flush_endpoint_tx(struct ath10k_htc *htc, 293 struct ath10k_htc_ep *ep) 294 { 295 struct sk_buff *skb; 296 struct ath10k_skb_cb *skb_cb; 297 298 spin_lock_bh(&htc->tx_lock); 299 for (;;) { 300 skb = __skb_dequeue(&ep->tx_queue); 301 if (!skb) 302 break; 303 304 skb_cb = ATH10K_SKB_CB(skb); 305 skb_cb->is_aborted = true; 306 ath10k_htc_notify_tx_completion(ep, skb); 307 } 308 spin_unlock_bh(&htc->tx_lock); 309 310 cancel_work_sync(&ep->send_work); 311 } 312 313 /***********/ 314 /* Receive */ 315 /***********/ 316 317 static void 318 ath10k_htc_process_credit_report(struct ath10k_htc *htc, 319 const struct ath10k_htc_credit_report *report, 320 int len, 321 enum ath10k_htc_ep_id eid) 322 { 323 struct ath10k_htc_ep *ep; 324 int i, n_reports; 325 326 if (len % sizeof(*report)) 327 ath10k_warn("Uneven credit report len %d", len); 328 329 n_reports = len / sizeof(*report); 330 331 spin_lock_bh(&htc->tx_lock); 332 for (i = 0; i < n_reports; i++, report++) { 333 if (report->eid >= ATH10K_HTC_EP_COUNT) 334 break; 335 336 ath10k_dbg(ATH10K_DBG_HTC, "ep %d got %d credits\n", 337 report->eid, report->credits); 338 339 ep = &htc->endpoint[report->eid]; 340 ep->tx_credits += report->credits; 341 342 if (ep->tx_credits && !skb_queue_empty(&ep->tx_queue)) 343 queue_work(htc->ar->workqueue, &ep->send_work); 344 } 345 spin_unlock_bh(&htc->tx_lock); 346 } 347 348 static int ath10k_htc_process_trailer(struct ath10k_htc *htc, 349 u8 *buffer, 350 int length, 351 enum ath10k_htc_ep_id src_eid) 352 { 353 int status = 0; 354 struct ath10k_htc_record *record; 355 u8 *orig_buffer; 356 int orig_length; 357 size_t len; 358 359 orig_buffer = buffer; 360 orig_length = length; 361 362 while (length > 0) { 363 record = (struct ath10k_htc_record *)buffer; 364 365 if (length < sizeof(record->hdr)) { 366 status = -EINVAL; 367 break; 368 } 369 370 if (record->hdr.len > length) { 371 /* no room left in buffer for record */ 372 ath10k_warn("Invalid record length: %d\n", 373 record->hdr.len); 374 status = -EINVAL; 375 break; 376 } 377 378 switch (record->hdr.id) { 379 case ATH10K_HTC_RECORD_CREDITS: 380 len = sizeof(struct ath10k_htc_credit_report); 381 if (record->hdr.len < len) { 382 ath10k_warn("Credit report too long\n"); 383 status = -EINVAL; 384 break; 385 } 386 ath10k_htc_process_credit_report(htc, 387 record->credit_report, 388 record->hdr.len, 389 src_eid); 390 break; 391 default: 392 ath10k_warn("Unhandled record: id:%d length:%d\n", 393 record->hdr.id, record->hdr.len); 394 break; 395 } 396 397 if (status) 398 break; 399 400 /* multiple records may be present in a trailer */ 401 buffer += sizeof(record->hdr) + record->hdr.len; 402 length -= sizeof(record->hdr) + record->hdr.len; 403 } 404 405 if (status) 406 ath10k_dbg_dump(ATH10K_DBG_HTC, "htc rx bad trailer", "", 407 orig_buffer, orig_length); 408 409 return status; 410 } 411 412 static int ath10k_htc_rx_completion_handler(struct ath10k *ar, 413 struct sk_buff *skb, 414 u8 pipe_id) 415 { 416 int status = 0; 417 struct ath10k_htc *htc = ar->htc; 418 struct ath10k_htc_hdr *hdr; 419 struct ath10k_htc_ep *ep; 420 u16 payload_len; 421 u32 trailer_len = 0; 422 size_t min_len; 423 u8 eid; 424 bool trailer_present; 425 426 hdr = (struct ath10k_htc_hdr *)skb->data; 427 skb_pull(skb, sizeof(*hdr)); 428 429 eid = hdr->eid; 430 431 if (eid >= ATH10K_HTC_EP_COUNT) { 432 ath10k_warn("HTC Rx: invalid eid %d\n", eid); 433 ath10k_dbg_dump(ATH10K_DBG_HTC, "htc bad header", "", 434 hdr, sizeof(*hdr)); 435 status = -EINVAL; 436 goto out; 437 } 438 439 ep = &htc->endpoint[eid]; 440 441 /* 442 * If this endpoint that received a message from the target has 443 * a to-target HIF pipe whose send completions are polled rather 444 * than interrupt-driven, this is a good point to ask HIF to check 445 * whether it has any completed sends to handle. 446 */ 447 if (ep->ul_is_polled) 448 ath10k_htc_send_complete_check(ep, 1); 449 450 payload_len = __le16_to_cpu(hdr->len); 451 452 if (payload_len + sizeof(*hdr) > ATH10K_HTC_MAX_LEN) { 453 ath10k_warn("HTC rx frame too long, len: %zu\n", 454 payload_len + sizeof(*hdr)); 455 ath10k_dbg_dump(ATH10K_DBG_HTC, "htc bad rx pkt len", "", 456 hdr, sizeof(*hdr)); 457 status = -EINVAL; 458 goto out; 459 } 460 461 if (skb->len < payload_len) { 462 ath10k_dbg(ATH10K_DBG_HTC, 463 "HTC Rx: insufficient length, got %d, expected %d\n", 464 skb->len, payload_len); 465 ath10k_dbg_dump(ATH10K_DBG_HTC, "htc bad rx pkt len", 466 "", hdr, sizeof(*hdr)); 467 status = -EINVAL; 468 goto out; 469 } 470 471 /* get flags to check for trailer */ 472 trailer_present = hdr->flags & ATH10K_HTC_FLAG_TRAILER_PRESENT; 473 if (trailer_present) { 474 u8 *trailer; 475 476 trailer_len = hdr->trailer_len; 477 min_len = sizeof(struct ath10k_ath10k_htc_record_hdr); 478 479 if ((trailer_len < min_len) || 480 (trailer_len > payload_len)) { 481 ath10k_warn("Invalid trailer length: %d\n", 482 trailer_len); 483 status = -EPROTO; 484 goto out; 485 } 486 487 trailer = (u8 *)hdr; 488 trailer += sizeof(*hdr); 489 trailer += payload_len; 490 trailer -= trailer_len; 491 status = ath10k_htc_process_trailer(htc, trailer, 492 trailer_len, hdr->eid); 493 if (status) 494 goto out; 495 496 skb_trim(skb, skb->len - trailer_len); 497 } 498 499 if (((int)payload_len - (int)trailer_len) <= 0) 500 /* zero length packet with trailer data, just drop these */ 501 goto out; 502 503 if (eid == ATH10K_HTC_EP_0) { 504 struct ath10k_htc_msg *msg = (struct ath10k_htc_msg *)skb->data; 505 506 switch (__le16_to_cpu(msg->hdr.message_id)) { 507 default: 508 /* handle HTC control message */ 509 if (completion_done(&htc->ctl_resp)) { 510 /* 511 * this is a fatal error, target should not be 512 * sending unsolicited messages on the ep 0 513 */ 514 ath10k_warn("HTC rx ctrl still processing\n"); 515 status = -EINVAL; 516 complete(&htc->ctl_resp); 517 goto out; 518 } 519 520 htc->control_resp_len = 521 min_t(int, skb->len, 522 ATH10K_HTC_MAX_CTRL_MSG_LEN); 523 524 memcpy(htc->control_resp_buffer, skb->data, 525 htc->control_resp_len); 526 527 complete(&htc->ctl_resp); 528 break; 529 case ATH10K_HTC_MSG_SEND_SUSPEND_COMPLETE: 530 htc->htc_ops.target_send_suspend_complete(ar); 531 } 532 goto out; 533 } 534 535 ath10k_dbg(ATH10K_DBG_HTC, "htc rx completion ep %d skb %p\n", 536 eid, skb); 537 ep->ep_ops.ep_rx_complete(ar, skb); 538 539 /* skb is now owned by the rx completion handler */ 540 skb = NULL; 541 out: 542 kfree_skb(skb); 543 544 return status; 545 } 546 547 static void ath10k_htc_control_rx_complete(struct ath10k *ar, 548 struct sk_buff *skb) 549 { 550 /* This is unexpected. FW is not supposed to send regular rx on this 551 * endpoint. */ 552 ath10k_warn("unexpected htc rx\n"); 553 kfree_skb(skb); 554 } 555 556 /***************/ 557 /* Init/Deinit */ 558 /***************/ 559 560 static const char *htc_service_name(enum ath10k_htc_svc_id id) 561 { 562 switch (id) { 563 case ATH10K_HTC_SVC_ID_RESERVED: 564 return "Reserved"; 565 case ATH10K_HTC_SVC_ID_RSVD_CTRL: 566 return "Control"; 567 case ATH10K_HTC_SVC_ID_WMI_CONTROL: 568 return "WMI"; 569 case ATH10K_HTC_SVC_ID_WMI_DATA_BE: 570 return "DATA BE"; 571 case ATH10K_HTC_SVC_ID_WMI_DATA_BK: 572 return "DATA BK"; 573 case ATH10K_HTC_SVC_ID_WMI_DATA_VI: 574 return "DATA VI"; 575 case ATH10K_HTC_SVC_ID_WMI_DATA_VO: 576 return "DATA VO"; 577 case ATH10K_HTC_SVC_ID_NMI_CONTROL: 578 return "NMI Control"; 579 case ATH10K_HTC_SVC_ID_NMI_DATA: 580 return "NMI Data"; 581 case ATH10K_HTC_SVC_ID_HTT_DATA_MSG: 582 return "HTT Data"; 583 case ATH10K_HTC_SVC_ID_TEST_RAW_STREAMS: 584 return "RAW"; 585 } 586 587 return "Unknown"; 588 } 589 590 static void ath10k_htc_reset_endpoint_states(struct ath10k_htc *htc) 591 { 592 struct ath10k_htc_ep *ep; 593 int i; 594 595 for (i = ATH10K_HTC_EP_0; i < ATH10K_HTC_EP_COUNT; i++) { 596 ep = &htc->endpoint[i]; 597 ep->service_id = ATH10K_HTC_SVC_ID_UNUSED; 598 ep->max_ep_message_len = 0; 599 ep->max_tx_queue_depth = 0; 600 ep->eid = i; 601 skb_queue_head_init(&ep->tx_queue); 602 ep->htc = htc; 603 ep->tx_credit_flow_enabled = true; 604 INIT_WORK(&ep->send_work, ath10k_htc_send_work); 605 } 606 } 607 608 static void ath10k_htc_setup_target_buffer_assignments(struct ath10k_htc *htc) 609 { 610 struct ath10k_htc_svc_tx_credits *entry; 611 612 entry = &htc->service_tx_alloc[0]; 613 614 /* 615 * for PCIE allocate all credists/HTC buffers to WMI. 616 * no buffers are used/required for data. data always 617 * remains on host. 618 */ 619 entry++; 620 entry->service_id = ATH10K_HTC_SVC_ID_WMI_CONTROL; 621 entry->credit_allocation = htc->total_transmit_credits; 622 } 623 624 static u8 ath10k_htc_get_credit_allocation(struct ath10k_htc *htc, 625 u16 service_id) 626 { 627 u8 allocation = 0; 628 int i; 629 630 for (i = 0; i < ATH10K_HTC_EP_COUNT; i++) { 631 if (htc->service_tx_alloc[i].service_id == service_id) 632 allocation = 633 htc->service_tx_alloc[i].credit_allocation; 634 } 635 636 return allocation; 637 } 638 639 int ath10k_htc_wait_target(struct ath10k_htc *htc) 640 { 641 int status = 0; 642 struct ath10k_htc_svc_conn_req conn_req; 643 struct ath10k_htc_svc_conn_resp conn_resp; 644 struct ath10k_htc_msg *msg; 645 u16 message_id; 646 u16 credit_count; 647 u16 credit_size; 648 649 INIT_COMPLETION(htc->ctl_resp); 650 651 status = ath10k_hif_start(htc->ar); 652 if (status) { 653 ath10k_err("could not start HIF (%d)\n", status); 654 goto err_start; 655 } 656 657 status = wait_for_completion_timeout(&htc->ctl_resp, 658 ATH10K_HTC_WAIT_TIMEOUT_HZ); 659 if (status <= 0) { 660 if (status == 0) 661 status = -ETIMEDOUT; 662 663 ath10k_err("ctl_resp never came in (%d)\n", status); 664 goto err_target; 665 } 666 667 if (htc->control_resp_len < sizeof(msg->hdr) + sizeof(msg->ready)) { 668 ath10k_err("Invalid HTC ready msg len:%d\n", 669 htc->control_resp_len); 670 671 status = -ECOMM; 672 goto err_target; 673 } 674 675 msg = (struct ath10k_htc_msg *)htc->control_resp_buffer; 676 message_id = __le16_to_cpu(msg->hdr.message_id); 677 credit_count = __le16_to_cpu(msg->ready.credit_count); 678 credit_size = __le16_to_cpu(msg->ready.credit_size); 679 680 if (message_id != ATH10K_HTC_MSG_READY_ID) { 681 ath10k_err("Invalid HTC ready msg: 0x%x\n", message_id); 682 status = -ECOMM; 683 goto err_target; 684 } 685 686 htc->total_transmit_credits = credit_count; 687 htc->target_credit_size = credit_size; 688 689 ath10k_dbg(ATH10K_DBG_HTC, 690 "Target ready! transmit resources: %d size:%d\n", 691 htc->total_transmit_credits, 692 htc->target_credit_size); 693 694 if ((htc->total_transmit_credits == 0) || 695 (htc->target_credit_size == 0)) { 696 status = -ECOMM; 697 ath10k_err("Invalid credit size received\n"); 698 goto err_target; 699 } 700 701 ath10k_htc_setup_target_buffer_assignments(htc); 702 703 /* setup our pseudo HTC control endpoint connection */ 704 memset(&conn_req, 0, sizeof(conn_req)); 705 memset(&conn_resp, 0, sizeof(conn_resp)); 706 conn_req.ep_ops.ep_tx_complete = ath10k_htc_control_tx_complete; 707 conn_req.ep_ops.ep_rx_complete = ath10k_htc_control_rx_complete; 708 conn_req.max_send_queue_depth = ATH10K_NUM_CONTROL_TX_BUFFERS; 709 conn_req.service_id = ATH10K_HTC_SVC_ID_RSVD_CTRL; 710 711 /* connect fake service */ 712 status = ath10k_htc_connect_service(htc, &conn_req, &conn_resp); 713 if (status) { 714 ath10k_err("could not connect to htc service (%d)\n", status); 715 goto err_target; 716 } 717 718 return 0; 719 err_target: 720 ath10k_hif_stop(htc->ar); 721 err_start: 722 return status; 723 } 724 725 int ath10k_htc_connect_service(struct ath10k_htc *htc, 726 struct ath10k_htc_svc_conn_req *conn_req, 727 struct ath10k_htc_svc_conn_resp *conn_resp) 728 { 729 struct ath10k_htc_msg *msg; 730 struct ath10k_htc_conn_svc *req_msg; 731 struct ath10k_htc_conn_svc_response resp_msg_dummy; 732 struct ath10k_htc_conn_svc_response *resp_msg = &resp_msg_dummy; 733 enum ath10k_htc_ep_id assigned_eid = ATH10K_HTC_EP_COUNT; 734 struct ath10k_htc_ep *ep; 735 struct sk_buff *skb; 736 unsigned int max_msg_size = 0; 737 int length, status; 738 bool disable_credit_flow_ctrl = false; 739 u16 message_id, service_id, flags = 0; 740 u8 tx_alloc = 0; 741 742 /* special case for HTC pseudo control service */ 743 if (conn_req->service_id == ATH10K_HTC_SVC_ID_RSVD_CTRL) { 744 disable_credit_flow_ctrl = true; 745 assigned_eid = ATH10K_HTC_EP_0; 746 max_msg_size = ATH10K_HTC_MAX_CTRL_MSG_LEN; 747 memset(&resp_msg_dummy, 0, sizeof(resp_msg_dummy)); 748 goto setup; 749 } 750 751 tx_alloc = ath10k_htc_get_credit_allocation(htc, 752 conn_req->service_id); 753 if (!tx_alloc) 754 ath10k_warn("HTC Service %s does not allocate target credits\n", 755 htc_service_name(conn_req->service_id)); 756 757 skb = ath10k_htc_build_tx_ctrl_skb(htc->ar); 758 if (!skb) { 759 ath10k_err("Failed to allocate HTC packet\n"); 760 return -ENOMEM; 761 } 762 763 length = sizeof(msg->hdr) + sizeof(msg->connect_service); 764 skb_put(skb, length); 765 memset(skb->data, 0, length); 766 767 msg = (struct ath10k_htc_msg *)skb->data; 768 msg->hdr.message_id = 769 __cpu_to_le16(ATH10K_HTC_MSG_CONNECT_SERVICE_ID); 770 771 flags |= SM(tx_alloc, ATH10K_HTC_CONN_FLAGS_RECV_ALLOC); 772 773 req_msg = &msg->connect_service; 774 req_msg->flags = __cpu_to_le16(flags); 775 req_msg->service_id = __cpu_to_le16(conn_req->service_id); 776 777 /* Only enable credit flow control for WMI ctrl service */ 778 if (conn_req->service_id != ATH10K_HTC_SVC_ID_WMI_CONTROL) { 779 flags |= ATH10K_HTC_CONN_FLAGS_DISABLE_CREDIT_FLOW_CTRL; 780 disable_credit_flow_ctrl = true; 781 } 782 783 INIT_COMPLETION(htc->ctl_resp); 784 785 status = ath10k_htc_send(htc, ATH10K_HTC_EP_0, skb); 786 if (status) { 787 kfree_skb(skb); 788 return status; 789 } 790 791 /* wait for response */ 792 status = wait_for_completion_timeout(&htc->ctl_resp, 793 ATH10K_HTC_CONN_SVC_TIMEOUT_HZ); 794 if (status <= 0) { 795 if (status == 0) 796 status = -ETIMEDOUT; 797 ath10k_err("Service connect timeout: %d\n", status); 798 return status; 799 } 800 801 /* we controlled the buffer creation, it's aligned */ 802 msg = (struct ath10k_htc_msg *)htc->control_resp_buffer; 803 resp_msg = &msg->connect_service_response; 804 message_id = __le16_to_cpu(msg->hdr.message_id); 805 service_id = __le16_to_cpu(resp_msg->service_id); 806 807 if ((message_id != ATH10K_HTC_MSG_CONNECT_SERVICE_RESP_ID) || 808 (htc->control_resp_len < sizeof(msg->hdr) + 809 sizeof(msg->connect_service_response))) { 810 ath10k_err("Invalid resp message ID 0x%x", message_id); 811 return -EPROTO; 812 } 813 814 ath10k_dbg(ATH10K_DBG_HTC, 815 "HTC Service %s connect response: status: 0x%x, assigned ep: 0x%x\n", 816 htc_service_name(service_id), 817 resp_msg->status, resp_msg->eid); 818 819 conn_resp->connect_resp_code = resp_msg->status; 820 821 /* check response status */ 822 if (resp_msg->status != ATH10K_HTC_CONN_SVC_STATUS_SUCCESS) { 823 ath10k_err("HTC Service %s connect request failed: 0x%x)\n", 824 htc_service_name(service_id), 825 resp_msg->status); 826 return -EPROTO; 827 } 828 829 assigned_eid = (enum ath10k_htc_ep_id)resp_msg->eid; 830 max_msg_size = __le16_to_cpu(resp_msg->max_msg_size); 831 832 setup: 833 834 if (assigned_eid >= ATH10K_HTC_EP_COUNT) 835 return -EPROTO; 836 837 if (max_msg_size == 0) 838 return -EPROTO; 839 840 ep = &htc->endpoint[assigned_eid]; 841 ep->eid = assigned_eid; 842 843 if (ep->service_id != ATH10K_HTC_SVC_ID_UNUSED) 844 return -EPROTO; 845 846 /* return assigned endpoint to caller */ 847 conn_resp->eid = assigned_eid; 848 conn_resp->max_msg_len = __le16_to_cpu(resp_msg->max_msg_size); 849 850 /* setup the endpoint */ 851 ep->service_id = conn_req->service_id; 852 ep->max_tx_queue_depth = conn_req->max_send_queue_depth; 853 ep->max_ep_message_len = __le16_to_cpu(resp_msg->max_msg_size); 854 ep->tx_credits = tx_alloc; 855 ep->tx_credit_size = htc->target_credit_size; 856 ep->tx_credits_per_max_message = ep->max_ep_message_len / 857 htc->target_credit_size; 858 859 if (ep->max_ep_message_len % htc->target_credit_size) 860 ep->tx_credits_per_max_message++; 861 862 /* copy all the callbacks */ 863 ep->ep_ops = conn_req->ep_ops; 864 865 status = ath10k_hif_map_service_to_pipe(htc->ar, 866 ep->service_id, 867 &ep->ul_pipe_id, 868 &ep->dl_pipe_id, 869 &ep->ul_is_polled, 870 &ep->dl_is_polled); 871 if (status) 872 return status; 873 874 ath10k_dbg(ATH10K_DBG_HTC, 875 "HTC service: %s UL pipe: %d DL pipe: %d eid: %d ready\n", 876 htc_service_name(ep->service_id), ep->ul_pipe_id, 877 ep->dl_pipe_id, ep->eid); 878 879 ath10k_dbg(ATH10K_DBG_HTC, 880 "EP %d UL polled: %d, DL polled: %d\n", 881 ep->eid, ep->ul_is_polled, ep->dl_is_polled); 882 883 if (disable_credit_flow_ctrl && ep->tx_credit_flow_enabled) { 884 ep->tx_credit_flow_enabled = false; 885 ath10k_dbg(ATH10K_DBG_HTC, 886 "HTC service: %s eid: %d TX flow control disabled\n", 887 htc_service_name(ep->service_id), assigned_eid); 888 } 889 890 return status; 891 } 892 893 struct sk_buff *ath10k_htc_alloc_skb(int size) 894 { 895 struct sk_buff *skb; 896 897 skb = dev_alloc_skb(size + sizeof(struct ath10k_htc_hdr)); 898 if (!skb) { 899 ath10k_warn("could not allocate HTC tx skb\n"); 900 return NULL; 901 } 902 903 skb_reserve(skb, sizeof(struct ath10k_htc_hdr)); 904 905 /* FW/HTC requires 4-byte aligned streams */ 906 if (!IS_ALIGNED((unsigned long)skb->data, 4)) 907 ath10k_warn("Unaligned HTC tx skb\n"); 908 909 return skb; 910 } 911 912 int ath10k_htc_start(struct ath10k_htc *htc) 913 { 914 struct sk_buff *skb; 915 int status = 0; 916 struct ath10k_htc_msg *msg; 917 918 skb = ath10k_htc_build_tx_ctrl_skb(htc->ar); 919 if (!skb) 920 return -ENOMEM; 921 922 skb_put(skb, sizeof(msg->hdr) + sizeof(msg->setup_complete_ext)); 923 memset(skb->data, 0, skb->len); 924 925 msg = (struct ath10k_htc_msg *)skb->data; 926 msg->hdr.message_id = 927 __cpu_to_le16(ATH10K_HTC_MSG_SETUP_COMPLETE_EX_ID); 928 929 ath10k_dbg(ATH10K_DBG_HTC, "HTC is using TX credit flow control\n"); 930 931 status = ath10k_htc_send(htc, ATH10K_HTC_EP_0, skb); 932 if (status) { 933 kfree_skb(skb); 934 return status; 935 } 936 937 return 0; 938 } 939 940 /* 941 * stop HTC communications, i.e. stop interrupt reception, and flush all 942 * queued buffers 943 */ 944 void ath10k_htc_stop(struct ath10k_htc *htc) 945 { 946 int i; 947 struct ath10k_htc_ep *ep; 948 949 spin_lock_bh(&htc->tx_lock); 950 htc->stopping = true; 951 spin_unlock_bh(&htc->tx_lock); 952 953 for (i = ATH10K_HTC_EP_0; i < ATH10K_HTC_EP_COUNT; i++) { 954 ep = &htc->endpoint[i]; 955 ath10k_htc_flush_endpoint_tx(htc, ep); 956 } 957 958 ath10k_hif_stop(htc->ar); 959 ath10k_htc_reset_endpoint_states(htc); 960 } 961 962 /* registered target arrival callback from the HIF layer */ 963 struct ath10k_htc *ath10k_htc_create(struct ath10k *ar, 964 struct ath10k_htc_ops *htc_ops) 965 { 966 struct ath10k_hif_cb htc_callbacks; 967 struct ath10k_htc_ep *ep = NULL; 968 struct ath10k_htc *htc = NULL; 969 970 /* FIXME: use struct ath10k instead */ 971 htc = kzalloc(sizeof(struct ath10k_htc), GFP_KERNEL); 972 if (!htc) 973 return ERR_PTR(-ENOMEM); 974 975 spin_lock_init(&htc->tx_lock); 976 977 memcpy(&htc->htc_ops, htc_ops, sizeof(struct ath10k_htc_ops)); 978 979 ath10k_htc_reset_endpoint_states(htc); 980 981 /* setup HIF layer callbacks */ 982 htc_callbacks.rx_completion = ath10k_htc_rx_completion_handler; 983 htc_callbacks.tx_completion = ath10k_htc_tx_completion_handler; 984 htc->ar = ar; 985 986 /* Get HIF default pipe for HTC message exchange */ 987 ep = &htc->endpoint[ATH10K_HTC_EP_0]; 988 989 ath10k_hif_init(ar, &htc_callbacks); 990 ath10k_hif_get_default_pipe(ar, &ep->ul_pipe_id, &ep->dl_pipe_id); 991 992 init_completion(&htc->ctl_resp); 993 994 return htc; 995 } 996 997 void ath10k_htc_destroy(struct ath10k_htc *htc) 998 { 999 kfree(htc); 1000 } 1001