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