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 коммит произвёл Greg Kroah-Hartman
Родитель e5ea8da06b
Коммит cda3b517a4
9 изменённых файлов: 7436 добавлений и 19651 удалений

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -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);
} }

Просмотреть файл

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

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Разница между файлами не показана из-за своего большого размера Загрузить разницу