1/**
2 * \file
3 * \brief Header file for net_queue_manager.h
4 */
5
6/*
7 * Copyright (c) 2007-12 ETH Zurich.
8 * All rights reserved.
9 *
10 * This file is distributed under the terms in the attached LICENSE file.
11 * If you do not find this file, copies can be found by writing to:
12 * ETH Zurich D-INFK, Universitaetstrasse 6, CH-8092 Zurich. Attn: Systems Group.
13 */
14
15#ifndef net_queue_manager_H
16#define net_queue_manager_H
17
18#include <barrelfish/barrelfish.h>
19#include <barrelfish/bulk_transfer.h>
20#include <netbench/netbench.h>
21#include <procon/procon.h>
22#include <barrelfish/net_constants.h>
23#include <net_interfaces/flags.h>
24#include <devif/queue_interface.h>
25
26/*****************************************************************
27 * Constants:
28 *****************************************************************/
29
30#define MAX_NR_TRANSMIT_PBUFS 80
31
32#define RECEIVE_CONNECTION 0
33#define TRANSMIT_CONNECTION 1
34
35/*****************************************************************
36 * common data-structures
37 *****************************************************************/
38
39#define MAX_PAUSE_BUFFER        10
40
41struct bufdesc {
42    char pkt_data[1600];
43    size_t pkt_len;
44    uint64_t flags;
45};
46
47struct filter {
48    uint64_t filter_id;
49    uint64_t filter_type;
50    uint8_t *data;
51    int32_t len;
52    bool paused;
53    struct bufdesc pause_buffer[MAX_PAUSE_BUFFER];
54    int pause_bufpos;
55    struct buffer_descriptor *buffer;
56    struct filter *next;
57};
58
59// State required in TX path to remember information about buffers
60struct buffer_state_metadata {
61    struct devq *device_queue;
62    uint64_t offset;
63//    uint64_t spp_index;
64//    uint64_t tx_pending;
65};
66
67struct bsm_queue {
68    size_t buffer_state_size; // size of slot queue
69    size_t buffer_state_head; // the index pointer
70    size_t buffer_state_used; // how many of them are used?
71    struct buffer_state_metadata *buffer_state;  // array of slots
72};
73
74
75struct buffer_descriptor {
76    uint64_t buffer_id;  // buffer identifier
77    struct devq *device_queue; // device queue
78    struct capref cap; // cap backing the buffer memory
79//    struct shared_pool_private *spp_prv; // shared producer consumer pool
80
81    struct bsm_queue rxq; // queue for receive path
82    struct bsm_queue txq; // queue for send path
83
84    uint8_t role;  // Role of buffer (RX/TX)
85    lpaddr_t pa;    // Physical address of buffer
86    uint64_t bytes; // Size of buffer in bytes
87    void *va;       // Virtual address of buffer
88    uint64_t queueid; // The queueid to which this buffer belongs
89
90    struct buffer_descriptor *next; // The next buffer (in singly linked list)
91    struct filter* tx_filters;  // List of filters associated with this buf
92};
93
94enum pbuf_lifecycle {
95    PBUF_REGISTERED,
96    PKT_RECEIVED,
97    RECV_NOTIFICATION_GENERATED,
98    RECV_NOTIFICATION_SENT,
99    PKT_ARRIVED_APP, // From here bellow, everything will be in APP
100    PKT_REACHED_APP,
101    PBUF_REGISTER_STARTED,
102    PBUF_REGISTER_GENERATED,
103    PBUF_REGISTER_SENT
104};
105
106
107struct driver_buffer {
108    uint64_t pa;
109    void    *va;
110    size_t   len;
111    void    *opaque;
112    uint64_t flags;
113};
114
115struct driver_rx_buffer {
116    size_t len;
117    void  *opaque;
118};
119
120
121#define MAX_STAT_EVENTS   5   // This is the count of pbuf_lifecycle events
122#define MAX_CHUNKS   5 // Max no. of allowed chunks for single packet
123
124
125/* This is client_closure for network service */
126struct client_closure {
127    int cl_no;  // Client indentifier
128    struct buffer_descriptor *buffer_ptr; // buffer associated with client
129    struct shared_pool_private *spp_ptr; // shared pool associted with client
130
131    /* Following two are used by packet transmit logic */
132    uint64_t tx_index;  // index of which is next slot to be sent
133    uint64_t rx_index;  // index of which is next slot to be received
134
135    uint64_t queueid; // The queueid to which this buffer belongs
136    struct devq *app_connection; // Application device queue
137    regionid_t region_id;
138    uint8_t role;  // Role of buffer (RX/TX)
139    uint64_t buffer_id;  // buffer identifier
140
141    // Place to store data when there are multiple parts to the packet
142    struct driver_buffer driver_buff_list[MAX_CHUNKS]; // list of already seen chunks
143    uint8_t chunk_counter; // How many chunks are already seen?
144
145    // For debugging and benchmarking help
146    uint8_t debug_print; // To control connection level debug prints
147    uint8_t debug_state;  // debug state for rx benchmark
148    uint8_t debug_state_tx; // debug state of tx benchmark
149    uint64_t start_ts;  // timestap of start of rx benchmark
150    uint64_t start_ts_tx; // timestamp of start of tx benchmark
151    uint64_t out_trigger_counter;  // index marking when to stop tx benchmark
152
153
154    // Some statistics.  Not needed for functionality
155    uint64_t pkt_count;  // # packets
156    uint64_t in_filter_matched;  // # total filters matched
157    uint64_t in_filter_matched_f; // # failed processing of matched filter
158    uint64_t in_filter_matched_p; // # successful processing of matched filter
159
160    uint64_t dropped_pkt_count;  // # packets dropped (for no space in hw-queue)
161    uint64_t pbuf_count;  // # pbufs sent
162    uint64_t in_dropped_app_buf_full; // # packets dropped for lack of buffers
163}; /* holds info about how much data is transferred to NIC. */
164
165/*****************************************************************
166 * Driver states
167 * ***************************************************************/
168
169
170/*******************************************************************
171 *  Following functions must be implemented by the driver which is
172 *  using the library.
173 ******************************************************************/
174typedef void (*ether_get_mac_address_t)(uint8_t *mac);
175typedef void (*ether_terminate_queue)(void);
176typedef errval_t (*ether_transmit_pbuf_list_t)(
177    struct driver_buffer *buffers,
178    size_t                count);
179typedef uint64_t (*ether_get_tx_free_slots)(void);
180typedef bool (*ether_handle_free_TX_slot)(void);
181typedef errval_t (*ether_rx_register_buffer)(uintptr_t paddr, void *vaddr,
182                                               void *opaque);
183typedef uint64_t (*ether_rx_get_free_slots)(void);
184
185
186
187/*****************************************************************/
188
189/**
190 * Initialize pair of ethernet RX/TX queues.
191 *
192 * @param service_name             Service name for the card to which this queue
193 *                                   belongs
194 * @param queueid                  Queue index
195 * @param get_mac_ptr              Callback that returns MAC address of the card
196 * @param terminate_queue_ptr      Callback that terminates the queue driver, or
197 *                                   NULL if this is not supported.
198 * @param transmit_ptr             Callback to put a buffer chain in TX queue
199 * @param tx_free_slots_ptr        Callback that returns number of free slots in
200 *                                   TX queue
201 * @param handle_free_tx_slots_ptr Callback to remove transmitted buffers from
202 *                                   queue
203 * @param rx_buffer_size           Expected RX buffer size
204 * @param rx_register_buffer_ptr   Callback to register buffer for RX queue
205 * @param rx_get_free_slots_ptr    Callback that returns number of free slots in
206 *                                   RX queue
207 */
208void ethersrv_init(
209    char *service_name,
210    uint64_t queueid,
211    ether_get_mac_address_t     get_mac_ptr,
212    ether_terminate_queue       terminate_queue_ptr,
213    ether_transmit_pbuf_list_t  transmit_ptr,
214    ether_get_tx_free_slots     tx_free_slots_ptr,
215    ether_handle_free_TX_slot   handle_free_tx_slots_ptr,
216    size_t                      rx_buffer_size,
217    ether_rx_register_buffer    rx_register_buffer_ptr,
218    ether_rx_get_free_slots     rx_get_free_slots_ptr);
219
220
221bool waiting_for_netd(void);
222
223/**
224 * Pass command line argument not used by driver to library. Can be called
225 * multiple times, once for each parameter.
226 */
227void ethersrv_argument(const char* arg);
228
229bool handle_tx_done(void *opaque);
230
231struct buffer_descriptor *find_buffer(uint64_t buffer_id);
232
233void process_received_packet(struct driver_rx_buffer *buffer, size_t count,
234    uint64_t flags);
235
236// For local loopback device
237void sf_process_received_packet_lo(void *opaque_rx, void *opaque_tx,
238        size_t pkt_len, bool is_last, uint64_t flags);
239
240/* for frag.c */
241bool handle_fragmented_packet(void* packet, size_t len, uint64_t flags);
242
243
244struct filter *execute_filters(void *data, size_t len);
245
246/* FIXME: put this into the local include file.  */
247bool copy_packet_to_user(struct buffer_descriptor* buffer,
248				void *data, uint64_t len, uint64_t flags);
249
250void do_pending_work_for_all(void);
251
252//debug
253void print_statistics(void);
254
255void check_queues(void);
256
257
258// For recording statistics
259
260enum Recorded_Events {
261    RE_ALL = 0,
262    RE_FILTER,
263    RE_COPY,
264    RE_DROPPED,
265    RE_USEFUL, // used
266    RE_PBUF_REG, // used
267    RE_PROCESSING_ALL, // used
268    RE_RX_ALL, // used
269    RE_PENDING_WORK,
270    RE_PENDING_1,
271    RE_PENDING_2,
272    RE_PENDING_3,
273    RE_PENDING_4,
274
275    RE_TX_NOTI_CS,
276    RE_TX_T,
277    RE_TX_SP_S,
278    RE_TX_SP_F,
279    RE_TX_DONE,
280    RE_TX_W_ALL,
281    RE_TX_DONE_NN,
282    RE_TX_DONE_N,
283    RE_TX_SP_MSG,
284    RE_TX_SP_MSG_Q,
285    EVENT_LIST_SIZE
286};
287
288extern struct netbench_details *bm;
289
290struct net_soft_filter_state
291{
292    struct waitset_chanstate initialization_completed;
293};
294
295// **************************************
296// Use of optimised memcpy for SCC
297
298void *memcpy_fast(void *dst0, const void *src0, size_t length);
299
300#endif // net_queue_manager_H
301