f3868a88ae3b7cbd169246c17294632d002ead33
[vpp.git] / src / plugins / vmxnet3 / vmxnet3.h
1 /*
2  * Copyright (c) 2018 Cisco and/or its affiliates.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at:
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15
16 #ifndef __included_vmnet_vmnet_h__
17 #define __included_vmnet_vmnet_h__
18
19 #define foreach_vmxnet3_tx_func_error          \
20   _(ERROR_PACKETS, "error packets") \
21   _(LINK_DOWN, "link down") \
22   _(NO_FREE_SLOTS, "no free tx slots")
23
24 typedef enum
25 {
26 #define _(f,s) VMXNET3_TX_ERROR_##f,
27   foreach_vmxnet3_tx_func_error
28 #undef _
29     VMXNET3_TX_N_ERROR,
30 } vmxnet3_tx_func_error_t;
31
32 #define foreach_vmxnet3_rxmode_flags \
33   _(0, UCAST, "unicast") \
34   _(1, MCAST, "multicast")                 \
35   _(2, BCAST, "broadcast") \
36   _(3, ALL_MULTI, "all multicast") \
37   _(4, PROMISC, "promiscuous")
38
39 enum
40 {
41 #define _(a, b, c) VMXNET3_RXMODE_##b = (1 << a),
42   foreach_vmxnet3_rxmode_flags
43 #undef _
44 };
45
46 /* BAR 0 */
47 #define VMXNET3_REG_IMR     0x0000      /* Interrupt Mask Register */
48 #define VMXNET3_REG_TXPROD  0x0600      /* Tx Producer Index */
49 #define VMXNET3_REG_RXPROD  0x0800      /* Rx Producer Index for ring 1 */
50 #define VMXNET3_REG_RXPROD2 0x0A00      /* Rx Producer Index for ring 2 */
51
52
53 /* BAR 1 */
54 #define VMXNET3_REG_VRRS 0x0000 /* VMXNET3 Revision Report Selection */
55 #define VMXNET3_REG_UVRS 0x0008 /* UPT Version Report Selection */
56 #define VMXNET3_REG_DSAL 0x0010 /* Driver Shared Address Low */
57 #define VMXNET3_REG_DSAH 0x0018 /* Driver Shared Address High */
58 #define VMXNET3_REG_CMD  0x0020 /* Command */
59 #define VMXNET3_REG_MACL 0x0028 /* MAC Address Low */
60 #define VMXNET3_REG_MACH 0x0030 /* MAC Address High */
61 #define VMXNET3_REG_ICR  0x0038 /* Interrupt Cause Register */
62 #define VMXNET3_REG_ECR  0x0040 /* Event Cause Register */
63
64 #define VMXNET3_VLAN_LEN 4
65 #define VMXNET3_FCS_LEN  4
66 #define VMXNET3_MTU (1514 + VMXNET3_VLAN_LEN + VMXNET3_FCS_LEN)
67
68 #define VMXNET3_RXF_BTYPE (1 << 14)     /* rx body buffer type */
69 #define VMXNET3_RXF_GEN   (1 << 31)     /* rx generation */
70 #define VMXNET3_RXCF_IP6  (1 << 20)     /* rx ip6 packet */
71 #define VMXNET3_RXCF_IP4  (1 << 21)     /* rx ip4 packet */
72 #define VMXNET3_RXCF_GEN  (1 << 31)     /* rx completion generation */
73 #define VMXNET3_RXC_INDEX (0xFFF)       /* rx completion index mask */
74
75 #define VMXNET3_TXF_GEN  (1 << 14)      /* tx generation */
76 #define VMXNET3_TXF_EOP  (1 << 12)      /* tx end of packet */
77 #define VMXNET3_TXF_CQ   (1 << 13)      /* tx completion request */
78 #define VMXNET3_TXCF_GEN (1 << 31)      /* tx completion generation */
79 #define VMXNET3_TXC_INDEX (0xFFF)       /* tx completion index mask */
80
81 #define VMXNET3_RX_RING_SIZE 2
82 #define VMXNET3_INPUT_REFILL_THRESHOLD 32
83 #define VMXNET3_NUM_TX_DESC 1024
84 #define VMXNET3_NUM_TX_COMP VMXNET3_NUM_TX_DESC
85 #define VMXNET3_NUM_RX_DESC 1024
86 #define VMXNET3_NUM_RX_COMP VMXNET3_NUM_RX_DESC
87
88 #define VMXNET3_VERSION_MAGIC 0x69505845
89 #define VMXNET3_SHARED_MAGIC  0xbabefee1
90 #define VMXNET3_VERSION_SELECT     1
91 #define VMXNET3_UPT_VERSION_SELECT 1
92 #define VMXNET3_MAX_INTRS          25
93 #define VMXNET3_IC_DISABLE_ALL     0x1
94
95 #define VMXNET3_GOS_BITS_32     (1 << 0)
96 #define VMXNET3_GOS_BITS_64     (2 << 0)
97 #define VMXNET3_GOS_TYPE_LINUX  (1 << 2)
98 #define VMXNET3_RXCL_LEN_MASK   (0x3FFF)        // 14 bits
99 #define VMXNET3_RXCL_ERROR      (1 << 14)
100 #define VMXNET3_RXCI_EOP        (1 << 14)
101 #define VMXNET3_RXCI_SOP        (1 << 15)
102
103 #define foreach_vmxnet3_device_flags \
104   _(0, INITIALIZED, "initialized") \
105   _(1, ERROR, "error")             \
106   _(2, ADMIN_UP, "admin-up") \
107   _(3, IOVA, "iova") \
108   _(4, LINK_UP, "link-up") \
109   _(5, SHARED_TXQ_LOCK, "shared-txq-lock") \
110   _(6, ELOG, "elog")
111
112 enum
113 {
114 #define _(a, b, c) VMXNET3_DEVICE_F_##b = (1 << a),
115   foreach_vmxnet3_device_flags
116 #undef _
117 };
118
119 #define foreach_vmxnet3_set_cmds \
120   _(0, ACTIVATE_DEV, "activate device") \
121   _(1, QUIESCE_DEV, "quiesce device") \
122   _(2, RESET_DEV, "reset device") \
123   _(3, UPDATE_RX_MODE, "update rx mode") \
124   _(4, UPDATE_MAC_FILTERS, "update mac filters") \
125   _(5, UPDATE_VLAN_FILTERS, "update vlan filters") \
126   _(6, UPDATE_RSSIDT, "update rss idt") \
127   _(7, UPDATE_IML, "update iml") \
128   _(8, UPDATE_PMCFG, "update pm cfg") \
129   _(9, UPDATE_FEATURE, "update feature") \
130   _(10, STOP_EMULATION, "stop emulation") \
131   _(11, LOAD_PLUGIN, "load plugin") \
132   _(12, ACTIVATE_VF, "activate vf") \
133   _(13, RESERVED3, "reserved 3") \
134   _(14, RESERVED4, "reservced 4") \
135   _(15, REGISTER_MEMREGS, "register mem regs")
136
137 enum
138 {
139 #define _(a, b, c) VMXNET3_CMD_##b = (a + 0xCAFE0000),
140   foreach_vmxnet3_set_cmds
141 #undef _
142 };
143
144 #define foreach_vmxnet3_get_cmds \
145   _(0, GET_QUEUE_STATUS, "get queue status") \
146   _(1, GET_STATS, "get stats") \
147   _(2, GET_LINK, "get link") \
148   _(3, GET_PERM_MAC_LO, "get perm mac lo") \
149   _(4, GET_PERM_MAC_HI, "get perm mac hi") \
150   _(5, GET_DID_LO, "get did lo") \
151   _(6, GET_DID_HI, "get did hi") \
152   _(7, GET_DEV_EXTRA_INFO, "get dev extra info") \
153   _(8, GET_CONF_INTR, "get conf intr") \
154   _(9, GET_ADAPTIVE_RING_INFO, "get adaptive ring info") \
155   _(10, GET_TXDATA_DESC_SIZE, "gte txdata desc size") \
156   _(11, RESERVED5, "reserved5")
157
158 enum
159 {
160 #define _(a, b, c) VMXNET3_CMD_##b = (a + 0xF00D0000),
161   foreach_vmxnet3_get_cmds
162 #undef _
163 };
164
165 typedef CLIB_PACKED (struct
166                      {
167                      u32 version; u32 guest_info; u32 version_support;
168                      u32 upt_version_support; u64 upt_features;
169                      u64 driver_data_address; u64 queue_desc_address;
170                      u32 driver_data_len; u32 queue_desc_len;
171                      u32 mtu;
172                      u16 max_num_rx_sg; u8 num_tx_queues; u8 num_rx_queues;
173                      u32 pad[4];
174                      }) vmxnet3_misc_config;
175
176 typedef CLIB_PACKED (struct
177                      {
178                      u8 mask_mode;
179                      u8 num_intrs;
180                      u8 event_intr_index;
181                      u8 moderation_level[VMXNET3_MAX_INTRS]; u32 control;
182                      u32 pad[2];
183                      }) vmxnet3_interrupt_config;
184
185 typedef CLIB_PACKED (struct
186                      {
187                      u32 mode;
188                      u16 multicast_len;
189                      u16 pad; u64 multicast_address; u8 vlan_filter[512];
190                      }) vmxnet3_rx_filter_config;
191
192 typedef CLIB_PACKED (struct
193                      {
194                      u32 version; u32 length;
195                      u64 address;
196                      }) vmxnet3_variable_config;
197
198 typedef CLIB_PACKED (struct
199                      {
200                      u32 magic;
201                      u32 pad;
202                      vmxnet3_misc_config misc;
203                      vmxnet3_interrupt_config interrupt;
204                      vmxnet3_rx_filter_config rx_filter;
205                      vmxnet3_variable_config rss;
206                      vmxnet3_variable_config pattern;
207                      vmxnet3_variable_config plugin; u32 ecr;
208                      u32 pad1[5];
209                      }) vmxnet3_shared;
210
211 typedef CLIB_PACKED (struct
212                      {
213                      u8 stopped;
214                      u8 pad[3];
215                      u32 error;
216                      }) vmxnet3_queue_status;
217
218 typedef CLIB_PACKED (struct
219                      {
220                      u32 num_deferred; u32 threshold;
221                      u64 pad;
222                      }) vmxnet3_tx_queue_control;
223
224 typedef CLIB_PACKED (struct
225                      {
226                      u64 desc_address;
227                      u64 data_address;
228                      u64 comp_address; u64 driver_data_address; u64 pad;
229                      u32 num_desc;
230                      u32 num_data;
231                      u32 num_comp; u32 driver_data_len; u8 intr_index;
232                      u8 pad1[7];
233                      }) vmxnet3_tx_queue_config;
234
235 typedef CLIB_PACKED (struct
236                      {
237                      u64 tso_pkts;
238                      u64 tso_bytes;
239                      u64 ucast_pkts; u64 ucast_bytes; u64 mcast_pkts;
240                      u64 mcast_bytes;
241                      u64 bcast_pkts; u64 bcast_bytes; u64 error_pkts;
242                      u64 discard_pkts;
243                      }) vmxnet3_tx_stats;
244
245 typedef CLIB_PACKED (struct
246                      {
247                      vmxnet3_tx_queue_control ctrl;
248                      vmxnet3_tx_queue_config cfg;
249                      vmxnet3_queue_status status; vmxnet3_tx_stats stats;
250                      u8 pad[88];
251                      }) vmxnet3_tx_queue;
252
253 typedef CLIB_PACKED (struct
254                      {
255                      u8 update_prod; u8 pad[7];
256                      u64 pad1;
257                      }) vmxnet3_rx_queue_control;
258
259 typedef CLIB_PACKED (struct
260                      {
261                      u64 desc_address[2];
262                      u64 comp_address; u64 driver_data_address; u64 pad;
263                      u32 num_desc[2];
264                      u32 num_comp; u32 driver_data_len; u8 intr_index;
265                      u8 pad1[7];
266                      }) vmxnet3_rx_queue_config;
267
268 typedef CLIB_PACKED (struct
269                      {
270                      u64 lro_pkts;
271                      u64 lro_bytes;
272                      u64 ucast_pkts; u64 ucast_bytes; u64 mcast_pkts;
273                      u64 mcast_bytes;
274                      u64 bcast_pkts; u64 bcast_bytes; u64 nobuf_pkts;
275                      u64 error_pkts;
276                      }) vmxnet3_rx_stats;
277
278 typedef CLIB_PACKED (struct
279                      {
280                      vmxnet3_rx_queue_control ctrl;
281                      vmxnet3_rx_queue_config cfg;
282                      vmxnet3_queue_status status; vmxnet3_rx_stats stats;
283                      u8 pad[88];
284                      }) vmxnet3_rx_queue;
285
286 typedef CLIB_PACKED (struct
287                      {
288                      vmxnet3_tx_queue tx; vmxnet3_rx_queue rx;
289                      }) vmxnet3_queues;
290
291 /*
292  * flags:
293  *   buffer length   -- bits 0-13
294  *   buffer type     -- bit  14
295  *   descriptor type -- bit  15
296  *   reserved        -- bits 16-30
297  *   generation      -- bit  31
298  */
299 typedef CLIB_PACKED (struct
300                      {
301                      u64 address;
302                      u32 flags;
303                      u32 pad;
304                      }) vmxnet3_rx_desc;
305
306 /*
307  * index:
308  *   RX desc index           -- bits 0-11
309  *   ext1                    -- bits 12-13
310  *   end of packet           -- bit  14
311  *   start of packet         -- bit  15
312  *   ring ID                 -- bits 16-25
313  *   RSS hash type           -- bits 26-29
314  *   checksum not calculated -- bit  30
315  *   ext2                    -- bit  31
316  *
317  * rss: RSS hash value
318  *
319  * len:
320  *   data length             -- bits 0-13
321  *   error                   -- bit  14
322  *   tag is stripped         -- bit  15
323  *   tag stripped            -- bits 16-31
324  *
325  * flags:
326  *   checksum                -- bits 0 - 15
327  *   tcp/udp checksum correct-- bit  16
328  *   udp packet              -- bit  17
329  *   tcp packet              -- bit  18
330  *   ip checksum correct     -- bit  19
331  *   ipv6                    -- bit  20
332  *   ipv4                    -- bit  21
333  *   ip fragment             -- bit  22
334  *   frame crc correct       -- bit  23
335  *   completion type         -- bits 24-30
336  *   generation              -- bit  31
337  */
338 typedef CLIB_PACKED (struct
339                      {
340                      u32 index; u32 rss;
341                      u32 len;
342                      u32 flags;
343                      }) vmxnet3_rx_comp;
344
345 /*
346  * index:
347  *   TX desc index           -- bits 0-11
348  *   ext1                    -- bits 12-31
349  *
350  * flags:
351  *   reserved                -- bits 0-23
352  *   completion type         -- bits 24-30
353  *   generation              -- bit  31
354  */
355 typedef CLIB_PACKED (struct
356                      {
357                      u32 index;
358                      u32 pad[2];
359                      u32 flags;
360                      }) vmxnet3_tx_comp;
361
362 /*
363  * flags[0]:
364  *   length                  -- bits 0-13
365  *   generation              -- bit  14
366  *   reserved                -- bit  15
367  *   descriptor type         -- bit  16
368  *   ext1                    -- bit  17
369  *   MSS, checksum offset    -- bits 18-31
370  * flags[1]:
371  *   header length           -- bits 0-9
372  *   offload mode            -- bits 10-11
373  *   end of packet           -- bit  12
374  *   completion request      -- bit  13
375  *   ext2                    -- bit  14
376  *   vlan tag insertion      -- bit  15
377  *   tag to insert           -- bits 16-31
378  */
379 typedef CLIB_PACKED (struct
380                      {
381                      u64 address;
382                      u32 flags[2];
383                      }) vmxnet3_tx_desc;
384
385 typedef struct
386 {
387   CLIB_CACHE_LINE_ALIGN_MARK (cacheline0);
388   u32 *bufs;
389   u32 gen;
390   u16 fill;
391   u16 rid;
392   u16 produce;
393   u16 consume;
394 } vmxnet3_rx_ring;
395
396 typedef struct
397 {
398   CLIB_CACHE_LINE_ALIGN_MARK (cacheline0);
399   u64 next;
400   u32 gen;
401 } vmxnet3_rx_comp_ring;
402
403 typedef struct
404 {
405   CLIB_CACHE_LINE_ALIGN_MARK (cacheline0);
406   u16 size;
407   u8 int_mode;
408   vmxnet3_rx_ring rx_ring[VMXNET3_RX_RING_SIZE];
409   vmxnet3_rx_desc *rx_desc[VMXNET3_RX_RING_SIZE];
410   vmxnet3_rx_comp *rx_comp;
411   vmxnet3_rx_comp_ring rx_comp_ring;
412 } vmxnet3_rxq_t;
413
414 typedef struct
415 {
416   CLIB_CACHE_LINE_ALIGN_MARK (cacheline0);
417   u32 *bufs;
418   u32 gen;
419   u16 produce;
420   u16 consume;
421 } vmxnet3_tx_ring;
422
423 typedef struct
424 {
425   CLIB_CACHE_LINE_ALIGN_MARK (cacheline0);
426   u64 next;
427   u32 gen;
428 } vmxnet3_tx_comp_ring;
429
430 typedef struct
431 {
432   CLIB_CACHE_LINE_ALIGN_MARK (cacheline0);
433   u16 size;
434   clib_spinlock_t lock;
435
436   vmxnet3_tx_desc *tx_desc;
437   vmxnet3_tx_comp *tx_comp;
438   vmxnet3_tx_ring tx_ring;
439   vmxnet3_tx_comp_ring tx_comp_ring;
440 } vmxnet3_txq_t;
441
442 typedef CLIB_PACKED (struct
443                      {
444                      vmxnet3_queues queues; vmxnet3_shared shared;
445                      }) vmxnet3_dma;
446
447 typedef struct
448 {
449   CLIB_CACHE_LINE_ALIGN_MARK (cacheline0);
450   u32 flags;
451   u32 per_interface_next_index;
452
453   u32 dev_instance;
454   u32 sw_if_index;
455   u32 hw_if_index;
456   vlib_pci_dev_handle_t pci_dev_handle;
457   vlib_pci_addr_t pci_addr;
458   void *bar[2];
459
460   /* queues */
461   vmxnet3_rxq_t *rxqs;
462   vmxnet3_txq_t *txqs;
463
464   u16 num_tx_queues;
465   u16 num_rx_queues;
466   u16 num_intrs;
467
468   u8 version;
469   u8 mac_addr[6];
470
471   /* error */
472   clib_error_t *error;
473
474   vmxnet3_dma *dma;
475
476   u32 link_speed;
477 } vmxnet3_device_t;
478
479 typedef struct
480 {
481   vmxnet3_device_t *devices;
482   vlib_physmem_region_index_t physmem_region;
483   u32 physmem_region_alloc;
484   u16 msg_id_base;
485 } vmxnet3_main_t;
486
487 extern vmxnet3_main_t vmxnet3_main;
488
489 typedef struct
490 {
491   vlib_pci_addr_t addr;
492   u32 enable_elog;
493   u16 rxq_size;
494   u16 txq_size;
495   /* return */
496   i32 rv;
497   u32 sw_if_index;
498   clib_error_t *error;
499 } vmxnet3_create_if_args_t;
500
501 typedef struct
502 {
503   u32 next_index;
504   u32 hw_if_index;
505   vlib_buffer_t buffer;
506 } vmxnet3_input_trace_t;
507
508 void vmxnet3_create_if (vlib_main_t * vm, vmxnet3_create_if_args_t * args);
509 void vmxnet3_delete_if (vlib_main_t * vm, vmxnet3_device_t * ad);
510
511 extern clib_error_t *vmxnet3_plugin_api_hookup (vlib_main_t * vm);
512 extern vlib_node_registration_t vmxnet3_input_node;
513 extern vnet_device_class_t vmxnet3_device_class;
514
515 /* format.c */
516 format_function_t format_vmxnet3_device;
517 format_function_t format_vmxnet3_device_name;
518 format_function_t format_vmxnet3_input_trace;
519
520 static_always_inline void
521 vmxnet3_reg_write (vmxnet3_device_t * vd, u8 bar, u32 addr, u32 val)
522 {
523   *(volatile u32 *) ((u8 *) vd->bar[bar] + addr) = val;
524 }
525
526 static_always_inline u32
527 vmxnet3_reg_read (vmxnet3_device_t * vd, u8 bar, u32 addr)
528 {
529   return *(volatile u32 *) (vd->bar[bar] + addr);
530 }
531
532 static_always_inline uword
533 vmxnet3_dma_addr (vlib_main_t * vm, vmxnet3_device_t * vd, void *p)
534 {
535   vmxnet3_main_t *vmxm = &vmxnet3_main;
536
537   return (vd->flags & VMXNET3_DEVICE_F_IOVA) ? pointer_to_uword (p) :
538     vlib_physmem_virtual_to_physical (vm, vmxm->physmem_region, p);
539 }
540
541 static_always_inline void
542 vmxnet3_rx_ring_advance_produce (vmxnet3_rxq_t * rxq, vmxnet3_rx_ring * ring)
543 {
544   ring->produce++;
545   if (PREDICT_FALSE (ring->produce == rxq->size))
546     {
547       ring->produce = 0;
548       ring->gen ^= VMXNET3_RXF_GEN;
549     }
550 }
551
552 static_always_inline clib_error_t *
553 vmxnet3_rxq_refill_ring0 (vlib_main_t * vm, vmxnet3_device_t * vd,
554                           vmxnet3_rxq_t * rxq)
555 {
556   vmxnet3_rx_desc *rxd;
557   u16 n_refill, n_alloc;
558   vmxnet3_rx_ring *ring;
559
560   ring = &rxq->rx_ring[0];
561   n_refill = rxq->size - ring->fill;
562
563   if (PREDICT_TRUE (n_refill <= VMXNET3_INPUT_REFILL_THRESHOLD))
564     return 0;
565
566   n_alloc =
567     vlib_buffer_alloc_to_ring (vm, ring->bufs, ring->produce, rxq->size,
568                                n_refill);
569   if (PREDICT_FALSE (n_alloc != n_refill))
570     {
571       if (n_alloc)
572         vlib_buffer_free_from_ring (vm, ring->bufs, ring->produce, rxq->size,
573                                     n_alloc);
574       return clib_error_return (0, "buffer alloc failed");
575     }
576
577   while (n_alloc)
578     {
579       rxd = &rxq->rx_desc[0][ring->produce];
580       rxd->address =
581         vlib_get_buffer_data_physical_address (vm, ring->bufs[ring->produce]);
582       rxd->flags = ring->gen | VLIB_BUFFER_DATA_SIZE;
583
584       vmxnet3_rx_ring_advance_produce (rxq, ring);
585       ring->fill++;
586       n_alloc--;
587     }
588
589   vmxnet3_reg_write (vd, 0, VMXNET3_REG_RXPROD, ring->produce);
590
591   return 0;
592 }
593
594 static_always_inline clib_error_t *
595 vmxnet3_rxq_refill_ring1 (vlib_main_t * vm, vmxnet3_device_t * vd,
596                           vmxnet3_rxq_t * rxq)
597 {
598   vmxnet3_rx_desc *rxd;
599   u16 n_refill, n_alloc;
600   vmxnet3_rx_ring *ring;
601
602   ring = &rxq->rx_ring[1];
603   n_refill = rxq->size - ring->fill;
604
605   if (PREDICT_TRUE (n_refill <= VMXNET3_INPUT_REFILL_THRESHOLD))
606     return 0;
607
608   n_alloc =
609     vlib_buffer_alloc_to_ring (vm, ring->bufs, ring->produce, rxq->size,
610                                n_refill);
611   if (PREDICT_FALSE (n_alloc != n_refill))
612     {
613       if (n_alloc)
614         vlib_buffer_free_from_ring (vm, ring->bufs, ring->produce, rxq->size,
615                                     n_alloc);
616       return clib_error_return (0, "buffer alloc failed");
617     }
618
619   while (n_alloc)
620     {
621       rxd = &rxq->rx_desc[1][ring->produce];
622       rxd->address =
623         vlib_get_buffer_data_physical_address (vm, ring->bufs[ring->produce]);
624       rxd->flags = ring->gen | VLIB_BUFFER_DATA_SIZE | VMXNET3_RXF_BTYPE;
625
626       vmxnet3_rx_ring_advance_produce (rxq, ring);
627       ring->fill++;
628       n_alloc--;
629     }
630
631   vmxnet3_reg_write (vd, 0, VMXNET3_REG_RXPROD2, ring->produce);
632
633   return 0;
634 }
635
636 #endif /* __included_vmnet_vmnet_h__ */
637 /*
638  * fd.io coding-style-patch-verification: ON
639  *
640  * Local Variables:
641  * eval: (c-set-style "gnu")
642  * End:
643  */