diff options
Diffstat (limited to 'drivers/net/hyperv/netvsc.c')
-rw-r--r-- | drivers/net/hyperv/netvsc.c | 88 |
1 files changed, 59 insertions, 29 deletions
diff --git a/drivers/net/hyperv/netvsc.c b/drivers/net/hyperv/netvsc.c index 6909c322de4e..20e09174ff62 100644 --- a/drivers/net/hyperv/netvsc.c +++ b/drivers/net/hyperv/netvsc.c | |||
@@ -1128,6 +1128,39 @@ static inline void netvsc_receive_inband(struct hv_device *hdev, | |||
1128 | } | 1128 | } |
1129 | } | 1129 | } |
1130 | 1130 | ||
1131 | static void netvsc_process_raw_pkt(struct hv_device *device, | ||
1132 | struct vmbus_channel *channel, | ||
1133 | struct netvsc_device *net_device, | ||
1134 | struct net_device *ndev, | ||
1135 | u64 request_id, | ||
1136 | struct vmpacket_descriptor *desc) | ||
1137 | { | ||
1138 | struct nvsp_message *nvmsg; | ||
1139 | |||
1140 | nvmsg = (struct nvsp_message *)((unsigned long) | ||
1141 | desc + (desc->offset8 << 3)); | ||
1142 | |||
1143 | switch (desc->type) { | ||
1144 | case VM_PKT_COMP: | ||
1145 | netvsc_send_completion(net_device, channel, device, desc); | ||
1146 | break; | ||
1147 | |||
1148 | case VM_PKT_DATA_USING_XFER_PAGES: | ||
1149 | netvsc_receive(net_device, channel, device, desc); | ||
1150 | break; | ||
1151 | |||
1152 | case VM_PKT_DATA_INBAND: | ||
1153 | netvsc_receive_inband(device, net_device, nvmsg); | ||
1154 | break; | ||
1155 | |||
1156 | default: | ||
1157 | netdev_err(ndev, "unhandled packet type %d, tid %llx\n", | ||
1158 | desc->type, request_id); | ||
1159 | break; | ||
1160 | } | ||
1161 | } | ||
1162 | |||
1163 | |||
1131 | void netvsc_channel_cb(void *context) | 1164 | void netvsc_channel_cb(void *context) |
1132 | { | 1165 | { |
1133 | int ret; | 1166 | int ret; |
@@ -1140,7 +1173,7 @@ void netvsc_channel_cb(void *context) | |||
1140 | unsigned char *buffer; | 1173 | unsigned char *buffer; |
1141 | int bufferlen = NETVSC_PACKET_SIZE; | 1174 | int bufferlen = NETVSC_PACKET_SIZE; |
1142 | struct net_device *ndev; | 1175 | struct net_device *ndev; |
1143 | struct nvsp_message *nvmsg; | 1176 | bool need_to_commit = false; |
1144 | 1177 | ||
1145 | if (channel->primary_channel != NULL) | 1178 | if (channel->primary_channel != NULL) |
1146 | device = channel->primary_channel->device_obj; | 1179 | device = channel->primary_channel->device_obj; |
@@ -1154,39 +1187,36 @@ void netvsc_channel_cb(void *context) | |||
1154 | buffer = get_per_channel_state(channel); | 1187 | buffer = get_per_channel_state(channel); |
1155 | 1188 | ||
1156 | do { | 1189 | do { |
1190 | desc = get_next_pkt_raw(channel); | ||
1191 | if (desc != NULL) { | ||
1192 | netvsc_process_raw_pkt(device, | ||
1193 | channel, | ||
1194 | net_device, | ||
1195 | ndev, | ||
1196 | desc->trans_id, | ||
1197 | desc); | ||
1198 | |||
1199 | put_pkt_raw(channel, desc); | ||
1200 | need_to_commit = true; | ||
1201 | continue; | ||
1202 | } | ||
1203 | if (need_to_commit) { | ||
1204 | need_to_commit = false; | ||
1205 | commit_rd_index(channel); | ||
1206 | } | ||
1207 | |||
1157 | ret = vmbus_recvpacket_raw(channel, buffer, bufferlen, | 1208 | ret = vmbus_recvpacket_raw(channel, buffer, bufferlen, |
1158 | &bytes_recvd, &request_id); | 1209 | &bytes_recvd, &request_id); |
1159 | if (ret == 0) { | 1210 | if (ret == 0) { |
1160 | if (bytes_recvd > 0) { | 1211 | if (bytes_recvd > 0) { |
1161 | desc = (struct vmpacket_descriptor *)buffer; | 1212 | desc = (struct vmpacket_descriptor *)buffer; |
1162 | nvmsg = (struct nvsp_message *)((unsigned long) | 1213 | netvsc_process_raw_pkt(device, |
1163 | desc + (desc->offset8 << 3)); | 1214 | channel, |
1164 | switch (desc->type) { | 1215 | net_device, |
1165 | case VM_PKT_COMP: | 1216 | ndev, |
1166 | netvsc_send_completion(net_device, | 1217 | request_id, |
1167 | channel, | 1218 | desc); |
1168 | device, desc); | 1219 | |
1169 | break; | ||
1170 | |||
1171 | case VM_PKT_DATA_USING_XFER_PAGES: | ||
1172 | netvsc_receive(net_device, channel, | ||
1173 | device, desc); | ||
1174 | break; | ||
1175 | |||
1176 | case VM_PKT_DATA_INBAND: | ||
1177 | netvsc_receive_inband(device, | ||
1178 | net_device, | ||
1179 | nvmsg); | ||
1180 | break; | ||
1181 | |||
1182 | default: | ||
1183 | netdev_err(ndev, | ||
1184 | "unhandled packet type %d, " | ||
1185 | "tid %llx len %d\n", | ||
1186 | desc->type, request_id, | ||
1187 | bytes_recvd); | ||
1188 | break; | ||
1189 | } | ||
1190 | 1220 | ||
1191 | } else { | 1221 | } else { |
1192 | /* | 1222 | /* |