diff options
Diffstat (limited to 'drivers/net/wireless/libertas/if_usb.c')
-rw-r--r-- | drivers/net/wireless/libertas/if_usb.c | 71 |
1 files changed, 21 insertions, 50 deletions
diff --git a/drivers/net/wireless/libertas/if_usb.c b/drivers/net/wireless/libertas/if_usb.c index 75aed9d07367..8032df72aaab 100644 --- a/drivers/net/wireless/libertas/if_usb.c +++ b/drivers/net/wireless/libertas/if_usb.c | |||
@@ -38,8 +38,6 @@ static void if_usb_receive_fwload(struct urb *urb); | |||
38 | static int if_usb_prog_firmware(struct if_usb_card *cardp); | 38 | static int if_usb_prog_firmware(struct if_usb_card *cardp); |
39 | static int if_usb_host_to_card(struct lbs_private *priv, uint8_t type, | 39 | static int if_usb_host_to_card(struct lbs_private *priv, uint8_t type, |
40 | uint8_t *payload, uint16_t nb); | 40 | uint8_t *payload, uint16_t nb); |
41 | static int if_usb_get_int_status(struct lbs_private *priv, uint8_t *); | ||
42 | static int if_usb_read_event_cause(struct lbs_private *); | ||
43 | static int usb_tx_block(struct if_usb_card *cardp, uint8_t *payload, | 41 | static int usb_tx_block(struct if_usb_card *cardp, uint8_t *payload, |
44 | uint16_t nb); | 42 | uint16_t nb); |
45 | static void if_usb_free(struct if_usb_card *cardp); | 43 | static void if_usb_free(struct if_usb_card *cardp); |
@@ -233,8 +231,6 @@ static int if_usb_probe(struct usb_interface *intf, | |||
233 | cardp->priv->fw_ready = 1; | 231 | cardp->priv->fw_ready = 1; |
234 | 232 | ||
235 | priv->hw_host_to_card = if_usb_host_to_card; | 233 | priv->hw_host_to_card = if_usb_host_to_card; |
236 | priv->hw_get_int_status = if_usb_get_int_status; | ||
237 | priv->hw_read_event_cause = if_usb_read_event_cause; | ||
238 | cardp->boot2_version = udev->descriptor.bcdDevice; | 234 | cardp->boot2_version = udev->descriptor.bcdDevice; |
239 | 235 | ||
240 | if_usb_submit_rx_urb(cardp); | 236 | if_usb_submit_rx_urb(cardp); |
@@ -582,7 +578,6 @@ static inline void process_cmdtypedata(int recvlength, struct sk_buff *skb, | |||
582 | skb_pull(skb, MESSAGE_HEADER_LEN); | 578 | skb_pull(skb, MESSAGE_HEADER_LEN); |
583 | 579 | ||
584 | lbs_process_rxed_packet(priv, skb); | 580 | lbs_process_rxed_packet(priv, skb); |
585 | priv->upld_len = (recvlength - MESSAGE_HEADER_LEN); | ||
586 | } | 581 | } |
587 | 582 | ||
588 | static inline void process_cmdrequest(int recvlength, uint8_t *recvbuff, | 583 | static inline void process_cmdrequest(int recvlength, uint8_t *recvbuff, |
@@ -590,6 +585,8 @@ static inline void process_cmdrequest(int recvlength, uint8_t *recvbuff, | |||
590 | struct if_usb_card *cardp, | 585 | struct if_usb_card *cardp, |
591 | struct lbs_private *priv) | 586 | struct lbs_private *priv) |
592 | { | 587 | { |
588 | u8 i; | ||
589 | |||
593 | if (recvlength > LBS_CMD_BUFFER_SIZE) { | 590 | if (recvlength > LBS_CMD_BUFFER_SIZE) { |
594 | lbs_deb_usbd(&cardp->udev->dev, | 591 | lbs_deb_usbd(&cardp->udev->dev, |
595 | "The receive buffer is too large\n"); | 592 | "The receive buffer is too large\n"); |
@@ -601,12 +598,15 @@ static inline void process_cmdrequest(int recvlength, uint8_t *recvbuff, | |||
601 | BUG(); | 598 | BUG(); |
602 | 599 | ||
603 | spin_lock(&priv->driver_lock); | 600 | spin_lock(&priv->driver_lock); |
604 | cardp->usb_int_cause |= MRVDRV_CMD_UPLD_RDY; | ||
605 | priv->upld_len = (recvlength - MESSAGE_HEADER_LEN); | ||
606 | memcpy(priv->upld_buf, recvbuff + MESSAGE_HEADER_LEN, priv->upld_len); | ||
607 | 601 | ||
602 | i = (priv->resp_idx == 0) ? 1 : 0; | ||
603 | BUG_ON(priv->resp_len[i]); | ||
604 | priv->resp_len[i] = (recvlength - MESSAGE_HEADER_LEN); | ||
605 | memcpy(priv->resp_buf[i], recvbuff + MESSAGE_HEADER_LEN, | ||
606 | priv->resp_len[i]); | ||
608 | kfree_skb(skb); | 607 | kfree_skb(skb); |
609 | lbs_interrupt(priv); | 608 | lbs_notify_command_response(priv, i); |
609 | |||
610 | spin_unlock(&priv->driver_lock); | 610 | spin_unlock(&priv->driver_lock); |
611 | 611 | ||
612 | lbs_deb_usbd(&cardp->udev->dev, | 612 | lbs_deb_usbd(&cardp->udev->dev, |
@@ -629,6 +629,7 @@ static void if_usb_receive(struct urb *urb) | |||
629 | uint8_t *recvbuff = NULL; | 629 | uint8_t *recvbuff = NULL; |
630 | uint32_t recvtype = 0; | 630 | uint32_t recvtype = 0; |
631 | __le32 *pkt = (__le32 *)(skb->data + IPFIELD_ALIGN_OFFSET); | 631 | __le32 *pkt = (__le32 *)(skb->data + IPFIELD_ALIGN_OFFSET); |
632 | uint32_t event; | ||
632 | 633 | ||
633 | lbs_deb_enter(LBS_DEB_USB); | 634 | lbs_deb_enter(LBS_DEB_USB); |
634 | 635 | ||
@@ -660,26 +661,20 @@ static void if_usb_receive(struct urb *urb) | |||
660 | break; | 661 | break; |
661 | 662 | ||
662 | case CMD_TYPE_INDICATION: | 663 | case CMD_TYPE_INDICATION: |
663 | /* Event cause handling */ | 664 | /* Event handling */ |
664 | spin_lock(&priv->driver_lock); | 665 | event = le32_to_cpu(pkt[1]); |
666 | lbs_deb_usbd(&cardp->udev->dev, "**EVENT** 0x%X\n", event); | ||
667 | kfree_skb(skb); | ||
665 | 668 | ||
666 | cardp->usb_event_cause = le32_to_cpu(pkt[1]); | 669 | /* Icky undocumented magic special case */ |
670 | if (event & 0xffff0000) { | ||
671 | u32 trycount = (event & 0xffff0000) >> 16; | ||
667 | 672 | ||
668 | lbs_deb_usbd(&cardp->udev->dev,"**EVENT** 0x%X\n", | 673 | lbs_send_tx_feedback(priv, trycount); |
669 | cardp->usb_event_cause); | 674 | } else |
675 | lbs_queue_event(priv, event & 0xFF); | ||
676 | break; | ||
670 | 677 | ||
671 | /* Icky undocumented magic special case */ | ||
672 | if (cardp->usb_event_cause & 0xffff0000) { | ||
673 | lbs_send_tx_feedback(priv); | ||
674 | spin_unlock(&priv->driver_lock); | ||
675 | break; | ||
676 | } | ||
677 | cardp->usb_event_cause <<= 3; | ||
678 | cardp->usb_int_cause |= MRVDRV_CARDEVENT; | ||
679 | kfree_skb(skb); | ||
680 | lbs_interrupt(priv); | ||
681 | spin_unlock(&priv->driver_lock); | ||
682 | goto rx_exit; | ||
683 | default: | 678 | default: |
684 | lbs_deb_usbd(&cardp->udev->dev, "Unknown command type 0x%X\n", | 679 | lbs_deb_usbd(&cardp->udev->dev, "Unknown command type 0x%X\n", |
685 | recvtype); | 680 | recvtype); |
@@ -722,30 +717,6 @@ static int if_usb_host_to_card(struct lbs_private *priv, uint8_t type, | |||
722 | return usb_tx_block(cardp, cardp->ep_out_buf, nb + MESSAGE_HEADER_LEN); | 717 | return usb_tx_block(cardp, cardp->ep_out_buf, nb + MESSAGE_HEADER_LEN); |
723 | } | 718 | } |
724 | 719 | ||
725 | /* called with priv->driver_lock held */ | ||
726 | static int if_usb_get_int_status(struct lbs_private *priv, uint8_t *ireg) | ||
727 | { | ||
728 | struct if_usb_card *cardp = priv->card; | ||
729 | |||
730 | *ireg = cardp->usb_int_cause; | ||
731 | cardp->usb_int_cause = 0; | ||
732 | |||
733 | lbs_deb_usbd(&cardp->udev->dev, "Int cause is 0x%X\n", *ireg); | ||
734 | |||
735 | return 0; | ||
736 | } | ||
737 | |||
738 | static int if_usb_read_event_cause(struct lbs_private *priv) | ||
739 | { | ||
740 | struct if_usb_card *cardp = priv->card; | ||
741 | |||
742 | priv->eventcause = cardp->usb_event_cause; | ||
743 | /* Re-submit rx urb here to avoid event lost issue */ | ||
744 | if_usb_submit_rx_urb(cardp); | ||
745 | |||
746 | return 0; | ||
747 | } | ||
748 | |||
749 | /** | 720 | /** |
750 | * @brief This function issues Boot command to the Boot2 code | 721 | * @brief This function issues Boot command to the Boot2 code |
751 | * @param ivalue 1:Boot from FW by USB-Download | 722 | * @param ivalue 1:Boot from FW by USB-Download |