| .. | .. |
|---|
| 1 | +/* SPDX-License-Identifier: ISC */ |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * Copyright (c) 2005-2011 Atheros Communications Inc. |
|---|
| 3 | 4 | * Copyright (c) 2011-2016 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 | 5 | */ |
|---|
| 17 | 6 | |
|---|
| 18 | 7 | #ifndef _HTC_H_ |
|---|
| .. | .. |
|---|
| 23 | 12 | #include <linux/bug.h> |
|---|
| 24 | 13 | #include <linux/skbuff.h> |
|---|
| 25 | 14 | #include <linux/timer.h> |
|---|
| 15 | +#include <linux/bitfield.h> |
|---|
| 26 | 16 | |
|---|
| 27 | 17 | struct ath10k; |
|---|
| 28 | 18 | |
|---|
| .. | .. |
|---|
| 50 | 40 | * 4-byte aligned. |
|---|
| 51 | 41 | */ |
|---|
| 52 | 42 | |
|---|
| 53 | | -#define HTC_HOST_MAX_MSG_PER_RX_BUNDLE 8 |
|---|
| 54 | | -#define HTC_HOST_MAX_MSG_PER_TX_BUNDLE 16 |
|---|
| 43 | +#define HTC_HOST_MAX_MSG_PER_RX_BUNDLE 32 |
|---|
| 55 | 44 | |
|---|
| 56 | 45 | enum ath10k_htc_tx_flags { |
|---|
| 57 | 46 | ATH10K_HTC_FLAG_NEED_CREDIT_UPDATE = 0x01, |
|---|
| .. | .. |
|---|
| 61 | 50 | enum ath10k_htc_rx_flags { |
|---|
| 62 | 51 | ATH10K_HTC_FLAGS_RECV_1MORE_BLOCK = 0x01, |
|---|
| 63 | 52 | ATH10K_HTC_FLAG_TRAILER_PRESENT = 0x02, |
|---|
| 64 | | - ATH10K_HTC_FLAG_BUNDLE_MASK = 0xF0 |
|---|
| 65 | 53 | }; |
|---|
| 54 | + |
|---|
| 55 | +#define ATH10K_HTC_FLAG_BUNDLE_MASK GENMASK(7, 4) |
|---|
| 56 | + |
|---|
| 57 | +/* bits 2-3 are for extra bundle count bits 4-5 */ |
|---|
| 58 | +#define ATH10K_HTC_BUNDLE_EXTRA_MASK GENMASK(3, 2) |
|---|
| 59 | +#define ATH10K_HTC_BUNDLE_EXTRA_SHIFT 4 |
|---|
| 60 | + |
|---|
| 61 | +static inline unsigned int ath10k_htc_get_bundle_count(u8 max_msgs, u8 flags) |
|---|
| 62 | +{ |
|---|
| 63 | + unsigned int count, extra_count = 0; |
|---|
| 64 | + |
|---|
| 65 | + count = FIELD_GET(ATH10K_HTC_FLAG_BUNDLE_MASK, flags); |
|---|
| 66 | + |
|---|
| 67 | + if (max_msgs > 16) |
|---|
| 68 | + extra_count = FIELD_GET(ATH10K_HTC_BUNDLE_EXTRA_MASK, flags) << |
|---|
| 69 | + ATH10K_HTC_BUNDLE_EXTRA_SHIFT; |
|---|
| 70 | + |
|---|
| 71 | + return count + extra_count; |
|---|
| 72 | +} |
|---|
| 66 | 73 | |
|---|
| 67 | 74 | struct ath10k_htc_hdr { |
|---|
| 68 | 75 | u8 eid; /* @enum ath10k_htc_ep_id */ |
|---|
| .. | .. |
|---|
| 76 | 83 | u8 seq_no; /* for tx */ |
|---|
| 77 | 84 | u8 control_byte1; |
|---|
| 78 | 85 | } __packed; |
|---|
| 79 | | - u8 pad0; |
|---|
| 80 | | - u8 pad1; |
|---|
| 86 | + union { |
|---|
| 87 | + __le16 pad_len; |
|---|
| 88 | + struct { |
|---|
| 89 | + u8 pad0; |
|---|
| 90 | + u8 pad1; |
|---|
| 91 | + } __packed; |
|---|
| 92 | + } __packed; |
|---|
| 93 | + |
|---|
| 81 | 94 | } __packed __aligned(4); |
|---|
| 82 | 95 | |
|---|
| 83 | 96 | enum ath10k_ath10k_htc_msg_id { |
|---|
| .. | .. |
|---|
| 106 | 119 | #define ATH10K_HTC_CONN_FLAGS_RECV_ALLOC_LSB 8 |
|---|
| 107 | 120 | }; |
|---|
| 108 | 121 | |
|---|
| 122 | +#define ATH10K_HTC_MSG_READY_EXT_ALT_DATA_MASK 0xFFF |
|---|
| 123 | + |
|---|
| 109 | 124 | enum ath10k_htc_conn_svc_status { |
|---|
| 110 | 125 | ATH10K_HTC_CONN_SVC_STATUS_SUCCESS = 0, |
|---|
| 111 | 126 | ATH10K_HTC_CONN_SVC_STATUS_NOT_FOUND = 1, |
|---|
| .. | .. |
|---|
| 113 | 128 | ATH10K_HTC_CONN_SVC_STATUS_NO_RESOURCES = 3, |
|---|
| 114 | 129 | ATH10K_HTC_CONN_SVC_STATUS_NO_MORE_EP = 4 |
|---|
| 115 | 130 | }; |
|---|
| 131 | + |
|---|
| 132 | +#define ATH10K_MAX_MSG_PER_HTC_TX_BUNDLE 32 |
|---|
| 133 | +#define ATH10K_MIN_MSG_PER_HTC_TX_BUNDLE 2 |
|---|
| 134 | +#define ATH10K_MIN_CREDIT_PER_HTC_TX_BUNDLE 2 |
|---|
| 116 | 135 | |
|---|
| 117 | 136 | enum ath10k_htc_setup_complete_flags { |
|---|
| 118 | 137 | ATH10K_HTC_SETUP_COMPLETE_FLAGS_RX_BNDL_EN = 1 |
|---|
| .. | .. |
|---|
| 138 | 157 | struct ath10k_htc_ready base; |
|---|
| 139 | 158 | u8 htc_version; /* @enum ath10k_htc_version */ |
|---|
| 140 | 159 | u8 max_msgs_per_htc_bundle; |
|---|
| 141 | | - u8 pad0; |
|---|
| 142 | | - u8 pad1; |
|---|
| 160 | + union { |
|---|
| 161 | + __le16 reserved; |
|---|
| 162 | + struct { |
|---|
| 163 | + u8 pad0; |
|---|
| 164 | + u8 pad1; |
|---|
| 165 | + } __packed; |
|---|
| 166 | + } __packed; |
|---|
| 167 | + |
|---|
| 143 | 168 | } __packed; |
|---|
| 144 | 169 | |
|---|
| 145 | 170 | struct ath10k_htc_conn_svc { |
|---|
| .. | .. |
|---|
| 346 | 371 | |
|---|
| 347 | 372 | u8 seq_no; /* for debugging */ |
|---|
| 348 | 373 | int tx_credits; |
|---|
| 374 | + int tx_credit_size; |
|---|
| 349 | 375 | bool tx_credit_flow_enabled; |
|---|
| 376 | + bool bundle_tx; |
|---|
| 377 | + struct sk_buff_head tx_req_head; |
|---|
| 378 | + struct sk_buff_head tx_complete_head; |
|---|
| 379 | + |
|---|
| 350 | 380 | }; |
|---|
| 351 | 381 | |
|---|
| 352 | 382 | struct ath10k_htc_svc_tx_credits { |
|---|
| .. | .. |
|---|
| 371 | 401 | int total_transmit_credits; |
|---|
| 372 | 402 | int target_credit_size; |
|---|
| 373 | 403 | u8 max_msgs_per_htc_bundle; |
|---|
| 404 | + int alt_data_credit_size; |
|---|
| 374 | 405 | }; |
|---|
| 375 | 406 | |
|---|
| 376 | 407 | int ath10k_htc_init(struct ath10k *ar); |
|---|
| 377 | 408 | int ath10k_htc_wait_target(struct ath10k_htc *htc); |
|---|
| 409 | +void ath10k_htc_setup_tx_req(struct ath10k_htc_ep *ep); |
|---|
| 378 | 410 | int ath10k_htc_start(struct ath10k_htc *htc); |
|---|
| 379 | 411 | int ath10k_htc_connect_service(struct ath10k_htc *htc, |
|---|
| 380 | 412 | struct ath10k_htc_svc_conn_req *conn_req, |
|---|
| 381 | 413 | struct ath10k_htc_svc_conn_resp *conn_resp); |
|---|
| 414 | +void ath10k_htc_change_tx_credit_flow(struct ath10k_htc *htc, |
|---|
| 415 | + enum ath10k_htc_ep_id eid, |
|---|
| 416 | + bool enable); |
|---|
| 382 | 417 | int ath10k_htc_send(struct ath10k_htc *htc, enum ath10k_htc_ep_id eid, |
|---|
| 383 | 418 | struct sk_buff *packet); |
|---|
| 419 | +void ath10k_htc_stop_hl(struct ath10k *ar); |
|---|
| 420 | + |
|---|
| 421 | +int ath10k_htc_send_hl(struct ath10k_htc *htc, enum ath10k_htc_ep_id eid, |
|---|
| 422 | + struct sk_buff *packet); |
|---|
| 384 | 423 | struct sk_buff *ath10k_htc_alloc_skb(struct ath10k *ar, int size); |
|---|
| 385 | 424 | void ath10k_htc_tx_completion_handler(struct ath10k *ar, struct sk_buff *skb); |
|---|
| 386 | 425 | void ath10k_htc_rx_completion_handler(struct ath10k *ar, struct sk_buff *skb); |
|---|