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