xref: /OK3568_Linux_fs/kernel/drivers/net/wireless/ath/ath10k/htt.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun // SPDX-License-Identifier: ISC
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun  * Copyright (c) 2005-2011 Atheros Communications Inc.
4*4882a593Smuzhiyun  * Copyright (c) 2011-2017 Qualcomm Atheros, Inc.
5*4882a593Smuzhiyun  */
6*4882a593Smuzhiyun 
7*4882a593Smuzhiyun #include <linux/slab.h>
8*4882a593Smuzhiyun #include <linux/if_ether.h>
9*4882a593Smuzhiyun 
10*4882a593Smuzhiyun #include "htt.h"
11*4882a593Smuzhiyun #include "core.h"
12*4882a593Smuzhiyun #include "debug.h"
13*4882a593Smuzhiyun #include "hif.h"
14*4882a593Smuzhiyun 
15*4882a593Smuzhiyun static const enum htt_t2h_msg_type htt_main_t2h_msg_types[] = {
16*4882a593Smuzhiyun 	[HTT_MAIN_T2H_MSG_TYPE_VERSION_CONF] = HTT_T2H_MSG_TYPE_VERSION_CONF,
17*4882a593Smuzhiyun 	[HTT_MAIN_T2H_MSG_TYPE_RX_IND] = HTT_T2H_MSG_TYPE_RX_IND,
18*4882a593Smuzhiyun 	[HTT_MAIN_T2H_MSG_TYPE_RX_FLUSH] = HTT_T2H_MSG_TYPE_RX_FLUSH,
19*4882a593Smuzhiyun 	[HTT_MAIN_T2H_MSG_TYPE_PEER_MAP] = HTT_T2H_MSG_TYPE_PEER_MAP,
20*4882a593Smuzhiyun 	[HTT_MAIN_T2H_MSG_TYPE_PEER_UNMAP] = HTT_T2H_MSG_TYPE_PEER_UNMAP,
21*4882a593Smuzhiyun 	[HTT_MAIN_T2H_MSG_TYPE_RX_ADDBA] = HTT_T2H_MSG_TYPE_RX_ADDBA,
22*4882a593Smuzhiyun 	[HTT_MAIN_T2H_MSG_TYPE_RX_DELBA] = HTT_T2H_MSG_TYPE_RX_DELBA,
23*4882a593Smuzhiyun 	[HTT_MAIN_T2H_MSG_TYPE_TX_COMPL_IND] = HTT_T2H_MSG_TYPE_TX_COMPL_IND,
24*4882a593Smuzhiyun 	[HTT_MAIN_T2H_MSG_TYPE_PKTLOG] = HTT_T2H_MSG_TYPE_PKTLOG,
25*4882a593Smuzhiyun 	[HTT_MAIN_T2H_MSG_TYPE_STATS_CONF] = HTT_T2H_MSG_TYPE_STATS_CONF,
26*4882a593Smuzhiyun 	[HTT_MAIN_T2H_MSG_TYPE_RX_FRAG_IND] = HTT_T2H_MSG_TYPE_RX_FRAG_IND,
27*4882a593Smuzhiyun 	[HTT_MAIN_T2H_MSG_TYPE_SEC_IND] = HTT_T2H_MSG_TYPE_SEC_IND,
28*4882a593Smuzhiyun 	[HTT_MAIN_T2H_MSG_TYPE_TX_INSPECT_IND] =
29*4882a593Smuzhiyun 		HTT_T2H_MSG_TYPE_TX_INSPECT_IND,
30*4882a593Smuzhiyun 	[HTT_MAIN_T2H_MSG_TYPE_MGMT_TX_COMPL_IND] =
31*4882a593Smuzhiyun 		HTT_T2H_MSG_TYPE_MGMT_TX_COMPLETION,
32*4882a593Smuzhiyun 	[HTT_MAIN_T2H_MSG_TYPE_TX_CREDIT_UPDATE_IND] =
33*4882a593Smuzhiyun 		HTT_T2H_MSG_TYPE_TX_CREDIT_UPDATE_IND,
34*4882a593Smuzhiyun 	[HTT_MAIN_T2H_MSG_TYPE_RX_PN_IND] = HTT_T2H_MSG_TYPE_RX_PN_IND,
35*4882a593Smuzhiyun 	[HTT_MAIN_T2H_MSG_TYPE_RX_OFFLOAD_DELIVER_IND] =
36*4882a593Smuzhiyun 		HTT_T2H_MSG_TYPE_RX_OFFLOAD_DELIVER_IND,
37*4882a593Smuzhiyun 	[HTT_MAIN_T2H_MSG_TYPE_TEST] = HTT_T2H_MSG_TYPE_TEST,
38*4882a593Smuzhiyun };
39*4882a593Smuzhiyun 
40*4882a593Smuzhiyun static const enum htt_t2h_msg_type htt_10x_t2h_msg_types[] = {
41*4882a593Smuzhiyun 	[HTT_10X_T2H_MSG_TYPE_VERSION_CONF] = HTT_T2H_MSG_TYPE_VERSION_CONF,
42*4882a593Smuzhiyun 	[HTT_10X_T2H_MSG_TYPE_RX_IND] = HTT_T2H_MSG_TYPE_RX_IND,
43*4882a593Smuzhiyun 	[HTT_10X_T2H_MSG_TYPE_RX_FLUSH] = HTT_T2H_MSG_TYPE_RX_FLUSH,
44*4882a593Smuzhiyun 	[HTT_10X_T2H_MSG_TYPE_PEER_MAP] = HTT_T2H_MSG_TYPE_PEER_MAP,
45*4882a593Smuzhiyun 	[HTT_10X_T2H_MSG_TYPE_PEER_UNMAP] = HTT_T2H_MSG_TYPE_PEER_UNMAP,
46*4882a593Smuzhiyun 	[HTT_10X_T2H_MSG_TYPE_RX_ADDBA] = HTT_T2H_MSG_TYPE_RX_ADDBA,
47*4882a593Smuzhiyun 	[HTT_10X_T2H_MSG_TYPE_RX_DELBA] = HTT_T2H_MSG_TYPE_RX_DELBA,
48*4882a593Smuzhiyun 	[HTT_10X_T2H_MSG_TYPE_TX_COMPL_IND] = HTT_T2H_MSG_TYPE_TX_COMPL_IND,
49*4882a593Smuzhiyun 	[HTT_10X_T2H_MSG_TYPE_PKTLOG] = HTT_T2H_MSG_TYPE_PKTLOG,
50*4882a593Smuzhiyun 	[HTT_10X_T2H_MSG_TYPE_STATS_CONF] = HTT_T2H_MSG_TYPE_STATS_CONF,
51*4882a593Smuzhiyun 	[HTT_10X_T2H_MSG_TYPE_RX_FRAG_IND] = HTT_T2H_MSG_TYPE_RX_FRAG_IND,
52*4882a593Smuzhiyun 	[HTT_10X_T2H_MSG_TYPE_SEC_IND] = HTT_T2H_MSG_TYPE_SEC_IND,
53*4882a593Smuzhiyun 	[HTT_10X_T2H_MSG_TYPE_RC_UPDATE_IND] = HTT_T2H_MSG_TYPE_RC_UPDATE_IND,
54*4882a593Smuzhiyun 	[HTT_10X_T2H_MSG_TYPE_TX_INSPECT_IND] = HTT_T2H_MSG_TYPE_TX_INSPECT_IND,
55*4882a593Smuzhiyun 	[HTT_10X_T2H_MSG_TYPE_TEST] = HTT_T2H_MSG_TYPE_TEST,
56*4882a593Smuzhiyun 	[HTT_10X_T2H_MSG_TYPE_CHAN_CHANGE] = HTT_T2H_MSG_TYPE_CHAN_CHANGE,
57*4882a593Smuzhiyun 	[HTT_10X_T2H_MSG_TYPE_AGGR_CONF] = HTT_T2H_MSG_TYPE_AGGR_CONF,
58*4882a593Smuzhiyun 	[HTT_10X_T2H_MSG_TYPE_STATS_NOUPLOAD] = HTT_T2H_MSG_TYPE_STATS_NOUPLOAD,
59*4882a593Smuzhiyun 	[HTT_10X_T2H_MSG_TYPE_MGMT_TX_COMPL_IND] =
60*4882a593Smuzhiyun 		HTT_T2H_MSG_TYPE_MGMT_TX_COMPLETION,
61*4882a593Smuzhiyun };
62*4882a593Smuzhiyun 
63*4882a593Smuzhiyun static const enum htt_t2h_msg_type htt_tlv_t2h_msg_types[] = {
64*4882a593Smuzhiyun 	[HTT_TLV_T2H_MSG_TYPE_VERSION_CONF] = HTT_T2H_MSG_TYPE_VERSION_CONF,
65*4882a593Smuzhiyun 	[HTT_TLV_T2H_MSG_TYPE_RX_IND] = HTT_T2H_MSG_TYPE_RX_IND,
66*4882a593Smuzhiyun 	[HTT_TLV_T2H_MSG_TYPE_RX_FLUSH] = HTT_T2H_MSG_TYPE_RX_FLUSH,
67*4882a593Smuzhiyun 	[HTT_TLV_T2H_MSG_TYPE_PEER_MAP] = HTT_T2H_MSG_TYPE_PEER_MAP,
68*4882a593Smuzhiyun 	[HTT_TLV_T2H_MSG_TYPE_PEER_UNMAP] = HTT_T2H_MSG_TYPE_PEER_UNMAP,
69*4882a593Smuzhiyun 	[HTT_TLV_T2H_MSG_TYPE_RX_ADDBA] = HTT_T2H_MSG_TYPE_RX_ADDBA,
70*4882a593Smuzhiyun 	[HTT_TLV_T2H_MSG_TYPE_RX_DELBA] = HTT_T2H_MSG_TYPE_RX_DELBA,
71*4882a593Smuzhiyun 	[HTT_TLV_T2H_MSG_TYPE_TX_COMPL_IND] = HTT_T2H_MSG_TYPE_TX_COMPL_IND,
72*4882a593Smuzhiyun 	[HTT_TLV_T2H_MSG_TYPE_PKTLOG] = HTT_T2H_MSG_TYPE_PKTLOG,
73*4882a593Smuzhiyun 	[HTT_TLV_T2H_MSG_TYPE_STATS_CONF] = HTT_T2H_MSG_TYPE_STATS_CONF,
74*4882a593Smuzhiyun 	[HTT_TLV_T2H_MSG_TYPE_RX_FRAG_IND] = HTT_T2H_MSG_TYPE_RX_FRAG_IND,
75*4882a593Smuzhiyun 	[HTT_TLV_T2H_MSG_TYPE_SEC_IND] = HTT_T2H_MSG_TYPE_SEC_IND,
76*4882a593Smuzhiyun 	[HTT_TLV_T2H_MSG_TYPE_RC_UPDATE_IND] = HTT_T2H_MSG_TYPE_RC_UPDATE_IND,
77*4882a593Smuzhiyun 	[HTT_TLV_T2H_MSG_TYPE_TX_INSPECT_IND] = HTT_T2H_MSG_TYPE_TX_INSPECT_IND,
78*4882a593Smuzhiyun 	[HTT_TLV_T2H_MSG_TYPE_MGMT_TX_COMPL_IND] =
79*4882a593Smuzhiyun 		HTT_T2H_MSG_TYPE_MGMT_TX_COMPLETION,
80*4882a593Smuzhiyun 	[HTT_TLV_T2H_MSG_TYPE_TX_CREDIT_UPDATE_IND] =
81*4882a593Smuzhiyun 		HTT_T2H_MSG_TYPE_TX_CREDIT_UPDATE_IND,
82*4882a593Smuzhiyun 	[HTT_TLV_T2H_MSG_TYPE_RX_PN_IND] = HTT_T2H_MSG_TYPE_RX_PN_IND,
83*4882a593Smuzhiyun 	[HTT_TLV_T2H_MSG_TYPE_RX_OFFLOAD_DELIVER_IND] =
84*4882a593Smuzhiyun 		HTT_T2H_MSG_TYPE_RX_OFFLOAD_DELIVER_IND,
85*4882a593Smuzhiyun 	[HTT_TLV_T2H_MSG_TYPE_RX_IN_ORD_PADDR_IND] =
86*4882a593Smuzhiyun 		HTT_T2H_MSG_TYPE_RX_IN_ORD_PADDR_IND,
87*4882a593Smuzhiyun 	[HTT_TLV_T2H_MSG_TYPE_WDI_IPA_OP_RESPONSE] =
88*4882a593Smuzhiyun 		HTT_T2H_MSG_TYPE_WDI_IPA_OP_RESPONSE,
89*4882a593Smuzhiyun 	[HTT_TLV_T2H_MSG_TYPE_CHAN_CHANGE] = HTT_T2H_MSG_TYPE_CHAN_CHANGE,
90*4882a593Smuzhiyun 	[HTT_TLV_T2H_MSG_TYPE_RX_OFLD_PKT_ERR] =
91*4882a593Smuzhiyun 		HTT_T2H_MSG_TYPE_RX_OFLD_PKT_ERR,
92*4882a593Smuzhiyun 	[HTT_TLV_T2H_MSG_TYPE_TEST] = HTT_T2H_MSG_TYPE_TEST,
93*4882a593Smuzhiyun };
94*4882a593Smuzhiyun 
95*4882a593Smuzhiyun static const enum htt_t2h_msg_type htt_10_4_t2h_msg_types[] = {
96*4882a593Smuzhiyun 	[HTT_10_4_T2H_MSG_TYPE_VERSION_CONF] = HTT_T2H_MSG_TYPE_VERSION_CONF,
97*4882a593Smuzhiyun 	[HTT_10_4_T2H_MSG_TYPE_RX_IND] = HTT_T2H_MSG_TYPE_RX_IND,
98*4882a593Smuzhiyun 	[HTT_10_4_T2H_MSG_TYPE_RX_FLUSH] = HTT_T2H_MSG_TYPE_RX_FLUSH,
99*4882a593Smuzhiyun 	[HTT_10_4_T2H_MSG_TYPE_PEER_MAP] = HTT_T2H_MSG_TYPE_PEER_MAP,
100*4882a593Smuzhiyun 	[HTT_10_4_T2H_MSG_TYPE_PEER_UNMAP] = HTT_T2H_MSG_TYPE_PEER_UNMAP,
101*4882a593Smuzhiyun 	[HTT_10_4_T2H_MSG_TYPE_RX_ADDBA] = HTT_T2H_MSG_TYPE_RX_ADDBA,
102*4882a593Smuzhiyun 	[HTT_10_4_T2H_MSG_TYPE_RX_DELBA] = HTT_T2H_MSG_TYPE_RX_DELBA,
103*4882a593Smuzhiyun 	[HTT_10_4_T2H_MSG_TYPE_TX_COMPL_IND] = HTT_T2H_MSG_TYPE_TX_COMPL_IND,
104*4882a593Smuzhiyun 	[HTT_10_4_T2H_MSG_TYPE_PKTLOG] = HTT_T2H_MSG_TYPE_PKTLOG,
105*4882a593Smuzhiyun 	[HTT_10_4_T2H_MSG_TYPE_STATS_CONF] = HTT_T2H_MSG_TYPE_STATS_CONF,
106*4882a593Smuzhiyun 	[HTT_10_4_T2H_MSG_TYPE_RX_FRAG_IND] = HTT_T2H_MSG_TYPE_RX_FRAG_IND,
107*4882a593Smuzhiyun 	[HTT_10_4_T2H_MSG_TYPE_SEC_IND] = HTT_T2H_MSG_TYPE_SEC_IND,
108*4882a593Smuzhiyun 	[HTT_10_4_T2H_MSG_TYPE_RC_UPDATE_IND] = HTT_T2H_MSG_TYPE_RC_UPDATE_IND,
109*4882a593Smuzhiyun 	[HTT_10_4_T2H_MSG_TYPE_TX_INSPECT_IND] =
110*4882a593Smuzhiyun 				HTT_T2H_MSG_TYPE_TX_INSPECT_IND,
111*4882a593Smuzhiyun 	[HTT_10_4_T2H_MSG_TYPE_MGMT_TX_COMPL_IND] =
112*4882a593Smuzhiyun 				HTT_T2H_MSG_TYPE_MGMT_TX_COMPLETION,
113*4882a593Smuzhiyun 	[HTT_10_4_T2H_MSG_TYPE_CHAN_CHANGE] = HTT_T2H_MSG_TYPE_CHAN_CHANGE,
114*4882a593Smuzhiyun 	[HTT_10_4_T2H_MSG_TYPE_TX_CREDIT_UPDATE_IND] =
115*4882a593Smuzhiyun 				HTT_T2H_MSG_TYPE_TX_CREDIT_UPDATE_IND,
116*4882a593Smuzhiyun 	[HTT_10_4_T2H_MSG_TYPE_RX_PN_IND] = HTT_T2H_MSG_TYPE_RX_PN_IND,
117*4882a593Smuzhiyun 	[HTT_10_4_T2H_MSG_TYPE_RX_OFFLOAD_DELIVER_IND] =
118*4882a593Smuzhiyun 				HTT_T2H_MSG_TYPE_RX_OFFLOAD_DELIVER_IND,
119*4882a593Smuzhiyun 	[HTT_10_4_T2H_MSG_TYPE_TEST] = HTT_T2H_MSG_TYPE_TEST,
120*4882a593Smuzhiyun 	[HTT_10_4_T2H_MSG_TYPE_EN_STATS] = HTT_T2H_MSG_TYPE_EN_STATS,
121*4882a593Smuzhiyun 	[HTT_10_4_T2H_MSG_TYPE_AGGR_CONF] = HTT_T2H_MSG_TYPE_AGGR_CONF,
122*4882a593Smuzhiyun 	[HTT_10_4_T2H_MSG_TYPE_TX_FETCH_IND] =
123*4882a593Smuzhiyun 				HTT_T2H_MSG_TYPE_TX_FETCH_IND,
124*4882a593Smuzhiyun 	[HTT_10_4_T2H_MSG_TYPE_TX_FETCH_CONFIRM] =
125*4882a593Smuzhiyun 				HTT_T2H_MSG_TYPE_TX_FETCH_CONFIRM,
126*4882a593Smuzhiyun 	[HTT_10_4_T2H_MSG_TYPE_STATS_NOUPLOAD] =
127*4882a593Smuzhiyun 				HTT_T2H_MSG_TYPE_STATS_NOUPLOAD,
128*4882a593Smuzhiyun 	[HTT_10_4_T2H_MSG_TYPE_TX_MODE_SWITCH_IND] =
129*4882a593Smuzhiyun 				HTT_T2H_MSG_TYPE_TX_MODE_SWITCH_IND,
130*4882a593Smuzhiyun 	[HTT_10_4_T2H_MSG_TYPE_PEER_STATS] =
131*4882a593Smuzhiyun 				HTT_T2H_MSG_TYPE_PEER_STATS,
132*4882a593Smuzhiyun };
133*4882a593Smuzhiyun 
ath10k_htt_connect(struct ath10k_htt * htt)134*4882a593Smuzhiyun int ath10k_htt_connect(struct ath10k_htt *htt)
135*4882a593Smuzhiyun {
136*4882a593Smuzhiyun 	struct ath10k_htc_svc_conn_req conn_req;
137*4882a593Smuzhiyun 	struct ath10k_htc_svc_conn_resp conn_resp;
138*4882a593Smuzhiyun 	struct ath10k *ar = htt->ar;
139*4882a593Smuzhiyun 	struct ath10k_htc_ep *ep;
140*4882a593Smuzhiyun 	int status;
141*4882a593Smuzhiyun 
142*4882a593Smuzhiyun 	memset(&conn_req, 0, sizeof(conn_req));
143*4882a593Smuzhiyun 	memset(&conn_resp, 0, sizeof(conn_resp));
144*4882a593Smuzhiyun 
145*4882a593Smuzhiyun 	conn_req.ep_ops.ep_tx_complete = ath10k_htt_htc_tx_complete;
146*4882a593Smuzhiyun 	conn_req.ep_ops.ep_rx_complete = ath10k_htt_htc_t2h_msg_handler;
147*4882a593Smuzhiyun 	conn_req.ep_ops.ep_tx_credits = ath10k_htt_op_ep_tx_credits;
148*4882a593Smuzhiyun 
149*4882a593Smuzhiyun 	/* connect to control service */
150*4882a593Smuzhiyun 	conn_req.service_id = ATH10K_HTC_SVC_ID_HTT_DATA_MSG;
151*4882a593Smuzhiyun 
152*4882a593Smuzhiyun 	status = ath10k_htc_connect_service(&htt->ar->htc, &conn_req,
153*4882a593Smuzhiyun 					    &conn_resp);
154*4882a593Smuzhiyun 
155*4882a593Smuzhiyun 	if (status)
156*4882a593Smuzhiyun 		return status;
157*4882a593Smuzhiyun 
158*4882a593Smuzhiyun 	htt->eid = conn_resp.eid;
159*4882a593Smuzhiyun 
160*4882a593Smuzhiyun 	if (ar->bus_param.dev_type == ATH10K_DEV_TYPE_HL) {
161*4882a593Smuzhiyun 		ep = &ar->htc.endpoint[htt->eid];
162*4882a593Smuzhiyun 		ath10k_htc_setup_tx_req(ep);
163*4882a593Smuzhiyun 	}
164*4882a593Smuzhiyun 
165*4882a593Smuzhiyun 	htt->disable_tx_comp = ath10k_hif_get_htt_tx_complete(htt->ar);
166*4882a593Smuzhiyun 	if (htt->disable_tx_comp)
167*4882a593Smuzhiyun 		ath10k_htc_change_tx_credit_flow(&htt->ar->htc, htt->eid, true);
168*4882a593Smuzhiyun 
169*4882a593Smuzhiyun 	return 0;
170*4882a593Smuzhiyun }
171*4882a593Smuzhiyun 
ath10k_htt_init(struct ath10k * ar)172*4882a593Smuzhiyun int ath10k_htt_init(struct ath10k *ar)
173*4882a593Smuzhiyun {
174*4882a593Smuzhiyun 	struct ath10k_htt *htt = &ar->htt;
175*4882a593Smuzhiyun 
176*4882a593Smuzhiyun 	htt->ar = ar;
177*4882a593Smuzhiyun 
178*4882a593Smuzhiyun 	/*
179*4882a593Smuzhiyun 	 * Prefetch enough data to satisfy target
180*4882a593Smuzhiyun 	 * classification engine.
181*4882a593Smuzhiyun 	 * This is for LL chips. HL chips will probably
182*4882a593Smuzhiyun 	 * transfer all frame in the tx fragment.
183*4882a593Smuzhiyun 	 */
184*4882a593Smuzhiyun 	htt->prefetch_len =
185*4882a593Smuzhiyun 		36 + /* 802.11 + qos + ht */
186*4882a593Smuzhiyun 		4 + /* 802.1q */
187*4882a593Smuzhiyun 		8 + /* llc snap */
188*4882a593Smuzhiyun 		2; /* ip4 dscp or ip6 priority */
189*4882a593Smuzhiyun 
190*4882a593Smuzhiyun 	switch (ar->running_fw->fw_file.htt_op_version) {
191*4882a593Smuzhiyun 	case ATH10K_FW_HTT_OP_VERSION_10_4:
192*4882a593Smuzhiyun 		ar->htt.t2h_msg_types = htt_10_4_t2h_msg_types;
193*4882a593Smuzhiyun 		ar->htt.t2h_msg_types_max = HTT_10_4_T2H_NUM_MSGS;
194*4882a593Smuzhiyun 		break;
195*4882a593Smuzhiyun 	case ATH10K_FW_HTT_OP_VERSION_10_1:
196*4882a593Smuzhiyun 		ar->htt.t2h_msg_types = htt_10x_t2h_msg_types;
197*4882a593Smuzhiyun 		ar->htt.t2h_msg_types_max = HTT_10X_T2H_NUM_MSGS;
198*4882a593Smuzhiyun 		break;
199*4882a593Smuzhiyun 	case ATH10K_FW_HTT_OP_VERSION_TLV:
200*4882a593Smuzhiyun 		ar->htt.t2h_msg_types = htt_tlv_t2h_msg_types;
201*4882a593Smuzhiyun 		ar->htt.t2h_msg_types_max = HTT_TLV_T2H_NUM_MSGS;
202*4882a593Smuzhiyun 		break;
203*4882a593Smuzhiyun 	case ATH10K_FW_HTT_OP_VERSION_MAIN:
204*4882a593Smuzhiyun 		ar->htt.t2h_msg_types = htt_main_t2h_msg_types;
205*4882a593Smuzhiyun 		ar->htt.t2h_msg_types_max = HTT_MAIN_T2H_NUM_MSGS;
206*4882a593Smuzhiyun 		break;
207*4882a593Smuzhiyun 	case ATH10K_FW_HTT_OP_VERSION_MAX:
208*4882a593Smuzhiyun 	case ATH10K_FW_HTT_OP_VERSION_UNSET:
209*4882a593Smuzhiyun 		WARN_ON(1);
210*4882a593Smuzhiyun 		return -EINVAL;
211*4882a593Smuzhiyun 	}
212*4882a593Smuzhiyun 	ath10k_htt_set_tx_ops(htt);
213*4882a593Smuzhiyun 	ath10k_htt_set_rx_ops(htt);
214*4882a593Smuzhiyun 
215*4882a593Smuzhiyun 	return 0;
216*4882a593Smuzhiyun }
217*4882a593Smuzhiyun 
218*4882a593Smuzhiyun #define HTT_TARGET_VERSION_TIMEOUT_HZ (3 * HZ)
219*4882a593Smuzhiyun 
ath10k_htt_verify_version(struct ath10k_htt * htt)220*4882a593Smuzhiyun static int ath10k_htt_verify_version(struct ath10k_htt *htt)
221*4882a593Smuzhiyun {
222*4882a593Smuzhiyun 	struct ath10k *ar = htt->ar;
223*4882a593Smuzhiyun 
224*4882a593Smuzhiyun 	ath10k_dbg(ar, ATH10K_DBG_BOOT, "htt target version %d.%d\n",
225*4882a593Smuzhiyun 		   htt->target_version_major, htt->target_version_minor);
226*4882a593Smuzhiyun 
227*4882a593Smuzhiyun 	if (htt->target_version_major != 2 &&
228*4882a593Smuzhiyun 	    htt->target_version_major != 3) {
229*4882a593Smuzhiyun 		ath10k_err(ar, "unsupported htt major version %d. supported versions are 2 and 3\n",
230*4882a593Smuzhiyun 			   htt->target_version_major);
231*4882a593Smuzhiyun 		return -ENOTSUPP;
232*4882a593Smuzhiyun 	}
233*4882a593Smuzhiyun 
234*4882a593Smuzhiyun 	return 0;
235*4882a593Smuzhiyun }
236*4882a593Smuzhiyun 
ath10k_htt_setup(struct ath10k_htt * htt)237*4882a593Smuzhiyun int ath10k_htt_setup(struct ath10k_htt *htt)
238*4882a593Smuzhiyun {
239*4882a593Smuzhiyun 	struct ath10k *ar = htt->ar;
240*4882a593Smuzhiyun 	int status;
241*4882a593Smuzhiyun 
242*4882a593Smuzhiyun 	init_completion(&htt->target_version_received);
243*4882a593Smuzhiyun 
244*4882a593Smuzhiyun 	status = ath10k_htt_h2t_ver_req_msg(htt);
245*4882a593Smuzhiyun 	if (status)
246*4882a593Smuzhiyun 		return status;
247*4882a593Smuzhiyun 
248*4882a593Smuzhiyun 	status = wait_for_completion_timeout(&htt->target_version_received,
249*4882a593Smuzhiyun 					     HTT_TARGET_VERSION_TIMEOUT_HZ);
250*4882a593Smuzhiyun 	if (status == 0) {
251*4882a593Smuzhiyun 		ath10k_warn(ar, "htt version request timed out\n");
252*4882a593Smuzhiyun 		return -ETIMEDOUT;
253*4882a593Smuzhiyun 	}
254*4882a593Smuzhiyun 
255*4882a593Smuzhiyun 	status = ath10k_htt_verify_version(htt);
256*4882a593Smuzhiyun 	if (status) {
257*4882a593Smuzhiyun 		ath10k_warn(ar, "failed to verify htt version: %d\n",
258*4882a593Smuzhiyun 			    status);
259*4882a593Smuzhiyun 		return status;
260*4882a593Smuzhiyun 	}
261*4882a593Smuzhiyun 
262*4882a593Smuzhiyun 	status = ath10k_htt_send_frag_desc_bank_cfg(htt);
263*4882a593Smuzhiyun 	if (status)
264*4882a593Smuzhiyun 		return status;
265*4882a593Smuzhiyun 
266*4882a593Smuzhiyun 	status = ath10k_htt_send_rx_ring_cfg(htt);
267*4882a593Smuzhiyun 	if (status) {
268*4882a593Smuzhiyun 		ath10k_warn(ar, "failed to setup rx ring: %d\n",
269*4882a593Smuzhiyun 			    status);
270*4882a593Smuzhiyun 		return status;
271*4882a593Smuzhiyun 	}
272*4882a593Smuzhiyun 
273*4882a593Smuzhiyun 	status = ath10k_htt_h2t_aggr_cfg_msg(htt,
274*4882a593Smuzhiyun 					     htt->max_num_ampdu,
275*4882a593Smuzhiyun 					     htt->max_num_amsdu);
276*4882a593Smuzhiyun 	if (status) {
277*4882a593Smuzhiyun 		ath10k_warn(ar, "failed to setup amsdu/ampdu limit: %d\n",
278*4882a593Smuzhiyun 			    status);
279*4882a593Smuzhiyun 		return status;
280*4882a593Smuzhiyun 	}
281*4882a593Smuzhiyun 
282*4882a593Smuzhiyun 	return 0;
283*4882a593Smuzhiyun }
284