net: Move flow control definitions to mii.h
[firefly-linux-kernel-4.4.55.git] / drivers / net / tg3.c
index 6972fe5ccbf6abc0aa94b2cf4a14312a76fd837f..f353f69caeb8357fa7f9c04d017b6ad9ede2cb2d 100644 (file)
@@ -69,8 +69,8 @@
 
 #define DRV_MODULE_NAME                "tg3"
 #define PFX DRV_MODULE_NAME    ": "
-#define DRV_MODULE_VERSION     "3.95"
-#define DRV_MODULE_RELDATE     "November 3, 2008"
+#define DRV_MODULE_VERSION     "3.96"
+#define DRV_MODULE_RELDATE     "November 21, 2008"
 
 #define TG3_DEF_MAC_MODE       0
 #define TG3_DEF_RX_MODE                0
@@ -213,6 +213,10 @@ static struct pci_device_id tg3_pci_tbl[] = {
        {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_5761S)},
        {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_5761SE)},
        {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5785)},
+       {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_57780)},
+       {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_57760)},
+       {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_57790)},
+       {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_57720)},
        {PCI_DEVICE(PCI_VENDOR_ID_SYSKONNECT, PCI_DEVICE_ID_SYSKONNECT_9DXX)},
        {PCI_DEVICE(PCI_VENDOR_ID_SYSKONNECT, PCI_DEVICE_ID_SYSKONNECT_9MXX)},
        {PCI_DEVICE(PCI_VENDOR_ID_ALTIMA, PCI_DEVICE_ID_ALTIMA_AC1000)},
@@ -1036,6 +1040,9 @@ static int tg3_mdio_init(struct tg3 *tp)
        }
 
        switch (phydev->drv->phy_id & phydev->drv->phy_id_mask) {
+       case TG3_PHY_ID_BCM57780:
+               phydev->interface = PHY_INTERFACE_MODE_GMII;
+               break;
        case TG3_PHY_ID_BCM50610:
                if (tp->tg3_flags3 & TG3_FLG3_RGMII_STD_IBND_DISABLE)
                        phydev->dev_flags |= PHY_BRCM_STD_IBND_DISABLE;
@@ -1180,9 +1187,9 @@ static void tg3_link_report(struct tg3 *tp)
                printk(KERN_INFO PFX
                       "%s: Flow control is %s for TX and %s for RX.\n",
                       tp->dev->name,
-                      (tp->link_config.active_flowctrl & TG3_FLOW_CTRL_TX) ?
+                      (tp->link_config.active_flowctrl & FLOW_CTRL_TX) ?
                       "on" : "off",
-                      (tp->link_config.active_flowctrl & TG3_FLOW_CTRL_RX) ?
+                      (tp->link_config.active_flowctrl & FLOW_CTRL_RX) ?
                       "on" : "off");
                tg3_ump_link_report(tp);
        }
