]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/dev/hyperv/netvsc/hv_net_vsc.c
hyperv/hn: Simplify NDIS initialization.
[FreeBSD/FreeBSD.git] / sys / dev / hyperv / netvsc / hv_net_vsc.c
1 /*-
2  * Copyright (c) 2009-2012,2016 Microsoft Corp.
3  * Copyright (c) 2010-2012 Citrix Inc.
4  * Copyright (c) 2012 NetApp Inc.
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice unmodified, this list of conditions, and the following
12  *    disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in the
15  *    documentation and/or other materials provided with the distribution.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27  *
28  * $FreeBSD$
29  */
30
31 /**
32  * HyperV vmbus network VSC (virtual services client) module
33  *
34  */
35
36
37 #include <sys/param.h>
38 #include <sys/kernel.h>
39 #include <sys/socket.h>
40 #include <sys/lock.h>
41 #include <net/if.h>
42 #include <net/if_var.h>
43 #include <net/if_arp.h>
44 #include <machine/bus.h>
45 #include <machine/atomic.h>
46
47 #include <dev/hyperv/include/hyperv.h>
48 #include <dev/hyperv/include/vmbus_xact.h>
49 #include <dev/hyperv/netvsc/hv_net_vsc.h>
50 #include <dev/hyperv/netvsc/hv_rndis.h>
51 #include <dev/hyperv/netvsc/hv_rndis_filter.h>
52 #include <dev/hyperv/netvsc/if_hnreg.h>
53
54 MALLOC_DEFINE(M_NETVSC, "netvsc", "Hyper-V netvsc driver");
55
56 /*
57  * Forward declarations
58  */
59 static void hv_nv_on_channel_callback(struct vmbus_channel *chan,
60     void *xrxr);
61 static int  hv_nv_init_send_buffer_with_net_vsp(struct hn_softc *sc);
62 static int  hv_nv_init_rx_buffer_with_net_vsp(struct hn_softc *);
63 static int  hv_nv_destroy_send_buffer(netvsc_dev *net_dev);
64 static int  hv_nv_destroy_rx_buffer(netvsc_dev *net_dev);
65 static int  hv_nv_connect_to_vsp(struct hn_softc *sc);
66 static void hv_nv_on_send_completion(netvsc_dev *net_dev,
67     struct vmbus_channel *, const struct vmbus_chanpkt_hdr *pkt);
68 static void hv_nv_on_receive_completion(struct vmbus_channel *chan,
69     uint64_t tid, uint32_t status);
70 static void hv_nv_on_receive(netvsc_dev *net_dev,
71     struct hn_rx_ring *rxr, struct vmbus_channel *chan,
72     const struct vmbus_chanpkt_hdr *pkt);
73 static void hn_nvs_sent_none(struct hn_send_ctx *sndc,
74     struct netvsc_dev_ *net_dev, struct vmbus_channel *chan,
75     const struct nvsp_msg_ *msg, int);
76 static void hn_nvs_sent_xact(struct hn_send_ctx *sndc,
77     struct netvsc_dev_ *net_dev, struct vmbus_channel *chan,
78     const struct nvsp_msg_ *msg, int dlen);
79
80 static struct hn_send_ctx       hn_send_ctx_none =
81     HN_SEND_CTX_INITIALIZER(hn_nvs_sent_none, NULL);
82
83 /*
84  *
85  */
86 static inline netvsc_dev *
87 hv_nv_alloc_net_device(struct hn_softc *sc)
88 {
89         netvsc_dev *net_dev;
90
91         net_dev = malloc(sizeof(netvsc_dev), M_NETVSC, M_WAITOK | M_ZERO);
92
93         net_dev->sc = sc;
94         net_dev->destroy = FALSE;
95         sc->net_dev = net_dev;
96
97         return (net_dev);
98 }
99
100 /*
101  * XXX unnecessary; nuke it.
102  */
103 static inline netvsc_dev *
104 hv_nv_get_outbound_net_device(struct hn_softc *sc)
105 {
106         return sc->net_dev;
107 }
108
109 /*
110  * XXX unnecessary; nuke it.
111  */
112 static inline netvsc_dev *
113 hv_nv_get_inbound_net_device(struct hn_softc *sc)
114 {
115         return sc->net_dev;
116 }
117
118 int
119 hv_nv_get_next_send_section(netvsc_dev *net_dev)
120 {
121         unsigned long bitsmap_words = net_dev->bitsmap_words;
122         unsigned long *bitsmap = net_dev->send_section_bitsmap;
123         unsigned long idx;
124         int ret = NVSP_1_CHIMNEY_SEND_INVALID_SECTION_INDEX;
125         int i;
126
127         for (i = 0; i < bitsmap_words; i++) {
128                 idx = ffsl(~bitsmap[i]);
129                 if (0 == idx)
130                         continue;
131
132                 idx--;
133                 KASSERT(i * BITS_PER_LONG + idx < net_dev->send_section_count,
134                     ("invalid i %d and idx %lu", i, idx));
135
136                 if (atomic_testandset_long(&bitsmap[i], idx))
137                         continue;
138
139                 ret = i * BITS_PER_LONG + idx;
140                 break;
141         }
142
143         return (ret);
144 }
145
146 /*
147  * Net VSC initialize receive buffer with net VSP
148  * 
149  * Net VSP:  Network virtual services client, also known as the
150  *     Hyper-V extensible switch and the synthetic data path.
151  */
152 static int 
153 hv_nv_init_rx_buffer_with_net_vsp(struct hn_softc *sc)
154 {
155         struct hn_send_ctx sndc;
156         netvsc_dev *net_dev;
157         nvsp_msg *init_pkt;
158         int ret = 0;
159
160         net_dev = hv_nv_get_outbound_net_device(sc);
161         if (!net_dev) {
162                 return (ENODEV);
163         }
164
165         net_dev->rx_buf = hyperv_dmamem_alloc(bus_get_dma_tag(sc->hn_dev),
166             PAGE_SIZE, 0, net_dev->rx_buf_size, &net_dev->rxbuf_dma,
167             BUS_DMA_WAITOK | BUS_DMA_ZERO);
168         if (net_dev->rx_buf == NULL) {
169                 device_printf(sc->hn_dev, "allocate rxbuf failed\n");
170                 return ENOMEM;
171         }
172
173         /*
174          * Connect the RXBUF GPADL to the primary channel.
175          *
176          * NOTE:
177          * Only primary channel has RXBUF connected to it.  Sub-channels
178          * just share this RXBUF.
179          */
180         ret = vmbus_chan_gpadl_connect(sc->hn_prichan,
181             net_dev->rxbuf_dma.hv_paddr, net_dev->rx_buf_size,
182             &net_dev->rx_buf_gpadl_handle);
183         if (ret != 0) {
184                 device_printf(sc->hn_dev, "rxbuf gpadl connect failed: %d\n",
185                     ret);
186                 goto cleanup;
187         }
188         
189         /* sema_wait(&ext->channel_init_sema); KYS CHECK */
190
191         /* Notify the NetVsp of the gpadl handle */
192         init_pkt = &net_dev->channel_init_packet;
193
194         memset(init_pkt, 0, sizeof(nvsp_msg));
195
196         init_pkt->hdr.msg_type = nvsp_msg_1_type_send_rx_buf;
197         init_pkt->msgs.vers_1_msgs.send_rx_buf.gpadl_handle =
198             net_dev->rx_buf_gpadl_handle;
199         init_pkt->msgs.vers_1_msgs.send_rx_buf.id =
200             NETVSC_RECEIVE_BUFFER_ID;
201
202         /* Send the gpadl notification request */
203
204         hn_send_ctx_init_simple(&sndc, hn_nvs_sent_wakeup, NULL);
205         ret = vmbus_chan_send(sc->hn_prichan,
206             VMBUS_CHANPKT_TYPE_INBAND, VMBUS_CHANPKT_FLAG_RC,
207             init_pkt, sizeof(nvsp_msg), (uint64_t)(uintptr_t)&sndc);
208         if (ret != 0) {
209                 goto cleanup;
210         }
211
212         sema_wait(&net_dev->channel_init_sema);
213
214         /* Check the response */
215         if (init_pkt->msgs.vers_1_msgs.send_rx_buf_complete.status
216             != nvsp_status_success) {
217                 ret = EINVAL;
218                 goto cleanup;
219         }
220
221         net_dev->rx_section_count =
222             init_pkt->msgs.vers_1_msgs.send_rx_buf_complete.num_sections;
223
224         net_dev->rx_sections = malloc(net_dev->rx_section_count *
225             sizeof(nvsp_1_rx_buf_section), M_NETVSC, M_WAITOK);
226         memcpy(net_dev->rx_sections, 
227             init_pkt->msgs.vers_1_msgs.send_rx_buf_complete.sections,
228             net_dev->rx_section_count * sizeof(nvsp_1_rx_buf_section));
229
230
231         /*
232          * For first release, there should only be 1 section that represents
233          * the entire receive buffer
234          */
235         if (net_dev->rx_section_count != 1
236             || net_dev->rx_sections->offset != 0) {
237                 ret = EINVAL;
238                 goto cleanup;
239         }
240
241         goto exit;
242
243 cleanup:
244         hv_nv_destroy_rx_buffer(net_dev);
245         
246 exit:
247         return (ret);
248 }
249
250 /*
251  * Net VSC initialize send buffer with net VSP
252  */
253 static int 
254 hv_nv_init_send_buffer_with_net_vsp(struct hn_softc *sc)
255 {
256         struct hn_send_ctx sndc;
257         netvsc_dev *net_dev;
258         nvsp_msg *init_pkt;
259         int ret = 0;
260
261         net_dev = hv_nv_get_outbound_net_device(sc);
262         if (!net_dev) {
263                 return (ENODEV);
264         }
265
266         net_dev->send_buf = hyperv_dmamem_alloc(bus_get_dma_tag(sc->hn_dev),
267             PAGE_SIZE, 0, net_dev->send_buf_size, &net_dev->txbuf_dma,
268             BUS_DMA_WAITOK | BUS_DMA_ZERO);
269         if (net_dev->send_buf == NULL) {
270                 device_printf(sc->hn_dev, "allocate chimney txbuf failed\n");
271                 return ENOMEM;
272         }
273
274         /*
275          * Connect chimney sending buffer GPADL to the primary channel.
276          *
277          * NOTE:
278          * Only primary channel has chimney sending buffer connected to it.
279          * Sub-channels just share this chimney sending buffer.
280          */
281         ret = vmbus_chan_gpadl_connect(sc->hn_prichan,
282             net_dev->txbuf_dma.hv_paddr, net_dev->send_buf_size,
283             &net_dev->send_buf_gpadl_handle);
284         if (ret != 0) {
285                 device_printf(sc->hn_dev, "chimney sending buffer gpadl "
286                     "connect failed: %d\n", ret);
287                 goto cleanup;
288         }
289
290         /* Notify the NetVsp of the gpadl handle */
291
292         init_pkt = &net_dev->channel_init_packet;
293
294         memset(init_pkt, 0, sizeof(nvsp_msg));
295
296         init_pkt->hdr.msg_type = nvsp_msg_1_type_send_send_buf;
297         init_pkt->msgs.vers_1_msgs.send_rx_buf.gpadl_handle =
298             net_dev->send_buf_gpadl_handle;
299         init_pkt->msgs.vers_1_msgs.send_rx_buf.id =
300             NETVSC_SEND_BUFFER_ID;
301
302         /* Send the gpadl notification request */
303
304         hn_send_ctx_init_simple(&sndc, hn_nvs_sent_wakeup, NULL);
305         ret = vmbus_chan_send(sc->hn_prichan,
306             VMBUS_CHANPKT_TYPE_INBAND, VMBUS_CHANPKT_FLAG_RC,
307             init_pkt, sizeof(nvsp_msg), (uint64_t)(uintptr_t)&sndc);
308         if (ret != 0) {
309                 goto cleanup;
310         }
311
312         sema_wait(&net_dev->channel_init_sema);
313
314         /* Check the response */
315         if (init_pkt->msgs.vers_1_msgs.send_send_buf_complete.status
316             != nvsp_status_success) {
317                 ret = EINVAL;
318                 goto cleanup;
319         }
320
321         net_dev->send_section_size =
322             init_pkt->msgs.vers_1_msgs.send_send_buf_complete.section_size;
323         net_dev->send_section_count =
324             net_dev->send_buf_size / net_dev->send_section_size;
325         net_dev->bitsmap_words = howmany(net_dev->send_section_count,
326             BITS_PER_LONG);
327         net_dev->send_section_bitsmap =
328             malloc(net_dev->bitsmap_words * sizeof(long), M_NETVSC,
329             M_WAITOK | M_ZERO);
330
331         goto exit;
332
333 cleanup:
334         hv_nv_destroy_send_buffer(net_dev);
335         
336 exit:
337         return (ret);
338 }
339
340 /*
341  * Net VSC destroy receive buffer
342  */
343 static int
344 hv_nv_destroy_rx_buffer(netvsc_dev *net_dev)
345 {
346         nvsp_msg *revoke_pkt;
347         int ret = 0;
348
349         /*
350          * If we got a section count, it means we received a
351          * send_rx_buf_complete msg 
352          * (ie sent nvsp_msg_1_type_send_rx_buf msg) therefore,
353          * we need to send a revoke msg here
354          */
355         if (net_dev->rx_section_count) {
356                 /* Send the revoke receive buffer */
357                 revoke_pkt = &net_dev->revoke_packet;
358                 memset(revoke_pkt, 0, sizeof(nvsp_msg));
359
360                 revoke_pkt->hdr.msg_type = nvsp_msg_1_type_revoke_rx_buf;
361                 revoke_pkt->msgs.vers_1_msgs.revoke_rx_buf.id =
362                     NETVSC_RECEIVE_BUFFER_ID;
363
364                 ret = vmbus_chan_send(net_dev->sc->hn_prichan,
365                     VMBUS_CHANPKT_TYPE_INBAND, 0, revoke_pkt, sizeof(nvsp_msg),
366                     (uint64_t)(uintptr_t)&hn_send_ctx_none);
367                 /*
368                  * If we failed here, we might as well return and have a leak 
369                  * rather than continue and a bugchk
370                  */
371                 if (ret != 0) {
372                         return (ret);
373                 }
374         }
375                 
376         /* Tear down the gpadl on the vsp end */
377         if (net_dev->rx_buf_gpadl_handle) {
378                 ret = vmbus_chan_gpadl_disconnect(net_dev->sc->hn_prichan,
379                     net_dev->rx_buf_gpadl_handle);
380                 /*
381                  * If we failed here, we might as well return and have a leak 
382                  * rather than continue and a bugchk
383                  */
384                 if (ret != 0) {
385                         return (ret);
386                 }
387                 net_dev->rx_buf_gpadl_handle = 0;
388         }
389
390         if (net_dev->rx_buf) {
391                 /* Free up the receive buffer */
392                 hyperv_dmamem_free(&net_dev->rxbuf_dma, net_dev->rx_buf);
393                 net_dev->rx_buf = NULL;
394         }
395
396         if (net_dev->rx_sections) {
397                 free(net_dev->rx_sections, M_NETVSC);
398                 net_dev->rx_sections = NULL;
399                 net_dev->rx_section_count = 0;
400         }
401
402         return (ret);
403 }
404
405 /*
406  * Net VSC destroy send buffer
407  */
408 static int
409 hv_nv_destroy_send_buffer(netvsc_dev *net_dev)
410 {
411         nvsp_msg *revoke_pkt;
412         int ret = 0;
413
414         /*
415          * If we got a section count, it means we received a
416          * send_rx_buf_complete msg 
417          * (ie sent nvsp_msg_1_type_send_rx_buf msg) therefore,
418          * we need to send a revoke msg here
419          */
420         if (net_dev->send_section_size) {
421                 /* Send the revoke send buffer */
422                 revoke_pkt = &net_dev->revoke_packet;
423                 memset(revoke_pkt, 0, sizeof(nvsp_msg));
424
425                 revoke_pkt->hdr.msg_type =
426                     nvsp_msg_1_type_revoke_send_buf;
427                 revoke_pkt->msgs.vers_1_msgs.revoke_send_buf.id =
428                     NETVSC_SEND_BUFFER_ID;
429
430                 ret = vmbus_chan_send(net_dev->sc->hn_prichan,
431                     VMBUS_CHANPKT_TYPE_INBAND, 0, revoke_pkt, sizeof(nvsp_msg),
432                     (uint64_t)(uintptr_t)&hn_send_ctx_none);
433                 /*
434                  * If we failed here, we might as well return and have a leak 
435                  * rather than continue and a bugchk
436                  */
437                 if (ret != 0) {
438                         return (ret);
439                 }
440         }
441                 
442         /* Tear down the gpadl on the vsp end */
443         if (net_dev->send_buf_gpadl_handle) {
444                 ret = vmbus_chan_gpadl_disconnect(net_dev->sc->hn_prichan,
445                     net_dev->send_buf_gpadl_handle);
446
447                 /*
448                  * If we failed here, we might as well return and have a leak 
449                  * rather than continue and a bugchk
450                  */
451                 if (ret != 0) {
452                         return (ret);
453                 }
454                 net_dev->send_buf_gpadl_handle = 0;
455         }
456
457         if (net_dev->send_buf) {
458                 /* Free up the receive buffer */
459                 hyperv_dmamem_free(&net_dev->txbuf_dma, net_dev->send_buf);
460                 net_dev->send_buf = NULL;
461         }
462
463         if (net_dev->send_section_bitsmap) {
464                 free(net_dev->send_section_bitsmap, M_NETVSC);
465         }
466
467         return (ret);
468 }
469
470 static int
471 hv_nv_negotiate_nvsp_protocol(struct hn_softc *sc, netvsc_dev *net_dev,
472     uint32_t nvs_ver)
473 {
474         struct hn_send_ctx sndc;
475         struct vmbus_xact *xact;
476         struct hn_nvs_init *init;
477         const struct hn_nvs_init_resp *resp;
478         size_t resp_len;
479         uint32_t status;
480         int error;
481
482         xact = vmbus_xact_get(sc->hn_xact, sizeof(*init));
483         if (xact == NULL) {
484                 if_printf(sc->hn_ifp, "no xact for nvs init\n");
485                 return (ENXIO);
486         }
487
488         init = vmbus_xact_req_data(xact);
489         init->nvs_type = HN_NVS_TYPE_INIT;
490         init->nvs_ver_min = nvs_ver;
491         init->nvs_ver_max = nvs_ver;
492
493         vmbus_xact_activate(xact);
494         hn_send_ctx_init_simple(&sndc, hn_nvs_sent_xact, xact);
495
496         error = vmbus_chan_send(sc->hn_prichan,
497             VMBUS_CHANPKT_TYPE_INBAND, VMBUS_CHANPKT_FLAG_RC,
498             init, sizeof(*init), (uint64_t)(uintptr_t)&sndc);
499         if (error) {
500                 if_printf(sc->hn_ifp, "send nvs init failed: %d\n", error);
501                 vmbus_xact_deactivate(xact);
502                 vmbus_xact_put(xact);
503                 return (error);
504         }
505
506         resp = vmbus_xact_wait(xact, &resp_len);
507         if (resp_len < sizeof(*resp)) {
508                 if_printf(sc->hn_ifp, "invalid init resp length %zu\n",
509                     resp_len);
510                 vmbus_xact_put(xact);
511                 return (EINVAL);
512         }
513         if (resp->nvs_type != HN_NVS_TYPE_INIT_RESP) {
514                 if_printf(sc->hn_ifp, "not init resp, type %u\n",
515                     resp->nvs_type);
516                 vmbus_xact_put(xact);
517                 return (EINVAL);
518         }
519
520         status = resp->nvs_status;
521         vmbus_xact_put(xact);
522
523         if (status != HN_NVS_STATUS_OK) {
524                 if_printf(sc->hn_ifp, "nvs init failed for ver 0x%x\n",
525                     nvs_ver);
526                 return (EINVAL);
527         }
528         return (0);
529 }
530
531 /*
532  * Send NDIS version 2 config packet containing MTU.
533  *
534  * Not valid for NDIS version 1.
535  */
536 static int
537 hv_nv_send_ndis_config(struct hn_softc *sc, uint32_t mtu)
538 {
539         struct hn_nvs_ndis_conf conf;
540         int error;
541
542         memset(&conf, 0, sizeof(conf));
543         conf.nvs_type = HN_NVS_TYPE_NDIS_CONF;
544         conf.nvs_mtu = mtu;
545         conf.nvs_caps = HN_NVS_NDIS_CONF_VLAN;
546
547         error = vmbus_chan_send(sc->hn_prichan, VMBUS_CHANPKT_TYPE_INBAND, 0,
548             &conf, sizeof(conf), (uint64_t)(uintptr_t)&hn_send_ctx_none);
549         if (error)
550                 if_printf(sc->hn_ifp, "send nvs ndis conf failed: %d\n", error);
551         return (error);
552 }
553
554 /*
555  * Net VSC connect to VSP
556  */
557 static int
558 hv_nv_connect_to_vsp(struct hn_softc *sc)
559 {
560         netvsc_dev *net_dev;
561         uint32_t protocol_list[] = { NVSP_PROTOCOL_VERSION_1,
562             NVSP_PROTOCOL_VERSION_2,
563             NVSP_PROTOCOL_VERSION_4,
564             NVSP_PROTOCOL_VERSION_5 };
565         int i;
566         int protocol_number = nitems(protocol_list);
567         int ret = 0;
568         device_t dev = sc->hn_dev;
569         struct ifnet *ifp = sc->hn_ifp;
570         struct hn_nvs_ndis_init ndis;
571
572         net_dev = hv_nv_get_outbound_net_device(sc);
573
574         /*
575          * Negotiate the NVSP version.  Try the latest NVSP first.
576          */
577         for (i = protocol_number - 1; i >= 0; i--) {
578                 if (hv_nv_negotiate_nvsp_protocol(sc, net_dev,
579                     protocol_list[i]) == 0) {
580                         net_dev->nvsp_version = protocol_list[i];
581                         if (bootverbose)
582                                 device_printf(dev, "Netvsc: got version 0x%x\n",
583                                     net_dev->nvsp_version);
584                         break;
585                 }
586         }
587
588         if (i < 0) {
589                 if (bootverbose)
590                         device_printf(dev, "failed to negotiate a valid "
591                             "protocol.\n");
592                 return (EPROTO);
593         }
594
595         /*
596          * Set the MTU if supported by this NVSP protocol version
597          * This needs to be right after the NVSP init message per Haiyang
598          */
599         if (net_dev->nvsp_version >= NVSP_PROTOCOL_VERSION_2)
600                 ret = hv_nv_send_ndis_config(sc, ifp->if_mtu);
601
602         /*
603          * Initialize NDIS.
604          */
605
606         memset(&ndis, 0, sizeof(ndis));
607         ndis.nvs_type = HN_NVS_TYPE_NDIS_INIT;
608         ndis.nvs_ndis_major = NDIS_VERSION_MAJOR_6;
609         if (net_dev->nvsp_version <= NVSP_PROTOCOL_VERSION_4)
610                 ndis.nvs_ndis_minor = NDIS_VERSION_MINOR_1;
611         else
612                 ndis.nvs_ndis_minor = NDIS_VERSION_MINOR_30;
613
614         ret = vmbus_chan_send(sc->hn_prichan, VMBUS_CHANPKT_TYPE_INBAND, 0,
615             &ndis, sizeof(ndis), (uint64_t)(uintptr_t)&hn_send_ctx_none);
616         if (ret != 0) {
617                 if_printf(sc->hn_ifp, "send nvs ndis init failed: %d\n", ret);
618                 goto cleanup;
619         }
620
621         /* Post the big receive buffer to NetVSP */
622         if (net_dev->nvsp_version <= NVSP_PROTOCOL_VERSION_2)
623                 net_dev->rx_buf_size = NETVSC_RECEIVE_BUFFER_SIZE_LEGACY;
624         else
625                 net_dev->rx_buf_size = NETVSC_RECEIVE_BUFFER_SIZE;
626         net_dev->send_buf_size = NETVSC_SEND_BUFFER_SIZE;
627
628         ret = hv_nv_init_rx_buffer_with_net_vsp(sc);
629         if (ret == 0)
630                 ret = hv_nv_init_send_buffer_with_net_vsp(sc);
631
632 cleanup:
633         return (ret);
634 }
635
636 /*
637  * Net VSC disconnect from VSP
638  */
639 static void
640 hv_nv_disconnect_from_vsp(netvsc_dev *net_dev)
641 {
642         hv_nv_destroy_rx_buffer(net_dev);
643         hv_nv_destroy_send_buffer(net_dev);
644 }
645
646 void
647 hv_nv_subchan_attach(struct vmbus_channel *chan, struct hn_rx_ring *rxr)
648 {
649         KASSERT(rxr->hn_rx_idx == vmbus_chan_subidx(chan),
650             ("chan%u subidx %u, rxr%d mismatch",
651              vmbus_chan_id(chan), vmbus_chan_subidx(chan), rxr->hn_rx_idx));
652         vmbus_chan_open(chan, NETVSC_DEVICE_RING_BUFFER_SIZE,
653             NETVSC_DEVICE_RING_BUFFER_SIZE, NULL, 0,
654             hv_nv_on_channel_callback, rxr);
655 }
656
657 /*
658  * Net VSC on device add
659  * 
660  * Callback when the device belonging to this driver is added
661  */
662 netvsc_dev *
663 hv_nv_on_device_add(struct hn_softc *sc, void *additional_info,
664     struct hn_rx_ring *rxr)
665 {
666         struct vmbus_channel *chan = sc->hn_prichan;
667         netvsc_dev *net_dev;
668         int ret = 0;
669
670         net_dev = hv_nv_alloc_net_device(sc);
671         if (net_dev == NULL)
672                 return NULL;
673
674         /* Initialize the NetVSC channel extension */
675
676         sema_init(&net_dev->channel_init_sema, 0, "netdev_sema");
677
678         /*
679          * Open the channel
680          */
681         KASSERT(rxr->hn_rx_idx == vmbus_chan_subidx(chan),
682             ("chan%u subidx %u, rxr%d mismatch",
683              vmbus_chan_id(chan), vmbus_chan_subidx(chan), rxr->hn_rx_idx));
684         ret = vmbus_chan_open(chan,
685             NETVSC_DEVICE_RING_BUFFER_SIZE, NETVSC_DEVICE_RING_BUFFER_SIZE,
686             NULL, 0, hv_nv_on_channel_callback, rxr);
687         if (ret != 0)
688                 goto cleanup;
689
690         /*
691          * Connect with the NetVsp
692          */
693         ret = hv_nv_connect_to_vsp(sc);
694         if (ret != 0)
695                 goto close;
696
697         return (net_dev);
698
699 close:
700         /* Now, we can close the channel safely */
701         vmbus_chan_close(chan);
702
703 cleanup:
704         /*
705          * Free the packet buffers on the netvsc device packet queue.
706          * Release other resources.
707          */
708         sema_destroy(&net_dev->channel_init_sema);
709         free(net_dev, M_NETVSC);
710
711         return (NULL);
712 }
713
714 /*
715  * Net VSC on device remove
716  */
717 int
718 hv_nv_on_device_remove(struct hn_softc *sc, boolean_t destroy_channel)
719 {
720         netvsc_dev *net_dev = sc->net_dev;;
721         
722         /* Stop outbound traffic ie sends and receives completions */
723         net_dev->destroy = TRUE;
724
725         hv_nv_disconnect_from_vsp(net_dev);
726
727         /* At this point, no one should be accessing net_dev except in here */
728
729         /* Now, we can close the channel safely */
730
731         vmbus_chan_close(sc->hn_prichan);
732
733         sema_destroy(&net_dev->channel_init_sema);
734         free(net_dev, M_NETVSC);
735
736         return (0);
737 }
738
739 void
740 hn_nvs_sent_wakeup(struct hn_send_ctx *sndc __unused,
741     struct netvsc_dev_ *net_dev, struct vmbus_channel *chan __unused,
742     const struct nvsp_msg_ *msg, int dlen __unused)
743 {
744         /* Copy the response back */
745         memcpy(&net_dev->channel_init_packet, msg, sizeof(nvsp_msg));
746         sema_post(&net_dev->channel_init_sema);
747 }
748
749 static void
750 hn_nvs_sent_xact(struct hn_send_ctx *sndc,
751     struct netvsc_dev_ *net_dev __unused, struct vmbus_channel *chan __unused,
752     const struct nvsp_msg_ *msg, int dlen)
753 {
754
755         vmbus_xact_wakeup(sndc->hn_cbarg, msg, dlen);
756 }
757
758 static void
759 hn_nvs_sent_none(struct hn_send_ctx *sndc __unused,
760     struct netvsc_dev_ *net_dev __unused, struct vmbus_channel *chan __unused,
761     const struct nvsp_msg_ *msg __unused, int dlen __unused)
762 {
763         /* EMPTY */
764 }
765
766 void
767 hn_chim_free(struct netvsc_dev_ *net_dev, uint32_t chim_idx)
768 {
769         u_long mask;
770         uint32_t idx;
771
772         idx = chim_idx / BITS_PER_LONG;
773         KASSERT(idx < net_dev->bitsmap_words,
774             ("invalid chimney index 0x%x", chim_idx));
775
776         mask = 1UL << (chim_idx % BITS_PER_LONG);
777         KASSERT(net_dev->send_section_bitsmap[idx] & mask,
778             ("index bitmap 0x%lx, chimney index %u, "
779              "bitmap idx %d, bitmask 0x%lx",
780              net_dev->send_section_bitsmap[idx], chim_idx, idx, mask));
781
782         atomic_clear_long(&net_dev->send_section_bitsmap[idx], mask);
783 }
784
785 /*
786  * Net VSC on send completion
787  */
788 static void
789 hv_nv_on_send_completion(netvsc_dev *net_dev, struct vmbus_channel *chan,
790     const struct vmbus_chanpkt_hdr *pkt)
791 {
792         struct hn_send_ctx *sndc;
793
794         sndc = (struct hn_send_ctx *)(uintptr_t)pkt->cph_xactid;
795         sndc->hn_cb(sndc, net_dev, chan, VMBUS_CHANPKT_CONST_DATA(pkt),
796             VMBUS_CHANPKT_DATALEN(pkt));
797         /*
798          * NOTE:
799          * 'sndc' CAN NOT be accessed anymore, since it can be freed by
800          * its callback.
801          */
802 }
803
804 /*
805  * Net VSC on send
806  * Sends a packet on the specified Hyper-V device.
807  * Returns 0 on success, non-zero on failure.
808  */
809 int
810 hv_nv_on_send(struct vmbus_channel *chan, bool is_data_pkt,
811     struct hn_send_ctx *sndc, struct vmbus_gpa *gpa, int gpa_cnt)
812 {
813         nvsp_msg send_msg;
814         int ret;
815
816         send_msg.hdr.msg_type = nvsp_msg_1_type_send_rndis_pkt;
817         if (is_data_pkt) {
818                 /* 0 is RMC_DATA */
819                 send_msg.msgs.vers_1_msgs.send_rndis_pkt.chan_type = 0;
820         } else {
821                 /* 1 is RMC_CONTROL */
822                 send_msg.msgs.vers_1_msgs.send_rndis_pkt.chan_type = 1;
823         }
824
825         send_msg.msgs.vers_1_msgs.send_rndis_pkt.send_buf_section_idx =
826             sndc->hn_chim_idx;
827         send_msg.msgs.vers_1_msgs.send_rndis_pkt.send_buf_section_size =
828             sndc->hn_chim_sz;
829
830         if (gpa_cnt) {
831                 ret = vmbus_chan_send_sglist(chan, gpa, gpa_cnt,
832                     &send_msg, sizeof(nvsp_msg), (uint64_t)(uintptr_t)sndc);
833         } else {
834                 ret = vmbus_chan_send(chan,
835                     VMBUS_CHANPKT_TYPE_INBAND, VMBUS_CHANPKT_FLAG_RC,
836                     &send_msg, sizeof(nvsp_msg), (uint64_t)(uintptr_t)sndc);
837         }
838
839         return (ret);
840 }
841
842 /*
843  * Net VSC on receive
844  *
845  * In the FreeBSD Hyper-V virtual world, this function deals exclusively
846  * with virtual addresses.
847  */
848 static void
849 hv_nv_on_receive(netvsc_dev *net_dev, struct hn_rx_ring *rxr,
850     struct vmbus_channel *chan, const struct vmbus_chanpkt_hdr *pkthdr)
851 {
852         const struct vmbus_chanpkt_rxbuf *pkt;
853         const nvsp_msg *nvsp_msg_pkt;
854         netvsc_packet vsc_pkt;
855         netvsc_packet *net_vsc_pkt = &vsc_pkt;
856         int count = 0;
857         int i = 0;
858         int status = nvsp_status_success;
859
860         nvsp_msg_pkt = VMBUS_CHANPKT_CONST_DATA(pkthdr);
861
862         /* Make sure this is a valid nvsp packet */
863         if (nvsp_msg_pkt->hdr.msg_type != nvsp_msg_1_type_send_rndis_pkt) {
864                 if_printf(rxr->hn_ifp, "packet hdr type %u is invalid!\n",
865                     nvsp_msg_pkt->hdr.msg_type);
866                 return;
867         }
868         
869         pkt = (const struct vmbus_chanpkt_rxbuf *)pkthdr;
870
871         if (pkt->cp_rxbuf_id != NETVSC_RECEIVE_BUFFER_ID) {
872                 if_printf(rxr->hn_ifp, "rxbuf_id %d is invalid!\n",
873                     pkt->cp_rxbuf_id);
874                 return;
875         }
876
877         count = pkt->cp_rxbuf_cnt;
878
879         /* Each range represents 1 RNDIS pkt that contains 1 Ethernet frame */
880         for (i = 0; i < count; i++) {
881                 net_vsc_pkt->status = nvsp_status_success;
882                 net_vsc_pkt->data = ((uint8_t *)net_dev->rx_buf +
883                     pkt->cp_rxbuf[i].rb_ofs);
884                 net_vsc_pkt->tot_data_buf_len = pkt->cp_rxbuf[i].rb_len;
885
886                 hv_rf_on_receive(net_dev, rxr, net_vsc_pkt);
887                 if (net_vsc_pkt->status != nvsp_status_success) {
888                         status = nvsp_status_failure;
889                 }
890         }
891         
892         /*
893          * Moved completion call back here so that all received 
894          * messages (not just data messages) will trigger a response
895          * message back to the host.
896          */
897         hv_nv_on_receive_completion(chan, pkt->cp_hdr.cph_xactid, status);
898 }
899
900 /*
901  * Net VSC on receive completion
902  *
903  * Send a receive completion packet to RNDIS device (ie NetVsp)
904  */
905 static void
906 hv_nv_on_receive_completion(struct vmbus_channel *chan, uint64_t tid,
907     uint32_t status)
908 {
909         nvsp_msg rx_comp_msg;
910         int retries = 0;
911         int ret = 0;
912         
913         rx_comp_msg.hdr.msg_type = nvsp_msg_1_type_send_rndis_pkt_complete;
914
915         /* Pass in the status */
916         rx_comp_msg.msgs.vers_1_msgs.send_rndis_pkt_complete.status =
917             status;
918
919 retry_send_cmplt:
920         /* Send the completion */
921         ret = vmbus_chan_send(chan, VMBUS_CHANPKT_TYPE_COMP, 0,
922             &rx_comp_msg, sizeof(nvsp_msg), tid);
923         if (ret == 0) {
924                 /* success */
925                 /* no-op */
926         } else if (ret == EAGAIN) {
927                 /* no more room... wait a bit and attempt to retry 3 times */
928                 retries++;
929
930                 if (retries < 4) {
931                         DELAY(100);
932                         goto retry_send_cmplt;
933                 }
934         }
935 }
936
937 /*
938  * Net VSC receiving vRSS send table from VSP
939  */
940 static void
941 hv_nv_send_table(struct hn_softc *sc, const struct vmbus_chanpkt_hdr *pkt)
942 {
943         netvsc_dev *net_dev;
944         const nvsp_msg *nvsp_msg_pkt;
945         int i;
946         uint32_t count;
947         const uint32_t *table;
948
949         net_dev = hv_nv_get_inbound_net_device(sc);
950         if (!net_dev)
951                 return;
952
953         nvsp_msg_pkt = VMBUS_CHANPKT_CONST_DATA(pkt);
954
955         if (nvsp_msg_pkt->hdr.msg_type !=
956             nvsp_msg5_type_send_indirection_table) {
957                 printf("Netvsc: !Warning! receive msg type not "
958                         "send_indirection_table. type = %d\n",
959                         nvsp_msg_pkt->hdr.msg_type);
960                 return;
961         }
962
963         count = nvsp_msg_pkt->msgs.vers_5_msgs.send_table.count;
964         if (count != VRSS_SEND_TABLE_SIZE) {
965                 printf("Netvsc: Received wrong send table size: %u\n", count);
966                 return;
967         }
968
969         table = (const uint32_t *)
970             ((const uint8_t *)&nvsp_msg_pkt->msgs.vers_5_msgs.send_table +
971              nvsp_msg_pkt->msgs.vers_5_msgs.send_table.offset);
972
973         for (i = 0; i < count; i++)
974                 net_dev->vrss_send_table[i] = table[i];
975 }
976
977 /*
978  * Net VSC on channel callback
979  */
980 static void
981 hv_nv_on_channel_callback(struct vmbus_channel *chan, void *xrxr)
982 {
983         struct hn_rx_ring *rxr = xrxr;
984         struct hn_softc *sc = rxr->hn_ifp->if_softc;
985         netvsc_dev *net_dev;
986         void *buffer;
987         int bufferlen = NETVSC_PACKET_SIZE;
988
989         net_dev = hv_nv_get_inbound_net_device(sc);
990         if (net_dev == NULL)
991                 return;
992
993         buffer = rxr->hn_rdbuf;
994         do {
995                 struct vmbus_chanpkt_hdr *pkt = buffer;
996                 uint32_t bytes_rxed;
997                 int ret;
998
999                 bytes_rxed = bufferlen;
1000                 ret = vmbus_chan_recv_pkt(chan, pkt, &bytes_rxed);
1001                 if (ret == 0) {
1002                         if (bytes_rxed > 0) {
1003                                 switch (pkt->cph_type) {
1004                                 case VMBUS_CHANPKT_TYPE_COMP:
1005                                         hv_nv_on_send_completion(net_dev, chan,
1006                                             pkt);
1007                                         break;
1008                                 case VMBUS_CHANPKT_TYPE_RXBUF:
1009                                         hv_nv_on_receive(net_dev, rxr, chan, pkt);
1010                                         break;
1011                                 case VMBUS_CHANPKT_TYPE_INBAND:
1012                                         hv_nv_send_table(sc, pkt);
1013                                         break;
1014                                 default:
1015                                         if_printf(rxr->hn_ifp,
1016                                             "unknown chan pkt %u\n",
1017                                             pkt->cph_type);
1018                                         break;
1019                                 }
1020                         }
1021                 } else if (ret == ENOBUFS) {
1022                         /* Handle large packet */
1023                         if (bufferlen > NETVSC_PACKET_SIZE) {
1024                                 free(buffer, M_NETVSC);
1025                                 buffer = NULL;
1026                         }
1027
1028                         /* alloc new buffer */
1029                         buffer = malloc(bytes_rxed, M_NETVSC, M_NOWAIT);
1030                         if (buffer == NULL) {
1031                                 if_printf(rxr->hn_ifp,
1032                                     "hv_cb malloc buffer failed, len=%u\n",
1033                                     bytes_rxed);
1034                                 bufferlen = 0;
1035                                 break;
1036                         }
1037                         bufferlen = bytes_rxed;
1038                 } else {
1039                         /* No more packets */
1040                         break;
1041                 }
1042         } while (1);
1043
1044         if (bufferlen > NETVSC_PACKET_SIZE)
1045                 free(buffer, M_NETVSC);
1046
1047         hv_rf_channel_rollup(rxr, rxr->hn_txr);
1048 }