1/*
2 * Copyright (c) 2008, ETH Zurich. All rights reserved.
3 *
4 * This file is distributed under the terms in the attached LICENSE file.
5 * If you do not find this file, copies can be found by writing to:
6 * ETH Zurich D-INFK, Haldeneggsteig 4, CH-8092 Zurich. Attn: Systems Group.
7 */
8/*
9 * e1000.c
10 *
11 *  Created on: Feb 12, 2013
12 *      Author: mao
13 *
14 * NOTES:
15 *      General:
16 *          The driver uses kaluga to probe for supported PCI/e devices. At boot, It might happen
17 *          that kaluga has not yet finished probing PCI devices and your card doesn't get detected.
18 *          If you want the driver automaticaly at boot, try passing device id as a parameter in grub.
19 *          Edit menu.lst:
20 *          module /x86_64/sbin/e1000 deviceid=xxxx
21 *
22 *          If you don't know your device id, use lshw -pci to list available PCI devices.
23 *          Try looking up all devices_id with vendor 0x8086 in the PCI database:
24 *              http://www.pcidatabase.com/vendor_details.php?id=1302
25 *          Your network card should be called some thing with e1000, Intel Pro/1000 or e1000.
26 *
27 *          If you use Simics, also read the Simics note.
28 *
29 *      Simics:
30 *          Currently Simics doesn't provide an EEPROM for the tested network cards and the mac_address
31 *          argument doesn't seem to set the MAC address properly. You will have to specify it manually:
32 *
33 *          e1000 mac=54:10:10:53:00:30
34 *
35 *
36 * This part of the code builds on the original e1000 Barrelfish driver.
37 *
38 */
39#include <stdio.h>
40#include <stdlib.h>
41#include <string.h>
42#include <barrelfish/barrelfish.h>
43#include <barrelfish/nameservice_client.h>
44#include <driverkit/driverkit.h>
45
46#include <if/octopus_defs.h>
47#include <if/e1000_devif_defs.h>
48
49#include <octopus/octopus.h>
50#include <octopus/trigger.h>
51#include <net_queue_manager/net_queue_manager.h>
52#include <trace/trace.h>
53#include <int_route/msix_ctrl.h>
54
55#include <pci/pci_driver_client.h>
56
57#include "e1000n.h"
58#include "test_instr.h"
59
60#if CONFIG_TRACE && NETWORK_STACK_TRACE
61#define TRACE_ETHERSRV_MODE 1
62#endif // CONFIG_TRACE && NETWORK_STACK_TRACE
63
64#define MAX_ALLOWED_PKT_PER_ITERATION   (0xff)  // working value
65
66/* MTU is 1500 bytes, plus Ethernet header plus CRC. */
67#define RX_PACKET_MAX_LEN       (1500 + 14 + 4)
68
69#define PACKET_SIZE_LIMIT       1073741824      /* 1 Gigabyte */
70
71/*****************************************************************
72 * External declarations for net_queue_manager
73 *
74 ****************************************************************/
75uint64_t interrupt_counter;
76
77static void e1000_print_link_status(struct e1000_driver_state *eds)
78{
79    const char *media_type = NULL;
80    e1000_status_t status;
81
82    status = e1000_status_rd(eds->device);
83    e1000_ledctl_rd(eds->device);
84
85    switch (eds->media_type) {
86    case e1000_media_type_copper:
87        media_type = "copper";
88        break;
89    case e1000_media_type_fiber:
90        media_type = "fiber";
91        break;
92    case e1000_media_type_serdes:
93        media_type = "SerDes";
94        break;
95    default:
96        media_type = "Unknown";
97        break;
98    }
99
100    if (e1000_check_link_up(eds->device)) {
101        const char *duplex;
102
103        if (e1000_status_fd_extract(status)) {
104            duplex = "Full";
105        } else {
106            duplex = "Half";
107        }
108
109        switch (e1000_status_speed_extract(status)) {
110        case 0x0:
111            E1000_PRINT("Media type: %s, Link speed: 10 Mb in %s duplex.\n",
112                        media_type, duplex);
113            break;
114        case 0x1:
115            E1000_PRINT("Media type: %s, Link speed: 100 Mb in %s duplex.\n",
116                        media_type, duplex);
117            break;
118        default:
119            E1000_PRINT("Media type: %s, Link speed: 1 Gb in %s duplex.\n",
120                        media_type, duplex);
121            break;
122        }
123    } else {
124        E1000_PRINT("Media type: %s, Link down.\n", media_type);
125    }
126}
127
128
129
130
131/*****************************************************************
132 * Parse MAC address to see if it has a valid format.
133 *
134 ****************************************************************/
135static bool parse_mac(uint8_t *mac, const char *str)
136{
137    for (int i = 0; i < 6; i++) {
138        char *next = NULL;
139        unsigned long val = strtoul(str, &next, 16);
140        if (val > UINT8_MAX || next == NULL || (i == 5 && *next != '\0')
141                || (i < 5 && (*next != ':' && *next != '-'))) {
142            return false; /* parse error */
143        }
144        mac[i] = val;
145        str = next + 1;
146    }
147
148    return true;
149}
150
151static void setup_internal_memory(struct e1000_driver_state * eds)
152{
153    eds->receive_opaque = calloc(sizeof(void *), DRIVER_RECEIVE_BUFFERS);
154    assert(eds->receive_opaque != NULL );
155}
156
157
158/*
159 * Start a MSIx controller client, if possible and requested.
160 */
161static errval_t e1000_init_msix_client(struct e1000_driver_state * eds) {
162
163    errval_t err;
164    int num_bars = pcid_get_bar_num(&eds->pdc);
165    if(num_bars < 3){
166        E1000_DEBUG("Less than 3 BARs received. No MSIx support. #bars=%d\n",
167                num_bars);
168        return PCI_ERR_MSIX_NOTSUP;
169    }
170
171    E1000_DEBUG("MSIx BAR received. Instantiating ctrl client\n");
172    struct capref bar2;
173    lvaddr_t vaddr;
174
175    err = pcid_get_bar_cap(&eds->pdc, 2, &bar2);
176    if (err_is_fail(err)) {
177        DEBUG_ERR(err, "pcid_get_bar_cap");
178        E1000_PRINT_ERROR("Error: pcid_get_bar_cap. Will not initialize"
179                " MSIx controller.\n");
180        return err;
181    }
182
183    err = map_device_cap(bar2, &vaddr);
184    if (err_is_fail(err)) {
185        DEBUG_ERR(err, "pcid_map_bar");
186        E1000_PRINT_ERROR("Error: map_device failed. Will not initialize"
187                " MSIx controller.\n");
188        return err;
189    }
190
191    err = msix_client_init_by_args(eds->args_len, eds->args, (void*) vaddr);
192    if(err == SYS_ERR_IRQ_INVALID){
193        E1000_DEBUG("Card supports MSI-x but legacy interrupt requested by Kaluga");
194        return err;
195    }
196    if(err_is_fail(err)){
197        DEBUG_ERR(err, "msix_client_init");
198        return err;
199    }
200
201    return SYS_ERR_OK;
202}
203
204/*****************************************************************
205 * e1000 interrupt handler
206 *
207 ****************************************************************/
208static void e1000_interrupt_handler_fn(void *arg)
209{
210    struct e1000_driver_state * eds = arg;
211    /* Read interrupt cause, this also acknowledges the interrupt */
212    e1000_intreg_t icr = e1000_icr_rd(eds->device);
213    test_instr_interrupt(eds, icr);
214
215#if TRACE_ETHERSRV_MODE
216    trace_event(TRACE_SUBSYS_NNET, TRACE_EVENT_NNET_NI_I, interrupt_counter);
217#endif
218
219//    printf("#### interrupt handler called: %"PRIu64"\n", interrupt_counter);
220    ++interrupt_counter;
221
222    printf("(%s) ############### Interrupt handler ###############\n",
223            eds->inst_name);
224
225    if (e1000_intreg_lsc_extract(icr) != 0) {
226        if (e1000_check_link_up(eds->device)) {
227            e1000_auto_negotiate_link(eds->device, eds->mac_type);
228        } else {
229            E1000_DEBUG("Link status change to down.\n");
230        }
231    }
232
233    if (e1000_intreg_rxt0_extract(icr) != 0) {
234        E1000_DEBUG("Packet received!.\n");
235    }
236}
237
238/* Configure the card to trigger MSI-x interrupts */
239static void e1000_enable_msix(struct e1000_driver_state * eds){
240    // enable all the msix interrupts and map those to MSI vector 0
241    e1000_ivar_82574_int_alloc0_wrf(eds->device, 0);
242    e1000_ivar_82574_int_alloc_val0_wrf(eds->device, 1);
243
244    e1000_ivar_82574_int_alloc1_wrf(eds->device, 0);
245    e1000_ivar_82574_int_alloc_val1_wrf(eds->device, 1);
246
247    e1000_ivar_82574_int_alloc2_wrf(eds->device, 0);
248    e1000_ivar_82574_int_alloc_val2_wrf(eds->device, 1);
249
250    e1000_ivar_82574_int_alloc3_wrf(eds->device, 0);
251    e1000_ivar_82574_int_alloc_val3_wrf(eds->device, 1);
252
253    e1000_ivar_82574_int_alloc4_wrf(eds->device, 0);
254    e1000_ivar_82574_int_alloc_val4_wrf(eds->device, 1);
255
256    e1000_ivar_82574_int_on_all_wb_wrf(eds->device, 1);
257    int count = 4;
258    pcid_enable_msix(&count);
259}
260
261/*****************************************************************
262 * PCI init callback.
263 *
264 * Setup device, create receive ring and connect to Ethernet server.
265 *
266 ****************************************************************/
267static void e1000_init_fn(struct e1000_driver_state * device)
268{
269    // set features
270    switch (device->mac_type) {
271        case e1000_82571:
272        case e1000_82572:
273        case e1000_82574: {
274            device->extended_interrupts = 0;
275            device->advanced_descriptors = 1;
276        } break;
277        case e1000_82576:
278        case e1000_I210:
279        case e1000_I219:
280        case e1000_I350: {
281            device->extended_interrupts = 1;
282            device->advanced_descriptors = 3;
283        } break;
284    default:
285        device->extended_interrupts = 0;
286        device->advanced_descriptors = 0;
287    }
288
289    E1000_DEBUG("Starting hardware initialization.\n");
290    e1000_hwinit(device);
291    E1000_DEBUG("Hardware initialization complete.\n");
292
293
294    errval_t err;
295    if (device->msix) {
296        E1000_DEBUG("MSI-X interrupt support!\n");
297        err = e1000_init_msix_client(device);
298        if(err_is_ok(err)){
299            // Can use MSIX
300            E1000_DEBUG("Successfully instantiated MSIx, setup int routing\n");
301            e1000_enable_msix(device);
302        }
303        err = pcid_connect_int(&device->pdc, 0, e1000_interrupt_handler_fn, device);
304
305    } else {
306        E1000_DEBUG("Legacy interrupt support!\n");
307#ifdef UNDER_TEST
308        err = pcid_connect_int(&device->pdc, 0, e1000_interrupt_handler_fn, device);
309        if(err_is_fail(err)){
310            USER_PANIC("Setting up interrupt failed \n");
311        }
312#endif
313    }
314
315    test_instr_init(device);
316
317    setup_internal_memory(device);
318}
319
320
321
322
323/*****************************************************************
324 * Print help and exit.
325 *
326 *
327 ****************************************************************/
328static void exit_help(void)
329{
330    fprintf(stderr, "Args for e1000n driver:\n");
331    fprintf(stderr, "\taffinitymin=  Set RAM min affinity. When using this option it's mandatory to also set affinitymax.\n");
332    fprintf(stderr, "\taffinitymax=  Set RAM max affinity. When using this option it's mandatory to also set affinitymin.\n");
333    fprintf(stderr, "\tserivcename=  Set device driver service name.\n");
334    fprintf(stderr, "\tbus=          Connect driver to device using this PCI bus.\n");
335    fprintf(stderr, "\tfunction=     Connect driver to PCI device with function id.\n");
336    fprintf(stderr, "\tdevice=       Connect driver to PCI device with type id.\n");
337    fprintf(stderr, "\tdeviceid=     Connect driver to PCI device with device id.\n");
338    fprintf(stderr, "\tmac=          Set device MAC address using MAC address format.\n");
339    fprintf(stderr, "\tnoirq         Do not enable PCI bus IRQ, use device polling instead.\n");
340    fprintf(stderr, "\t-h, --help    Print this help.\n");
341
342    exit(2);
343}
344
345
346/*
347static void e1000_reregister_handler(void *arg)
348{
349    errval_t err;
350    printf("%s:%s:%d:\n", __FILE__, __FUNCTION__, __LINE__);
351    err = pci_reregister_irq_for_device(
352            class, subclass, program_interface,
353            vendor, deviceid, bus, device, function,
354            e1000_interrupt_handler_fn, NULL,
355            e1000_reregister_handler, NULL);
356    if (err_is_fail(err)) {
357        DEBUG_ERR(err, "pci_reregister_irq_for_device");
358    }
359
360    return;
361} */
362
363void e1000_driver_state_init(struct e1000_driver_state * eds){
364    memset(eds, 0, sizeof(struct e1000_driver_state));
365    eds->mac_type = e1000_undefined;
366    eds->user_mac_address = false;
367    //eds->use_interrupt = false;
368    eds->use_interrupt = true;
369    eds->use_force = false;
370    eds->queue_init_done = false;
371
372    eds->rx_bsize = bsize_16384;
373    //eds->rx_bsize = bsize_2048;
374
375    eds->minbase = -1;
376    eds->maxbase = -1;
377}
378
379
380/******************************************************************************/
381/* Management interface implemetation */
382
383static errval_t cd_create_queue_rpc(struct e1000_devif_binding *b,
384                                struct capref rx, struct capref tx, bool interrupt,
385                                uint64_t *mac, struct capref *regs,
386                                struct capref *irq, errval_t* err)
387{
388    struct e1000_driver_state* driver = (struct e1000_driver_state*) b->st;
389
390    assert(driver != NULL);
391
392    if (!driver->queue_init_done) {
393        e1000_init_queues(driver, rx, DRIVER_RECEIVE_BUFFERS, tx, DRIVER_TRANSMIT_BUFFERS);
394    } else {
395        debug_printf("e1000: queue already initalized. \n");
396        return DEVQ_ERR_INIT_QUEUE;
397    }
398    memcpy(mac, driver->mac_address, sizeof(driver->mac_address));
399    *regs = driver->regs;
400
401    *err = pcid_get_interrupt_cap(&driver->pdc, irq);
402    return SYS_ERR_OK;
403}
404
405
406static void cd_create_queue(struct e1000_devif_binding *b, struct capref rx,
407                            struct capref tx, bool interrupt)
408{
409    debug_printf("in cd_create_queue\n");
410    uint64_t mac = 0;
411    errval_t err = SYS_ERR_OK;
412
413    struct capref regs;
414    struct capref irq;
415
416    cd_create_queue_rpc(b, rx, tx, interrupt, &mac, &regs, &irq, &err);
417
418    //if(interrupt){
419        // enable interrupts for that queue
420        // send back interrupt cap
421   //}
422
423    err = b->tx_vtbl.create_queue_response(b, NOP_CONT, mac, regs, irq, err);
424    assert(err_is_ok(err));
425}
426
427static errval_t cd_destroy_queue_rpc(struct e1000_devif_binding *b, errval_t* err)
428{
429    USER_PANIC("NIY \n");
430    return SYS_ERR_OK;
431}
432
433
434static void cd_destroy_queue(struct e1000_devif_binding *b)
435{
436    errval_t err = SYS_ERR_OK;
437
438    cd_destroy_queue_rpc(b, &err);
439
440    err = b->tx_vtbl.destroy_queue_response(b, NOP_CONT, SYS_ERR_OK);
441    assert(err_is_ok(err));
442}
443
444
445static errval_t connect_devif_cb(void *st, struct e1000_devif_binding *b)
446{
447
448    b->rx_vtbl.create_queue_call = cd_create_queue;
449    b->rx_vtbl.destroy_queue_call = cd_destroy_queue;
450
451    b->rpc_rx_vtbl.create_queue_call = cd_create_queue_rpc;
452    b->rpc_rx_vtbl.destroy_queue_call = cd_destroy_queue_rpc;
453    b->st = st;
454
455    return SYS_ERR_OK;
456}
457
458static void export_devif_cb(void *st, errval_t err, iref_t iref)
459{
460    struct e1000_driver_state* s = (struct e1000_driver_state*) st;
461    const char *suffix = "devif";
462    char name[256];
463
464    assert(err_is_ok(err));
465
466    // Build label for interal management service
467    sprintf(name, "%s_%x_%x_%x_%s", s->service_name, s->pdc.addr.bus, s->pdc.addr.device,
468            s->pdc.addr.function, suffix);
469
470    err = nameservice_register(name, iref);
471    assert(err_is_ok(err));
472    s->initialized = true;
473}
474
475/**
476 * Initialize management interface for queue drivers.
477 * This has to be done _after_ the hardware is initialized.
478 */
479static void initialize_mngif(struct e1000_driver_state* st)
480{
481    errval_t r;
482
483    r = e1000_devif_export(st, export_devif_cb, connect_devif_cb,
484                           get_default_waitset(), 1);
485    assert(err_is_ok(r));
486}
487
488static errval_t init(struct bfdriver_instance* bfi, const char* name, uint64_t
489        flags, struct capref* caps, size_t caps_len, char** args, size_t
490        args_len, iref_t* dev) {
491
492    errval_t err;
493
494    /** Parse command line arguments. */
495    E1000_DEBUG("e1000 driver module started. instance name=%s\n",
496            bfi->name);
497    E1000_DEBUG("args_len=%ld, caps_len=%ld\n", args_len, caps_len);
498
499    struct e1000_driver_state * eds = malloc(sizeof(struct e1000_driver_state));
500    e1000_driver_state_init(eds);
501    bfi->dstate = eds;
502
503    err = pcid_init(&eds->pdc, caps, caps_len, args, args_len, get_default_waitset());
504    if(err_is_fail(err)){
505        DEBUG_ERR(err, "pcid_init");
506        goto err_out;
507    }
508
509    eds->args = args;
510    eds->args_len = args_len;
511    eds->service_name = "e1000"; // default name
512    eds->inst_name = bfi->name;
513
514    for (int i = 1; i < args_len; i++) {
515        E1000_DEBUG("arg %d = %s\n", i, args[i]);
516        if (strcmp(args[i], "auto") == 0) {
517            continue;
518        }
519        if (strncmp(args[i], "affinitymin=", strlen("affinitymin=")) == 0) {
520            eds->minbase = atol(args[i] + strlen("affinitymin="));
521            E1000_DEBUG("minbase = %lu\n", eds->minbase);
522        } else if (strncmp(args[i], "affinitymax=", strlen("affinitymax="))
523                 == 0) {
524            eds->maxbase = atol(args[i] + strlen("affinitymax="));
525            E1000_DEBUG("maxbase = %lu\n", eds->maxbase);
526        } else if (strncmp(args[i], "mac=", strlen("mac=")) == 0) {
527            uint8_t* mac = eds->mac_address;
528            if (parse_mac(mac, args[i] + strlen("mac="))) {
529                eds->user_mac_address = true;
530                E1000_DEBUG("MAC= %02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx\n",
531                            mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
532            } else {
533                E1000_PRINT_ERROR("Error: Failed parsing MAC address '%s'.\n", args[i]);
534                exit(1);
535            }
536        } else if(strncmp(args[i], "servicename=", strlen("servicename=")) == 0) {
537            eds->service_name = args[i]  + strlen("servicename=");
538            E1000_DEBUG("Service name=%s.\n", eds->service_name);
539        } else if(strcmp(args[i],"noirq")==0) {
540            E1000_DEBUG("Driver working in polling mode.\n");
541            eds->use_interrupt = false;
542        } else if (strcmp(args[i], "-h") == 0 ||
543                 strcmp(args[i], "--help") == 0) {
544            exit_help();
545        } else {
546            E1000_DEBUG("Parsed Kaluga device address %s.\n", args[i]);
547        }
548    } // end for :
549
550    if ((eds->minbase != -1) && (eds->maxbase != -1)) {
551        E1000_DEBUG("set memory affinity [%lx, %lx]\n", eds->minbase, eds->maxbase);
552        ram_set_affinity(eds->minbase, eds->maxbase);
553    }
554
555    E1000_DEBUG("Starting e1000 driver.\n");
556
557    eds->mac_type = e1000_get_mac_type(eds->pdc.id.vendor, eds->pdc.id.device);
558    E1000_DEBUG("mac_type is: %s\n", e1000_mac_type_to_str(eds->mac_type));
559
560    /* Setup known device info */
561    if (eds->mac_type == e1000_82575
562        || eds->mac_type == e1000_82576
563        || eds->mac_type == e1000_I210
564        || eds->mac_type == e1000_I219
565        || eds->mac_type == e1000_I350) {
566        // These cards do not have a bsex reg entry
567        // therefore, we can't use 16384 buffer size.
568        // If we use smaller buffers than 2048 bytes the
569        // eop bit on received packets might not be set in case the package
570        // is biger than the receive buffer size and we don't handle these
571        // cases currently.
572        eds->rx_bsize = bsize_2048;
573    } else {
574        eds->rx_bsize = bsize_16384;
575    }
576    eds->media_type = e1000_media_type_undefined;
577
578    // Setup int routing in init_fn
579    e1000_init_fn(eds);
580
581    if(false) e1000_print_link_status(eds);
582
583    initialize_mngif(eds);
584
585    return err;
586
587err_out:
588    free(eds);
589    return err;
590}
591
592static errval_t attach(struct bfdriver_instance* bfi) {
593    return SYS_ERR_OK;
594}
595
596static errval_t detach(struct bfdriver_instance* bfi) {
597    return SYS_ERR_OK;
598}
599
600static errval_t set_sleep_level(struct bfdriver_instance* bfi, uint32_t level) {
601    struct e1000_driver_state* eds = bfi->dstate;
602    eds->level = level;
603    return SYS_ERR_OK;
604}
605
606static errval_t destroy(struct bfdriver_instance* bfi) {
607    struct e1000_driver_state* eds = bfi->dstate;
608    free(eds);
609    bfi->dstate = NULL;
610    // XXX: Tear-down the service
611    bfi->device = 0x0;
612    return SYS_ERR_OK;
613}
614
615#ifdef UNDER_TEST
616DEFINE_MODULE(e1000n_irqtest_module, init, attach, detach, set_sleep_level, destroy);
617#else
618DEFINE_MODULE(e1000n_module, init, attach, detach, set_sleep_level, destroy);
619#endif
620