i40e_bm.h 9.31 KB
Newer Older
Antoine Kaufmann's avatar
Antoine Kaufmann committed
1
2
3
4
5
6
7
8
9
10
#pragma once

#include <list>
#include <vector>
#include <stdint.h>
extern "C" {
#include <cosim_pcie_proto.h>
}
#include <nicbm.h>

11
12
struct i40e_aq_desc;

Antoine Kaufmann's avatar
Antoine Kaufmann committed
13
14
15
namespace i40e {

class i40e_bm;
16
class lan;
Antoine Kaufmann's avatar
Antoine Kaufmann committed
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35

class dma_base : public nicbm::DMAOp {
    public:
        /** i40e_bm will call this when dma is done */
        virtual void done() = 0;
};

class queue_base {
    protected:
        class dma_fetch : public dma_base {
            protected:
                queue_base &queue;
            public:
                uint32_t index;
                dma_fetch(queue_base &queue_, size_t len);
                virtual ~dma_fetch();
                virtual void done();
        };

36
37
38
39
40
41
42
43
44
45
46
47
        class dma_data_fetch : public dma_base {
            protected:
                queue_base &queue;
            public:
                uint32_t index;
                void *desc;
                dma_data_fetch(queue_base &queue_, size_t len, const void *desc,
                        size_t desc_len);
                virtual ~dma_data_fetch();
                virtual void done();
        };

Antoine Kaufmann's avatar
Antoine Kaufmann committed
48
49
50
51
52
53
54
55
56
57
        class dma_wb : public dma_base {
            protected:
                queue_base &queue;
            public:
                uint32_t index;
                dma_wb(queue_base &queue_, size_t len);
                virtual ~dma_wb();
                virtual void done();
        };

58
59
60
61
62
63
64
65
66
67
68
        class dma_data_wb : public dma_base {
            protected:
                queue_base &queue;
                dma_wb &desc_dma;
            public:
                uint32_t index;
                dma_data_wb(queue_base &queue_, size_t len, dma_wb &desc_dma_);
                virtual ~dma_data_wb();
                virtual void done();
        };

Antoine Kaufmann's avatar
Antoine Kaufmann committed
69
70
71
72
73
74
75
76
77
78
        uint64_t base;
        uint32_t len;
        uint32_t fetch_head;
        uint32_t &reg_head;
        uint32_t &reg_tail;

        bool enabled;
        size_t desc_len;

        void trigger_fetch();
79
        void data_fetch(const void *desc, uint32_t idx, uint64_t addr, size_t len);
Antoine Kaufmann's avatar
Antoine Kaufmann committed
80
        void desc_writeback(const void *desc, uint32_t idx);
81
82
        void desc_writeback_indirect(const void *desc, uint32_t idx,
                uint64_t data_addr, const void *data, size_t data_len);
Antoine Kaufmann's avatar
Antoine Kaufmann committed
83

84
        // called when a descriptor is fetched
Antoine Kaufmann's avatar
Antoine Kaufmann committed
85
        virtual void desc_fetched(void *desc, uint32_t idx) = 0;
86
87
        // called when data is fetched
        virtual void data_fetched(void *desc, uint32_t idx, void *data) = 0;
Antoine Kaufmann's avatar
Antoine Kaufmann committed
88
89
90
91
92
        virtual void desc_written_back(uint32_t idx);

    public:
        queue_base(uint32_t &reg_head_, uint32_t &reg_tail_);
        void reg_updated();
93
        bool is_enabled();
Antoine Kaufmann's avatar
Antoine Kaufmann committed
94
95
96
97
98
99
};

class queue_admin_tx : public queue_base {
    protected:
        i40e_bm &dev;

100
101
102
103
104
105
106
107
108
109
110
        // prepare completion descriptor (fills flags, and return value)
        void desc_compl_prepare(struct i40e_aq_desc *d, uint16_t retval,
                uint16_t extra_flags);

        // complete direct response
        void desc_complete(struct i40e_aq_desc *d, uint32_t idx,
                uint16_t retval, uint16_t extra_flags = 0);
        // complete indirect response
        void desc_complete_indir(struct i40e_aq_desc *d, uint32_t idx,
                uint16_t retval, const void *data, size_t len,
                uint16_t extra_flags = 0);
111
112
113
114
115

        // run command
        virtual void cmd_run(void *desc, uint32_t idx, void *data);

