Staging: sxg: Add Rev B support in the Sahara SXG driver
authorMithlesh Thukral <mithlesh@linsyssoft.com>
Wed, 18 Feb 2009 13:24:14 +0000 (18:54 +0530)
committerGreg Kroah-Hartman <gregkh@suse.de>
Fri, 3 Apr 2009 21:53:12 +0000 (14:53 -0700)
This patch makes the Sahara SXG driver use Rev B firmware instead of Rev A.
The firmware version is 1.71

Signed-off-by: Michael Miles <mmiles@alacritech.com>
Signed-off-by: Mithlesh Thukral <mithlesh@linsyssoft.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
drivers/staging/sxg/sxg.c
drivers/staging/sxg/sxg.h
drivers/staging/sxg/sxghif.h
drivers/staging/sxg/sxghw.h

index 9ce3af5..09ff800 100644 (file)
 #include "sxg.h"
 #include "sxgdbg.h"
 
-#include "sxgphycode.h"
+#include "sxgphycode-1.2.h"
 #define SXG_UCODE_DBG                  0       /* Turn on for debugging */
 #ifdef SXG_UCODE_DBG
-#include "saharadbgdownload.c"
-#include "saharadbgdownloadB.c"
+#include "saharadbgdownload-1.71.c"
+#include "saharadbgdownloadB-1.10.c"
 #else
