ath6kl: Add HTC pipe implementation

This is needed for USB.

Based on code by Kevin Fang.

Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
This commit is contained in:
Kalle Valo 2012-03-25 17:15:28 +03:00
parent e76ac2bf63
commit 636f828844
7 changed files with 1808 additions and 0 deletions

View File

@ -26,6 +26,7 @@ obj-$(CONFIG_ATH6KL) += ath6kl_core.o
ath6kl_core-y += debug.o
ath6kl_core-y += hif.o
ath6kl_core-y += htc_mbox.o
ath6kl_core-y += htc_pipe.o
ath6kl_core-y += bmi.o
ath6kl_core-y += cfg80211.o
ath6kl_core-y += init.o

View File

@ -40,6 +40,18 @@ module_param(uart_debug, uint, 0644);
module_param(ath6kl_p2p, uint, 0644);
module_param(testmode, uint, 0644);
void ath6kl_core_tx_complete(struct ath6kl *ar, struct sk_buff *skb)
{
ath6kl_htc_tx_complete(ar, skb);
}
EXPORT_SYMBOL(ath6kl_core_tx_complete);
void ath6kl_core_rx_complete(struct ath6kl *ar, struct sk_buff *skb, u8 pipe)
{
ath6kl_htc_rx_complete(ar, skb, pipe);
}
EXPORT_SYMBOL(ath6kl_core_rx_complete);
int ath6kl_core_init(struct ath6kl *ar, enum ath6kl_htc_type htc_type)
{
struct ath6kl_bmi_target_info targ_info;
@ -50,6 +62,9 @@ int ath6kl_core_init(struct ath6kl *ar, enum ath6kl_htc_type htc_type)
case ATH6KL_HTC_TYPE_MBOX:
ath6kl_htc_mbox_attach(ar);
break;
case ATH6KL_HTC_TYPE_PIPE:
ath6kl_htc_pipe_attach(ar);
break;
default:
WARN_ON(1);
return -ENOMEM;

View File

@ -464,6 +464,7 @@ enum ath6kl_hif_type {
enum ath6kl_htc_type {
ATH6KL_HTC_TYPE_MBOX,
ATH6KL_HTC_TYPE_PIPE,
};
/* Max number of filters that hw supports */
@ -835,6 +836,9 @@ int ath6kl_init_hw_params(struct ath6kl *ar);
void ath6kl_check_wow_status(struct ath6kl *ar);
void ath6kl_core_tx_complete(struct ath6kl *ar, struct sk_buff *skb);
void ath6kl_core_rx_complete(struct ath6kl *ar, struct sk_buff *skb, u8 pipe);
struct ath6kl *ath6kl_core_create(struct device *dev);
int ath6kl_core_init(struct ath6kl *ar, enum ath6kl_htc_type htc_type);
void ath6kl_core_cleanup(struct ath6kl *ar);

View File

@ -150,4 +150,38 @@ static inline void ath6kl_hif_stop(struct ath6kl *ar)
ar->hif_ops->stop(ar);
}
static inline int ath6kl_hif_pipe_send(struct ath6kl *ar,
u8 pipe, struct sk_buff *hdr_buf,
struct sk_buff *buf)
{
ath6kl_dbg(ATH6KL_DBG_HIF, "hif pipe send\n");
return ar->hif_ops->pipe_send(ar, pipe, hdr_buf, buf);
}
static inline void ath6kl_hif_pipe_get_default(struct ath6kl *ar,
u8 *ul_pipe, u8 *dl_pipe)
{
ath6kl_dbg(ATH6KL_DBG_HIF, "hif pipe get default\n");
ar->hif_ops->pipe_get_default(ar, ul_pipe, dl_pipe);
}
static inline int ath6kl_hif_pipe_map_service(struct ath6kl *ar,
u16 service_id, u8 *ul_pipe,
u8 *dl_pipe)
{
ath6kl_dbg(ATH6KL_DBG_HIF, "hif pipe get default\n");
return ar->hif_ops->pipe_map_service(ar, service_id, ul_pipe, dl_pipe);
}
static inline u16 ath6kl_hif_pipe_get_free_queue_number(struct ath6kl *ar,
u8 pipe)
{
ath6kl_dbg(ATH6KL_DBG_HIF, "hif pipe get free queue number\n");
return ar->hif_ops->pipe_get_free_queue_number(ar, pipe);
}
#endif

View File

@ -256,6 +256,12 @@ struct ath6kl_hif_ops {
int (*power_on)(struct ath6kl *ar);
int (*power_off)(struct ath6kl *ar);
void (*stop)(struct ath6kl *ar);
int (*pipe_send)(struct ath6kl *ar, u8 pipe, struct sk_buff *hdr_buf,
struct sk_buff *buf);
void (*pipe_get_default)(struct ath6kl *ar, u8 *pipe_ul, u8 *pipe_dl);
int (*pipe_map_service)(struct ath6kl *ar, u16 service_id, u8 *pipe_ul,
u8 *pipe_dl);
u16 (*pipe_get_free_queue_number)(struct ath6kl *ar, u8 pipe);
};
int ath6kl_hif_setup(struct ath6kl_device *dev);

View File

@ -25,6 +25,7 @@
/* send direction */
#define HTC_FLAGS_NEED_CREDIT_UPDATE (1 << 0)
#define HTC_FLAGS_SEND_BUNDLE (1 << 1)
#define HTC_FLAGS_TX_FIXUP_NETBUF (1 << 2)
/* receive direction */
#define HTC_FLG_RX_UNUSED (1 << 0)
@ -56,6 +57,10 @@
#define HTC_CONN_FLGS_THRESH_LVL_THREE_QUAT 0x2
#define HTC_CONN_FLGS_REDUCE_CRED_DRIB 0x4
#define HTC_CONN_FLGS_THRESH_MASK 0x3
/* disable credit flow control on a specific service */
#define HTC_CONN_FLGS_DISABLE_CRED_FLOW_CTRL (1 << 3)
#define HTC_CONN_FLGS_SET_RECV_ALLOC_SHIFT 8
#define HTC_CONN_FLGS_SET_RECV_ALLOC_MASK 0xFF00
/* connect response status codes */
#define HTC_SERVICE_SUCCESS 0
@ -75,6 +80,7 @@
#define HTC_RECORD_LOOKAHEAD_BUNDLE 3
#define HTC_SETUP_COMP_FLG_RX_BNDL_EN (1 << 0)
#define HTC_SETUP_COMP_FLG_DISABLE_TX_CREDIT_FLOW (1 << 1)
#define MAKE_SERVICE_ID(group, index) \
(int)(((int)group << 8) | (int)(index))
@ -109,6 +115,8 @@
/* HTC operational parameters */
#define HTC_TARGET_RESPONSE_TIMEOUT 2000 /* in ms */
#define HTC_TARGET_RESPONSE_POLL_WAIT 10
#define HTC_TARGET_RESPONSE_POLL_COUNT 200
#define HTC_TARGET_DEBUG_INTR_MASK 0x01
#define HTC_TARGET_CREDIT_INTR_MASK 0xF0
@ -128,6 +136,7 @@
#define HTC_RECV_WAIT_BUFFERS (1 << 0)
#define HTC_OP_STATE_STOPPING (1 << 0)
#define HTC_OP_STATE_SETUP_COMPLETE (1 << 1)
/*
* The frame header length and message formats defined herein were selected
@ -512,6 +521,13 @@ struct htc_endpoint {
u32 conn_flags;
struct htc_endpoint_stats ep_st;
u16 tx_drop_packet_threshold;
struct {
u8 pipeid_ul;
u8 pipeid_dl;
struct list_head tx_lookup_queue;
bool tx_credit_flow_enabled;
} pipe;
};
struct htc_control_buffer {
@ -519,6 +535,16 @@ struct htc_control_buffer {
u8 *buf;
};
struct htc_pipe_txcredit_alloc {
u16 service_id;
u8 credit_alloc;
};
enum htc_send_queue_result {
HTC_SEND_QUEUE_OK = 0, /* packet was queued */
HTC_SEND_QUEUE_DROP = 1, /* this packet should be dropped */
};
struct ath6kl_htc_ops {
void* (*create)(struct ath6kl *ar);
int (*wait_target)(struct htc_target *target);
@ -593,6 +619,14 @@ struct htc_target {
/* counts the number of Tx without bundling continously per AC */
u32 ac_tx_count[WMM_NUM_AC];
struct {
struct htc_packet *htc_packet_pool;
u8 ctrl_response_buf[HTC_MAX_CTRL_MSG_LEN];
int ctrl_response_len;
bool ctrl_response_valid;
struct htc_pipe_txcredit_alloc txcredit_alloc[ENDPOINT_MAX];
} pipe;
};
int ath6kl_htc_rxmsg_pending_handler(struct htc_target *target,
@ -637,6 +671,7 @@ static inline int get_queue_depth(struct list_head *queue)
return depth;
}
void ath6kl_htc_pipe_attach(struct ath6kl *ar);
void ath6kl_htc_mbox_attach(struct ath6kl *ar);
#endif

File diff suppressed because it is too large Load Diff