]> Pileus Git - ~andy/linux/commitdiff
tg3: Add NVRAM support for 5762
authorMichael Chan <mchan@broadcom.com>
Sun, 6 Jan 2013 12:51:08 +0000 (12:51 +0000)
committerDavid S. Miller <davem@davemloft.net>
Mon, 7 Jan 2013 05:02:07 +0000 (21:02 -0800)
Detect NVRAM types for 5762 and read OTP firmware version.

Signed-off-by: Michael Chan <mchan@broadcom.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/broadcom/tg3.c
drivers/net/ethernet/broadcom/tg3.h

index 01e3201427ee729f943a6bcbdebbe149a874c52e..6eab7d7ae4dfab2f3370d1d4317a2e999cacf2e1 100644 (file)
@@ -330,6 +330,9 @@ static DEFINE_PCI_DEVICE_TABLE(tg3_pci_tbl) = {
        {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_5719)},
        {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_5720)},
        {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_57762)},
+       {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_5762)},
+       {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_5725)},
+       {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_5727)},
        {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)},
@@ -13714,6 +13717,20 @@ static void tg3_get_5720_nvram_info(struct tg3 *tp)
        nvcfg1 = tr32(NVRAM_CFG1);
        nvmpinstrp = nvcfg1 & NVRAM_CFG1_5752VENDOR_MASK;
 
+       if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5762) {
+               if (!(nvcfg1 & NVRAM_CFG1_5762VENDOR_MASK)) {
+                       tg3_flag_set(tp, NO_NVRAM);
+                       return;
+               }
+
+               switch (nvmpinstrp) {
+               case FLASH_5762_EEPROM_HD:
+                       nvmpinstrp = FLASH_5720_EEPROM_HD;
+               case FLASH_5762_EEPROM_LD:
+                       nvmpinstrp = FLASH_5720_EEPROM_LD;
+               }
+       }
+
        switch (nvmpinstrp) {
        case FLASH_5720_EEPROM_HD:
        case FLASH_5720_EEPROM_LD:
@@ -13817,6 +13834,17 @@ static void tg3_get_5720_nvram_info(struct tg3 *tp)
        tg3_nvram_get_pagesize(tp, nvcfg1);
        if (tp->nvram_pagesize != 264 && tp->nvram_pagesize != 528)
                tg3_flag_set(tp, NO_NVRAM_ADDR_TRANS);
+
+       if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5762) {
+               u32 val;
+
+               if (tg3_nvram_read(tp, 0, &val))
+                       return;
+
+               if (val != TG3_EEPROM_MAGIC &&
+                   (val & TG3_EEPROM_MAGIC_FW_MSK) != TG3_EEPROM_MAGIC_FW)
+                       tg3_flag_set(tp, NO_NVRAM);
+       }
 }
 
 /* Chips other than 5700/5701 use the NVRAM for fetching info. */
@@ -13866,7 +13894,8 @@ static void tg3_nvram_init(struct tg3 *tp)
                else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 ||
                         GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719)
                        tg3_get_5717_nvram_info(tp);
-               else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5720)
+               else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5720 ||
+                        GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5762)
                        tg3_get_5720_nvram_info(tp);
                else
                        tg3_get_nvram_info(tp);
@@ -14168,6 +14197,39 @@ done:
                device_set_wakeup_capable(&tp->pdev->dev, false);
 }
 
+static int tg3_ape_otp_read(struct tg3 *tp, u32 offset, u32 *val)
+{
+       int i, err;
+       u32 val2, off = offset * 8;
+
+       err = tg3_nvram_lock(tp);
+       if (err)
+               return err;
+
+       tg3_ape_write32(tp, TG3_APE_OTP_ADDR, off | APE_OTP_ADDR_CPU_ENABLE);
+       tg3_ape_write32(tp, TG3_APE_OTP_CTRL, APE_OTP_CTRL_PROG_EN |
+                       APE_OTP_CTRL_CMD_RD | APE_OTP_CTRL_START);
+       tg3_ape_read32(tp, TG3_APE_OTP_CTRL);
+       udelay(10);
+
+       for (i = 0; i < 100; i++) {
+               val2 = tg3_ape_read32(tp, TG3_APE_OTP_STATUS);
+               if (val2 & APE_OTP_STATUS_CMD_DONE) {
+                       *val = tg3_ape_read32(tp, TG3_APE_OTP_RD_DATA);
+                       break;
+               }
+               udelay(10);
+       }
+
+       tg3_ape_write32(tp, TG3_APE_OTP_CTRL, 0);
+
+       tg3_nvram_unlock(tp);
+       if (val2 & APE_OTP_STATUS_CMD_DONE)
+               return 0;
+
+       return -EBUSY;
+}
+
 static int tg3_issue_otp_command(struct tg3 *tp, u32 cmd)
 {
        int i;
@@ -14708,6 +14770,8 @@ static void tg3_read_dash_ver(struct tg3 *tp)
 
        if (tg3_flag(tp, APE_HAS_NCSI))
                fwtype = "NCSI";
+       else if (tp->pdev->device == TG3PCI_DEVICE_TIGON3_5725)
+               fwtype = "SMASH";
        else
                fwtype = "DASH";
 
@@ -14721,6 +14785,31 @@ static void tg3_read_dash_ver(struct tg3 *tp)
                 (apedata & APE_FW_VERSION_BLDMSK));
 }
 
