179 lines
5.4 KiB
Diff
179 lines
5.4 KiB
Diff
From: Ben Hutchings <ben@decadent.org.uk>
|
|
Date: Mon, 17 Aug 2009 02:17:09 +0100
|
|
Subject: [PATCH] ib_qib: use request_firmware() to load SD7220 firmware
|
|
|
|
|
|
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
|
|
---
|
|
--- a/drivers/infiniband/hw/qib/qib_7220.h
|
|
+++ b/drivers/infiniband/hw/qib/qib_7220.h
|
|
@@ -109,10 +109,6 @@ struct qib_chippport_specific {
|
|
*/
|
|
int qib_sd7220_presets(struct qib_devdata *dd);
|
|
int qib_sd7220_init(struct qib_devdata *dd);
|
|
-int qib_sd7220_prog_ld(struct qib_devdata *dd, int sdnum, u8 *img,
|
|
- int len, int offset);
|
|
-int qib_sd7220_prog_vfy(struct qib_devdata *dd, int sdnum, const u8 *img,
|
|
- int len, int offset);
|
|
void qib_sd7220_clr_ibpar(struct qib_devdata *);
|
|
/*
|
|
* Below used for sdnum parameter, selecting one of the two sections
|
|
@@ -121,9 +117,6 @@ void qib_sd7220_clr_ibpar(struct qib_devdata *);
|
|
*/
|
|
#define IB_7220_SERDES 2
|
|
|
|
-int qib_sd7220_ib_load(struct qib_devdata *dd);
|
|
-int qib_sd7220_ib_vfy(struct qib_devdata *dd);
|
|
-
|
|
static inline u32 qib_read_kreg32(const struct qib_devdata *dd,
|
|
const u16 regno)
|
|
{
|
|
--- a/drivers/infiniband/hw/qib/qib_sd7220.c
|
|
+++ b/drivers/infiniband/hw/qib/qib_sd7220.c
|
|
@@ -37,10 +37,14 @@
|
|
|
|
#include <linux/pci.h>
|
|
#include <linux/delay.h>
|
|
+#include <linux/firmware.h>
|
|
|
|
#include "qib.h"
|
|
#include "qib_7220.h"
|
|
|
|
+#define SD7220_FW_NAME "qlogic/sd7220.fw"
|
|
+MODULE_FIRMWARE(SD7220_FW_NAME);
|
|
+
|
|
/*
|
|
* Same as in qib_iba7220.c, but just the registers needed here.
|
|
* Could move whole set to qib_7220.h, but decided better to keep
|
|
@@ -74,6 +78,11 @@
|
|
#define PCIE_SERDES0 0
|
|
#define PCIE_SERDES1 1
|
|
|
|
+static int
|
|
+qib_sd7220_ib_load(struct qib_devdata *dd, const struct firmware *fw);
|
|
+static int
|
|
+qib_sd7220_ib_vfy(struct qib_devdata *dd, const struct firmware *fw);
|
|
+
|
|
/*
|
|
* The EPB requires addressing in a particular form. EPB_LOC() is intended
|
|
* to make #definitions a little more readable.
|
|
@@ -110,10 +119,12 @@ static int epb_access(struct qib_devdata *dd, int sdnum, int claim);
|
|
* state of the reset "pin", is no longer valid. Instead, we check for the
|
|
* actual uC code having been loaded.
|
|
*/
|
|
-static int qib_ibsd_ucode_loaded(struct qib_pportdata *ppd)
|
|
+static int
|
|
+qib_ibsd_ucode_loaded(struct qib_pportdata *ppd, const struct firmware *fw)
|
|
{
|
|
struct qib_devdata *dd = ppd->dd;
|
|
- if (!dd->cspec->serdes_first_init_done && (qib_sd7220_ib_vfy(dd) > 0))
|
|
+ if (!dd->cspec->serdes_first_init_done &&
|
|
+ (qib_sd7220_ib_vfy(dd, fw) > 0))
|
|
dd->cspec->serdes_first_init_done = 1;
|
|
return dd->cspec->serdes_first_init_done;
|
|
}
|
|
@@ -377,6 +388,7 @@ static void qib_sd_trimdone_monitor(struct qib_devdata *dd,
|
|
*/
|
|
int qib_sd7220_init(struct qib_devdata *dd)
|
|
{
|
|
+ const struct firmware *fw;
|
|
int ret = 1; /* default to failure */
|
|
int first_reset, was_reset;
|
|
|
|
@@ -387,8 +399,15 @@ int qib_sd7220_init(struct qib_devdata *dd)
|
|
qib_ibsd_reset(dd, 1);
|
|
qib_sd_trimdone_monitor(dd, "Driver-reload");
|
|
}
|
|
+
|
|
+ ret = request_firmware(&fw, SD7220_FW_NAME, &dd->pcidev->dev);
|
|
+ if (ret) {
|
|
+ qib_dev_err(dd, "Failed to load IB SERDES image\n");
|
|
+ goto done;
|
|
+ }
|
|
+
|
|
/* Substitute our deduced value for was_reset */
|
|
- ret = qib_ibsd_ucode_loaded(dd->pport);
|
|
+ ret = qib_ibsd_ucode_loaded(dd->pport, fw);
|
|
if (ret < 0)
|
|
goto bail;
|
|
|
|
@@ -437,13 +456,13 @@ int qib_sd7220_init(struct qib_devdata *dd)
|
|
int vfy;
|
|
int trim_done;
|
|
|
|
- ret = qib_sd7220_ib_load(dd);
|
|
+ ret = qib_sd7220_ib_load(dd, fw);
|
|
if (ret < 0) {
|
|
qib_dev_err(dd, "Failed to load IB SERDES image\n");
|
|
goto bail;
|
|
} else {
|
|
/* Loaded image, try to verify */
|
|
- vfy = qib_sd7220_ib_vfy(dd);
|
|
+ vfy = qib_sd7220_ib_vfy(dd, fw);
|
|
if (vfy != ret) {
|
|
qib_dev_err(dd, "SERDES PRAM VFY failed\n");
|
|
goto bail;
|
|
@@ -506,6 +525,8 @@ bail:
|
|
done:
|
|
/* start relock timer regardless, but start at 1 second */
|
|
set_7220_relock_poll(dd, -1);
|
|
+
|
|
+ release_firmware(fw);
|
|
return ret;
|
|
}
|
|
|
|
@@ -829,8 +850,8 @@ static int qib_sd7220_ram_xfer(struct qib_devdata *dd, int sdnum, u32 loc,
|
|
|
|
#define PROG_CHUNK 64
|
|
|
|
-int qib_sd7220_prog_ld(struct qib_devdata *dd, int sdnum,
|
|
- u8 *img, int len, int offset)
|
|
+static int qib_sd7220_prog_ld(struct qib_devdata *dd, int sdnum,
|
|
+ const u8 *img, int len, int offset)
|
|
{
|
|
int cnt, sofar, req;
|
|
|
|
@@ -840,7 +861,7 @@ int qib_sd7220_prog_ld(struct qib_devdata *dd, int sdnum,
|
|
if (req > PROG_CHUNK)
|
|
req = PROG_CHUNK;
|
|
cnt = qib_sd7220_ram_xfer(dd, sdnum, offset + sofar,
|
|
- img + sofar, req, 0);
|
|
+ (u8 *)img + sofar, req, 0);
|
|
if (cnt < req) {
|
|
sofar = -1;
|
|
break;
|
|
@@ -853,8 +874,8 @@ int qib_sd7220_prog_ld(struct qib_devdata *dd, int sdnum,
|
|
#define VFY_CHUNK 64
|
|
#define SD_PRAM_ERROR_LIMIT 42
|
|
|
|
-int qib_sd7220_prog_vfy(struct qib_devdata *dd, int sdnum,
|
|
- const u8 *img, int len, int offset)
|
|
+static int qib_sd7220_prog_vfy(struct qib_devdata *dd, int sdnum,
|
|
+ const u8 *img, int len, int offset)
|
|
{
|
|
int cnt, sofar, req, idx, errors;
|
|
unsigned char readback[VFY_CHUNK];
|
|
@@ -881,16 +902,16 @@ int qib_sd7220_prog_vfy(struct qib_devdata *dd, int sdnum,
|
|
return errors ? -errors : sofar;
|
|
}
|
|
|
|
-int
|
|
-qib_sd7220_ib_load(struct qib_devdata *dd)
|
|
+static int
|
|
+qib_sd7220_ib_load(struct qib_devdata *dd, const struct firmware *fw)
|
|
{
|
|
- return -1;
|
|
+ return qib_sd7220_prog_ld(dd, IB_7220_SERDES, fw->data, fw->size, 0);
|
|
}
|
|
|
|
-int
|
|
-qib_sd7220_ib_vfy(struct qib_devdata *dd)
|
|
+static int
|
|
+qib_sd7220_ib_vfy(struct qib_devdata *dd, const struct firmware *fw)
|
|
{
|
|
- return -1;
|
|
+ return qib_sd7220_prog_vfy(dd, IB_7220_SERDES, fw->data, fw->size, 0);
|
|
}
|
|
|
|
/*
|