2011-07-18 00:22:30 +03:00
/*
* Copyright ( c ) 2004 - 2011 Atheros Communications Inc .
*
* Permission to use , copy , modify , and / or distribute this software for any
* purpose with or without fee is hereby granted , provided that the above
* copyright notice and this permission notice appear in all copies .
*
* THE SOFTWARE IS PROVIDED " AS IS " AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS . IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL , DIRECT , INDIRECT , OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE , DATA OR PROFITS , WHETHER IN AN
* ACTION OF CONTRACT , NEGLIGENCE OR OTHER TORTIOUS ACTION , ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE .
*/
# ifndef HTC_H
# define HTC_H
# include "common.h"
/* frame header flags */
/* send direction */
# define HTC_FLAGS_NEED_CREDIT_UPDATE (1 << 0)
# define HTC_FLAGS_SEND_BUNDLE (1 << 1)
/* receive direction */
# define HTC_FLG_RX_UNUSED (1 << 0)
# define HTC_FLG_RX_TRAILER (1 << 1)
/* Bundle count maske and shift */
# define HTC_FLG_RX_BNDL_CNT (0xF0)
# define HTC_FLG_RX_BNDL_CNT_S 4
# define HTC_HDR_LENGTH (sizeof(struct htc_frame_hdr))
# define HTC_MAX_PAYLOAD_LENGTH (4096 - sizeof(struct htc_frame_hdr))
/* HTC control message IDs */
# define HTC_MSG_READY_ID 1
# define HTC_MSG_CONN_SVC_ID 2
# define HTC_MSG_CONN_SVC_RESP_ID 3
# define HTC_MSG_SETUP_COMPLETE_ID 4
# define HTC_MSG_SETUP_COMPLETE_EX_ID 5
# define HTC_MAX_CTRL_MSG_LEN 256
# define HTC_VERSION_2P0 0x00
# define HTC_VERSION_2P1 0x01
# define HTC_SERVICE_META_DATA_MAX_LENGTH 128
# define HTC_CONN_FLGS_THRESH_LVL_QUAT 0x0
# define HTC_CONN_FLGS_THRESH_LVL_HALF 0x1
# define HTC_CONN_FLGS_THRESH_LVL_THREE_QUAT 0x2
# define HTC_CONN_FLGS_REDUCE_CRED_DRIB 0x4
# define HTC_CONN_FLGS_THRESH_MASK 0x3
/* connect response status codes */
# define HTC_SERVICE_SUCCESS 0
# define HTC_SERVICE_NOT_FOUND 1
# define HTC_SERVICE_FAILED 2
/* no resources (i.e. no more endpoints) */
# define HTC_SERVICE_NO_RESOURCES 3
/* specific service is not allowing any more endpoints */
# define HTC_SERVICE_NO_MORE_EP 4
/* report record IDs */
# define HTC_RECORD_NULL 0
# define HTC_RECORD_CREDITS 1
# define HTC_RECORD_LOOKAHEAD 2
# define HTC_RECORD_LOOKAHEAD_BUNDLE 3
# define HTC_SETUP_COMP_FLG_RX_BNDL_EN (1 << 0)
# define MAKE_SERVICE_ID(group, index) \
( int ) ( ( ( int ) group < < 8 ) | ( int ) ( index ) )
/* NOTE: service ID of 0x0000 is reserved and should never be used */
# define HTC_CTRL_RSVD_SVC MAKE_SERVICE_ID(RSVD_SERVICE_GROUP, 1)
# define WMI_CONTROL_SVC MAKE_SERVICE_ID(WMI_SERVICE_GROUP, 0)
# define WMI_DATA_BE_SVC MAKE_SERVICE_ID(WMI_SERVICE_GROUP, 1)
# define WMI_DATA_BK_SVC MAKE_SERVICE_ID(WMI_SERVICE_GROUP, 2)
# define WMI_DATA_VI_SVC MAKE_SERVICE_ID(WMI_SERVICE_GROUP, 3)
# define WMI_DATA_VO_SVC MAKE_SERVICE_ID(WMI_SERVICE_GROUP, 4)
# define WMI_MAX_SERVICES 5
/* reserved and used to flush ALL packets */
# define HTC_TX_PACKET_TAG_ALL 0
# define HTC_SERVICE_TX_PACKET_TAG 1
# define HTC_TX_PACKET_TAG_USER_DEFINED (HTC_SERVICE_TX_PACKET_TAG + 9)
/* more packets on this endpoint are being fetched */
# define HTC_RX_FLAGS_INDICATE_MORE_PKTS (1 << 0)
/* TODO.. for BMI */
# define ENDPOINT1 0
/* TODO -remove me, but we have to fix BMI first */
# define HTC_MAILBOX_NUM_MAX 4
/* enable send bundle padding for this endpoint */
# define HTC_FLGS_TX_BNDL_PAD_EN (1 << 0)
# define HTC_EP_ACTIVE ((u32) (1u << 31))
/* HTC operational parameters */
# define HTC_TARGET_RESPONSE_TIMEOUT 2000 /* in ms */
# define HTC_TARGET_DEBUG_INTR_MASK 0x01
# define HTC_TARGET_CREDIT_INTR_MASK 0xF0
# define HTC_HOST_MAX_MSG_PER_BUNDLE 8
# define HTC_MIN_HTC_MSGS_TO_BUNDLE 2
/* packet flags */
# define HTC_RX_PKT_IGNORE_LOOKAHEAD (1 << 0)
# define HTC_RX_PKT_REFRESH_HDR (1 << 1)
# define HTC_RX_PKT_PART_OF_BUNDLE (1 << 2)
# define HTC_RX_PKT_NO_RECYCLE (1 << 3)
# define NUM_CONTROL_BUFFERS 8
# define NUM_CONTROL_TX_BUFFERS 2
# define NUM_CONTROL_RX_BUFFERS (NUM_CONTROL_BUFFERS - NUM_CONTROL_TX_BUFFERS)
# define HTC_RECV_WAIT_BUFFERS (1 << 0)
# define HTC_OP_STATE_STOPPING (1 << 0)
/*
* The frame header length and message formats defined herein were selected
* to accommodate optimal alignment for target processing . This reduces
* code size and improves performance . Any changes to the header length may
* alter the alignment and cause exceptions on the target . When adding to
* the messagestructures insure that fields are properly aligned .
*/
/* HTC frame header
*
* NOTE : do not remove or re - arrange the fields , these are minimally
* required to take advantage of 4 - byte lookaheads in some hardware
* implementations .
*/
struct htc_frame_hdr {
u8 eid ;
u8 flags ;
/* length of data (including trailer) that follows the header */
__le16 payld_len ;
/* end of 4-byte lookahead */
u8 ctrl [ 2 ] ;
} __packed ;
/* HTC ready message */
struct htc_ready_msg {
__le16 msg_id ;
__le16 cred_cnt ;
__le16 cred_sz ;
u8 max_ep ;
u8 pad ;
} __packed ;
/* extended HTC ready message */
struct htc_ready_ext_msg {
struct htc_ready_msg ver2_0_info ;
u8 htc_ver ;
u8 msg_per_htc_bndl ;
} __packed ;
/* connect service */
struct htc_conn_service_msg {
__le16 msg_id ;
__le16 svc_id ;
__le16 conn_flags ;
u8 svc_meta_len ;
u8 pad ;
} __packed ;
/* connect response */
struct htc_conn_service_resp {
__le16 msg_id ;
__le16 svc_id ;
u8 status ;
u8 eid ;
__le16 max_msg_sz ;
u8 svc_meta_len ;
u8 pad ;
} __packed ;
struct htc_setup_comp_msg {
__le16 msg_id ;
} __packed ;
/* extended setup completion message */
struct htc_setup_comp_ext_msg {
__le16 msg_id ;
__le32 flags ;
u8 msg_per_rxbndl ;
u8 Rsvd [ 3 ] ;
} __packed ;
struct htc_record_hdr {
u8 rec_id ;
u8 len ;
} __packed ;
struct htc_credit_report {
u8 eid ;
u8 credits ;
} __packed ;
/*
* NOTE : The lk_ahd array is guarded by a pre_valid
* and Post Valid guard bytes . The pre_valid bytes must
* equal the inverse of the post_valid byte .
*/
struct htc_lookahead_report {
u8 pre_valid ;
u8 lk_ahd [ 4 ] ;
u8 post_valid ;
} __packed ;
struct htc_bundle_lkahd_rpt {
u8 lk_ahd [ 4 ] ;
} __packed ;
/* Current service IDs */
enum htc_service_grp_ids {
RSVD_SERVICE_GROUP = 0 ,
WMI_SERVICE_GROUP = 1 ,
HTC_TEST_GROUP = 254 ,
HTC_SERVICE_GROUP_LAST = 255
} ;
/* ------ endpoint IDS ------ */
enum htc_endpoint_id {
ENDPOINT_UNUSED = - 1 ,
ENDPOINT_0 = 0 ,
ENDPOINT_1 = 1 ,
ENDPOINT_2 = 2 ,
ENDPOINT_3 ,
ENDPOINT_4 ,
ENDPOINT_5 ,
ENDPOINT_6 ,
ENDPOINT_7 ,
ENDPOINT_8 ,
ENDPOINT_MAX ,
} ;
struct htc_tx_packet_info {
u16 tag ;
int cred_used ;
u8 flags ;
int seqno ;
} ;
struct htc_rx_packet_info {
u32 exp_hdr ;
u32 rx_flags ;
u32 indicat_flags ;
} ;
struct htc_target ;
/* wrapper around endpoint-specific packets */
struct htc_packet {
struct list_head list ;
/* caller's per packet specific context */
void * pkt_cntxt ;
/*
* the true buffer start , the caller can store the real
* buffer start here . In receive callbacks , the HTC layer
* sets buf to the start of the payload past the header .
* This field allows the caller to reset buf when it recycles
* receive packets back to HTC .
*/
u8 * buf_start ;
/*
* Pointer to the start of the buffer . In the transmit
* direction this points to the start of the payload . In the
* receive direction , however , the buffer when queued up
* points to the start of the HTC header but when returned
* to the caller points to the start of the payload
*/
u8 * buf ;
u32 buf_len ;
/* actual length of payload */
u32 act_len ;
/* endpoint that this packet was sent/recv'd from */
enum htc_endpoint_id endpoint ;
/* completion status */
int status ;
union {
struct htc_tx_packet_info tx ;
struct htc_rx_packet_info rx ;
} info ;
void ( * completion ) ( struct htc_target * , struct htc_packet * ) ;
struct htc_target * context ;
} ;
enum htc_send_full_action {
HTC_SEND_FULL_KEEP = 0 ,
HTC_SEND_FULL_DROP = 1 ,
} ;
struct htc_ep_callbacks {
void ( * rx ) ( struct htc_target * , struct htc_packet * ) ;
void ( * rx_refill ) ( struct htc_target * , enum htc_endpoint_id endpoint ) ;
enum htc_send_full_action ( * tx_full ) ( struct htc_target * ,
struct htc_packet * ) ;
struct htc_packet * ( * rx_allocthresh ) ( struct htc_target * ,
enum htc_endpoint_id , int ) ;
int rx_alloc_thresh ;
int rx_refill_thresh ;
} ;
/* service connection information */
struct htc_service_connect_req {
u16 svc_id ;
u16 conn_flags ;
struct htc_ep_callbacks ep_cb ;
int max_txq_depth ;
u32 flags ;
unsigned int max_rxmsg_sz ;
} ;
/* service connection response information */
struct htc_service_connect_resp {
u8 buf_len ;
u8 act_len ;
enum htc_endpoint_id endpoint ;
unsigned int len_max ;
u8 resp_code ;
} ;
/* endpoint distributionstructure */
struct htc_endpoint_credit_dist {
struct list_head list ;
/* Service ID (set by HTC) */
u16 svc_id ;
/* endpoint for this distributionstruct (set by HTC) */
enum htc_endpoint_id endpoint ;
u32 dist_flags ;
/*
* credits for normal operation , anything above this
* indicates the endpoint is over - subscribed .
*/
int cred_norm ;
/* floor for credit distribution */
int cred_min ;
int cred_assngd ;
/* current credits available */
int credits ;
/*
* pending credits to distribute on this endpoint , this
* is set by HTC when credit reports arrive . The credit
* distribution functions sets this to zero when it distributes
* the credits .
*/
int cred_to_dist ;
/*
* the number of credits that the current pending TX packet needs
* to transmit . This is set by HTC when endpoint needs credits in
* order to transmit .
*/
int seek_cred ;
/* size in bytes of each credit */
int cred_sz ;
/* credits required for a maximum sized messages */
int cred_per_msg ;
/* reserved for HTC use */
void * htc_rsvd ;
/*
* current depth of TX queue , i . e . messages waiting for credits
* This field is valid only when HTC_CREDIT_DIST_ACTIVITY_CHANGE
* or HTC_CREDIT_DIST_SEND_COMPLETE is indicated on an endpoint
* that has non - zero credits to recover .
*/
int txq_depth ;
} ;
/*
* credit distibution code that is passed into the distrbution function ,
* there are mandatory and optional codes that must be handled
*/
enum htc_credit_dist_reason {
HTC_CREDIT_DIST_SEND_COMPLETE = 0 ,
HTC_CREDIT_DIST_ACTIVITY_CHANGE = 1 ,
HTC_CREDIT_DIST_SEEK_CREDITS ,
} ;
struct htc_credit_state_info {
int total_avail_credits ;
int cur_free_credits ;
struct list_head lowestpri_ep_dist ;
} ;
/* endpoint statistics */
struct htc_endpoint_stats {
/*
* number of times the host set the credit - low flag in a send
* message on this endpoint
*/
u32 cred_low_indicate ;
u32 tx_issued ;
u32 tx_pkt_bundled ;
u32 tx_bundles ;
u32 tx_dropped ;
/* running count of total credit reports received for this endpoint */
u32 tx_cred_rpt ;
/* credit reports received from this endpoint's RX packets */
u32 cred_rpt_from_rx ;
/* credit reports received from RX packets of other endpoints */
u32 cred_rpt_from_other ;
/* credit reports received from endpoint 0 RX packets */
u32 cred_rpt_ep0 ;
/* count of credits received via Rx packets on this endpoint */
u32 cred_from_rx ;
/* count of credits received via another endpoint */
u32 cred_from_other ;
/* count of credits received via another endpoint */
u32 cred_from_ep0 ;
/* count of consummed credits */
u32 cred_cosumd ;
/* count of credits returned */
u32 cred_retnd ;
u32 rx_pkts ;
/* count of lookahead records found in Rx msg */
u32 rx_lkahds ;
/* count of recv packets received in a bundle */
u32 rx_bundl ;
/* count of number of bundled lookaheads */
u32 rx_bundle_lkahd ;
/* count of the number of bundle indications from the HTC header */
u32 rx_bundle_from_hdr ;
/* the number of times the recv allocation threshold was hit */
u32 rx_alloc_thresh_hit ;
/* total number of bytes */
u32 rxalloc_thresh_byte ;
} ;
struct htc_endpoint {
enum htc_endpoint_id eid ;
u16 svc_id ;
struct list_head txq ;
struct list_head rx_bufq ;
struct htc_endpoint_credit_dist cred_dist ;
struct htc_ep_callbacks ep_cb ;
int max_txq_depth ;
int len_max ;
int tx_proc_cnt ;
int rx_proc_cnt ;
struct htc_target * target ;
u8 seqno ;
u32 conn_flags ;
struct htc_endpoint_stats ep_st ;
} ;
struct htc_control_buffer {
struct htc_packet packet ;
u8 * buf ;
} ;
struct ath6kl_device ;
/* our HTC target state */
struct htc_target {
struct htc_endpoint endpoint [ ENDPOINT_MAX ] ;
struct list_head cred_dist_list ;
struct list_head free_ctrl_txbuf ;
struct list_head free_ctrl_rxbuf ;
struct htc_credit_state_info * cred_dist_cntxt ;
int tgt_creds ;
unsigned int tgt_cred_sz ;
spinlock_t htc_lock ;
spinlock_t rx_lock ;
spinlock_t tx_lock ;
struct ath6kl_device * dev ;
u32 htc_flags ;
u32 rx_st_flags ;
enum htc_endpoint_id ep_waiting ;
u8 htc_tgt_ver ;
/* max messages per bundle for HTC */
int msg_per_bndl_max ;
bool tx_bndl_enable ;
int rx_bndl_enable ;
2011-07-18 14:23:27 +05:30
int max_rx_bndl_sz ;
int max_tx_bndl_sz ;
2011-07-18 14:23:28 +05:30
u32 block_sz ;
u32 block_mask ;
2011-07-18 14:23:29 +05:30
int max_scat_entries ;
int max_xfer_szper_scatreq ;
2011-07-18 14:23:31 +05:30
int chk_irq_status_cnt ;
2011-07-18 00:22:30 +03:00
} ;
2011-08-10 09:49:12 +03:00
void * ath6kl_htc_create ( struct ath6kl * ar ) ;
void ath6kl_htc_set_credit_dist ( struct htc_target * target ,
struct htc_credit_state_info * cred_info ,
u16 svc_pri_order [ ] , int len ) ;
int ath6kl_htc_wait_target ( struct htc_target * target ) ;
int ath6kl_htc_start ( struct htc_target * target ) ;
int ath6kl_htc_conn_service ( struct htc_target * target ,
struct htc_service_connect_req * req ,
struct htc_service_connect_resp * resp ) ;
int ath6kl_htc_tx ( struct htc_target * target , struct htc_packet * packet ) ;
void ath6kl_htc_stop ( struct htc_target * target ) ;
void ath6kl_htc_cleanup ( struct htc_target * target ) ;
void ath6kl_htc_flush_txep ( struct htc_target * target ,
enum htc_endpoint_id endpoint , u16 tag ) ;
void ath6kl_htc_flush_rx_buf ( struct htc_target * target ) ;
void ath6kl_htc_indicate_activity_change ( struct htc_target * target ,
enum htc_endpoint_id endpoint ,
bool active ) ;
int ath6kl_htc_get_rxbuf_num ( struct htc_target * target ,
enum htc_endpoint_id endpoint ) ;
int ath6kl_htc_add_rxbuf_multiple ( struct htc_target * target ,
struct list_head * pktq ) ;
int ath6kl_htc_rxmsg_pending_handler ( struct htc_target * target ,
2011-10-03 17:26:27 +05:30
u32 msg_look_ahead , int * n_pkts ) ;
2011-07-18 00:22:30 +03:00
static inline void set_htc_pkt_info ( struct htc_packet * packet , void * context ,
u8 * buf , unsigned int len ,
enum htc_endpoint_id eid , u16 tag )
{
packet - > pkt_cntxt = context ;
packet - > buf = buf ;
packet - > act_len = len ;
packet - > endpoint = eid ;
packet - > info . tx . tag = tag ;
}
static inline void htc_rxpkt_reset ( struct htc_packet * packet )
{
packet - > buf = packet - > buf_start ;
packet - > act_len = 0 ;
}
static inline void set_htc_rxpkt_info ( struct htc_packet * packet , void * context ,
u8 * buf , unsigned long len ,
enum htc_endpoint_id eid )
{
packet - > pkt_cntxt = context ;
packet - > buf = buf ;
packet - > buf_start = buf ;
packet - > buf_len = len ;
packet - > endpoint = eid ;
}
static inline int get_queue_depth ( struct list_head * queue )
{
struct list_head * tmp_list ;
int depth = 0 ;
list_for_each ( tmp_list , queue )
depth + + ;
return depth ;
}
# endif