blob: baf03b7cd2adfd09b7733be1901a4df2e13da398 [file] [log] [blame]
Damjan Marion8bdc63b2016-11-02 14:48:21 +01001/*
2 * Copyright (c) 2016 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_vnet_vnet_device_h
17#define included_vnet_vnet_device_h
18
19#include <vnet/unix/pcap.h>
20#include <vnet/l3_types.h>
21
22typedef enum
23{
John Loa60d4cb2016-12-17 03:09:58 -050024 VNET_DEVICE_INPUT_NEXT_IP4_NCS_INPUT,
Damjan Marion8bdc63b2016-11-02 14:48:21 +010025 VNET_DEVICE_INPUT_NEXT_IP4_INPUT,
26 VNET_DEVICE_INPUT_NEXT_IP6_INPUT,
27 VNET_DEVICE_INPUT_NEXT_MPLS_INPUT,
28 VNET_DEVICE_INPUT_NEXT_ETHERNET_INPUT,
29 VNET_DEVICE_INPUT_NEXT_DROP,
30 VNET_DEVICE_INPUT_N_NEXT_NODES,
31} vnet_device_input_next_t;
32
33#define VNET_DEVICE_INPUT_NEXT_NODES { \
34 [VNET_DEVICE_INPUT_NEXT_DROP] = "error-drop", \
35 [VNET_DEVICE_INPUT_NEXT_ETHERNET_INPUT] = "ethernet-input", \
John Loa60d4cb2016-12-17 03:09:58 -050036 [VNET_DEVICE_INPUT_NEXT_IP4_NCS_INPUT] = "ip4-input-no-checksum", \
37 [VNET_DEVICE_INPUT_NEXT_IP4_INPUT] = "ip4-input", \
Damjan Marion8bdc63b2016-11-02 14:48:21 +010038 [VNET_DEVICE_INPUT_NEXT_IP6_INPUT] = "ip6-input", \
39 [VNET_DEVICE_INPUT_NEXT_MPLS_INPUT] = "mpls-input", \
40}
41
Damjan Marionb3bb1012017-02-28 21:55:28 +010042typedef struct
43{
44 CLIB_CACHE_LINE_ALIGN_MARK (cacheline0);
45
46 /* total input packet counter */
47 u64 aggregate_rx_packets;
48} vnet_device_per_worker_data_t;
49
50typedef struct
51{
52 vnet_device_per_worker_data_t *workers;
Damjan Marion586afd72017-04-05 19:18:20 +020053 uword first_worker_thread_index;
54 uword last_worker_thread_index;
55 uword next_worker_thread_index;
Damjan Marionb3bb1012017-02-28 21:55:28 +010056} vnet_device_main_t;
57
Damjan Marion153646e2017-04-05 18:15:45 +020058typedef enum
59{
60 VNET_DEVICE_INPUT_MODE_POLLING = 0,
61 VNET_DEVICE_INPUT_MODE_INTERRUPT,
62 VNET_DEVICE_INPUT_N_MODES,
63} vnet_device_input_mode_t;
64
Damjan Marioneb743fa2017-03-20 16:34:15 +010065typedef struct
66{
67 u32 hw_if_index;
68 u32 dev_instance;
69 u16 queue_id;
Damjan Marion153646e2017-04-05 18:15:45 +020070 vnet_device_input_mode_t mode;
71 uword interrupt_pending;
Damjan Marioneb743fa2017-03-20 16:34:15 +010072} vnet_device_and_queue_t;
73
74typedef struct
75{
76 vnet_device_and_queue_t *devices_and_queues;
Damjan Marion153646e2017-04-05 18:15:45 +020077 vlib_node_state_t enabled_node_state;
Damjan Marioneb743fa2017-03-20 16:34:15 +010078} vnet_device_input_runtime_t;
79
Damjan Marionb3bb1012017-02-28 21:55:28 +010080extern vnet_device_main_t vnet_device_main;
Damjan Marion51327ac2016-11-09 11:59:42 +010081extern vlib_node_registration_t device_input_node;
Damjan Marion7dc41462016-11-15 19:47:58 +010082extern const u32 device_input_next_node_advance[];
Damjan Marion51327ac2016-11-09 11:59:42 +010083
Damjan Marioneb743fa2017-03-20 16:34:15 +010084static inline void
Damjan Marion153646e2017-04-05 18:15:45 +020085vnet_set_device_input_node (vnet_main_t * vnm, u32 hw_if_index,
86 u32 node_index)
Damjan Marioneb743fa2017-03-20 16:34:15 +010087{
Damjan Marioneb743fa2017-03-20 16:34:15 +010088 vnet_hw_interface_t *hw = vnet_get_hw_interface (vnm, hw_if_index);
89 hw->input_node_index = node_index;
90}
91
Damjan Marion153646e2017-04-05 18:15:45 +020092void vnet_device_input_assign_thread (vnet_main_t * vnm, u32 hw_if_index,
93 u16 queue_id, uword thread_index);
94int vnet_device_input_unassign_thread (vnet_main_t * vnm, u32 hw_if_index,
95 u16 queue_id, uword thread_index);
96int vnet_device_input_set_mode (vnet_main_t * vnm, u32 hw_if_index,
97 u16 queue_id, vnet_device_input_mode_t mode);
98int vnet_device_input_get_mode (vnet_main_t * vnm, u32 hw_if_index,
99 u16 queue_id,
100 vnet_device_input_mode_t * mode);
Damjan Marioneb743fa2017-03-20 16:34:15 +0100101
Damjan Marionb3bb1012017-02-28 21:55:28 +0100102static inline u64
103vnet_get_aggregate_rx_packets (void)
104{
105 vnet_device_main_t *vdm = &vnet_device_main;
106 u64 sum = 0;
107 vnet_device_per_worker_data_t *pwd;
108
109 vec_foreach (pwd, vdm->workers) sum += pwd->aggregate_rx_packets;
110
111 return sum;
112}
113
114static inline void
Damjan Marion586afd72017-04-05 19:18:20 +0200115vnet_device_increment_rx_packets (u32 thread_index, u64 count)
Damjan Marionb3bb1012017-02-28 21:55:28 +0100116{
117 vnet_device_main_t *vdm = &vnet_device_main;
118 vnet_device_per_worker_data_t *pwd;
119
Damjan Marion586afd72017-04-05 19:18:20 +0200120 pwd = vec_elt_at_index (vdm->workers, thread_index);
Damjan Marionb3bb1012017-02-28 21:55:28 +0100121 pwd->aggregate_rx_packets += count;
122}
123
Damjan Marioneb743fa2017-03-20 16:34:15 +0100124static_always_inline vnet_device_and_queue_t *
125vnet_get_device_and_queue (vlib_main_t * vm, vlib_node_runtime_t * node)
126{
127 vnet_device_input_runtime_t *rt = (void *) node->runtime_data;
128 return rt->devices_and_queues;
129}
130
Damjan Marion153646e2017-04-05 18:15:45 +0200131static_always_inline uword
132vnet_get_device_input_thread_index (vnet_main_t * vnm, u32 hw_if_index,
133 u16 queue_id)
134{
135 vnet_hw_interface_t *hw = vnet_get_hw_interface (vnm, hw_if_index);
136 ASSERT (queue_id < vec_len (hw->input_node_thread_index_by_queue));
137 return hw->input_node_thread_index_by_queue[queue_id];
138}
139
Damjan Marioneb743fa2017-03-20 16:34:15 +0100140static_always_inline void
141vnet_device_input_set_interrupt_pending (vnet_main_t * vnm, u32 hw_if_index,
142 u16 queue_id)
143{
Damjan Marion153646e2017-04-05 18:15:45 +0200144 vlib_main_t *vm;
145 vnet_hw_interface_t *hw;
146 vnet_device_input_runtime_t *rt;
147 vnet_device_and_queue_t *dq;
148 uword idx;
Damjan Marioneb743fa2017-03-20 16:34:15 +0100149
Damjan Marion153646e2017-04-05 18:15:45 +0200150 hw = vnet_get_hw_interface (vnm, hw_if_index);
151 idx = vnet_get_device_input_thread_index (vnm, hw_if_index, queue_id);
152 vm = vlib_mains[idx];
153 rt = vlib_node_get_runtime_data (vm, hw->input_node_index);
154 idx = hw->dq_runtime_index_by_queue[queue_id];
155 dq = vec_elt_at_index (rt->devices_and_queues, idx);
156 dq->interrupt_pending = 1;
157
158 vlib_node_set_interrupt_pending (vm, hw->input_node_index);
Damjan Marioneb743fa2017-03-20 16:34:15 +0100159}
160
Damjan Marion153646e2017-04-05 18:15:45 +0200161#define foreach_device_and_queue(var,vec) \
162 for (var = (vec); var < vec_end (vec); var++) \
163 if (clib_smp_swap (&((var)->interrupt_pending), 0) || \
164 var->mode == VNET_DEVICE_INPUT_MODE_POLLING)
165
Damjan Marion8bdc63b2016-11-02 14:48:21 +0100166#endif /* included_vnet_vnet_device_h */
167
168/*
169 * fd.io coding-style-patch-verification: ON
170 *
171 * Local Variables:
172 * eval: (c-set-style "gnu")
173 * End:
174 */