0001
0002
0003
0004
0005
0006
0007 #ifndef _HTC_H_
0008 #define _HTC_H_
0009
0010 #include <linux/kernel.h>
0011 #include <linux/list.h>
0012 #include <linux/bug.h>
0013 #include <linux/skbuff.h>
0014 #include <linux/timer.h>
0015 #include <linux/bitfield.h>
0016
0017 struct ath10k;
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043 #define HTC_HOST_MAX_MSG_PER_RX_BUNDLE 32
0044
0045 enum ath10k_htc_tx_flags {
0046 ATH10K_HTC_FLAG_NEED_CREDIT_UPDATE = 0x01,
0047 ATH10K_HTC_FLAG_SEND_BUNDLE = 0x02
0048 };
0049
0050 enum ath10k_htc_rx_flags {
0051 ATH10K_HTC_FLAGS_RECV_1MORE_BLOCK = 0x01,
0052 ATH10K_HTC_FLAG_TRAILER_PRESENT = 0x02,
0053 };
0054
0055 #define ATH10K_HTC_FLAG_BUNDLE_MASK GENMASK(7, 4)
0056
0057
0058 #define ATH10K_HTC_BUNDLE_EXTRA_MASK GENMASK(3, 2)
0059 #define ATH10K_HTC_BUNDLE_EXTRA_SHIFT 4
0060
0061 static inline unsigned int ath10k_htc_get_bundle_count(u8 max_msgs, u8 flags)
0062 {
0063 unsigned int count, extra_count = 0;
0064
0065 count = FIELD_GET(ATH10K_HTC_FLAG_BUNDLE_MASK, flags);
0066
0067 if (max_msgs > 16)
0068 extra_count = FIELD_GET(ATH10K_HTC_BUNDLE_EXTRA_MASK, flags) <<
0069 ATH10K_HTC_BUNDLE_EXTRA_SHIFT;
0070
0071 return count + extra_count;
0072 }
0073
0074 struct ath10k_htc_hdr {
0075 u8 eid;
0076 u8 flags;
0077 __le16 len;
0078 union {
0079 u8 trailer_len;
0080 u8 control_byte0;
0081 } __packed;
0082 union {
0083 u8 seq_no;
0084 u8 control_byte1;
0085 } __packed;
0086 union {
0087 __le16 pad_len;
0088 struct {
0089 u8 pad0;
0090 u8 pad1;
0091 } __packed;
0092 } __packed;
0093
0094 } __packed __aligned(4);
0095
0096 enum ath10k_ath10k_htc_msg_id {
0097 ATH10K_HTC_MSG_READY_ID = 1,
0098 ATH10K_HTC_MSG_CONNECT_SERVICE_ID = 2,
0099 ATH10K_HTC_MSG_CONNECT_SERVICE_RESP_ID = 3,
0100 ATH10K_HTC_MSG_SETUP_COMPLETE_ID = 4,
0101 ATH10K_HTC_MSG_SETUP_COMPLETE_EX_ID = 5,
0102 ATH10K_HTC_MSG_SEND_SUSPEND_COMPLETE = 6
0103 };
0104
0105 enum ath10k_htc_version {
0106 ATH10K_HTC_VERSION_2P0 = 0x00,
0107 ATH10K_HTC_VERSION_2P1 = 0x01,
0108 };
0109
0110 enum ath10k_htc_conn_flags {
0111 ATH10K_HTC_CONN_FLAGS_THRESHOLD_LEVEL_ONE_FOURTH = 0x0,
0112 ATH10K_HTC_CONN_FLAGS_THRESHOLD_LEVEL_ONE_HALF = 0x1,
0113 ATH10K_HTC_CONN_FLAGS_THRESHOLD_LEVEL_THREE_FOURTHS = 0x2,
0114 ATH10K_HTC_CONN_FLAGS_THRESHOLD_LEVEL_UNITY = 0x3,
0115 #define ATH10K_HTC_CONN_FLAGS_THRESHOLD_LEVEL_MASK 0x3
0116 ATH10K_HTC_CONN_FLAGS_REDUCE_CREDIT_DRIBBLE = 1 << 2,
0117 ATH10K_HTC_CONN_FLAGS_DISABLE_CREDIT_FLOW_CTRL = 1 << 3
0118 #define ATH10K_HTC_CONN_FLAGS_RECV_ALLOC_MASK 0xFF00
0119 #define ATH10K_HTC_CONN_FLAGS_RECV_ALLOC_LSB 8
0120 };
0121
0122 #define ATH10K_HTC_MSG_READY_EXT_ALT_DATA_MASK 0xFFF
0123
0124 enum ath10k_htc_conn_svc_status {
0125 ATH10K_HTC_CONN_SVC_STATUS_SUCCESS = 0,
0126 ATH10K_HTC_CONN_SVC_STATUS_NOT_FOUND = 1,
0127 ATH10K_HTC_CONN_SVC_STATUS_FAILED = 2,
0128 ATH10K_HTC_CONN_SVC_STATUS_NO_RESOURCES = 3,
0129 ATH10K_HTC_CONN_SVC_STATUS_NO_MORE_EP = 4
0130 };
0131
0132 #define ATH10K_MAX_MSG_PER_HTC_TX_BUNDLE 32
0133 #define ATH10K_MIN_MSG_PER_HTC_TX_BUNDLE 2
0134 #define ATH10K_MIN_CREDIT_PER_HTC_TX_BUNDLE 2
0135
0136 enum ath10k_htc_setup_complete_flags {
0137 ATH10K_HTC_SETUP_COMPLETE_FLAGS_RX_BNDL_EN = 1
0138 };
0139
0140 struct ath10k_ath10k_htc_msg_hdr {
0141 __le16 message_id;
0142 } __packed;
0143
0144 struct ath10k_htc_unknown {
0145 u8 pad0;
0146 u8 pad1;
0147 } __packed;
0148
0149 struct ath10k_htc_ready {
0150 __le16 credit_count;
0151 __le16 credit_size;
0152 u8 max_endpoints;
0153 u8 pad0;
0154 } __packed;
0155
0156 struct ath10k_htc_ready_extended {
0157 struct ath10k_htc_ready base;
0158 u8 htc_version;
0159 u8 max_msgs_per_htc_bundle;
0160 union {
0161 __le16 reserved;
0162 struct {
0163 u8 pad0;
0164 u8 pad1;
0165 } __packed;
0166 } __packed;
0167
0168 } __packed;
0169
0170 struct ath10k_htc_conn_svc {
0171 __le16 service_id;
0172 __le16 flags;
0173 u8 pad0;
0174 u8 pad1;
0175 } __packed;
0176
0177 struct ath10k_htc_conn_svc_response {
0178 __le16 service_id;
0179 u8 status;
0180 u8 eid;
0181 __le16 max_msg_size;
0182 } __packed;
0183
0184 struct ath10k_htc_setup_complete_extended {
0185 u8 pad0;
0186 u8 pad1;
0187 __le32 flags;
0188 u8 max_msgs_per_bundled_recv;
0189 u8 pad2;
0190 u8 pad3;
0191 u8 pad4;
0192 } __packed;
0193
0194 struct ath10k_htc_msg {
0195 struct ath10k_ath10k_htc_msg_hdr hdr;
0196 union {
0197
0198 struct ath10k_htc_conn_svc connect_service;
0199 struct ath10k_htc_ready ready;
0200 struct ath10k_htc_ready_extended ready_ext;
0201 struct ath10k_htc_unknown unknown;
0202 struct ath10k_htc_setup_complete_extended setup_complete_ext;
0203
0204
0205 struct ath10k_htc_conn_svc_response connect_service_response;
0206 };
0207 } __packed __aligned(4);
0208
0209 enum ath10k_ath10k_htc_record_id {
0210 ATH10K_HTC_RECORD_NULL = 0,
0211 ATH10K_HTC_RECORD_CREDITS = 1,
0212 ATH10K_HTC_RECORD_LOOKAHEAD = 2,
0213 ATH10K_HTC_RECORD_LOOKAHEAD_BUNDLE = 3,
0214 };
0215
0216 struct ath10k_ath10k_htc_record_hdr {
0217 u8 id;
0218 u8 len;
0219 u8 pad0;
0220 u8 pad1;
0221 } __packed;
0222
0223 struct ath10k_htc_credit_report {
0224 u8 eid;
0225 u8 credits;
0226 u8 pad0;
0227 u8 pad1;
0228 } __packed;
0229
0230 struct ath10k_htc_lookahead_report {
0231 u8 pre_valid;
0232 u8 pad0;
0233 u8 pad1;
0234 u8 pad2;
0235 u8 lookahead[4];
0236 u8 post_valid;
0237 u8 pad3;
0238 u8 pad4;
0239 u8 pad5;
0240 } __packed;
0241
0242 struct ath10k_htc_lookahead_bundle {
0243 u8 lookahead[4];
0244 } __packed;
0245
0246 struct ath10k_htc_record {
0247 struct ath10k_ath10k_htc_record_hdr hdr;
0248 union {
0249 struct ath10k_htc_credit_report credit_report[0];
0250 struct ath10k_htc_lookahead_report lookahead_report[0];
0251 struct ath10k_htc_lookahead_bundle lookahead_bundle[0];
0252 u8 pauload[0];
0253 };
0254 } __packed __aligned(4);
0255
0256
0257
0258
0259
0260 struct ath10k_htc_frame {
0261 struct ath10k_htc_hdr hdr;
0262 union {
0263 struct ath10k_htc_msg msg;
0264 u8 payload[0];
0265 };
0266 struct ath10k_htc_record trailer[0];
0267 } __packed __aligned(4);
0268
0269
0270
0271
0272
0273 enum ath10k_htc_svc_gid {
0274 ATH10K_HTC_SVC_GRP_RSVD = 0,
0275 ATH10K_HTC_SVC_GRP_WMI = 1,
0276 ATH10K_HTC_SVC_GRP_NMI = 2,
0277 ATH10K_HTC_SVC_GRP_HTT = 3,
0278 ATH10K_LOG_SERVICE_GROUP = 6,
0279
0280 ATH10K_HTC_SVC_GRP_TEST = 254,
0281 ATH10K_HTC_SVC_GRP_LAST = 255,
0282 };
0283
0284 #define SVC(group, idx) \
0285 (int)(((int)(group) << 8) | (int)(idx))
0286
0287 enum ath10k_htc_svc_id {
0288
0289 ATH10K_HTC_SVC_ID_RESERVED = 0x0000,
0290 ATH10K_HTC_SVC_ID_UNUSED = ATH10K_HTC_SVC_ID_RESERVED,
0291
0292 ATH10K_HTC_SVC_ID_RSVD_CTRL = SVC(ATH10K_HTC_SVC_GRP_RSVD, 1),
0293 ATH10K_HTC_SVC_ID_WMI_CONTROL = SVC(ATH10K_HTC_SVC_GRP_WMI, 0),
0294 ATH10K_HTC_SVC_ID_WMI_DATA_BE = SVC(ATH10K_HTC_SVC_GRP_WMI, 1),
0295 ATH10K_HTC_SVC_ID_WMI_DATA_BK = SVC(ATH10K_HTC_SVC_GRP_WMI, 2),
0296 ATH10K_HTC_SVC_ID_WMI_DATA_VI = SVC(ATH10K_HTC_SVC_GRP_WMI, 3),
0297 ATH10K_HTC_SVC_ID_WMI_DATA_VO = SVC(ATH10K_HTC_SVC_GRP_WMI, 4),
0298
0299 ATH10K_HTC_SVC_ID_NMI_CONTROL = SVC(ATH10K_HTC_SVC_GRP_NMI, 0),
0300 ATH10K_HTC_SVC_ID_NMI_DATA = SVC(ATH10K_HTC_SVC_GRP_NMI, 1),
0301
0302 ATH10K_HTC_SVC_ID_HTT_DATA_MSG = SVC(ATH10K_HTC_SVC_GRP_HTT, 0),
0303
0304 ATH10K_HTC_SVC_ID_HTT_DATA2_MSG = SVC(ATH10K_HTC_SVC_GRP_HTT, 1),
0305 ATH10K_HTC_SVC_ID_HTT_DATA3_MSG = SVC(ATH10K_HTC_SVC_GRP_HTT, 2),
0306 ATH10K_HTC_SVC_ID_HTT_LOG_MSG = SVC(ATH10K_LOG_SERVICE_GROUP, 0),
0307
0308 ATH10K_HTC_SVC_ID_TEST_RAW_STREAMS = SVC(ATH10K_HTC_SVC_GRP_TEST, 0),
0309 };
0310
0311 #undef SVC
0312
0313 enum ath10k_htc_ep_id {
0314 ATH10K_HTC_EP_UNUSED = -1,
0315 ATH10K_HTC_EP_0 = 0,
0316 ATH10K_HTC_EP_1 = 1,
0317 ATH10K_HTC_EP_2,
0318 ATH10K_HTC_EP_3,
0319 ATH10K_HTC_EP_4,
0320 ATH10K_HTC_EP_5,
0321 ATH10K_HTC_EP_6,
0322 ATH10K_HTC_EP_7,
0323 ATH10K_HTC_EP_8,
0324 ATH10K_HTC_EP_COUNT,
0325 };
0326
0327 struct ath10k_htc_ops {
0328 void (*target_send_suspend_complete)(struct ath10k *ar);
0329 };
0330
0331 struct ath10k_htc_ep_ops {
0332 void (*ep_tx_complete)(struct ath10k *, struct sk_buff *);
0333 void (*ep_rx_complete)(struct ath10k *, struct sk_buff *);
0334 void (*ep_tx_credits)(struct ath10k *);
0335 };
0336
0337
0338 struct ath10k_htc_svc_conn_req {
0339 u16 service_id;
0340 struct ath10k_htc_ep_ops ep_ops;
0341 int max_send_queue_depth;
0342 };
0343
0344
0345 struct ath10k_htc_svc_conn_resp {
0346 u8 buffer_len;
0347 u8 actual_len;
0348 enum ath10k_htc_ep_id eid;
0349 unsigned int max_msg_len;
0350 u8 connect_resp_code;
0351 };
0352
0353 #define ATH10K_NUM_CONTROL_TX_BUFFERS 2
0354 #define ATH10K_HTC_MAX_LEN 4096
0355 #define ATH10K_HTC_MAX_CTRL_MSG_LEN 256
0356 #define ATH10K_HTC_WAIT_TIMEOUT_HZ (1 * HZ)
0357 #define ATH10K_HTC_CONTROL_BUFFER_SIZE (ATH10K_HTC_MAX_CTRL_MSG_LEN + \
0358 sizeof(struct ath10k_htc_hdr))
0359 #define ATH10K_HTC_CONN_SVC_TIMEOUT_HZ (1 * HZ)
0360
0361 struct ath10k_htc_ep {
0362 struct ath10k_htc *htc;
0363 enum ath10k_htc_ep_id eid;
0364 enum ath10k_htc_svc_id service_id;
0365 struct ath10k_htc_ep_ops ep_ops;
0366
0367 int max_tx_queue_depth;
0368 int max_ep_message_len;
0369 u8 ul_pipe_id;
0370 u8 dl_pipe_id;
0371
0372 u8 seq_no;
0373 int tx_credits;
0374 int tx_credit_size;
0375 bool tx_credit_flow_enabled;
0376 bool bundle_tx;
0377 struct sk_buff_head tx_req_head;
0378 struct sk_buff_head tx_complete_head;
0379
0380 };
0381
0382 struct ath10k_htc_svc_tx_credits {
0383 u16 service_id;
0384 u8 credit_allocation;
0385 };
0386
0387 struct ath10k_htc {
0388 struct ath10k *ar;
0389 struct ath10k_htc_ep endpoint[ATH10K_HTC_EP_COUNT];
0390
0391
0392 spinlock_t tx_lock;
0393
0394 struct ath10k_htc_ops htc_ops;
0395
0396 u8 control_resp_buffer[ATH10K_HTC_MAX_CTRL_MSG_LEN];
0397 int control_resp_len;
0398
0399 struct completion ctl_resp;
0400
0401 int total_transmit_credits;
0402 int target_credit_size;
0403 u8 max_msgs_per_htc_bundle;
0404 int alt_data_credit_size;
0405 };
0406
0407 int ath10k_htc_init(struct ath10k *ar);
0408 int ath10k_htc_wait_target(struct ath10k_htc *htc);
0409 void ath10k_htc_setup_tx_req(struct ath10k_htc_ep *ep);
0410 int ath10k_htc_start(struct ath10k_htc *htc);
0411 int ath10k_htc_connect_service(struct ath10k_htc *htc,
0412 struct ath10k_htc_svc_conn_req *conn_req,
0413 struct ath10k_htc_svc_conn_resp *conn_resp);
0414 void ath10k_htc_change_tx_credit_flow(struct ath10k_htc *htc,
0415 enum ath10k_htc_ep_id eid,
0416 bool enable);
0417 int ath10k_htc_send(struct ath10k_htc *htc, enum ath10k_htc_ep_id eid,
0418 struct sk_buff *packet);
0419 void ath10k_htc_stop_hl(struct ath10k *ar);
0420
0421 int ath10k_htc_send_hl(struct ath10k_htc *htc, enum ath10k_htc_ep_id eid,
0422 struct sk_buff *packet);
0423 struct sk_buff *ath10k_htc_alloc_skb(struct ath10k *ar, int size);
0424 void ath10k_htc_tx_completion_handler(struct ath10k *ar, struct sk_buff *skb);
0425 void ath10k_htc_rx_completion_handler(struct ath10k *ar, struct sk_buff *skb);
0426 void ath10k_htc_notify_tx_completion(struct ath10k_htc_ep *ep,
0427 struct sk_buff *skb);
0428 int ath10k_htc_process_trailer(struct ath10k_htc *htc,
0429 u8 *buffer,
0430 int length,
0431 enum ath10k_htc_ep_id src_eid,
0432 void *next_lookaheads,
0433 int *next_lookaheads_len);
0434
0435 #endif