Deleted Added
full compact
33c33
< /*$FreeBSD: head/sys/dev/e1000/if_em.c 295133 2016-02-01 23:51:30Z marius $*/
---
> /*$FreeBSD: head/sys/dev/e1000/if_em.c 295323 2016-02-05 17:14:37Z erj $*/
99,103d98
< * Set this to one to display debug statistics
< *********************************************************************/
< int em_display_debug_stats = 0;
<
< /*********************************************************************
106c101
< char em_driver_version[] = "7.4.2";
---
> char em_driver_version[] = "7.6.1-k";
193a189,195
> { 0x8086, E1000_DEV_ID_PCH_SPT_I219_LM, PCI_ANY_ID, PCI_ANY_ID, 0},
> { 0x8086, E1000_DEV_ID_PCH_SPT_I219_V, PCI_ANY_ID, PCI_ANY_ID, 0},
> { 0x8086, E1000_DEV_ID_PCH_SPT_I219_LM2,
> PCI_ANY_ID, PCI_ANY_ID, 0},
> { 0x8086, E1000_DEV_ID_PCH_SPT_I219_V2, PCI_ANY_ID, PCI_ANY_ID, 0},
> { 0x8086, E1000_DEV_ID_PCH_LBG_I219_LM3,
> PCI_ANY_ID, PCI_ANY_ID, 0},
240a243
> static void em_flush_desc_rings(struct adapter *);
579a583,595
> /*
> ** In the new SPT device flash is not a
> ** seperate BAR, rather it is also in BAR0,
> ** so use the same tag and an offset handle for the
> ** FLASH read/write macros in the shared code.
> */
> else if (hw->mac.type == e1000_pch_spt) {
> adapter->osdep.flash_bus_space_tag =
> adapter->osdep.mem_bus_space_tag;
> adapter->osdep.flash_bus_space_handle =
> adapter->osdep.mem_bus_space_handle
> + E1000_FLASH_BASE_ADDR;
> }
582,583c598,601
< if (e1000_setup_init_funcs(hw, TRUE)) {
< device_printf(dev, "Setup of Shared code failed\n");
---
> error = e1000_setup_init_funcs(hw, TRUE);
> if (error) {
> device_printf(dev, "Setup of Shared code failed, error %d\n",
> error);
1172a1191
> case e1000_pch_spt:
2361a2381,2382
> if (hw->mac.type == e1000_pch_spt)
> msec_delay(50);
2452a2474,2477
> /* I219 needs some special flushing to avoid hangs */
> if (adapter->hw.mac.type == e1000_pch_spt)
> em_flush_desc_rings(adapter);
>
2871a2897,3006
> /*
> ** The 3 following flush routines are used as a workaround in the
> ** I219 client parts and only for them.
> **
> ** em_flush_tx_ring - remove all descriptors from the tx_ring
> **
> ** We want to clear all pending descriptors from the TX ring.
> ** zeroing happens when the HW reads the regs. We assign the ring itself as
> ** the data of the next descriptor. We don't care about the data we are about
> ** to reset the HW.
> */
> static void
> em_flush_tx_ring(struct adapter *adapter)
> {
> struct e1000_hw *hw = &adapter->hw;
> struct tx_ring *txr = adapter->tx_rings;
> struct e1000_tx_desc *txd;
> u32 tctl, txd_lower = E1000_TXD_CMD_IFCS;
> u16 size = 512;
>
> tctl = E1000_READ_REG(hw, E1000_TCTL);
> E1000_WRITE_REG(hw, E1000_TCTL, tctl | E1000_TCTL_EN);
>
> txd = &txr->tx_base[txr->next_avail_desc++];
> if (txr->next_avail_desc == adapter->num_tx_desc)
> txr->next_avail_desc = 0;
>
> /* Just use the ring as a dummy buffer addr */
> txd->buffer_addr = txr->txdma.dma_paddr;
> txd->lower.data = htole32(txd_lower | size);
> txd->upper.data = 0;
>
> /* flush descriptors to memory before notifying the HW */
> wmb();
>
> E1000_WRITE_REG(hw, E1000_TDT(0), txr->next_avail_desc);
> mb();
> usec_delay(250);
> }
>
> /*
> ** em_flush_rx_ring - remove all descriptors from the rx_ring
> **
> ** Mark all descriptors in the RX ring as consumed and disable the rx ring
> */
> static void
> em_flush_rx_ring(struct adapter *adapter)
> {
> struct e1000_hw *hw = &adapter->hw;
> u32 rctl, rxdctl;
>
> rctl = E1000_READ_REG(hw, E1000_RCTL);
> E1000_WRITE_REG(hw, E1000_RCTL, rctl & ~E1000_RCTL_EN);
> E1000_WRITE_FLUSH(hw);
> usec_delay(150);
>
> rxdctl = E1000_READ_REG(hw, E1000_RXDCTL(0));
> /* zero the lower 14 bits (prefetch and host thresholds) */
> rxdctl &= 0xffffc000;
> /*
> * update thresholds: prefetch threshold to 31, host threshold to 1
> * and make sure the granularity is "descriptors" and not "cache lines"
> */
> rxdctl |= (0x1F | (1 << 8) | E1000_RXDCTL_THRESH_UNIT_DESC);
> E1000_WRITE_REG(hw, E1000_RXDCTL(0), rxdctl);
>
> /* momentarily enable the RX ring for the changes to take effect */
> E1000_WRITE_REG(hw, E1000_RCTL, rctl | E1000_RCTL_EN);
> E1000_WRITE_FLUSH(hw);
> usec_delay(150);
> E1000_WRITE_REG(hw, E1000_RCTL, rctl & ~E1000_RCTL_EN);
> }
>
> /*
> ** em_flush_desc_rings - remove all descriptors from the descriptor rings
> **
> ** In i219, the descriptor rings must be emptied before resetting the HW
> ** or before changing the device state to D3 during runtime (runtime PM).
> **
> ** Failure to do this will cause the HW to enter a unit hang state which can
> ** only be released by PCI reset on the device
> **
> */
> static void
> em_flush_desc_rings(struct adapter *adapter)
> {
> struct e1000_hw *hw = &adapter->hw;
> device_t dev = adapter->dev;
> u16 hang_state;
> u32 fext_nvm11, tdlen;
>
> /* First, disable MULR fix in FEXTNVM11 */
> fext_nvm11 = E1000_READ_REG(hw, E1000_FEXTNVM11);
> fext_nvm11 |= E1000_FEXTNVM11_DISABLE_MULR_FIX;
> E1000_WRITE_REG(hw, E1000_FEXTNVM11, fext_nvm11);
>
> /* do nothing if we're not in faulty state, or if the queue is empty */
> tdlen = E1000_READ_REG(hw, E1000_TDLEN(0));
> hang_state = pci_read_config(dev, PCICFG_DESC_RING_STATUS, 2);
> if (!(hang_state & FLUSH_DESC_REQUIRED) || !tdlen)
> return;
> em_flush_tx_ring(adapter);
>
> /* recheck, maybe the fault is caused by the rx ring */
> hang_state = pci_read_config(dev, PCICFG_DESC_RING_STATUS, 2);
> if (hang_state & FLUSH_DESC_REQUIRED)
> em_flush_rx_ring(adapter);
> }
>
>
2932a3068
> case e1000_pch_spt:
2990a3127
> case e1000_pch_spt:
3014a3152,3155
> /* I219 needs some special flushing to avoid hangs */
> if (hw->mac.type == e1000_pch_spt)
> em_flush_desc_rings(adapter);
>
3610a3752,3760
> if (hw->mac.type == e1000_pch_spt) {
> u32 reg;
> reg = E1000_READ_REG(hw, E1000_IOSFPC);
> reg |= E1000_RCTL_RDMTS_HEX;
> E1000_WRITE_REG(hw, E1000_IOSFPC, reg);
> reg = E1000_READ_REG(hw, E1000_TARC(0));
> reg |= E1000_TARC0_CB_MULTIQ_3_REQ;
> E1000_WRITE_REG(hw, E1000_TARC(0), reg);
> }