1 /* 2 * Copyright (c) 2004-2011 Atheros Communications Inc. 3 * Copyright (c) 2011 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 #ifndef HTC_H 19 #define HTC_H 20 21 #include "common.h" 22 23 /* frame header flags */ 24 25 /* send direction */ 26 #define HTC_FLAGS_NEED_CREDIT_UPDATE (1 << 0) 27 #define HTC_FLAGS_SEND_BUNDLE (1 << 1) 28 29 /* receive direction */ 30 #define HTC_FLG_RX_UNUSED (1 << 0) 31 #define HTC_FLG_RX_TRAILER (1 << 1) 32 /* Bundle count maske and shift */ 33 #define HTC_FLG_RX_BNDL_CNT (0xF0) 34 #define HTC_FLG_RX_BNDL_CNT_S 4 35 36 #define HTC_HDR_LENGTH (sizeof(struct htc_frame_hdr)) 37 #define HTC_MAX_PAYLOAD_LENGTH (4096 - sizeof(struct htc_frame_hdr)) 38 39 /* HTC control message IDs */ 40 41 #define HTC_MSG_READY_ID 1 42 #define HTC_MSG_CONN_SVC_ID 2 43 #define HTC_MSG_CONN_SVC_RESP_ID 3 44 #define HTC_MSG_SETUP_COMPLETE_ID 4 45 #define HTC_MSG_SETUP_COMPLETE_EX_ID 5 46 47 #define HTC_MAX_CTRL_MSG_LEN 256 48 49 #define HTC_VERSION_2P0 0x00 50 #define HTC_VERSION_2P1 0x01 51 52 #define HTC_SERVICE_META_DATA_MAX_LENGTH 128 53 54 #define HTC_CONN_FLGS_THRESH_LVL_QUAT 0x0 55 #define HTC_CONN_FLGS_THRESH_LVL_HALF 0x1 56 #define HTC_CONN_FLGS_THRESH_LVL_THREE_QUAT 0x2 57 #define HTC_CONN_FLGS_REDUCE_CRED_DRIB 0x4 58 #define HTC_CONN_FLGS_THRESH_MASK 0x3 59 60 /* connect response status codes */ 61 #define HTC_SERVICE_SUCCESS 0 62 #define HTC_SERVICE_NOT_FOUND 1 63 #define HTC_SERVICE_FAILED 2 64 65 /* no resources (i.e. no more endpoints) */ 66 #define HTC_SERVICE_NO_RESOURCES 3 67 68 /* specific service is not allowing any more endpoints */ 69 #define HTC_SERVICE_NO_MORE_EP 4 70 71 /* report record IDs */ 72 #define HTC_RECORD_NULL 0 73 #define HTC_RECORD_CREDITS 1 74 #define HTC_RECORD_LOOKAHEAD 2 75 #define HTC_RECORD_LOOKAHEAD_BUNDLE 3 76 77 #define HTC_SETUP_COMP_FLG_RX_BNDL_EN (1 << 0) 78 79 #define MAKE_SERVICE_ID(group, index) \ 80 (int)(((int)group << 8) | (int)(index)) 81 82 /* NOTE: service ID of 0x0000 is reserved and should never be used */ 83 #define HTC_CTRL_RSVD_SVC MAKE_SERVICE_ID(RSVD_SERVICE_GROUP, 1) 84 #define WMI_CONTROL_SVC MAKE_SERVICE_ID(WMI_SERVICE_GROUP, 0) 85 #define WMI_DATA_BE_SVC MAKE_SERVICE_ID(WMI_SERVICE_GROUP, 1) 86 #define WMI_DATA_BK_SVC MAKE_SERVICE_ID(WMI_SERVICE_GROUP, 2) 87 #define WMI_DATA_VI_SVC MAKE_SERVICE_ID(WMI_SERVICE_GROUP, 3) 88 #define WMI_DATA_VO_SVC MAKE_SERVICE_ID(WMI_SERVICE_GROUP, 4) 89 #define WMI_MAX_SERVICES 5 90 91 /* reserved and used to flush ALL packets */ 92 #define HTC_TX_PACKET_TAG_ALL 0 93 #define HTC_SERVICE_TX_PACKET_TAG 1 94 #define HTC_TX_PACKET_TAG_USER_DEFINED (HTC_SERVICE_TX_PACKET_TAG + 9) 95 96 /* more packets on this endpoint are being fetched */ 97 #define HTC_RX_FLAGS_INDICATE_MORE_PKTS (1 << 0) 98 99 /* TODO.. for BMI */ 100 #define ENDPOINT1 0 101 /* TODO -remove me, but we have to fix BMI first */ 102 #define HTC_MAILBOX_NUM_MAX 4 103 104 /* enable send bundle padding for this endpoint */ 105 #define HTC_FLGS_TX_BNDL_PAD_EN (1 << 0) 106 #define HTC_EP_ACTIVE ((u32) (1u << 31)) 107 108 /* HTC operational parameters */ 109 #define HTC_TARGET_RESPONSE_TIMEOUT 2000 /* in ms */ 110 #define HTC_TARGET_DEBUG_INTR_MASK 0x01 111 #define HTC_TARGET_CREDIT_INTR_MASK 0xF0 112 113 #define HTC_HOST_MAX_MSG_PER_BUNDLE 8 114 #define HTC_MIN_HTC_MSGS_TO_BUNDLE 2 115 116 /* packet flags */ 117 118 #define HTC_RX_PKT_IGNORE_LOOKAHEAD (1 << 0) 119 #define HTC_RX_PKT_REFRESH_HDR (1 << 1) 120 #define HTC_RX_PKT_PART_OF_BUNDLE (1 << 2) 121 #define HTC_RX_PKT_NO_RECYCLE (1 << 3) 122 123 #define NUM_CONTROL_BUFFERS 8 124 #define NUM_CONTROL_TX_BUFFERS 2 125 #define NUM_CONTROL_RX_BUFFERS (NUM_CONTROL_BUFFERS - NUM_CONTROL_TX_BUFFERS) 126 127 #define HTC_RECV_WAIT_BUFFERS (1 << 0) 128 #define HTC_OP_STATE_STOPPING (1 << 0) 129 130 /* 131 * The frame header length and message formats defined herein were selected 132 * to accommodate optimal alignment for target processing. This reduces 133 * code size and improves performance. Any changes to the header length may 134 * alter the alignment and cause exceptions on the target. When adding to 135 * the messagestructures insure that fields are properly aligned. 136 */ 137 138 /* HTC frame header 139 * 140 * NOTE: do not remove or re-arrange the fields, these are minimally 141 * required to take advantage of 4-byte lookaheads in some hardware 142 * implementations. 143 */ 144 struct htc_frame_hdr { 145 u8 eid; 146 u8 flags; 147 148 /* length of data (including trailer) that follows the header */ 149 __le16 payld_len; 150 151 /* end of 4-byte lookahead */ 152 153 u8 ctrl[2]; 154 } __packed; 155 156 /* HTC ready message */ 157 struct htc_ready_msg { 158 __le16 msg_id; 159 __le16 cred_cnt; 160 __le16 cred_sz; 161 u8 max_ep; 162 u8 pad; 163 } __packed; 164 165 /* extended HTC ready message */ 166 struct htc_ready_ext_msg { 167 struct htc_ready_msg ver2_0_info; 168 u8 htc_ver; 169 u8 msg_per_htc_bndl; 170 } __packed; 171 172 /* connect service */ 173 struct htc_conn_service_msg { 174 __le16 msg_id; 175 __le16 svc_id; 176 __le16 conn_flags; 177 u8 svc_meta_len; 178 u8 pad; 179 } __packed; 180 181 /* connect response */ 182 struct htc_conn_service_resp { 183 __le16 msg_id; 184 __le16 svc_id; 185 u8 status; 186 u8 eid; 187 __le16 max_msg_sz; 188 u8 svc_meta_len; 189 u8 pad; 190 } __packed; 191 192 struct htc_setup_comp_msg { 193 __le16 msg_id; 194 } __packed; 195 196 /* extended setup completion message */ 197 struct htc_setup_comp_ext_msg { 198 __le16 msg_id; 199 __le32 flags; 200 u8 msg_per_rxbndl; 201 u8 Rsvd[3]; 202 } __packed; 203 204 struct htc_record_hdr { 205 u8 rec_id; 206 u8 len; 207 } __packed; 208 209 struct htc_credit_report { 210 u8 eid; 211 u8 credits; 212 } __packed; 213 214 /* 215 * NOTE: The lk_ahd array is guarded by a pre_valid 216 * and Post Valid guard bytes. The pre_valid bytes must 217 * equal the inverse of the post_valid byte. 218 */ 219 struct htc_lookahead_report { 220 u8 pre_valid; 221 u8 lk_ahd[4]; 222 u8 post_valid; 223 } __packed; 224 225 struct htc_bundle_lkahd_rpt { 226 u8 lk_ahd[4]; 227 } __packed; 228 229 /* Current service IDs */ 230 231 enum htc_service_grp_ids { 232 RSVD_SERVICE_GROUP = 0, 233 WMI_SERVICE_GROUP = 1, 234 235 HTC_TEST_GROUP = 254, 236 HTC_SERVICE_GROUP_LAST = 255 237 }; 238 239 /* ------ endpoint IDS ------ */ 240 241 enum htc_endpoint_id { 242 ENDPOINT_UNUSED = -1, 243 ENDPOINT_0 = 0, 244 ENDPOINT_1 = 1, 245 ENDPOINT_2 = 2, 246 ENDPOINT_3, 247 ENDPOINT_4, 248 ENDPOINT_5, 249 ENDPOINT_6, 250 ENDPOINT_7, 251 ENDPOINT_8, 252 ENDPOINT_MAX, 253 }; 254 255 struct htc_tx_packet_info { 256 u16 tag; 257 int cred_used; 258 u8 flags; 259 int seqno; 260 }; 261 262 struct htc_rx_packet_info { 263 u32 exp_hdr; 264 u32 rx_flags; 265 u32 indicat_flags; 266 }; 267 268 struct htc_target; 269 270 /* wrapper around endpoint-specific packets */ 271 struct htc_packet { 272 struct list_head list; 273 274 /* caller's per packet specific context */ 275 void *pkt_cntxt; 276 277 /* 278 * the true buffer start , the caller can store the real 279 * buffer start here. In receive callbacks, the HTC layer 280 * sets buf to the start of the payload past the header. 281 * This field allows the caller to reset buf when it recycles 282 * receive packets back to HTC. 283 */ 284 u8 *buf_start; 285 286 /* 287 * Pointer to the start of the buffer. In the transmit 288 * direction this points to the start of the payload. In the 289 * receive direction, however, the buffer when queued up 290 * points to the start of the HTC header but when returned 291 * to the caller points to the start of the payload 292 */ 293 u8 *buf; 294 u32 buf_len; 295 296 /* actual length of payload */ 297 u32 act_len; 298 299 /* endpoint that this packet was sent/recv'd from */ 300 enum htc_endpoint_id endpoint; 301 302 /* completion status */ 303 304 int status; 305 union { 306 struct htc_tx_packet_info tx; 307 struct htc_rx_packet_info rx; 308 } info; 309 310 void (*completion) (struct htc_target *, struct htc_packet *); 311 struct htc_target *context; 312 }; 313 314 enum htc_send_full_action { 315 HTC_SEND_FULL_KEEP = 0, 316 HTC_SEND_FULL_DROP = 1, 317 }; 318 319 struct htc_ep_callbacks { 320 void (*rx) (struct htc_target *, struct htc_packet *); 321 void (*rx_refill) (struct htc_target *, enum htc_endpoint_id endpoint); 322 enum htc_send_full_action (*tx_full) (struct htc_target *, 323 struct htc_packet *); 324 struct htc_packet *(*rx_allocthresh) (struct htc_target *, 325 enum htc_endpoint_id, int); 326 int rx_alloc_thresh; 327 int rx_refill_thresh; 328 }; 329 330 /* service connection information */ 331 struct htc_service_connect_req { 332 u16 svc_id; 333 u16 conn_flags; 334 struct htc_ep_callbacks ep_cb; 335 int max_txq_depth; 336 u32 flags; 337 unsigned int max_rxmsg_sz; 338 }; 339 340 /* service connection response information */ 341 struct htc_service_connect_resp { 342 u8 buf_len; 343 u8 act_len; 344 enum htc_endpoint_id endpoint; 345 unsigned int len_max; 346 u8 resp_code; 347 }; 348 349 /* endpoint distributionstructure */ 350 struct htc_endpoint_credit_dist { 351 struct list_head list; 352 353 /* Service ID (set by HTC) */ 354 u16 svc_id; 355 356 /* endpoint for this distributionstruct (set by HTC) */ 357 enum htc_endpoint_id endpoint; 358 359 u32 dist_flags; 360 361 /* 362 * credits for normal operation, anything above this 363 * indicates the endpoint is over-subscribed. 364 */ 365 int cred_norm; 366 367 /* floor for credit distribution */ 368 int cred_min; 369 370 int cred_assngd; 371 372 /* current credits available */ 373 int credits; 374 375 /* 376 * pending credits to distribute on this endpoint, this 377 * is set by HTC when credit reports arrive. The credit 378 * distribution functions sets this to zero when it distributes 379 * the credits. 380 */ 381 int cred_to_dist; 382 383 /* 384 * the number of credits that the current pending TX packet needs 385 * to transmit. This is set by HTC when endpoint needs credits in 386 * order to transmit. 387 */ 388 int seek_cred; 389 390 /* size in bytes of each credit */ 391 int cred_sz; 392 393 /* credits required for a maximum sized messages */ 394 int cred_per_msg; 395 396 /* reserved for HTC use */ 397 struct htc_endpoint *htc_ep; 398 399 /* 400 * current depth of TX queue , i.e. messages waiting for credits 401 * This field is valid only when HTC_CREDIT_DIST_ACTIVITY_CHANGE 402 * or HTC_CREDIT_DIST_SEND_COMPLETE is indicated on an endpoint 403 * that has non-zero credits to recover. 404 */ 405 int txq_depth; 406 }; 407 408 /* 409 * credit distibution code that is passed into the distrbution function, 410 * there are mandatory and optional codes that must be handled 411 */ 412 enum htc_credit_dist_reason { 413 HTC_CREDIT_DIST_SEND_COMPLETE = 0, 414 HTC_CREDIT_DIST_ACTIVITY_CHANGE = 1, 415 HTC_CREDIT_DIST_SEEK_CREDITS, 416 }; 417 418 struct ath6kl_htc_credit_info { 419 int total_avail_credits; 420 int cur_free_credits; 421 422 /* list of lowest priority endpoints */ 423 struct list_head lowestpri_ep_dist; 424 }; 425 426 /* endpoint statistics */ 427 struct htc_endpoint_stats { 428 /* 429 * number of times the host set the credit-low flag in a send 430 * message on this endpoint 431 */ 432 u32 cred_low_indicate; 433 434 u32 tx_issued; 435 u32 tx_pkt_bundled; 436 u32 tx_bundles; 437 u32 tx_dropped; 438 439 /* running count of total credit reports received for this endpoint */ 440 u32 tx_cred_rpt; 441 442 /* credit reports received from this endpoint's RX packets */ 443 u32 cred_rpt_from_rx; 444 445 /* credit reports received from RX packets of other endpoints */ 446 u32 cred_rpt_from_other; 447 448 /* credit reports received from endpoint 0 RX packets */ 449 u32 cred_rpt_ep0; 450 451 /* count of credits received via Rx packets on this endpoint */ 452 u32 cred_from_rx; 453 454 /* count of credits received via another endpoint */ 455 u32 cred_from_other; 456 457 /* count of credits received via another endpoint */ 458 u32 cred_from_ep0; 459 460 /* count of consummed credits */ 461 u32 cred_cosumd; 462 463 /* count of credits returned */ 464 u32 cred_retnd; 465 466 u32 rx_pkts; 467 468 /* count of lookahead records found in Rx msg */ 469 u32 rx_lkahds; 470 471 /* count of recv packets received in a bundle */ 472 u32 rx_bundl; 473 474 /* count of number of bundled lookaheads */ 475 u32 rx_bundle_lkahd; 476 477 /* count of the number of bundle indications from the HTC header */ 478 u32 rx_bundle_from_hdr; 479 480 /* the number of times the recv allocation threshold was hit */ 481 u32 rx_alloc_thresh_hit; 482 483 /* total number of bytes */ 484 u32 rxalloc_thresh_byte; 485 }; 486 487 struct htc_endpoint { 488 enum htc_endpoint_id eid; 489 u16 svc_id; 490 struct list_head txq; 491 struct list_head rx_bufq; 492 struct htc_endpoint_credit_dist cred_dist; 493 struct htc_ep_callbacks ep_cb; 494 int max_txq_depth; 495 int len_max; 496 int tx_proc_cnt; 497 int rx_proc_cnt; 498 struct htc_target *target; 499 u8 seqno; 500 u32 conn_flags; 501 struct htc_endpoint_stats ep_st; 502 }; 503 504 struct htc_control_buffer { 505 struct htc_packet packet; 506 u8 *buf; 507 }; 508 509 struct ath6kl_device; 510 511 /* our HTC target state */ 512 struct htc_target { 513 struct htc_endpoint endpoint[ENDPOINT_MAX]; 514 515 /* contains struct htc_endpoint_credit_dist */ 516 struct list_head cred_dist_list; 517 518 struct list_head free_ctrl_txbuf; 519 struct list_head free_ctrl_rxbuf; 520 struct ath6kl_htc_credit_info *credit_info; 521 int tgt_creds; 522 unsigned int tgt_cred_sz; 523 spinlock_t htc_lock; 524 spinlock_t rx_lock; 525 spinlock_t tx_lock; 526 struct ath6kl_device *dev; 527 u32 htc_flags; 528 u32 rx_st_flags; 529 enum htc_endpoint_id ep_waiting; 530 u8 htc_tgt_ver; 531 532 /* max messages per bundle for HTC */ 533 int msg_per_bndl_max; 534 535 bool tx_bndl_enable; 536 int rx_bndl_enable; 537 int max_rx_bndl_sz; 538 int max_tx_bndl_sz; 539 540 u32 block_sz; 541 u32 block_mask; 542 543 int max_scat_entries; 544 int max_xfer_szper_scatreq; 545 546 int chk_irq_status_cnt; 547 }; 548 549 void *ath6kl_htc_create(struct ath6kl *ar); 550 void ath6kl_htc_set_credit_dist(struct htc_target *target, 551 struct ath6kl_htc_credit_info *cred_info, 552 u16 svc_pri_order[], int len); 553 int ath6kl_htc_wait_target(struct htc_target *target); 554 int ath6kl_htc_start(struct htc_target *target); 555 int ath6kl_htc_conn_service(struct htc_target *target, 556 struct htc_service_connect_req *req, 557 struct htc_service_connect_resp *resp); 558 int ath6kl_htc_tx(struct htc_target *target, struct htc_packet *packet); 559 void ath6kl_htc_stop(struct htc_target *target); 560 void ath6kl_htc_cleanup(struct htc_target *target); 561 void ath6kl_htc_flush_txep(struct htc_target *target, 562 enum htc_endpoint_id endpoint, u16 tag); 563 void ath6kl_htc_flush_rx_buf(struct htc_target *target); 564 void ath6kl_htc_indicate_activity_change(struct htc_target *target, 565 enum htc_endpoint_id endpoint, 566 bool active); 567 int ath6kl_htc_get_rxbuf_num(struct htc_target *target, 568 enum htc_endpoint_id endpoint); 569 int ath6kl_htc_add_rxbuf_multiple(struct htc_target *target, 570 struct list_head *pktq); 571 int ath6kl_htc_rxmsg_pending_handler(struct htc_target *target, 572 u32 msg_look_ahead, int *n_pkts); 573 574 int ath6kl_credit_setup(void *htc_handle, 575 struct ath6kl_htc_credit_info *cred_info); 576 577 static inline void set_htc_pkt_info(struct htc_packet *packet, void *context, 578 u8 *buf, unsigned int len, 579 enum htc_endpoint_id eid, u16 tag) 580 { 581 packet->pkt_cntxt = context; 582 packet->buf = buf; 583 packet->act_len = len; 584 packet->endpoint = eid; 585 packet->info.tx.tag = tag; 586 } 587 588 static inline void htc_rxpkt_reset(struct htc_packet *packet) 589 { 590 packet->buf = packet->buf_start; 591 packet->act_len = 0; 592 } 593 594 static inline void set_htc_rxpkt_info(struct htc_packet *packet, void *context, 595 u8 *buf, unsigned long len, 596 enum htc_endpoint_id eid) 597 { 598 packet->pkt_cntxt = context; 599 packet->buf = buf; 600 packet->buf_start = buf; 601 packet->buf_len = len; 602 packet->endpoint = eid; 603 } 604 605 static inline int get_queue_depth(struct list_head *queue) 606 { 607 struct list_head *tmp_list; 608 int depth = 0; 609 610 list_for_each(tmp_list, queue) 611 depth++; 612 613 return depth; 614 } 615 616 #endif 617