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