These changes are the raw update to linux-4.4.6-rt14. Kernel sources
[kvmfornfv.git] / kernel / drivers / net / wireless / ath / ath10k / htc.c
index 2fd9e18..5b3c6bc 100644 (file)
 /* Send */
 /********/
 
-static inline void ath10k_htc_send_complete_check(struct ath10k_htc_ep *ep,
-                                                 int force)
-{
-       /*
-        * Check whether HIF has any prior sends that have finished,
-        * have not had the post-processing done.
-        */
-       ath10k_hif_send_complete_check(ep->htc->ar, ep->ul_pipe_id, force);
-}
-
 static void ath10k_htc_control_tx_complete(struct ath10k *ar,
                                           struct sk_buff *skb)
 {
@@ -86,21 +76,6 @@ static void ath10k_htc_notify_tx_completion(struct ath10k_htc_ep *ep,
        ep->ep_ops.ep_tx_complete(ep->htc->ar, skb);
 }
 
-/* assumes tx_lock is held */
-static bool ath10k_htc_ep_need_credit_update(struct ath10k_htc_ep *ep)
-{
-       struct ath10k *ar = ep->htc->ar;
-
-       if (!ep->tx_credit_flow_enabled)
-               return false;
-       if (ep->tx_credits >= ep->tx_credits_per_max_message)
-               return false;
-
-       ath10k_dbg(ar, ATH10K_DBG_HTC, "HTC: endpoint %d needs credit update\n",
-                  ep->eid);
-       return true;
-}
-
 static void ath10k_htc_prepare_tx_skb(struct ath10k_htc_ep *ep,
                                      struct sk_buff *skb)
 {
@@ -111,13 +86,10 @@ static void ath10k_htc_prepare_tx_skb(struct ath10k_htc_ep *ep,
        hdr->eid = ep->eid;
        hdr->len = __cpu_to_le16(skb->len - sizeof(*hdr));
        hdr->flags = 0;
+       hdr->flags |= ATH10K_HTC_FLAG_NEED_CREDIT_UPDATE;
 
        spin_lock_bh(&ep->htc->tx_lock);
        hdr->seq_no = ep->seq_no++;
-
-       if (ath10k_htc_ep_need_credit_update(ep))
-               hdr->flags |= ATH10K_HTC_FLAG_NEED_CREDIT_UPDATE;
-
        spin_unlock_bh(&ep->htc->tx_lock);
 }
 
@@ -163,8 +135,10 @@ int ath10k_htc_send(struct ath10k_htc *htc,
        skb_cb->eid = eid;
        skb_cb->paddr = dma_map_single(dev, skb->data, skb->len, DMA_TO_DEVICE);
        ret = dma_mapping_error(dev, skb_cb->paddr);
-       if (ret)
+       if (ret) {
+               ret = -EIO;
                goto err_credits;
+       }
 
        sg_item.transfer_id = ep->eid;
        sg_item.transfer_context = skb;
@@ -197,24 +171,22 @@ err_pull:
        return ret;
 }
 
-static int ath10k_htc_tx_completion_handler(struct ath10k *ar,
-                                           struct sk_buff *skb)
+void ath10k_htc_tx_completion_handler(struct ath10k *ar, struct sk_buff *skb)
 {
        struct ath10k_htc *htc = &ar->htc;
        struct ath10k_skb_cb *skb_cb;
        struct ath10k_htc_ep *ep;
 
        if (WARN_ON_ONCE(!skb))
-               return 0;
+               return;
 
        skb_cb = ATH10K_SKB_CB(skb);
        ep = &htc->endpoint[skb_cb->eid];
 
        ath10k_htc_notify_tx_completion(ep, skb);
        /* the skb now belongs to the completion handler */
-
-       return 0;
 }
+EXPORT_SYMBOL(ath10k_htc_tx_completion_handler);
 
 /***********/
 /* Receive */
@@ -320,8 +292,7 @@ static int ath10k_htc_process_trailer(struct ath10k_htc *htc,
        return status;
 }
 
-static int ath10k_htc_rx_completion_handler(struct ath10k *ar,
-                                           struct sk_buff *skb)
+void ath10k_htc_rx_completion_handler(struct ath10k *ar, struct sk_buff *skb)
 {
        int status = 0;
        struct ath10k_htc *htc = &ar->htc;
@@ -342,21 +313,11 @@ static int ath10k_htc_rx_completion_handler(struct ath10k *ar,
                ath10k_warn(ar, "HTC Rx: invalid eid %d\n", eid);
                ath10k_dbg_dump(ar, ATH10K_DBG_HTC, "htc bad header", "",
                                hdr, sizeof(*hdr));
-               status = -EINVAL;
                goto out;
        }
 
        ep = &htc->endpoint[eid];
 
-       /*
-        * If this endpoint that received a message from the target has
-        * a to-target HIF pipe whose send completions are polled rather
-        * than interrupt-driven, this is a good point to ask HIF to check
-        * whether it has any completed sends to handle.
-        */
-       if (ep->ul_is_polled)
-               ath10k_htc_send_complete_check(ep, 1);
-
        payload_len = __le16_to_cpu(hdr->len);
 
        if (payload_len + sizeof(*hdr) > ATH10K_HTC_MAX_LEN) {
@@ -364,7 +325,6 @@ static int ath10k_htc_rx_completion_handler(struct ath10k *ar,
                            payload_len + sizeof(*hdr));
                ath10k_dbg_dump(ar, ATH10K_DBG_HTC, "htc bad rx pkt len", "",
                                hdr, sizeof(*hdr));
-               status = -EINVAL;
                goto out;
        }
 
@@ -374,7 +334,6 @@ static int ath10k_htc_rx_completion_handler(struct ath10k *ar,
                           skb->len, payload_len);
                ath10k_dbg_dump(ar, ATH10K_DBG_HTC, "htc bad rx pkt len",
                                "", hdr, sizeof(*hdr));
-               status = -EINVAL;
                goto out;
        }
 
@@ -390,7 +349,6 @@ static int ath10k_htc_rx_completion_handler(struct ath10k *ar,
                    (trailer_len > payload_len)) {
                        ath10k_warn(ar, "Invalid trailer length: %d\n",
                                    trailer_len);
-                       status = -EPROTO;
                        goto out;
                }
 
@@ -414,7 +372,8 @@ static int ath10k_htc_rx_completion_handler(struct ath10k *ar,
                struct ath10k_htc_msg *msg = (struct ath10k_htc_msg *)skb->data;
 
                switch (__le16_to_cpu(msg->hdr.message_id)) {
-               default:
+               case ATH10K_HTC_MSG_READY_ID:
+               case ATH10K_HTC_MSG_CONNECT_SERVICE_RESP_ID:
                        /* handle HTC control message */
                        if (completion_done(&htc->ctl_resp)) {
                                /*
@@ -422,7 +381,6 @@ static int ath10k_htc_rx_completion_handler(struct ath10k *ar,
                                 * sending unsolicited messages on the ep 0
                                 */
                                ath10k_warn(ar, "HTC rx ctrl still processing\n");
-                               status = -EINVAL;
                                complete(&htc->ctl_resp);
                                goto out;
                        }
@@ -438,6 +396,10 @@ static int ath10k_htc_rx_completion_handler(struct ath10k *ar,
                        break;
                case ATH10K_HTC_MSG_SEND_SUSPEND_COMPLETE:
                        htc->htc_ops.target_send_suspend_complete(ar);
+                       break;
+               default:
+                       ath10k_warn(ar, "ignoring unsolicited htc ep0 event\n");
+                       break;
                }
                goto out;
        }
@@ -450,9 +412,8 @@ static int ath10k_htc_rx_completion_handler(struct ath10k *ar,
        skb = NULL;
 out:
        kfree_skb(skb);
-
-       return status;
 }
+EXPORT_SYMBOL(ath10k_htc_rx_completion_handler);
 
 static void ath10k_htc_control_rx_complete(struct ath10k *ar,
                                           struct sk_buff *skb)
@@ -548,6 +509,7 @@ int ath10k_htc_wait_target(struct ath10k_htc *htc)
 {
        struct ath10k *ar = htc->ar;
        int i, status = 0;
+       unsigned long time_left;
        struct ath10k_htc_svc_conn_req conn_req;
        struct ath10k_htc_svc_conn_resp conn_resp;
        struct ath10k_htc_msg *msg;
@@ -555,9 +517,9 @@ int ath10k_htc_wait_target(struct ath10k_htc *htc)
        u16 credit_count;
        u16 credit_size;
 
-       status = wait_for_completion_timeout(&htc->ctl_resp,
-                                            ATH10K_HTC_WAIT_TIMEOUT_HZ);
-       if (status == 0) {
+       time_left = wait_for_completion_timeout(&htc->ctl_resp,
+                                               ATH10K_HTC_WAIT_TIMEOUT_HZ);
+       if (!time_left) {
                /* Workaround: In some cases the PCI HIF doesn't
                 * receive interrupt for the control response message
                 * even if the buffer was completed. It is suspected
@@ -569,10 +531,11 @@ int ath10k_htc_wait_target(struct ath10k_htc *htc)
                for (i = 0; i < CE_COUNT; i++)
                        ath10k_hif_send_complete_check(htc->ar, i, 1);
 
-               status = wait_for_completion_timeout(&htc->ctl_resp,
-                                                    ATH10K_HTC_WAIT_TIMEOUT_HZ);
+               time_left =
+               wait_for_completion_timeout(&htc->ctl_resp,
+                                           ATH10K_HTC_WAIT_TIMEOUT_HZ);
 
-               if (status == 0)
+               if (!time_left)
                        status = -ETIMEDOUT;
        }
 
@@ -646,6 +609,7 @@ int ath10k_htc_connect_service(struct ath10k_htc *htc,
        struct sk_buff *skb;
        unsigned int max_msg_size = 0;
        int length, status;
+       unsigned long time_left;
        bool disable_credit_flow_ctrl = false;
        u16 message_id, service_id, flags = 0;
        u8 tx_alloc = 0;
@@ -701,10 +665,10 @@ int ath10k_htc_connect_service(struct ath10k_htc *htc,
        }
 
        /* wait for response */
-       status = wait_for_completion_timeout(&htc->ctl_resp,
-                                            ATH10K_HTC_CONN_SVC_TIMEOUT_HZ);
-       if (status == 0) {
-               ath10k_err(ar, "Service connect timeout: %d\n", status);
+       time_left = wait_for_completion_timeout(&htc->ctl_resp,
+                                               ATH10K_HTC_CONN_SVC_TIMEOUT_HZ);
+       if (!time_left) {
+               ath10k_err(ar, "Service connect timeout\n");
                return -ETIMEDOUT;
        }
 
@@ -775,9 +739,7 @@ setup:
        status = ath10k_hif_map_service_to_pipe(htc->ar,
                                                ep->service_id,
                                                &ep->ul_pipe_id,
-                                               &ep->dl_pipe_id,
-                                               &ep->ul_is_polled,
-                                               &ep->dl_is_polled);
+                                               &ep->dl_pipe_id);
        if (status)
                return status;
 
@@ -786,10 +748,6 @@ setup:
                   htc_service_name(ep->service_id), ep->ul_pipe_id,
                   ep->dl_pipe_id, ep->eid);
 
-       ath10k_dbg(ar, ATH10K_DBG_BOOT,
-                  "boot htc ep %d ul polled %d dl polled %d\n",
-                  ep->eid, ep->ul_is_polled, ep->dl_is_polled);
-
        if (disable_credit_flow_ctrl && ep->tx_credit_flow_enabled) {
                ep->tx_credit_flow_enabled = false;
                ath10k_dbg(ar, ATH10K_DBG_BOOT,
@@ -849,7 +807,6 @@ int ath10k_htc_start(struct ath10k_htc *htc)
 /* registered target arrival callback from the HIF layer */
 int ath10k_htc_init(struct ath10k *ar)
 {
-       struct ath10k_hif_cb htc_callbacks;
        struct ath10k_htc_ep *ep = NULL;
        struct ath10k_htc *htc = &ar->htc;
 
@@ -857,15 +814,11 @@ int ath10k_htc_init(struct ath10k *ar)
 
        ath10k_htc_reset_endpoint_states(htc);
 
-       /* setup HIF layer callbacks */
-       htc_callbacks.rx_completion = ath10k_htc_rx_completion_handler;
-       htc_callbacks.tx_completion = ath10k_htc_tx_completion_handler;
        htc->ar = ar;
 
        /* Get HIF default pipe for HTC message exchange */
        ep = &htc->endpoint[ATH10K_HTC_EP_0];
 
-       ath10k_hif_set_callbacks(ar, &htc_callbacks);
        ath10k_hif_get_default_pipe(ar, &ep->ul_pipe_id, &ep->dl_pipe_id);
 
        init_completion(&htc->ctl_resp);