2 * Copyright (c) 2010-2011 Atheros Communications Inc.
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
21 static int htc_issue_send(struct htc_target
*target
, struct sk_buff
* skb
,
22 u16 len
, u8 flags
, u8 epid
)
25 struct htc_frame_hdr
*hdr
;
26 struct htc_endpoint
*endpoint
= &target
->endpoint
[epid
];
29 hdr
= skb_push(skb
, sizeof(struct htc_frame_hdr
));
30 hdr
->endpoint_id
= epid
;
32 hdr
->payload_len
= cpu_to_be16(len
);
33 memset(hdr
->control
, 0, sizeof(hdr
->control
));
35 status
= target
->hif
->send(target
->hif_dev
, endpoint
->ul_pipeid
, skb
);
40 static struct htc_endpoint
*get_next_avail_ep(struct htc_endpoint
*endpoint
)
42 enum htc_endpoint_id avail_epid
;
44 for (avail_epid
= (ENDPOINT_MAX
- 1); avail_epid
> ENDPOINT0
; avail_epid
--)
45 if (endpoint
[avail_epid
].service_id
== 0)
46 return &endpoint
[avail_epid
];
50 static u8
service_to_ulpipe(u16 service_id
)
69 static u8
service_to_dlpipe(u16 service_id
)
88 static void htc_process_target_rdy(struct htc_target
*target
,
91 struct htc_endpoint
*endpoint
;
92 struct htc_ready_msg
*htc_ready_msg
= buf
;
94 target
->credit_size
= be16_to_cpu(htc_ready_msg
->credit_size
);
96 endpoint
= &target
->endpoint
[ENDPOINT0
];
97 endpoint
->service_id
= HTC_CTRL_RSVD_SVC
;
98 endpoint
->max_msglen
= HTC_MAX_CONTROL_MESSAGE_LENGTH
;
99 atomic_inc(&target
->tgt_ready
);
100 complete(&target
->target_wait
);
103 static void htc_process_conn_rsp(struct htc_target
*target
,
104 struct htc_frame_hdr
*htc_hdr
)
106 struct htc_conn_svc_rspmsg
*svc_rspmsg
;
107 struct htc_endpoint
*endpoint
, *tmp_endpoint
= NULL
;
110 enum htc_endpoint_id epid
, tepid
;
112 svc_rspmsg
= (struct htc_conn_svc_rspmsg
*)
113 ((void *) htc_hdr
+ sizeof(struct htc_frame_hdr
));
115 if (svc_rspmsg
->status
== HTC_SERVICE_SUCCESS
) {
116 epid
= svc_rspmsg
->endpoint_id
;
118 /* Check that the received epid for the endpoint to attach
119 * a new service is valid. ENDPOINT0 can't be used here as it
120 * is already reserved for HTC_CTRL_RSVD_SVC service and thus
121 * should not be modified.
123 if (epid
<= ENDPOINT0
|| epid
>= ENDPOINT_MAX
)
126 service_id
= be16_to_cpu(svc_rspmsg
->service_id
);
127 max_msglen
= be16_to_cpu(svc_rspmsg
->max_msg_len
);
128 endpoint
= &target
->endpoint
[epid
];
130 for (tepid
= (ENDPOINT_MAX
- 1); tepid
> ENDPOINT0
; tepid
--) {
131 tmp_endpoint
= &target
->endpoint
[tepid
];
132 if (tmp_endpoint
->service_id
== service_id
) {
133 tmp_endpoint
->service_id
= 0;
138 if (tepid
== ENDPOINT0
)
141 endpoint
->service_id
= service_id
;
142 endpoint
->max_txqdepth
= tmp_endpoint
->max_txqdepth
;
143 endpoint
->ep_callbacks
= tmp_endpoint
->ep_callbacks
;
144 endpoint
->ul_pipeid
= tmp_endpoint
->ul_pipeid
;
145 endpoint
->dl_pipeid
= tmp_endpoint
->dl_pipeid
;
146 endpoint
->max_msglen
= max_msglen
;
147 target
->conn_rsp_epid
= epid
;
148 complete(&target
->cmd_wait
);
150 target
->conn_rsp_epid
= ENDPOINT_UNUSED
;
154 static int htc_config_pipe_credits(struct htc_target
*target
)
157 struct htc_config_pipe_msg
*cp_msg
;
159 unsigned long time_left
;
161 skb
= alloc_skb(50 + sizeof(struct htc_frame_hdr
), GFP_ATOMIC
);
163 dev_err(target
->dev
, "failed to allocate send buffer\n");
166 skb_reserve(skb
, sizeof(struct htc_frame_hdr
));
168 cp_msg
= skb_put(skb
, sizeof(struct htc_config_pipe_msg
));
170 cp_msg
->message_id
= cpu_to_be16(HTC_MSG_CONFIG_PIPE_ID
);
171 cp_msg
->pipe_id
= USB_WLAN_TX_PIPE
;
172 cp_msg
->credits
= target
->credits
;
174 target
->htc_flags
|= HTC_OP_CONFIG_PIPE_CREDITS
;
176 ret
= htc_issue_send(target
, skb
, skb
->len
, 0, ENDPOINT0
);
180 time_left
= wait_for_completion_timeout(&target
->cmd_wait
, HZ
);
182 dev_err(target
->dev
, "HTC credit config timeout\n");
192 static int htc_setup_complete(struct htc_target
*target
)
195 struct htc_comp_msg
*comp_msg
;
197 unsigned long time_left
;
199 skb
= alloc_skb(50 + sizeof(struct htc_frame_hdr
), GFP_ATOMIC
);
201 dev_err(target
->dev
, "failed to allocate send buffer\n");
204 skb_reserve(skb
, sizeof(struct htc_frame_hdr
));
206 comp_msg
= skb_put(skb
, sizeof(struct htc_comp_msg
));
207 comp_msg
->msg_id
= cpu_to_be16(HTC_MSG_SETUP_COMPLETE_ID
);
209 target
->htc_flags
|= HTC_OP_START_WAIT
;
211 ret
= htc_issue_send(target
, skb
, skb
->len
, 0, ENDPOINT0
);
215 time_left
= wait_for_completion_timeout(&target
->cmd_wait
, HZ
);
217 dev_err(target
->dev
, "HTC start timeout\n");
230 int htc_init(struct htc_target
*target
)
234 ret
= htc_config_pipe_credits(target
);
238 return htc_setup_complete(target
);
241 int htc_connect_service(struct htc_target
*target
,
242 struct htc_service_connreq
*service_connreq
,
243 enum htc_endpoint_id
*conn_rsp_epid
)
246 struct htc_endpoint
*endpoint
;
247 struct htc_conn_svc_msg
*conn_msg
;
249 unsigned long time_left
;
251 /* Find an available endpoint */
252 endpoint
= get_next_avail_ep(target
->endpoint
);
254 dev_err(target
->dev
, "Endpoint is not available for service %d\n",
255 service_connreq
->service_id
);
259 endpoint
->service_id
= service_connreq
->service_id
;
260 endpoint
->max_txqdepth
= service_connreq
->max_send_qdepth
;
261 endpoint
->ul_pipeid
= service_to_ulpipe(service_connreq
->service_id
);
262 endpoint
->dl_pipeid
= service_to_dlpipe(service_connreq
->service_id
);
263 endpoint
->ep_callbacks
= service_connreq
->ep_callbacks
;
265 skb
= alloc_skb(sizeof(struct htc_conn_svc_msg
) +
266 sizeof(struct htc_frame_hdr
), GFP_ATOMIC
);
268 dev_err(target
->dev
, "Failed to allocate buf to send"
269 "service connect req\n");
273 skb_reserve(skb
, sizeof(struct htc_frame_hdr
));
275 conn_msg
= skb_put(skb
, sizeof(struct htc_conn_svc_msg
));
276 conn_msg
->service_id
= cpu_to_be16(service_connreq
->service_id
);
277 conn_msg
->msg_id
= cpu_to_be16(HTC_MSG_CONNECT_SERVICE_ID
);
278 conn_msg
->con_flags
= cpu_to_be16(service_connreq
->con_flags
);
279 conn_msg
->dl_pipeid
= endpoint
->dl_pipeid
;
280 conn_msg
->ul_pipeid
= endpoint
->ul_pipeid
;
282 /* To prevent infoleak */
283 conn_msg
->svc_meta_len
= 0;
286 ret
= htc_issue_send(target
, skb
, skb
->len
, 0, ENDPOINT0
);
290 time_left
= wait_for_completion_timeout(&target
->cmd_wait
, HZ
);
292 dev_err(target
->dev
, "Service connection timeout for: %d\n",
293 service_connreq
->service_id
);
297 if (target
->conn_rsp_epid
< 0 || target
->conn_rsp_epid
>= ENDPOINT_MAX
)
300 *conn_rsp_epid
= target
->conn_rsp_epid
;
307 int htc_send(struct htc_target
*target
, struct sk_buff
*skb
)
309 struct ath9k_htc_tx_ctl
*tx_ctl
;
311 tx_ctl
= HTC_SKB_CB(skb
);
312 return htc_issue_send(target
, skb
, skb
->len
, 0, tx_ctl
->epid
);
315 int htc_send_epid(struct htc_target
*target
, struct sk_buff
*skb
,
316 enum htc_endpoint_id epid
)
318 return htc_issue_send(target
, skb
, skb
->len
, 0, epid
);
321 void htc_stop(struct htc_target
*target
)
323 target
->hif
->stop(target
->hif_dev
);
326 void htc_start(struct htc_target
*target
)
328 target
->hif
->start(target
->hif_dev
);
331 void htc_sta_drain(struct htc_target
*target
, u8 idx
)
333 target
->hif
->sta_drain(target
->hif_dev
, idx
);
336 void ath9k_htc_txcompletion_cb(struct htc_target
*htc_handle
,
337 struct sk_buff
*skb
, bool txok
)
339 struct htc_endpoint
*endpoint
;
340 struct htc_frame_hdr
*htc_hdr
= NULL
;
342 if (htc_handle
->htc_flags
& HTC_OP_CONFIG_PIPE_CREDITS
) {
343 complete(&htc_handle
->cmd_wait
);
344 htc_handle
->htc_flags
&= ~HTC_OP_CONFIG_PIPE_CREDITS
;
348 if (htc_handle
->htc_flags
& HTC_OP_START_WAIT
) {
349 complete(&htc_handle
->cmd_wait
);
350 htc_handle
->htc_flags
&= ~HTC_OP_START_WAIT
;
355 htc_hdr
= (struct htc_frame_hdr
*) skb
->data
;
356 if (htc_hdr
->endpoint_id
>= ARRAY_SIZE(htc_handle
->endpoint
))
358 endpoint
= &htc_handle
->endpoint
[htc_hdr
->endpoint_id
];
359 skb_pull(skb
, sizeof(struct htc_frame_hdr
));
361 if (endpoint
->ep_callbacks
.tx
) {
362 endpoint
->ep_callbacks
.tx(endpoint
->ep_callbacks
.priv
,
363 skb
, htc_hdr
->endpoint_id
,
375 static void ath9k_htc_fw_panic_report(struct htc_target
*htc_handle
,
376 struct sk_buff
*skb
, u32 len
)
378 uint32_t *pattern
= (uint32_t *)skb
->data
;
380 if (*pattern
== 0x33221199 && len
>= sizeof(struct htc_panic_bad_vaddr
)) {
381 struct htc_panic_bad_vaddr
*htc_panic
;
382 htc_panic
= (struct htc_panic_bad_vaddr
*) skb
->data
;
383 dev_err(htc_handle
->dev
, "ath: firmware panic! "
384 "exccause: 0x%08x; pc: 0x%08x; badvaddr: 0x%08x.\n",
385 htc_panic
->exccause
, htc_panic
->pc
,
386 htc_panic
->badvaddr
);
389 if (*pattern
== 0x33221299) {
390 struct htc_panic_bad_epid
*htc_panic
;
391 htc_panic
= (struct htc_panic_bad_epid
*) skb
->data
;
392 dev_err(htc_handle
->dev
, "ath: firmware panic! "
393 "bad epid: 0x%08x\n", htc_panic
->epid
);
396 dev_err(htc_handle
->dev
, "ath: unknown panic pattern!\n");
400 * HTC Messages are handled directly here and the obtained SKB
403 * Service messages (Data, WMI) are passed to the corresponding
404 * endpoint RX handlers, which have to free the SKB.
406 void ath9k_htc_rx_msg(struct htc_target
*htc_handle
,
407 struct sk_buff
*skb
, u32 len
, u8 pipe_id
)
409 struct htc_frame_hdr
*htc_hdr
;
410 enum htc_endpoint_id epid
;
411 struct htc_endpoint
*endpoint
;
414 if (!htc_handle
|| !skb
)
417 /* A valid message requires len >= 8.
419 * sizeof(struct htc_frame_hdr) == 8
420 * sizeof(struct htc_ready_msg) == 8
421 * sizeof(struct htc_panic_bad_vaddr) == 16
422 * sizeof(struct htc_panic_bad_epid) == 8
424 if (unlikely(len
< sizeof(struct htc_frame_hdr
)))
426 htc_hdr
= (struct htc_frame_hdr
*) skb
->data
;
427 epid
= htc_hdr
->endpoint_id
;
430 ath9k_htc_fw_panic_report(htc_handle
, skb
, len
);
435 if (epid
< 0 || epid
>= ENDPOINT_MAX
) {
437 if (pipe_id
!= USB_REG_IN_PIPE
)
438 dev_kfree_skb_any(skb
);
444 if (epid
== ENDPOINT0
) {
447 if (htc_hdr
->flags
& HTC_FLAGS_RECV_TRAILER
) {
448 if (be32_to_cpu(*(__be32
*) skb
->data
) == 0x00C60000) {
449 /* Move past the Watchdog pattern */
450 htc_hdr
= (struct htc_frame_hdr
*)(skb
->data
+ 4);
455 /* Get the message ID */
456 if (unlikely(len
< sizeof(struct htc_frame_hdr
) + sizeof(__be16
)))
458 msg_id
= (__be16
*) ((void *) htc_hdr
+
459 sizeof(struct htc_frame_hdr
));
461 /* Now process HTC messages */
462 switch (be16_to_cpu(*msg_id
)) {
463 case HTC_MSG_READY_ID
:
464 if (unlikely(len
< sizeof(struct htc_ready_msg
)))
466 htc_process_target_rdy(htc_handle
, htc_hdr
);
468 case HTC_MSG_CONNECT_SERVICE_RESPONSE_ID
:
469 if (unlikely(len
< sizeof(struct htc_frame_hdr
) +
470 sizeof(struct htc_conn_svc_rspmsg
)))
472 htc_process_conn_rsp(htc_handle
, htc_hdr
);
481 if (htc_hdr
->flags
& HTC_FLAGS_RECV_TRAILER
)
482 skb_trim(skb
, len
- htc_hdr
->control
[0]);
484 skb_pull(skb
, sizeof(struct htc_frame_hdr
));
486 endpoint
= &htc_handle
->endpoint
[epid
];
487 if (endpoint
->ep_callbacks
.rx
)
488 endpoint
->ep_callbacks
.rx(endpoint
->ep_callbacks
.priv
,
495 struct htc_target
*ath9k_htc_hw_alloc(void *hif_handle
,
496 struct ath9k_htc_hif
*hif
,
499 struct htc_endpoint
*endpoint
;
500 struct htc_target
*target
;
502 target
= kzalloc(sizeof(struct htc_target
), GFP_KERNEL
);
506 init_completion(&target
->target_wait
);
507 init_completion(&target
->cmd_wait
);
510 target
->hif_dev
= hif_handle
;
513 /* Assign control endpoint pipe IDs */
514 endpoint
= &target
->endpoint
[ENDPOINT0
];
515 endpoint
->ul_pipeid
= hif
->control_ul_pipe
;
516 endpoint
->dl_pipeid
= hif
->control_dl_pipe
;
518 atomic_set(&target
->tgt_ready
, 0);
523 void ath9k_htc_hw_free(struct htc_target
*htc
)
528 int ath9k_htc_hw_init(struct htc_target
*target
,
529 struct device
*dev
, u16 devid
,
530 char *product
, u32 drv_info
)
532 if (ath9k_htc_probe_device(target
, dev
, devid
, product
, drv_info
)) {
533 pr_err("Failed to initialize the device\n");
540 void ath9k_htc_hw_deinit(struct htc_target
*target
, bool hot_unplug
)
543 ath9k_htc_disconnect_device(target
, hot_unplug
);