+static void tg3_read_otp_ver(struct tg3 *tp)
+{
+       u32 val, val2;
+
+       if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5762)
+               return;
+
+       if (!tg3_ape_otp_read(tp, OTP_ADDRESS_MAGIC0, &val) &&
+           !tg3_ape_otp_read(tp, OTP_ADDRESS_MAGIC0 + 4, &val2) &&
+           TG3_OTP_MAGIC0_VALID(val)) {
+               u64 val64 = (u64) val << 32 | val2;
+               u32 ver = 0;
+               int i, vlen;
+
+               for (i = 0; i < 7; i++) {
+                       if ((val64 & 0xff) == 0)
+                               break;
+                       ver = val64 & 0xff;
+                       val64 >>= 8;
+               }
+               vlen = strlen(tp->fw_ver);
+               snprintf(&tp->fw_ver[vlen], TG3_VER_SIZE - vlen, " .%02d", ver);
+       }
+}
+
 static void tg3_read_fw_ver(struct tg3 *tp)
 {
        u32 val;
@@ -14731,6 +14820,7 @@ static void tg3_read_fw_ver(struct tg3 *tp)
 
        if (tg3_flag(tp, NO_NVRAM)) {
                strcat(tp->fw_ver, "sb");
+               tg3_read_otp_ver(tp);
                return;
        }
 
@@ -15428,6 +15518,10 @@ static int tg3_get_invariants(struct tg3 *tp, const struct pci_device_id *ent)
                                              GRC_LCLCTRL_GPIO_OUTPUT0;
        }
 
+       if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5762)
+               tp->grc_local_ctrl |=
+                       tr32(GRC_LOCAL_CTRL) & GRC_LCLCTRL_GPIO_UART_SEL;
+
        /* Switch out of Vaux if it is a NIC */
        tg3_pwrsrc_switch_to_vmain(tp);
 
index 46d43f72f8edac8e3d1ba723008f975385827725..39afc0edeaa67f47a394adfed9d74cde69d2e91f 100644 (file)
 #define  FLASH_VENDOR_SST_SMALL                 0x00000001
 #define  FLASH_VENDOR_SST_LARGE                 0x02000001
 #define  NVRAM_CFG1_5752VENDOR_MASK     0x03c00003
+#define  NVRAM_CFG1_5762VENDOR_MASK     0x03e00003
 #define  FLASH_5752VENDOR_ATMEL_EEPROM_64KHZ    0x00000000
 #define  FLASH_5752VENDOR_ATMEL_EEPROM_376KHZ   0x02000000
 #define  FLASH_5752VENDOR_ATMEL_FLASH_BUFFERED  0x02000003
 #define  APE_LOCK_REQ_DRIVER            0x00001000
 #define TG3_APE_LOCK_GRANT             0x004c
 #define  APE_LOCK_GRANT_DRIVER          0x00001000
+#define TG3_APE_OTP_CTRL               0x00e8
+#define  APE_OTP_CTRL_PROG_EN           0x200000
+#define  APE_OTP_CTRL_CMD_RD            0x000000
+#define  APE_OTP_CTRL_START             0x000001
+#define TG3_APE_OTP_STATUS             0x00ec
+#define  APE_OTP_STATUS_CMD_DONE        0x000001
+#define TG3_APE_OTP_ADDR               0x00f0
+#define  APE_OTP_ADDR_CPU_ENABLE        0x80000000
+#define TG3_APE_OTP_RD_DATA            0x00f8
+
+#define OTP_ADDRESS_MAGIC0              0x00000050
+#define TG3_OTP_MAGIC0_VALID(val)              \
+       ((((val) & 0xf0000000) == 0xa0000000) ||\
+        (((val) & 0x0f000000) == 0x0a000000))
 
 /* APE shared memory.  Accessible through BAR1 */
 #define TG3_APE_SHMEM_BASE             0x4000