i40e_bm.h 11.2 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
        uint64_t base;
        uint32_t len;
        uint32_t fetch_head;
        uint32_t &reg_head;
        uint32_t &reg_tail;

        bool enabled;
        size_t desc_len;
77
        uint32_t pending_fetches;
Antoine Kaufmann's avatar
Antoine Kaufmann committed
78
79

        void trigger_fetch();
80
        void data_fetch(const void *desc, uint32_t idx, uint64_t addr, size_t len);
Antoine Kaufmann's avatar
Antoine Kaufmann committed
81
        void desc_writeback(const void *desc, uint32_t idx);
82
83
        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
84

85
86
87
        // returns how many descriptors the queue can fetch max during the next
        // fetch: default UINT32_MAX, but can be overriden by child classes
        virtual uint32_t max_fetch_capacity();
88
        // called when a descriptor is fetched
Antoine Kaufmann's avatar
Antoine Kaufmann committed
89
        virtual void desc_fetched(void *desc, uint32_t idx) = 0;
90
91
        // called when data is fetched
        virtual void data_fetched(void *desc, uint32_t idx, void *data) = 0;
Antoine Kaufmann's avatar
Antoine Kaufmann committed
92
        virtual void desc_written_back(uint32_t idx);
93
94
95
        void desc_done(uint32_t idx);
        // dummy function, needs to be overriden if interrupts are required
        virtual void interrupt();
Antoine Kaufmann's avatar
Antoine Kaufmann committed
96
97
98

    public:
        queue_base(uint32_t &reg_head_, uint32_t &reg_tail_);
99
        virtual void reset();
Antoine Kaufmann's avatar
Antoine Kaufmann committed
100
        void reg_updated();
101
        bool is_enabled();
Antoine Kaufmann's avatar
Antoine Kaufmann committed
102
103
104
105
106
107
};

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

108
109
110
111
112
113
114
115
116
117
118
        // 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);
119
120
121
122
123

        // 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
124
        virtual void desc_fetched(void *desc, uint32_t idx);
125
126
        // 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
127
128
129
130
131
132
133
134
135

        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
136
137
138
139
140
141
// host memory cache
class host_mem_cache {
    protected:
        static const uint16_t MAX_SEGMENTS = 0x1000;

        struct segment {
142
            uint64_t addr;
Antoine Kaufmann's avatar
Antoine Kaufmann committed
143
144
145
146
147
148
149
            uint16_t pgcount;
            bool valid;
            bool direct;
        };

        i40e_bm &dev;
        segment segs[MAX_SEGMENTS];
150

Antoine Kaufmann's avatar
Antoine Kaufmann committed
151
    public:
152
153
154
155
156
        class mem_op : public dma_base {
            public:
                bool failed;
        };

Antoine Kaufmann's avatar
Antoine Kaufmann committed
157
        host_mem_cache(i40e_bm &dev);
158
        void reset();
Antoine Kaufmann's avatar
Antoine Kaufmann committed
159
        void reg_updated(uint64_t addr);
160
161
162

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

165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
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;

        void ctx_fetched();
        void ctx_written_back();

181
        virtual void interrupt();
182
183
184
185
186
187
188
        virtual void initialize() = 0;

    public:
        bool enabling;
        size_t idx;
        uint32_t &reg_ena;
        uint32_t &fpm_basereg;
189
        uint32_t &reg_intqctl;
190
191
192
193
194
195
        size_t ctx_size;
        void *ctx;

        uint32_t reg_dummy_head;

        lan_queue_base(lan &lanmgr_, uint32_t &reg_tail, size_t idx_,
196
197
                uint32_t &reg_ena_, uint32_t &fpm_basereg, uint32_t &reg_intqctl,
                uint16_t ctx_size);
198
        virtual void reset();
199
200
201
202
203
204
        void enable();
        void disable();
};

class lan_queue_tx : public lan_queue_base {
    protected:
205
206
207
208
209
210
211
212
213
214
215
        class dma_hwb : public dma_base {
            protected:
                lan_queue_tx &queue;
            public:
                uint32_t head;
                uint32_t next_head;
                dma_hwb(lan_queue_tx &queue_, uint32_t head_, uint32_t qlen);
                virtual ~dma_hwb();
                virtual void done();
        };

Antoine Kaufmann's avatar
Antoine Kaufmann committed
216
217
218
219
        static const uint16_t MTU = 2048;
        uint8_t pktbuf[MTU];
        uint16_t pktbuf_len;

220
221
222
223
        bool hwb;
        uint64_t hwb_addr;

        virtual void initialize();
224
225
226
227
228