        // called by base class when a descriptor has been fetched
Antoine Kaufmann's avatar
Antoine Kaufmann committed
116
        virtual void desc_fetched(void *desc, uint32_t idx);
117
118
        // called by basee class when data for a descriptor has been fetched
        virtual void data_fetched(void *desc, uint32_t idx, void *data);
Antoine Kaufmann's avatar
Antoine Kaufmann committed
119
120
121
122
123
124
125
126
127

        uint64_t &reg_base;
        uint32_t &reg_len;
    public:
        queue_admin_tx(i40e_bm &dev_, uint64_t &reg_base_,
                uint32_t &reg_len_, uint32_t &reg_head_, uint32_t &reg_tail_);
        void reg_updated();
};

Antoine Kaufmann's avatar
Antoine Kaufmann committed
128
129
130
131
132
133
// host memory cache
class host_mem_cache {
    protected:
        static const uint16_t MAX_SEGMENTS = 0x1000;

        struct segment {
134
            uint64_t addr;
Antoine Kaufmann's avatar
Antoine Kaufmann committed
135
136
137
138
139
140
141
            uint16_t pgcount;
            bool valid;
            bool direct;
        };

        i40e_bm &dev;
        segment segs[MAX_SEGMENTS];
142

Antoine Kaufmann's avatar
Antoine Kaufmann committed
143
    public:
144
145
146
147
148
        class mem_op : public dma_base {
            public:
                bool failed;
        };

Antoine Kaufmann's avatar
Antoine Kaufmann committed
149
150
        host_mem_cache(i40e_bm &dev);
        void reg_updated(uint64_t addr);
151
152
153

        // issue a hmc memory operation (address is in the context
        void issue_mem_op(mem_op &op);
Antoine Kaufmann's avatar
Antoine Kaufmann committed
154
155
};

156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
class lan_queue_base : public queue_base {
    protected:
        class qctx_fetch : public host_mem_cache::mem_op {
            public:
                lan_queue_base &lq;

                qctx_fetch(lan_queue_base &lq_);
                virtual void done();
        };


        lan &lanmgr;

        // called by base class when a descriptor has been fetched
        virtual void desc_fetched(void *desc, uint32_t idx);
        // called by basee class when data for a descriptor has been fetched
        virtual void data_fetched(void *desc, uint32_t idx, void *data);

        void ctx_fetched();
        void ctx_written_back();

        virtual void initialize() = 0;

    public:
        bool enabling;
        size_t idx;
        uint32_t &reg_ena;
        uint32_t &fpm_basereg;
        size_t ctx_size;
        void *ctx;

        uint32_t reg_dummy_head;

        lan_queue_base(lan &lanmgr_, uint32_t &reg_tail, size_t idx_,
                uint32_t &reg_ena_, uint32_t &fpm_basereg, uint16_t ctx_size);
        void enable();
        void disable();
};

class lan_queue_tx : public lan_queue_base {
    protected:
        bool hwb;
        uint64_t hwb_addr;

        virtual void initialize();
    public:
        lan_queue_tx(lan &lanmgr_, uint32_t &reg_tail, size_t idx,
                uint32_t &reg_ena, uint32_t &fpm_basereg);
};

class lan_queue_rx : public lan_queue_base {
    protected:
        uint16_t dbuff_size;
        uint16_t hbuff_size;
        uint16_t rxmax;
        bool crc_strip;

        virtual void initialize();
    public:
        lan_queue_rx(lan &lanmgr_, uint32_t &reg_tail, size_t idx,
                uint32_t &reg_ena, uint32_t &fpm_basereg);
};

219
220
221
// rx tx management
class lan {
    protected:
222
223
224
225
        friend class lan_queue_base;
        friend class lan_queue_tx;
        friend class lan_queue_rx;

226
227
        i40e_bm &dev;
        const size_t num_qs;
228
229
230
        lan_queue_rx **rxqs;
        lan_queue_tx **txqs;

231
232
233
234
235
    public:
        lan(i40e_bm &dev, size_t num_qs);
        void qena_updated(uint16_t idx, bool rx);
        void tail_updated(uint16_t idx, bool rx);
};
Antoine Kaufmann's avatar
Antoine Kaufmann committed
236

Antoine Kaufmann's avatar
Antoine Kaufmann committed
237
238
239
240
241
242
243
244
245
246
247
248
249
250
class shadow_ram {
    protected:
        i40e_bm &dev;

