Commit bc304dd3 authored by Stephen Hemminger's avatar Stephen Hemminger Committed by David S. Miller

hv_netvsc: refactor completion function

Break the different cases, code is cleaner if broken up
Signed-off-by: default avatarStephen Hemminger <sthemmin@microsoft.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 0ab05141
...@@ -696,69 +696,78 @@ static inline void netvsc_free_send_slot(struct netvsc_device *net_device, ...@@ -696,69 +696,78 @@ static inline void netvsc_free_send_slot(struct netvsc_device *net_device,
sync_change_bit(index, net_device->send_section_map); sync_change_bit(index, net_device->send_section_map);
} }
static void netvsc_send_tx_complete(struct netvsc_device *net_device,
struct vmbus_channel *incoming_channel,
struct hv_device *device,
struct vmpacket_descriptor *packet)
{
struct sk_buff *skb = (struct sk_buff *)(unsigned long)packet->trans_id;
struct net_device *ndev = hv_get_drvdata(device);
struct net_device_context *net_device_ctx = netdev_priv(ndev);
struct vmbus_channel *channel = device->channel;
int num_outstanding_sends;
u16 q_idx = 0;
int queue_sends;
/* Notify the layer above us */
if (likely(skb)) {
struct hv_netvsc_packet *nvsc_packet
= (struct hv_netvsc_packet *)skb->cb;
u32 send_index = nvsc_packet->send_buf_index;
if (send_index != NETVSC_INVALID_INDEX)
netvsc_free_send_slot(net_device, send_index);
q_idx = nvsc_packet->q_idx;
channel = incoming_channel;
dev_kfree_skb_any(skb);
}
num_outstanding_sends =
atomic_dec_return(&net_device->num_outstanding_sends);
queue_sends = atomic_dec_return(&net_device->queue_sends[q_idx]);
if (net_device->destroy && num_outstanding_sends == 0)
wake_up(&net_device->wait_drain);
if (netif_tx_queue_stopped(netdev_get_tx_queue(ndev, q_idx)) &&
!net_device_ctx->start_remove &&
(hv_ringbuf_avail_percent(&channel->outbound) > RING_AVAIL_PERCENT_HIWATER ||
queue_sends < 1))
netif_tx_wake_queue(netdev_get_tx_queue(ndev, q_idx));
}
static void netvsc_send_completion(struct netvsc_device *net_device, static void netvsc_send_completion(struct netvsc_device *net_device,
struct vmbus_channel *incoming_channel, struct vmbus_channel *incoming_channel,
struct hv_device *device, struct hv_device *device,
struct vmpacket_descriptor *packet) struct vmpacket_descriptor *packet)
{ {
struct nvsp_message *nvsp_packet; struct nvsp_message *nvsp_packet;
struct hv_netvsc_packet *nvsc_packet;
struct net_device *ndev = hv_get_drvdata(device); struct net_device *ndev = hv_get_drvdata(device);
struct net_device_context *net_device_ctx = netdev_priv(ndev);
u32 send_index;
struct sk_buff *skb;
nvsp_packet = (struct nvsp_message *)((unsigned long)packet + nvsp_packet = (struct nvsp_message *)((unsigned long)packet +
(packet->offset8 << 3)); (packet->offset8 << 3));
if ((nvsp_packet->hdr.msg_type == NVSP_MSG_TYPE_INIT_COMPLETE) || switch (nvsp_packet->hdr.msg_type) {
(nvsp_packet->hdr.msg_type == case NVSP_MSG_TYPE_INIT_COMPLETE:
NVSP_MSG1_TYPE_SEND_RECV_BUF_COMPLETE) || case NVSP_MSG1_TYPE_SEND_RECV_BUF_COMPLETE:
(nvsp_packet->hdr.msg_type == case NVSP_MSG1_TYPE_SEND_SEND_BUF_COMPLETE:
NVSP_MSG1_TYPE_SEND_SEND_BUF_COMPLETE) || case NVSP_MSG5_TYPE_SUBCHANNEL:
(nvsp_packet->hdr.msg_type ==
NVSP_MSG5_TYPE_SUBCHANNEL)) {
/* Copy the response back */ /* Copy the response back */
memcpy(&net_device->channel_init_pkt, nvsp_packet, memcpy(&net_device->channel_init_pkt, nvsp_packet,
sizeof(struct nvsp_message)); sizeof(struct nvsp_message));
complete(&net_device->channel_init_wait); complete(&net_device->channel_init_wait);
} else if (nvsp_packet->hdr.msg_type == break;
NVSP_MSG1_TYPE_SEND_RNDIS_PKT_COMPLETE) {
int num_outstanding_sends;
u16 q_idx = 0;
struct vmbus_channel *channel = device->channel;
int queue_sends;
/* Get the send context */
skb = (struct sk_buff *)(unsigned long)packet->trans_id;
/* Notify the layer above us */
if (skb) {
nvsc_packet = (struct hv_netvsc_packet *) skb->cb;
send_index = nvsc_packet->send_buf_index;
if (send_index != NETVSC_INVALID_INDEX)
netvsc_free_send_slot(net_device, send_index);
q_idx = nvsc_packet->q_idx;
channel = incoming_channel;
dev_kfree_skb_any(skb);
}
num_outstanding_sends =
atomic_dec_return(&net_device->num_outstanding_sends);
queue_sends = atomic_dec_return(&net_device->
queue_sends[q_idx]);
if (net_device->destroy && num_outstanding_sends == 0) case NVSP_MSG1_TYPE_SEND_RNDIS_PKT_COMPLETE:
wake_up(&net_device->wait_drain); netvsc_send_tx_complete(net_device, incoming_channel,
device, packet);
break;
if (netif_tx_queue_stopped(netdev_get_tx_queue(ndev, q_idx)) && default:
!net_device_ctx->start_remove && netdev_err(ndev,
(hv_ringbuf_avail_percent(&channel->outbound) > "Unknown send completion type %d received!!\n",
RING_AVAIL_PERCENT_HIWATER || queue_sends < 1)) nvsp_packet->hdr.msg_type);
netif_tx_wake_queue(netdev_get_tx_queue(ndev, q_idx));
} else {
netdev_err(ndev, "Unknown send completion packet type- "
"%d received!!\n", nvsp_packet->hdr.msg_type);
} }
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment