extractedLnx/linux-2.6.38/drivers/net/tg3.c_tg3_reset_hw.c
static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
{
u32 val, rdmac_mode;
int i, err, limit;
struct tg3_rx_prodring_set *tpr = &tp->napi[0].prodring;
tg3_disable_ints(tp);
tg3_stop_fw(tp);
tg3_write_sig_pre_reset(tp, RESET_KIND_INIT);
if (tp->tg3_flags & TG3_FLAG_INIT_COMPLETE)
tg3_abort_hw(tp, 1);
/* Enable MAC control of LPI */
if (tp->phy_flags & TG3_PHYFLG_EEE_CAP) {
tw32_f(TG3_CPMU_EEE_LNKIDL_CTRL,
TG3_CPMU_EEE_LNKIDL_PCIE_NL0 |
TG3_CPMU_EEE_LNKIDL_UART_IDL);
tw32_f(TG3_CPMU_EEE_CTRL,
TG3_CPMU_EEE_CTRL_EXIT_20_1_US);
val = TG3_CPMU_EEEMD_ERLY_L1_XIT_DET |
TG3_CPMU_EEEMD_LPI_IN_TX |
TG3_CPMU_EEEMD_LPI_IN_RX |
TG3_CPMU_EEEMD_EEE_ENABLE;
if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5717)
val |= TG3_CPMU_EEEMD_SND_IDX_DET_EN;
if (tp->tg3_flags3 & TG3_FLG3_ENABLE_APE)
val |= TG3_CPMU_EEEMD_APE_TX_DET_EN;
tw32_f(TG3_CPMU_EEE_MODE, val);
tw32_f(TG3_CPMU_EEE_DBTMR1,
TG3_CPMU_DBTMR1_PCIEXIT_2047US |
TG3_CPMU_DBTMR1_LNKIDLE_2047US);
tw32_f(TG3_CPMU_EEE_DBTMR2,
TG3_CPMU_DBTMR1_APE_TX_2047US |
TG3_CPMU_DBTMR2_TXIDXEQ_2047US);
}
if (reset_phy)
tg3_phy_reset(tp);
err = tg3_chip_reset(tp);
if (err)
return err;
tg3_write_sig_legacy(tp, RESET_KIND_INIT);
if (GET_CHIP_REV(tp->pci_chip_rev_id) == CHIPREV_5784_AX) {
val = tr32(TG3_CPMU_CTRL);
val &= ~(CPMU_CTRL_LINK_AWARE_MODE | CPMU_CTRL_LINK_IDLE_MODE);
tw32(TG3_CPMU_CTRL, val);
val = tr32(TG3_CPMU_LSPD_10MB_CLK);
val &= ~CPMU_LSPD_10MB_MACCLK_MASK;
val |= CPMU_LSPD_10MB_MACCLK_6_25;
tw32(TG3_CPMU_LSPD_10MB_CLK, val);
val = tr32(TG3_CPMU_LNK_AWARE_PWRMD);
val &= ~CPMU_LNK_AWARE_MACCLK_MASK;
val |= CPMU_LNK_AWARE_MACCLK_6_25;
tw32(TG3_CPMU_LNK_AWARE_PWRMD, val);
val = tr32(TG3_CPMU_HST_ACC);
val &= ~CPMU_HST_ACC_MACCLK_MASK;
val |= CPMU_HST_ACC_MACCLK_6_25;
tw32(TG3_CPMU_HST_ACC, val);
}
if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57780) {
val = tr32(PCIE_PWR_MGMT_THRESH) & ~PCIE_PWR_MGMT_L1_THRESH_MSK;
val |= PCIE_PWR_MGMT_EXT_ASPM_TMR_EN |
PCIE_PWR_MGMT_L1_THRESH_4MS;
tw32(PCIE_PWR_MGMT_THRESH, val);
val = tr32(TG3_PCIE_EIDLE_DELAY) & ~TG3_PCIE_EIDLE_DELAY_MASK;
tw32(TG3_PCIE_EIDLE_DELAY, val | TG3_PCIE_EIDLE_DELAY_13_CLKS);
tw32(TG3_CORR_ERR_STAT, TG3_CORR_ERR_STAT_CLEAR);
val = tr32(TG3_PCIE_LNKCTL) & ~TG3_PCIE_LNKCTL_L1_PLL_PD_EN;
tw32(TG3_PCIE_LNKCTL, val | TG3_PCIE_LNKCTL_L1_PLL_PD_DIS);
}
if (tp->tg3_flags3 & TG3_FLG3_L1PLLPD_EN) {
u32 grc_mode = tr32(GRC_MODE);
/* Access the lower 1K of PL PCIE block registers. */
val = grc_mode & ~GRC_MODE_PCIE_PORT_MASK;
tw32(GRC_MODE, val | GRC_MODE_PCIE_PL_SEL);
val = tr32(TG3_PCIE_TLDLPL_PORT + TG3_PCIE_PL_LO_PHYCTL1);
tw32(TG3_PCIE_TLDLPL_PORT + TG3_PCIE_PL_LO_PHYCTL1,
val | TG3_PCIE_PL_LO_PHYCTL1_L1PLLPD_EN);
tw32(GRC_MODE, grc_mode);
}
if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57765) {
if (tp->pci_chip_rev_id == CHIPREV_ID_57765_A0) {
u32 grc_mode = tr32(GRC_MODE);
/* Access the lower 1K of PL PCIE block registers. */
val = grc_mode & ~GRC_MODE_PCIE_PORT_MASK;
tw32(GRC_MODE, val | GRC_MODE_PCIE_PL_SEL);
val = tr32(TG3_PCIE_TLDLPL_PORT +
TG3_PCIE_PL_LO_PHYCTL5);
tw32(TG3_PCIE_TLDLPL_PORT + TG3_PCIE_PL_LO_PHYCTL5,
val | TG3_PCIE_PL_LO_PHYCTL5_DIS_L2CLKREQ);
tw32(GRC_MODE, grc_mode);
}
val = tr32(TG3_CPMU_LSPD_10MB_CLK);
val &= ~CPMU_LSPD_10MB_MACCLK_MASK;
val |= CPMU_LSPD_10MB_MACCLK_6_25;
tw32(TG3_CPMU_LSPD_10MB_CLK, val);
}
/* This works around an issue with Athlon chipsets on
* B3 tigon3 silicon. This bit has no effect on any
* other revision. But do not set this on PCI Express
* chips and don't even touch the clocks if the CPMU is present.
*/
if (!(tp->tg3_flags & TG3_FLAG_CPMU_PRESENT)) {
if (!(tp->tg3_flags2 & TG3_FLG2_PCI_EXPRESS))
tp->pci_clock_ctrl |= CLOCK_CTRL_DELAY_PCI_GRANT;
tw32_f(TG3PCI_CLOCK_CTRL, tp->pci_clock_ctrl);
}
if (tp->pci_chip_rev_id == CHIPREV_ID_5704_A0 &&
(tp->tg3_flags & TG3_FLAG_PCIX_MODE)) {
val = tr32(TG3PCI_PCISTATE);
val |= PCISTATE_RETRY_SAME_DMA;
tw32(TG3PCI_PCISTATE, val);
}
if (tp->tg3_flags3 & TG3_FLG3_ENABLE_APE) {
/* Allow reads and writes to the
* APE register and memory space.
*/
val = tr32(TG3PCI_PCISTATE);
val |= PCISTATE_ALLOW_APE_CTLSPC_WR |
PCISTATE_ALLOW_APE_SHMEM_WR |
PCISTATE_ALLOW_APE_PSPACE_WR;
tw32(TG3PCI_PCISTATE, val);
}
if (GET_CHIP_REV(tp->pci_chip_rev_id) == CHIPREV_5704_BX) {
/* Enable some hw fixes. */
val = tr32(TG3PCI_MSI_DATA);
val |= (1 << 26) | (1 << 28) | (1 << 29);
tw32(TG3PCI_MSI_DATA, val);
}
/* Descriptor ring init may make accesses to the
* NIC SRAM area to setup the TX descriptors, so we
* can only do this after the hardware has been
* successfully reset.
*/
err = tg3_init_rings(tp);
if (err)
return err;
if (tp->tg3_flags3 & TG3_FLG3_5717_PLUS) {
val = tr32(TG3PCI_DMA_RW_CTRL) &
~DMA_RWCTRL_DIS_CACHE_ALIGNMENT;
if (tp->pci_chip_rev_id == CHIPREV_ID_57765_A0)
val &= ~DMA_RWCTRL_CRDRDR_RDMA_MRRS_MSK;
tw32(TG3PCI_DMA_RW_CTRL, val | tp->dma_rwctrl);
} else if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5784 &&
GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5761) {
/* This value is determined during the probe time DMA
* engine test, tg3_test_dma.
*/
tw32(TG3PCI_DMA_RW_CTRL, tp->dma_rwctrl);
}
tp->grc_mode &= ~(GRC_MODE_HOST_SENDBDS |
GRC_MODE_4X_NIC_SEND_RINGS |
GRC_MODE_NO_TX_PHDR_CSUM |
GRC_MODE_NO_RX_PHDR_CSUM);
tp->grc_mode |= GRC_MODE_HOST_SENDBDS;
/* Pseudo-header checksum is done by hardware logic and not
* the offload processers, so make the chip do the pseudo-
* header checksums on receive. For transmit it is more
* convenient to do the pseudo-header checksum in software
* as Linux does that on transmit for us in all cases.
*/
tp->grc_mode |= GRC_MODE_NO_TX_PHDR_CSUM;
tw32(GRC_MODE,
tp->grc_mode |
(GRC_MODE_IRQ_ON_MAC_ATTN | GRC_MODE_HOST_STACKUP));
/* Setup the timer prescalar register. Clock is always 66Mhz. */
val = tr32(GRC_MISC_CFG);
val &= ~0xff;
val |= (65 << GRC_MISC_CFG_PRESCALAR_SHIFT);
tw32(GRC_MISC_CFG, val);
/* Initialize MBUF/DESC pool. */
if (tp->tg3_flags2 & TG3_FLG2_5750_PLUS) {
/* Do nothing. */
} else if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5705) {
tw32(BUFMGR_MB_POOL_ADDR, NIC_SRAM_MBUF_POOL_BASE);
if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704)
tw32(BUFMGR_MB_POOL_SIZE, NIC_SRAM_MBUF_POOL_SIZE64);
else
tw32(BUFMGR_MB_POOL_SIZE, NIC_SRAM_MBUF_POOL_SIZE96);
tw32(BUFMGR_DMA_DESC_POOL_ADDR, NIC_SRAM_DMA_DESC_POOL_BASE);
tw32(BUFMGR_DMA_DESC_POOL_SIZE, NIC_SRAM_DMA_DESC_POOL_SIZE);
} else if (tp->tg3_flags2 & TG3_FLG2_TSO_CAPABLE) {
int fw_len;
fw_len = tp->fw_len;
fw_len = (fw_len + (0x80 - 1)) & ~(0x80 - 1);
tw32(BUFMGR_MB_POOL_ADDR,
NIC_SRAM_MBUF_POOL_BASE5705 + fw_len);
tw32(BUFMGR_MB_POOL_SIZE,
NIC_SRAM_MBUF_POOL_SIZE5705 - fw_len - 0xa00);
}
if (tp->dev->mtu <= ETH_DATA_LEN) {
tw32(BUFMGR_MB_RDMA_LOW_WATER,
tp->bufmgr_config.mbuf_read_dma_low_water);
tw32(BUFMGR_MB_MACRX_LOW_WATER,
tp->bufmgr_config.mbuf_mac_rx_low_water);
tw32(BUFMGR_MB_HIGH_WATER,
tp->bufmgr_config.mbuf_high_water);
} else {
tw32(BUFMGR_MB_RDMA_LOW_WATER,
tp->bufmgr_config.mbuf_read_dma_low_water_jumbo);
tw32(BUFMGR_MB_MACRX_LOW_WATER,
tp->bufmgr_config.mbuf_mac_rx_low_water_jumbo);
tw32(BUFMGR_MB_HIGH_WATER,
tp->bufmgr_config.mbuf_high_water_jumbo);
}
tw32(BUFMGR_DMA_LOW_WATER,
tp->bufmgr_config.dma_low_water);
tw32(BUFMGR_DMA_HIGH_WATER,
tp->bufmgr_config.dma_high_water);
val = BUFMGR_MODE_ENABLE | BUFMGR_MODE_ATTN_ENABLE;
if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719)
val |= BUFMGR_MODE_NO_TX_UNDERRUN;
tw32(BUFMGR_MODE, val);
for (i = 0; i < 2000; i++) {
if (tr32(BUFMGR_MODE) & BUFMGR_MODE_ENABLE)
break;
udelay(10);
}
if (i >= 2000) {
netdev_err(tp->dev, "%s cannot enable BUFMGR\n", __func__);
return -ENODEV;
}
/* Setup replenish threshold. */
val = tp->rx_pending / 8;
if (val == 0)
val = 1;
else if (val > tp->rx_std_max_post)
val = tp->rx_std_max_post;
else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906) {
if (tp->pci_chip_rev_id == CHIPREV_ID_5906_A1)
tw32(ISO_PKT_TX, (tr32(ISO_PKT_TX) & ~0x3) | 0x2);
if (val > (TG3_RX_INTERNAL_RING_SZ_5906 / 2))
val = TG3_RX_INTERNAL_RING_SZ_5906 / 2;
}
tw32(RCVBDI_STD_THRESH, val);
/* Initialize TG3_BDINFO's at:
* RCVDBDI_STD_BD: standard eth size rx ring
* RCVDBDI_JUMBO_BD: jumbo frame rx ring
* RCVDBDI_MINI_BD: small frame rx ring (??? does not work)
*
* like so:
* TG3_BDINFO_HOST_ADDR: high/low parts of DMA address of ring
* TG3_BDINFO_MAXLEN_FLAGS: (rx max buffer size << 16) |
* ring attribute flags
* TG3_BDINFO_NIC_ADDR: location of descriptors in nic SRAM
*
* Standard receive ring @ NIC_SRAM_RX_BUFFER_DESC, 512 entries.
* Jumbo receive ring @ NIC_SRAM_RX_JUMBO_BUFFER_DESC, 256 entries.
*
* The size of each ring is fixed in the firmware, but the location is
* configurable.
*/
tw32(RCVDBDI_STD_BD + TG3_BDINFO_HOST_ADDR + TG3_64BIT_REG_HIGH,
((u64) tpr->rx_std_mapping >> 32));
tw32(RCVDBDI_STD_BD + TG3_BDINFO_HOST_ADDR + TG3_64BIT_REG_LOW,
((u64) tpr->rx_std_mapping & 0xffffffff));
if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5717 &&
GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5719)
tw32(RCVDBDI_STD_BD + TG3_BDINFO_NIC_ADDR,
NIC_SRAM_RX_BUFFER_DESC);
/* Disable the mini ring */
if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS))
tw32(RCVDBDI_MINI_BD + TG3_BDINFO_MAXLEN_FLAGS,
BDINFO_FLAGS_DISABLED);
/* Program the jumbo buffer descriptor ring control
* blocks on those devices that have them.
*/
if ((tp->tg3_flags & TG3_FLAG_JUMBO_CAPABLE) &&
!(tp->tg3_flags2 & TG3_FLG2_5780_CLASS)) {
/* Setup replenish threshold. */
tw32(RCVBDI_JUMBO_THRESH, tp->rx_jumbo_pending / 8);
if (tp->tg3_flags & TG3_FLAG_JUMBO_RING_ENABLE) {
tw32(RCVDBDI_JUMBO_BD + TG3_BDINFO_HOST_ADDR + TG3_64BIT_REG_HIGH,
((u64) tpr->rx_jmb_mapping >> 32));
tw32(RCVDBDI_JUMBO_BD + TG3_BDINFO_HOST_ADDR + TG3_64BIT_REG_LOW,
((u64) tpr->rx_jmb_mapping & 0xffffffff));
tw32(RCVDBDI_JUMBO_BD + TG3_BDINFO_MAXLEN_FLAGS,
(RX_JUMBO_MAX_SIZE << BDINFO_FLAGS_MAXLEN_SHIFT) |
BDINFO_FLAGS_USE_EXT_RECV);
if (!(tp->tg3_flags3 & TG3_FLG3_USE_JUMBO_BDFLAG) ||
GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57765)
tw32(RCVDBDI_JUMBO_BD + TG3_BDINFO_NIC_ADDR,
NIC_SRAM_RX_JUMBO_BUFFER_DESC);
} else {
tw32(RCVDBDI_JUMBO_BD + TG3_BDINFO_MAXLEN_FLAGS,
BDINFO_FLAGS_DISABLED);
}
if (tp->tg3_flags3 & TG3_FLG3_5717_PLUS) {
if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57765)
val = RX_STD_MAX_SIZE_5705;
else
val = RX_STD_MAX_SIZE_5717;
val <<= BDINFO_FLAGS_MAXLEN_SHIFT;
val |= (TG3_RX_STD_DMA_SZ << 2);
} else
val = TG3_RX_STD_DMA_SZ << BDINFO_FLAGS_MAXLEN_SHIFT;
} else
val = RX_STD_MAX_SIZE_5705 << BDINFO_FLAGS_MAXLEN_SHIFT;
tw32(RCVDBDI_STD_BD + TG3_BDINFO_MAXLEN_FLAGS, val);
tpr->rx_std_prod_idx = tp->rx_pending;
tw32_rx_mbox(TG3_RX_STD_PROD_IDX_REG, tpr->rx_std_prod_idx);
tpr->rx_jmb_prod_idx = (tp->tg3_flags & TG3_FLAG_JUMBO_RING_ENABLE) ?
tp->rx_jumbo_pending : 0;
tw32_rx_mbox(TG3_RX_JMB_PROD_IDX_REG, tpr->rx_jmb_prod_idx);
if (tp->tg3_flags3 & TG3_FLG3_5717_PLUS) {
tw32(STD_REPLENISH_LWM, 32);
tw32(JMB_REPLENISH_LWM, 16);
}
tg3_rings_reset(tp);
/* Initialize MAC address and backoff seed. */
__tg3_set_mac_addr(tp, 0);
/* MTU + ethernet header + FCS + optional VLAN tag */
tw32(MAC_RX_MTU_SIZE,
tp->dev->mtu + ETH_HLEN + ETH_FCS_LEN + VLAN_HLEN);
/* The slot time is changed by tg3_setup_phy if we
* run at gigabit with half duplex.
*/
tw32(MAC_TX_LENGTHS,
(2 << TX_LENGTHS_IPG_CRS_SHIFT) |
(6 << TX_LENGTHS_IPG_SHIFT) |
(32 << TX_LENGTHS_SLOT_TIME_SHIFT));
/* Receive rules. */
tw32(MAC_RCV_RULE_CFG, RCV_RULE_CFG_DEFAULT_CLASS);
tw32(RCVLPC_CONFIG, 0x0181);
/* Calculate RDMAC_MODE setting early, we need it to determine
* the RCVLPC_STATE_ENABLE mask.
*/
rdmac_mode = (RDMAC_MODE_ENABLE | RDMAC_MODE_TGTABORT_ENAB |
RDMAC_MODE_MSTABORT_ENAB | RDMAC_MODE_PARITYERR_ENAB |
RDMAC_MODE_ADDROFLOW_ENAB | RDMAC_MODE_FIFOOFLOW_ENAB |
RDMAC_MODE_FIFOURUN_ENAB | RDMAC_MODE_FIFOOREAD_ENAB |
RDMAC_MODE_LNGREAD_ENAB);
if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717)
rdmac_mode |= RDMAC_MODE_MULT_DMA_RD_DIS;
if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5784 ||
GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5785 ||
GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57780)
rdmac_mode |= RDMAC_MODE_BD_SBD_CRPT_ENAB |
RDMAC_MODE_MBUF_RBD_CRPT_ENAB |
RDMAC_MODE_MBUF_SBD_CRPT_ENAB;
/* If statement applies to 5705 and 5750 PCI devices only */
if ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705 &&
tp->pci_chip_rev_id != CHIPREV_ID_5705_A0) ||
(GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5750)) {
if (tp->tg3_flags2 & TG3_FLG2_TSO_CAPABLE &&
GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705) {
rdmac_mode |= RDMAC_MODE_FIFO_SIZE_128;
} else if (!(tr32(TG3PCI_PCISTATE) & PCISTATE_BUS_SPEED_HIGH) &&
!(tp->tg3_flags2 & TG3_FLG2_IS_5788)) {
rdmac_mode |= RDMAC_MODE_FIFO_LONG_BURST;
}
}
if (tp->tg3_flags2 & TG3_FLG2_PCI_EXPRESS)
rdmac_mode |= RDMAC_MODE_FIFO_LONG_BURST;
if (tp->tg3_flags2 & TG3_FLG2_HW_TSO)
rdmac_mode |= RDMAC_MODE_IPV4_LSO_EN;
if ((tp->tg3_flags2 & TG3_FLG2_HW_TSO_3) ||
GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5785 ||
GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57780)
rdmac_mode |= RDMAC_MODE_IPV6_LSO_EN;
if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5761 ||
GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5784 ||
GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5785 ||
GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57780 ||
(tp->tg3_flags3 & TG3_FLG3_5717_PLUS)) {
val = tr32(TG3_RDMA_RSRVCTRL_REG);
if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719) {
val &= ~TG3_RDMA_RSRVCTRL_TXMRGN_MASK;
val |= TG3_RDMA_RSRVCTRL_TXMRGN_320B;
}
tw32(TG3_RDMA_RSRVCTRL_REG,
val | TG3_RDMA_RSRVCTRL_FIFO_OFLW_FIX);
}
if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719) {
val = tr32(TG3_LSO_RD_DMA_CRPTEN_CTRL);
tw32(TG3_LSO_RD_DMA_CRPTEN_CTRL, val |
TG3_LSO_RD_DMA_CRPTEN_CTRL_BLEN_BD_4K |
TG3_LSO_RD_DMA_CRPTEN_CTRL_BLEN_LSO_4K);
}
/* Receive/send statistics. */
if (tp->tg3_flags2 & TG3_FLG2_5750_PLUS) {
val = tr32(RCVLPC_STATS_ENABLE);
val &= ~RCVLPC_STATSENAB_DACK_FIX;
tw32(RCVLPC_STATS_ENABLE, val);
} else if ((rdmac_mode & RDMAC_MODE_FIFO_SIZE_128) &&
(tp->tg3_flags2 & TG3_FLG2_TSO_CAPABLE)) {
val = tr32(RCVLPC_STATS_ENABLE);
val &= ~RCVLPC_STATSENAB_LNGBRST_RFIX;
tw32(RCVLPC_STATS_ENABLE, val);
} else {
tw32(RCVLPC_STATS_ENABLE, 0xffffff);
}
tw32(RCVLPC_STATSCTRL, RCVLPC_STATSCTRL_ENABLE);
tw32(SNDDATAI_STATSENAB, 0xffffff);
tw32(SNDDATAI_STATSCTRL,
(SNDDATAI_SCTRL_ENABLE |
SNDDATAI_SCTRL_FASTUPD));
/* Setup host coalescing engine. */
tw32(HOSTCC_MODE, 0);
for (i = 0; i < 2000; i++) {
if (!(tr32(HOSTCC_MODE) & HOSTCC_MODE_ENABLE))
break;
udelay(10);
}
__tg3_set_coalesce(tp, &tp->coal);
if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS)) {
/* Status/statistics block address. See tg3_timer,
* the tg3_periodic_fetch_stats call there, and
* tg3_get_stats to see how this works for 5705/5750 chips.
*/
tw32(HOSTCC_STATS_BLK_HOST_ADDR + TG3_64BIT_REG_HIGH,
((u64) tp->stats_mapping >> 32));
tw32(HOSTCC_STATS_BLK_HOST_ADDR + TG3_64BIT_REG_LOW,
((u64) tp->stats_mapping & 0xffffffff));
tw32(HOSTCC_STATS_BLK_NIC_ADDR, NIC_SRAM_STATS_BLK);
tw32(HOSTCC_STATUS_BLK_NIC_ADDR, NIC_SRAM_STATUS_BLK);
/* Clear statistics and status block memory areas */
for (i = NIC_SRAM_STATS_BLK;
i < NIC_SRAM_STATUS_BLK + TG3_HW_STATUS_SIZE;
i += sizeof(u32)) {
tg3_write_mem(tp, i, 0);
udelay(40);
}
}
tw32(HOSTCC_MODE, HOSTCC_MODE_ENABLE | tp->coalesce_mode);
tw32(RCVCC_MODE, RCVCC_MODE_ENABLE | RCVCC_MODE_ATTN_ENABLE);
tw32(RCVLPC_MODE, RCVLPC_MODE_ENABLE);
if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS))
tw32(RCVLSC_MODE, RCVLSC_MODE_ENABLE | RCVLSC_MODE_ATTN_ENABLE);
if (tp->phy_flags & TG3_PHYFLG_MII_SERDES) {
tp->phy_flags &= ~TG3_PHYFLG_PARALLEL_DETECT;
/* reset to prevent losing 1st rx packet intermittently */
tw32_f(MAC_RX_MODE, RX_MODE_RESET);
udelay(10);
}
if (tp->tg3_flags3 & TG3_FLG3_ENABLE_APE)
tp->mac_mode = MAC_MODE_APE_TX_EN | MAC_MODE_APE_RX_EN;
else
tp->mac_mode = 0;
tp->mac_mode |= MAC_MODE_TXSTAT_ENABLE | MAC_MODE_RXSTAT_ENABLE |
MAC_MODE_TDE_ENABLE | MAC_MODE_RDE_ENABLE | MAC_MODE_FHDE_ENABLE;
if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS) &&
!(tp->phy_flags & TG3_PHYFLG_PHY_SERDES) &&
GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5700)
tp->mac_mode |= MAC_MODE_LINK_POLARITY;
tw32_f(MAC_MODE, tp->mac_mode | MAC_MODE_RXSTAT_CLEAR | MAC_MODE_TXSTAT_CLEAR);
udelay(40);
/* tp->grc_local_ctrl is partially set up during tg3_get_invariants().
* If TG3_FLG2_IS_NIC is zero, we should read the
* register to preserve the GPIO settings for LOMs. The GPIOs,
* whether used as inputs or outputs, are set by boot code after
* reset.
*/
if (!(tp->tg3_flags2 & TG3_FLG2_IS_NIC)) {
u32 gpio_mask;
gpio_mask = GRC_LCLCTRL_GPIO_OE0 | GRC_LCLCTRL_GPIO_OE1 |
GRC_LCLCTRL_GPIO_OE2 | GRC_LCLCTRL_GPIO_OUTPUT0 |
GRC_LCLCTRL_GPIO_OUTPUT1 | GRC_LCLCTRL_GPIO_OUTPUT2;
if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5752)
gpio_mask |= GRC_LCLCTRL_GPIO_OE3 |
GRC_LCLCTRL_GPIO_OUTPUT3;
if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5755)
gpio_mask |= GRC_LCLCTRL_GPIO_UART_SEL;
tp->grc_local_ctrl &= ~gpio_mask;
tp->grc_local_ctrl |= tr32(GRC_LOCAL_CTRL) & gpio_mask;
/* GPIO1 must be driven high for eeprom write protect */
if (tp->tg3_flags & TG3_FLAG_EEPROM_WRITE_PROT)
tp->grc_local_ctrl |= (GRC_LCLCTRL_GPIO_OE1 |
GRC_LCLCTRL_GPIO_OUTPUT1);
}
tw32_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl);
udelay(100);
if (tp->tg3_flags2 & TG3_FLG2_USING_MSIX) {
val = tr32(MSGINT_MODE);
val |= MSGINT_MODE_MULTIVEC_EN | MSGINT_MODE_ENABLE;
tw32(MSGINT_MODE, val);
}
if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS)) {
tw32_f(DMAC_MODE, DMAC_MODE_ENABLE);
udelay(40);
}
val = (WDMAC_MODE_ENABLE | WDMAC_MODE_TGTABORT_ENAB |
WDMAC_MODE_MSTABORT_ENAB | WDMAC_MODE_PARITYERR_ENAB |
WDMAC_MODE_ADDROFLOW_ENAB | WDMAC_MODE_FIFOOFLOW_ENAB |
WDMAC_MODE_FIFOURUN_ENAB | WDMAC_MODE_FIFOOREAD_ENAB |
WDMAC_MODE_LNGREAD_ENAB);
/* If statement applies to 5705 and 5750 PCI devices only */
if ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705 &&
tp->pci_chip_rev_id != CHIPREV_ID_5705_A0) ||
GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5750) {
if ((tp->tg3_flags2 & TG3_FLG2_TSO_CAPABLE) &&
(tp->pci_chip_rev_id == CHIPREV_ID_5705_A1 ||
tp->pci_chip_rev_id == CHIPREV_ID_5705_A2)) {
/* nothing */
} else if (!(tr32(TG3PCI_PCISTATE) & PCISTATE_BUS_SPEED_HIGH) &&
!(tp->tg3_flags2 & TG3_FLG2_IS_5788) &&
!(tp->tg3_flags2 & TG3_FLG2_PCI_EXPRESS)) {
val |= WDMAC_MODE_RX_ACCEL;
}
}
/* Enable host coalescing bug fix */
if (tp->tg3_flags3 & TG3_FLG3_5755_PLUS)
val |= WDMAC_MODE_STATUS_TAG_FIX;
if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5785)
val |= WDMAC_MODE_BURST_ALL_DATA;
tw32_f(WDMAC_MODE, val);
udelay(40);
if (tp->tg3_flags & TG3_FLAG_PCIX_MODE) {
u16 pcix_cmd;
pci_read_config_word(tp->pdev, tp->pcix_cap + PCI_X_CMD,
&pcix_cmd);
if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5703) {
pcix_cmd &= ~PCI_X_CMD_MAX_READ;
pcix_cmd |= PCI_X_CMD_READ_2K;
} else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704) {
pcix_cmd &= ~(PCI_X_CMD_MAX_SPLIT | PCI_X_CMD_MAX_READ);
pcix_cmd |= PCI_X_CMD_READ_2K;
}
pci_write_config_word(tp->pdev, tp->pcix_cap + PCI_X_CMD,
pcix_cmd);
}
tw32_f(RDMAC_MODE, rdmac_mode);
udelay(40);
tw32(RCVDCC_MODE, RCVDCC_MODE_ENABLE | RCVDCC_MODE_ATTN_ENABLE);
if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS))
tw32(MBFREE_MODE, MBFREE_MODE_ENABLE);
if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5761)
tw32(SNDDATAC_MODE,
SNDDATAC_MODE_ENABLE | SNDDATAC_MODE_CDELAY);
else
tw32(SNDDATAC_MODE, SNDDATAC_MODE_ENABLE);
tw32(SNDBDC_MODE, SNDBDC_MODE_ENABLE | SNDBDC_MODE_ATTN_ENABLE);
tw32(RCVBDI_MODE, RCVBDI_MODE_ENABLE | RCVBDI_MODE_RCB_ATTN_ENAB);
val = RCVDBDI_MODE_ENABLE | RCVDBDI_MODE_INV_RING_SZ;
if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 ||
GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719)
val |= RCVDBDI_MODE_LRG_RING_SZ;
tw32(RCVDBDI_MODE, val);
tw32(SNDDATAI_MODE, SNDDATAI_MODE_ENABLE);
if (tp->tg3_flags2 & TG3_FLG2_HW_TSO)
tw32(SNDDATAI_MODE, SNDDATAI_MODE_ENABLE | 0x8);
val = SNDBDI_MODE_ENABLE | SNDBDI_MODE_ATTN_ENABLE;
if (tp->tg3_flags3 & TG3_FLG3_ENABLE_TSS)
val |= SNDBDI_MODE_MULTI_TXQ_EN;
tw32(SNDBDI_MODE, val);
tw32(SNDBDS_MODE, SNDBDS_MODE_ENABLE | SNDBDS_MODE_ATTN_ENABLE);
if (tp->pci_chip_rev_id == CHIPREV_ID_5701_A0) {
err = tg3_load_5701_a0_firmware_fix(tp);
if (err)
return err;
}
if (tp->tg3_flags2 & TG3_FLG2_TSO_CAPABLE) {
err = tg3_load_tso_firmware(tp);
if (err)
return err;
}
tp->tx_mode = TX_MODE_ENABLE;
if ((tp->tg3_flags3 & TG3_FLG3_5755_PLUS) ||
GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906)
tp->tx_mode |= TX_MODE_MBUF_LOCKUP_FIX;
tw32_f(MAC_TX_MODE, tp->tx_mode);
udelay(100);
if (tp->tg3_flags3 & TG3_FLG3_ENABLE_RSS) {
u32 reg = MAC_RSS_INDIR_TBL_0;
u8 *ent = (u8 *)&val;
/* Setup the indirection table */
for (i = 0; i < TG3_RSS_INDIR_TBL_SIZE; i++) {
int idx = i % sizeof(val);
ent[idx] = i % (tp->irq_cnt - 1);
if (idx == sizeof(val) - 1) {
tw32(reg, val);
reg += 4;
}
}
/* Setup the "secret" hash key. */
tw32(MAC_RSS_HASH_KEY_0, 0x5f865437);
tw32(MAC_RSS_HASH_KEY_1, 0xe4ac62cc);
tw32(MAC_RSS_HASH_KEY_2, 0x50103a45);
tw32(MAC_RSS_HASH_KEY_3, 0x36621985);
tw32(MAC_RSS_HASH_KEY_4, 0xbf14c0e8);
tw32(MAC_RSS_HASH_KEY_5, 0x1bc27a1e);
tw32(MAC_RSS_HASH_KEY_6, 0x84f4b556);
tw32(MAC_RSS_HASH_KEY_7, 0x094ea6fe);
tw32(MAC_RSS_HASH_KEY_8, 0x7dda01e7);
tw32(MAC_RSS_HASH_KEY_9, 0xc04d7481);
}
tp->rx_mode = RX_MODE_ENABLE;
if (tp->tg3_flags3 & TG3_FLG3_5755_PLUS)
tp->rx_mode |= RX_MODE_IPV6_CSUM_ENABLE;
if (tp->tg3_flags3 & TG3_FLG3_ENABLE_RSS)
tp->rx_mode |= RX_MODE_RSS_ENABLE |
RX_MODE_RSS_ITBL_HASH_BITS_7 |
RX_MODE_RSS_IPV6_HASH_EN |
RX_MODE_RSS_TCP_IPV6_HASH_EN |
RX_MODE_RSS_IPV4_HASH_EN |
RX_MODE_RSS_TCP_IPV4_HASH_EN;
tw32_f(MAC_RX_MODE, tp->rx_mode);
udelay(10);
tw32(MAC_LED_CTRL, tp->led_ctrl);
tw32(MAC_MI_STAT, MAC_MI_STAT_LNKSTAT_ATTN_ENAB);
if (tp->phy_flags & TG3_PHYFLG_PHY_SERDES) {
tw32_f(MAC_RX_MODE, RX_MODE_RESET);
udelay(10);
}
tw32_f(MAC_RX_MODE, tp->rx_mode);
udelay(10);
if (tp->phy_flags & TG3_PHYFLG_PHY_SERDES) {
if ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704) &&
!(tp->phy_flags & TG3_PHYFLG_SERDES_PREEMPHASIS)) {
/* Set drive transmission level to 1.2V */
/* only if the signal pre-emphasis bit is not set */
val = tr32(MAC_SERDES_CFG);
val &= 0xfffff000;
val |= 0x880;
tw32(MAC_SERDES_CFG, val);
}
if (tp->pci_chip_rev_id == CHIPREV_ID_5703_A1)
tw32(MAC_SERDES_CFG, 0x616000);
}
/* Prevent chip from dropping frames when flow control
* is enabled.
*/
if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57765)
val = 1;
else
val = 2;
tw32_f(MAC_LOW_WMARK_MAX_RX_FRAME, val);
if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704 &&
(tp->phy_flags & TG3_PHYFLG_PHY_SERDES)) {
/* Use hardware link auto-negotiation */
tp->tg3_flags2 |= TG3_FLG2_HW_AUTONEG;
}
if ((tp->phy_flags & TG3_PHYFLG_MII_SERDES) &&
(GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5714)) {
u32 tmp;
tmp = tr32(SERDES_RX_CTRL);
tw32(SERDES_RX_CTRL, tmp | SERDES_RX_SIG_DETECT);
tp->grc_local_ctrl &= ~GRC_LCLCTRL_USE_EXT_SIG_DETECT;
tp->grc_local_ctrl |= GRC_LCLCTRL_USE_SIG_DETECT;
tw32(GRC_LOCAL_CTRL, tp->grc_local_ctrl);
}
if (!(tp->tg3_flags3 & TG3_FLG3_USE_PHYLIB)) {
if (tp->phy_flags & TG3_PHYFLG_IS_LOW_POWER) {
tp->phy_flags &= ~TG3_PHYFLG_IS_LOW_POWER;
tp->link_config.speed = tp->link_config.orig_speed;
tp->link_config.duplex = tp->link_config.orig_duplex;
tp->link_config.autoneg = tp->link_config.orig_autoneg;
}
err = tg3_setup_phy(tp, 0);
if (err)
return err;
if (!(tp->phy_flags & TG3_PHYFLG_PHY_SERDES) &&
!(tp->phy_flags & TG3_PHYFLG_IS_FET)) {
u32 tmp;
/* Clear CRC stats. */
if (!tg3_readphy(tp, MII_TG3_TEST1, &tmp)) {
tg3_writephy(tp, MII_TG3_TEST1,
tmp | MII_TG3_TEST1_CRC_EN);
tg3_readphy(tp, MII_TG3_RXR_COUNTERS, &tmp);
}
}
}
__tg3_set_rx_mode(tp->dev);
/* Initialize receive rules. */
tw32(MAC_RCV_RULE_0, 0xc2000000 & RCV_RULE_DISABLE_MASK);
tw32(MAC_RCV_VALUE_0, 0xffffffff & RCV_RULE_DISABLE_MASK);
tw32(MAC_RCV_RULE_1, 0x86000004 & RCV_RULE_DISABLE_MASK);
tw32(MAC_RCV_VALUE_1, 0xffffffff & RCV_RULE_DISABLE_MASK);
if ((tp->tg3_flags2 & TG3_FLG2_5705_PLUS) &&
!(tp->tg3_flags2 & TG3_FLG2_5780_CLASS))
limit = 8;
else
limit = 16;
if (tp->tg3_flags & TG3_FLAG_ENABLE_ASF)
limit -= 4;
switch (limit) {
case 16:
tw32(MAC_RCV_RULE_15, 0); tw32(MAC_RCV_VALUE_15, 0);
case 15:
tw32(MAC_RCV_RULE_14, 0); tw32(MAC_RCV_VALUE_14, 0);
case 14:
tw32(MAC_RCV_RULE_13, 0); tw32(MAC_RCV_VALUE_13, 0);
case 13:
tw32(MAC_RCV_RULE_12, 0); tw32(MAC_RCV_VALUE_12, 0);
case 12:
tw32(MAC_RCV_RULE_11, 0); tw32(MAC_RCV_VALUE_11, 0);
case 11:
tw32(MAC_RCV_RULE_10, 0); tw32(MAC_RCV_VALUE_10, 0);
case 10:
tw32(MAC_RCV_RULE_9, 0); tw32(MAC_RCV_VALUE_9, 0);
case 9:
tw32(MAC_RCV_RULE_8, 0); tw32(MAC_RCV_VALUE_8, 0);
case 8:
tw32(MAC_RCV_RULE_7, 0); tw32(MAC_RCV_VALUE_7, 0);
case 7:
tw32(MAC_RCV_RULE_6, 0); tw32(MAC_RCV_VALUE_6, 0);
case 6:
tw32(MAC_RCV_RULE_5, 0); tw32(MAC_RCV_VALUE_5, 0);
case 5:
tw32(MAC_RCV_RULE_4, 0); tw32(MAC_RCV_VALUE_4, 0);
case 4:
/* tw32(MAC_RCV_RULE_3, 0); tw32(MAC_RCV_VALUE_3, 0); */
case 3:
/* tw32(MAC_RCV_RULE_2, 0); tw32(MAC_RCV_VALUE_2, 0); */
case 2:
case 1:
default:
break;
}
if (tp->tg3_flags3 & TG3_FLG3_ENABLE_APE)
/* Write our heartbeat update interval to APE. */
tg3_ape_write32(tp, TG3_APE_HOST_HEARTBEAT_INT_MS,
APE_HOST_HEARTBEAT_INT_DISABLE);
tg3_write_sig_post_reset(tp, RESET_KIND_INIT);
return 0;
}
Generated by GNU enscript 1.6.4.