aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStephen Hemminger <sthemmin@microsoft.com>2016-08-23 15:17:53 -0400
committerDavid S. Miller <davem@davemloft.net>2016-08-23 15:05:37 -0400
commitbc304dd3b4444b84082c483534a8dcac7a22cb9d (patch)
tree936f78435b5261047012a8530a68e24cc31ef0d5
parent0ab05141f97de2ac954c267c27b256ebd241e762 (diff)
hv_netvsc: refactor completion function
Break the different cases, code is cleaner if broken up Signed-off-by: Stephen Hemminger <sthemmin@microsoft.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/hyperv/netvsc.c103
1 files changed, 56 insertions, 47 deletions
diff --git a/drivers/net/hyperv/netvsc.c b/drivers/net/hyperv/netvsc.c
index 27eb507d64f9..830aae2d9510 100644
--- a/drivers/net/hyperv/netvsc.c
+++ b/drivers/net/hyperv/netvsc.c
@@ -696,69 +696,78 @@ static inline void netvsc_free_send_slot(struct netvsc_device *net_device,
696 sync_change_bit(index, net_device->send_section_map); 696 sync_change_bit(index, net_device->send_section_map);
697} 697}
698 698
699static void netvsc_send_tx_complete(struct netvsc_device *net_device,
700 struct vmbus_channel *incoming_channel,
701 struct hv_device *device,
702 struct vmpacket_descriptor *packet)
703{
704 struct sk_buff *skb = (struct sk_buff *)(unsigned long)packet->trans_id;
705 struct net_device *ndev = hv_get_drvdata(device);
706 struct net_device_context *net_device_ctx = netdev_priv(ndev);
707 struct vmbus_channel *channel = device->channel;
708 int num_outstanding_sends;
709 u16 q_idx = 0;
710 int queue_sends;
711
712 /* Notify the layer above us */
713 if (likely(skb)) {
714 struct hv_netvsc_packet *nvsc_packet
715 = (struct hv_netvsc_packet *)skb->cb;
716 u32 send_index = nvsc_packet->send_buf_index;
717
718 if (send_index != NETVSC_INVALID_INDEX)
719 netvsc_free_send_slot(net_device, send_index);
720 q_idx = nvsc_packet->q_idx;
721 channel = incoming_channel;
722
723 dev_kfree_skb_any(skb);
724 }
725
726 num_outstanding_sends =
727 atomic_dec_return(&net_device->num_outstanding_sends);
728 queue_sends = atomic_dec_return(&net_device->queue_sends[q_idx]);
729
730 if (net_device->destroy && num_outstanding_sends == 0)
731 wake_up(&net_device->wait_drain);
732
733 if (netif_tx_queue_stopped(netdev_get_tx_queue(ndev, q_idx)) &&
734 !net_device_ctx->start_remove &&
735 (hv_ringbuf_avail_percent(&channel->outbound) > RING_AVAIL_PERCENT_HIWATER ||
736 queue_sends < 1))
737 netif_tx_wake_queue(netdev_get_tx_queue(ndev, q_idx));
738}
739
699static void netvsc_send_completion(struct netvsc_device *net_device, 740static void netvsc_send_completion(struct netvsc_device *net_device,
700 struct vmbus_channel *incoming_channel, 741 struct vmbus_channel *incoming_channel,
701 struct hv_device *device, 742 struct hv_device *device,
702 struct vmpacket_descriptor *packet) 743 struct vmpacket_descriptor *packet)
703{ 744{
704 struct nvsp_message *nvsp_packet; 745 struct nvsp_message *nvsp_packet;
705 struct hv_netvsc_packet *nvsc_packet;
706 struct net_device *ndev = hv_get_drvdata(device); 746 struct net_device *ndev = hv_get_drvdata(device);
707 struct net_device_context *net_device_ctx = netdev_priv(ndev);
708 u32 send_index;
709 struct sk_buff *skb;
710 747
711 nvsp_packet = (struct nvsp_message *)((unsigned long)packet + 748 nvsp_packet = (struct nvsp_message *)((unsigned long)packet +
712 (packet->offset8 << 3)); 749 (packet->offset8 << 3));
713 750
714 if ((nvsp_packet->hdr.msg_type == NVSP_MSG_TYPE_INIT_COMPLETE) || 751 switch (nvsp_packet->hdr.msg_type) {
715 (nvsp_packet->hdr.msg_type == 752 case NVSP_MSG_TYPE_INIT_COMPLETE:
716 NVSP_MSG1_TYPE_SEND_RECV_BUF_COMPLETE) || 753 case NVSP_MSG1_TYPE_SEND_RECV_BUF_COMPLETE:
717 (nvsp_packet->hdr.msg_type == 754 case NVSP_MSG1_TYPE_SEND_SEND_BUF_COMPLETE:
718 NVSP_MSG1_TYPE_SEND_SEND_BUF_COMPLETE) || 755 case NVSP_MSG5_TYPE_SUBCHANNEL:
719 (nvsp_packet->hdr.msg_type ==
720 NVSP_MSG5_TYPE_SUBCHANNEL)) {
721 /* Copy the response back */ 756 /* Copy the response back */
722 memcpy(&net_device->channel_init_pkt, nvsp_packet, 757 memcpy(&net_device->channel_init_pkt, nvsp_packet,
723 sizeof(struct nvsp_message)); 758 sizeof(struct nvsp_message));
724 complete(&net_device->channel_init_wait); 759 complete(&net_device->channel_init_wait);
725 } else if (nvsp_packet->hdr.msg_type == 760 break;
726 NVSP_MSG1_TYPE_SEND_RNDIS_PKT_COMPLETE) {
727 int num_outstanding_sends;
728 u16 q_idx = 0;
729 struct vmbus_channel *channel = device->channel;
730 int queue_sends;
731
732 /* Get the send context */
733 skb = (struct sk_buff *)(unsigned long)packet->trans_id;
734
735 /* Notify the layer above us */
736 if (skb) {
737 nvsc_packet = (struct hv_netvsc_packet *) skb->cb;
738 send_index = nvsc_packet->send_buf_index;
739 if (send_index != NETVSC_INVALID_INDEX)
740 netvsc_free_send_slot(net_device, send_index);
741 q_idx = nvsc_packet->q_idx;
742 channel = incoming_channel;
743 dev_kfree_skb_any(skb);
744 }
745
746 num_outstanding_sends =
747 atomic_dec_return(&net_device->num_outstanding_sends);
748 queue_sends = atomic_dec_return(&net_device->
749 queue_sends[q_idx]);
750 761
751 if (net_device->destroy && num_outstanding_sends == 0) 762 case NVSP_MSG1_TYPE_SEND_RNDIS_PKT_COMPLETE:
752 wake_up(&net_device->wait_drain); 763 netvsc_send_tx_complete(net_device, incoming_channel,
764 device, packet);
765 break;
753 766
754 if (netif_tx_queue_stopped(netdev_get_tx_queue(ndev, q_idx)) && 767 default:
755 !net_device_ctx->start_remove && 768 netdev_err(ndev,
756 (hv_ringbuf_avail_percent(&channel->outbound) > 769 "Unknown send completion type %d received!!\n",
757 RING_AVAIL_PERCENT_HIWATER || queue_sends < 1)) 770 nvsp_packet->hdr.msg_type);
758 netif_tx_wake_queue(netdev_get_tx_queue(ndev, q_idx));
759 } else {
760 netdev_err(ndev, "Unknown send completion packet type- "
761 "%d received!!\n", nvsp_packet->hdr.msg_type);
762 } 771 }
763} 772}
764 773