@@ -1192,11 +1199,11 @@ static u16 tg3_advert_flowctrl_1000T(u8 flow_ctrl)
 {
        u16 miireg;
 
-       if ((flow_ctrl & TG3_FLOW_CTRL_TX) && (flow_ctrl & TG3_FLOW_CTRL_RX))
+       if ((flow_ctrl & FLOW_CTRL_TX) && (flow_ctrl & FLOW_CTRL_RX))
                miireg = ADVERTISE_PAUSE_CAP;
-       else if (flow_ctrl & TG3_FLOW_CTRL_TX)
+       else if (flow_ctrl & FLOW_CTRL_TX)
                miireg = ADVERTISE_PAUSE_ASYM;
-       else if (flow_ctrl & TG3_FLOW_CTRL_RX)
+       else if (flow_ctrl & FLOW_CTRL_RX)
                miireg = ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM;
        else
                miireg = 0;
@@ -1208,11 +1215,11 @@ static u16 tg3_advert_flowctrl_1000X(u8 flow_ctrl)
 {
        u16 miireg;
 
-       if ((flow_ctrl & TG3_FLOW_CTRL_TX) && (flow_ctrl & TG3_FLOW_CTRL_RX))
+       if ((flow_ctrl & FLOW_CTRL_TX) && (flow_ctrl & FLOW_CTRL_RX))
                miireg = ADVERTISE_1000XPAUSE;
-       else if (flow_ctrl & TG3_FLOW_CTRL_TX)
+       else if (flow_ctrl & FLOW_CTRL_TX)
                miireg = ADVERTISE_1000XPSE_ASYM;
-       else if (flow_ctrl & TG3_FLOW_CTRL_RX)
+       else if (flow_ctrl & FLOW_CTRL_RX)
                miireg = ADVERTISE_1000XPAUSE | ADVERTISE_1000XPSE_ASYM;
        else
                miireg = 0;
@@ -1249,16 +1256,16 @@ static u8 tg3_resolve_flowctrl_1000X(u16 lcladv, u16 rmtadv)
        if (lcladv & ADVERTISE_1000XPAUSE) {
                if (lcladv & ADVERTISE_1000XPSE_ASYM) {
                        if (rmtadv & LPA_1000XPAUSE)
-                               cap = TG3_FLOW_CTRL_TX | TG3_FLOW_CTRL_RX;
+                               cap = FLOW_CTRL_TX | FLOW_CTRL_RX;
                        else if (rmtadv & LPA_1000XPAUSE_ASYM)
-                               cap = TG3_FLOW_CTRL_RX;
+                               cap = FLOW_CTRL_RX;
                } else {
                        if (rmtadv & LPA_1000XPAUSE)
-                               cap = TG3_FLOW_CTRL_TX | TG3_FLOW_CTRL_RX;
+                               cap = FLOW_CTRL_TX | FLOW_CTRL_RX;
                }
        } else if (lcladv & ADVERTISE_1000XPSE_ASYM) {
                if ((rmtadv & LPA_1000XPAUSE) && (rmtadv & LPA_1000XPAUSE_ASYM))
-                       cap = TG3_FLOW_CTRL_TX;
+                       cap = FLOW_CTRL_TX;
        }
 
        return cap;
@@ -1287,7 +1294,7 @@ static void tg3_setup_flow_control(struct tg3 *tp, u32 lcladv, u32 rmtadv)
 
        tp->link_config.active_flowctrl = flowctrl;
 
-       if (flowctrl & TG3_FLOW_CTRL_RX)
+       if (flowctrl & FLOW_CTRL_RX)
                tp->rx_mode |= RX_MODE_FLOW_CTRL_ENABLE;
        else
                tp->rx_mode &= ~RX_MODE_FLOW_CTRL_ENABLE;
@@ -1295,7 +1302,7 @@ static void tg3_setup_flow_control(struct tg3 *tp, u32 lcladv, u32 rmtadv)
        if (old_rx_mode != tp->rx_mode)
                tw32_f(MAC_RX_MODE, tp->rx_mode);
 
-       if (flowctrl & TG3_FLOW_CTRL_TX)
+       if (flowctrl & FLOW_CTRL_TX)
                tp->tx_mode |= TX_MODE_FLOW_CTRL_ENABLE;
        else
                tp->tx_mode &= ~TX_MODE_FLOW_CTRL_ENABLE;
@@ -1409,10 +1416,13 @@ static int tg3_phy_init(struct tg3 *tp)
        switch (phydev->interface) {
        case PHY_INTERFACE_MODE_GMII:
        case PHY_INTERFACE_MODE_RGMII:
-               phydev->supported &= (PHY_GBIT_FEATURES |
-                                     SUPPORTED_Pause |
-                                     SUPPORTED_Asym_Pause);
-               break;
+               if (!(tp->tg3_flags & TG3_FLAG_10_100_ONLY)) {
+                       phydev->supported &= (PHY_GBIT_FEATURES |
+                                             SUPPORTED_Pause |
+                                             SUPPORTED_Asym_Pause);
+                       break;
+               }
+               /* fallthru */
        case PHY_INTERFACE_MODE_MII:
                phydev->supported &= (PHY_BASIC_FEATURES |
                                      SUPPORTED_Pause |
@@ -2400,8 +2410,7 @@ static int tg3_set_power_state(struct tg3 *tp, pci_power_t state)
        }
 
        if (!(device_should_wake) &&
-           !(tp->tg3_flags & TG3_FLAG_ENABLE_ASF) &&
-           !(tp->tg3_flags3 & TG3_FLG3_ENABLE_APE))
+           !(tp->tg3_flags & TG3_FLAG_ENABLE_ASF))
                tg3_power_down_phy(tp, do_low_power);
 
        tg3_frob_aux_power(tp);
@@ -5992,11 +6001,7 @@ static int tg3_chip_reset(struct tg3 *tp)
        tg3_save_pci_state(tp);
 
        if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5752 ||
-           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)
+           (tp->tg3_flags3 & TG3_FLG3_5755_PLUS))
                tw32(GRC_FASTBOOT_PC, 0);
 
        /*
@@ -7512,7 +7517,8 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
                      RDMAC_MODE_LNGREAD_ENAB);
 
        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_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;
@@ -7681,11 +7687,7 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
        }
 
        /* Enable host coalescing bug fix */
