fix bug in the determination of the link speed

This commit is contained in:
Stefan Lankes 2012-08-02 10:46:47 +02:00
parent e2550fbdb2
commit 9575ffb769
2 changed files with 73 additions and 15 deletions

View file

@ -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.

View file

@ -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 */