_ 12 mbz;
};
+ register eec_82574 rw also addr(base, 0x0010) "EEPROM/Flash control for 82574" {
+ ee_sk 1 "Clock input to EEPROM";
+ ee_cs 1 "Chip select to EEPROM";
+ ee_di 1 "Data input to EEPROM";
+ ee_do 1 "Data output bit from EEPROM";
+ fwe 2 type(flashenable) "Flash write enable control";
+ ee_req 1 "Request EEPROM access";
+ ee_gnt 1 "Grant EEPROM access";
+ ee_pres 1 "EEPROM present";
+ auto_rd 1 "EEPROM Auto Read Done";
+ _ 1 mbz;
+ nv_size 4 "NVM Size";
+ nv_adds 2 "NVM Address size";
+ _ 3 mbz;
+ audpen 1 "Autonomous flash update";
+ _ 1 mbz;
+ sec1val 1 "Sec 1 valid";
+ nvmtype 1 "NVM Type";
+ _ 8 mbz;
+ };
+
// 13.3.4
// NM93C46 compatible EEPROMs
register eerd_nm rw addr(base, 0x0014) "EEPROM read" {
};
// 13.3.17
- register ufuse3 ro addr(base, 0x00f0) "ULT Fuse register 3" {
+ register ufuse3 ro also addr(base, 0x00f0) "ULT Fuse register 3" {
drred 15 "Data RAM redundancy fuses";
crred 13 "Code RAM redundancy fuses";
enad 1 "Enable Data RAM redundancy fuses";
// 13.3.32
register iam rw addr(base, 0x00e0) "Interrupt ack auto mask" type(intreg);
+ // 82574: 10.2.4.3
+ regarray eitr_82574 addr(base, 0x00e8)[4;0x4] "Extended Interrupt Throttle" {
+ interval 16 "Minimum inter-interrupt interval (x256ns)";
+ _ 16 mbz;
+ };
+
regarray eitr addr(base, 0x1680)[9;0x4] "Extended Interrupt Throttle" {
_ 2 mbz;
interval 13 "Interval";
+++ /dev/null
-/*
- * Copyright (c) 2016, ETH Zurich. All rights reserved.
- *
- * This file is distributed under the terms in the attached LICENSE file.
- * If you do not find this file, copies can be found by writing to:
- * ETH Zurich D-INFK, Haldeneggsteig 4, CH-8092 Zurich. Attn: Systems Group.
- */
-
-/*
- * e1000e.dev
- *
- * DESCRIPTION: Intel e1000e family Gigabit Ethernet NICs
- *
- * Source of this interface is the
- * Intel 82574 GbE Controller Family Datasheet
- * The card is similar but not compatible to the e1000.
- */
-
-device e1000e lsbfirst ( addr base ) "Intel e1000e Gigabit Ethernet" {
-
- /************************************
- * General registers
- ***********************************/
-
- // 13.3.1
- constants linkspeed "Link speed" {
- mb10 = 0b00 "10Mb/s";
- mb100 = 0b01 "100Mb/s";
- mb1000 = 0b10 "1Gb/s";
- mb_notused = 0b11 "1Gb/s";
- };
-
-
- // 10.2.2.1
- register ctrl rw addr(base, 0x0000) "Device control" {
- fd 1 "full-duplex";
- _ 1 mbz;
- gio_md 1 "GIO master disable";
- _ 1 mb1;
- _ 1 mbz;
- asde 1 "Auto-Speed Detection Enable";
- slu 1 "Set link up";
- _ 1 mbz;
- speed 2 type(linkspeed) "Speed selection";
- _ 1 mbz;
- frcspd 1 "Force speed";
- frcdplx 1 "Force duplex";
- _ 7 mbz;
- advd3wuc 1 "D3cold wakeup capability";
- _ 5 mbz;
- rst 1 "Device reset";
- rfce 1 "Receive flow control enable";
- tfce 1 "Transmit flow control enable";
- _ 1 mbz;
- vme 1 "VLAN mode enable";
- phy_rst 1 "PHY reset";
- };
-
- register ctrldup rw addr(base, 0x0004) "Device Control Duplicate (Shadow)" {
- fd 1 "full-duplex";
- _ 1 mbz;
- gio_md 1 "GIO master disable";
- _ 1 mb1; // must be one
- _ 1 mbz;
- asde 1 "Auto-Speed Detection Enable";
- slu 1 "Set link up";
- _ 1 mbz;
- speed 2 type(linkspeed) "Speed selection";
- _ 1 mbz;
- frcspd 1 "Force speed";
- frcdplx 1 "Force duplex";
- _ 7 mbz;
- advd3wuc 1 "D3cold wakeup capability";
- _ 5 mbz;
- rst 1 "Device reset";
- rfce 1 "Receive flow control enable";
- tfce 1 "Transmit flow control enable";
- _ 1 mbz;
- vme 1 "VLAN mode enable";
- phy_rst 1 "PHY reset";
- };
-
- constants lanid "LAN ID" {
- lan_a = 0b00 "LAN A";
- lan_b = 0b01 "LAN B";
- lan_not_u1 = 0b10 "LAN ID not used";
- lan_not_u2 = 0b11 "LAN ID not used";
- };
- constants mac_mask "LAN MAC MASK" {
- lan_b_mask = 0x0100 "LAN B mask";
- };
-
- // 10.2.2.2
- register status ro addr(base, 0x0008) "Device status" {
- fd 1 "Link full duplex configuration";
- lu 1 "Link up";
- func_id 2 "Function ID";
- txoff 1 "Transmission paused";
- tbimode 1 "TBI mode";
- speed 2 type(linkspeed) "Link speed setting";
- asdv 2 type(linkspeed) "Auto speed detection value";
- phyra 1 "PHY reset asserted";
- pci66 1 "PCI Bus speed indication";
- bus64 1 "PCI Bus Width indication";
- pcix_mode 1 "PCI-X Mode indication";
- pcixspd 2 "PCI-X Bus Speed Indication";
- _ 3 mbz;
- gio_mes 1 "GIO master enable status";
- dev_rst_set 1 "Device reset set";
- pf_rst_done 1 "Software Rest or device reset completed";
- _ 10 mbz;
- };
-
-
- // 13.3.3
- constants flashenable "Flash write enable control" {
- flash_erase = 0b00 "Flash erase";
- flash_wr_disable = 0b01 "Flash writes discarded";
- flash_wr_enable = 0b10 "Flash writed enabled";
- };
-
- constants eeaddrsize "EEPROM address size" {
- bits8or9 = 0 "8- and 9-bit";
- bits16 = 1 "16-bit";
- };
-
- constants nvmtype "Non-volatile memory type" {
- eeprom = 0b00 "EEPROM";
- saflash = 0b01 "Stand-alone Flash";
- spiflash = 0b10 "Shared SPI Flash";
- sio = 0b11 "SIO";
- };
-
- register eecd rw addr(base, 0x0010) "EEPROM/Flash control" {
- ee_sk 1 "Clock input to EEPROM";
- ee_cs 1 "Chip select to EEPROM";
- ee_di 1 "Data input to EEPROM";
- ee_do 1 "Data output bit from EEPROM";
- fwe 2 type(flashenable) "Flash write enable control";
- ee_req 1 "Request EEPROM access";
- ee_gnt 1 "Grant EEPROM access";
- ee_pres 1 "EEPROM present";
-
- auto_rd 1 "NVM Auto Read Done";
- _ 1 mbz;
- nv_size 4 "NVM Size";
- nvadds 2 "NVM Address Size";
- _ 3 mbz;
- audpen 1 "Enable autonomous flash update";
- _ 1 mbz;
- sec1val 1 "Sector 1 valid";
- nvmtype 1 "NVM Type";
- _ 8 mbz;
- };
-
- // 10.2.2.4
- register eerd rw addr(base, 0x0014) "EEPROM read" {
- start 1 "Start read";
- done 1 ro "Read done";
- addr 14 "Read address";
- data 16 "Read data";
- };
-
-
- // 10.2.2.5
- register ctrlext rw addr(base, 0x0018) "Extended device control" {
- _ 12 mbz;
- asdchk 1 "Auto-speed-detection check";
- ee_rst 1 "EEPROM reset";
- _ 1 mbz;
- spd_byps 1 "Speed select bypass";
- _ 1;
- rodis 1 "Relaxed ordering disabled";
- _ 1 mbz;
- dmadge 1 "DMA dynamic gating enable";
- phypde 1 "PHY power down enable";
- _ 1;
- txlsflow 1 "Tx LS Flow";
- txls 1 "TxLS";
- eiame 1 "Extended interrupt acknowledge auto-mask enable";
- _ 2 mbz;
- iame 1 "Interrupt acknowledge auto-mask enable";
- drv_load 1 "Driver loaded";
- int_tca 1 "Timers clear enable";
- _ 1 mbz;
- pbasupport 1 "PBA support";
- };
-
- // 10.2.2.6
- register fla rw addr(base, 0x001c) "Flash access" {
- fl_nvm_sk 1 "Clock input to the Flash";
- fl_ce 1 "Chip select input to the Flash";
- fl_si 1 "Data input to the Flash";
- fl_so 1 "X Data output bit from the Flash";
- fl_req 1 "Request Flash Access";
- fl_gnt 1 "Grant Flash Access";
- fl_dev_er_ind 1 "Device erase initiated";
- fl_sec_er_ind 1 "Sector erase initiated";
- fl_wr_ind 1 "Write initiated";
- sw_wr_done 1 "Last write done";
- _ 20 mbz;
- fl_busy 1 "Flash Busy";
- fl_er 1 "Flash Erase Command";
- };
-
- // 10.2.2..7
- constants phyop "PHY register opcode" {
- mdi_write = 0b01 "MDI Write";
- mdi_read = 0b10 "MDI Read";
- };
- register mdic rw addr(base, 0x0020) "MDI control" {
- data 16 "Data";
- regadd 5 "PHY register address";
- phyadd 5 "PHY address";
- op 2 type(phyop) "Opcode";
- r 1 "Ready bit";
- i 1 "Interript enable";
- e 1 "Error";
- _ 1 mbz;
- };
-
- // There are a lot of PHY registers, all accessed through the MDIC.
- // We don't yet list them here.
-
- // 10.2.2.8-9
- constants fca "Flow control address" {
- fca_lo = 0x0c28001;
- fca_hi = 0x0000100;
- };
- register fcal rw addr(base, 0x0028) "Flow control address low" type(uint32);
- register fcah rw addr(base, 0x002C) "Flow control address low" type(uint32);
-
- // 10.2.2.10
- constants fctval "Flow control type" {
- fct_val = 0x0008808;
- };
- register fct rw addr(base, 0x0030) "Flow control type" type(uint32);
-
- // 10.2.2.11
- constants vet_val "VLAN ether type value" {
- vlan_type = 0x0008100;
- };
- register vet rw addr(base, 0x0038) "VLAN Ether type" type(uint32);
-
- // 10.2.2.12
- register fcttv rw addr(base, 0x0170) "Flow control transmit timer value" {
- ttv 16 "Transmit timer value";
- _ 16 mbz;
- };
-
- // 10.2.2.14
- constants ledmode "LED output mode" {
- link_10_100 = 0b0000 "Either 10 or 100 Mbs link established";
- link_100_1000 = 0b0001 "Either 100 or 1000 Mbs link established";
- link_up = 0b0010 "Any speed link established";
- filter_activity = 0b0011 "Packets passing MAC filtering";
- link_activity = 0b0100 "No transmit or receive activity";
- link_10 = 0b0101 "10 Mbs link established";
- link_100 = 0b0110 "100 Mbs link established";
- link_1000 = 0b0111 "1000 Mbs link established";
- full_duplex = 0b1001 "Link configured for full-duplex";
- collision = 0b1010 "Collision is observed";
- activity = 0b1011 "Link established and packets sent or revd";
- bus_size = 0b1100 "Controller detects 1 PCIe lane conn.";
- paused = 0b1101 "Transmitter is flow controlled";
- led_on = 0b1110 "Always on";
- led_off = 0b1111 "Always off";
- };
- constants blmode "LED blink mode" {
- ms200 = 0 "200ms on, 200ms off";
- ms83 = 1 "83ms on, 83 ms off";
- };
- register ledctl rw addr(base, 0x0e00) "LED control" {
- led0_mode 4 type(ledmode) "LED0/LINK# mode";
- _ 1 mbz;
- global_blink_mode 1 type(blmode) "Global blink mode";
- led0_ivrt 1 "LED0 invert";
- led0_blink 1 "LED0 blink";
-
- led1_mode 4 type(ledmode) "LED1/LINK# mode";
- _ 1 mbz;
- led1_blink_mode 1 type(blmode) "Global blink mode";
- led1_ivrt 1 "LED1 invert";
- led1_blink 1 "LED1 blink";
-
- led2_mode 4 type(ledmode) "LED2/LINK# mode";
- _ 1 mbz;
- led2_blink_mode 1 type(blmode) "Global blink mode";
- led2_ivrt 1 "LED2 invert";
- led2_blink 1 "LED2 blink";
- _ 8 mbz;
- };
-
- // 10.2.2.15
- register extcnf_ctrl rw addr(base, 0x0f00) "Extended config control" {
- _ 3 mbz;
- _ 1 mb1;
- _ 1 mbz;
- mdio_swown 1 "MDIO software ownership (ro)";
- mdio_hwown 1 "MDIO hoftware ownership (ro)";
- mdio_mngown 1 "MDIO MNG ownership";
- _ 24 mbz;
- };
-
- // 10.2.2.16
- register extcnf_size rw addr(base, 0x0f08) "Extended config size" {
- phy_len 8 "Extended PHY configuration area length";
- dock_len 8 "Extended dock configuration area length";
- _ 8 mbz;
- _ 8;
- };
-
- // 10.2.2.17
- register pba rw addr(base, 0x1000) "Packet buffer allocation" {
- rxa 16 "Rx packet buffer allocation in KB";
- txa 16 "Tx packet buffer allocation in KB";
- };
-
- // 10.2.2.18
- register eemngctl ro addr(base, 0x1010) "MNG EEPROM control" {
- addr 15 "Address";
- start 1 "Start";
- write 1 "Write";
- eebusy 1 "EPROM Busy";
- _ 1 mbz;
- ee_trans_e 1 "Transaction";
- _ 11 mbz;
- done 1 "Transaction Done";
- };
-
-
- /************************************
- * Interrupt registers
- ***********************************/
-
- // 10.2.3.13
- register pbaclr rw addr(base, 0x5B68) "MSI-x PBA Clear" {
- penbit 5 "MSI-x Pending bit clear";
- _ 27 mbz;
- };
-
- // 10.2.4.1
- regtype intreg "Interrupt register format" {
- txdw 1 "Transmit descriptor written back";
- txqe 1 "Transmit queue empty";
- lsc 1 "Link status change";
- _ 1 mbz;
- rxdmt0 1 "Receive descriptor minimum threshold reached";
- _ 1;
- rxo 1 "Receiver overrun";
- rxt0 1 "Receiver timer interrupt";
- _ 1;
- mdac 1 "MDI/O access complete";
- _ 5 mbz;
- txd_low 1 "TX desc low threshold hit";
- srpd 1 "Small receive packet detected";
- ack 1 "Receive ack frame detected";
- mng 1 "Manageability event";
- _ 1 mbz;
- rx_q0 1 "Rx Queue 0 Interrupt";
- rx_q1 1 "Rx Queue 1 Interrupt";
- tx_q0 1 "Rx Queue 0 Interrupt";
- tx_q1 1 "Rx Queue 1 Interrupt";
- other 1 "Other interrupt";
- _ 6 mbz;
- int_asserted 1 "Interrupt asserted";
- };
-
- // 10.2.4.1
- register icr ro addr(base, 0x00c0) "Interrupt cause read" type(intreg);
-
- // 10.2.4.2
- register itr rw addr(base, 0x00c4) "Interrupt throttling rate" {
- interval 16 "Minimum inter-interrupt interval (x256ns)";
- _ 16 mbz;
- };
-
- // 10.2.4.3
- regarray eitr addr(base, 0x00e8)[4;0x4] "Extended Interrupt Throttle" {
- interval 16 "Minimum inter-interrupt interval (x256ns)";
- _ 16 mbz;
- };
-
- // 10.2.4.4
- register ics wo addr(base, 0x00c8) "Interrupt cause write" type(intreg);
-
- // 10.2.4.5
- register ims rw addr(base, 0x00d0) "Interrupt mask set/read" type(intreg);
-
- // 10.2.4.6
- register imc wo addr(base, 0x00d8) "Interrupt mask clear" type(intreg);
-
- // 10.2.4.7
- register eiac rw addr(base, 0x00dc) "Ext Interrupt auto clear" {
- _ 20 mbz;
- value 5 "Auto clear bits for the corresponding bits of ICR";
- _ 7 mbz;
- };
-
- // 10.2.4.8
- register iam rw addr(base, 0x00e0) "Interrupt ack auto mask" type(intreg);
-
- // 10.2.4.9
- // This maps internal int causes to an entry in the MSIx-vec table
- register ivar rw addr(base, 0x00e4) "Interrupt vector allocation register" {
- int_alloc0 3 "RxQ0 interrupt";
- int_alloc0_en 1 "RxQ0 int enable";
- int_alloc1 3 "RxQ1 interrupt";
- int_alloc1_en 1 "RxQ1 int enable";
- int_alloc2 3 "TxQ0 interrupt";
- int_alloc2_en 1 "TxQ0 int enable";
- int_alloc3 3 "TxQ1 interrupt";
- int_alloc3_en 1 "TxQ1 int enable";
- int_alloc4 3 "Other cause interrupt";
- int_alloc4_en 1 "Other cause int enabled";
- _ 11 mbz;
- int_on_all_wb 1 "Interrupt on every write back";
- };
-
-
- // TODO: All receive and send registers
-
-
-};
mac_type = e1000_get_mac_type(vendor, deviceid);
}
+ E1000_DEBUG("mac_type is: %s\n", e1000_mac_type_to_str(mac_type));
+
/* Setup known device info */
e1000_device.device = &e1000;
e1000_device.mac_type = mac_type;
#define E1000_DEVICE_I350_DUMMY 0x10A6
#define E1000_DEVICE_82546GB_QUAD_COPPER_KSP3 0x10B5
+/**
+ * Initial default values
+ */
+
+#define E1000_DEFAULT_INT_THROTTLE_RATE 5580
+#define E1000_INT_THROTTLE_RATE_DISABLED 0
+
/**
* Group definitions for cards that share specification and quirks.
e1000_mac_type_t e1000_get_mac_type(uint32_t vendor, uint32_t device_id);
+char * e1000_mac_type_to_str(e1000_mac_type_t mt);
bool e1000_supported_device(uint32_t vendor, uint32_t device_id);
bool e1000_link_up_led_status(e1000_device_t *dev);
bool e1000_check_link_up(e1000_device_t *dev);
bool e1000_auto_negotiate_link(e1000_device_t *dev);
void *alloc_map_frame(vregion_flags_t attr, size_t size, struct capref *retcap);
+void e1000_set_interrupt_throttle(e1000_device_t *dev, uint16_t rate);
void e1000_hwinit(e1000_device_t *device, struct device_mem *bar_info,
int nr_allocated_bars,
volatile struct tx_desc **transmit_ring,
return e1000_undefined;
}
+char * e1000_mac_type_to_str(e1000_mac_type_t mt){
+ char * names[] = {
+ "undefined",
+ "82542",
+ "82543",
+ "82544",
+ "82540",
+ "82545",
+ "82545_rev_3",
+ "82546",
+ "82546_rev_3",
+ "82541",
+ "82541_rev_2",
+ "82547",
+ "82547_rev_2",
+ "82563",
+ "82571",
+ "82572",
+ "82573",
+ "82574",
+ "82575",
+ "82576",
+ "I210",
+ "I350"
+ };
+ if(mt >= e1000_num_macs) return NULL;
+ return names[mt];
+};
+
/*****************************************************************
* allocate a single frame, mapping it into our vspace with given
{
int timeout = 1000;
- /* Make shore there are no direct access requests on
+ /* Make sure there are no direct access requests on
* devices that support this.
*/
- if (dev->mac_type != e1000_82544) {
+ if (dev->mac_type == e1000_82574){
+ e1000_eec_ee_req_wrf(dev->device, 1);
+ } else if (dev->mac_type != e1000_82544) {
e1000_eecd_ee_req_wrf(dev->device, 1);
}
}
/* EEPROM present */
- // TODO(gz): Why does e1000 82574 have ee_pres == 0?
+ // TODO(gz): Why does e1000 82574 have ee_pres == 0? LH: QEMUs 82574 has ee_pres=1?
if (e1000_eecd_ee_pres_rdf(dev->device) ||
dev->mac_type == e1000_82574) {
e1000_eerd_ms_t eerd_ms = 0;
{
uint16_t data;
errval_t err;
-
- err = e1000_read_eeprom(dev, 0, &data);
+
+ if(dev->mac_type == e1000_82574){
+ // For the 82574 we just check the auto rd flag without issuing
+ // an eeprom read. (FreeBSD does it like this)
+ int timeout = 1000;
+ while(timeout-- > 0){
+ if(e1000_eec_82574_auto_rd_rdf(dev->device)){
+ return SYS_ERR_OK;
+ }
+ usec_delay(10);
+ }
+ E1000_DEBUG("Timeout reached while waiting for auto_rd_done");
+ return 1;
+ } else {
+ err = e1000_read_eeprom(dev, 0, &data);
+ }
/* PHY configuration from NVM just starts after EECD_AUTO_RD sets to high.
* Need to wait for PHY configuration completion before accessing NVM
}
}
+ if(dev->mac_type == e1000_82574){
+ // 82574: Must poll on GIO Master Enable Status in status register
+ E1000_DEBUG("Disabling GIO management.\n");
+ e1000_ctrl_gio_md_wrf(dev->device, 1);
+
+ timeout = 1000;
+ do {
+ usec_delay(10);
+ } while (e1000_status_gio_mes_rdf(dev->device) && 0 < timeout--);
+
+ if (timeout <= 0) {
+ E1000_DEBUG("Error: Failed to disable GIO management.\n");
+ // return -1;
+ }
+ }
+
if (dev->mac_type == e1000_I350) {
E1000_DEBUG("Disabling GIO management.\n");
e1000_ctrl_gio_md_wrf(dev->device, 1);
/* Must acquire MDIO ownership before MAC reset
* Ownership defaults to firmware after a reset */
- if (dev->mac_type == e1000_82573) {
+ int mdio_acquired = false;
+ if (dev->mac_type == e1000_82573 || dev->mac_type == e1000_82574) {
timeout = 1000;
do {
e1000_extcnf_ctrl_mdio_swown_wrf(dev->device, 1);
usec_delay(200);
} while (e1000_extcnf_ctrl_mdio_swown_rdf(dev->device) == 0
&& 0 < timeout--);
+ if(timeout > 0){
+ mdio_acquired = true;
+ } else {
+ E1000_DEBUG("Could not acquire MDIO software ownership.\n");
+ }
}
E1000_DEBUG("Resetting device.\n");
E1000_DEBUG("Error: Failed to reset device.\n");
}
break;
+
+ case e1000_82574:
+ e1000_ctrl_rst_wrf(dev->device, 1);
+ usec_delay(10);
+ break;
+
default:
e1000_ctrl_rst_wrf(dev->device, 1);
break;
}
+ /*
+ * If acquired, release mdio ownership
+ */
+ if (mdio_acquired) {
+ timeout = 1000;
+ do {
+ e1000_extcnf_ctrl_mdio_swown_wrf(dev->device, 0);
+ usec_delay(200);
+ } while (e1000_extcnf_ctrl_mdio_swown_rdf(dev->device) == 1
+ && 0 < timeout--);
+ if(timeout > 0){
+ mdio_acquired = 0;
+ } else {
+ E1000_DEBUG("Could not release MDIO software ownership.\n");
+ }
+ }
+
/* After MAC reset, force reload of EEPROM to restore power-on settings to
* device. Later controllers reload the EEPROM automatically, so just wait
usec_delay(20000);
break;
case e1000_82573:
+ case e1000_82574:
if (e1000_is_onboard_nvm_eeprom(dev) == false) {
usec_delay(100);
e1000_ctrlext_ee_rst_wrf(dev->device, 1);
e1000_set_rxbsize(dev, dev->rx_bsize);
}
+/*
+ * Set interrupt throttle for all interrupts
+ */
+void e1000_set_interrupt_throttle(e1000_device_t *dev, uint16_t rate){
+ /* Enable interrupt throttling rate.
+ *
+ * The optimal performance setting for this register is very system and
+ * configuration specific. A initial suggested range is 651-5580 (28Bh - 15CCh).
+ * The value 0 will disable interrupt throttling
+ */
+ if (dev->mac_type == e1000_82575
+ || dev->mac_type == e1000_82576
+ || dev->mac_type == e1000_I210
+ || dev->mac_type == e1000_I350) {
+ // TODO(lh): Check if these cards really dont need the itr set as well.
+ e1000_eitr_interval_wrf(dev->device, 0, rate);
+ e1000_eitr_interval_wrf(dev->device, 1, rate);
+ e1000_eitr_interval_wrf(dev->device, 2, rate);
+ e1000_eitr_interval_wrf(dev->device, 3, rate);
+ }
+ else if(dev->mac_type == e1000_82574){
+ e1000_itr_interval_wrf(dev->device, rate);
+ e1000_eitr_82574_interval_wrf(dev->device, 0, rate);
+ e1000_eitr_82574_interval_wrf(dev->device, 1, rate);
+ e1000_eitr_82574_interval_wrf(dev->device, 2, rate);
+ e1000_eitr_82574_interval_wrf(dev->device, 3, rate);
+ }
+ else {
+ e1000_itr_interval_wrf(dev->device, 5580);
+ }
+}
+
/*****************************************************************
* Initialize the hardware
*
/* Enable interrupts */
if (use_interrupt) {
-
- /* Enable interrupt throttling rate.
- *
- * The optimal performance setting for this register is very system and
- * configuration specific. A initial suggested range is 651-5580 (28Bh - 15CCh).
- * The value 0 will disable interrupt throttling
- */
- if (dev->mac_type == e1000_82575
- || dev->mac_type == e1000_82576
- || dev->mac_type == e1000_I210
- || dev->mac_type == e1000_I350) {
- e1000_eitr_interval_wrf(dev->device, 0, 5580);
- //e1000_eitr_interval_wrf(dev->device, 0, 10);
- }
- else {
- e1000_itr_interval_wrf(dev->device, 5580);
- //e1000_itr_interval_wrf(dev->device, 10);
- }
+ e1000_set_interrupt_throttle(dev, E1000_DEFAULT_INT_THROTTLE_RATE);
e1000_intreg_t intreg = 0;
-
+ /* Activate link change interrupt */
intreg = e1000_intreg_lsc_insert(intreg, 1);
+ /* Activate rx0 interrupt */
intreg = e1000_intreg_rxt0_insert(intreg, 1);
e1000_ims_wr(dev->device, intreg);
+
+ /* In case of the 82574, we explicitly activate int cause auto clear to
+ * get the same behaviour as the other cards */
+ if(dev->mac_type == e1000_82574){
+ e1000_ctrlext_iame_wrf(dev->device, 1);
+ }
}
}
+++ /dev/null
---------------------------------------------------------------------------
--- Copyright (c) 2007-2009, ETH Zurich.
--- All rights reserved.
---
--- This file is distributed under the terms in the attached LICENSE file.
--- If you do not find this file, copies can be found by writing to:
--- ETH Zurich D-INFK, Haldeneggsteig 4, CH-8092 Zurich. Attn: Systems Group.
---
--- Hakefile for /usr/drivers/e1000e
---
---------------------------------------------------------------------------
-
-[ build application { target = "e1000e_irqtest",
- cFiles = [ "e1000e.c"],
- flounderBindings = [ "net_queue_manager",
- "net_soft_filters", "octopus" ],
- mackerelDevices = [ "e1000e" ],
- addLibraries = libDeps [ "pci", "netQmng", "trace", "octopus" ],
- architectures = [ "x86_64" ],
- addCFlags = [ "-DIRQTEST" ]
- }
-]
+++ /dev/null
-/*
- * Copyright (c) 2016, ETH Zurich. All rights reserved.
- *
- * This file is distributed under the terms in the attached LICENSE file.
- * If you do not find this file, copies can be found by writing to:
- * ETH Zurich D-INFK, Haldeneggsteig 4, CH-8092 Zurich. Attn: Systems Group.
- */
-/*
- * e1000e.c
- *
- * Created on: Oct 10, 2016
- * Author: lh
- *
- * NOTES:
- * General:
- * The driver must be started by Kaluga. It supports
- * the Intel 82574 GbE Controller Family.
- *
- * PCI Ids:
- * Vendor: 0x8086, Device: 0x10d3
- *
- *
- * Inspired by the Barrelfish e1000 driver.
- *
- */
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <barrelfish/barrelfish.h>
-#include <barrelfish/nameservice_client.h>
-#include <octopus/octopus.h>
-#include <net_queue_manager/net_queue_manager.h>
-#include <if/net_queue_manager_defs.h>
-#include <pci/devids.h>
-#include <pci/pci.h>
-
-#include "e1000e_debug.h"
-
-#include <dev/e1000e_dev.h>
-
-static void e1000e_hwinit(e1000e_t *dev, struct device_mem *bar_info,
- int nr_allocated_bars)
-{
- errval_t err;
- if (nr_allocated_bars < 1) {
- USER_PANIC("Error: Not enough PCI bars allocated. Can not initialize network device.\n");
- }
-
- err = map_device(&bar_info[0]);
- if (err_is_fail(err)) {
- USER_PANIC("Error: map_device failed. Can not initialize network device.\n");
- }
-
- e1000e_initialize(dev, (void *) bar_info[0].vaddr);
-}
-
-// Interrupt handler
-static void e1000e_interrupt_handler_fn(void *arg)
-{
- E1000E_DEBUG("e1000e_interrupt_handler called");
-}
-
-// Callback from pci lib
-static void e1000e_init_fn(struct device_mem *bar_info, int nr_allocated_bars) {
- E1000E_DEBUG("e1000e_init_fn interrupt handler called");
- e1000e_t dev;
- e1000e_hwinit(&dev, bar_info, nr_allocated_bars);
-}
-
-// On core move
-static void e1000e_reregister_handler(void *arg) {
- printf("%s:%s:%d:\n", __FILE__, __FUNCTION__, __LINE__);
-}
-
-// Local state
-static uint32_t class = PCI_CLASS_ETHERNET;
-static uint32_t subclass = PCI_DONT_CARE;
-static uint32_t bus = PCI_DONT_CARE;
-static uint32_t device = PCI_DONT_CARE;
-static uint32_t function = PCI_DONT_CARE;
-static uint32_t deviceid = PCI_DONT_CARE;
-static uint32_t vendor = PCI_VENDOR_INTEL;
-static uint32_t program_interface = PCI_DONT_CARE;
-
-int main(int argc, char **argv)
-{
- errval_t err;
- // Parse command line arguments.
- E1000E_DEBUG("e1000e standalone driver started.\n");
- E1000E_DEBUG("argc = %d\n", argc);
-
- // try parse Kaluga information which is located at the last argument
- if (argc > 1) {
- uint32_t parsed = sscanf(argv[argc - 1], "%x:%x:%x:%x:%x", &vendor,
- &deviceid, &bus, &device, &function);
- if (parsed != 5) {
- E1000E_DEBUG("Driver seems not to be started by Kaluga.\n");
- vendor = PCI_DONT_CARE;
- deviceid = PCI_DONT_CARE;
- bus = PCI_DONT_CARE;
- device = PCI_DONT_CARE;
- function = PCI_DONT_CARE;
- } else {
- E1000E_DEBUG("PCI Device (%u, %u, %u) Vendor: 0x%04x, Device 0x%04x\n",
- bus, device, function, vendor, deviceid);
- // remove the last argument
- argc--;
- }
- }
-
- printf("########### Driver with interrupts ###########\n");
- err = pci_register_driver_movable_irq(e1000e_init_fn, class, subclass, program_interface,
- vendor, deviceid, bus, device, function,
- e1000e_interrupt_handler_fn, NULL,
- e1000e_reregister_handler,
- NULL);
- assert(err_is_ok(err));
-
- E1000E_DEBUG("#### starting polling.\n");
- while (true) {
- event_dispatch(get_default_waitset());
- }
- return 1;
-}
-
+++ /dev/null
-/*
- * Copyright (c) 2016, ETH Zurich. All rights reserved.
- *
- * This file is distributed under the terms in the attached LICENSE file.
- * If you do not find this file, copies can be found by writing to:
- * ETH Zurich D-INFK, Haldeneggsteig 4, CH-8092 Zurich. Attn: Systems Group.
- */
-
-#ifndef __E1000E_DEBUG_H__
-#define __E1000E_DEBUG_H__
-
-
-/*****************************************************************
- * Debug printer:
- *****************************************************************/
-#define E1000E_SERVICE_DEBUG 1
-
-
-#if defined(E1000E_SERVICE_DEBUG) || defined(GLOBAL_DEBUG)
-#define E1000E_DEBUG(fmt, ...) printf("e1000e: " fmt, ##__VA_ARGS__)
-#else
-#define E1000E_DEBUG(fmt, ...) ((void)0)
-#endif
-
-#endif // __E1000E_DEBUG_H__
pci_card{ vendor: 16'8086, device: 16'100e, function: _, subvendor: _, subdevice: _ },
pci_card{ vendor: 16'8086, device: 16'10c9, function: _, subvendor: _, subdevice: _ },
pci_card{ vendor: 16'8086, device: 16'10a7, function: _, subvendor: _, subdevice: _ },
+ pci_card{ vendor: 16'8086, device: 16'10d3, function: _, subvendor: _, subdevice: _ },
pci_card{ vendor: 16'8086, device: 16'1533, function: _, subvendor: _, subdevice: _ } ],
core_hint: 0,
core_offset: 0,
% Load the irqtest program with a higher priority than the e1000 driver
pci_driver{
binary: "e1000n_irqtest",
- binary: "irqtest",
supported_cards:
[ pci_card{ vendor: 16'8086, device: 16'1521, function: _, subvendor: _, subdevice: _ },
pci_card{ vendor: 16'8086, device: 16'107d, function: _, subvendor: _, subdevice: _ },
pci_card{ vendor: 16'8086, device: 16'100e, function: _, subvendor: _, subdevice: _ },
pci_card{ vendor: 16'8086, device: 16'10c9, function: _, subvendor: _, subdevice: _ },
pci_card{ vendor: 16'8086, device: 16'10a7, function: _, subvendor: _, subdevice: _ },
- pci_card{ vendor: 16'8086, device: 16'1533, function: _, subvendor: _, subdevice: _ } ],
+ pci_card{ vendor: 16'8086, device: 16'1533, function: _, subvendor: _, subdevice: _ },
+ pci_card{ vendor: 16'8086, device: 16'10d3, function: _, subvendor: _, subdevice: _ } ],
core_hint: 0,
core_offset: 0,
multi_instance: 0,
priority: 1000
}.
-% Load the irqtest_e1000e program
-pci_driver{
- binary: "e1000e_irqtest",
- supported_cards:
- [ pci_card{ vendor: 16'8086, device: 16'10d3, function: _, subvendor: _, subdevice: _ } ],
- core_hint: 0,
- core_offset: 0,
- multi_instance: 0,
- interrupt_load: 0.75,
- platforms: ['x86_64']
-}.