diff --git a/src/drivers/net/tg3/tg3.c b/src/drivers/net/tg3/tg3.c index b2cba72..d182404 100644 --- a/src/drivers/net/tg3/tg3.c +++ b/src/drivers/net/tg3/tg3.c @@ -323,7 +323,9 @@ static int tg3_transmit(struct net_device *dev, struct io_buffer *iob) /* Packets are ready, update Tx producer idx local and on card. */ tw32_tx_mbox(tp->prodmbox, entry); - writel(entry, tp->regs + MAILBOX_SNDHOST_PROD_IDX_0 + TG3_64BIT_REG_LOW); + //writel(entry, tp->regs + MAILBOX_SNDHOST_PROD_IDX_0 + TG3_64BIT_REG_LOW); + tg3_write_indirect_reg32(tp, + MAILBOX_SNDHOST_PROD_IDX_0 + TG3_64BIT_REG_LOW, entry); tp->tx_prod = entry; diff --git a/src/drivers/net/tg3/tg3_hw.c b/src/drivers/net/tg3/tg3_hw.c index 13d5962..7875dd4 100644 --- a/src/drivers/net/tg3/tg3_hw.c +++ b/src/drivers/net/tg3/tg3_hw.c @@ -826,6 +826,26 @@ int tg3_get_invariants(struct tg3 *tp) 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) + tg3_flag_set(tp, USE_LINKCHG_REG); + else + tg3_flag_clear(tp, 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->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; + tg3_flag_set(tp, USE_LINKCHG_REG); + } + /* For all SERDES we poll the MAC status register. */ if (tp->phy_flags & TG3_PHYFLG_PHY_SERDES) tg3_flag_set(tp, POLL_SERDES); @@ -2125,7 +2145,14 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy) tw32(RCVDBDI_MINI_BD + TG3_BDINFO_MAXLEN_FLAGS, BDINFO_FLAGS_DISABLED); - val = TG3_RX_STD_MAX_SIZE_5700 << BDINFO_FLAGS_MAXLEN_SHIFT; + if (tg3_flag(tp, 57765_PLUS)) { + /* 5717's size crashes - use smaller size */ + //val = TG3_RX_STD_MAX_SIZE_5717; + val = TG3_RX_STD_MAX_SIZE_5700; + val <<= BDINFO_FLAGS_MAXLEN_SHIFT; + val |= (TG3_RX_STD_DMA_SZ << 2); + } else + val = TG3_RX_STD_MAX_SIZE_5700 << BDINFO_FLAGS_MAXLEN_SHIFT; tw32(RCVDBDI_STD_BD + TG3_BDINFO_MAXLEN_FLAGS, val); diff --git a/src/drivers/net/tg3/tg3_phy.c b/src/drivers/net/tg3/tg3_phy.c index f49c7f0..54ec366 100644 --- a/src/drivers/net/tg3/tg3_phy.c +++ b/src/drivers/net/tg3/tg3_phy.c @@ -1008,11 +1008,27 @@ skip_phy_reset: void tg3_poll_link(struct tg3 *tp) { DBGP("%s\n", __func__); + struct tg3_hw_status *sblk = tp->hw_status; u32 mac_stat; + int res = 0; - mac_stat = tr32(MAC_STATUS); + if (tg3_flag(tp, USE_LINKCHG_REG)) { + mac_stat = tr32(MAC_STATUS); - if (mac_stat & MAC_STATUS_LNKSTATE_CHANGED) + if (mac_stat & MAC_STATUS_LNKSTATE_CHANGED) + res = 1; + + } else { + + if (sblk->status & SD_STATUS_LINK_CHG) { + sblk->status = SD_STATUS_UPDATED | + (sblk->status & ~SD_STATUS_LINK_CHG); + + res = 1; + } + } + + if (res) tg3_setup_phy(tp, 0); } @@ -1506,9 +1522,12 @@ relink: tw32_f(MAC_MODE, tp->mac_mode); udelay(40); - /* We always use the link change register */ - /* NOTE: this freezes for mdc? */ - tw32_f(MAC_EVENT, 0); + if (tg3_flag(tp, USE_LINKCHG_REG)) + /* NOTE: this freezes for mdc? */ + tw32_f(MAC_EVENT, 0); + else + tw32_f(MAC_EVENT, MAC_EVENT_LNKSTATE_CHANGED); + udelay(40); if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5700 &&