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: Christopher Harrer <charrer@alacritech.com>
Signed-off-by: Mithlesh Thukral <mithlesh@linsyssoft.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
This commit is contained in:
Mithlesh Thukral 2009-03-20 17:39:04 +05:30 committed by Greg Kroah-Hartman
parent e5ea8da06b
commit cda3b517a4
9 changed files with 7436 additions and 19651 deletions

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -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 @@
#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)
/* /*
* 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)
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) { /*
case SXG_UCODE_SYSTEM: // System (operational) ucode * This routine is only implemented to download the microcode
switch (adapter->asictype) { * for the Revision B Sahara chip. Rev A and Diagnostic
case SAHARA_REV_A: * microcode is not supported at this time. If Rev A or
DBG_ERROR("%s SAHARA CARD REVISION A\n", * diagnostic ucode is required, this routine will obviously
__func__); * need to change. Also, eventually need to add support for
numSections = SNumSections; * Rev B checked version of ucode. That's easy enough once
for (i = 0; i < numSections; i++) { * the free version of Rev B works.
sectionSize[i] = */
SSectionSize[i]; ASSERT(UcodeSel == SXG_UCODE_SYSTEM);
sectionStart[i] = ASSERT(adapter->asictype == SAHARA_REV_B);
SSectionStart[i]; #if SXG_UCODE_DEBUG
} file = "sxg/saharadbgdownloadB.sys";
break; #else
case SAHARA_REV_B: file = "sxg/saharadownloadB.sys";
DBG_ERROR("%s SAHARA CARD REVISION B\n", #endif
__func__); ret = request_firmware(&fw, file, &adapter->pcidev->dev);
numSections = SBNumSections; if (ret) {
for (i = 0; i < numSections; i++) { DBG_ERROR("%s SXG_NIC: Failed to load firmware %s\n", __func__,file);
sectionSize[i] = return ret;
SBSectionSize[i]; }
sectionStart[i] =
SBSectionStart[i]; /*
} * The microcode .sys file contains starts with a 4 byte word containing
break; * the number of sections. That is followed by "num_sections" 4 byte
} * words containing each "section" size. That is followed num_sections
break; * 4 byte words containing each section "start" address.
default: *
printk(KERN_ERR KBUILD_MODNAME * Following the above header, the .sys file contains num_sections,
": Woah, big error with the microcode!\n"); * where each section size is specified, newline delineatetd 12 byte
break; * microcode instructions.
*/
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,
* 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,
} }
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,
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,
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);
} }

View file

@ -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

View file

@ -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

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff