From mithlesh@linsyssoft.com Wed Feb 18 15:53:45 2009 From: Mithlesh Thukral Date: Wed, 18 Feb 2009 18:54:14 +0530 (IST) Subject: Staging: sxg: Add Rev B support in the Sahara SXG driver To: Greg Kroah-Hartman Cc: Sahara Project , Christopher Harrer Message-ID: From: Mithlesh Thukral 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 Signed-off-by: Mithlesh Thukral Signed-off-by: Greg Kroah-Hartman --- drivers/staging/sxg/sxg.c | 183 ++++++++++++++++++++++++++++++------------- drivers/staging/sxg/sxg.h | 9 +- drivers/staging/sxg/sxghif.h | 11 +- drivers/staging/sxg/sxghw.h | 33 ++++++- 4 files changed, 169 insertions(+), 67 deletions(-) --- a/drivers/staging/sxg/sxg.c +++ b/drivers/staging/sxg/sxg.c @@ -81,14 +81,14 @@ #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(struc 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(struc 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(struc 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(struc * 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_de 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_de 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_de 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_de } 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( 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_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_s * 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 ad 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 ad 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 ad * 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 ad 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 adapte 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->Dead = FALSE; adapter->PingOutstanding = FALSE; + adapter->XmtFcEnabled = TRUE; + adapter->RcvFcEnabled = TRUE; + adapter->State = SXG_STATE_RUNNING; SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "XInit", --- a/drivers/staging/sxg/sxg.h +++ b/drivers/staging/sxg/sxg.h @@ -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 */ --- a/drivers/staging/sxg/sxghif.h +++ b/drivers/staging/sxg/sxghif.h @@ -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 */ --- a/drivers/staging/sxg/sxghw.h +++ b/drivers/staging/sxg/sxghw.h @@ -18,6 +18,22 @@ /* 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 */