diff options
Diffstat (limited to 'drivers/infiniband/hw/qib/qib_sd7220.c')
-rw-r--r-- | drivers/infiniband/hw/qib/qib_sd7220.c | 56 |
1 files changed, 45 insertions, 11 deletions
diff --git a/drivers/infiniband/hw/qib/qib_sd7220.c b/drivers/infiniband/hw/qib/qib_sd7220.c index 0aeed0e..e9f9f8b 100644 --- a/drivers/infiniband/hw/qib/qib_sd7220.c +++ b/drivers/infiniband/hw/qib/qib_sd7220.c @@ -1,5 +1,6 @@ /* - * Copyright (c) 2006, 2007, 2008, 2009 QLogic Corporation. All rights reserved. + * Copyright (c) 2006, 2007, 2008, 2009, 2010 QLogic Corporation. + * All rights reserved. * Copyright (c) 2003, 2004, 2005, 2006 PathScale, Inc. All rights reserved. * * This software is available to you under a choice of one of two @@ -37,10 +38,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 @@ -102,6 +107,10 @@ static int qib_internal_presets(struct qib_devdata *dd); /* Tweak the register (CMUCTRL5) that contains the TRIMSELF controls */ static int qib_sd_trimself(struct qib_devdata *dd, int val); static int epb_access(struct qib_devdata *dd, int sdnum, int claim); +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); /* * Below keeps track of whether the "once per power-on" initialization has @@ -110,10 +119,13 @@ 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 +389,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 +400,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 +457,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 +526,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 +851,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 +862,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 +875,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,6 +903,18 @@ int qib_sd7220_prog_vfy(struct qib_devdata *dd, int sdnum, return errors ? -errors : sofar; } +static int +qib_sd7220_ib_load(struct qib_devdata *dd, const struct firmware *fw) +{ + return qib_sd7220_prog_ld(dd, IB_7220_SERDES, fw->data, fw->size, 0); +} + +static int +qib_sd7220_ib_vfy(struct qib_devdata *dd, const struct firmware *fw) +{ + return qib_sd7220_prog_vfy(dd, IB_7220_SERDES, fw->data, fw->size, 0); +} + /* * IRQ not set up at this point in init, so we poll. */ |