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