-#include "saharadownload.c"
-#include "saharadownloadB.c"
+#include "saharadownload-1.55.c"
+#include "saharadownloadB-1.8.c"
 #endif
 
 static int sxg_allocate_buffer_memory(struct adapter_t *adapter, u32 Size,
@@ -410,22 +410,42 @@ static bool sxg_download_microcode(struct adapter_t *adapter,
        DBG_ERROR("sxg: %s ENTER\n", __func__);
 
        switch (UcodeSel) {
-       case SXG_UCODE_SAHARA:  /* Sahara operational ucode */
-               numSections = SNumSections;
-               for (i = 0; i < numSections; i++) {
-                       sectionSize[i] = SSectionSize[i];
-                       sectionStart[i] = SSectionStart[i];
-               }
-               break;
-       default:
-               printk(KERN_ERR KBUILD_MODNAME
-                      ": Woah, big error with the microcode!\n");
-               break;
+               case SXG_UCODE_SYSTEM:      // System (operational) ucode
+                       switch (adapter->asictype) {
+                               case SAHARA_REV_A:
+                                       DBG_ERROR("%s SAHARA CARD REVISION A\n",
+                                                __func__);
+                                       numSections = SNumSections;
+                                       for (i = 0; i < numSections; i++) {
+                                               sectionSize[i] =
+                                                       SSectionSize[i];
+                                               sectionStart[i] =
+                                                       SSectionStart[i];
+                                       }
+                                       break;
+                               case SAHARA_REV_B:
+                                       DBG_ERROR("%s SAHARA CARD REVISION B\n",
+                                                __func__);
+                                       numSections = SBNumSections;
+                                       for (i = 0; i < numSections; i++) {
+                                               sectionSize[i] =
+                                                       SBSectionSize[i];
+                                               sectionStart[i] =
+                                                       SBSectionStart[i];
+                                       }
+                                       break;
+                       }
+                       break;
+               default:
+                       printk(KERN_ERR KBUILD_MODNAME
+                               ": Woah, big error with the microcode!\n");
+                       break;
        }
 
        DBG_ERROR("sxg: RESET THE CARD\n");
        /* First, reset the card */
        WRITE_REG(HwRegs->Reset, 0xDEAD, FLUSH);
+       udelay(50);
 
        /*
         * Download each section of the microcode as specified in
@@ -436,13 +456,21 @@ static bool sxg_download_microcode(struct adapter_t *adapter,
        for (Section = 0; Section < numSections; Section++) {
                DBG_ERROR("sxg: SECTION # %d\n", Section);
                switch (UcodeSel) {
-               case SXG_UCODE_SAHARA:
-                       Instruction = (u32 *) & SaharaUCode[Section][0];
+               case SXG_UCODE_SYSTEM:
+                       switch (adapter->asictype) {
+                               case SAHARA_REV_A:
+                                       Instruction = (u32 *) & SaharaUCode[Section][0];
+                                       break;
+                               case SAHARA_REV_B:
+                                       Instruction = (u32 *) & SaharaUCodeB[Section][0];
+                                       break;
+                       }
                        break;
                default:
                        ASSERT(0);
                        break;
                }
+
                BaseAddress = sectionStart[Section];
                /* Size in instructions */
                ThisSectionSize = sectionSize[Section] / 12;
@@ -481,12 +509,21 @@ static bool sxg_download_microcode(struct adapter_t *adapter,
        for (Section = 0; Section < numSections; Section++) {
                DBG_ERROR("sxg: check SECTION # %d\n", Section);
                switch (UcodeSel) {
-               case SXG_UCODE_SAHARA:
-                       Instruction = (u32 *) & SaharaUCode[Section][0];
-                       break;
-               default:
-                       ASSERT(0);
-                       break;
+                       case SXG_UCODE_SYSTEM:
+                               switch (adapter->asictype) {
+                                       case SAHARA_REV_A:
+                                               Instruction = (u32 *) &
+                                                   SaharaUCode[Section][0];
+                                               break;
+                                       case SAHARA_REV_B:
+                                               Instruction = (u32 *) &
+                                                   SaharaUCodeB[Section][0];
+                                               break;
+                               }
+                               break;
+                       default:
+                               ASSERT(0);
+                               break;
                }
                BaseAddress = sectionStart[Section];
                /* Size in instructions */
@@ -555,7 +592,7 @@ static bool sxg_download_microcode(struct adapter_t *adapter,
         * synchronize with the card so it can scribble on the memory
         * that contained 0xCAFE from the "CardUp" step above
         */
-       if (UcodeSel == SXG_UCODE_SAHARA) {
+       if (UcodeSel == SXG_UCODE_SYSTEM) {
                WRITE_REG(adapter->UcodeRegs[0].LoadSync, 0, FLUSH);
        }
 
@@ -891,6 +928,7 @@ static int sxg_entry_probe(struct pci_dev *pcidev,
        u32 status = 0;
        ulong mmio_start = 0;
        ulong mmio_len = 0;
+       unsigned char revision_id;
 
        DBG_ERROR("sxg: %s 2.6 VERSION ENTER jiffies[%lx] cpu %d\n",
                  __func__, jiffies, smp_processor_id());
@@ -915,6 +953,8 @@ static int sxg_entry_probe(struct pci_dev *pcidev,
                printk(KERN_INFO "%s\n", SXG_DRV_VERSION);
        }
 
+       pci_read_config_byte(pcidev, PCI_REVISION_ID, &revision_id);
+
        if (!(err = pci_set_dma_mask(pcidev, DMA_64BIT_MASK))) {
                DBG_ERROR("pci_set_dma_mask(DMA_64BIT_MASK) successful\n");
        } else {
@@ -950,6 +990,15 @@ static int sxg_entry_probe(struct pci_dev *pcidev,
 
        pci_set_drvdata(pcidev, netdev);
        adapter = netdev_priv(netdev);
+       if (revision_id == 1) {
+               adapter->asictype = SAHARA_REV_A;
+       } else if (revision_id == 2) {
+               adapter->asictype = SAHARA_REV_B;
+       } else {
+               ASSERT(0);
+               DBG_ERROR("%s Unexpected revision ID %x\n", __FUNCTION__, revision_id);
+               goto err_out_exit_sxg_probe;
+       }
        adapter->netdev = netdev;
        adapter->pcidev = pcidev;
 
@@ -1054,7 +1103,7 @@ static int sxg_entry_probe(struct pci_dev *pcidev,
        }
 
        DBG_ERROR("sxg: %s ENTER sxg_download_microcode\n", __func__);
-       if (sxg_download_microcode(adapter, SXG_UCODE_SAHARA)) {
+       if (sxg_download_microcode(adapter, SXG_UCODE_SYSTEM)) {
                DBG_ERROR("sxg: %s ENTER sxg_adapter_set_hwaddr\n",
                          __func__);
                sxg_read_config(adapter);
@@ -1762,9 +1811,6 @@ static struct sk_buff *sxg_slow_receive(struct adapter_t *adapter,
        if (Event->Status & EVENT_STATUS_RCVERR) {
                SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "RcvError",
                          Event, Event->Status, Event->HostHandle, 0);
-               /* XXXTODO - Remove this print later */
-               DBG_ERROR("SXG: Receive error %x\n", *(u32 *)
-                         SXG_RECEIVE_DATA_LOCATION(RcvDataBufferHdr));
                sxg_process_rcv_error(adapter, *(u32 *)
                                      SXG_RECEIVE_DATA_LOCATION
                                      (RcvDataBufferHdr));
@@ -2144,7 +2190,7 @@ static int sxg_entry_open(struct net_device *dev)
         * The microcode expects it to be downloaded on every open.
         */
        DBG_ERROR("sxg: %s ENTER sxg_download_microcode\n", __FUNCTION__);
-       if (sxg_download_microcode(adapter, SXG_UCODE_SAHARA)) {
+       if (sxg_download_microcode(adapter, SXG_UCODE_SYSTEM)) {
                DBG_ERROR("sxg: %s ENTER sxg_adapter_set_hwaddr\n",
                                __FUNCTION__);
                sxg_read_config(adapter);
@@ -2639,7 +2685,8 @@ static int sxg_dumb_sgl(struct sxg_x64_sgl *pSgl,
         * the start of the next 64k boundary and continue
         */
 
-       if (SXG_INVALID_SGL(phys_addr,skb->data_len))
+       if ((adapter->asictype == SAHARA_REV_A) &&
+               (SXG_INVALID_SGL(phys_addr,skb->data_len)))
        {
                spin_unlock_irqrestore(&adapter->XmtZeroLock, flags);
                /* Silently drop this packet */
@@ -2725,6 +2772,7 @@ static int sxg_initialize_link(struct adapter_t *adapter)
        u32 Value;
        u32 ConfigData;
        u32 MaxFrame;
+       u32 AxgMacReg1;
        int status;
 
        SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "InitLink",
@@ -2771,24 +2819,27 @@ static int sxg_initialize_link(struct adapter_t *adapter)
        WRITE_REG(HwRegs->MacConfig0, 0, TRUE);
 
        /* Configure MAC */
-       WRITE_REG(HwRegs->MacConfig1, (
-                                       /* Allow sending of pause */
-                                       AXGMAC_CFG1_XMT_PAUSE |
-                                       /* Enable XMT */
-                                       AXGMAC_CFG1_XMT_EN |
-                                       /* Enable detection of pause */
-                                       AXGMAC_CFG1_RCV_PAUSE |
-                                       /* Enable receive */
-                                       AXGMAC_CFG1_RCV_EN |
-                                       /* short frame detection */
-                                       AXGMAC_CFG1_SHORT_ASSERT |
-                                       /* Verify frame length */
-                                       AXGMAC_CFG1_CHECK_LEN |
-                                       /* Generate FCS */
-                                       AXGMAC_CFG1_GEN_FCS |
-                                       /* Pad frames to 64 bytes */
-                                       AXGMAC_CFG1_PAD_64),
-                                 TRUE);
+       AxgMacReg1 = (  /* Enable XMT */
+                       AXGMAC_CFG1_XMT_EN |
+                       /* Enable receive */
+                       AXGMAC_CFG1_RCV_EN |
+                       /* short frame detection */
+                       AXGMAC_CFG1_SHORT_ASSERT |
+                       /* Verify frame length */
+                       AXGMAC_CFG1_CHECK_LEN |
+                       /* Generate FCS */
+                       AXGMAC_CFG1_GEN_FCS |
+                       /* Pad frames to 64 bytes */
+                       AXGMAC_CFG1_PAD_64);
+
+       if (adapter->XmtFcEnabled) {
+               AxgMacReg1 |=  AXGMAC_CFG1_XMT_PAUSE;  /* Allow sending of pause */
+       }
+       if (adapter->RcvFcEnabled) {
+               AxgMacReg1 |=  AXGMAC_CFG1_RCV_PAUSE;  /* Enable detection of pause */
+       }
+
+       WRITE_REG(HwRegs->MacConfig1, AxgMacReg1, TRUE);
 
        /* Set AXGMAC max frame length if jumbo.  Not needed for standard MTU */
        if (adapter->JumboEnabled) {
@@ -2806,13 +2857,20 @@ static int sxg_initialize_link(struct adapter_t *adapter)
         * This value happens to be the default value for this register, so we
         * really don't have to do this.
         */
-       WRITE_REG(HwRegs->MacAmiimConfig, 0x0000003E, TRUE);
+       if (adapter->asictype == SAHARA_REV_B) {
+               WRITE_REG(HwRegs->MacAmiimConfig, 0x0000001F, TRUE);
+       } else {
+               WRITE_REG(HwRegs->MacAmiimConfig, 0x0000003E, TRUE);
+       }
 
        /* Power up and enable PHY and XAUI/XGXS/Serdes logic */
        WRITE_REG(HwRegs->LinkStatus,
-                 (LS_PHY_CLR_RESET |
-                  LS_XGXS_ENABLE |
-                  LS_XGXS_CTL | LS_PHY_CLK_EN | LS_ATTN_ALARM), TRUE);
+                  (LS_PHY_CLR_RESET |
+                   LS_XGXS_ENABLE |
+                   LS_XGXS_CTL |
+                   LS_PHY_CLK_EN |
+                   LS_ATTN_ALARM),
+                   TRUE);
        DBG_ERROR("After Power Up and enable PHY in sxg_initialize_link\n");
 
        /*
@@ -2886,6 +2944,11 @@ static int sxg_initialize_link(struct adapter_t *adapter)
                      RCV_CONFIG_TZIPV4 |
                      RCV_CONFIG_HASH_16 |
                      RCV_CONFIG_SOCKET | RCV_CONFIG_BUFSIZE(MaxFrame));
+
+       if (adapter->asictype == SAHARA_REV_B) {
+               ConfigData |= (RCV_CONFIG_HIPRICTL  |
+                               RCV_CONFIG_NEWSTATUSFMT);
+       }
        WRITE_REG(HwRegs->RcvConfig, ConfigData, TRUE);
 
        WRITE_REG(HwRegs->XmtConfig, XMT_CONFIG_ENABLE, TRUE);
@@ -2994,7 +3057,16 @@ static void sxg_link_event(struct adapter_t *adapter)
                        sxg_link_state(adapter, SXG_LINK_DOWN);
                /* ASSERT(0); */
                }
-               ASSERT(Value & LASI_STATUS_LS_ALARM);
+               /*
+                * We used to assert that the LASI_LS_ALARM bit was set, as
+                * it should be.  But there appears to be cases during
+                * initialization (when the PHY is reset and re-initialized)
+                * when we get a link alarm, but the status bit is 0 when we
+                * read it.  Rather than trying to assure this never happens
+                * (and nver being certain), just ignore it.
+
+                * ASSERT(Value & LASI_STATUS_LS_ALARM);
+                */
 
                /* Now get and set the link state */
                LinkState = sxg_get_link_state(adapter);
@@ -4118,6 +4190,9 @@ static int sxg_initialize_adapter(struct adapter_t *adapter)
         */
        adapter->Dead = FALSE;
        adapter->PingOutstanding = FALSE;
+       adapter->XmtFcEnabled = TRUE;
+       adapter->RcvFcEnabled = TRUE;
+
        adapter->State = SXG_STATE_RUNNING;
 
        SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "XInit",
index 7bf0a43..899cf15 100644 (file)
@@ -369,9 +369,9 @@ enum SXG_LINK_STATE {
 
 /* Microcode file selection codes */
 enum SXG_UCODE_SEL {
-       SXG_UCODE_SAHARA,       /* Sahara ucode */
-       SXG_UCODE_SDIAGCPU,     /* Sahara CPU diagnostic ucode */
-       SXG_UCODE_SDIAGSYS      /* Sahara system diagnostic ucode */
+       SXG_UCODE_SYSTEM,       /* System (operational) uucode */
+       SXG_UCODE_SDIAGCPU,     /* System CPU diagnostic ucode */
+       SXG_UCODE_SDIAGSYS      /* System diagnostic ucode */
 };
 
 
@@ -537,6 +537,7 @@ struct adapter_t {
        u32             memorylength;
        u32             drambase;
        u32             dramlength;
+       enum asic_type  asictype;      /* type of ASIC (chip) */
        unsigned int                activated;
        u32             intrregistered;
        unsigned int                isp_initialized;
@@ -680,6 +681,8 @@ struct adapter_t {
        u32             RssEnabled:1;           /* RSS Enabled */
        u32             FailOnBadEeprom:1;      /* Fail on Bad Eeprom */
        u32             DiagStart:1;            /* Init adapter for diagnostic start */
+       u32             XmtFcEnabled:1;
+       u32             RcvFcEnabled:1;
        /* Stats */
        u32             PendingRcvCount;        /* Outstanding rcv indications */
        u32             PendingXmtCount;        /* Outstanding send requests */
index 2b0f080..e190d6a 100644 (file)
@@ -150,13 +150,16 @@ struct sxg_ucode_regs {
 /* Disable interrupt aggregation on xmt */
 #define SXG_AGG_XMT_DISABLE    0x80000000
 
-/* The Microcode supports up to 8 RSS queues */
-#define SXG_MAX_RSS                            8
+/* The Microcode supports up to 16 RSS queues (RevB) */
+#define SXG_MAX_RSS                    16
+#define SXG_MAX_RSS_REVA               8
 
 #define SXG_MAX_RSS_TABLE_SIZE 256             /* 256-byte max */
 
-#define SXG_RSS_TCP6           0x00000001      /* RSS TCP over IPv6 */
-#define SXG_RSS_TCP4           0x00000002      /* RSS TCP over IPv4 */
+#define SXG_RSS_REVA_TCP6      0x00000001      /* RSS TCP over IPv6 */
+#define SXG_RSS_REVA_TCP4      0x00000002      /* RSS TCP over IPv4 */
+#define SXG_RSS_IP             0x00000001      /* RSS TCP over IPv6 */
+#define SXG_RSS_TCP            0x00000002      /* RSS TCP over IPv4 */
 #define SXG_RSS_LEGACY         0x00000004      /* Line-base interrupts */
 #define SXG_RSS_TABLE_SIZE     0x0000FF00      /* Table size mask */
 
index cf26d71..f59a86a 100644 (file)
 /*  PCI Device ID */
 #define SXG_DEVICE_ID                  0x0009  /* Sahara Device ID */
 
+
+/* Type of ASIC in use */
+enum asic_type {
+       SAHARA_REV_A,
+       SAHARA_REV_B
+};
+
+/* Type of Xcvr in fiber card */
+enum xcvr_type {
+       XCVR_UNKNOWN,
+       XCVR_NONE,
+       XCVR_SR,
+       XCVR_LR,
+       XCVR_LRM,
+       XCVR_CR
+};
 /*
  * Subsystem IDs.
  *
@@ -265,9 +281,11 @@ struct sxg_hw_regs {
 #define        RCV_CONFIG_HASH_4               0x00020000 /* Hash depth 4 */
 #define        RCV_CONFIG_HASH_2               0x00030000 /* Hash depth 2 */
 /* Buffer length bits 15:4. ie multiple of 16. */
-#define        RCV_CONFIG_BUFLEN_MASK          0x0000FFF0
+#define        RCV_CONFIG_BUFLEN_MASK          0x0000FFE0
 /* Disable socket detection on attn */
 #define RCV_CONFIG_SKT_DIS             0x00000008
+#define RCV_CONFIG_HIPRICTL     0x00000002 /* Ctrl frames on high-prioirty RcvQ */
+#define RCV_CONFIG_NEWSTATUSFMT 0x00000001 /* Use RevB status format */
 /*
  * Macro to determine RCV_CONFIG_BUFLEN based on maximum frame size.
  * We add 18 bytes for Sahara receive status and padding, plus 4 bytes for CRC,
@@ -640,6 +658,9 @@ struct sxg_hw_regs {
 /* PHY_XS_LANE_STATUS register bit definitions */
 #define        XS_LANE_ALIGN           0x1000          /* XS transmit lanes aligned */
 
+#define XCVR_VENDOR_LEN                16  /* xcvr vendor len */
+#define XCVR_MODEL_LEN         16  /* xcvr model len */
+
 /* PHY Microcode download data structure */
 struct phy_ucode {
        ushort  Addr;
@@ -970,6 +991,10 @@ struct adapt_userinfo {
        /* u32              LinkState; */
        u32                 LinkSpeed;          /* not currently needed */
        u32                 LinkDuplex;         /* not currently needed */
+       enum xcvr_type      XcvrType;           /* type of xcvr on fiber card */
+       /* fiber card xcvr vendor */
+       unsigned char           XcvrVendor[XCVR_VENDOR_LEN];
+       unsigned char           XcvrMode[XCVR_MODEL_LEN];
        u32                 Port;               /* not currently needed */
        u32                 PhysPort;           /* not currently needed */
        ushort              PciLanes;
@@ -984,11 +1009,7 @@ struct adapt_userinfo {
 
 /* Miscellaneous Hardware definitions */
 
-/* Type of ASIC in use */
-enum ASIC_TYPE{
-       SAHARA_REV_A,
-       SAHARA_REV_B
-};
+/* Hardware Type definitions  */
 
 /* Sahara (ASIC level) defines */
 #define SAHARA_GRAM_SIZE       0x020000        /* GRAM size - 128 KB */