diff options
Diffstat (limited to 'drivers/net/wireless/ath/ath6kl/txrx.c')
-rw-r--r-- | drivers/net/wireless/ath/ath6kl/txrx.c | 47 |
1 files changed, 33 insertions, 14 deletions
diff --git a/drivers/net/wireless/ath/ath6kl/txrx.c b/drivers/net/wireless/ath/ath6kl/txrx.c index 7dfa0fd86d7..78b36928657 100644 --- a/drivers/net/wireless/ath/ath6kl/txrx.c +++ b/drivers/net/wireless/ath/ath6kl/txrx.c | |||
@@ -288,8 +288,16 @@ int ath6kl_control_tx(void *devt, struct sk_buff *skb, | |||
288 | int status = 0; | 288 | int status = 0; |
289 | struct ath6kl_cookie *cookie = NULL; | 289 | struct ath6kl_cookie *cookie = NULL; |
290 | 290 | ||
291 | if (WARN_ON_ONCE(ar->state == ATH6KL_STATE_WOW)) | 291 | if (WARN_ON_ONCE(ar->state == ATH6KL_STATE_WOW)) { |
292 | dev_kfree_skb(skb); | ||
292 | return -EACCES; | 293 | return -EACCES; |
294 | } | ||
295 | |||
296 | if (WARN_ON_ONCE(eid == ENDPOINT_UNUSED || | ||
297 | eid >= ENDPOINT_MAX)) { | ||
298 | status = -EINVAL; | ||
299 | goto fail_ctrl_tx; | ||
300 | } | ||
293 | 301 | ||
294 | spin_lock_bh(&ar->lock); | 302 | spin_lock_bh(&ar->lock); |
295 | 303 | ||
@@ -591,6 +599,7 @@ enum htc_send_full_action ath6kl_tx_queue_full(struct htc_target *target, | |||
591 | */ | 599 | */ |
592 | set_bit(WMI_CTRL_EP_FULL, &ar->flag); | 600 | set_bit(WMI_CTRL_EP_FULL, &ar->flag); |
593 | ath6kl_err("wmi ctrl ep is full\n"); | 601 | ath6kl_err("wmi ctrl ep is full\n"); |
602 | ath6kl_recovery_err_notify(ar, ATH6KL_FW_EP_FULL); | ||
594 | return action; | 603 | return action; |
595 | } | 604 | } |
596 | 605 | ||
@@ -695,22 +704,31 @@ void ath6kl_tx_complete(struct htc_target *target, | |||
695 | list); | 704 | list); |
696 | list_del(&packet->list); | 705 | list_del(&packet->list); |
697 | 706 | ||
707 | if (WARN_ON_ONCE(packet->endpoint == ENDPOINT_UNUSED || | ||
708 | packet->endpoint >= ENDPOINT_MAX)) | ||
709 | continue; | ||
710 | |||
698 | ath6kl_cookie = (struct ath6kl_cookie *)packet->pkt_cntxt; | 711 | ath6kl_cookie = (struct ath6kl_cookie *)packet->pkt_cntxt; |
699 | if (!ath6kl_cookie) | 712 | if (WARN_ON_ONCE(!ath6kl_cookie)) |
700 | goto fatal; | 713 | continue; |
701 | 714 | ||
702 | status = packet->status; | 715 | status = packet->status; |
703 | skb = ath6kl_cookie->skb; | 716 | skb = ath6kl_cookie->skb; |
704 | eid = packet->endpoint; | 717 | eid = packet->endpoint; |
705 | map_no = ath6kl_cookie->map_no; | 718 | map_no = ath6kl_cookie->map_no; |
706 | 719 | ||
707 | if (!skb || !skb->data) | 720 | if (WARN_ON_ONCE(!skb || !skb->data)) { |
708 | goto fatal; | 721 | dev_kfree_skb(skb); |
722 | ath6kl_free_cookie(ar, ath6kl_cookie); | ||
723 | continue; | ||
724 | } | ||
709 | 725 | ||
710 | __skb_queue_tail(&skb_queue, skb); | 726 | __skb_queue_tail(&skb_queue, skb); |
711 | 727 | ||
712 | if (!status && (packet->act_len != skb->len)) | 728 | if (WARN_ON_ONCE(!status && (packet->act_len != skb->len))) { |
713 | goto fatal; | 729 | ath6kl_free_cookie(ar, ath6kl_cookie); |
730 | continue; | ||
731 | } | ||
714 | 732 | ||
715 | ar->tx_pending[eid]--; | 733 | ar->tx_pending[eid]--; |
716 | 734 | ||
@@ -792,11 +810,6 @@ void ath6kl_tx_complete(struct htc_target *target, | |||
792 | wake_up(&ar->event_wq); | 810 | wake_up(&ar->event_wq); |
793 | 811 | ||
794 | return; | 812 | return; |
795 | |||
796 | fatal: | ||
797 | WARN_ON(1); | ||
798 | spin_unlock_bh(&ar->lock); | ||
799 | return; | ||
800 | } | 813 | } |
801 | 814 | ||
802 | void ath6kl_tx_data_cleanup(struct ath6kl *ar) | 815 | void ath6kl_tx_data_cleanup(struct ath6kl *ar) |
@@ -885,8 +898,11 @@ void ath6kl_rx_refill(struct htc_target *target, enum htc_endpoint_id endpoint) | |||
885 | break; | 898 | break; |
886 | 899 | ||
887 | packet = (struct htc_packet *) skb->head; | 900 | packet = (struct htc_packet *) skb->head; |
888 | if (!IS_ALIGNED((unsigned long) skb->data, 4)) | 901 | if (!IS_ALIGNED((unsigned long) skb->data, 4)) { |
902 | size_t len = skb_headlen(skb); | ||
889 | skb->data = PTR_ALIGN(skb->data - 4, 4); | 903 | skb->data = PTR_ALIGN(skb->data - 4, 4); |
904 | skb_set_tail_pointer(skb, len); | ||
905 | } | ||
890 | set_htc_rxpkt_info(packet, skb, skb->data, | 906 | set_htc_rxpkt_info(packet, skb, skb->data, |
891 | ATH6KL_BUFFER_SIZE, endpoint); | 907 | ATH6KL_BUFFER_SIZE, endpoint); |
892 | packet->skb = skb; | 908 | packet->skb = skb; |
@@ -908,8 +924,11 @@ void ath6kl_refill_amsdu_rxbufs(struct ath6kl *ar, int count) | |||
908 | return; | 924 | return; |
909 | 925 | ||
910 | packet = (struct htc_packet *) skb->head; | 926 | packet = (struct htc_packet *) skb->head; |
911 | if (!IS_ALIGNED((unsigned long) skb->data, 4)) | 927 | if (!IS_ALIGNED((unsigned long) skb->data, 4)) { |
928 | size_t len = skb_headlen(skb); | ||
912 | skb->data = PTR_ALIGN(skb->data - 4, 4); | 929 | skb->data = PTR_ALIGN(skb->data - 4, 4); |
930 | skb_set_tail_pointer(skb, len); | ||
931 | } | ||
913 | set_htc_rxpkt_info(packet, skb, skb->data, | 932 | set_htc_rxpkt_info(packet, skb, skb->data, |
914 | ATH6KL_AMSDU_BUFFER_SIZE, 0); | 933 | ATH6KL_AMSDU_BUFFER_SIZE, 0); |
915 | packet->skb = skb; | 934 | packet->skb = skb; |