685 lines · c
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 any6 * purpose with or without fee is hereby granted, provided that the above7 * copyright notice and this permission notice appear in all copies.8 *9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.16 */17 18#ifndef HTC_H19#define HTC_H20 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 436 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 143#define HTC_MSG_CONN_SVC_ID 244#define HTC_MSG_CONN_SVC_RESP_ID 345#define HTC_MSG_SETUP_COMPLETE_ID 446#define HTC_MSG_SETUP_COMPLETE_EX_ID 547 48#define HTC_MAX_CTRL_MSG_LEN 25649 50#define HTC_VERSION_2P0 0x0051#define HTC_VERSION_2P1 0x0152 53#define HTC_SERVICE_META_DATA_MAX_LENGTH 12854 55#define HTC_CONN_FLGS_THRESH_LVL_QUAT 0x056#define HTC_CONN_FLGS_THRESH_LVL_HALF 0x157#define HTC_CONN_FLGS_THRESH_LVL_THREE_QUAT 0x258#define HTC_CONN_FLGS_REDUCE_CRED_DRIB 0x459#define HTC_CONN_FLGS_THRESH_MASK 0x360/* 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 863#define HTC_CONN_FLGS_SET_RECV_ALLOC_MASK 0xFF00U64 65/* connect response status codes */66#define HTC_SERVICE_SUCCESS 067#define HTC_SERVICE_NOT_FOUND 168#define HTC_SERVICE_FAILED 269 70/* no resources (i.e. no more endpoints) */71#define HTC_SERVICE_NO_RESOURCES 372 73/* specific service is not allowing any more endpoints */74#define HTC_SERVICE_NO_MORE_EP 475 76/* report record IDs */77#define HTC_RECORD_NULL 078#define HTC_RECORD_CREDITS 179#define HTC_RECORD_LOOKAHEAD 280#define HTC_RECORD_LOOKAHEAD_BUNDLE 381 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 596 97#define WMM_NUM_AC 498 99/* reserved and used to flush ALL packets */100#define HTC_TX_PACKET_TAG_ALL 0101#define HTC_SERVICE_TX_PACKET_TAG 1102#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 0109/* TODO -remove me, but we have to fix BMI first */110#define HTC_MAILBOX_NUM_MAX 4111 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 10119#define HTC_TARGET_RESPONSE_POLL_COUNT 200120#define HTC_TARGET_DEBUG_INTR_MASK 0x01121#define HTC_TARGET_CREDIT_INTR_MASK 0xF0122 123#define HTC_HOST_MAX_MSG_PER_BUNDLE 8124#define HTC_MIN_HTC_MSGS_TO_BUNDLE 2125 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 8134#define NUM_CONTROL_TX_BUFFERS 2135#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 selected143 * to accommodate optimal alignment for target processing. This reduces144 * code size and improves performance. Any changes to the header length may145 * alter the alignment and cause exceptions on the target. When adding to146 * the messagestructures insure that fields are properly aligned.147 */148 149/* HTC frame header150 *151 * NOTE: do not remove or re-arrange the fields, these are minimally152 * required to take advantage of 4-byte lookaheads in some hardware153 * 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_valid234 * and Post Valid guard bytes. The pre_valid bytes must235 * 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 = 255255};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 real297 * buffer start here. In receive callbacks, the HTC layer298 * sets buf to the start of the payload past the header.299 * This field allows the caller to reset buf when it recycles300 * receive packets back to HTC.301 */302 u8 *buf_start;303 304 /*305 * Pointer to the start of the buffer. In the transmit306 * direction this points to the start of the payload. In the307 * receive direction, however, the buffer when queued up308 * points to the start of the HTC header but when returned309 * to the caller points to the start of the payload310 */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 packet333 * can pass the network buffer corresponding to the HTC packet334 * lower layers may optimized the transfer knowing this is335 * a network buffer336 */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 this391 * 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, this405 * is set by HTC when credit reports arrive. The credit406 * distribution functions sets this to zero when it distributes407 * the credits.408 */409 int cred_to_dist;410 411 /*412 * the number of credits that the current pending TX packet needs413 * to transmit. This is set by HTC when endpoint needs credits in414 * 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 credits429 * This field is valid only when HTC_CREDIT_DIST_ACTIVITY_CHANGE430 * or HTC_CREDIT_DIST_SEND_COMPLETE is indicated on an endpoint431 * 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 handled439 */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 send458 * message on this endpoint459 */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#endif685