    public:
        shadow_ram(i40e_bm &dev);
        void reg_updated();
        uint16_t read(uint16_t addr);
        void write(uint16_t addr, uint16_t val);
};

class i40e_bm : public nicbm::Runner::Device {
protected:
    friend class queue_admin_tx;
251
    friend class host_mem_cache;
252
253
    friend class lan;
    friend class lan_queue_base;
254
    friend class shadow_ram;
Antoine Kaufmann's avatar
Antoine Kaufmann committed
255
256
257
258
259
260

    static const unsigned BAR_REGS = 0;
    static const unsigned BAR_IO = 2;

    static const uint32_t NUM_QUEUES = 1536;
    static const uint32_t NUM_PFINTS = 512;
261
    static const uint16_t MAX_MTU = 2048;
Antoine Kaufmann's avatar
Antoine Kaufmann committed
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278

    struct i40e_regs {
        uint32_t glgen_rstctl;
        uint32_t gllan_rctl_0;
        uint32_t pfint_lnklst0;
        uint32_t pfint_icr0_ena;

        uint32_t pfint_dyn_ctln[NUM_PFINTS - 1];
        uint32_t pfint_lnklstn[NUM_PFINTS - 1];
        uint32_t pfint_raten[NUM_PFINTS - 1];
        uint32_t gllan_txpre_qdis[12];

        uint32_t glnvm_srctl;
        uint32_t glnvm_srdata;

        uint32_t qint_tqctl[NUM_QUEUES];
        uint32_t qtx_ena[NUM_QUEUES];
279
        uint32_t qtx_tail[NUM_QUEUES];
Antoine Kaufmann's avatar
Antoine Kaufmann committed
280
281
        uint32_t qint_rqctl[NUM_QUEUES];
        uint32_t qrx_ena[NUM_QUEUES];
282
        uint32_t qrx_tail[NUM_QUEUES];
Antoine Kaufmann's avatar
Antoine Kaufmann committed
283

284
285
286
287
288
        uint32_t glhmc_lantxbase[16];
        uint32_t glhmc_lantxcnt[16];
        uint32_t glhmc_lanrxbase[16];
        uint32_t glhmc_lanrxcnt[16];

Antoine Kaufmann's avatar
Antoine Kaufmann committed
289
290
291
292
293
294
295
        uint32_t pfhmc_sdcmd;
        uint32_t pfhmc_sddatalow;
        uint32_t pfhmc_sddatahigh;
        uint32_t pfhmc_pdinv;
        uint32_t pfhmc_errorinfo;
        uint32_t pfhmc_errordata;

Antoine Kaufmann's avatar
Antoine Kaufmann committed
296
297
298
299
300
301
302
303
304
        uint64_t pf_atqba;
        uint32_t pf_atqlen;
        uint32_t pf_atqh;
        uint32_t pf_atqt;

        uint64_t pf_arqba;
        uint32_t pf_arqlen;
        uint32_t pf_arqh;
        uint32_t pf_arqt;
Antoine Kaufmann's avatar
Antoine Kaufmann committed
305
306

        uint32_t glqf_hkey[13];
Antoine Kaufmann's avatar
Antoine Kaufmann committed
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
    };

public:
    nicbm::Runner *runner;

    i40e_bm();
    ~i40e_bm();

    virtual void setup_intro(struct cosim_pcie_proto_dev_intro &di);
    virtual void reg_read(uint8_t bar, uint64_t addr, void *dest, size_t len);
    virtual void reg_write(uint8_t bar, uint64_t addr, const void *src,
            size_t len);
    virtual void dma_complete(nicbm::DMAOp &op);
    virtual void eth_rx(uint8_t port, const void *data, size_t len);

protected:
    i40e_regs regs;
    queue_admin_tx pf_atq;
Antoine Kaufmann's avatar
Antoine Kaufmann committed
325
    host_mem_cache hmc;
Antoine Kaufmann's avatar
Antoine Kaufmann committed
326
    shadow_ram shram;
327
    lan lanmgr;
Antoine Kaufmann's avatar
Antoine Kaufmann committed
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342

    /** Read from the I/O bar */
    virtual uint32_t reg_io_read(uint64_t addr);
    /** Write to the I/O bar */
    virtual void reg_io_write(uint64_t addr, uint32_t val);

    /** 32-bit read from the memory bar (should be the default) */
    virtual uint32_t reg_mem_read32(uint64_t addr);
    /** 32-bit write to the memory bar (should be the default) */
    virtual void reg_mem_write32(uint64_t addr, uint32_t val);

    void reset();
};

} // namespace corundum