/* only call this for fiber/serdes connections to es2lan */ static int e1000_set_es2lan_mac_loopback(struct e1000_adapter *adapter) { struct e1000_hw *hw = &adapter->hw; u32 ctrlext = er32(CTRL_EXT); u32 ctrl = er32(CTRL); /* * save CTRL_EXT to restore later, reuse an empty variable (unused * on mac_type 80003es2lan) */ adapter->tx_fifo_head = ctrlext; /* clear the serdes mode bits, putting the device into mac loopback */ ctrlext &= ~E1000_CTRL_EXT_LINK_MODE_PCIE_SERDES; ew32(CTRL_EXT, ctrlext); /* force speed to 1000/FD, link up */ ctrl &= ~(E1000_CTRL_SPD_1000 | E1000_CTRL_SPD_100); ctrl |= (E1000_CTRL_SLU | E1000_CTRL_FRCSPD | E1000_CTRL_FRCDPX | E1000_CTRL_SPD_1000 | E1000_CTRL_FD); ew32(CTRL, ctrl); /* set mac loopback */ ctrl = er32(RCTL); ctrl |= E1000_RCTL_LBM_MAC; ew32(RCTL, ctrl); /* set testing mode parameters (no need to reset later) */ #define KMRNCTRLSTA_OPMODE (0x1F << 16) #define KMRNCTRLSTA_OPMODE_1GB_FD_GMII 0x0582 ew32(KMRNCTRLSTA, (KMRNCTRLSTA_OPMODE | KMRNCTRLSTA_OPMODE_1GB_FD_GMII)); return 0; }
/** * e1000e_reset - bring the hardware into a known good state * * This function boots the hardware and enables some settings that * require a configuration cycle of the hardware - those cannot be * set/changed during runtime. After reset the device needs to be * properly configured for Rx, Tx etc. */ void e1000e_reset(struct e1000_adapter *adapter) { struct e1000_mac_info *mac = &adapter->hw.mac; struct e1000_fc_info *fc = &adapter->hw.fc; u32 pba = adapter->pba; struct e1000_hw *hw = &adapter->hw; /* Reset Packet Buffer Allocation to default */ ew32(PBA, pba); hw->fc.requested_mode = e1000_fc_none; fc->current_mode = fc->requested_mode; /* Allow time for pending master requests to run */ mac->ops.reset_hw(hw); /* * For parts with AMT enabled, let the firmware know * that the network interface is in control */ if (adapter->flags & FLAG_HAS_AMT) e1000e_get_hw_control(adapter); ew32(WUC, 0); if (adapter->flags2 & FLAG2_HAS_PHY_WAKEUP) e1e_wphy(&adapter->hw, BM_WUC, 0); if (mac->ops.init_hw(hw)) DBG("Hardware Error\n"); /* additional part of the flow-control workaround above */ if (hw->mac.type == e1000_pchlan) ew32(FCRTV_PCH, 0x1000); e1000e_reset_adaptive(hw); e1000e_get_phy_info(hw); if ((adapter->flags & FLAG_HAS_SMART_POWER_DOWN) && !(adapter->flags & FLAG_SMART_POWER_DOWN)) { u16 phy_data = 0; /* * speed up time to link by disabling smart power down, ignore * the return value of this function because there is nothing * different we would do if it failed */ e1e_rphy(hw, IGP02E1000_PHY_POWER_MGMT, &phy_data); phy_data &= ~IGP02E1000_PM_SPD; e1e_wphy(hw, IGP02E1000_PHY_POWER_MGMT, phy_data); } }
/** * e1000_get_hw_control - get control of the h/w from f/w * @adapter: address of board private structure * * e1000_get_hw_control sets {CTRL_EXT|SWSM}:DRV_LOAD bit. * For ASF and Pass Through versions of f/w this means that * the driver is loaded. For AMT version (only with 82573) * of the f/w this means that the network i/f is open. **/ static void e1000e_get_hw_control(struct e1000_adapter *adapter) { struct e1000_hw *hw = &adapter->hw; u32 ctrl_ext; u32 swsm; /* Let firmware know the driver has taken over */ if (adapter->flags & FLAG_HAS_SWSM_ON_LOAD) { swsm = er32(SWSM); ew32(SWSM, swsm | E1000_SWSM_DRV_LOAD); } else if (adapter->flags & FLAG_HAS_CTRLEXT_ON_LOAD) { ctrl_ext = er32(CTRL_EXT); ew32(CTRL_EXT, ctrl_ext | E1000_CTRL_EXT_DRV_LOAD); } }
static int e1000_setup_loopback_test(struct e1000_adapter *adapter) { struct e1000_hw *hw = &adapter->hw; u32 rctl; if (hw->phy.media_type == e1000_media_type_fiber || hw->phy.media_type == e1000_media_type_internal_serdes) { switch (hw->mac.type) { case e1000_80003es2lan: return e1000_set_es2lan_mac_loopback(adapter); break; case e1000_82571: case e1000_82572: return e1000_set_82571_fiber_loopback(adapter); break; default: rctl = er32(RCTL); rctl |= E1000_RCTL_LBM_TCVR; ew32(RCTL, rctl); return 0; } } else if (hw->phy.media_type == e1000_media_type_copper) { return e1000_integrated_phy_loopback(adapter); } return 7; }
/** * e1000e_irq_disable - Mask off interrupt generation on the NIC **/ static void e1000e_irq_disable(struct e1000_adapter *adapter) { struct e1000_hw *hw = &adapter->hw; ew32(IMC, ~0); e1e_flush(); }
/** * e1000e_mng_write_dhcp_info - Writes DHCP info to host interface * @hw: pointer to the HW structure * @buffer: pointer to the host interface * @length: size of the buffer * * Writes the DHCP information to the host interface. **/ s32 e1000e_mng_write_dhcp_info(struct e1000_hw *hw, u8 *buffer, u16 length) { struct e1000_host_mng_command_header hdr; s32 ret_val; u32 hicr; hdr.command_id = E1000_MNG_DHCP_TX_PAYLOAD_CMD; hdr.command_length = length; hdr.reserved1 = 0; hdr.reserved2 = 0; hdr.checksum = 0; /* Enable the host interface */ ret_val = hw->mac.ops.mng_enable_host_if(hw); if (ret_val) return ret_val; /* Populate the host interface with the contents of "buffer". */ ret_val = hw->mac.ops.mng_host_if_write(hw, buffer, length, sizeof(hdr), &(hdr.checksum)); if (ret_val) return ret_val; /* Write the manageability command header */ ret_val = hw->mac.ops.mng_write_cmd_header(hw, &hdr); if (ret_val) return ret_val; /* Tell the ARC a new command is pending. */ hicr = er32(HICR); ew32(HICR, hicr | E1000_HICR_C); return 0; }
/** * e1000_write_mbx_vf - Write a message to the mailbox * @hw: pointer to the HW structure * @msg: The message buffer * @size: Length of buffer * * returns SUCCESS if it successfully copied message into the buffer **/ static s32 e1000_write_mbx_vf(struct e1000_hw *hw, u32 *msg, u16 size) { s32 err; u16 i; /* lock the mailbox to prevent pf/vf race condition */ err = e1000_obtain_mbx_lock_vf(hw); if (err) goto out_no_write; /* flush any ack or msg as we are going to overwrite mailbox */ e1000_check_for_ack_vf(hw); e1000_check_for_msg_vf(hw); /* copy the caller specified message to the mailbox memory buffer */ for (i = 0; i < size; i++) array_ew32(VMBMEM(0), i, msg[i]); /* update stats */ hw->mbx.stats.msgs_tx++; /* Drop VFU and interrupt the PF to tell it a message has been sent */ ew32(V2PMAILBOX(0), E1000_V2PMAILBOX_REQ); out_no_write: return err; }
/** * e1000e_irq_enable - Enable default interrupt generation settings **/ static void e1000e_irq_enable(struct e1000_adapter *adapter) { struct e1000_hw *hw = &adapter->hw; ew32(IMS, IMS_ENABLE_MASK); e1e_flush(); }
/** * e1000_read_mbx_vf - Reads a message from the inbox intended for VF * @hw: pointer to the HW structure * @msg: The message buffer * @size: Length of buffer * * returns SUCCESS if it successfully read message from buffer **/ static s32 e1000_read_mbx_vf(struct e1000_hw *hw, u32 *msg, u16 size) { s32 err; u16 i; WARN_ON_ONCE(!spin_is_locked(&hw->mbx_lock)); /* lock the mailbox to prevent pf/vf race condition */ err = e1000_obtain_mbx_lock_vf(hw); if (err) goto out_no_read; /* copy the message from the mailbox memory buffer */ for (i = 0; i < size; i++) msg[i] = array_er32(VMBMEM(0), i); /* Acknowledge receipt and release mailbox, then we're done */ ew32(V2PMAILBOX(0), E1000_V2PMAILBOX_ACK); /* update stats */ hw->mbx.stats.msgs_rx++; out_no_read: return err; }
/** * e1000_obtain_mbx_lock_vf - obtain mailbox lock * @hw: pointer to the HW structure * * return SUCCESS if we obtained the mailbox lock **/ static s32 e1000_obtain_mbx_lock_vf(struct e1000_hw *hw) { s32 ret_val = -E1000_ERR_MBX; /* Take ownership of the buffer */ ew32(V2PMAILBOX(0), E1000_V2PMAILBOX_VFU); /* reserve mailbox for vf use */ if (e1000_read_v2p_mailbox(hw) & E1000_V2PMAILBOX_VFU) ret_val = E1000_SUCCESS; return ret_val; }
static int e1000_set_82571_fiber_loopback(struct e1000_adapter *adapter) { struct e1000_hw *hw = &adapter->hw; u32 ctrl = er32(CTRL); int link = 0; /* special requirements for 82571/82572 fiber adapters */ /* * jump through hoops to make sure link is up because serdes * link is hardwired up */ ctrl |= E1000_CTRL_SLU; ew32(CTRL, ctrl); /* disable autoneg */ ctrl = er32(TXCW); ctrl &= ~(1 << 31); ew32(TXCW, ctrl); link = (er32(STATUS) & E1000_STATUS_LU); if (!link) { /* set invert loss of signal */ ctrl = er32(CTRL); ctrl |= E1000_CTRL_ILOS; ew32(CTRL, ctrl); } /* * special write to serdes control register to enable SerDes analog * loopback */ #define E1000_SERDES_LB_ON 0x410 ew32(SCTL, E1000_SERDES_LB_ON); msleep(10); return 0; }
static void e1000_loopback_cleanup(struct e1000_adapter *adapter) { struct e1000_hw *hw = &adapter->hw; u32 rctl; u16 phy_reg; rctl = er32(RCTL); rctl &= ~(E1000_RCTL_LBM_TCVR | E1000_RCTL_LBM_MAC); ew32(RCTL, rctl); switch (hw->mac.type) { case e1000_80003es2lan: if (hw->phy.media_type == e1000_media_type_fiber || hw->phy.media_type == e1000_media_type_internal_serdes) { /* restore CTRL_EXT, steal
/** * e1000e_phc_adjfreq - adjust the frequency of the hardware clock * @ptp: ptp clock structure * @delta: Desired frequency change in parts per billion * * Adjust the frequency of the PHC cycle counter by the indicated delta from * the base frequency. **/ static int e1000e_phc_adjfreq(struct ptp_clock_info *ptp, s32 delta) { struct e1000_adapter *adapter = container_of(ptp, struct e1000_adapter, ptp_clock_info); struct e1000_hw *hw = &adapter->hw; bool neg_adj = false; unsigned long flags; u64 adjustment; u32 timinca, incvalue; s32 ret_val; if ((delta > ptp->max_adj) || (delta <= -1000000000)) return -EINVAL; if (delta < 0) { neg_adj = true; delta = -delta; } /* Get the System Time Register SYSTIM base frequency */ ret_val = e1000e_get_base_timinca(adapter, &timinca); if (ret_val) return ret_val; spin_lock_irqsave(&adapter->systim_lock, flags); incvalue = timinca & E1000_TIMINCA_INCVALUE_MASK; adjustment = incvalue; adjustment *= delta; adjustment = div_u64(adjustment, 1000000000); incvalue = neg_adj ? (incvalue - adjustment) : (incvalue + adjustment); timinca &= ~E1000_TIMINCA_INCVALUE_MASK; timinca |= incvalue; ew32(TIMINCA, timinca); adapter->ptp_delta = delta; spin_unlock_irqrestore(&adapter->systim_lock, flags); return 0; }
/** * e1000_obtain_mbx_lock_vf - obtain mailbox lock * @hw: pointer to the HW structure * * return SUCCESS if we obtained the mailbox lock **/ static s32 e1000_obtain_mbx_lock_vf(struct e1000_hw *hw) { s32 ret_val = -E1000_ERR_MBX; int count = 10; do { /* Take ownership of the buffer */ ew32(V2PMAILBOX(0), E1000_V2PMAILBOX_VFU); /* reserve mailbox for VF use */ if (e1000_read_v2p_mailbox(hw) & E1000_V2PMAILBOX_VFU) { ret_val = 0; break; } udelay(1000); } while (count-- > 0); return ret_val; }
static int e1000_hw_reset(struct e1000_hw *hw) { uint32_t ctrl; uint32_t icr; /* Clear interrupt mask to stop board from generating interrupts */ ew32(IMC, 0xffffffff); /* Disable the Transmit and Receive units. Then delay to allow * any pending transactions to complete before we hit the MAC with * the global reset. */ ew32(RCTL, 0); ew32(TCTL, E1000_TCTL_PSP); er32(STATUS); /* wait for complete */ /* Delay to allow any outstanding PCI transactions to complete before * resetting the device */ delay_usec(10000); ctrl = er32(CTRL); /* reset phy */ ew32(CTRL, (ctrl | E1000_CTRL_PHY_RST)); delay_usec(5000); /* Issue a global reset to the MAC. This will reset the chip's * transmit, receive, DMA, and link units. It will not effect * the current PCI configuration. The global reset bit is self- * clearing, and should clear within a microsecond. */ ew32(CTRL, (ctrl | E1000_CTRL_RST)); /* After MAC reset, force reload of EEPROM to restore power-on * settings to device. Later controllers reload the EEPROM * automatically, so just wait for reload to complete. */ delay_usec(20000); /* Clear interrupt mask to stop board from generating interrupts */ ew32(IMC, 0xffffffff); /* Clear any pending interrupt events. */ icr = er32(ICR); return 0; }
/** * e1000e_phc_get_syncdevicetime - Callback given to timekeeping code reads system/device registers * @device: current device time * @system: system counter value read synchronously with device time * @ctx: context provided by timekeeping code * * Read device and system (ART) clock simultaneously and return the corrected * clock values in ns. **/ static int e1000e_phc_get_syncdevicetime(ktime_t *device, struct system_counterval_t *system, void *ctx) { struct e1000_adapter *adapter = (struct e1000_adapter *)ctx; struct e1000_hw *hw = &adapter->hw; unsigned long flags; int i; u32 tsync_ctrl; u64 dev_cycles; u64 sys_cycles; tsync_ctrl = er32(TSYNCTXCTL); tsync_ctrl |= E1000_TSYNCTXCTL_START_SYNC | E1000_TSYNCTXCTL_MAX_ALLOWED_DLY_MASK; ew32(TSYNCTXCTL, tsync_ctrl); for (i = 0; i < MAX_HW_WAIT_COUNT; ++i) { udelay(1); tsync_ctrl = er32(TSYNCTXCTL); if (tsync_ctrl & E1000_TSYNCTXCTL_SYNC_COMP) break; } if (i == MAX_HW_WAIT_COUNT) return -ETIMEDOUT; dev_cycles = er32(SYSSTMPH); dev_cycles <<= 32; dev_cycles |= er32(SYSSTMPL); spin_lock_irqsave(&adapter->systim_lock, flags); *device = ns_to_ktime(timecounter_cyc2time(&adapter->tc, dev_cycles)); spin_unlock_irqrestore(&adapter->systim_lock, flags); sys_cycles = er32(PLTSTMPH); sys_cycles <<= 32; sys_cycles |= er32(PLTSTMPL); *system = convert_art_to_tsc(sys_cycles); return 0; }
static int e1000_setup_desc_rings(struct e1000_adapter *adapter) { struct e1000_ring *tx_ring = &adapter->test_tx_ring; struct e1000_ring *rx_ring = &adapter->test_rx_ring; struct pci_dev *pdev = adapter->pdev; struct e1000_hw *hw = &adapter->hw; u32 rctl; int i; int ret_val; /* Setup Tx descriptor ring and Tx buffers */ if (!tx_ring->count) tx_ring->count = E1000_DEFAULT_TXD; tx_ring->buffer_info = kcalloc(tx_ring->count, sizeof(struct e1000_buffer), GFP_KERNEL); if (!(tx_ring->buffer_info)) { ret_val = 1; goto err_nomem; } tx_ring->size = tx_ring->count * sizeof(struct e1000_tx_desc); tx_ring->size = ALIGN(tx_ring->size, 4096); tx_ring->desc = dma_alloc_coherent(&pdev->dev, tx_ring->size, &tx_ring->dma, GFP_KERNEL); if (!tx_ring->desc) { ret_val = 2; goto err_nomem; } tx_ring->next_to_use = 0; tx_ring->next_to_clean = 0; ew32(TDBAL, ((u64) tx_ring->dma & 0x00000000FFFFFFFF)); ew32(TDBAH, ((u64) tx_ring->dma >> 32)); ew32(TDLEN, tx_ring->count * sizeof(struct e1000_tx_desc)); ew32(TDH, 0); ew32(TDT, 0); ew32(TCTL, E1000_TCTL_PSP | E1000_TCTL_EN | E1000_TCTL_MULR | E1000_COLLISION_THRESHOLD << E1000_CT_SHIFT | E1000_COLLISION_DISTANCE << E1000_COLD_SHIFT); for (i = 0; i < tx_ring->count; i++) { struct e1000_tx_desc *tx_desc = E1000_TX_DESC(*tx_ring, i); struct sk_buff *skb; unsigned int skb_size = 1024; skb = alloc_skb(skb_size, GFP_KERNEL); if (!skb) { ret_val = 3; goto err_nomem; } skb_put(skb, skb_size); tx_ring->buffer_info[i].skb = skb; tx_ring->buffer_info[i].length = skb->len; tx_ring->buffer_info[i].dma = pci_map_single(pdev, skb->data, skb->len, PCI_DMA_TODEVICE); if (pci_dma_mapping_error(pdev, tx_ring->buffer_info[i].dma)) { ret_val = 4; goto err_nomem; } tx_desc->buffer_addr = cpu_to_le64(tx_ring->buffer_info[i].dma); tx_desc->lower.data = cpu_to_le32(skb->len); tx_desc->lower.data |= cpu_to_le32(E1000_TXD_CMD_EOP | E1000_TXD_CMD_IFCS | E1000_TXD_CMD_RS); tx_desc->upper.data = 0; } /* Setup Rx descriptor ring and Rx buffers */ if (!rx_ring->count) rx_ring->count = E1000_DEFAULT_RXD; rx_ring->buffer_info = kcalloc(rx_ring->count, sizeof(struct e1000_buffer), GFP_KERNEL); if (!(rx_ring->buffer_info)) { ret_val = 5; goto err_nomem; } rx_ring->size = rx_ring->count * sizeof(struct e1000_rx_desc); rx_ring->desc = dma_alloc_coherent(&pdev->dev, rx_ring->size, &rx_ring->dma, GFP_KERNEL); if (!rx_ring->desc) { ret_val = 6; goto err_nomem; } rx_ring->next_to_use = 0; rx_ring->next_to_clean = 0; rctl = er32(RCTL); ew32(RCTL, rctl & ~E1000_RCTL_EN); ew32(RDBAL, ((u64) rx_ring->dma & 0xFFFFFFFF)); ew32(RDBAH, ((u64) rx_ring->dma >> 32)); ew32(RDLEN, rx_ring->size); ew32(RDH, 0); ew32(RDT, 0); rctl = E1000_RCTL_EN | E1000_RCTL_BAM | E1000_RCTL_SZ_2048 | E1000_RCTL_UPE | E1000_RCTL_MPE | E1000_RCTL_LPE | E1000_RCTL_SBP | E1000_RCTL_SECRC | E1000_RCTL_LBM_NO | E1000_RCTL_RDMTS_HALF | (adapter->hw.mac.mc_filter_type << E1000_RCTL_MO_SHIFT); ew32(RCTL, rctl); for (i = 0; i < rx_ring->count; i++) { struct e1000_rx_desc *rx_desc = E1000_RX_DESC(*rx_ring, i); struct sk_buff *skb; skb = alloc_skb(2048 + NET_IP_ALIGN, GFP_KERNEL); if (!skb) { ret_val = 7; goto err_nomem; } skb_reserve(skb, NET_IP_ALIGN); rx_ring->buffer_info[i].skb = skb; rx_ring->buffer_info[i].dma = pci_map_single(pdev, skb->data, 2048, PCI_DMA_FROMDEVICE); if (pci_dma_mapping_error(pdev, rx_ring->buffer_info[i].dma)) { ret_val = 8; goto err_nomem; } rx_desc->buffer_addr = cpu_to_le64(rx_ring->buffer_info[i].dma); memset(skb->data, 0x00, skb->len); } return 0; err_nomem: e1000_free_desc_rings(adapter); return ret_val; }
static int e1000_intr_test(struct e1000_adapter *adapter, u64 *data) { struct net_device *netdev = adapter->netdev; struct e1000_hw *hw = &adapter->hw; u32 mask; u32 shared_int = 1; u32 irq = adapter->pdev->irq; int i; int ret_val = 0; int int_mode = E1000E_INT_MODE_LEGACY; *data = 0; /* NOTE: we don't test MSI/MSI-X interrupts here, yet */ if (adapter->int_mode == E1000E_INT_MODE_MSIX) { int_mode = adapter->int_mode; e1000e_reset_interrupt_capability(adapter); adapter->int_mode = E1000E_INT_MODE_LEGACY; e1000e_set_interrupt_capability(adapter); } /* Hook up test interrupt handler just for this test */ if (!request_irq(irq, e1000_test_intr, IRQF_PROBE_SHARED, netdev->name, netdev)) { shared_int = 0; } else if (request_irq(irq, e1000_test_intr, IRQF_SHARED, netdev->name, netdev)) { *data = 1; ret_val = -1; goto out; } e_info("testing %s interrupt\n", (shared_int ? "shared" : "unshared")); /* Disable all the interrupts */ ew32(IMC, 0xFFFFFFFF); e1e_flush(); usleep_range(10000, 20000); /* Test each interrupt */ for (i = 0; i < 10; i++) { /* Interrupt to test */ mask = 1 << i; if (adapter->flags & FLAG_IS_ICH) { switch (mask) { case E1000_ICR_RXSEQ: continue; case 0x00000100: if (adapter->hw.mac.type == e1000_ich8lan || adapter->hw.mac.type == e1000_ich9lan) continue; break; default: break; } } if (!shared_int) { /* * Disable the interrupt to be reported in * the cause register and then force the same * interrupt and see if one gets posted. If * an interrupt was posted to the bus, the * test failed. */ adapter->test_icr = 0; ew32(IMC, mask); ew32(ICS, mask); e1e_flush(); usleep_range(10000, 20000); if (adapter->test_icr & mask) { *data = 3; break; } } /* * Enable the interrupt to be reported in * the cause register and then force the same * interrupt and see if one gets posted. If * an interrupt was not posted to the bus, the * test failed. */ adapter->test_icr = 0; ew32(IMS, mask); ew32(ICS, mask); e1e_flush(); usleep_range(10000, 20000); if (!(adapter->test_icr & mask)) { *data = 4; break; } if (!shared_int) { /* * Disable the other interrupts to be reported in * the cause register and then force the other * interrupts and see if any get posted. If * an interrupt was posted to the bus, the * test failed. */ adapter->test_icr = 0; ew32(IMC, ~mask & 0x00007FFF); ew32(ICS, ~mask & 0x00007FFF); e1e_flush(); usleep_range(10000, 20000); if (adapter->test_icr) { *data = 5; break; } } } /* Disable all the interrupts */ ew32(IMC, 0xFFFFFFFF); e1e_flush(); usleep_range(10000, 20000); /* Unhook test interrupt handler */ free_irq(irq, netdev); out: if (int_mode == E1000E_INT_MODE_MSIX) { e1000e_reset_interrupt_capability(adapter); adapter->int_mode = int_mode; e1000e_set_interrupt_capability(adapter); } return ret_val; }
static int e1000_reg_test(struct e1000_adapter *adapter, u64 *data) { struct e1000_hw *hw = &adapter->hw; struct e1000_mac_info *mac = &adapter->hw.mac; u32 value; u32 before; u32 after; u32 i; u32 toggle; u32 mask; u32 wlock_mac = 0; /* * The status register is Read Only, so a write should fail. * Some bits that get toggled are ignored. */ switch (mac->type) { /* there are several bits on newer hardware that are r/w */ case e1000_82571: case e1000_82572: case e1000_80003es2lan: toggle = 0x7FFFF3FF; break; default: toggle = 0x7FFFF033; break; } before = er32(STATUS); value = (er32(STATUS) & toggle); ew32(STATUS, toggle); after = er32(STATUS) & toggle; if (value != after) { e_err("failed STATUS register test got: 0x%08X expected: 0x%08X\n", after, value); *data = 1; return 1; } /* restore previous status */ ew32(STATUS, before); if (!(adapter->flags & FLAG_IS_ICH)) { REG_PATTERN_TEST(E1000_FCAL, 0xFFFFFFFF, 0xFFFFFFFF); REG_PATTERN_TEST(E1000_FCAH, 0x0000FFFF, 0xFFFFFFFF); REG_PATTERN_TEST(E1000_FCT, 0x0000FFFF, 0xFFFFFFFF); REG_PATTERN_TEST(E1000_VET, 0x0000FFFF, 0xFFFFFFFF); } REG_PATTERN_TEST(E1000_RDTR, 0x0000FFFF, 0xFFFFFFFF); REG_PATTERN_TEST(E1000_RDBAH(0), 0xFFFFFFFF, 0xFFFFFFFF); REG_PATTERN_TEST(E1000_RDLEN(0), 0x000FFF80, 0x000FFFFF); REG_PATTERN_TEST(E1000_RDH(0), 0x0000FFFF, 0x0000FFFF); REG_PATTERN_TEST(E1000_RDT(0), 0x0000FFFF, 0x0000FFFF); REG_PATTERN_TEST(E1000_FCRTH, 0x0000FFF8, 0x0000FFF8); REG_PATTERN_TEST(E1000_FCTTV, 0x0000FFFF, 0x0000FFFF); REG_PATTERN_TEST(E1000_TIPG, 0x3FFFFFFF, 0x3FFFFFFF); REG_PATTERN_TEST(E1000_TDBAH(0), 0xFFFFFFFF, 0xFFFFFFFF); REG_PATTERN_TEST(E1000_TDLEN(0), 0x000FFF80, 0x000FFFFF); REG_SET_AND_CHECK(E1000_RCTL, 0xFFFFFFFF, 0x00000000); before = ((adapter->flags & FLAG_IS_ICH) ? 0x06C3B33E : 0x06DFB3FE); REG_SET_AND_CHECK(E1000_RCTL, before, 0x003FFFFB); REG_SET_AND_CHECK(E1000_TCTL, 0xFFFFFFFF, 0x00000000); REG_SET_AND_CHECK(E1000_RCTL, before, 0xFFFFFFFF); REG_PATTERN_TEST(E1000_RDBAL(0), 0xFFFFFFF0, 0xFFFFFFFF); if (!(adapter->flags & FLAG_IS_ICH)) REG_PATTERN_TEST(E1000_TXCW, 0xC000FFFF, 0x0000FFFF); REG_PATTERN_TEST(E1000_TDBAL(0), 0xFFFFFFF0, 0xFFFFFFFF); REG_PATTERN_TEST(E1000_TIDV, 0x0000FFFF, 0x0000FFFF); mask = 0x8003FFFF; switch (mac->type) { case e1000_ich10lan: case e1000_pchlan: case e1000_pch2lan: case e1000_pch_lpt: mask |= (1 << 18); break; default: break; } if (mac->type == e1000_pch_lpt) wlock_mac = (er32(FWSM) & E1000_FWSM_WLOCK_MAC_MASK) >> E1000_FWSM_WLOCK_MAC_SHIFT; for (i = 0; i < mac->rar_entry_count; i++) { /* Cannot test write-protected SHRAL[n] registers */ if ((wlock_mac == 1) || (wlock_mac && (i > wlock_mac))) continue; REG_PATTERN_TEST_ARRAY(E1000_RA, ((i << 1) + 1), mask, 0xFFFFFFFF); } for (i = 0; i < mac->mta_reg_count; i++) REG_PATTERN_TEST_ARRAY(E1000_MTA, i, 0xFFFFFFFF, 0xFFFFFFFF); *data = 0; return 0; }
/** * e1000_configure_tx - Configure 8254x Transmit Unit after Reset * @adapter: board private structure * * Configure the Tx unit of the MAC after a reset. **/ static void e1000e_configure_tx ( struct e1000_adapter *adapter ) { struct e1000_hw *hw = &adapter->hw; u32 tctl, tipg, tarc; u32 ipgr1, ipgr2; DBGP ( "e1000_configure_tx\n" ); /* disable transmits while setting up the descriptors */ tctl = E1000_READ_REG ( hw, E1000_TCTL ); E1000_WRITE_REG ( hw, E1000_TCTL, tctl & ~E1000_TCTL_EN ); e1e_flush(); mdelay(10); E1000_WRITE_REG ( hw, E1000_TDBAH(0), 0 ); E1000_WRITE_REG ( hw, E1000_TDBAL(0), virt_to_bus ( adapter->tx_base ) ); E1000_WRITE_REG ( hw, E1000_TDLEN(0), adapter->tx_ring_size ); DBG ( "E1000_TDBAL(0): %#08x\n", E1000_READ_REG ( hw, E1000_TDBAL(0) ) ); DBG ( "E1000_TDLEN(0): %d\n", E1000_READ_REG ( hw, E1000_TDLEN(0) ) ); /* Setup the HW Tx Head and Tail descriptor pointers */ E1000_WRITE_REG ( hw, E1000_TDH(0), 0 ); E1000_WRITE_REG ( hw, E1000_TDT(0), 0 ); adapter->tx_head = 0; adapter->tx_tail = 0; adapter->tx_fill_ctr = 0; /* Set the default values for the Tx Inter Packet Gap timer */ tipg = DEFAULT_82543_TIPG_IPGT_COPPER; /* 8 */ ipgr1 = DEFAULT_82543_TIPG_IPGR1; /* 8 */ ipgr2 = DEFAULT_82543_TIPG_IPGR2; /* 6 */ if (adapter->flags & FLAG_TIPG_MEDIUM_FOR_80003ESLAN) ipgr2 = DEFAULT_80003ES2LAN_TIPG_IPGR2; /* 7 */ tipg |= ipgr1 << E1000_TIPG_IPGR1_SHIFT; tipg |= ipgr2 << E1000_TIPG_IPGR2_SHIFT; ew32(TIPG, tipg); /* Program the Transmit Control Register */ tctl = er32(TCTL); tctl &= ~E1000_TCTL_CT; tctl |= E1000_TCTL_PSP | E1000_TCTL_RTLC | (E1000_COLLISION_THRESHOLD << E1000_CT_SHIFT); if (adapter->flags & FLAG_TARC_SPEED_MODE_BIT) { tarc = er32(TARC(0)); /* * set the speed mode bit, we'll clear it if we're not at * gigabit link later */ #define SPEED_MODE_BIT (1 << 21) tarc |= SPEED_MODE_BIT; ew32(TARC(0), tarc); } /* errata: program both queues to unweighted RR */ if (adapter->flags & FLAG_TARC_SET_BIT_ZERO) { tarc = er32(TARC(0)); tarc |= 1; ew32(TARC(0), tarc); tarc = er32(TARC(1)); tarc |= 1; ew32(TARC(1), tarc); } /* Setup Transmit Descriptor Settings for eop descriptor */ adapter->txd_cmd = E1000_TXD_CMD_EOP | E1000_TXD_CMD_IFCS; /* enable Report Status bit */ adapter->txd_cmd |= E1000_TXD_CMD_RS; /* * enable transmits in the hardware, need to do this * after setting TARC(0) */ tctl |= E1000_TCTL_EN; ew32(TCTL, tctl); e1e_flush(); e1000e_config_collision_dist(hw); }
static int e1000_integrated_phy_loopback(struct e1000_adapter *adapter) { struct e1000_hw *hw = &adapter->hw; u32 ctrl_reg = 0; u32 stat_reg = 0; u16 phy_reg = 0; hw->mac.autoneg = 0; if (hw->phy.type == e1000_phy_m88) { /* Auto-MDI/MDIX Off */ e1e_wphy(hw, M88E1000_PHY_SPEC_CTRL, 0x0808); /* reset to update Auto-MDI/MDIX */ e1e_wphy(hw, PHY_CONTROL, 0x9140); /* autoneg off */ e1e_wphy(hw, PHY_CONTROL, 0x8140); } else if (hw->phy.type == e1000_phy_gg82563) e1e_wphy(hw, GG82563_PHY_KMRN_MODE_CTRL, 0x1CC); ctrl_reg = er32(CTRL); switch (hw->phy.type) { case e1000_phy_ife: /* force 100, set loopback */ e1e_wphy(hw, PHY_CONTROL, 0x6100); /* Now set up the MAC to the same speed/duplex as the PHY. */ ctrl_reg &= ~E1000_CTRL_SPD_SEL; /* Clear the speed sel bits */ ctrl_reg |= (E1000_CTRL_FRCSPD | /* Set the Force Speed Bit */ E1000_CTRL_FRCDPX | /* Set the Force Duplex Bit */ E1000_CTRL_SPD_100 |/* Force Speed to 100 */ E1000_CTRL_FD); /* Force Duplex to FULL */ break; case e1000_phy_bm: /* Set Default MAC Interface speed to 1GB */ e1e_rphy(hw, PHY_REG(2, 21), &phy_reg); phy_reg &= ~0x0007; phy_reg |= 0x006; e1e_wphy(hw, PHY_REG(2, 21), phy_reg); /* Assert SW reset for above settings to take effect */ e1000e_commit_phy(hw); mdelay(1); /* Force Full Duplex */ e1e_rphy(hw, PHY_REG(769, 16), &phy_reg); e1e_wphy(hw, PHY_REG(769, 16), phy_reg | 0x000C); /* Set Link Up (in force link) */ e1e_rphy(hw, PHY_REG(776, 16), &phy_reg); e1e_wphy(hw, PHY_REG(776, 16), phy_reg | 0x0040); /* Force Link */ e1e_rphy(hw, PHY_REG(769, 16), &phy_reg); e1e_wphy(hw, PHY_REG(769, 16), phy_reg | 0x0040); /* Set Early Link Enable */ e1e_rphy(hw, PHY_REG(769, 20), &phy_reg); e1e_wphy(hw, PHY_REG(769, 20), phy_reg | 0x0400); /* fall through */ default: /* force 1000, set loopback */ e1e_wphy(hw, PHY_CONTROL, 0x4140); mdelay(250); /* Now set up the MAC to the same speed/duplex as the PHY. */ ctrl_reg = er32(CTRL); ctrl_reg &= ~E1000_CTRL_SPD_SEL; /* Clear the speed sel bits */ ctrl_reg |= (E1000_CTRL_FRCSPD | /* Set the Force Speed Bit */ E1000_CTRL_FRCDPX | /* Set the Force Duplex Bit */ E1000_CTRL_SPD_1000 |/* Force Speed to 1000 */ E1000_CTRL_FD); /* Force Duplex to FULL */ if (adapter->flags & FLAG_IS_ICH) ctrl_reg |= E1000_CTRL_SLU; /* Set Link Up */ } if (hw->phy.media_type == e1000_media_type_copper && hw->phy.type == e1000_phy_m88) { ctrl_reg |= E1000_CTRL_ILOS; /* Invert Loss of Signal */ } else { /* * Set the ILOS bit on the fiber Nic if half duplex link is * detected. */ stat_reg = er32(STATUS); if ((stat_reg & E1000_STATUS_FD) == 0) ctrl_reg |= (E1000_CTRL_ILOS | E1000_CTRL_SLU); } ew32(CTRL, ctrl_reg); /* * Disable the receiver on the PHY so when a cable is plugged in, the * PHY does not begin to autoneg when a cable is reconnected to the NIC. */ if (hw->phy.type == e1000_phy_m88) e1000_phy_disable_receiver(adapter); udelay(500); return 0; }