forked from Minki/linux
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:
parent
e76ac2bf63
commit
636f828844
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
1713
drivers/net/wireless/ath/ath6kl/htc_pipe.c
Normal file
1713
drivers/net/wireless/ath/ath6kl/htc_pipe.c
Normal file
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user