extractedLnx/linux-2.6.38/drivers/net/tg3.c_tg3_get_invariants.c
static int __devinit tg3_get_invariants(struct tg3 *tp)
{
u32 misc_ctrl_reg;
u32 pci_state_reg, grc_misc_cfg;
u32 val;
u16 pci_cmd;
int err;
/* Force memory write invalidate off. If we leave it on,
* then on 5700_BX chips we have to enable a workaround.
* The workaround is to set the TG3PCI_DMA_RW_CTRL boundary
* to match the cacheline size. The Broadcom driver have this
* workaround but turns MWI off all the times so never uses
* it. This seems to suggest that the workaround is insufficient.
*/
pci_read_config_word(tp->pdev, PCI_COMMAND, &pci_cmd);
pci_cmd &= ~PCI_COMMAND_INVALIDATE;
pci_write_config_word(tp->pdev, PCI_COMMAND, pci_cmd);
/* It is absolutely critical that TG3PCI_MISC_HOST_CTRL
* has the register indirect write enable bit set before
* we try to access any of the MMIO registers. It is also
* critical that the PCI-X hw workaround situation is decided
* before that as well.
*/
pci_read_config_dword(tp->pdev, TG3PCI_MISC_HOST_CTRL,
&misc_ctrl_reg);
tp->pci_chip_rev_id = (misc_ctrl_reg >>
MISC_HOST_CTRL_CHIPREV_SHIFT);
if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_USE_PROD_ID_REG) {
u32 prod_id_asic_rev;
if (tp->pdev->device == TG3PCI_DEVICE_TIGON3_5717 ||
tp->pdev->device == TG3PCI_DEVICE_TIGON3_5718 ||
tp->pdev->device == TG3PCI_DEVICE_TIGON3_5719)
pci_read_config_dword(tp->pdev,
TG3PCI_GEN2_PRODID_ASICREV,
&prod_id_asic_rev);
else if (tp->pdev->device == TG3PCI_DEVICE_TIGON3_57781 ||
tp->pdev->device == TG3PCI_DEVICE_TIGON3_57785 ||
tp->pdev->device == TG3PCI_DEVICE_TIGON3_57761 ||
tp->pdev->device == TG3PCI_DEVICE_TIGON3_57765 ||
tp->pdev->device == TG3PCI_DEVICE_TIGON3_57791 ||
tp->pdev->device == TG3PCI_DEVICE_TIGON3_57795)
pci_read_config_dword(tp->pdev,
TG3PCI_GEN15_PRODID_ASICREV,
&prod_id_asic_rev);
else
pci_read_config_dword(tp->pdev, TG3PCI_PRODID_ASICREV,
&prod_id_asic_rev);
tp->pci_chip_rev_id = prod_id_asic_rev;
}
/* Wrong chip ID in 5752 A0. This code can be removed later
* as A0 is not in production.
*/
if (tp->pci_chip_rev_id == CHIPREV_ID_5752_A0_HW)
tp->pci_chip_rev_id = CHIPREV_ID_5752_A0;
/* If we have 5702/03 A1 or A2 on certain ICH chipsets,
* we need to disable memory and use config. cycles
* only to access all registers. The 5702/03 chips
* can mistakenly decode the special cycles from the
* ICH chipsets as memory write cycles, causing corruption
* of register and memory space. Only certain ICH bridges
* will drive special cycles with non-zero data during the
* address phase which can fall within the 5703's address
* range. This is not an ICH bug as the PCI spec allows
* non-zero address during special cycles. However, only
* these ICH bridges are known to drive non-zero addresses
* during special cycles.
*
* Since special cycles do not cross PCI bridges, we only
* enable this workaround if the 5703 is on the secondary
* bus of these ICH bridges.
*/
if ((tp->pci_chip_rev_id == CHIPREV_ID_5703_A1) ||
(tp->pci_chip_rev_id == CHIPREV_ID_5703_A2)) {
static struct tg3_dev_id {
u32 vendor;
u32 device;
u32 rev;
} ich_chipsets[] = {
{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801AA_8,
PCI_ANY_ID },
{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801AB_8,
PCI_ANY_ID },
{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801BA_11,
0xa },
{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801BA_6,
PCI_ANY_ID },
{ },
};
struct tg3_dev_id *pci_id = &ich_chipsets[0];
struct pci_dev *bridge = NULL;
while (pci_id->vendor != 0) {
bridge = pci_get_device(pci_id->vendor, pci_id->device,
bridge);
if (!bridge) {
pci_id++;
continue;
}
if (pci_id->rev != PCI_ANY_ID) {
if (bridge->revision > pci_id->rev)
continue;
}
if (bridge->subordinate &&
(bridge->subordinate->number ==
tp->pdev->bus->number)) {
tp->tg3_flags2 |= TG3_FLG2_ICH_WORKAROUND;
pci_dev_put(bridge);
break;
}
}
}
if ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5701)) {
static struct tg3_dev_id {
u32 vendor;
u32 device;
} bridge_chipsets[] = {
{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_PXH_0 },
{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_PXH_1 },
{ },
};
struct tg3_dev_id *pci_id = &bridge_chipsets[0];
struct pci_dev *bridge = NULL;
while (pci_id->vendor != 0) {
bridge = pci_get_device(pci_id->vendor,
pci_id->device,
bridge);
if (!bridge) {
pci_id++;
continue;
}
if (bridge->subordinate &&
(bridge->subordinate->number <=
tp->pdev->bus->number) &&
(bridge->subordinate->subordinate >=
tp->pdev->bus->number)) {
tp->tg3_flags3 |= TG3_FLG3_5701_DMA_BUG;
pci_dev_put(bridge);
break;
}
}
}
/* The EPB bridge inside 5714, 5715, and 5780 cannot support
* DMA addresses > 40-bit. This bridge may have other additional
* 57xx devices behind it in some 4-port NIC designs for example.
* Any tg3 device found behind the bridge will also need the 40-bit
* DMA workaround.
*/
if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5780 ||
GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5714) {
tp->tg3_flags2 |= TG3_FLG2_5780_CLASS;
tp->tg3_flags |= TG3_FLAG_40BIT_DMA_BUG;
tp->msi_cap = pci_find_capability(tp->pdev, PCI_CAP_ID_MSI);
} else {
struct pci_dev *bridge = NULL;
do {
bridge = pci_get_device(PCI_VENDOR_ID_SERVERWORKS,
PCI_DEVICE_ID_SERVERWORKS_EPB,
bridge);
if (bridge && bridge->subordinate &&
(bridge->subordinate->number <=
tp->pdev->bus->number) &&
(bridge->subordinate->subordinate >=
tp->pdev->bus->number)) {
tp->tg3_flags |= TG3_FLAG_40BIT_DMA_BUG;
pci_dev_put(bridge);
break;
}
} while (bridge);
}
/* Initialize misc host control in PCI block. */
tp->misc_host_ctrl |= (misc_ctrl_reg &
MISC_HOST_CTRL_CHIPREV);
pci_write_config_dword(tp->pdev, TG3PCI_MISC_HOST_CTRL,
tp->misc_host_ctrl);
if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704 ||
GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5714 ||
GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717)
tp->pdev_peer = tg3_find_peer(tp);
if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 ||
GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719 ||
GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57765)
tp->tg3_flags3 |= TG3_FLG3_5717_PLUS;
/* Intentionally exclude ASIC_REV_5906 */
if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5755 ||
GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5787 ||
GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5784 ||
GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5761 ||
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))
tp->tg3_flags3 |= TG3_FLG3_5755_PLUS;
if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5750 ||
GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5752 ||
GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906 ||
(tp->tg3_flags3 & TG3_FLG3_5755_PLUS) ||
(tp->tg3_flags2 & TG3_FLG2_5780_CLASS))
tp->tg3_flags2 |= TG3_FLG2_5750_PLUS;
if ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705) ||
(tp->tg3_flags2 & TG3_FLG2_5750_PLUS))
tp->tg3_flags2 |= TG3_FLG2_5705_PLUS;
/* 5700 B0 chips do not support checksumming correctly due
* to hardware bugs.
*/
if (tp->pci_chip_rev_id == CHIPREV_ID_5700_B0)
tp->tg3_flags |= TG3_FLAG_BROKEN_CHECKSUMS;
else {
unsigned long features = NETIF_F_IP_CSUM | NETIF_F_SG | NETIF_F_GRO;
tp->tg3_flags |= TG3_FLAG_RX_CHECKSUMS;
if (tp->tg3_flags3 & TG3_FLG3_5755_PLUS)
features |= NETIF_F_IPV6_CSUM;
tp->dev->features |= features;
vlan_features_add(tp->dev, features);
}
/* Determine TSO capabilities */
if (tp->tg3_flags3 & TG3_FLG3_5717_PLUS)
tp->tg3_flags2 |= TG3_FLG2_HW_TSO_3;
else if ((tp->tg3_flags3 & TG3_FLG3_5755_PLUS) ||
GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906)
tp->tg3_flags2 |= TG3_FLG2_HW_TSO_2;
else if (tp->tg3_flags2 & TG3_FLG2_5750_PLUS) {
tp->tg3_flags2 |= TG3_FLG2_HW_TSO_1 | TG3_FLG2_TSO_BUG;
if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5750 &&
tp->pci_chip_rev_id >= CHIPREV_ID_5750_C2)
tp->tg3_flags2 &= ~TG3_FLG2_TSO_BUG;
} else if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5700 &&
GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5701 &&
tp->pci_chip_rev_id != CHIPREV_ID_5705_A0) {
tp->tg3_flags2 |= TG3_FLG2_TSO_BUG;
if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705)
tp->fw_needed = FIRMWARE_TG3TSO5;
else
tp->fw_needed = FIRMWARE_TG3TSO;
}
tp->irq_max = 1;
if (tp->tg3_flags2 & TG3_FLG2_5750_PLUS) {
tp->tg3_flags |= TG3_FLAG_SUPPORT_MSI;
if (GET_CHIP_REV(tp->pci_chip_rev_id) == CHIPREV_5750_AX ||
GET_CHIP_REV(tp->pci_chip_rev_id) == CHIPREV_5750_BX ||
(GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5714 &&
tp->pci_chip_rev_id <= CHIPREV_ID_5714_A2 &&
tp->pdev_peer == tp->pdev))
tp->tg3_flags &= ~TG3_FLAG_SUPPORT_MSI;
if ((tp->tg3_flags3 & TG3_FLG3_5755_PLUS) ||
GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906) {
tp->tg3_flags2 |= TG3_FLG2_1SHOT_MSI;
}
if (tp->tg3_flags3 & TG3_FLG3_5717_PLUS) {
tp->tg3_flags |= TG3_FLAG_SUPPORT_MSIX;
tp->irq_max = TG3_IRQ_MAX_VECS;
}
}
if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 ||
GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719 ||
GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906)
tp->tg3_flags3 |= TG3_FLG3_SHORT_DMA_BUG;
else if (!(tp->tg3_flags3 & TG3_FLG3_5755_PLUS)) {
tp->tg3_flags3 |= TG3_FLG3_4G_DMA_BNDRY_BUG;
tp->tg3_flags3 |= TG3_FLG3_40BIT_DMA_LIMIT_BUG;
}
if (tp->tg3_flags3 & TG3_FLG3_5717_PLUS)
tp->tg3_flags3 |= TG3_FLG3_USE_JUMBO_BDFLAG;
if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS) ||
(tp->tg3_flags2 & TG3_FLG2_5780_CLASS) ||
(tp->tg3_flags3 & TG3_FLG3_USE_JUMBO_BDFLAG))
tp->tg3_flags |= TG3_FLAG_JUMBO_CAPABLE;
pci_read_config_dword(tp->pdev, TG3PCI_PCISTATE,
&pci_state_reg);
tp->pcie_cap = pci_find_capability(tp->pdev, PCI_CAP_ID_EXP);
if (tp->pcie_cap != 0) {
u16 lnkctl;
tp->tg3_flags2 |= TG3_FLG2_PCI_EXPRESS;
tp->pcie_readrq = 4096;
if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719) {
u16 word;
pci_read_config_word(tp->pdev,
tp->pcie_cap + PCI_EXP_LNKSTA,
&word);
switch (word & PCI_EXP_LNKSTA_CLS) {
case PCI_EXP_LNKSTA_CLS_2_5GB:
word &= PCI_EXP_LNKSTA_NLW;
word >>= PCI_EXP_LNKSTA_NLW_SHIFT;
switch (word) {
case 2:
tp->pcie_readrq = 2048;
break;
case 4:
tp->pcie_readrq = 1024;
break;
}
break;
case PCI_EXP_LNKSTA_CLS_5_0GB:
word &= PCI_EXP_LNKSTA_NLW;
word >>= PCI_EXP_LNKSTA_NLW_SHIFT;
switch (word) {
case 1:
tp->pcie_readrq = 2048;
break;
case 2:
tp->pcie_readrq = 1024;
break;
case 4:
tp->pcie_readrq = 512;
break;
}
}
}
pcie_set_readrq(tp->pdev, tp->pcie_readrq);
pci_read_config_word(tp->pdev,
tp->pcie_cap + PCI_EXP_LNKCTL,
&lnkctl);
if (lnkctl & PCI_EXP_LNKCTL_CLKREQ_EN) {
if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906)
tp->tg3_flags2 &= ~TG3_FLG2_HW_TSO_2;
if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5784 ||
GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5761 ||
tp->pci_chip_rev_id == CHIPREV_ID_57780_A0 ||
tp->pci_chip_rev_id == CHIPREV_ID_57780_A1)
tp->tg3_flags3 |= TG3_FLG3_CLKREQ_BUG;
} else if (tp->pci_chip_rev_id == CHIPREV_ID_5717_A0) {
tp->tg3_flags3 |= TG3_FLG3_L1PLLPD_EN;
}
} else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5785) {
tp->tg3_flags2 |= TG3_FLG2_PCI_EXPRESS;
} else if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS) ||
(tp->tg3_flags2 & TG3_FLG2_5780_CLASS)) {
tp->pcix_cap = pci_find_capability(tp->pdev, PCI_CAP_ID_PCIX);
if (!tp->pcix_cap) {
dev_err(&tp->pdev->dev,
"Cannot find PCI-X capability, aborting\n");
return -EIO;
}
if (!(pci_state_reg & PCISTATE_CONV_PCI_MODE))
tp->tg3_flags |= TG3_FLAG_PCIX_MODE;
}
/* If we have an AMD 762 or VIA K8T800 chipset, write
* reordering to the mailbox registers done by the host
* controller can cause major troubles. We read back from
* every mailbox register write to force the writes to be
* posted to the chip in order.
*/
if (pci_dev_present(write_reorder_chipsets) &&
!(tp->tg3_flags2 & TG3_FLG2_PCI_EXPRESS))
tp->tg3_flags |= TG3_FLAG_MBOX_WRITE_REORDER;
pci_read_config_byte(tp->pdev, PCI_CACHE_LINE_SIZE,
&tp->pci_cacheline_sz);
pci_read_config_byte(tp->pdev, PCI_LATENCY_TIMER,
&tp->pci_lat_timer);
if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5703 &&
tp->pci_lat_timer < 64) {
tp->pci_lat_timer = 64;
pci_write_config_byte(tp->pdev, PCI_LATENCY_TIMER,
tp->pci_lat_timer);
}
if (GET_CHIP_REV(tp->pci_chip_rev_id) == CHIPREV_5700_BX) {
/* 5700 BX chips need to have their TX producer index
* mailboxes written twice to workaround a bug.
*/
tp->tg3_flags |= TG3_FLAG_TXD_MBOX_HWBUG;
/* If we are in PCI-X mode, enable register write workaround.
*
* The workaround is to use indirect register accesses
* for all chip writes not to mailbox registers.
*/
if (tp->tg3_flags & TG3_FLAG_PCIX_MODE) {
u32 pm_reg;
tp->tg3_flags |= TG3_FLAG_PCIX_TARGET_HWBUG;
/* The chip can have it's power management PCI config
* space registers clobbered due to this bug.
* So explicitly force the chip into D0 here.
*/
pci_read_config_dword(tp->pdev,
tp->pm_cap + PCI_PM_CTRL,
&pm_reg);
pm_reg &= ~PCI_PM_CTRL_STATE_MASK;
pm_reg |= PCI_PM_CTRL_PME_ENABLE | 0 /* D0 */;
pci_write_config_dword(tp->pdev,
tp->pm_cap + PCI_PM_CTRL,
pm_reg);
/* Also, force SERR#/PERR# in PCI command. */
pci_read_config_word(tp->pdev, PCI_COMMAND, &pci_cmd);
pci_cmd |= PCI_COMMAND_PARITY | PCI_COMMAND_SERR;
pci_write_config_word(tp->pdev, PCI_COMMAND, pci_cmd);
}
}
if ((pci_state_reg & PCISTATE_BUS_SPEED_HIGH) != 0)
tp->tg3_flags |= TG3_FLAG_PCI_HIGH_SPEED;
if ((pci_state_reg & PCISTATE_BUS_32BIT) != 0)
tp->tg3_flags |= TG3_FLAG_PCI_32BIT;
/* Chip-specific fixup from Broadcom driver */
if ((tp->pci_chip_rev_id == CHIPREV_ID_5704_A0) &&
(!(pci_state_reg & PCISTATE_RETRY_SAME_DMA))) {
pci_state_reg |= PCISTATE_RETRY_SAME_DMA;
pci_write_config_dword(tp->pdev, TG3PCI_PCISTATE, pci_state_reg);
}
/* Default fast path register access methods */
tp->read32 = tg3_read32;
tp->write32 = tg3_write32;
tp->read32_mbox = tg3_read32;
tp->write32_mbox = tg3_write32;
tp->write32_tx_mbox = tg3_write32;
tp->write32_rx_mbox = tg3_write32;
/* Various workaround register access methods */
if (tp->tg3_flags & TG3_FLAG_PCIX_TARGET_HWBUG)
tp->write32 = tg3_write_indirect_reg32;
else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5701 ||
((tp->tg3_flags2 & TG3_FLG2_PCI_EXPRESS) &&
tp->pci_chip_rev_id == CHIPREV_ID_5750_A0)) {
/*
* Back to back register writes can cause problems on these
* chips, the workaround is to read back all reg writes
* except those to mailbox regs.
*
* See tg3_write_indirect_reg32().
*/
tp->write32 = tg3_write_flush_reg32;
}
if ((tp->tg3_flags & TG3_FLAG_TXD_MBOX_HWBUG) ||
(tp->tg3_flags & TG3_FLAG_MBOX_WRITE_REORDER)) {
tp->write32_tx_mbox = tg3_write32_tx_mbox;
if (tp->tg3_flags & TG3_FLAG_MBOX_WRITE_REORDER)
tp->write32_rx_mbox = tg3_write_flush_reg32;
}
if (tp->tg3_flags2 & TG3_FLG2_ICH_WORKAROUND) {
tp->read32 = tg3_read_indirect_reg32;
tp->write32 = tg3_write_indirect_reg32;
tp->read32_mbox = tg3_read_indirect_mbox;
tp->write32_mbox = tg3_write_indirect_mbox;
tp->write32_tx_mbox = tg3_write_indirect_mbox;
tp->write32_rx_mbox = tg3_write_indirect_mbox;
iounmap(tp->regs);
tp->regs = NULL;
pci_read_config_word(tp->pdev, PCI_COMMAND, &pci_cmd);
pci_cmd &= ~PCI_COMMAND_MEMORY;
pci_write_config_word(tp->pdev, PCI_COMMAND, pci_cmd);
}
if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906) {
tp->read32_mbox = tg3_read32_mbox_5906;
tp->write32_mbox = tg3_write32_mbox_5906;
tp->write32_tx_mbox = tg3_write32_mbox_5906;
tp->write32_rx_mbox = tg3_write32_mbox_5906;
}
if (tp->write32 == tg3_write_indirect_reg32 ||
((tp->tg3_flags & TG3_FLAG_PCIX_MODE) &&
(GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5700 ||
GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5701)))
tp->tg3_flags |= TG3_FLAG_SRAM_USE_CONFIG;
/* Get eeprom hw config before calling tg3_set_power_state().
* In particular, the TG3_FLG2_IS_NIC flag must be
* determined before calling tg3_set_power_state() so that
* we know whether or not to switch out of Vaux power.
* When the flag is set, it means that GPIO1 is used for eeprom
* write protect and also implies that it is a LOM where GPIOs
* are not used to switch power.
*/
tg3_get_eeprom_hw_cfg(tp);
if (tp->tg3_flags3 & TG3_FLG3_ENABLE_APE) {
/* Allow reads and writes to the
* APE register and memory space.
*/
pci_state_reg |= PCISTATE_ALLOW_APE_CTLSPC_WR |
PCISTATE_ALLOW_APE_SHMEM_WR |
PCISTATE_ALLOW_APE_PSPACE_WR;
pci_write_config_dword(tp->pdev, TG3PCI_PCISTATE,
pci_state_reg);
}
if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5784 ||
GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5761 ||
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))
tp->tg3_flags |= TG3_FLAG_CPMU_PRESENT;
/* Set up tp->grc_local_ctrl before calling tg_power_up().
* GPIO1 driven high will bring 5700's external PHY out of reset.
* It is also used as eeprom write protect on LOMs.
*/
tp->grc_local_ctrl = GRC_LCLCTRL_INT_ON_ATTN | GRC_LCLCTRL_AUTO_SEEPROM;
if ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5700) ||
(tp->tg3_flags & TG3_FLAG_EEPROM_WRITE_PROT))
tp->grc_local_ctrl |= (GRC_LCLCTRL_GPIO_OE1 |
GRC_LCLCTRL_GPIO_OUTPUT1);
/* Unused GPIO3 must be driven as output on 5752 because there
* are no pull-up resistors on unused GPIO pins.
*/
else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5752)
tp->grc_local_ctrl |= GRC_LCLCTRL_GPIO_OE3;
if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5755 ||
GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57780 ||
GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57765)
tp->grc_local_ctrl |= GRC_LCLCTRL_GPIO_UART_SEL;
if (tp->pdev->device == PCI_DEVICE_ID_TIGON3_5761 ||
tp->pdev->device == TG3PCI_DEVICE_TIGON3_5761S) {
/* Turn off the debug UART. */
tp->grc_local_ctrl |= GRC_LCLCTRL_GPIO_UART_SEL;
if (tp->tg3_flags2 & TG3_FLG2_IS_NIC)
/* Keep VMain power. */
tp->grc_local_ctrl |= GRC_LCLCTRL_GPIO_OE0 |
GRC_LCLCTRL_GPIO_OUTPUT0;
}
/* Force the chip into D0. */
err = tg3_power_up(tp);
if (err) {
dev_err(&tp->pdev->dev, "Transition to D0 failed\n");
return err;
}
/* Derive initial jumbo mode from MTU assigned in
* ether_setup() via the alloc_etherdev() call
*/
if (tp->dev->mtu > ETH_DATA_LEN &&
!(tp->tg3_flags2 & TG3_FLG2_5780_CLASS))
tp->tg3_flags |= TG3_FLAG_JUMBO_RING_ENABLE;
/* Determine WakeOnLan speed to use. */
if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5700 ||
tp->pci_chip_rev_id == CHIPREV_ID_5701_A0 ||
tp->pci_chip_rev_id == CHIPREV_ID_5701_B0 ||
tp->pci_chip_rev_id == CHIPREV_ID_5701_B2) {
tp->tg3_flags &= ~(TG3_FLAG_WOL_SPEED_100MB);
} else {
tp->tg3_flags |= TG3_FLAG_WOL_SPEED_100MB;
}
if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906)
tp->phy_flags |= TG3_PHYFLG_IS_FET;
/* A few boards don't want Ethernet@WireSpeed phy feature */
if ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5700) ||
((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705) &&
(tp->pci_chip_rev_id != CHIPREV_ID_5705_A0) &&
(tp->pci_chip_rev_id != CHIPREV_ID_5705_A1)) ||
(tp->phy_flags & TG3_PHYFLG_IS_FET) ||
(tp->phy_flags & TG3_PHYFLG_ANY_SERDES))
tp->phy_flags |= TG3_PHYFLG_NO_ETH_WIRE_SPEED;
if (GET_CHIP_REV(tp->pci_chip_rev_id) == CHIPREV_5703_AX ||
GET_CHIP_REV(tp->pci_chip_rev_id) == CHIPREV_5704_AX)
tp->phy_flags |= TG3_PHYFLG_ADC_BUG;
if (tp->pci_chip_rev_id == CHIPREV_ID_5704_A0)
tp->phy_flags |= TG3_PHYFLG_5704_A0_BUG;
if ((tp->tg3_flags2 & TG3_FLG2_5705_PLUS) &&
!(tp->phy_flags & TG3_PHYFLG_IS_FET) &&
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)) {
if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5755 ||
GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5787 ||
GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5784 ||
GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5761) {
if (tp->pdev->device != PCI_DEVICE_ID_TIGON3_5756 &&
tp->pdev->device != PCI_DEVICE_ID_TIGON3_5722)
tp->phy_flags |= TG3_PHYFLG_JITTER_BUG;
if (tp->pdev->device == PCI_DEVICE_ID_TIGON3_5755M)
tp->phy_flags |= TG3_PHYFLG_ADJUST_TRIM;
} else
tp->phy_flags |= TG3_PHYFLG_BER_BUG;
}
if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5784 &&
GET_CHIP_REV(tp->pci_chip_rev_id) != CHIPREV_5784_AX) {
tp->phy_otp = tg3_read_otp_phycfg(tp);
if (tp->phy_otp == 0)
tp->phy_otp = TG3_OTP_DEFAULT;
}
if (tp->tg3_flags & TG3_FLAG_CPMU_PRESENT)
tp->mi_mode = MAC_MI_MODE_500KHZ_CONST;
else
tp->mi_mode = MAC_MI_MODE_BASE;
tp->coalesce_mode = 0;
if (GET_CHIP_REV(tp->pci_chip_rev_id) != CHIPREV_5700_AX &&
GET_CHIP_REV(tp->pci_chip_rev_id) != CHIPREV_5700_BX)
tp->coalesce_mode |= HOSTCC_MODE_32BYTE;
if (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_USE_PHYLIB;
err = tg3_mdio_init(tp);
if (err)
return err;
/* Initialize data/descriptor byte/word swapping. */
val = tr32(GRC_MODE);
val &= GRC_MODE_HOST_STACKUP;
tw32(GRC_MODE, val | tp->grc_mode);
tg3_switch_clocks(tp);
/* Clear this out for sanity. */
tw32(TG3PCI_MEM_WIN_BASE_ADDR, 0);
pci_read_config_dword(tp->pdev, TG3PCI_PCISTATE,
&pci_state_reg);
if ((pci_state_reg & PCISTATE_CONV_PCI_MODE) == 0 &&
(tp->tg3_flags & TG3_FLAG_PCIX_TARGET_HWBUG) == 0) {
u32 chiprevid = GET_CHIP_REV_ID(tp->misc_host_ctrl);
if (chiprevid == CHIPREV_ID_5701_A0 ||
chiprevid == CHIPREV_ID_5701_B0 ||
chiprevid == CHIPREV_ID_5701_B2 ||
chiprevid == CHIPREV_ID_5701_B5) {
void __iomem *sram_base;
/* Write some dummy words into the SRAM status block
* area, see if it reads back correctly. If the return
* value is bad, force enable the PCIX workaround.
*/
sram_base = tp->regs + NIC_SRAM_WIN_BASE + NIC_SRAM_STATS_BLK;
writel(0x00000000, sram_base);
writel(0x00000000, sram_base + 4);
writel(0xffffffff, sram_base + 4);
if (readl(sram_base) != 0x00000000)
tp->tg3_flags |= TG3_FLAG_PCIX_TARGET_HWBUG;
}
}
udelay(50);
tg3_nvram_init(tp);
grc_misc_cfg = tr32(GRC_MISC_CFG);
grc_misc_cfg &= GRC_MISC_CFG_BOARD_ID_MASK;
if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705 &&
(grc_misc_cfg == GRC_MISC_CFG_BOARD_ID_5788 ||
grc_misc_cfg == GRC_MISC_CFG_BOARD_ID_5788M))
tp->tg3_flags2 |= TG3_FLG2_IS_5788;
if (!(tp->tg3_flags2 & TG3_FLG2_IS_5788) &&
(GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5700))
tp->tg3_flags |= TG3_FLAG_TAGGED_STATUS;
if (tp->tg3_flags & TG3_FLAG_TAGGED_STATUS) {
tp->coalesce_mode |= (HOSTCC_MODE_CLRTICK_RXBD |
HOSTCC_MODE_CLRTICK_TXBD);
tp->misc_host_ctrl |= MISC_HOST_CTRL_TAGGED_STATUS;
pci_write_config_dword(tp->pdev, TG3PCI_MISC_HOST_CTRL,
tp->misc_host_ctrl);
}
/* Preserve the APE MAC_MODE bits */
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 = TG3_DEF_MAC_MODE;
/* these are limited to 10/100 only */
if ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5703 &&
(grc_misc_cfg == 0x8000 || grc_misc_cfg == 0x4000)) ||
(GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705 &&
tp->pdev->vendor == PCI_VENDOR_ID_BROADCOM &&
(tp->pdev->device == PCI_DEVICE_ID_TIGON3_5901 ||
tp->pdev->device == PCI_DEVICE_ID_TIGON3_5901_2 ||
tp->pdev->device == PCI_DEVICE_ID_TIGON3_5705F)) ||
(tp->pdev->vendor == PCI_VENDOR_ID_BROADCOM &&
(tp->pdev->device == PCI_DEVICE_ID_TIGON3_5751F ||
tp->pdev->device == PCI_DEVICE_ID_TIGON3_5753F ||
tp->pdev->device == PCI_DEVICE_ID_TIGON3_5787F)) ||
tp->pdev->device == TG3PCI_DEVICE_TIGON3_57790 ||
tp->pdev->device == TG3PCI_DEVICE_TIGON3_57791 ||
tp->pdev->device == TG3PCI_DEVICE_TIGON3_57795 ||
(tp->phy_flags & TG3_PHYFLG_IS_FET))
tp->phy_flags |= TG3_PHYFLG_10_100_ONLY;
err = tg3_phy_probe(tp);
if (err) {
dev_err(&tp->pdev->dev, "phy probe failed, err %d\n", err);
/* ... but do not return immediately ... */
tg3_mdio_fini(tp);
}
tg3_read_vpd(tp);
tg3_read_fw_ver(tp);
if (tp->phy_flags & TG3_PHYFLG_PHY_SERDES) {
tp->phy_flags &= ~TG3_PHYFLG_USE_MI_INTERRUPT;
} else {
if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5700)
tp->phy_flags |= TG3_PHYFLG_USE_MI_INTERRUPT;
else
tp->phy_flags &= ~TG3_PHYFLG_USE_MI_INTERRUPT;
}
/* 5700 {AX,BX} chips have a broken status block link
* change bit implementation, so we must use the
* status register in those cases.
*/
if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5700)
tp->tg3_flags |= TG3_FLAG_USE_LINKCHG_REG;
else
tp->tg3_flags &= ~TG3_FLAG_USE_LINKCHG_REG;
/* The led_ctrl is set during tg3_phy_probe, here we might
* have to force the link status polling mechanism based
* upon subsystem IDs.
*/
if (tp->pdev->subsystem_vendor == PCI_VENDOR_ID_DELL &&
GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5701 &&
!(tp->phy_flags & TG3_PHYFLG_PHY_SERDES)) {
tp->phy_flags |= TG3_PHYFLG_USE_MI_INTERRUPT;
tp->tg3_flags |= TG3_FLAG_USE_LINKCHG_REG;
}
/* For all SERDES we poll the MAC status register. */
if (tp->phy_flags & TG3_PHYFLG_PHY_SERDES)
tp->tg3_flags |= TG3_FLAG_POLL_SERDES;
else
tp->tg3_flags &= ~TG3_FLAG_POLL_SERDES;
tp->rx_offset = NET_IP_ALIGN;
tp->rx_copy_thresh = TG3_RX_COPY_THRESHOLD;
if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5701 &&
(tp->tg3_flags & TG3_FLAG_PCIX_MODE) != 0) {
tp->rx_offset = 0;
#ifndef CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS
tp->rx_copy_thresh = ~(u16)0;
#endif
}
tp->rx_std_ring_mask = TG3_RX_STD_RING_SIZE(tp) - 1;
tp->rx_jmb_ring_mask = TG3_RX_JMB_RING_SIZE(tp) - 1;
tp->rx_ret_ring_mask = tg3_rx_ret_ring_size(tp) - 1;
tp->rx_std_max_post = tp->rx_std_ring_mask + 1;
/* Increment the rx prod index on the rx std ring by at most
* 8 for these chips to workaround hw errata.
*/
if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5750 ||
GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5752 ||
GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5755)
tp->rx_std_max_post = 8;
if (tp->tg3_flags & TG3_FLAG_ASPM_WORKAROUND)
tp->pwrmgmt_thresh = tr32(PCIE_PWR_MGMT_THRESH) &
PCIE_PWR_MGMT_L1_THRESH_MSK;
return err;
}
Generated by GNU enscript 1.6.4.