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 0aeed0e74cb6..e9f9f8bc3204 100644 --- a/drivers/infiniband/hw/qib/qib_sd7220.c +++ b/drivers/infiniband/hw/qib/qib_sd7220.c | |||
@@ -1,5 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) 2006, 2007, 2008, 2009 QLogic Corporation. All rights reserved. | 2 | * Copyright (c) 2006, 2007, 2008, 2009, 2010 QLogic Corporation. |
3 | * All rights reserved. | ||
3 | * Copyright (c) 2003, 2004, 2005, 2006 PathScale, Inc. All rights reserved. | 4 | * Copyright (c) 2003, 2004, 2005, 2006 PathScale, Inc. All rights reserved. |
4 | * | 5 | * |
5 | * This software is available to you under a choice of one of two | 6 | * This software is available to you under a choice of one of two |
@@ -37,10 +38,14 @@ | |||
37 | 38 | ||
38 | #include <linux/pci.h> | 39 | #include <linux/pci.h> |
39 | #include <linux/delay.h> | 40 | #include <linux/delay.h> |
41 | #include <linux/firmware.h> | ||
40 | 42 | ||
41 | #include "qib.h" | 43 | #include "qib.h" |
42 | #include "qib_7220.h" | 44 | #include "qib_7220.h" |
43 | 45 | ||
46 | #define SD7220_FW_NAME "qlogic/sd7220.fw" | ||
47 | MODULE_FIRMWARE(SD7220_FW_NAME); | ||
48 | |||
44 | /* | 49 | /* |
45 | * Same as in qib_iba7220.c, but just the registers needed here. | 50 | * Same as in qib_iba7220.c, but just the registers needed here. |
46 | * Could move whole set to qib_7220.h, but decided better to keep | 51 | * 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); | |||
102 | /* Tweak the register (CMUCTRL5) that contains the TRIMSELF controls */ | 107 | /* Tweak the register (CMUCTRL5) that contains the TRIMSELF controls */ |
103 | static int qib_sd_trimself(struct qib_devdata *dd, int val); | 108 | static int qib_sd_trimself(struct qib_devdata *dd, int val); |
104 | static int epb_access(struct qib_devdata *dd, int sdnum, int claim); | 109 | static int epb_access(struct qib_devdata *dd, int sdnum, int claim); |
110 | static int qib_sd7220_ib_load(struct qib_devdata *dd, | ||
111 | const struct firmware *fw); | ||
112 | static int qib_sd7220_ib_vfy(struct qib_devdata *dd, | ||
113 | const struct firmware *fw); | ||
105 | 114 | ||
106 | /* | 115 | /* |
107 | * Below keeps track of whether the "once per power-on" initialization has | 116 | * 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); | |||
110 | * state of the reset "pin", is no longer valid. Instead, we check for the | 119 | * state of the reset "pin", is no longer valid. Instead, we check for the |
111 | * actual uC code having been loaded. | 120 | * actual uC code having been loaded. |
112 | */ | 121 | */ |
113 | static int qib_ibsd_ucode_loaded(struct qib_pportdata *ppd) | 122 | static int qib_ibsd_ucode_loaded(struct qib_pportdata *ppd, |
123 | const struct firmware *fw) | ||
114 | { | 124 | { |
115 | struct qib_devdata *dd = ppd->dd; | 125 | struct qib_devdata *dd = ppd->dd; |
116 | if (!dd->cspec->serdes_first_init_done && (qib_sd7220_ib_vfy(dd) > 0)) | 126 | |
127 | if (!dd->cspec->serdes_first_init_done && | ||
128 | qib_sd7220_ib_vfy(dd, fw) > 0) | ||
117 | dd->cspec->serdes_first_init_done = 1; | 129 | dd->cspec->serdes_first_init_done = 1; |
118 | return dd->cspec->serdes_first_init_done; | 130 | return dd->cspec->serdes_first_init_done; |
119 | } | 131 | } |
@@ -377,6 +389,7 @@ static void qib_sd_trimdone_monitor(struct qib_devdata *dd, | |||
377 | */ | 389 | */ |
378 | int qib_sd7220_init(struct qib_devdata *dd) | 390 | int qib_sd7220_init(struct qib_devdata *dd) |
379 | { | 391 | { |
392 | const struct firmware *fw; | ||
380 | int ret = 1; /* default to failure */ | 393 | int ret = 1; /* default to failure */ |
381 | int first_reset, was_reset; | 394 | int first_reset, was_reset; |
382 | 395 | ||
@@ -387,8 +400,15 @@ int qib_sd7220_init(struct qib_devdata *dd) | |||
387 | qib_ibsd_reset(dd, 1); | 400 | qib_ibsd_reset(dd, 1); |
388 | qib_sd_trimdone_monitor(dd, "Driver-reload"); | 401 | qib_sd_trimdone_monitor(dd, "Driver-reload"); |
389 | } | 402 | } |
403 | |||
404 | ret = request_firmware(&fw, SD7220_FW_NAME, &dd->pcidev->dev); | ||
405 | if (ret) { | ||
406 | qib_dev_err(dd, "Failed to load IB SERDES image\n"); | ||
407 | goto done; | ||
408 | } | ||
409 | |||
390 | /* Substitute our deduced value for was_reset */ | 410 | /* Substitute our deduced value for was_reset */ |
391 | ret = qib_ibsd_ucode_loaded(dd->pport); | 411 | ret = qib_ibsd_ucode_loaded(dd->pport, fw); |
392 | if (ret < 0) | 412 | if (ret < 0) |
393 | goto bail; | 413 | goto bail; |
394 | 414 | ||
@@ -437,13 +457,13 @@ int qib_sd7220_init(struct qib_devdata *dd) | |||
437 | int vfy; | 457 | int vfy; |
438 | int trim_done; | 458 | int trim_done; |
439 | 459 | ||
440 | ret = qib_sd7220_ib_load(dd); | 460 | ret = qib_sd7220_ib_load(dd, fw); |
441 | if (ret < 0) { | 461 | if (ret < 0) { |
442 | qib_dev_err(dd, "Failed to load IB SERDES image\n"); | 462 | qib_dev_err(dd, "Failed to load IB SERDES image\n"); |
443 | goto bail; | 463 | goto bail; |
444 | } else { | 464 | } else { |
445 | /* Loaded image, try to verify */ | 465 | /* Loaded image, try to verify */ |
446 | vfy = qib_sd7220_ib_vfy(dd); | 466 | vfy = qib_sd7220_ib_vfy(dd, fw); |
447 | if (vfy != ret) { | 467 | if (vfy != ret) { |
448 | qib_dev_err(dd, "SERDES PRAM VFY failed\n"); | 468 | qib_dev_err(dd, "SERDES PRAM VFY failed\n"); |
449 | goto bail; | 469 | goto bail; |
@@ -506,6 +526,8 @@ bail: | |||
506 | done: | 526 | done: |
507 | /* start relock timer regardless, but start at 1 second */ | 527 | /* start relock timer regardless, but start at 1 second */ |
508 | set_7220_relock_poll(dd, -1); | 528 | set_7220_relock_poll(dd, -1); |
529 | |||
530 | release_firmware(fw); | ||
509 | return ret; | 531 | return ret; |
510 | } | 532 | } |
511 | 533 | ||
@@ -829,8 +851,8 @@ static int qib_sd7220_ram_xfer(struct qib_devdata *dd, int sdnum, u32 loc, | |||
829 | 851 | ||
830 | #define PROG_CHUNK 64 | 852 | #define PROG_CHUNK 64 |
831 | 853 | ||
832 | int qib_sd7220_prog_ld(struct qib_devdata *dd, int sdnum, | 854 | static int qib_sd7220_prog_ld(struct qib_devdata *dd, int sdnum, |
833 | u8 *img, int len, int offset) | 855 | const u8 *img, int len, int offset) |
834 | { | 856 | { |
835 | int cnt, sofar, req; | 857 | int cnt, sofar, req; |
836 | 858 | ||
@@ -840,7 +862,7 @@ int qib_sd7220_prog_ld(struct qib_devdata *dd, int sdnum, | |||
840 | if (req > PROG_CHUNK) | 862 | if (req > PROG_CHUNK) |
841 | req = PROG_CHUNK; | 863 | req = PROG_CHUNK; |
842 | cnt = qib_sd7220_ram_xfer(dd, sdnum, offset + sofar, | 864 | cnt = qib_sd7220_ram_xfer(dd, sdnum, offset + sofar, |
843 | img + sofar, req, 0); | 865 | (u8 *)img + sofar, req, 0); |
844 | if (cnt < req) { | 866 | if (cnt < req) { |
845 | sofar = -1; | 867 | sofar = -1; |
846 | break; | 868 | break; |
@@ -853,8 +875,8 @@ int qib_sd7220_prog_ld(struct qib_devdata *dd, int sdnum, | |||
853 | #define VFY_CHUNK 64 | 875 | #define VFY_CHUNK 64 |
854 | #define SD_PRAM_ERROR_LIMIT 42 | 876 | #define SD_PRAM_ERROR_LIMIT 42 |
855 | 877 | ||
856 | int qib_sd7220_prog_vfy(struct qib_devdata *dd, int sdnum, | 878 | static int qib_sd7220_prog_vfy(struct qib_devdata *dd, int sdnum, |
857 | const u8 *img, int len, int offset) | 879 | const u8 *img, int len, int offset) |
858 | { | 880 | { |
859 | int cnt, sofar, req, idx, errors; | 881 | int cnt, sofar, req, idx, errors; |
860 | unsigned char readback[VFY_CHUNK]; | 882 | unsigned char readback[VFY_CHUNK]; |
@@ -881,6 +903,18 @@ int qib_sd7220_prog_vfy(struct qib_devdata *dd, int sdnum, | |||
881 | return errors ? -errors : sofar; | 903 | return errors ? -errors : sofar; |
882 | } | 904 | } |
883 | 905 | ||
906 | static int | ||
907 | qib_sd7220_ib_load(struct qib_devdata *dd, const struct firmware *fw) | ||
908 | { | ||
909 | return qib_sd7220_prog_ld(dd, IB_7220_SERDES, fw->data, fw->size, 0); | ||
910 | } | ||
911 | |||
912 | static int | ||
913 | qib_sd7220_ib_vfy(struct qib_devdata *dd, const struct firmware *fw) | ||
914 | { | ||
915 | return qib_sd7220_prog_vfy(dd, IB_7220_SERDES, fw->data, fw->size, 0); | ||
916 | } | ||
917 | |||
884 | /* | 918 | /* |
885 | * IRQ not set up at this point in init, so we poll. | 919 | * IRQ not set up at this point in init, so we poll. |
886 | */ | 920 | */ |