Commit | Line | Data |
---|---|---|
5e3dd157 KV |
1 | /* |
2 | * Copyright (c) 2005-2011 Atheros Communications Inc. | |
3 | * Copyright (c) 2011-2013 Qualcomm Atheros, Inc. | |
4 | * | |
5 | * Permission to use, copy, modify, and/or distribute this software for any | |
6 | * purpose with or without fee is hereby granted, provided that the above | |
7 | * copyright notice and this permission notice appear in all copies. | |
8 | * | |
9 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | |
10 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | |
11 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | |
12 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | |
13 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | |
14 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | |
15 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | |
16 | */ | |
17 | ||
18 | #include <linux/slab.h> | |
edb8236d | 19 | #include <linux/if_ether.h> |
5e3dd157 KV |
20 | |
21 | #include "htt.h" | |
22 | #include "core.h" | |
23 | #include "debug.h" | |
24 | ||
8348db29 RM |
25 | static const enum htt_t2h_msg_type htt_main_t2h_msg_types[] = { |
26 | [HTT_MAIN_T2H_MSG_TYPE_VERSION_CONF] = HTT_T2H_MSG_TYPE_VERSION_CONF, | |
27 | [HTT_MAIN_T2H_MSG_TYPE_RX_IND] = HTT_T2H_MSG_TYPE_RX_IND, | |
28 | [HTT_MAIN_T2H_MSG_TYPE_RX_FLUSH] = HTT_T2H_MSG_TYPE_RX_FLUSH, | |
29 | [HTT_MAIN_T2H_MSG_TYPE_PEER_MAP] = HTT_T2H_MSG_TYPE_PEER_MAP, | |
30 | [HTT_MAIN_T2H_MSG_TYPE_PEER_UNMAP] = HTT_T2H_MSG_TYPE_PEER_UNMAP, | |
31 | [HTT_MAIN_T2H_MSG_TYPE_RX_ADDBA] = HTT_T2H_MSG_TYPE_RX_ADDBA, | |
32 | [HTT_MAIN_T2H_MSG_TYPE_RX_DELBA] = HTT_T2H_MSG_TYPE_RX_DELBA, | |
33 | [HTT_MAIN_T2H_MSG_TYPE_TX_COMPL_IND] = HTT_T2H_MSG_TYPE_TX_COMPL_IND, | |
34 | [HTT_MAIN_T2H_MSG_TYPE_PKTLOG] = HTT_T2H_MSG_TYPE_PKTLOG, | |
35 | [HTT_MAIN_T2H_MSG_TYPE_STATS_CONF] = HTT_T2H_MSG_TYPE_STATS_CONF, | |
36 | [HTT_MAIN_T2H_MSG_TYPE_RX_FRAG_IND] = HTT_T2H_MSG_TYPE_RX_FRAG_IND, | |
37 | [HTT_MAIN_T2H_MSG_TYPE_SEC_IND] = HTT_T2H_MSG_TYPE_SEC_IND, | |
38 | [HTT_MAIN_T2H_MSG_TYPE_TX_INSPECT_IND] = | |
39 | HTT_T2H_MSG_TYPE_TX_INSPECT_IND, | |
40 | [HTT_MAIN_T2H_MSG_TYPE_MGMT_TX_COMPL_IND] = | |
41 | HTT_T2H_MSG_TYPE_MGMT_TX_COMPLETION, | |
42 | [HTT_MAIN_T2H_MSG_TYPE_TX_CREDIT_UPDATE_IND] = | |
43 | HTT_T2H_MSG_TYPE_TX_CREDIT_UPDATE_IND, | |
44 | [HTT_MAIN_T2H_MSG_TYPE_RX_PN_IND] = HTT_T2H_MSG_TYPE_RX_PN_IND, | |
45 | [HTT_MAIN_T2H_MSG_TYPE_RX_OFFLOAD_DELIVER_IND] = | |
46 | HTT_T2H_MSG_TYPE_RX_OFFLOAD_DELIVER_IND, | |
47 | [HTT_MAIN_T2H_MSG_TYPE_TEST] = HTT_T2H_MSG_TYPE_TEST, | |
48 | }; | |
49 | ||
50 | static const enum htt_t2h_msg_type htt_10x_t2h_msg_types[] = { | |
51 | [HTT_10X_T2H_MSG_TYPE_VERSION_CONF] = HTT_T2H_MSG_TYPE_VERSION_CONF, | |
52 | [HTT_10X_T2H_MSG_TYPE_RX_IND] = HTT_T2H_MSG_TYPE_RX_IND, | |
53 | [HTT_10X_T2H_MSG_TYPE_RX_FLUSH] = HTT_T2H_MSG_TYPE_RX_FLUSH, | |
54 | [HTT_10X_T2H_MSG_TYPE_PEER_MAP] = HTT_T2H_MSG_TYPE_PEER_MAP, | |
55 | [HTT_10X_T2H_MSG_TYPE_PEER_UNMAP] = HTT_T2H_MSG_TYPE_PEER_UNMAP, | |
56 | [HTT_10X_T2H_MSG_TYPE_RX_ADDBA] = HTT_T2H_MSG_TYPE_RX_ADDBA, | |
57 | [HTT_10X_T2H_MSG_TYPE_RX_DELBA] = HTT_T2H_MSG_TYPE_RX_DELBA, | |
58 | [HTT_10X_T2H_MSG_TYPE_TX_COMPL_IND] = HTT_T2H_MSG_TYPE_TX_COMPL_IND, | |
59 | [HTT_10X_T2H_MSG_TYPE_PKTLOG] = HTT_T2H_MSG_TYPE_PKTLOG, | |
60 | [HTT_10X_T2H_MSG_TYPE_STATS_CONF] = HTT_T2H_MSG_TYPE_STATS_CONF, | |
61 | [HTT_10X_T2H_MSG_TYPE_RX_FRAG_IND] = HTT_T2H_MSG_TYPE_RX_FRAG_IND, | |
62 | [HTT_10X_T2H_MSG_TYPE_SEC_IND] = HTT_T2H_MSG_TYPE_SEC_IND, | |
63 | [HTT_10X_T2H_MSG_TYPE_RC_UPDATE_IND] = HTT_T2H_MSG_TYPE_RC_UPDATE_IND, | |
64 | [HTT_10X_T2H_MSG_TYPE_TX_INSPECT_IND] = HTT_T2H_MSG_TYPE_TX_INSPECT_IND, | |
65 | [HTT_10X_T2H_MSG_TYPE_TEST] = HTT_T2H_MSG_TYPE_TEST, | |
66 | [HTT_10X_T2H_MSG_TYPE_CHAN_CHANGE] = HTT_T2H_MSG_TYPE_CHAN_CHANGE, | |
67 | [HTT_10X_T2H_MSG_TYPE_AGGR_CONF] = HTT_T2H_MSG_TYPE_AGGR_CONF, | |
68 | [HTT_10X_T2H_MSG_TYPE_STATS_NOUPLOAD] = HTT_T2H_MSG_TYPE_STATS_NOUPLOAD, | |
69 | [HTT_10X_T2H_MSG_TYPE_MGMT_TX_COMPL_IND] = | |
70 | HTT_T2H_MSG_TYPE_MGMT_TX_COMPLETION, | |
71 | }; | |
72 | ||
73 | static const enum htt_t2h_msg_type htt_tlv_t2h_msg_types[] = { | |
74 | [HTT_TLV_T2H_MSG_TYPE_VERSION_CONF] = HTT_T2H_MSG_TYPE_VERSION_CONF, | |
75 | [HTT_TLV_T2H_MSG_TYPE_RX_IND] = HTT_T2H_MSG_TYPE_RX_IND, | |
76 | [HTT_TLV_T2H_MSG_TYPE_RX_FLUSH] = HTT_T2H_MSG_TYPE_RX_FLUSH, | |
77 | [HTT_TLV_T2H_MSG_TYPE_PEER_MAP] = HTT_T2H_MSG_TYPE_PEER_MAP, | |
78 | [HTT_TLV_T2H_MSG_TYPE_PEER_UNMAP] = HTT_T2H_MSG_TYPE_PEER_UNMAP, | |
79 | [HTT_TLV_T2H_MSG_TYPE_RX_ADDBA] = HTT_T2H_MSG_TYPE_RX_ADDBA, | |
80 | [HTT_TLV_T2H_MSG_TYPE_RX_DELBA] = HTT_T2H_MSG_TYPE_RX_DELBA, | |
81 | [HTT_TLV_T2H_MSG_TYPE_TX_COMPL_IND] = HTT_T2H_MSG_TYPE_TX_COMPL_IND, | |
82 | [HTT_TLV_T2H_MSG_TYPE_PKTLOG] = HTT_T2H_MSG_TYPE_PKTLOG, | |
83 | [HTT_TLV_T2H_MSG_TYPE_STATS_CONF] = HTT_T2H_MSG_TYPE_STATS_CONF, | |
84 | [HTT_TLV_T2H_MSG_TYPE_RX_FRAG_IND] = HTT_T2H_MSG_TYPE_RX_FRAG_IND, | |
85 | [HTT_TLV_T2H_MSG_TYPE_SEC_IND] = HTT_T2H_MSG_TYPE_SEC_IND, | |
86 | [HTT_TLV_T2H_MSG_TYPE_RC_UPDATE_IND] = HTT_T2H_MSG_TYPE_RC_UPDATE_IND, | |
87 | [HTT_TLV_T2H_MSG_TYPE_TX_INSPECT_IND] = HTT_T2H_MSG_TYPE_TX_INSPECT_IND, | |
88 | [HTT_TLV_T2H_MSG_TYPE_MGMT_TX_COMPL_IND] = | |
89 | HTT_T2H_MSG_TYPE_MGMT_TX_COMPLETION, | |
90 | [HTT_TLV_T2H_MSG_TYPE_TX_CREDIT_UPDATE_IND] = | |
91 | HTT_T2H_MSG_TYPE_TX_CREDIT_UPDATE_IND, | |
92 | [HTT_TLV_T2H_MSG_TYPE_RX_PN_IND] = HTT_T2H_MSG_TYPE_RX_PN_IND, | |
93 | [HTT_TLV_T2H_MSG_TYPE_RX_OFFLOAD_DELIVER_IND] = | |
94 | HTT_T2H_MSG_TYPE_RX_OFFLOAD_DELIVER_IND, | |
95 | [HTT_TLV_T2H_MSG_TYPE_RX_IN_ORD_PADDR_IND] = | |
96 | HTT_T2H_MSG_TYPE_RX_IN_ORD_PADDR_IND, | |
97 | [HTT_TLV_T2H_MSG_TYPE_WDI_IPA_OP_RESPONSE] = | |
98 | HTT_T2H_MSG_TYPE_WDI_IPA_OP_RESPONSE, | |
99 | [HTT_TLV_T2H_MSG_TYPE_CHAN_CHANGE] = HTT_T2H_MSG_TYPE_CHAN_CHANGE, | |
100 | [HTT_TLV_T2H_MSG_TYPE_RX_OFLD_PKT_ERR] = | |
101 | HTT_T2H_MSG_TYPE_RX_OFLD_PKT_ERR, | |
102 | [HTT_TLV_T2H_MSG_TYPE_TEST] = HTT_T2H_MSG_TYPE_TEST, | |
103 | }; | |
104 | ||
721ad3ca RM |
105 | static const enum htt_t2h_msg_type htt_10_4_t2h_msg_types[] = { |
106 | [HTT_10_4_T2H_MSG_TYPE_VERSION_CONF] = HTT_T2H_MSG_TYPE_VERSION_CONF, | |
107 | [HTT_10_4_T2H_MSG_TYPE_RX_IND] = HTT_T2H_MSG_TYPE_RX_IND, | |
108 | [HTT_10_4_T2H_MSG_TYPE_RX_FLUSH] = HTT_T2H_MSG_TYPE_RX_FLUSH, | |
109 | [HTT_10_4_T2H_MSG_TYPE_PEER_MAP] = HTT_T2H_MSG_TYPE_PEER_MAP, | |
110 | [HTT_10_4_T2H_MSG_TYPE_PEER_UNMAP] = HTT_T2H_MSG_TYPE_PEER_UNMAP, | |
111 | [HTT_10_4_T2H_MSG_TYPE_RX_ADDBA] = HTT_T2H_MSG_TYPE_RX_ADDBA, | |
112 | [HTT_10_4_T2H_MSG_TYPE_RX_DELBA] = HTT_T2H_MSG_TYPE_RX_DELBA, | |
113 | [HTT_10_4_T2H_MSG_TYPE_TX_COMPL_IND] = HTT_T2H_MSG_TYPE_TX_COMPL_IND, | |
114 | [HTT_10_4_T2H_MSG_TYPE_PKTLOG] = HTT_T2H_MSG_TYPE_PKTLOG, | |
115 | [HTT_10_4_T2H_MSG_TYPE_STATS_CONF] = HTT_T2H_MSG_TYPE_STATS_CONF, | |
116 | [HTT_10_4_T2H_MSG_TYPE_RX_FRAG_IND] = HTT_T2H_MSG_TYPE_RX_FRAG_IND, | |
117 | [HTT_10_4_T2H_MSG_TYPE_SEC_IND] = HTT_T2H_MSG_TYPE_SEC_IND, | |
118 | [HTT_10_4_T2H_MSG_TYPE_RC_UPDATE_IND] = HTT_T2H_MSG_TYPE_RC_UPDATE_IND, | |
119 | [HTT_10_4_T2H_MSG_TYPE_TX_INSPECT_IND] = | |
120 | HTT_T2H_MSG_TYPE_TX_INSPECT_IND, | |
121 | [HTT_10_4_T2H_MSG_TYPE_MGMT_TX_COMPL_IND] = | |
122 | HTT_T2H_MSG_TYPE_MGMT_TX_COMPLETION, | |
123 | [HTT_10_4_T2H_MSG_TYPE_CHAN_CHANGE] = HTT_T2H_MSG_TYPE_CHAN_CHANGE, | |
124 | [HTT_10_4_T2H_MSG_TYPE_TX_CREDIT_UPDATE_IND] = | |
125 | HTT_T2H_MSG_TYPE_TX_CREDIT_UPDATE_IND, | |
126 | [HTT_10_4_T2H_MSG_TYPE_RX_PN_IND] = HTT_T2H_MSG_TYPE_RX_PN_IND, | |
127 | [HTT_10_4_T2H_MSG_TYPE_RX_OFFLOAD_DELIVER_IND] = | |
128 | HTT_T2H_MSG_TYPE_RX_OFFLOAD_DELIVER_IND, | |
129 | [HTT_10_4_T2H_MSG_TYPE_TEST] = HTT_T2H_MSG_TYPE_TEST, | |
130 | [HTT_10_4_T2H_MSG_TYPE_EN_STATS] = HTT_T2H_MSG_TYPE_EN_STATS, | |
131 | [HTT_10_4_T2H_MSG_TYPE_AGGR_CONF] = HTT_T2H_MSG_TYPE_AGGR_CONF, | |
132 | [HTT_10_4_T2H_MSG_TYPE_TX_FETCH_IND] = | |
133 | HTT_T2H_MSG_TYPE_TX_FETCH_IND, | |
df94e702 MK |
134 | [HTT_10_4_T2H_MSG_TYPE_TX_FETCH_CONFIRM] = |
135 | HTT_T2H_MSG_TYPE_TX_FETCH_CONFIRM, | |
721ad3ca RM |
136 | [HTT_10_4_T2H_MSG_TYPE_STATS_NOUPLOAD] = |
137 | HTT_T2H_MSG_TYPE_STATS_NOUPLOAD, | |
df94e702 MK |
138 | [HTT_10_4_T2H_MSG_TYPE_TX_MODE_SWITCH_IND] = |
139 | HTT_T2H_MSG_TYPE_TX_MODE_SWITCH_IND, | |
721ad3ca RM |
140 | }; |
141 | ||
95bf21f9 | 142 | int ath10k_htt_connect(struct ath10k_htt *htt) |
5e3dd157 KV |
143 | { |
144 | struct ath10k_htc_svc_conn_req conn_req; | |
145 | struct ath10k_htc_svc_conn_resp conn_resp; | |
146 | int status; | |
147 | ||
148 | memset(&conn_req, 0, sizeof(conn_req)); | |
149 | memset(&conn_resp, 0, sizeof(conn_resp)); | |
150 | ||
151 | conn_req.ep_ops.ep_tx_complete = ath10k_htt_htc_tx_complete; | |
e3a91f87 | 152 | conn_req.ep_ops.ep_rx_complete = ath10k_htt_htc_t2h_msg_handler; |
5e3dd157 KV |
153 | |
154 | /* connect to control service */ | |
155 | conn_req.service_id = ATH10K_HTC_SVC_ID_HTT_DATA_MSG; | |
156 | ||
cd003fad | 157 | status = ath10k_htc_connect_service(&htt->ar->htc, &conn_req, |
5e3dd157 KV |
158 | &conn_resp); |
159 | ||
160 | if (status) | |
161 | return status; | |
162 | ||
163 | htt->eid = conn_resp.eid; | |
164 | ||
165 | return 0; | |
166 | } | |
167 | ||
95bf21f9 | 168 | int ath10k_htt_init(struct ath10k *ar) |
5e3dd157 | 169 | { |
edb8236d | 170 | struct ath10k_htt *htt = &ar->htt; |
5e3dd157 | 171 | |
5e3dd157 | 172 | htt->ar = ar; |
5e3dd157 | 173 | |
5e3dd157 KV |
174 | /* |
175 | * Prefetch enough data to satisfy target | |
176 | * classification engine. | |
177 | * This is for LL chips. HL chips will probably | |
178 | * transfer all frame in the tx fragment. | |
179 | */ | |
180 | htt->prefetch_len = | |
181 | 36 + /* 802.11 + qos + ht */ | |
182 | 4 + /* 802.1q */ | |
183 | 8 + /* llc snap */ | |
184 | 2; /* ip4 dscp or ip6 priority */ | |
185 | ||
77561f93 | 186 | switch (ar->running_fw->fw_file.htt_op_version) { |
721ad3ca RM |
187 | case ATH10K_FW_HTT_OP_VERSION_10_4: |
188 | ar->htt.t2h_msg_types = htt_10_4_t2h_msg_types; | |
189 | ar->htt.t2h_msg_types_max = HTT_10_4_T2H_NUM_MSGS; | |
190 | break; | |
8348db29 RM |
191 | case ATH10K_FW_HTT_OP_VERSION_10_1: |
192 | ar->htt.t2h_msg_types = htt_10x_t2h_msg_types; | |
193 | ar->htt.t2h_msg_types_max = HTT_10X_T2H_NUM_MSGS; | |
194 | break; | |
195 | case ATH10K_FW_HTT_OP_VERSION_TLV: | |
196 | ar->htt.t2h_msg_types = htt_tlv_t2h_msg_types; | |
197 | ar->htt.t2h_msg_types_max = HTT_TLV_T2H_NUM_MSGS; | |
198 | break; | |
199 | case ATH10K_FW_HTT_OP_VERSION_MAIN: | |
8348db29 RM |
200 | ar->htt.t2h_msg_types = htt_main_t2h_msg_types; |
201 | ar->htt.t2h_msg_types_max = HTT_MAIN_T2H_NUM_MSGS; | |
202 | break; | |
203 | case ATH10K_FW_HTT_OP_VERSION_MAX: | |
dc3632a1 | 204 | case ATH10K_FW_HTT_OP_VERSION_UNSET: |
8348db29 RM |
205 | WARN_ON(1); |
206 | return -EINVAL; | |
207 | } | |
edb8236d | 208 | return 0; |
5e3dd157 KV |
209 | } |
210 | ||
14e105cd | 211 | #define HTT_TARGET_VERSION_TIMEOUT_HZ (3 * HZ) |
5e3dd157 KV |
212 | |
213 | static int ath10k_htt_verify_version(struct ath10k_htt *htt) | |
214 | { | |
7aa7a72a MK |
215 | struct ath10k *ar = htt->ar; |
216 | ||
217 | ath10k_dbg(ar, ATH10K_DBG_BOOT, "htt target version %d.%d\n", | |
c8c39afe | 218 | htt->target_version_major, htt->target_version_minor); |
961d4c38 MK |
219 | |
220 | if (htt->target_version_major != 2 && | |
221 | htt->target_version_major != 3) { | |
7aa7a72a | 222 | ath10k_err(ar, "unsupported htt major version %d. supported versions are 2 and 3\n", |
961d4c38 | 223 | htt->target_version_major); |
5e3dd157 KV |
224 | return -ENOTSUPP; |
225 | } | |
226 | ||
5e3dd157 KV |
227 | return 0; |
228 | } | |
229 | ||
95bf21f9 | 230 | int ath10k_htt_setup(struct ath10k_htt *htt) |
5e3dd157 | 231 | { |
7aa7a72a | 232 | struct ath10k *ar = htt->ar; |
5e3dd157 KV |
233 | int status; |
234 | ||
235 | init_completion(&htt->target_version_received); | |
236 | ||
237 | status = ath10k_htt_h2t_ver_req_msg(htt); | |
238 | if (status) | |
239 | return status; | |
240 | ||
241 | status = wait_for_completion_timeout(&htt->target_version_received, | |
5b07e07f | 242 | HTT_TARGET_VERSION_TIMEOUT_HZ); |
38e2a644 | 243 | if (status == 0) { |
7aa7a72a | 244 | ath10k_warn(ar, "htt version request timed out\n"); |
5e3dd157 KV |
245 | return -ETIMEDOUT; |
246 | } | |
247 | ||
248 | status = ath10k_htt_verify_version(htt); | |
ccec9038 DL |
249 | if (status) { |
250 | ath10k_warn(ar, "failed to verify htt version: %d\n", | |
251 | status); | |
5e3dd157 | 252 | return status; |
ccec9038 | 253 | } |
5e3dd157 | 254 | |
d9156b5f RM |
255 | status = ath10k_htt_send_frag_desc_bank_cfg(htt); |
256 | if (status) | |
257 | return status; | |
258 | ||
ccec9038 DL |
259 | status = ath10k_htt_send_rx_ring_cfg_ll(htt); |
260 | if (status) { | |
261 | ath10k_warn(ar, "failed to setup rx ring: %d\n", | |
262 | status); | |
263 | return status; | |
264 | } | |
265 | ||
266 | status = ath10k_htt_h2t_aggr_cfg_msg(htt, | |
267 | htt->max_num_ampdu, | |
268 | htt->max_num_amsdu); | |
269 | if (status) { | |
270 | ath10k_warn(ar, "failed to setup amsdu/ampdu limit: %d\n", | |
271 | status); | |
272 | return status; | |
273 | } | |
274 | ||
275 | return 0; | |
5e3dd157 | 276 | } |