1
From 1e9da7da73886eaf63449e56ebf16cf7daa4a9e5 Mon Sep 17 00:00:00 2001
2
From: Ben Hutchings <ben@decadent.org.uk>
3
Date: Mon, 17 Aug 2009 02:17:09 +0100
4
Subject: [PATCH 3/3] ib_ipath: use request_firmware() to load SD7220 firmware
6
[A later version of this was applied to the qib driver in
7
commit ecd4b48a163b55d7eb4132617100b90d0d2768ec upstream.]
10
drivers/infiniband/hw/ipath/Makefile | 7 ++--
11
drivers/infiniband/hw/ipath/ipath_7220.h | 7 ----
12
drivers/infiniband/hw/ipath/ipath_driver.c | 4 --
13
drivers/infiniband/hw/ipath/ipath_sd7220.c | 49 ++++++++++++++++++++++-----
14
4 files changed, 43 insertions(+), 24 deletions(-)
16
diff --git a/drivers/infiniband/hw/ipath/Makefile b/drivers/infiniband/hw/ipath/Makefile
17
index 42d8d4c..fc892cf 100644
18
--- a/drivers/infiniband/hw/ipath/Makefile
19
+++ b/drivers/infiniband/hw/ipath/Makefile
20
@@ -29,10 +29,9 @@ ib_ipath-y := \
26
-# IBA7220 depends on firmware to be removed
27
-ib_ipath-$(CONFIG_BROKEN) += ipath_iba7220.o ipath_sd7220.o
32
ib_ipath-$(CONFIG_HT_IRQ) += ipath_iba6110.o
33
ib_ipath-$(CONFIG_PCI_MSI) += ipath_iba6120.o
34
diff --git a/drivers/infiniband/hw/ipath/ipath_7220.h b/drivers/infiniband/hw/ipath/ipath_7220.h
35
index 74fa5cc..29a73e0 100644
36
--- a/drivers/infiniband/hw/ipath/ipath_7220.h
37
+++ b/drivers/infiniband/hw/ipath/ipath_7220.h
40
int ipath_sd7220_presets(struct ipath_devdata *dd);
41
int ipath_sd7220_init(struct ipath_devdata *dd, int was_reset);
42
-int ipath_sd7220_prog_ld(struct ipath_devdata *dd, int sdnum, u8 *img,
43
- int len, int offset);
44
-int ipath_sd7220_prog_vfy(struct ipath_devdata *dd, int sdnum, const u8 *img,
45
- int len, int offset);
47
* Below used for sdnum parameter, selecting one of the two sections
48
* used for PCIe, or the single SerDes used for IB, which is the
49
@@ -51,7 +47,4 @@ int ipath_sd7220_prog_vfy(struct ipath_devdata *dd, int sdnum, const u8 *img,
51
#define IB_7220_SERDES 2
53
-int ipath_sd7220_ib_load(struct ipath_devdata *dd);
54
-int ipath_sd7220_ib_vfy(struct ipath_devdata *dd);
56
#endif /* _IPATH_7220_H */
57
diff --git a/drivers/infiniband/hw/ipath/ipath_driver.c b/drivers/infiniband/hw/ipath/ipath_driver.c
58
index 20407a0..04e88b6 100644
59
--- a/drivers/infiniband/hw/ipath/ipath_driver.c
60
+++ b/drivers/infiniband/hw/ipath/ipath_driver.c
61
@@ -140,9 +140,7 @@ static int __devinit ipath_init_one(struct pci_dev *,
62
static const struct pci_device_id ipath_pci_tbl[] = {
63
{ PCI_DEVICE(PCI_VENDOR_ID_PATHSCALE, PCI_DEVICE_ID_INFINIPATH_HT) },
64
{ PCI_DEVICE(PCI_VENDOR_ID_PATHSCALE, PCI_DEVICE_ID_INFINIPATH_PE800) },
66
{ PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_INFINIPATH_7220) },
71
@@ -537,7 +535,6 @@ static int __devinit ipath_init_one(struct pci_dev *pdev,
72
"CONFIG_PCI_MSI is not enabled\n", ent->device);
76
case PCI_DEVICE_ID_INFINIPATH_7220:
77
#ifndef CONFIG_PCI_MSI
78
ipath_dbg("CONFIG_PCI_MSI is not enabled, "
79
@@ -545,7 +542,6 @@ static int __devinit ipath_init_one(struct pci_dev *pdev,
81
ipath_init_iba7220_funcs(dd);
85
ipath_dev_err(dd, "Found unknown QLogic deviceid 0x%x, "
86
"failing\n", ent->device);
87
diff --git a/drivers/infiniband/hw/ipath/ipath_sd7220.c b/drivers/infiniband/hw/ipath/ipath_sd7220.c
88
index aa47eb5..df3735d 100644
89
--- a/drivers/infiniband/hw/ipath/ipath_sd7220.c
90
+++ b/drivers/infiniband/hw/ipath/ipath_sd7220.c
93
#include <linux/pci.h>
94
#include <linux/delay.h>
95
+#include <linux/firmware.h>
97
#include "ipath_kernel.h"
98
#include "ipath_registers.h"
99
#include "ipath_7220.h"
101
+#define SD7220_FW_NAME "qlogic/sd7220.fw"
102
+MODULE_FIRMWARE(SD7220_FW_NAME);
105
* The IBSerDesMappTable is a memory that holds values to be stored in
106
* various SerDes registers by IBC. It is not part of the normal kregs
107
@@ -88,6 +92,11 @@ static int ipath_internal_presets(struct ipath_devdata *dd);
108
static int ipath_sd_trimself(struct ipath_devdata *dd, int val);
109
static int epb_access(struct ipath_devdata *dd, int sdnum, int claim);
112
+ipath_sd7220_ib_load(struct ipath_devdata *dd, const struct firmware *fw);
114
+ipath_sd7220_ib_vfy(struct ipath_devdata *dd, const struct firmware *fw);
116
void ipath_set_relock_poll(struct ipath_devdata *dd, int ibup);
119
@@ -98,9 +107,10 @@ void ipath_set_relock_poll(struct ipath_devdata *dd, int ibup);
120
* ipath_sd7220_init() is no longer valid. Instead, we check for the
121
* actual uC code having been loaded.
123
-static int ipath_ibsd_ucode_loaded(struct ipath_devdata *dd)
125
+ipath_ibsd_ucode_loaded(struct ipath_devdata *dd, const struct firmware *fw)
127
- if (!dd->serdes_first_init_done && (ipath_sd7220_ib_vfy(dd) > 0))
128
+ if (!dd->serdes_first_init_done && (ipath_sd7220_ib_vfy(dd, fw) > 0))
129
dd->serdes_first_init_done = 1;
130
return dd->serdes_first_init_done;
132
@@ -363,6 +373,7 @@ static void ipath_sd_trimdone_monitor(struct ipath_devdata *dd,
134
int ipath_sd7220_init(struct ipath_devdata *dd, int was_reset)
136
+ const struct firmware *fw;
137
int ret = 1; /* default to failure */
140
@@ -373,8 +384,14 @@ int ipath_sd7220_init(struct ipath_devdata *dd, int was_reset)
141
ipath_sd_trimdone_monitor(dd, "Driver-reload");
144
+ ret = request_firmware(&fw, SD7220_FW_NAME, &dd->pcidev->dev);
146
+ ipath_dev_err(dd, "Failed to load IB SERDES image\n");
150
/* Substitute our deduced value for was_reset */
151
- ret = ipath_ibsd_ucode_loaded(dd);
152
+ ret = ipath_ibsd_ucode_loaded(dd, fw);
156
@@ -431,7 +448,7 @@ int ipath_sd7220_init(struct ipath_devdata *dd, int was_reset)
159
ipath_dbg("SerDes uC was reset, reloading PRAM\n");
160
- ret = ipath_sd7220_ib_load(dd);
161
+ ret = ipath_sd7220_ib_load(dd, fw);
163
ipath_dev_err(dd, "Failed to load IB SERDES image\n");
165
@@ -439,7 +456,7 @@ int ipath_sd7220_init(struct ipath_devdata *dd, int was_reset)
168
/* Loaded image, try to verify */
169
- vfy = ipath_sd7220_ib_vfy(dd);
170
+ vfy = ipath_sd7220_ib_vfy(dd, fw);
172
ipath_dev_err(dd, "SERDES PRAM VFY failed\n");
174
@@ -500,6 +517,8 @@ int ipath_sd7220_init(struct ipath_devdata *dd, int was_reset)
176
/* start relock timer regardless, but start at 1 second */
177
ipath_set_relock_poll(dd, -1);
179
+ release_firmware(fw);
183
@@ -836,8 +855,8 @@ static int ipath_sd7220_ram_xfer(struct ipath_devdata *dd, int sdnum, u32 loc,
185
#define PROG_CHUNK 64
187
-int ipath_sd7220_prog_ld(struct ipath_devdata *dd, int sdnum,
188
- u8 *img, int len, int offset)
189
+static int ipath_sd7220_prog_ld(struct ipath_devdata *dd, int sdnum,
190
+ const u8 *img, int len, int offset)
194
@@ -847,7 +866,7 @@ int ipath_sd7220_prog_ld(struct ipath_devdata *dd, int sdnum,
195
if (req > PROG_CHUNK)
197
cnt = ipath_sd7220_ram_xfer(dd, sdnum, offset + sofar,
198
- img + sofar, req, 0);
199
+ (u8 *)img + sofar, req, 0);
203
@@ -860,7 +879,7 @@ int ipath_sd7220_prog_ld(struct ipath_devdata *dd, int sdnum,
205
#define SD_PRAM_ERROR_LIMIT 42
207
-int ipath_sd7220_prog_vfy(struct ipath_devdata *dd, int sdnum,
208
+static int ipath_sd7220_prog_vfy(struct ipath_devdata *dd, int sdnum,
209
const u8 *img, int len, int offset)
211
int cnt, sofar, req, idx, errors;
212
@@ -888,6 +907,18 @@ int ipath_sd7220_prog_vfy(struct ipath_devdata *dd, int sdnum,
213
return errors ? -errors : sofar;
217
+ipath_sd7220_ib_load(struct ipath_devdata *dd, const struct firmware *fw)
219
+ return ipath_sd7220_prog_ld(dd, IB_7220_SERDES, fw->data, fw->size, 0);
223
+ipath_sd7220_ib_vfy(struct ipath_devdata *dd, const struct firmware *fw)
225
+ return ipath_sd7220_prog_vfy(dd, IB_7220_SERDES, fw->data, fw->size, 0);
228
/* IRQ not set up at this point in init, so we poll. */
229
#define IB_SERDES_TRIM_DONE (1ULL << 11)
230
#define TRIM_TMO (30)