Commit cda3b517 authored by Mithlesh Thukral's avatar Mithlesh Thukral Committed by Greg Kroah-Hartman

Staging: sxg: Add support to download the firmware using request_firmware()

Add support for downloading the firmware using kernel-builtin mechanism.
This will remove the need for the firmware files in the driver source code.
Signed-off-by: default avatarChristopher Harrer <charrer@alacritech.com>
Signed-off-by: default avatarMithlesh Thukral <mithlesh@linsyssoft.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
parent e5ea8da0
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
...@@ -48,6 +48,7 @@ ...@@ -48,6 +48,7 @@
#include <linux/errno.h> #include <linux/errno.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/moduleparam.h> #include <linux/moduleparam.h>
#include <linux/firmware.h>
#include <linux/ioport.h> #include <linux/ioport.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
...@@ -74,22 +75,15 @@ ...@@ -74,22 +75,15 @@
#define SXG_POWER_MANAGEMENT_ENABLED 0 #define SXG_POWER_MANAGEMENT_ENABLED 0
#define VPCI 0 #define VPCI 0
#define ATK_DEBUG 1 #define ATK_DEBUG 1
#define SXG_UCODE_DEBUG 0
#include "sxg_os.h" #include "sxg_os.h"
#include "sxghw.h" #include "sxghw.h"
#include "sxghif.h" #include "sxghif.h"
#include "sxg.h" #include "sxg.h"
#include "sxgdbg.h" #include "sxgdbg.h"
#include "sxgphycode-1.2.h" #include "sxgphycode-1.2.h"
#define SXG_UCODE_DBG 0 /* Turn on for debugging */
#ifdef SXG_UCODE_DBG
#include "saharadbgdownload-1.71.c"
#include "saharadbgdownloadB-1.10.c"
#else
#include "saharadownload-1.55.c"
#include "saharadownloadB-1.8.c"
#endif
static int sxg_allocate_buffer_memory(struct adapter_t *adapter, u32 Size, static int sxg_allocate_buffer_memory(struct adapter_t *adapter, u32 Size,
enum sxg_buffer_type BufferType); enum sxg_buffer_type BufferType);
...@@ -384,7 +378,8 @@ void sxg_reset_interrupt_capability(struct adapter_t *adapter) ...@@ -384,7 +378,8 @@ void sxg_reset_interrupt_capability(struct adapter_t *adapter)
/* /*
* sxg_download_microcode * sxg_download_microcode
* *
* Download Microcode to Sahara adapter * Download Microcode to Sahara adapter using the Linux
* Firmware module to get the ucode.sys file.
* *
* Arguments - * Arguments -
* adapter - A pointer to our adapter structure * adapter - A pointer to our adapter structure
...@@ -396,99 +391,114 @@ void sxg_reset_interrupt_capability(struct adapter_t *adapter) ...@@ -396,99 +391,114 @@ void sxg_reset_interrupt_capability(struct adapter_t *adapter)
static bool sxg_download_microcode(struct adapter_t *adapter, static bool sxg_download_microcode(struct adapter_t *adapter,
enum SXG_UCODE_SEL UcodeSel) enum SXG_UCODE_SEL UcodeSel)
{ {
const struct firmware *fw;
const char *file = "";
struct sxg_hw_regs *HwRegs = adapter->HwRegs; struct sxg_hw_regs *HwRegs = adapter->HwRegs;
int ret;
int ucode_start;
u32 Section; u32 Section;
u32 ThisSectionSize; u32 ThisSectionSize;
u32 *Instruction = NULL; u32 instruction = 0;
u32 BaseAddress, AddressOffset, Address; u32 BaseAddress, AddressOffset, Address;
/* u32 Failure; */ /* u32 Failure; */
u32 ValueRead; u32 ValueRead;
u32 i; u32 i;
u32 numSections = 0; u32 index = 0;
u32 num_sections = 0;
u32 sectionSize[16]; u32 sectionSize[16];
u32 sectionStart[16]; u32 sectionStart[16];
SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "DnldUcod", SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "DnldUcod",
adapter, 0, 0, 0); adapter, 0, 0, 0);
DBG_ERROR("sxg: %s ENTER\n", __func__);
/*
switch (UcodeSel) { * This routine is only implemented to download the microcode
case SXG_UCODE_SYSTEM: // System (operational) ucode * for the Revision B Sahara chip. Rev A and Diagnostic
switch (adapter->asictype) { * microcode is not supported at this time. If Rev A or
case SAHARA_REV_A: * diagnostic ucode is required, this routine will obviously
DBG_ERROR("%s SAHARA CARD REVISION A\n", * need to change. Also, eventually need to add support for
__func__); * Rev B checked version of ucode. That's easy enough once
numSections = SNumSections; * the free version of Rev B works.
for (i = 0; i < numSections; i++) { */
sectionSize[i] = ASSERT(UcodeSel == SXG_UCODE_SYSTEM);
SSectionSize[i]; ASSERT(adapter->asictype == SAHARA_REV_B);
sectionStart[i] = #if SXG_UCODE_DEBUG
SSectionStart[i]; file = "sxg/saharadbgdownloadB.sys";
} #else
break; file = "sxg/saharadownloadB.sys";
case SAHARA_REV_B: #endif
DBG_ERROR("%s SAHARA CARD REVISION B\n", ret = request_firmware(&fw, file, &adapter->pcidev->dev);
__func__); if (ret) {
numSections = SBNumSections; DBG_ERROR("%s SXG_NIC: Failed to load firmware %s\n", __func__,file);
for (i = 0; i < numSections; i++) { return ret;
sectionSize[i] = }
SBSectionSize[i];
sectionStart[i] = /*
SBSectionStart[i]; * The microcode .sys file contains starts with a 4 byte word containing
} * the number of sections. That is followed by "num_sections" 4 byte
break; * words containing each "section" size. That is followed num_sections
} * 4 byte words containing each section "start" address.
break; *
default: * Following the above header, the .sys file contains num_sections,
printk(KERN_ERR KBUILD_MODNAME * where each section size is specified, newline delineatetd 12 byte
": Woah, big error with the microcode!\n"); * microcode instructions.
break; */
num_sections = *(u32 *)(fw->data + index);
index += 4;
ASSERT(num_sections <= 3);
for (i = 0; i < num_sections; i++) {
sectionSize[i] = *(u32 *)(fw->data + index);
index += 4;
}
for (i = 0; i < num_sections; i++) {
sectionStart[i] = *(u32 *)(fw->data + index);
index += 4;
} }
DBG_ERROR("sxg: RESET THE CARD\n");
/* First, reset the card */ /* First, reset the card */
WRITE_REG(HwRegs->Reset, 0xDEAD, FLUSH); WRITE_REG(HwRegs->Reset, 0xDEAD, FLUSH);
udelay(50); udelay(50);
HwRegs = adapter->HwRegs;
/* /*
* Download each section of the microcode as specified in * Download each section of the microcode as specified in
* its download file. The *download.c file is generated using * sectionSize[index] to sectionStart[index] address. As
* the saharaobjtoc facility which converts the metastep .obj * described above, the .sys file contains 12 byte word
* file to a .c file which contains a two dimentional array. * microcode instructions. The *download.sys file is generated
* using the objtosys.exe utility that was built for Sahara
* microcode.
*/ */
for (Section = 0; Section < numSections; Section++) { /* See usage of this below when we read back for parity */
DBG_ERROR("sxg: SECTION # %d\n", Section); ucode_start = index;
switch (UcodeSel) { instruction = *(u32 *)(fw->data + index);
case SXG_UCODE_SYSTEM: index += 4;
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;
}
for (Section = 0; Section < num_sections; Section++) {
BaseAddress = sectionStart[Section]; BaseAddress = sectionStart[Section];
/* Size in instructions */ /* Size in instructions */
ThisSectionSize = sectionSize[Section] / 12; ThisSectionSize = sectionSize[Section] / 12;
for (AddressOffset = 0; AddressOffset < ThisSectionSize; for (AddressOffset = 0; AddressOffset < ThisSectionSize;
AddressOffset++) { AddressOffset++) {
u32 first_instr = 0; /* See comment below */
Address = BaseAddress + AddressOffset; Address = BaseAddress + AddressOffset;
ASSERT((Address & ~MICROCODE_ADDRESS_MASK) == 0); ASSERT((Address & ~MICROCODE_ADDRESS_MASK) == 0);
/* Write instruction bits 31 - 0 */ /* Write instruction bits 31 - 0 (low) */
WRITE_REG(HwRegs->UcodeDataLow, *Instruction, FLUSH); first_instr = instruction;
/* Write instruction bits 63-32 */ WRITE_REG(HwRegs->UcodeDataLow, instruction, FLUSH);
WRITE_REG(HwRegs->UcodeDataMiddle, *(Instruction + 1), instruction = *(u32 *)(fw->data + index);
FLUSH); index += 4; /* Advance to the "next" instruction */
/* Write instruction bits 95-64 */
WRITE_REG(HwRegs->UcodeDataHigh, *(Instruction + 2), /* Write instruction bits 63-32 (middle) */
FLUSH); WRITE_REG(HwRegs->UcodeDataMiddle, instruction, FLUSH);
instruction = *(u32 *)(fw->data + index);
index += 4; /* Advance to the "next" instruction */
/* Write instruction bits 95-64 (high) */
WRITE_REG(HwRegs->UcodeDataHigh, instruction, FLUSH);
instruction = *(u32 *)(fw->data + index);
index += 4; /* Advance to the "next" instruction */
/* Write instruction address with the WRITE bit set */ /* Write instruction address with the WRITE bit set */
WRITE_REG(HwRegs->UcodeAddr, WRITE_REG(HwRegs->UcodeAddr,
(Address | MICROCODE_ADDRESS_WRITE), FLUSH); (Address | MICROCODE_ADDRESS_WRITE), FLUSH);
...@@ -500,34 +510,16 @@ static bool sxg_download_microcode(struct adapter_t *adapter, ...@@ -500,34 +510,16 @@ static bool sxg_download_microcode(struct adapter_t *adapter,
* and write the data for the next instruction to DataLow. That * and write the data for the next instruction to DataLow. That
* write should succeed. * write should succeed.
*/ */
WRITE_REG(HwRegs->UcodeDataLow, *Instruction, TRUE); WRITE_REG(HwRegs->UcodeDataLow, first_instr, FLUSH);
/* Advance 3 u32S to start of next instruction */
Instruction += 3;
} }
} }
/* /*
* Now repeat the entire operation reading the instruction back and * Now repeat the entire operation reading the instruction back and
* checking for parity errors * checking for parity errors
*/ */
for (Section = 0; Section < numSections; Section++) { index = ucode_start;
DBG_ERROR("sxg: check SECTION # %d\n", Section);
switch (UcodeSel) { for (Section = 0; Section < num_sections; Section++) {
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]; BaseAddress = sectionStart[Section];
/* Size in instructions */ /* Size in instructions */
ThisSectionSize = sectionSize[Section] / 12; ThisSectionSize = sectionSize[Section] / 12;
...@@ -547,29 +539,36 @@ static bool sxg_download_microcode(struct adapter_t *adapter, ...@@ -547,29 +539,36 @@ static bool sxg_download_microcode(struct adapter_t *adapter,
} }
ASSERT((ValueRead & MICROCODE_ADDRESS_MASK) == Address); ASSERT((ValueRead & MICROCODE_ADDRESS_MASK) == Address);
/* Read the instruction back and compare */ /* Read the instruction back and compare */
/* First instruction */
instruction = *(u32 *)(fw->data + index);
index += 4;
READ_REG(HwRegs->UcodeDataLow, ValueRead); READ_REG(HwRegs->UcodeDataLow, ValueRead);
if (ValueRead != *Instruction) { if (ValueRead != instruction) {
DBG_ERROR("sxg: %s MISCOMPARE LOW\n", DBG_ERROR("sxg: %s MISCOMPARE LOW\n",
__func__); __func__);
return FALSE; /* Miscompare */ return FALSE; /* Miscompare */
} }
instruction = *(u32 *)(fw->data + index);
index += 4;
READ_REG(HwRegs->UcodeDataMiddle, ValueRead); READ_REG(HwRegs->UcodeDataMiddle, ValueRead);
if (ValueRead != *(Instruction + 1)) { if (ValueRead != instruction) {
DBG_ERROR("sxg: %s MISCOMPARE MIDDLE\n", DBG_ERROR("sxg: %s MISCOMPARE MIDDLE\n",
__func__); __func__);
return FALSE; /* Miscompare */ return FALSE; /* Miscompare */
} }
instruction = *(u32 *)(fw->data + index);
index += 4;
READ_REG(HwRegs->UcodeDataHigh, ValueRead); READ_REG(HwRegs->UcodeDataHigh, ValueRead);
if (ValueRead != *(Instruction + 2)) { if (ValueRead != instruction) {
DBG_ERROR("sxg: %s MISCOMPARE HIGH\n", DBG_ERROR("sxg: %s MISCOMPARE HIGH\n",
__func__); __func__);
return FALSE; /* Miscompare */ return FALSE; /* Miscompare */
} }
/* Advance 3 u32S to start of next instruction */
Instruction += 3;
} }
} }
/* download finished */
release_firmware(fw);
/* Everything OK, Go. */ /* Everything OK, Go. */
WRITE_REG(HwRegs->UcodeAddr, MICROCODE_ADDRESS_GO, FLUSH); WRITE_REG(HwRegs->UcodeAddr, MICROCODE_ADDRESS_GO, FLUSH);
...@@ -581,12 +580,11 @@ static bool sxg_download_microcode(struct adapter_t *adapter, ...@@ -581,12 +580,11 @@ static bool sxg_download_microcode(struct adapter_t *adapter,
udelay(50); udelay(50);
READ_REG(adapter->UcodeRegs[0].CardUp, ValueRead); READ_REG(adapter->UcodeRegs[0].CardUp, ValueRead);
if (ValueRead == 0xCAFE) { if (ValueRead == 0xCAFE) {
DBG_ERROR("sxg: %s BOO YA 0xCAFE\n", __func__);
break; break;
} }
} }
if (i == 10000) { if (i == 10000) {
DBG_ERROR("sxg: %s TIMEOUT\n", __func__); DBG_ERROR("sxg: %s TIMEOUT bringing up card - verify MICROCODE\n", __func__);
return FALSE; /* Timeout */ return FALSE; /* Timeout */
} }
...@@ -601,8 +599,6 @@ static bool sxg_download_microcode(struct adapter_t *adapter, ...@@ -601,8 +599,6 @@ static bool sxg_download_microcode(struct adapter_t *adapter,
SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "XDnldUcd", SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "XDnldUcd",
adapter, 0, 0, 0); adapter, 0, 0, 0);
DBG_ERROR("sxg: %s EXIT\n", __func__);
return (TRUE); return (TRUE);
} }
......
...@@ -53,6 +53,8 @@ fw-shipped-$(CONFIG_SLICOSS) += slicoss/gbdownload.sys slicoss/gbrcvucode.sys \ ...@@ -53,6 +53,8 @@ fw-shipped-$(CONFIG_SLICOSS) += slicoss/gbdownload.sys slicoss/gbrcvucode.sys \
slicoss/oasisdbgdownload.sys \ slicoss/oasisdbgdownload.sys \
slicoss/oasisdownload.sys \ slicoss/oasisdownload.sys \
slicoss/oasisrcvucode.sys slicoss/oasisrcvucode.sys
fw-shipped-$(CONFIG_SXG) += sxg/saharadownloadB.sys \
sxg/saharadbgdownloadB.sys
fw-shipped-$(CONFIG_SND_YMFPCI) += yamaha/ds1_ctrl.fw yamaha/ds1_dsp.fw \ fw-shipped-$(CONFIG_SND_YMFPCI) += yamaha/ds1_ctrl.fw yamaha/ds1_dsp.fw \
yamaha/ds1e_ctrl.fw yamaha/ds1e_ctrl.fw
fw-shipped-$(CONFIG_TEHUTI) += tehuti/bdx.bin fw-shipped-$(CONFIG_TEHUTI) += tehuti/bdx.bin
......
...@@ -378,6 +378,18 @@ Found in hex form in kernel source. ...@@ -378,6 +378,18 @@ Found in hex form in kernel source.
-------------------------------------------------------------------------- --------------------------------------------------------------------------
Driver: SXG - Alacritech IS-NIC products
File: sxg/saharadownloadB.sys.ihex
File: sxg/saharadbgdownloadB.sys.ihex
Licence: Unknown
Found in hex form in kernel source.
Copyright 1997-2009 Alacritech, Inc. All rights reserved.
--------------------------------------------------------------------------
Driver: cxgb3 - Chelsio Terminator 3 1G/10G Ethernet adapter Driver: cxgb3 - Chelsio Terminator 3 1G/10G Ethernet adapter
File: cxgb3/t3b_psram-1.1.0.bin.ihex File: cxgb3/t3b_psram-1.1.0.bin.ihex
......
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment