From 9575ffb769f24a7c6a3b4bf576bcc3ffb11bba5c Mon Sep 17 00:00:00 2001 From: Stefan Lankes Date: Thu, 2 Aug 2012 10:46:47 +0200 Subject: [PATCH] fix bug in the determination of the link speed --- drivers/net/e1000.c | 53 ++++++++++++++++++++++++++++++++------------- drivers/net/e1000.h | 35 ++++++++++++++++++++++++++++++ 2 files changed, 73 insertions(+), 15 deletions(-) diff --git a/drivers/net/e1000.c b/drivers/net/e1000.c index 26aae4c3..74eb4592 100644 --- a/drivers/net/e1000.c +++ b/drivers/net/e1000.c @@ -38,7 +38,7 @@ #define RX_BUF_LEN (2048) #define TX_BUF_LEN (1792) -#define INT_MASK (E1000_IMS_RXO|E1000_IMS_RXT0|E1000_IMS_RXDMT0|E1000_IMS_RXSEQ|E1000_IMS_LSC) +#define INT_MASK (E1000_ICR_TXDW|E1000_ICR_TXQE|E1000_IMS_RXO|E1000_IMS_RXT0|E1000_IMS_RXDMT0|E1000_IMS_RXSEQ|E1000_IMS_LSC) #define INT_MASK_NO_RX (E1000_IMS_LSC) typedef struct { @@ -353,7 +353,7 @@ err_t e1000if_init(struct netif* netif) pci_info_t pci_info; e1000if_t* e1000if = NULL; uint32_t tmp32; - uint16_t tmp16, speed; + uint16_t tmp16, speed, cold = 0x40; uint8_t tmp8, is64bit, mem_type, prefetch; static uint8_t num = 0; @@ -400,6 +400,8 @@ err_t e1000if_init(struct netif* netif) // reset device e1000_write(e1000if->bar0, E1000_CTRL, E1000_CTRL_RST); e1000_flush(e1000if->bar0); + /* Wait for reset to complete */ + udelay(10); e1000if->irq = pci_info.irq; e1000if->rx_desc = mem_allocation(NUM_RX_DESCRIPTORS*sizeof(rx_desc_t), MAP_KERNEL_SPACE|MAP_NO_CACHE); @@ -441,6 +443,11 @@ err_t e1000if_init(struct netif* netif) e1000_flush(e1000if->bar0); kprintf("e1000if_init: Device Control Register 0x%x\n", e1000_read(e1000if->bar0, E1000_CTRL)); + /* make sure transmits are disabled while setting up the descriptors */ + tmp32 = e1000_read(e1000if->bar0, E1000_TCTL); + e1000_write(e1000if->bar0, E1000_TCTL, tmp32 & ~E1000_TCTL_EN); + e1000_flush(e1000if->bar0); + // setup the transmit descriptor ring buffer e1000_write(e1000if->bar0, E1000_TDBAL, (uint32_t)((uint64_t)virt_to_phys((size_t)e1000if->tx_desc) & 0xFFFFFFFF)); e1000_write(e1000if->bar0, E1000_TDBAH, (uint32_t)((uint64_t)virt_to_phys((size_t)e1000if->tx_desc) >> 32)); @@ -454,8 +461,21 @@ err_t e1000if_init(struct netif* netif) e1000_write(e1000if->bar0, E1000_TDT, 0); e1000if->tx_tail = 0; + tmp32 = e1000_read(e1000if->bar0, E1000_STATUS); + if (tmp32 & E1000_STATUS_SPEED_1000) + speed = 1000; + else if (tmp32 & E1000_STATUS_SPEED_100) + speed = 100; + else + speed = 10; + + if ((!(tmp32 & E1000_STATUS_FD)) && (speed == 1000)) + cold = 0x200; + LWIP_DEBUGF(NETIF_DEBUG, ("e1000if_init: speed = %u mbps\n", speed)); + LWIP_DEBUGF(NETIF_DEBUG, ("e1000if_init: Full-Duplex %u\n", tmp32 & E1000_STATUS_FD)); + // set the transmit control register (padshortpackets) - e1000_write(e1000if->bar0, E1000_TCTL, (E1000_TCTL_EN | E1000_TCTL_PSP | (0x40 << 12) | (0x10 << 4))); + e1000_write(e1000if->bar0, E1000_TCTL, (E1000_TCTL_EN | E1000_TCTL_PSP | (cold << 12) | (0x10 << 4))); e1000_flush(e1000if->bar0); // set IEEE 802.3 standard IPG value @@ -470,6 +490,12 @@ err_t e1000if_init(struct netif* netif) ((uint8_t*) &tmp32)[tmp8] = mynetif->hwaddr[tmp8+4]; e1000_write(e1000if->bar0, E1000_RA+4, tmp32 | (1 << 31)); // set also AV bit to check incoming packets + /* Zero out the other receive addresses. */ + for (tmp8=1; tmp8<16; tmp8++) { + e1000_write(e1000if->bar0, E1000_RA+8*tmp8, 0); + e1000_write(e1000if->bar0, E1000_RA+8*tmp8+4, 0); + } + LWIP_DEBUGF(NETIF_DEBUG, ("e1000if_init: MAC address ")); tmp32 = e1000_read(e1000if->bar0, E1000_RA); for(tmp8=0; tmp8<4; tmp8++) { @@ -490,6 +516,11 @@ err_t e1000if_init(struct netif* netif) // set IRQ handler irq_install_handler(e1000if->irq+32, e1000if_handler); + /* make sure receives are disabled while setting up the descriptors */ + tmp32 = e1000_read(e1000if->bar0, E1000_RCTL); + e1000_write(e1000if->bar0, E1000_RCTL, tmp32 & ~E1000_RCTL_EN); + e1000_flush(e1000if->bar0); + // clear IMS & IMC registers e1000_write(e1000if->bar0, E1000_IMS, 0xFFFF); e1000_flush(e1000if->bar0); @@ -524,20 +555,12 @@ err_t e1000if_init(struct netif* netif) e1000_write(e1000if->bar0, E1000_RDT, 0); e1000if->rx_tail = 0; - // set the receieve control register (promisc ON) - e1000_write(e1000if->bar0, E1000_RCTL, (E1000_RCTL_EN|/*E1000_RCTL_LPE|*/E1000_RCTL_BAM|E1000_RCTL_SZ_2048| - E1000_RCTL_SECRC|E1000_RCTL_RDMTS_HALF|E1000_RCTL_MO_0|E1000_RCTL_UPE|E1000_RCTL_MPE)); + // set the receieve control register + e1000_write(e1000if->bar0, E1000_RCTL, (E1000_RCTL_EN|/*E1000_RCTL_LPE|*/E1000_RCTL_LBM_NO|E1000_RCTL_BAM|E1000_RCTL_SZ_2048| + E1000_RCTL_SECRC|E1000_RCTL_RDMTS_HALF|E1000_RCTL_MO_0/*|E1000_RCTL_UPE|E1000_RCTL_MPE*/)); e1000_flush(e1000if->bar0); - tmp32 = e1000_read(e1000if->bar0, E1000_CTRL); - if (tmp32 & E1000_CTRL_SPD_1000) - speed = 1000; - else if (tmp32 & E1000_CTRL_SPD_100) - speed = 100; - else - speed = 10; - - LWIP_DEBUGF(NETIF_DEBUG, ("e1000if_init: speed = %u mbps\n", speed)); + LWIP_DEBUGF(NETIF_DEBUG, ("e1000if_init: status = 0x%x\n", e1000_read(e1000if->bar0, E1000_STATUS))); /* * Initialize the snmp variables and counters inside the struct netif. diff --git a/drivers/net/e1000.h b/drivers/net/e1000.h index 92d63423..d6e44777 100644 --- a/drivers/net/e1000.h +++ b/drivers/net/e1000.h @@ -35,6 +35,7 @@ #define E1000_STATUS 0x00008 /* Device Status - RO */ #define E1000_EECD 0x00010 /* EEPROM/Flash Control - RW */ #define E1000_EERD 0x00014 /* EEPROM Read - RW */ +#define E1000_CTRL_EXT 0x00018 /* Extended Device Control - RW */ #define E1000_ICR 0x000C0 /* Interrupt Cause Read - R/clr */ #define E1000_ITR 0x000C4 /* Interrupt Throttling Rate - RW */ #define E1000_ICS 0x000C8 /* Interrupt Cause Set - WO */ @@ -95,6 +96,40 @@ #define E1000_CTRL_PHY_RST 0x80000000 /* PHY Reset */ #define E1000_CTRL_SW2FW_INT 0x02000000 /* Initiate an interrupt to manageability engine */ +/* Device Status */ +#define E1000_STATUS_FD 0x00000001 /* Full duplex.0=half,1=full */ +#define E1000_STATUS_LU 0x00000002 /* Link up.0=no,1=link */ +#define E1000_STATUS_FUNC_MASK 0x0000000C /* PCI Function Mask */ +#define E1000_STATUS_FUNC_SHIFT 2 +#define E1000_STATUS_FUNC_0 0x00000000 /* Function 0 */ +#define E1000_STATUS_FUNC_1 0x00000004 /* Function 1 */ +#define E1000_STATUS_TXOFF 0x00000010 /* transmission paused */ +#define E1000_STATUS_TBIMODE 0x00000020 /* TBI mode */ +#define E1000_STATUS_SPEED_MASK 0x000000C0 +#define E1000_STATUS_SPEED_10 0x00000000 /* Speed 10Mb/s */ +#define E1000_STATUS_SPEED_100 0x00000040 /* Speed 100Mb/s */ +#define E1000_STATUS_SPEED_1000 0x00000080 /* Speed 1000Mb/s */ +#define E1000_STATUS_LAN_INIT_DONE 0x00000200 /* Lan Init Completion + by EEPROM/Flash */ +#define E1000_STATUS_ASDV 0x00000300 /* Auto speed detect value */ +#define E1000_STATUS_DOCK_CI 0x00000800 /* Change in Dock/Undock state. Clear on write '0'. */ +#define E1000_STATUS_GIO_MASTER_ENABLE 0x00080000 /* Status of Master requests. */ +#define E1000_STATUS_MTXCKOK 0x00000400 /* MTX clock running OK */ +#define E1000_STATUS_PCI66 0x00000800 /* In 66Mhz slot */ +#define E1000_STATUS_BUS64 0x00001000 /* In 64 bit slot */ +#define E1000_STATUS_PCIX_MODE 0x00002000 /* PCI-X mode */ +#define E1000_STATUS_PCIX_SPEED 0x0000C000 /* PCI-X bus speed */ +#define E1000_STATUS_BMC_SKU_0 0x00100000 /* BMC USB redirect disabled */ +#define E1000_STATUS_BMC_SKU_1 0x00200000 /* BMC SRAM disabled */ +#define E1000_STATUS_BMC_SKU_2 0x00400000 /* BMC SDRAM disabled */ +#define E1000_STATUS_BMC_CRYPTO 0x00800000 /* BMC crypto disabled */ +#define E1000_STATUS_BMC_LITE 0x01000000 /* BMC external code execution disabled */ +#define E1000_STATUS_RGMII_ENABLE 0x02000000 /* RGMII disabled */ +#define E1000_STATUS_FUSE_8 0x04000000 +#define E1000_STATUS_FUSE_9 0x08000000 +#define E1000_STATUS_SERDES0_DIS 0x10000000 /* SERDES disabled on port 0 */ +#define E1000_STATUS_SERDES1_DIS 0x20000000 /* SERDES disabled on port 1 */ + /* Transmit Control */ #define E1000_TCTL_RST 0x00000001 /* software reset */ #define E1000_TCTL_EN 0x00000002 /* enable tx */