1/*
2 * Copyright (c) 2007-12 ETH Zurich.
3 * All rights reserved.
4 *
5 * This file is distributed under the terms in the attached LICENSE file.
6 * If you do not find this file, copies can be found by writing to:
7 * ETH Zurich D-INFK, Haldeneggsteig 4, CH-8092 Zurich. Attn: Systems Group.
8 */
9
10#include <stdio.h>
11#include <string.h>
12
13#include <barrelfish/barrelfish.h>
14#include <barrelfish/waitset.h>
15#include <barrelfish/nameservice_client.h>
16#include <lwip/inet.h>
17
18#include <if/e10k_defs.h>
19
20#include "port_management_support.h"
21#include "device_manager_debug.h"
22
23
24
25/******************************************************************************
26 * Local state
27 ******************************************************************************/
28
29/** Connection to e10k management service */
30struct e10k_binding *binding = NULL;
31
32/******************************************************************************
33 * Operations for filter interface
34 ******************************************************************************/
35
36// Callback for bind
37static void bind_cb(void *st, errval_t err, struct e10k_binding *b)
38{
39    assert(err_is_ok(err));
40
41    NDM_DEBUG("Sucessfully connected to management interface\n");
42
43    binding = b;
44    e10k_rpc_client_init(binding);
45}
46
47/** Open connection to management interface */
48static void connect_to_mngif(char *dev_name)
49{
50    errval_t r;
51    iref_t iref;
52    const char *suffix = "_e10kmng";
53    char name[strlen(dev_name) + strlen(suffix) + 1];
54
55    // Build label for management service
56    sprintf(name, "%s%s", dev_name, suffix);
57
58    // Connect to service
59    r = nameservice_blocking_lookup(name, &iref);
60    assert(err_is_ok(r));
61
62    r = e10k_bind(iref, bind_cb, NULL, get_default_waitset(),
63            IDC_BIND_FLAGS_DEFAULT);
64    assert(err_is_ok(r));
65}
66
67/******************************************************************************
68 * Operations for filter interface
69 ******************************************************************************/
70
71static void init_filters(char *dev_name, qid_t qid)
72{
73    NDM_DEBUG("e10_flt: init %s %d\n", dev_name, (int) qid);
74
75    // Check if we are already initialized from another queue
76    if (binding != NULL) {
77        return;
78    }
79
80    connect_to_mngif(dev_name);
81
82    // waiting for connection to succeed.
83    NDM_DEBUG("e10k_init_filters: wait connection\n");
84    while (binding == NULL) {
85        messages_wait_and_handle_next();
86    }
87}
88
89static void reg_arp_filters(uint64_t id, uint64_t len_rx,
90                            uint64_t len_tx)
91{
92    USER_PANIC("reg_arp_filters() not supported in e10k filters");
93}
94
95static errval_t reg_filters(uint16_t port,
96                            port_type_t type,
97                            bufid_t buffer_id_rx,
98                            bufid_t buffer_id_tx,
99                            appid_t appid,
100                            qid_t qid,
101                            uint64_t *id, errval_t *rerr, uint64_t *filter_id)
102{
103    e10k_port_type_t t;
104    assert(binding != NULL);
105
106    NDM_DEBUG("e10k_reg_filters()\n");
107
108    if (type == net_ports_PORT_TCP) {
109        t = e10k_PORT_TCP;
110    } else {
111        t = e10k_PORT_UDP;
112    }
113    errval_t err;
114    err = binding->rpc_tx_vtbl.register_port_filter(binding, buffer_id_rx, buffer_id_tx, qid, t, port, rerr, filter_id);
115
116    return err;
117}
118
119static errval_t unreg_filters(uint64_t filter_id, qid_t qid)
120{
121    assert(binding != NULL);
122
123    NDM_DEBUG("e10k_unreg_filters()\n");
124    errval_t err, rerr;
125    err = binding->rpc_tx_vtbl.unregister_filter(binding, qid, &rerr);
126    assert(err_is_ok(err));
127
128    return rerr;
129}
130
131
132/******************************************************************************
133 * Get signature of this service
134 ******************************************************************************/
135
136static struct filters_tx_vtbl e10k_filts_mng = {
137    .type = "e10k_filters",
138    .init_filters = init_filters,
139    .reg_arp_filters = reg_arp_filters,
140    .reg_filters = reg_filters,
141    .unreg_filters = unreg_filters,
142};
143
144struct filters_tx_vtbl *get_e10k_filt_mng_sign(void)
145{
146    return &e10k_filts_mng;
147}
148