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:
Родитель
e5ea8da06b
Коммит
cda3b517a4
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -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
|
||||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
Загрузка…
Ссылка в новой задаче