18bdc63b6SDamjan Marion/*
28bdc63b6SDamjan Marion * Copyright (c) 2016 Cisco and/or its affiliates.
38bdc63b6SDamjan Marion * Licensed under the Apache License, Version 2.0 (the "License");
48bdc63b6SDamjan Marion * you may not use this file except in compliance with the License.
58bdc63b6SDamjan Marion * You may obtain a copy of the License at:
68bdc63b6SDamjan Marion *
78bdc63b6SDamjan Marion *     http://www.apache.org/licenses/LICENSE-2.0
88bdc63b6SDamjan Marion *
98bdc63b6SDamjan Marion * Unless required by applicable law or agreed to in writing, software
108bdc63b6SDamjan Marion * distributed under the License is distributed on an "AS IS" BASIS,
118bdc63b6SDamjan Marion * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
128bdc63b6SDamjan Marion * See the License for the specific language governing permissions and
138bdc63b6SDamjan Marion * limitations under the License.
148bdc63b6SDamjan Marion */
158bdc63b6SDamjan Marion
168bdc63b6SDamjan Marion#ifndef included_vnet_vnet_device_h
178bdc63b6SDamjan Marion#define included_vnet_vnet_device_h
188bdc63b6SDamjan Marion
193ae2873eSDave Barach#include <vppinfra/pcap.h>
208bdc63b6SDamjan Marion#include <vnet/l3_types.h>
218bdc63b6SDamjan Marion
228bdc63b6SDamjan Mariontypedef enum
238bdc63b6SDamjan Marion{
24a60d4cb0SJohn Lo  VNET_DEVICE_INPUT_NEXT_IP4_NCS_INPUT,
258bdc63b6SDamjan Marion  VNET_DEVICE_INPUT_NEXT_IP4_INPUT,
268bdc63b6SDamjan Marion  VNET_DEVICE_INPUT_NEXT_IP6_INPUT,
278bdc63b6SDamjan Marion  VNET_DEVICE_INPUT_NEXT_MPLS_INPUT,
288bdc63b6SDamjan Marion  VNET_DEVICE_INPUT_NEXT_ETHERNET_INPUT,
298bdc63b6SDamjan Marion  VNET_DEVICE_INPUT_NEXT_DROP,
308bdc63b6SDamjan Marion  VNET_DEVICE_INPUT_N_NEXT_NODES,
318bdc63b6SDamjan Marion} vnet_device_input_next_t;
328bdc63b6SDamjan Marion
338bdc63b6SDamjan Marion#define VNET_DEVICE_INPUT_NEXT_NODES {					\
348bdc63b6SDamjan Marion    [VNET_DEVICE_INPUT_NEXT_DROP] = "error-drop",			\
358bdc63b6SDamjan Marion    [VNET_DEVICE_INPUT_NEXT_ETHERNET_INPUT] = "ethernet-input",		\
36a60d4cb0SJohn Lo    [VNET_DEVICE_INPUT_NEXT_IP4_NCS_INPUT] = "ip4-input-no-checksum",	\
37a60d4cb0SJohn Lo    [VNET_DEVICE_INPUT_NEXT_IP4_INPUT] = "ip4-input",			\
388bdc63b6SDamjan Marion    [VNET_DEVICE_INPUT_NEXT_IP6_INPUT] = "ip6-input",			\
398bdc63b6SDamjan Marion    [VNET_DEVICE_INPUT_NEXT_MPLS_INPUT] = "mpls-input",			\
408bdc63b6SDamjan Marion}
418bdc63b6SDamjan Marion
42b3bb1010SDamjan Mariontypedef struct
43b3bb1010SDamjan Marion{
44b3bb1010SDamjan Marion  CLIB_CACHE_LINE_ALIGN_MARK (cacheline0);
45b3bb1010SDamjan Marion
46b3bb1010SDamjan Marion  /* total input packet counter */
47b3bb1010SDamjan Marion  u64 aggregate_rx_packets;
48b3bb1010SDamjan Marion} vnet_device_per_worker_data_t;
49b3bb1010SDamjan Marion
50b3bb1010SDamjan Mariontypedef struct
51b3bb1010SDamjan Marion{
52b3bb1010SDamjan Marion  vnet_device_per_worker_data_t *workers;
53586afd76SDamjan Marion  uword first_worker_thread_index;
54586afd76SDamjan Marion  uword last_worker_thread_index;
55586afd76SDamjan Marion  uword next_worker_thread_index;
56b3bb1010SDamjan Marion} vnet_device_main_t;
57b3bb1010SDamjan Marion
58eb743fadSDamjan Mariontypedef struct
59eb743fadSDamjan Marion{
60eb743fadSDamjan Marion  u32 hw_if_index;
61eb743fadSDamjan Marion  u32 dev_instance;
62eb743fadSDamjan Marion  u16 queue_id;
634403690cSDamjan Marion  vnet_hw_interface_rx_mode mode;
6426054ea1SChristophe Fontaine  u32 interrupt_pending;
65eb743fadSDamjan Marion} vnet_device_and_queue_t;
66eb743fadSDamjan Marion
67eb743fadSDamjan Mariontypedef struct
68eb743fadSDamjan Marion{
69eb743fadSDamjan Marion  vnet_device_and_queue_t *devices_and_queues;
70153646e8SDamjan Marion  vlib_node_state_t enabled_node_state;
71eb743fadSDamjan Marion} vnet_device_input_runtime_t;
72eb743fadSDamjan Marion
73b3bb1010SDamjan Marionextern vnet_device_main_t vnet_device_main;
7451327ac5SDamjan Marionextern vlib_node_registration_t device_input_node;
757dc4146eSDamjan Marionextern const u32 device_input_next_node_advance[];
76bd846cdcSDamjan Marionextern const u32 device_input_next_node_flags[];
7751327ac5SDamjan Marion
78eb743fadSDamjan Marionstatic inline void
794403690cSDamjan Marionvnet_hw_interface_set_input_node (vnet_main_t * vnm, u32 hw_if_index,
804403690cSDamjan Marion				  u32 node_index)
81eb743fadSDamjan Marion{
82eb743fadSDamjan Marion  vnet_hw_interface_t *hw = vnet_get_hw_interface (vnm, hw_if_index);
83eb743fadSDamjan Marion  hw->input_node_index = node_index;
84eb743fadSDamjan Marion}
85eb743fadSDamjan Marion
864403690cSDamjan Marionvoid vnet_hw_interface_assign_rx_thread (vnet_main_t * vnm, u32 hw_if_index,
874403690cSDamjan Marion					 u16 queue_id, uword thread_index);
884403690cSDamjan Marionint vnet_hw_interface_unassign_rx_thread (vnet_main_t * vnm, u32 hw_if_index,
894403690cSDamjan Marion					  u16 queue_id);
904403690cSDamjan Marionint vnet_hw_interface_set_rx_mode (vnet_main_t * vnm, u32 hw_if_index,
914403690cSDamjan Marion				   u16 queue_id,
924403690cSDamjan Marion				   vnet_hw_interface_rx_mode mode);
934403690cSDamjan Marionint vnet_hw_interface_get_rx_mode (vnet_main_t * vnm, u32 hw_if_index,
944403690cSDamjan Marion				   u16 queue_id,
954403690cSDamjan Marion				   vnet_hw_interface_rx_mode * mode);
96eb743fadSDamjan Marion
97b3bb1010SDamjan Marionstatic inline u64
98b3bb1010SDamjan Marionvnet_get_aggregate_rx_packets (void)
99b3bb1010SDamjan Marion{
100b3bb1010SDamjan Marion  vnet_device_main_t *vdm = &vnet_device_main;
101b3bb1010SDamjan Marion  u64 sum = 0;
102b3bb1010SDamjan Marion  vnet_device_per_worker_data_t *pwd;
103b3bb1010SDamjan Marion
104b3bb1010SDamjan Marion  vec_foreach (pwd, vdm->workers) sum += pwd->aggregate_rx_packets;
105b3bb1010SDamjan Marion
106b3bb1010SDamjan Marion  return sum;
107b3bb1010SDamjan Marion}
108b3bb1010SDamjan Marion
109b3bb1010SDamjan Marionstatic inline void
110586afd76SDamjan Marionvnet_device_increment_rx_packets (u32 thread_index, u64 count)
111b3bb1010SDamjan Marion{
112b3bb1010SDamjan Marion  vnet_device_main_t *vdm = &vnet_device_main;
113b3bb1010SDamjan Marion  vnet_device_per_worker_data_t *pwd;
114b3bb1010SDamjan Marion
115586afd76SDamjan Marion  pwd = vec_elt_at_index (vdm->workers, thread_index);
116b3bb1010SDamjan Marion  pwd->aggregate_rx_packets += count;
117b3bb1010SDamjan Marion}
118b3bb1010SDamjan Marion
119eb743fadSDamjan Marionstatic_always_inline vnet_device_and_queue_t *
120eb743fadSDamjan Marionvnet_get_device_and_queue (vlib_main_t * vm, vlib_node_runtime_t * node)
121eb743fadSDamjan Marion{
122eb743fadSDamjan Marion  vnet_device_input_runtime_t *rt = (void *) node->runtime_data;
123eb743fadSDamjan Marion  return rt->devices_and_queues;
124eb743fadSDamjan Marion}
125eb743fadSDamjan Marion
126153646e8SDamjan Marionstatic_always_inline uword
127153646e8SDamjan Marionvnet_get_device_input_thread_index (vnet_main_t * vnm, u32 hw_if_index,
128153646e8SDamjan Marion				    u16 queue_id)
129153646e8SDamjan Marion{
130153646e8SDamjan Marion  vnet_hw_interface_t *hw = vnet_get_hw_interface (vnm, hw_if_index);
131153646e8SDamjan Marion  ASSERT (queue_id < vec_len (hw->input_node_thread_index_by_queue));
132153646e8SDamjan Marion  return hw->input_node_thread_index_by_queue[queue_id];
133153646e8SDamjan Marion}
134153646e8SDamjan Marion
135eb743fadSDamjan Marionstatic_always_inline void
136eb743fadSDamjan Marionvnet_device_input_set_interrupt_pending (vnet_main_t * vnm, u32 hw_if_index,
137eb743fadSDamjan Marion					 u16 queue_id)
138eb743fadSDamjan Marion{
139153646e8SDamjan Marion  vlib_main_t *vm;
140153646e8SDamjan Marion  vnet_hw_interface_t *hw;
141153646e8SDamjan Marion  vnet_device_input_runtime_t *rt;
142153646e8SDamjan Marion  vnet_device_and_queue_t *dq;
143153646e8SDamjan Marion  uword idx;
144153646e8SDamjan Marion
145153646e8SDamjan Marion  hw = vnet_get_hw_interface (vnm, hw_if_index);
146153646e8SDamjan Marion  idx = vnet_get_device_input_thread_index (vnm, hw_if_index, queue_id);
147153646e8SDamjan Marion  vm = vlib_mains[idx];
148153646e8SDamjan Marion  rt = vlib_node_get_runtime_data (vm, hw->input_node_index);
149153646e8SDamjan Marion  idx = hw->dq_runtime_index_by_queue[queue_id];
150153646e8SDamjan Marion  dq = vec_elt_at_index (rt->devices_and_queues, idx);
1515b718d5cSSirshak Das
1525b718d5cSSirshak Das  clib_atomic_store_rel_n (&(dq->interrupt_pending), 1);
153153646e8SDamjan Marion
154153646e8SDamjan Marion  vlib_node_set_interrupt_pending (vm, hw->input_node_index);
155eb743fadSDamjan Marion}
156eb743fadSDamjan Marion
1575b718d5cSSirshak Das/*
1585b718d5cSSirshak Das * Acquire RMW Access
1595b718d5cSSirshak Das * Paired with Release Store in vnet_device_input_set_interrupt_pending
1605b718d5cSSirshak Das */
16132f4e18cSDave Barach#define foreach_device_and_queue(var,vec)                       \
16232f4e18cSDave Barach  for (var = (vec); var < vec_end (vec); var++)                 \
16332f4e18cSDave Barach    if ((var->mode == VNET_HW_INTERFACE_RX_MODE_POLLING)        \
1645b718d5cSSirshak Das        || clib_atomic_swap_acq_n (&((var)->interrupt_pending), 0))
165153646e8SDamjan Marion
1668bdc63b6SDamjan Marion#endif /* included_vnet_vnet_device_h */
1678bdc63b6SDamjan Marion
1688bdc63b6SDamjan Marion/*
1698bdc63b6SDamjan Marion * fd.io coding-style-patch-verification: ON
1708bdc63b6SDamjan Marion *
1718bdc63b6SDamjan Marion * Local Variables:
1728bdc63b6SDamjan Marion * eval: (c-set-style "gnu")
1738bdc63b6SDamjan Marion * End:
1748bdc63b6SDamjan Marion */
175