0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
0018
0019 #include "htc.h"
0020
0021 static int htc_issue_send(struct htc_target *target, struct sk_buff* skb,
0022 u16 len, u8 flags, u8 epid)
0023
0024 {
0025 struct htc_frame_hdr *hdr;
0026 struct htc_endpoint *endpoint = &target->endpoint[epid];
0027 int status;
0028
0029 hdr = skb_push(skb, sizeof(struct htc_frame_hdr));
0030 hdr->endpoint_id = epid;
0031 hdr->flags = flags;
0032 hdr->payload_len = cpu_to_be16(len);
0033 memset(hdr->control, 0, sizeof(hdr->control));
0034
0035 status = target->hif->send(target->hif_dev, endpoint->ul_pipeid, skb);
0036
0037 return status;
0038 }
0039
0040 static struct htc_endpoint *get_next_avail_ep(struct htc_endpoint *endpoint)
0041 {
0042 enum htc_endpoint_id avail_epid;
0043
0044 for (avail_epid = (ENDPOINT_MAX - 1); avail_epid > ENDPOINT0; avail_epid--)
0045 if (endpoint[avail_epid].service_id == 0)
0046 return &endpoint[avail_epid];
0047 return NULL;
0048 }
0049
0050 static u8 service_to_ulpipe(u16 service_id)
0051 {
0052 switch (service_id) {
0053 case WMI_CONTROL_SVC:
0054 return 4;
0055 case WMI_BEACON_SVC:
0056 case WMI_CAB_SVC:
0057 case WMI_UAPSD_SVC:
0058 case WMI_MGMT_SVC:
0059 case WMI_DATA_VO_SVC:
0060 case WMI_DATA_VI_SVC:
0061 case WMI_DATA_BE_SVC:
0062 case WMI_DATA_BK_SVC:
0063 return 1;
0064 default:
0065 return 0;
0066 }
0067 }
0068
0069 static u8 service_to_dlpipe(u16 service_id)
0070 {
0071 switch (service_id) {
0072 case WMI_CONTROL_SVC:
0073 return 3;
0074 case WMI_BEACON_SVC:
0075 case WMI_CAB_SVC:
0076 case WMI_UAPSD_SVC:
0077 case WMI_MGMT_SVC:
0078 case WMI_DATA_VO_SVC:
0079 case WMI_DATA_VI_SVC:
0080 case WMI_DATA_BE_SVC:
0081 case WMI_DATA_BK_SVC:
0082 return 2;
0083 default:
0084 return 0;
0085 }
0086 }
0087
0088 static void htc_process_target_rdy(struct htc_target *target,
0089 void *buf)
0090 {
0091 struct htc_endpoint *endpoint;
0092 struct htc_ready_msg *htc_ready_msg = (struct htc_ready_msg *) buf;
0093
0094 target->credit_size = be16_to_cpu(htc_ready_msg->credit_size);
0095
0096 endpoint = &target->endpoint[ENDPOINT0];
0097 endpoint->service_id = HTC_CTRL_RSVD_SVC;
0098 endpoint->max_msglen = HTC_MAX_CONTROL_MESSAGE_LENGTH;
0099 atomic_inc(&target->tgt_ready);
0100 complete(&target->target_wait);
0101 }
0102
0103 static void htc_process_conn_rsp(struct htc_target *target,
0104 struct htc_frame_hdr *htc_hdr)
0105 {
0106 struct htc_conn_svc_rspmsg *svc_rspmsg;
0107 struct htc_endpoint *endpoint, *tmp_endpoint = NULL;
0108 u16 service_id;
0109 u16 max_msglen;
0110 enum htc_endpoint_id epid, tepid;
0111
0112 svc_rspmsg = (struct htc_conn_svc_rspmsg *)
0113 ((void *) htc_hdr + sizeof(struct htc_frame_hdr));
0114
0115 if (svc_rspmsg->status == HTC_SERVICE_SUCCESS) {
0116 epid = svc_rspmsg->endpoint_id;
0117 if (epid < 0 || epid >= ENDPOINT_MAX)
0118 return;
0119
0120 service_id = be16_to_cpu(svc_rspmsg->service_id);
0121 max_msglen = be16_to_cpu(svc_rspmsg->max_msg_len);
0122 endpoint = &target->endpoint[epid];
0123
0124 for (tepid = (ENDPOINT_MAX - 1); tepid > ENDPOINT0; tepid--) {
0125 tmp_endpoint = &target->endpoint[tepid];
0126 if (tmp_endpoint->service_id == service_id) {
0127 tmp_endpoint->service_id = 0;
0128 break;
0129 }
0130 }
0131
0132 if (tepid == ENDPOINT0)
0133 return;
0134
0135 endpoint->service_id = service_id;
0136 endpoint->max_txqdepth = tmp_endpoint->max_txqdepth;
0137 endpoint->ep_callbacks = tmp_endpoint->ep_callbacks;
0138 endpoint->ul_pipeid = tmp_endpoint->ul_pipeid;
0139 endpoint->dl_pipeid = tmp_endpoint->dl_pipeid;
0140 endpoint->max_msglen = max_msglen;
0141 target->conn_rsp_epid = epid;
0142 complete(&target->cmd_wait);
0143 } else {
0144 target->conn_rsp_epid = ENDPOINT_UNUSED;
0145 }
0146 }
0147
0148 static int htc_config_pipe_credits(struct htc_target *target)
0149 {
0150 struct sk_buff *skb;
0151 struct htc_config_pipe_msg *cp_msg;
0152 int ret;
0153 unsigned long time_left;
0154
0155 skb = alloc_skb(50 + sizeof(struct htc_frame_hdr), GFP_ATOMIC);
0156 if (!skb) {
0157 dev_err(target->dev, "failed to allocate send buffer\n");
0158 return -ENOMEM;
0159 }
0160 skb_reserve(skb, sizeof(struct htc_frame_hdr));
0161
0162 cp_msg = skb_put(skb, sizeof(struct htc_config_pipe_msg));
0163
0164 cp_msg->message_id = cpu_to_be16(HTC_MSG_CONFIG_PIPE_ID);
0165 cp_msg->pipe_id = USB_WLAN_TX_PIPE;
0166 cp_msg->credits = target->credits;
0167
0168 target->htc_flags |= HTC_OP_CONFIG_PIPE_CREDITS;
0169
0170 ret = htc_issue_send(target, skb, skb->len, 0, ENDPOINT0);
0171 if (ret)
0172 goto err;
0173
0174 time_left = wait_for_completion_timeout(&target->cmd_wait, HZ);
0175 if (!time_left) {
0176 dev_err(target->dev, "HTC credit config timeout\n");
0177 return -ETIMEDOUT;
0178 }
0179
0180 return 0;
0181 err:
0182 kfree_skb(skb);
0183 return -EINVAL;
0184 }
0185
0186 static int htc_setup_complete(struct htc_target *target)
0187 {
0188 struct sk_buff *skb;
0189 struct htc_comp_msg *comp_msg;
0190 int ret = 0;
0191 unsigned long time_left;
0192
0193 skb = alloc_skb(50 + sizeof(struct htc_frame_hdr), GFP_ATOMIC);
0194 if (!skb) {
0195 dev_err(target->dev, "failed to allocate send buffer\n");
0196 return -ENOMEM;
0197 }
0198 skb_reserve(skb, sizeof(struct htc_frame_hdr));
0199
0200 comp_msg = skb_put(skb, sizeof(struct htc_comp_msg));
0201 comp_msg->msg_id = cpu_to_be16(HTC_MSG_SETUP_COMPLETE_ID);
0202
0203 target->htc_flags |= HTC_OP_START_WAIT;
0204
0205 ret = htc_issue_send(target, skb, skb->len, 0, ENDPOINT0);
0206 if (ret)
0207 goto err;
0208
0209 time_left = wait_for_completion_timeout(&target->cmd_wait, HZ);
0210 if (!time_left) {
0211 dev_err(target->dev, "HTC start timeout\n");
0212 return -ETIMEDOUT;
0213 }
0214
0215 return 0;
0216
0217 err:
0218 kfree_skb(skb);
0219 return -EINVAL;
0220 }
0221
0222
0223
0224 int htc_init(struct htc_target *target)
0225 {
0226 int ret;
0227
0228 ret = htc_config_pipe_credits(target);
0229 if (ret)
0230 return ret;
0231
0232 return htc_setup_complete(target);
0233 }
0234
0235 int htc_connect_service(struct htc_target *target,
0236 struct htc_service_connreq *service_connreq,
0237 enum htc_endpoint_id *conn_rsp_epid)
0238 {
0239 struct sk_buff *skb;
0240 struct htc_endpoint *endpoint;
0241 struct htc_conn_svc_msg *conn_msg;
0242 int ret;
0243 unsigned long time_left;
0244
0245
0246 endpoint = get_next_avail_ep(target->endpoint);
0247 if (!endpoint) {
0248 dev_err(target->dev, "Endpoint is not available for service %d\n",
0249 service_connreq->service_id);
0250 return -EINVAL;
0251 }
0252
0253 endpoint->service_id = service_connreq->service_id;
0254 endpoint->max_txqdepth = service_connreq->max_send_qdepth;
0255 endpoint->ul_pipeid = service_to_ulpipe(service_connreq->service_id);
0256 endpoint->dl_pipeid = service_to_dlpipe(service_connreq->service_id);
0257 endpoint->ep_callbacks = service_connreq->ep_callbacks;
0258
0259 skb = alloc_skb(sizeof(struct htc_conn_svc_msg) +
0260 sizeof(struct htc_frame_hdr), GFP_ATOMIC);
0261 if (!skb) {
0262 dev_err(target->dev, "Failed to allocate buf to send"
0263 "service connect req\n");
0264 return -ENOMEM;
0265 }
0266
0267 skb_reserve(skb, sizeof(struct htc_frame_hdr));
0268
0269 conn_msg = skb_put(skb, sizeof(struct htc_conn_svc_msg));
0270 conn_msg->service_id = cpu_to_be16(service_connreq->service_id);
0271 conn_msg->msg_id = cpu_to_be16(HTC_MSG_CONNECT_SERVICE_ID);
0272 conn_msg->con_flags = cpu_to_be16(service_connreq->con_flags);
0273 conn_msg->dl_pipeid = endpoint->dl_pipeid;
0274 conn_msg->ul_pipeid = endpoint->ul_pipeid;
0275
0276
0277 conn_msg->svc_meta_len = 0;
0278 conn_msg->pad = 0;
0279
0280 ret = htc_issue_send(target, skb, skb->len, 0, ENDPOINT0);
0281 if (ret)
0282 goto err;
0283
0284 time_left = wait_for_completion_timeout(&target->cmd_wait, HZ);
0285 if (!time_left) {
0286 dev_err(target->dev, "Service connection timeout for: %d\n",
0287 service_connreq->service_id);
0288 return -ETIMEDOUT;
0289 }
0290
0291 *conn_rsp_epid = target->conn_rsp_epid;
0292 return 0;
0293 err:
0294 kfree_skb(skb);
0295 return ret;
0296 }
0297
0298 int htc_send(struct htc_target *target, struct sk_buff *skb)
0299 {
0300 struct ath9k_htc_tx_ctl *tx_ctl;
0301
0302 tx_ctl = HTC_SKB_CB(skb);
0303 return htc_issue_send(target, skb, skb->len, 0, tx_ctl->epid);
0304 }
0305
0306 int htc_send_epid(struct htc_target *target, struct sk_buff *skb,
0307 enum htc_endpoint_id epid)
0308 {
0309 return htc_issue_send(target, skb, skb->len, 0, epid);
0310 }
0311
0312 void htc_stop(struct htc_target *target)
0313 {
0314 target->hif->stop(target->hif_dev);
0315 }
0316
0317 void htc_start(struct htc_target *target)
0318 {
0319 target->hif->start(target->hif_dev);
0320 }
0321
0322 void htc_sta_drain(struct htc_target *target, u8 idx)
0323 {
0324 target->hif->sta_drain(target->hif_dev, idx);
0325 }
0326
0327 void ath9k_htc_txcompletion_cb(struct htc_target *htc_handle,
0328 struct sk_buff *skb, bool txok)
0329 {
0330 struct htc_endpoint *endpoint;
0331 struct htc_frame_hdr *htc_hdr = NULL;
0332
0333 if (htc_handle->htc_flags & HTC_OP_CONFIG_PIPE_CREDITS) {
0334 complete(&htc_handle->cmd_wait);
0335 htc_handle->htc_flags &= ~HTC_OP_CONFIG_PIPE_CREDITS;
0336 goto ret;
0337 }
0338
0339 if (htc_handle->htc_flags & HTC_OP_START_WAIT) {
0340 complete(&htc_handle->cmd_wait);
0341 htc_handle->htc_flags &= ~HTC_OP_START_WAIT;
0342 goto ret;
0343 }
0344
0345 if (skb) {
0346 htc_hdr = (struct htc_frame_hdr *) skb->data;
0347 if (htc_hdr->endpoint_id >= ARRAY_SIZE(htc_handle->endpoint))
0348 goto ret;
0349 endpoint = &htc_handle->endpoint[htc_hdr->endpoint_id];
0350 skb_pull(skb, sizeof(struct htc_frame_hdr));
0351
0352 if (endpoint->ep_callbacks.tx) {
0353 endpoint->ep_callbacks.tx(endpoint->ep_callbacks.priv,
0354 skb, htc_hdr->endpoint_id,
0355 txok);
0356 } else {
0357 kfree_skb(skb);
0358 }
0359 }
0360
0361 return;
0362 ret:
0363 kfree_skb(skb);
0364 }
0365
0366 static void ath9k_htc_fw_panic_report(struct htc_target *htc_handle,
0367 struct sk_buff *skb)
0368 {
0369 uint32_t *pattern = (uint32_t *)skb->data;
0370
0371 switch (*pattern) {
0372 case 0x33221199:
0373 {
0374 struct htc_panic_bad_vaddr *htc_panic;
0375 htc_panic = (struct htc_panic_bad_vaddr *) skb->data;
0376 dev_err(htc_handle->dev, "ath: firmware panic! "
0377 "exccause: 0x%08x; pc: 0x%08x; badvaddr: 0x%08x.\n",
0378 htc_panic->exccause, htc_panic->pc,
0379 htc_panic->badvaddr);
0380 break;
0381 }
0382 case 0x33221299:
0383 {
0384 struct htc_panic_bad_epid *htc_panic;
0385 htc_panic = (struct htc_panic_bad_epid *) skb->data;
0386 dev_err(htc_handle->dev, "ath: firmware panic! "
0387 "bad epid: 0x%08x\n", htc_panic->epid);
0388 break;
0389 }
0390 default:
0391 dev_err(htc_handle->dev, "ath: unknown panic pattern!\n");
0392 break;
0393 }
0394 }
0395
0396
0397
0398
0399
0400
0401
0402
0403 void ath9k_htc_rx_msg(struct htc_target *htc_handle,
0404 struct sk_buff *skb, u32 len, u8 pipe_id)
0405 {
0406 struct htc_frame_hdr *htc_hdr;
0407 enum htc_endpoint_id epid;
0408 struct htc_endpoint *endpoint;
0409 __be16 *msg_id;
0410
0411 if (!htc_handle || !skb)
0412 return;
0413
0414 htc_hdr = (struct htc_frame_hdr *) skb->data;
0415 epid = htc_hdr->endpoint_id;
0416
0417 if (epid == 0x99) {
0418 ath9k_htc_fw_panic_report(htc_handle, skb);
0419 kfree_skb(skb);
0420 return;
0421 }
0422
0423 if (epid < 0 || epid >= ENDPOINT_MAX) {
0424 if (pipe_id != USB_REG_IN_PIPE)
0425 dev_kfree_skb_any(skb);
0426 else
0427 kfree_skb(skb);
0428 return;
0429 }
0430
0431 if (epid == ENDPOINT0) {
0432
0433
0434 if (htc_hdr->flags & HTC_FLAGS_RECV_TRAILER) {
0435 if (be32_to_cpu(*(__be32 *) skb->data) == 0x00C60000)
0436
0437 htc_hdr = (struct htc_frame_hdr *)(skb->data + 4);
0438 }
0439
0440
0441 msg_id = (__be16 *) ((void *) htc_hdr +
0442 sizeof(struct htc_frame_hdr));
0443
0444
0445 switch (be16_to_cpu(*msg_id)) {
0446 case HTC_MSG_READY_ID:
0447 htc_process_target_rdy(htc_handle, htc_hdr);
0448 break;
0449 case HTC_MSG_CONNECT_SERVICE_RESPONSE_ID:
0450 htc_process_conn_rsp(htc_handle, htc_hdr);
0451 break;
0452 default:
0453 break;
0454 }
0455
0456 kfree_skb(skb);
0457
0458 } else {
0459 if (htc_hdr->flags & HTC_FLAGS_RECV_TRAILER)
0460 skb_trim(skb, len - htc_hdr->control[0]);
0461
0462 skb_pull(skb, sizeof(struct htc_frame_hdr));
0463
0464 endpoint = &htc_handle->endpoint[epid];
0465 if (endpoint->ep_callbacks.rx)
0466 endpoint->ep_callbacks.rx(endpoint->ep_callbacks.priv,
0467 skb, epid);
0468 }
0469 }
0470
0471 struct htc_target *ath9k_htc_hw_alloc(void *hif_handle,
0472 struct ath9k_htc_hif *hif,
0473 struct device *dev)
0474 {
0475 struct htc_endpoint *endpoint;
0476 struct htc_target *target;
0477
0478 target = kzalloc(sizeof(struct htc_target), GFP_KERNEL);
0479 if (!target)
0480 return NULL;
0481
0482 init_completion(&target->target_wait);
0483 init_completion(&target->cmd_wait);
0484
0485 target->hif = hif;
0486 target->hif_dev = hif_handle;
0487 target->dev = dev;
0488
0489
0490 endpoint = &target->endpoint[ENDPOINT0];
0491 endpoint->ul_pipeid = hif->control_ul_pipe;
0492 endpoint->dl_pipeid = hif->control_dl_pipe;
0493
0494 atomic_set(&target->tgt_ready, 0);
0495
0496 return target;
0497 }
0498
0499 void ath9k_htc_hw_free(struct htc_target *htc)
0500 {
0501 kfree(htc);
0502 }
0503
0504 int ath9k_htc_hw_init(struct htc_target *target,
0505 struct device *dev, u16 devid,
0506 char *product, u32 drv_info)
0507 {
0508 if (ath9k_htc_probe_device(target, dev, devid, product, drv_info)) {
0509 pr_err("Failed to initialize the device\n");
0510 return -ENODEV;
0511 }
0512
0513 return 0;
0514 }
0515
0516 void ath9k_htc_hw_deinit(struct htc_target *target, bool hot_unplug)
0517 {
0518 if (target)
0519 ath9k_htc_disconnect_device(target, hot_unplug);
0520 }