root/drivers/net/wireless/ath/ath10k/htc.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. ath10k_htc_control_tx_complete
  2. ath10k_htc_build_tx_ctrl_skb
  3. ath10k_htc_restore_tx_skb
  4. ath10k_htc_notify_tx_completion
  5. ath10k_htc_prepare_tx_skb
  6. ath10k_htc_send
  7. ath10k_htc_tx_completion_handler
  8. ath10k_htc_process_credit_report
  9. ath10k_htc_process_lookahead
  10. ath10k_htc_process_lookahead_bundle
  11. ath10k_htc_process_trailer
  12. ath10k_htc_rx_completion_handler
  13. ath10k_htc_control_rx_complete
  14. htc_service_name
  15. ath10k_htc_reset_endpoint_states
  16. ath10k_htc_get_credit_allocation
  17. ath10k_htc_wait_target
  18. ath10k_htc_connect_service
  19. ath10k_htc_alloc_skb
  20. ath10k_htc_pktlog_process_rx
  21. ath10k_htc_pktlog_connect
  22. ath10k_htc_pktlog_svc_supported
  23. ath10k_htc_start
  24. ath10k_htc_init

   1 // SPDX-License-Identifier: ISC
   2 /*
   3  * Copyright (c) 2005-2011 Atheros Communications Inc.
   4  * Copyright (c) 2011-2017 Qualcomm Atheros, Inc.
   5  */
   6 
   7 #include "core.h"
   8 #include "hif.h"
   9 #include "debug.h"
  10 
  11 /********/
  12 /* Send */
  13 /********/
  14 
  15 static void ath10k_htc_control_tx_complete(struct ath10k *ar,
  16                                            struct sk_buff *skb)
  17 {
  18         kfree_skb(skb);
  19 }
  20 
  21 static struct sk_buff *ath10k_htc_build_tx_ctrl_skb(void *ar)
  22 {
  23         struct sk_buff *skb;
  24         struct ath10k_skb_cb *skb_cb;
  25 
  26         skb = dev_alloc_skb(ATH10K_HTC_CONTROL_BUFFER_SIZE);
  27         if (!skb)
  28                 return NULL;
  29 
  30         skb_reserve(skb, 20); /* FIXME: why 20 bytes? */
  31         WARN_ONCE((unsigned long)skb->data & 3, "unaligned skb");
  32 
  33         skb_cb = ATH10K_SKB_CB(skb);
  34         memset(skb_cb, 0, sizeof(*skb_cb));
  35 
  36         ath10k_dbg(ar, ATH10K_DBG_HTC, "%s: skb %pK\n", __func__, skb);
  37         return skb;
  38 }
  39 
  40 static inline void ath10k_htc_restore_tx_skb(struct ath10k_htc *htc,
  41                                              struct sk_buff *skb)
  42 {
  43         struct ath10k_skb_cb *skb_cb = ATH10K_SKB_CB(skb);
  44 
  45         if (htc->ar->bus_param.dev_type != ATH10K_DEV_TYPE_HL)
  46                 dma_unmap_single(htc->ar->dev, skb_cb->paddr, skb->len, DMA_TO_DEVICE);
  47         skb_pull(skb, sizeof(struct ath10k_htc_hdr));
  48 }
  49 
  50 void ath10k_htc_notify_tx_completion(struct ath10k_htc_ep *ep,
  51                                      struct sk_buff *skb)
  52 {
  53         struct ath10k *ar = ep->htc->ar;
  54 
  55         ath10k_dbg(ar, ATH10K_DBG_HTC, "%s: ep %d skb %pK\n", __func__,
  56                    ep->eid, skb);
  57 
  58         ath10k_htc_restore_tx_skb(ep->htc, skb);
  59 
  60         if (!ep->ep_ops.ep_tx_complete) {
  61                 ath10k_warn(ar, "no tx handler for eid %d\n", ep->eid);
  62                 dev_kfree_skb_any(skb);
  63                 return;
  64         }
  65 
  66         ep->ep_ops.ep_tx_complete(ep->htc->ar, skb);
  67 }
  68 EXPORT_SYMBOL(ath10k_htc_notify_tx_completion);
  69 
  70 static void ath10k_htc_prepare_tx_skb(struct ath10k_htc_ep *ep,
  71                                       struct sk_buff *skb)
  72 {
  73         struct ath10k_htc_hdr *hdr;
  74 
  75         hdr = (struct ath10k_htc_hdr *)skb->data;
  76         memset(hdr, 0, sizeof(struct ath10k_htc_hdr));
  77 
  78         hdr->eid = ep->eid;
  79         hdr->len = __cpu_to_le16(skb->len - sizeof(*hdr));
  80         hdr->flags = 0;
  81         if (ep->tx_credit_flow_enabled)
  82                 hdr->flags |= ATH10K_HTC_FLAG_NEED_CREDIT_UPDATE;
  83 
  84         spin_lock_bh(&ep->htc->tx_lock);
  85         hdr->seq_no = ep->seq_no++;
  86         spin_unlock_bh(&ep->htc->tx_lock);
  87 }
  88 
  89 int ath10k_htc_send(struct ath10k_htc *htc,
  90                     enum ath10k_htc_ep_id eid,
  91                     struct sk_buff *skb)
  92 {
  93         struct ath10k *ar = htc->ar;
  94         struct ath10k_htc_ep *ep = &htc->endpoint[eid];
  95         struct ath10k_skb_cb *skb_cb = ATH10K_SKB_CB(skb);
  96         struct ath10k_hif_sg_item sg_item;
  97         struct device *dev = htc->ar->dev;
  98         int credits = 0;
  99         int ret;
 100 
 101         if (htc->ar->state == ATH10K_STATE_WEDGED)
 102                 return -ECOMM;
 103 
 104         if (eid >= ATH10K_HTC_EP_COUNT) {
 105                 ath10k_warn(ar, "Invalid endpoint id: %d\n", eid);
 106                 return -ENOENT;
 107         }
 108 
 109         skb_push(skb, sizeof(struct ath10k_htc_hdr));
 110 
 111         if (ep->tx_credit_flow_enabled) {
 112                 credits = DIV_ROUND_UP(skb->len, htc->target_credit_size);
 113                 spin_lock_bh(&htc->tx_lock);
 114                 if (ep->tx_credits < credits) {
 115                         ath10k_dbg(ar, ATH10K_DBG_HTC,
 116                                    "htc insufficient credits ep %d required %d available %d\n",
 117                                    eid, credits, ep->tx_credits);
 118                         spin_unlock_bh(&htc->tx_lock);
 119                         ret = -EAGAIN;
 120                         goto err_pull;
 121                 }
 122                 ep->tx_credits -= credits;
 123                 ath10k_dbg(ar, ATH10K_DBG_HTC,
 124                            "htc ep %d consumed %d credits (total %d)\n",
 125                            eid, credits, ep->tx_credits);
 126                 spin_unlock_bh(&htc->tx_lock);
 127         }
 128 
 129         ath10k_htc_prepare_tx_skb(ep, skb);
 130 
 131         skb_cb->eid = eid;
 132         if (ar->bus_param.dev_type != ATH10K_DEV_TYPE_HL) {
 133                 skb_cb->paddr = dma_map_single(dev, skb->data, skb->len,
 134                                                DMA_TO_DEVICE);
 135                 ret = dma_mapping_error(dev, skb_cb->paddr);
 136                 if (ret) {
 137                         ret = -EIO;
 138                         goto err_credits;
 139                 }
 140         }
 141 
 142         sg_item.transfer_id = ep->eid;
 143         sg_item.transfer_context = skb;
 144         sg_item.vaddr = skb->data;
 145         sg_item.paddr = skb_cb->paddr;
 146         sg_item.len = skb->len;
 147 
 148         ret = ath10k_hif_tx_sg(htc->ar, ep->ul_pipe_id, &sg_item, 1);
 149         if (ret)
 150                 goto err_unmap;
 151 
 152         return 0;
 153 
 154 err_unmap:
 155         if (ar->bus_param.dev_type != ATH10K_DEV_TYPE_HL)
 156                 dma_unmap_single(dev, skb_cb->paddr, skb->len, DMA_TO_DEVICE);
 157 err_credits:
 158         if (ep->tx_credit_flow_enabled) {
 159                 spin_lock_bh(&htc->tx_lock);
 160                 ep->tx_credits += credits;
 161                 ath10k_dbg(ar, ATH10K_DBG_HTC,
 162                            "htc ep %d reverted %d credits back (total %d)\n",
 163                            eid, credits, ep->tx_credits);
 164                 spin_unlock_bh(&htc->tx_lock);
 165 
 166                 if (ep->ep_ops.ep_tx_credits)
 167                         ep->ep_ops.ep_tx_credits(htc->ar);
 168         }
 169 err_pull:
 170         skb_pull(skb, sizeof(struct ath10k_htc_hdr));
 171         return ret;
 172 }
 173 
 174 void ath10k_htc_tx_completion_handler(struct ath10k *ar, struct sk_buff *skb)
 175 {
 176         struct ath10k_htc *htc = &ar->htc;
 177         struct ath10k_skb_cb *skb_cb;
 178         struct ath10k_htc_ep *ep;
 179 
 180         if (WARN_ON_ONCE(!skb))
 181                 return;
 182 
 183         skb_cb = ATH10K_SKB_CB(skb);
 184         ep = &htc->endpoint[skb_cb->eid];
 185 
 186         ath10k_htc_notify_tx_completion(ep, skb);
 187         /* the skb now belongs to the completion handler */
 188 }
 189 EXPORT_SYMBOL(ath10k_htc_tx_completion_handler);
 190 
 191 /***********/
 192 /* Receive */
 193 /***********/
 194 
 195 static void
 196 ath10k_htc_process_credit_report(struct ath10k_htc *htc,
 197                                  const struct ath10k_htc_credit_report *report,
 198                                  int len,
 199                                  enum ath10k_htc_ep_id eid)
 200 {
 201         struct ath10k *ar = htc->ar;
 202         struct ath10k_htc_ep *ep;
 203         int i, n_reports;
 204 
 205         if (len % sizeof(*report))
 206                 ath10k_warn(ar, "Uneven credit report len %d", len);
 207 
 208         n_reports = len / sizeof(*report);
 209 
 210         spin_lock_bh(&htc->tx_lock);
 211         for (i = 0; i < n_reports; i++, report++) {
 212                 if (report->eid >= ATH10K_HTC_EP_COUNT)
 213                         break;
 214 
 215                 ep = &htc->endpoint[report->eid];
 216                 ep->tx_credits += report->credits;
 217 
 218                 ath10k_dbg(ar, ATH10K_DBG_HTC, "htc ep %d got %d credits (total %d)\n",
 219                            report->eid, report->credits, ep->tx_credits);
 220 
 221                 if (ep->ep_ops.ep_tx_credits) {
 222                         spin_unlock_bh(&htc->tx_lock);
 223                         ep->ep_ops.ep_tx_credits(htc->ar);
 224                         spin_lock_bh(&htc->tx_lock);
 225                 }
 226         }
 227         spin_unlock_bh(&htc->tx_lock);
 228 }
 229 
 230 static int
 231 ath10k_htc_process_lookahead(struct ath10k_htc *htc,
 232                              const struct ath10k_htc_lookahead_report *report,
 233                              int len,
 234                              enum ath10k_htc_ep_id eid,
 235                              void *next_lookaheads,
 236                              int *next_lookaheads_len)
 237 {
 238         struct ath10k *ar = htc->ar;
 239 
 240         /* Invalid lookahead flags are actually transmitted by
 241          * the target in the HTC control message.
 242          * Since this will happen at every boot we silently ignore
 243          * the lookahead in this case
 244          */
 245         if (report->pre_valid != ((~report->post_valid) & 0xFF))
 246                 return 0;
 247 
 248         if (next_lookaheads && next_lookaheads_len) {
 249                 ath10k_dbg(ar, ATH10K_DBG_HTC,
 250                            "htc rx lookahead found pre_valid 0x%x post_valid 0x%x\n",
 251                            report->pre_valid, report->post_valid);
 252 
 253                 /* look ahead bytes are valid, copy them over */
 254                 memcpy((u8 *)next_lookaheads, report->lookahead, 4);
 255 
 256                 *next_lookaheads_len = 1;
 257         }
 258 
 259         return 0;
 260 }
 261 
 262 static int
 263 ath10k_htc_process_lookahead_bundle(struct ath10k_htc *htc,
 264                                     const struct ath10k_htc_lookahead_bundle *report,
 265                                     int len,
 266                                     enum ath10k_htc_ep_id eid,
 267                                     void *next_lookaheads,
 268                                     int *next_lookaheads_len)
 269 {
 270         struct ath10k *ar = htc->ar;
 271         int bundle_cnt = len / sizeof(*report);
 272 
 273         if (!bundle_cnt || (bundle_cnt > HTC_HOST_MAX_MSG_PER_RX_BUNDLE)) {
 274                 ath10k_warn(ar, "Invalid lookahead bundle count: %d\n",
 275                             bundle_cnt);
 276                 return -EINVAL;
 277         }
 278 
 279         if (next_lookaheads && next_lookaheads_len) {
 280                 int i;
 281 
 282                 for (i = 0; i < bundle_cnt; i++) {
 283                         memcpy(((u8 *)next_lookaheads) + 4 * i,
 284                                report->lookahead, 4);
 285                         report++;
 286                 }
 287 
 288                 *next_lookaheads_len = bundle_cnt;
 289         }
 290 
 291         return 0;
 292 }
 293 
 294 int ath10k_htc_process_trailer(struct ath10k_htc *htc,
 295                                u8 *buffer,
 296                                int length,
 297                                enum ath10k_htc_ep_id src_eid,
 298                                void *next_lookaheads,
 299                                int *next_lookaheads_len)
 300 {
 301         struct ath10k_htc_lookahead_bundle *bundle;
 302         struct ath10k *ar = htc->ar;
 303         int status = 0;
 304         struct ath10k_htc_record *record;
 305         u8 *orig_buffer;
 306         int orig_length;
 307         size_t len;
 308 
 309         orig_buffer = buffer;
 310         orig_length = length;
 311 
 312         while (length > 0) {
 313                 record = (struct ath10k_htc_record *)buffer;
 314 
 315                 if (length < sizeof(record->hdr)) {
 316                         status = -EINVAL;
 317                         break;
 318                 }
 319 
 320                 if (record->hdr.len > length) {
 321                         /* no room left in buffer for record */
 322                         ath10k_warn(ar, "Invalid record length: %d\n",
 323                                     record->hdr.len);
 324                         status = -EINVAL;
 325                         break;
 326                 }
 327 
 328                 switch (record->hdr.id) {
 329                 case ATH10K_HTC_RECORD_CREDITS:
 330                         len = sizeof(struct ath10k_htc_credit_report);
 331                         if (record->hdr.len < len) {
 332                                 ath10k_warn(ar, "Credit report too long\n");
 333                                 status = -EINVAL;
 334                                 break;
 335                         }
 336                         ath10k_htc_process_credit_report(htc,
 337                                                          record->credit_report,
 338                                                          record->hdr.len,
 339                                                          src_eid);
 340                         break;
 341                 case ATH10K_HTC_RECORD_LOOKAHEAD:
 342                         len = sizeof(struct ath10k_htc_lookahead_report);
 343                         if (record->hdr.len < len) {
 344                                 ath10k_warn(ar, "Lookahead report too long\n");
 345                                 status = -EINVAL;
 346                                 break;
 347                         }
 348                         status = ath10k_htc_process_lookahead(htc,
 349                                                               record->lookahead_report,
 350                                                               record->hdr.len,
 351                                                               src_eid,
 352                                                               next_lookaheads,
 353                                                               next_lookaheads_len);
 354                         break;
 355                 case ATH10K_HTC_RECORD_LOOKAHEAD_BUNDLE:
 356                         bundle = record->lookahead_bundle;
 357                         status = ath10k_htc_process_lookahead_bundle(htc,
 358                                                                      bundle,
 359                                                                      record->hdr.len,
 360                                                                      src_eid,
 361                                                                      next_lookaheads,
 362                                                                      next_lookaheads_len);
 363                         break;
 364                 default:
 365                         ath10k_warn(ar, "Unhandled record: id:%d length:%d\n",
 366                                     record->hdr.id, record->hdr.len);
 367                         break;
 368                 }
 369 
 370                 if (status)
 371                         break;
 372 
 373                 /* multiple records may be present in a trailer */
 374                 buffer += sizeof(record->hdr) + record->hdr.len;
 375                 length -= sizeof(record->hdr) + record->hdr.len;
 376         }
 377 
 378         if (status)
 379                 ath10k_dbg_dump(ar, ATH10K_DBG_HTC, "htc rx bad trailer", "",
 380                                 orig_buffer, orig_length);
 381 
 382         return status;
 383 }
 384 EXPORT_SYMBOL(ath10k_htc_process_trailer);
 385 
 386 void ath10k_htc_rx_completion_handler(struct ath10k *ar, struct sk_buff *skb)
 387 {
 388         int status = 0;
 389         struct ath10k_htc *htc = &ar->htc;
 390         struct ath10k_htc_hdr *hdr;
 391         struct ath10k_htc_ep *ep;
 392         u16 payload_len;
 393         u32 trailer_len = 0;
 394         size_t min_len;
 395         u8 eid;
 396         bool trailer_present;
 397 
 398         hdr = (struct ath10k_htc_hdr *)skb->data;
 399         skb_pull(skb, sizeof(*hdr));
 400 
 401         eid = hdr->eid;
 402 
 403         if (eid >= ATH10K_HTC_EP_COUNT) {
 404                 ath10k_warn(ar, "HTC Rx: invalid eid %d\n", eid);
 405                 ath10k_dbg_dump(ar, ATH10K_DBG_HTC, "htc bad header", "",
 406                                 hdr, sizeof(*hdr));
 407                 goto out;
 408         }
 409 
 410         ep = &htc->endpoint[eid];
 411 
 412         payload_len = __le16_to_cpu(hdr->len);
 413 
 414         if (payload_len + sizeof(*hdr) > ATH10K_HTC_MAX_LEN) {
 415                 ath10k_warn(ar, "HTC rx frame too long, len: %zu\n",
 416                             payload_len + sizeof(*hdr));
 417                 ath10k_dbg_dump(ar, ATH10K_DBG_HTC, "htc bad rx pkt len", "",
 418                                 hdr, sizeof(*hdr));
 419                 goto out;
 420         }
 421 
 422         if (skb->len < payload_len) {
 423                 ath10k_dbg(ar, ATH10K_DBG_HTC,
 424                            "HTC Rx: insufficient length, got %d, expected %d\n",
 425                            skb->len, payload_len);
 426                 ath10k_dbg_dump(ar, ATH10K_DBG_HTC, "htc bad rx pkt len",
 427                                 "", hdr, sizeof(*hdr));
 428                 goto out;
 429         }
 430 
 431         /* get flags to check for trailer */
 432         trailer_present = hdr->flags & ATH10K_HTC_FLAG_TRAILER_PRESENT;
 433         if (trailer_present) {
 434                 u8 *trailer;
 435 
 436                 trailer_len = hdr->trailer_len;
 437                 min_len = sizeof(struct ath10k_ath10k_htc_record_hdr);
 438 
 439                 if ((trailer_len < min_len) ||
 440                     (trailer_len > payload_len)) {
 441                         ath10k_warn(ar, "Invalid trailer length: %d\n",
 442                                     trailer_len);
 443                         goto out;
 444                 }
 445 
 446                 trailer = (u8 *)hdr;
 447                 trailer += sizeof(*hdr);
 448                 trailer += payload_len;
 449                 trailer -= trailer_len;
 450                 status = ath10k_htc_process_trailer(htc, trailer,
 451                                                     trailer_len, hdr->eid,
 452                                                     NULL, NULL);
 453                 if (status)
 454                         goto out;
 455 
 456                 skb_trim(skb, skb->len - trailer_len);
 457         }
 458 
 459         if (((int)payload_len - (int)trailer_len) <= 0)
 460                 /* zero length packet with trailer data, just drop these */
 461                 goto out;
 462 
 463         ath10k_dbg(ar, ATH10K_DBG_HTC, "htc rx completion ep %d skb %pK\n",
 464                    eid, skb);
 465         ep->ep_ops.ep_rx_complete(ar, skb);
 466 
 467         /* skb is now owned by the rx completion handler */
 468         skb = NULL;
 469 out:
 470         kfree_skb(skb);
 471 }
 472 EXPORT_SYMBOL(ath10k_htc_rx_completion_handler);
 473 
 474 static void ath10k_htc_control_rx_complete(struct ath10k *ar,
 475                                            struct sk_buff *skb)
 476 {
 477         struct ath10k_htc *htc = &ar->htc;
 478         struct ath10k_htc_msg *msg = (struct ath10k_htc_msg *)skb->data;
 479 
 480         switch (__le16_to_cpu(msg->hdr.message_id)) {
 481         case ATH10K_HTC_MSG_READY_ID:
 482         case ATH10K_HTC_MSG_CONNECT_SERVICE_RESP_ID:
 483                 /* handle HTC control message */
 484                 if (completion_done(&htc->ctl_resp)) {
 485                         /* this is a fatal error, target should not be
 486                          * sending unsolicited messages on the ep 0
 487                          */
 488                         ath10k_warn(ar, "HTC rx ctrl still processing\n");
 489                         complete(&htc->ctl_resp);
 490                         goto out;
 491                 }
 492 
 493                 htc->control_resp_len =
 494                         min_t(int, skb->len,
 495                               ATH10K_HTC_MAX_CTRL_MSG_LEN);
 496 
 497                 memcpy(htc->control_resp_buffer, skb->data,
 498                        htc->control_resp_len);
 499 
 500                 complete(&htc->ctl_resp);
 501                 break;
 502         case ATH10K_HTC_MSG_SEND_SUSPEND_COMPLETE:
 503                 htc->htc_ops.target_send_suspend_complete(ar);
 504                 break;
 505         default:
 506                 ath10k_warn(ar, "ignoring unsolicited htc ep0 event\n");
 507                 break;
 508         }
 509 
 510 out:
 511         kfree_skb(skb);
 512 }
 513 
 514 /***************/
 515 /* Init/Deinit */
 516 /***************/
 517 
 518 static const char *htc_service_name(enum ath10k_htc_svc_id id)
 519 {
 520         switch (id) {
 521         case ATH10K_HTC_SVC_ID_RESERVED:
 522                 return "Reserved";
 523         case ATH10K_HTC_SVC_ID_RSVD_CTRL:
 524                 return "Control";
 525         case ATH10K_HTC_SVC_ID_WMI_CONTROL:
 526                 return "WMI";
 527         case ATH10K_HTC_SVC_ID_WMI_DATA_BE:
 528                 return "DATA BE";
 529         case ATH10K_HTC_SVC_ID_WMI_DATA_BK:
 530                 return "DATA BK";
 531         case ATH10K_HTC_SVC_ID_WMI_DATA_VI:
 532                 return "DATA VI";
 533         case ATH10K_HTC_SVC_ID_WMI_DATA_VO:
 534                 return "DATA VO";
 535         case ATH10K_HTC_SVC_ID_NMI_CONTROL:
 536                 return "NMI Control";
 537         case ATH10K_HTC_SVC_ID_NMI_DATA:
 538                 return "NMI Data";
 539         case ATH10K_HTC_SVC_ID_HTT_DATA_MSG:
 540                 return "HTT Data";
 541         case ATH10K_HTC_SVC_ID_HTT_DATA2_MSG:
 542                 return "HTT Data";
 543         case ATH10K_HTC_SVC_ID_HTT_DATA3_MSG:
 544                 return "HTT Data";
 545         case ATH10K_HTC_SVC_ID_TEST_RAW_STREAMS:
 546                 return "RAW";
 547         case ATH10K_HTC_SVC_ID_HTT_LOG_MSG:
 548                 return "PKTLOG";
 549         }
 550 
 551         return "Unknown";
 552 }
 553 
 554 static void ath10k_htc_reset_endpoint_states(struct ath10k_htc *htc)
 555 {
 556         struct ath10k_htc_ep *ep;
 557         int i;
 558 
 559         for (i = ATH10K_HTC_EP_0; i < ATH10K_HTC_EP_COUNT; i++) {
 560                 ep = &htc->endpoint[i];
 561                 ep->service_id = ATH10K_HTC_SVC_ID_UNUSED;
 562                 ep->max_ep_message_len = 0;
 563                 ep->max_tx_queue_depth = 0;
 564                 ep->eid = i;
 565                 ep->htc = htc;
 566                 ep->tx_credit_flow_enabled = true;
 567         }
 568 }
 569 
 570 static u8 ath10k_htc_get_credit_allocation(struct ath10k_htc *htc,
 571                                            u16 service_id)
 572 {
 573         u8 allocation = 0;
 574 
 575         /* The WMI control service is the only service with flow control.
 576          * Let it have all transmit credits.
 577          */
 578         if (service_id == ATH10K_HTC_SVC_ID_WMI_CONTROL)
 579                 allocation = htc->total_transmit_credits;
 580 
 581         return allocation;
 582 }
 583 
 584 int ath10k_htc_wait_target(struct ath10k_htc *htc)
 585 {
 586         struct ath10k *ar = htc->ar;
 587         int i, status = 0;
 588         unsigned long time_left;
 589         struct ath10k_htc_msg *msg;
 590         u16 message_id;
 591 
 592         time_left = wait_for_completion_timeout(&htc->ctl_resp,
 593                                                 ATH10K_HTC_WAIT_TIMEOUT_HZ);
 594         if (!time_left) {
 595                 /* Workaround: In some cases the PCI HIF doesn't
 596                  * receive interrupt for the control response message
 597                  * even if the buffer was completed. It is suspected
 598                  * iomap writes unmasking PCI CE irqs aren't propagated
 599                  * properly in KVM PCI-passthrough sometimes.
 600                  */
 601                 ath10k_warn(ar, "failed to receive control response completion, polling..\n");
 602 
 603                 for (i = 0; i < CE_COUNT; i++)
 604                         ath10k_hif_send_complete_check(htc->ar, i, 1);
 605 
 606                 time_left =
 607                 wait_for_completion_timeout(&htc->ctl_resp,
 608                                             ATH10K_HTC_WAIT_TIMEOUT_HZ);
 609 
 610                 if (!time_left)
 611                         status = -ETIMEDOUT;
 612         }
 613 
 614         if (status < 0) {
 615                 ath10k_err(ar, "ctl_resp never came in (%d)\n", status);
 616                 return status;
 617         }
 618 
 619         if (htc->control_resp_len < sizeof(msg->hdr) + sizeof(msg->ready)) {
 620                 ath10k_err(ar, "Invalid HTC ready msg len:%d\n",
 621                            htc->control_resp_len);
 622                 return -ECOMM;
 623         }
 624 
 625         msg = (struct ath10k_htc_msg *)htc->control_resp_buffer;
 626         message_id   = __le16_to_cpu(msg->hdr.message_id);
 627 
 628         if (message_id != ATH10K_HTC_MSG_READY_ID) {
 629                 ath10k_err(ar, "Invalid HTC ready msg: 0x%x\n", message_id);
 630                 return -ECOMM;
 631         }
 632 
 633         htc->total_transmit_credits = __le16_to_cpu(msg->ready.credit_count);
 634         htc->target_credit_size = __le16_to_cpu(msg->ready.credit_size);
 635 
 636         ath10k_dbg(ar, ATH10K_DBG_HTC,
 637                    "Target ready! transmit resources: %d size:%d\n",
 638                    htc->total_transmit_credits,
 639                    htc->target_credit_size);
 640 
 641         if ((htc->total_transmit_credits == 0) ||
 642             (htc->target_credit_size == 0)) {
 643                 ath10k_err(ar, "Invalid credit size received\n");
 644                 return -ECOMM;
 645         }
 646 
 647         /* The only way to determine if the ready message is an extended
 648          * message is from the size.
 649          */
 650         if (htc->control_resp_len >=
 651             sizeof(msg->hdr) + sizeof(msg->ready_ext)) {
 652                 htc->max_msgs_per_htc_bundle =
 653                         min_t(u8, msg->ready_ext.max_msgs_per_htc_bundle,
 654                               HTC_HOST_MAX_MSG_PER_RX_BUNDLE);
 655                 ath10k_dbg(ar, ATH10K_DBG_HTC,
 656                            "Extended ready message. RX bundle size: %d\n",
 657                            htc->max_msgs_per_htc_bundle);
 658         }
 659 
 660         return 0;
 661 }
 662 
 663 int ath10k_htc_connect_service(struct ath10k_htc *htc,
 664                                struct ath10k_htc_svc_conn_req *conn_req,
 665                                struct ath10k_htc_svc_conn_resp *conn_resp)
 666 {
 667         struct ath10k *ar = htc->ar;
 668         struct ath10k_htc_msg *msg;
 669         struct ath10k_htc_conn_svc *req_msg;
 670         struct ath10k_htc_conn_svc_response resp_msg_dummy;
 671         struct ath10k_htc_conn_svc_response *resp_msg = &resp_msg_dummy;
 672         enum ath10k_htc_ep_id assigned_eid = ATH10K_HTC_EP_COUNT;
 673         struct ath10k_htc_ep *ep;
 674         struct sk_buff *skb;
 675         unsigned int max_msg_size = 0;
 676         int length, status;
 677         unsigned long time_left;
 678         bool disable_credit_flow_ctrl = false;
 679         u16 message_id, service_id, flags = 0;
 680         u8 tx_alloc = 0;
 681 
 682         /* special case for HTC pseudo control service */
 683         if (conn_req->service_id == ATH10K_HTC_SVC_ID_RSVD_CTRL) {
 684                 disable_credit_flow_ctrl = true;
 685                 assigned_eid = ATH10K_HTC_EP_0;
 686                 max_msg_size = ATH10K_HTC_MAX_CTRL_MSG_LEN;
 687                 memset(&resp_msg_dummy, 0, sizeof(resp_msg_dummy));
 688                 goto setup;
 689         }
 690 
 691         tx_alloc = ath10k_htc_get_credit_allocation(htc,
 692                                                     conn_req->service_id);
 693         if (!tx_alloc)
 694                 ath10k_dbg(ar, ATH10K_DBG_BOOT,
 695                            "boot htc service %s does not allocate target credits\n",
 696                            htc_service_name(conn_req->service_id));
 697 
 698         skb = ath10k_htc_build_tx_ctrl_skb(htc->ar);
 699         if (!skb) {
 700                 ath10k_err(ar, "Failed to allocate HTC packet\n");
 701                 return -ENOMEM;
 702         }
 703 
 704         length = sizeof(msg->hdr) + sizeof(msg->connect_service);
 705         skb_put(skb, length);
 706         memset(skb->data, 0, length);
 707 
 708         msg = (struct ath10k_htc_msg *)skb->data;
 709         msg->hdr.message_id =
 710                 __cpu_to_le16(ATH10K_HTC_MSG_CONNECT_SERVICE_ID);
 711 
 712         flags |= SM(tx_alloc, ATH10K_HTC_CONN_FLAGS_RECV_ALLOC);
 713 
 714         /* Only enable credit flow control for WMI ctrl service */
 715         if (conn_req->service_id != ATH10K_HTC_SVC_ID_WMI_CONTROL) {
 716                 flags |= ATH10K_HTC_CONN_FLAGS_DISABLE_CREDIT_FLOW_CTRL;
 717                 disable_credit_flow_ctrl = true;
 718         }
 719 
 720         req_msg = &msg->connect_service;
 721         req_msg->flags = __cpu_to_le16(flags);
 722         req_msg->service_id = __cpu_to_le16(conn_req->service_id);
 723 
 724         reinit_completion(&htc->ctl_resp);
 725 
 726         status = ath10k_htc_send(htc, ATH10K_HTC_EP_0, skb);
 727         if (status) {
 728                 kfree_skb(skb);
 729                 return status;
 730         }
 731 
 732         /* wait for response */
 733         time_left = wait_for_completion_timeout(&htc->ctl_resp,
 734                                                 ATH10K_HTC_CONN_SVC_TIMEOUT_HZ);
 735         if (!time_left) {
 736                 ath10k_err(ar, "Service connect timeout\n");
 737                 return -ETIMEDOUT;
 738         }
 739 
 740         /* we controlled the buffer creation, it's aligned */
 741         msg = (struct ath10k_htc_msg *)htc->control_resp_buffer;
 742         resp_msg = &msg->connect_service_response;
 743         message_id = __le16_to_cpu(msg->hdr.message_id);
 744         service_id = __le16_to_cpu(resp_msg->service_id);
 745 
 746         if ((message_id != ATH10K_HTC_MSG_CONNECT_SERVICE_RESP_ID) ||
 747             (htc->control_resp_len < sizeof(msg->hdr) +
 748              sizeof(msg->connect_service_response))) {
 749                 ath10k_err(ar, "Invalid resp message ID 0x%x", message_id);
 750                 return -EPROTO;
 751         }
 752 
 753         ath10k_dbg(ar, ATH10K_DBG_HTC,
 754                    "HTC Service %s connect response: status: 0x%x, assigned ep: 0x%x\n",
 755                    htc_service_name(service_id),
 756                    resp_msg->status, resp_msg->eid);
 757 
 758         conn_resp->connect_resp_code = resp_msg->status;
 759 
 760         /* check response status */
 761         if (resp_msg->status != ATH10K_HTC_CONN_SVC_STATUS_SUCCESS) {
 762                 ath10k_err(ar, "HTC Service %s connect request failed: 0x%x)\n",
 763                            htc_service_name(service_id),
 764                            resp_msg->status);
 765                 return -EPROTO;
 766         }
 767 
 768         assigned_eid = (enum ath10k_htc_ep_id)resp_msg->eid;
 769         max_msg_size = __le16_to_cpu(resp_msg->max_msg_size);
 770 
 771 setup:
 772 
 773         if (assigned_eid >= ATH10K_HTC_EP_COUNT)
 774                 return -EPROTO;
 775 
 776         if (max_msg_size == 0)
 777                 return -EPROTO;
 778 
 779         ep = &htc->endpoint[assigned_eid];
 780         ep->eid = assigned_eid;
 781 
 782         if (ep->service_id != ATH10K_HTC_SVC_ID_UNUSED)
 783                 return -EPROTO;
 784 
 785         /* return assigned endpoint to caller */
 786         conn_resp->eid = assigned_eid;
 787         conn_resp->max_msg_len = __le16_to_cpu(resp_msg->max_msg_size);
 788 
 789         /* setup the endpoint */
 790         ep->service_id = conn_req->service_id;
 791         ep->max_tx_queue_depth = conn_req->max_send_queue_depth;
 792         ep->max_ep_message_len = __le16_to_cpu(resp_msg->max_msg_size);
 793         ep->tx_credits = tx_alloc;
 794 
 795         /* copy all the callbacks */
 796         ep->ep_ops = conn_req->ep_ops;
 797 
 798         status = ath10k_hif_map_service_to_pipe(htc->ar,
 799                                                 ep->service_id,
 800                                                 &ep->ul_pipe_id,
 801                                                 &ep->dl_pipe_id);
 802         if (status) {
 803                 ath10k_warn(ar, "unsupported HTC service id: %d\n",
 804                             ep->service_id);
 805                 return status;
 806         }
 807 
 808         ath10k_dbg(ar, ATH10K_DBG_BOOT,
 809                    "boot htc service '%s' ul pipe %d dl pipe %d eid %d ready\n",
 810                    htc_service_name(ep->service_id), ep->ul_pipe_id,
 811                    ep->dl_pipe_id, ep->eid);
 812 
 813         if (disable_credit_flow_ctrl && ep->tx_credit_flow_enabled) {
 814                 ep->tx_credit_flow_enabled = false;
 815                 ath10k_dbg(ar, ATH10K_DBG_BOOT,
 816                            "boot htc service '%s' eid %d TX flow control disabled\n",
 817                            htc_service_name(ep->service_id), assigned_eid);
 818         }
 819 
 820         return status;
 821 }
 822 
 823 struct sk_buff *ath10k_htc_alloc_skb(struct ath10k *ar, int size)
 824 {
 825         struct sk_buff *skb;
 826 
 827         skb = dev_alloc_skb(size + sizeof(struct ath10k_htc_hdr));
 828         if (!skb)
 829                 return NULL;
 830 
 831         skb_reserve(skb, sizeof(struct ath10k_htc_hdr));
 832 
 833         /* FW/HTC requires 4-byte aligned streams */
 834         if (!IS_ALIGNED((unsigned long)skb->data, 4))
 835                 ath10k_warn(ar, "Unaligned HTC tx skb\n");
 836 
 837         return skb;
 838 }
 839 
 840 static void ath10k_htc_pktlog_process_rx(struct ath10k *ar, struct sk_buff *skb)
 841 {
 842         trace_ath10k_htt_pktlog(ar, skb->data, skb->len);
 843         dev_kfree_skb_any(skb);
 844 }
 845 
 846 static int ath10k_htc_pktlog_connect(struct ath10k *ar)
 847 {
 848         struct ath10k_htc_svc_conn_resp conn_resp;
 849         struct ath10k_htc_svc_conn_req conn_req;
 850         int status;
 851 
 852         memset(&conn_req, 0, sizeof(conn_req));
 853         memset(&conn_resp, 0, sizeof(conn_resp));
 854 
 855         conn_req.ep_ops.ep_tx_complete = NULL;
 856         conn_req.ep_ops.ep_rx_complete = ath10k_htc_pktlog_process_rx;
 857         conn_req.ep_ops.ep_tx_credits = NULL;
 858 
 859         /* connect to control service */
 860         conn_req.service_id = ATH10K_HTC_SVC_ID_HTT_LOG_MSG;
 861         status = ath10k_htc_connect_service(&ar->htc, &conn_req, &conn_resp);
 862         if (status) {
 863                 ath10k_warn(ar, "failed to connect to PKTLOG service: %d\n",
 864                             status);
 865                 return status;
 866         }
 867 
 868         return 0;
 869 }
 870 
 871 static bool ath10k_htc_pktlog_svc_supported(struct ath10k *ar)
 872 {
 873         u8 ul_pipe_id;
 874         u8 dl_pipe_id;
 875         int status;
 876 
 877         status = ath10k_hif_map_service_to_pipe(ar, ATH10K_HTC_SVC_ID_HTT_LOG_MSG,
 878                                                 &ul_pipe_id,
 879                                                 &dl_pipe_id);
 880         if (status) {
 881                 ath10k_warn(ar, "unsupported HTC service id: %d\n",
 882                             ATH10K_HTC_SVC_ID_HTT_LOG_MSG);
 883 
 884                 return false;
 885         }
 886 
 887         return true;
 888 }
 889 
 890 int ath10k_htc_start(struct ath10k_htc *htc)
 891 {
 892         struct ath10k *ar = htc->ar;
 893         struct sk_buff *skb;
 894         int status = 0;
 895         struct ath10k_htc_msg *msg;
 896 
 897         skb = ath10k_htc_build_tx_ctrl_skb(htc->ar);
 898         if (!skb)
 899                 return -ENOMEM;
 900 
 901         skb_put(skb, sizeof(msg->hdr) + sizeof(msg->setup_complete_ext));
 902         memset(skb->data, 0, skb->len);
 903 
 904         msg = (struct ath10k_htc_msg *)skb->data;
 905         msg->hdr.message_id =
 906                 __cpu_to_le16(ATH10K_HTC_MSG_SETUP_COMPLETE_EX_ID);
 907 
 908         if (ar->hif.bus == ATH10K_BUS_SDIO) {
 909                 /* Extra setup params used by SDIO */
 910                 msg->setup_complete_ext.flags =
 911                         __cpu_to_le32(ATH10K_HTC_SETUP_COMPLETE_FLAGS_RX_BNDL_EN);
 912                 msg->setup_complete_ext.max_msgs_per_bundled_recv =
 913                         htc->max_msgs_per_htc_bundle;
 914         }
 915         ath10k_dbg(ar, ATH10K_DBG_HTC, "HTC is using TX credit flow control\n");
 916 
 917         status = ath10k_htc_send(htc, ATH10K_HTC_EP_0, skb);
 918         if (status) {
 919                 kfree_skb(skb);
 920                 return status;
 921         }
 922 
 923         if (ath10k_htc_pktlog_svc_supported(ar)) {
 924                 status = ath10k_htc_pktlog_connect(ar);
 925                 if (status) {
 926                         ath10k_err(ar, "failed to connect to pktlog: %d\n", status);
 927                         return status;
 928                 }
 929         }
 930 
 931         return 0;
 932 }
 933 
 934 /* registered target arrival callback from the HIF layer */
 935 int ath10k_htc_init(struct ath10k *ar)
 936 {
 937         int status;
 938         struct ath10k_htc *htc = &ar->htc;
 939         struct ath10k_htc_svc_conn_req conn_req;
 940         struct ath10k_htc_svc_conn_resp conn_resp;
 941 
 942         spin_lock_init(&htc->tx_lock);
 943 
 944         ath10k_htc_reset_endpoint_states(htc);
 945 
 946         htc->ar = ar;
 947 
 948         /* setup our pseudo HTC control endpoint connection */
 949         memset(&conn_req, 0, sizeof(conn_req));
 950         memset(&conn_resp, 0, sizeof(conn_resp));
 951         conn_req.ep_ops.ep_tx_complete = ath10k_htc_control_tx_complete;
 952         conn_req.ep_ops.ep_rx_complete = ath10k_htc_control_rx_complete;
 953         conn_req.max_send_queue_depth = ATH10K_NUM_CONTROL_TX_BUFFERS;
 954         conn_req.service_id = ATH10K_HTC_SVC_ID_RSVD_CTRL;
 955 
 956         /* connect fake service */
 957         status = ath10k_htc_connect_service(htc, &conn_req, &conn_resp);
 958         if (status) {
 959                 ath10k_err(ar, "could not connect to htc service (%d)\n",
 960                            status);
 961                 return status;
 962         }
 963 
 964         init_completion(&htc->ctl_resp);
 965 
 966         return 0;
 967 }

/* [<][>][^][v][top][bottom][index][help] */