-       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))
+       if (tp->tg3_flags3 & TG3_FLG3_5755_PLUS)
                val |= WDMAC_MODE_STATUS_TAG_FIX;
 
        tw32_f(WDMAC_MODE, val);
@@ -7746,10 +7748,7 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
        udelay(100);
 
        tp->rx_mode = RX_MODE_ENABLE;
-       if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5755 ||
-           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)
+       if (tp->tg3_flags3 & TG3_FLG3_5755_PLUS)
                tp->rx_mode |= RX_MODE_IPV6_CSUM_ENABLE;
 
        tw32_f(MAC_RX_MODE, tp->rx_mode);
@@ -9304,7 +9303,8 @@ static int tg3_set_tso(struct net_device *dev, u32 value)
                        if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5761 ||
                            (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5784 &&
                             GET_CHIP_REV(tp->pci_chip_rev_id) != CHIPREV_5784_AX) ||
-                           GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5785)
+                           GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5785 ||
+                           GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57780)
                                dev->features |= NETIF_F_TSO_ECN;
                } else
                        dev->features &= ~(NETIF_F_TSO6 | NETIF_F_TSO_ECN);
@@ -9419,12 +9419,12 @@ static void tg3_get_pauseparam(struct net_device *dev, struct ethtool_pauseparam
 
        epause->autoneg = (tp->tg3_flags & TG3_FLAG_PAUSE_AUTONEG) != 0;
 
-       if (tp->link_config.active_flowctrl & TG3_FLOW_CTRL_RX)
+       if (tp->link_config.active_flowctrl & FLOW_CTRL_RX)
                epause->rx_pause = 1;
        else
                epause->rx_pause = 0;
 
-       if (tp->link_config.active_flowctrl & TG3_FLOW_CTRL_TX)
+       if (tp->link_config.active_flowctrl & FLOW_CTRL_TX)
                epause->tx_pause = 1;
        else
                epause->tx_pause = 0;
@@ -9475,14 +9475,14 @@ static int tg3_set_pauseparam(struct net_device *dev, struct ethtool_pauseparam
                        }
                } else {
                        if (epause->rx_pause)
-                               tp->link_config.flowctrl |= TG3_FLOW_CTRL_RX;
+                               tp->link_config.flowctrl |= FLOW_CTRL_RX;
                        else
-                               tp->link_config.flowctrl &= ~TG3_FLOW_CTRL_RX;
+                               tp->link_config.flowctrl &= ~FLOW_CTRL_RX;
 
                        if (epause->tx_pause)
-                               tp->link_config.flowctrl |= TG3_FLOW_CTRL_TX;
+                               tp->link_config.flowctrl |= FLOW_CTRL_TX;
                        else
-                               tp->link_config.flowctrl &= ~TG3_FLOW_CTRL_TX;
+                               tp->link_config.flowctrl &= ~FLOW_CTRL_TX;
 
                        if (netif_running(dev))
                                tg3_setup_flow_control(tp, 0, 0);
@@ -9502,13 +9502,13 @@ static int tg3_set_pauseparam(struct net_device *dev, struct ethtool_pauseparam
                else
                        tp->tg3_flags &= ~TG3_FLAG_PAUSE_AUTONEG;
                if (epause->rx_pause)
-                       tp->link_config.flowctrl |= TG3_FLOW_CTRL_RX;
+                       tp->link_config.flowctrl |= FLOW_CTRL_RX;
                else
-                       tp->link_config.flowctrl &= ~TG3_FLOW_CTRL_RX;
+                       tp->link_config.flowctrl &= ~FLOW_CTRL_RX;
                if (epause->tx_pause)
-                       tp->link_config.flowctrl |= TG3_FLOW_CTRL_TX;
+                       tp->link_config.flowctrl |= FLOW_CTRL_TX;
                else
-                       tp->link_config.flowctrl &= ~TG3_FLOW_CTRL_TX;
+                       tp->link_config.flowctrl &= ~FLOW_CTRL_TX;
 
                if (netif_running(dev)) {
                        tg3_halt(tp, RESET_KIND_SHUTDOWN, 1);
@@ -9559,11 +9559,7 @@ static int tg3_set_tx_csum(struct net_device *dev, u32 data)
                return 0;
        }
 
-       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)
+       if (tp->tg3_flags3 & TG3_FLG3_5755_PLUS)
                ethtool_op_set_tx_ipv6_csum(dev, data);
        else
                ethtool_op_set_tx_csum(dev, data);
@@ -10080,18 +10076,13 @@ static int tg3_test_memory(struct tg3 *tp)
        int err = 0;
        int i;
 
-       if (tp->tg3_flags2 & TG3_FLG2_5705_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 ||
-                   GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5785)
-                       mem_tbl = mem_tbl_5755;
-               else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906)
-                       mem_tbl = mem_tbl_5906;
-               else
-                       mem_tbl = mem_tbl_5705;
-       } else
+       if (tp->tg3_flags3 & TG3_FLG3_5755_PLUS)
+               mem_tbl = mem_tbl_5755;
+       else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906)
+               mem_tbl = mem_tbl_5906;
+       else if (tp->tg3_flags2 & TG3_FLG2_5705_PLUS)
+               mem_tbl = mem_tbl_5705;
+       else
                mem_tbl = mem_tbl_570x;
 
        for (i = 0; mem_tbl[i].offset != 0xffffffff; i++) {
@@ -10295,9 +10286,7 @@ static int tg3_test_loopback(struct tg3 *tp)
        if (tp->tg3_flags3 & TG3_FLG3_PHY_ENABLE_APD)
                tg3_phy_toggle_apd(tp, false);
 
-       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) {
+       if (tp->tg3_flags & TG3_FLAG_CPMU_PRESENT) {
                int i;
                u32 status;
 
@@ -10324,9 +10313,7 @@ static int tg3_test_loopback(struct tg3 *tp)
        if (tg3_run_loopback(tp, TG3_MAC_LOOPBACK))
                err |= TG3_MAC_LOOPBACK_FAILED;
 
-       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) {
+       if (tp->tg3_flags & TG3_FLAG_CPMU_PRESENT) {
                tw32(TG3_CPMU_CTRL, cpmuctrl);
 
                /* Release the mutex */
@@ -10945,6 +10932,102 @@ static void __devinit tg3_get_5906_nvram_info(struct tg3 *tp)
        tp->nvram_pagesize = ATMEL_AT24C512_CHIP_SIZE;
 }
 
+static void __devinit tg3_get_57780_nvram_info(struct tg3 *tp)
+{
+       u32 nvcfg1;
+
+       nvcfg1 = tr32(NVRAM_CFG1);
+
+       switch (nvcfg1 & NVRAM_CFG1_5752VENDOR_MASK) {
+       case FLASH_5787VENDOR_ATMEL_EEPROM_376KHZ:
+       case FLASH_5787VENDOR_MICRO_EEPROM_376KHZ:
+               tp->nvram_jedecnum = JEDEC_ATMEL;
+               tp->tg3_flags |= TG3_FLAG_NVRAM_BUFFERED;
+               tp->nvram_pagesize = ATMEL_AT24C512_CHIP_SIZE;
+
+               nvcfg1 &= ~NVRAM_CFG1_COMPAT_BYPASS;
+               tw32(NVRAM_CFG1, nvcfg1);
+               return;
+       case FLASH_5752VENDOR_ATMEL_FLASH_BUFFERED:
+       case FLASH_57780VENDOR_ATMEL_AT45DB011D:
+       case FLASH_57780VENDOR_ATMEL_AT45DB011B:
+       case FLASH_57780VENDOR_ATMEL_AT45DB021D:
+       case FLASH_57780VENDOR_ATMEL_AT45DB021B:
+       case FLASH_57780VENDOR_ATMEL_AT45DB041D:
+       case FLASH_57780VENDOR_ATMEL_AT45DB041B:
+               tp->nvram_jedecnum = JEDEC_ATMEL;
+               tp->tg3_flags |= TG3_FLAG_NVRAM_BUFFERED;
+               tp->tg3_flags2 |= TG3_FLG2_FLASH;
+
+               switch (nvcfg1 & NVRAM_CFG1_5752VENDOR_MASK) {
+               case FLASH_5752VENDOR_ATMEL_FLASH_BUFFERED:
+               case FLASH_57780VENDOR_ATMEL_AT45DB011D:
+               case FLASH_57780VENDOR_ATMEL_AT45DB011B:
+                       tp->nvram_size = TG3_NVRAM_SIZE_128KB;
+                       break;
+               case FLASH_57780VENDOR_ATMEL_AT45DB021D:
+               case FLASH_57780VENDOR_ATMEL_AT45DB021B:
+                       tp->nvram_size = TG3_NVRAM_SIZE_256KB;
+                       break;
+               case FLASH_57780VENDOR_ATMEL_AT45DB041D:
+               case FLASH_57780VENDOR_ATMEL_AT45DB041B:
+                       tp->nvram_size = TG3_NVRAM_SIZE_512KB;
+                       break;
+               }
+               break;
+       case FLASH_5752VENDOR_ST_M45PE10:
+       case FLASH_5752VENDOR_ST_M45PE20:
+       case FLASH_5752VENDOR_ST_M45PE40:
+               tp->nvram_jedecnum = JEDEC_ST;
+               tp->tg3_flags |= TG3_FLAG_NVRAM_BUFFERED;
+               tp->tg3_flags2 |= TG3_FLG2_FLASH;
+
+               switch (nvcfg1 & NVRAM_CFG1_5752VENDOR_MASK) {
+               case FLASH_5752VENDOR_ST_M45PE10:
+                       tp->nvram_size = TG3_NVRAM_SIZE_128KB;
+                       break;
+               case FLASH_5752VENDOR_ST_M45PE20:
+                       tp->nvram_size = TG3_NVRAM_SIZE_256KB;
+                       break;
+               case FLASH_5752VENDOR_ST_M45PE40:
+                       tp->nvram_size = TG3_NVRAM_SIZE_512KB;
+                       break;
+               }
+               break;
+       default:
+               return;
+       }
+
+       switch (nvcfg1 & NVRAM_CFG1_5752PAGE_SIZE_MASK) {
+       case FLASH_5752PAGE_SIZE_256:
+               tp->tg3_flags3 |= TG3_FLG3_NO_NVRAM_ADDR_TRANS;
+               tp->nvram_pagesize = 256;
+               break;
+       case FLASH_5752PAGE_SIZE_512:
+               tp->tg3_flags3 |= TG3_FLG3_NO_NVRAM_ADDR_TRANS;
+               tp->nvram_pagesize = 512;
+               break;
+       case FLASH_5752PAGE_SIZE_1K:
+               tp->tg3_flags3 |= TG3_FLG3_NO_NVRAM_ADDR_TRANS;
+               tp->nvram_pagesize = 1024;
+               break;
+       case FLASH_5752PAGE_SIZE_2K:
+               tp->tg3_flags3 |= TG3_FLG3_NO_NVRAM_ADDR_TRANS;
+               tp->nvram_pagesize = 2048;
+               break;
+       case FLASH_5752PAGE_SIZE_4K:
+               tp->tg3_flags3 |= TG3_FLG3_NO_NVRAM_ADDR_TRANS;
+               tp->nvram_pagesize = 4096;
+               break;
+       case FLASH_5752PAGE_SIZE_264:
+               tp->nvram_pagesize = 264;
+               break;
+       case FLASH_5752PAGE_SIZE_528:
+               tp->nvram_pagesize = 528;
+               break;
+       }
+}
+
 /* Chips other than 5700/5701 use the NVRAM for fetching info. */
 static void __devinit tg3_nvram_init(struct tg3 *tp)
 {
@@ -10985,6 +11068,8 @@ static void __devinit tg3_nvram_init(struct tg3 *tp)
                        tg3_get_5761_nvram_info(tp);
                else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906)
                        tg3_get_5906_nvram_info(tp);
+               else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57780)
+                       tg3_get_57780_nvram_info(tp);
                else
                        tg3_get_nvram_info(tp);
 
@@ -11305,12 +11390,8 @@ static int tg3_nvram_write_block_buffered(struct tg3 *tp, u32 offset, u32 len,
                if (i == (len - 4))
                        nvram_cmd |= NVRAM_CMD_LAST;
 
-               if ((GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5752) &&
-                   (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) &&
+               if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5752 &&
+                   !(tp->tg3_flags3 & TG3_FLG3_5755_PLUS) &&
                    (tp->nvram_jedecnum == JEDEC_ST) &&
                    (nvram_cmd & NVRAM_CMD_FIRST)) {
 
@@ -11631,8 +11712,8 @@ static void __devinit tg3_get_eeprom_hw_cfg(struct tg3 *tp)
                if (cfg2 & (1 << 18))
                        tp->tg3_flags2 |= TG3_FLG2_SERDES_PREEMPHASIS;
 
-               if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5784 &&
-                   GET_CHIP_REV(tp->pci_chip_rev_id) != CHIPREV_5784_AX &&
+               if (((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5784 &&
+                     GET_CHIP_REV(tp->pci_chip_rev_id) != CHIPREV_5784_AX)) &&
                    (cfg2 & NIC_SRAM_DATA_CFG_2_APD_EN))
                        tp->tg3_flags3 |= TG3_FLG3_PHY_ENABLE_APD;
 
@@ -11951,6 +12032,51 @@ static int __devinit tg3_fw_img_is_valid(struct tg3 *tp, u32 offset)
        return 1;
 }
 
+static void __devinit tg3_read_sb_ver(struct tg3 *tp, u32 val)
+{
+       u32 offset, major, minor, build;
+
+       tp->fw_ver[0] = 's';
+       tp->fw_ver[1] = 'b';
+       tp->fw_ver[2] = '\0';
+
+       if ((val & TG3_EEPROM_SB_FORMAT_MASK) != TG3_EEPROM_SB_FORMAT_1)
+               return;
+
+       switch (val & TG3_EEPROM_SB_REVISION_MASK) {
+       case TG3_EEPROM_SB_REVISION_0:
+               offset = TG3_EEPROM_SB_F1R0_EDH_OFF;
+               break;
+       case TG3_EEPROM_SB_REVISION_2:
+               offset = TG3_EEPROM_SB_F1R2_EDH_OFF;
+               break;
+       case TG3_EEPROM_SB_REVISION_3:
+               offset = TG3_EEPROM_SB_F1R3_EDH_OFF;
+               break;
+       default:
+               return;
+       }
+
+       if (tg3_nvram_read_swab(tp, offset, &val))
+               return;
+
+       build = (val & TG3_EEPROM_SB_EDH_BLD_MASK) >>
+               TG3_EEPROM_SB_EDH_BLD_SHFT;
+       major = (val & TG3_EEPROM_SB_EDH_MAJ_MASK) >>
+               TG3_EEPROM_SB_EDH_MAJ_SHFT;
+       minor =  val & TG3_EEPROM_SB_EDH_MIN_MASK;
+
+       if (minor > 99 || build > 26)
+               return;
+
+       snprintf(&tp->fw_ver[2], 30, " v%d.%02d", major, minor);
+
+       if (build > 0) {
+               tp->fw_ver[8] = 'a' + build - 1;
+               tp->fw_ver[9] = '\0';
+       }
+}
+
 static void __devinit tg3_read_fw_ver(struct tg3 *tp)
 {
        u32 val, offset, start;
@@ -11960,8 +12086,12 @@ static void __devinit tg3_read_fw_ver(struct tg3 *tp)
        if (tg3_nvram_read_swab(tp, 0, &val))
                return;
 
-       if (val != TG3_EEPROM_MAGIC)
+       if (val != TG3_EEPROM_MAGIC) {
+               if ((val & TG3_EEPROM_MAGIC_FW_MSK) == TG3_EEPROM_MAGIC_FW)
+                       tg3_read_sb_ver(tp, val);
+
                return;
+       }
 
        if (tg3_nvram_read_swab(tp, 0xc, &offset) ||
            tg3_nvram_read_swab(tp, 0x4, &start))
@@ -12082,7 +12212,7 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
 
                pci_read_config_dword(tp->pdev, TG3PCI_PRODID_ASICREV,
                                      &prod_id_asic_rev);
-               tp->pci_chip_rev_id = prod_id_asic_rev & PROD_ID_ASIC_REV_MASK;
+               tp->pci_chip_rev_id = prod_id_asic_rev;
        }
 
        /* Wrong chip ID in 5752 A0. This code can be removed later
@@ -12231,14 +12361,19 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
            (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5714))
                tp->pdev_peer = tg3_find_peer(tp);
 
-       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 ||
+       /* 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_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;
 
@@ -12255,11 +12390,7 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
                     tp->pdev_peer == tp->pdev))
                        tp->tg3_flags &= ~TG3_FLAG_SUPPORT_MSI;
 
-               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 ||
+               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;
                        tp->tg3_flags2 |= TG3_FLG2_1SHOT_MSI;
@@ -12294,7 +12425,8 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
                        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)
+                           GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5761 ||
+                           GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57780)
                                tp->tg3_flags3 |= TG3_FLG3_CLKREQ_BUG;
                }
        } else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5785) {
@@ -12465,7 +12597,8 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
 
        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_5785 ||
+           GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57780)
                tp->tg3_flags |= TG3_FLAG_CPMU_PRESENT;
 
        /* Set up tp->grc_local_ctrl before calling tg3_set_power_state().
@@ -12483,7 +12616,8 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
        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)
+       if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5755 ||
+           GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57780)
                tp->grc_local_ctrl |= GRC_LCLCTRL_GPIO_UART_SEL;
 
        if (tp->pdev->device == PCI_DEVICE_ID_TIGON3_5761) {
@@ -12541,7 +12675,10 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
        if (tp->pci_chip_rev_id == CHIPREV_ID_5704_A0)
                tp->tg3_flags2 |= TG3_FLG2_PHY_5704_A0_BUG;
 
-       if (tp->tg3_flags2 & TG3_FLG2_5705_PLUS) {
+       if ((tp->tg3_flags2 & TG3_FLG2_5705_PLUS) &&
+           GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5906 &&
+           GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5785 &&
+           GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_57780) {
                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 ||
@@ -12551,8 +12688,7 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
                                tp->tg3_flags2 |= TG3_FLG2_PHY_JITTER_BUG;
                        if (tp->pdev->device == PCI_DEVICE_ID_TIGON3_5755M)
                                tp->tg3_flags2 |= TG3_FLG2_PHY_ADJUST_TRIM;
-               } else if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5906 &&
-                          GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5785)
+               } else
                        tp->tg3_flags2 |= TG3_FLG2_PHY_BER_BUG;
        }
 
@@ -12573,7 +12709,8 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
            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)
+       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);
@@ -12658,6 +12795,7 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
             (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 ||
            GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906)
                tp->tg3_flags |= TG3_FLAG_10_100_ONLY;
 
@@ -13465,7 +13603,6 @@ static int __devinit tg3_init_one(struct pci_dev *pdev,
                                  const struct pci_device_id *ent)
 {
        static int tg3_version_printed = 0;
-       resource_size_t tg3reg_len;
        struct net_device *dev;
        struct tg3 *tp;
        int err, pm_cap;
@@ -13482,13 +13619,6 @@ static int __devinit tg3_init_one(struct pci_dev *pdev,
                return err;
        }
 
-       if (!(pci_resource_flags(pdev, BAR_0) & IORESOURCE_MEM)) {
-               printk(KERN_ERR PFX "Cannot find proper PCI device "
-                      "base address, aborting.\n");
-               err = -ENODEV;
-               goto err_out_disable_pdev;
-       }
-
        err = pci_request_regions(pdev, DRV_MODULE_NAME);
        if (err) {
                printk(KERN_ERR PFX "Cannot obtain PCI resources, "
@@ -13557,11 +13687,7 @@ static int __devinit tg3_init_one(struct pci_dev *pdev,
        spin_lock_init(&tp->indirect_lock);
        INIT_WORK(&tp->reset_task, tg3_reset_task);
 
-       dev->mem_start = pci_resource_start(pdev, BAR_0);
-       tg3reg_len = pci_resource_len(pdev, BAR_0);
-       dev->mem_end = dev->mem_start + tg3reg_len;
-
-       tp->regs = ioremap_nocache(dev->mem_start, tg3reg_len);
+       tp->regs = pci_ioremap_bar(pdev, BAR_0);
        if (!tp->regs) {
                printk(KERN_ERR PFX "Cannot map device registers, "
                       "aborting.\n");
@@ -13587,11 +13713,7 @@ static int __devinit tg3_init_one(struct pci_dev *pdev,
                goto err_out_iounmap;
        }
 
-       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 ||
+       if ((tp->tg3_flags3 & TG3_FLG3_5755_PLUS) ||
            GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906)
                dev->netdev_ops = &tg3_netdev_ops;
        else
@@ -13664,7 +13786,8 @@ static int __devinit tg3_init_one(struct pci_dev *pdev,
                if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5761 ||
                    (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5784 &&
                     GET_CHIP_REV(tp->pci_chip_rev_id) != CHIPREV_5784_AX) ||
-                       GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5785)
+                       GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5785 ||
+                   GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57780)
                        dev->features |= NETIF_F_TSO_ECN;
        }
 
@@ -13684,13 +13807,6 @@ static int __devinit tg3_init_one(struct pci_dev *pdev,
        }
 
        if (tp->tg3_flags3 & TG3_FLG3_ENABLE_APE) {
-               if (!(pci_resource_flags(pdev, BAR_2) & IORESOURCE_MEM)) {
-                       printk(KERN_ERR PFX "Cannot find proper PCI device "
-                              "base address for APE, aborting.\n");
-                       err = -ENODEV;
-                       goto err_out_iounmap;
-               }
-
                tp->aperegs = pci_ioremap_bar(pdev, BAR_2);
                if (!tp->aperegs) {
                        printk(KERN_ERR PFX "Cannot map APE registers, "
@@ -13724,11 +13840,7 @@ static int __devinit tg3_init_one(struct pci_dev *pdev,
         */
        if ((tp->tg3_flags & TG3_FLAG_BROKEN_CHECKSUMS) == 0) {
                dev->features |= NETIF_F_IP_CSUM | NETIF_F_SG;
-               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)
+               if (tp->tg3_flags3 & TG3_FLG3_5755_PLUS)
                        dev->features |= NETIF_F_IPV6_CSUM;
 
                tp->tg3_flags |= TG3_FLAG_RX_CHECKSUMS;
@@ -13737,7 +13849,7 @@ static int __devinit tg3_init_one(struct pci_dev *pdev,
 
        /* flow control autonegotiation is default behavior */
        tp->tg3_flags |= TG3_FLAG_PAUSE_AUTONEG;
-       tp->link_config.flowctrl = TG3_FLOW_CTRL_TX | TG3_FLOW_CTRL_RX;
+       tp->link_config.flowctrl = FLOW_CTRL_TX | FLOW_CTRL_RX;
 
        tg3_init_coal(tp);