mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-10-03 15:47:36 +00:00
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:
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
|
@ -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
|
||||||
|
|
3937
firmware/sxg/saharadbgdownloadB.sys.ihex
Normal file
3937
firmware/sxg/saharadbgdownloadB.sys.ihex
Normal file
File diff suppressed because it is too large
Load diff
3385
firmware/sxg/saharadownloadB.sys.ihex
Normal file
3385
firmware/sxg/saharadownloadB.sys.ihex
Normal file
File diff suppressed because it is too large
Load diff
Loading…
Reference in a new issue