        virtual void desc_fetched(void *desc, uint32_t idx);
        virtual void data_fetched(void *desc, uint32_t idx, void *data);
        void desc_writeback(const void *desc, uint32_t idx);

229
230
    public:
        lan_queue_tx(lan &lanmgr_, uint32_t &reg_tail, size_t idx,
231
232
                uint32_t &reg_ena, uint32_t &fpm_basereg,
                uint32_t &reg_intqctl);
233
234
235
236
};

class lan_queue_rx : public lan_queue_base {
    protected:
237
238
239
240
241
        struct desc_cache {
            uint64_t buf;
            uint64_t hbuf;
        };

242
243
244
245
246
        uint16_t dbuff_size;
        uint16_t hbuff_size;
        uint16_t rxmax;
        bool crc_strip;

247
248
249
250
251
252
        static const uint16_t DCACHE_SIZE = 128;
        struct desc_cache dcache[DCACHE_SIZE];
        uint32_t dcache_first_idx;
        uint16_t dcache_first_pos;
        uint16_t dcache_first_cnt;

253
        virtual void initialize();
254

255
        virtual uint32_t max_fetch_capacity();
256
257
258
        virtual void desc_fetched(void *desc, uint32_t idx);
        virtual void data_fetched(void *desc, uint32_t idx, void *data);

259
260
    public:
        lan_queue_rx(lan &lanmgr_, uint32_t &reg_tail, size_t idx,
261
262
                uint32_t &reg_ena, uint32_t &fpm_basereg,
                uint32_t &reg_intqctl);
263
        virtual void reset();
264
        void packet_received(const void *data, size_t len);
265
266
};

267
268
269
// rx tx management
class lan {
    protected:
270
271
272
273
        friend class lan_queue_base;
        friend class lan_queue_tx;
        friend class lan_queue_rx;

274
275
        i40e_bm &dev;
        const size_t num_qs;
276
277
278
        lan_queue_rx **rxqs;
        lan_queue_tx **txqs;

279
280
    public:
        lan(i40e_bm &dev, size_t num_qs);
281
        void reset();
282
283
        void qena_updated(uint16_t idx, bool rx);
        void tail_updated(uint16_t idx, bool rx);
284
        void packet_received(const void *data, size_t len);
285
};
Antoine Kaufmann's avatar
Antoine Kaufmann committed
286

Antoine Kaufmann's avatar
Antoine Kaufmann committed
287
288
289
290
291
292
293
294
295
296
297
298
299
300
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;
301
    friend class host_mem_cache;
302
303
    friend class lan;
    friend class lan_queue_base;
304
305
    friend class lan_queue_rx;
    friend class lan_queue_tx;
306
    friend class shadow_ram;
Antoine Kaufmann's avatar
Antoine Kaufmann committed
307
308
309
310
311
312

    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;
313
    static const uint32_t NUM_VSIS = 384;
314
    static const uint16_t MAX_MTU = 2048;
Antoine Kaufmann's avatar
Antoine Kaufmann committed
315
316
317
318
319
320

    struct i40e_regs {
        uint32_t glgen_rstctl;
        uint32_t gllan_rctl_0;
        uint32_t pfint_lnklst0;
        uint32_t pfint_icr0_ena;
Antoine Kaufmann's avatar
Antoine Kaufmann committed
321
        uint32_t pfint_icr0;
Antoine Kaufmann's avatar
Antoine Kaufmann committed
322
323
324
325
326
327
328
329
330
331
332

        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];
333
        uint32_t qtx_tail[NUM_QUEUES];
Antoine Kaufmann's avatar
Antoine Kaufmann committed
334
335
        uint32_t qint_rqctl[NUM_QUEUES];
        uint32_t qrx_ena[NUM_QUEUES];
336
        uint32_t qrx_tail[NUM_QUEUES];
Antoine Kaufmann's avatar
Antoine Kaufmann committed
337

338
339
340
341
342
        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
343
344
345
346
347
348
349
        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
350
351
352
353
354
355
356
357
358
        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
359
360

        uint32_t glqf_hkey[13];
Antoine Kaufmann's avatar
Antoine Kaufmann committed
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
    };

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
379
    host_mem_cache hmc;
Antoine Kaufmann's avatar
Antoine Kaufmann committed
380
    shadow_ram shram;
381
    lan lanmgr;
Antoine Kaufmann's avatar
Antoine Kaufmann committed
382
383
384
385
386
387
388
389
390
391
392

    /** 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);

393
    void reset(bool indicate_done);
Antoine Kaufmann's avatar
Antoine Kaufmann committed
394
395
};

396
397
398
// places the tcp checksum in the packet (assuming ipv4)
void xsum_tcp(void *tcphdr, size_t l4len);

Antoine Kaufmann's avatar
Antoine Kaufmann committed
399
} // namespace corundum