aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/qlge/qlge_mpi.c
diff options
context:
space:
mode:
authorRon Mercer <ron.mercer@qlogic.com>2010-01-15 08:31:28 -0500
committerDavid S. Miller <davem@davemloft.net>2010-01-16 04:01:52 -0500
commit8aae2600030f54494f9061d2cde141802d774be9 (patch)
tree543f1b31264ee96703bb45ed454d293796f45948 /drivers/net/qlge/qlge_mpi.c
parentb87babeb40aaf879d20268792390ce831805a557 (diff)
qlge: Add basic firmware dump.
Adding the infrstructure and basic data for the firmware core dump. The firmware coredump is turned OFF by default. There will be no memory allocations for data dumps to the log. Signed-off-by: Ron Mercer <ron.mercer@qlogic.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/qlge/qlge_mpi.c')
-rw-r--r--drivers/net/qlge/qlge_mpi.c73
1 files changed, 73 insertions, 0 deletions
diff --git a/drivers/net/qlge/qlge_mpi.c b/drivers/net/qlge/qlge_mpi.c
index e2b2286102d4..242b1ea955e4 100644
--- a/drivers/net/qlge/qlge_mpi.c
+++ b/drivers/net/qlge/qlge_mpi.c
@@ -1,5 +1,35 @@
1#include "qlge.h" 1#include "qlge.h"
2 2
3int ql_unpause_mpi_risc(struct ql_adapter *qdev)
4{
5 u32 tmp;
6
7 /* Un-pause the RISC */
8 tmp = ql_read32(qdev, CSR);
9 if (!(tmp & CSR_RP))
10 return -EIO;
11
12 ql_write32(qdev, CSR, CSR_CMD_CLR_PAUSE);
13 return 0;
14}
15
16int ql_pause_mpi_risc(struct ql_adapter *qdev)
17{
18 u32 tmp;
19 int count = UDELAY_COUNT;
20
21 /* Pause the RISC */
22 ql_write32(qdev, CSR, CSR_CMD_SET_PAUSE);
23 do {
24 tmp = ql_read32(qdev, CSR);
25 if (tmp & CSR_RP)
26 break;
27 mdelay(UDELAY_DELAY);
28 count--;
29 } while (count);
30 return (count == 0) ? -ETIMEDOUT : 0;
31}
32
3int ql_read_mpi_reg(struct ql_adapter *qdev, u32 reg, u32 *data) 33int ql_read_mpi_reg(struct ql_adapter *qdev, u32 reg, u32 *data)
4{ 34{
5 int status; 35 int status;
@@ -45,6 +75,35 @@ int ql_soft_reset_mpi_risc(struct ql_adapter *qdev)
45 return status; 75 return status;
46} 76}
47 77
78/* Determine if we are in charge of the firwmare. If
79 * we are the lower of the 2 NIC pcie functions, or if
80 * we are the higher function and the lower function
81 * is not enabled.
82 */
83int ql_own_firmware(struct ql_adapter *qdev)
84{
85 u32 temp;
86
87 /* If we are the lower of the 2 NIC functions
88 * on the chip the we are responsible for
89 * core dump and firmware reset after an error.
90 */
91 if (qdev->func < qdev->alt_func)
92 return 1;
93
94 /* If we are the higher of the 2 NIC functions
95 * on the chip and the lower function is not
96 * enabled, then we are responsible for
97 * core dump and firmware reset after an error.
98 */
99 temp = ql_read32(qdev, STS);
100 if (!(temp & (1 << (8 + qdev->alt_func))))
101 return 1;
102
103 return 0;
104
105}
106
48static int ql_get_mb_sts(struct ql_adapter *qdev, struct mbox_params *mbcp) 107static int ql_get_mb_sts(struct ql_adapter *qdev, struct mbox_params *mbcp)
49{ 108{
50 int i, status; 109 int i, status;
@@ -1143,5 +1202,19 @@ void ql_mpi_reset_work(struct work_struct *work)
1143 cancel_delayed_work_sync(&qdev->mpi_work); 1202 cancel_delayed_work_sync(&qdev->mpi_work);
1144 cancel_delayed_work_sync(&qdev->mpi_port_cfg_work); 1203 cancel_delayed_work_sync(&qdev->mpi_port_cfg_work);
1145 cancel_delayed_work_sync(&qdev->mpi_idc_work); 1204 cancel_delayed_work_sync(&qdev->mpi_idc_work);
1205 /* If we're not the dominant NIC function,
1206 * then there is nothing to do.
1207 */
1208 if (!ql_own_firmware(qdev)) {
1209 QPRINTK(qdev, DRV, ERR, "Don't own firmware!\n");
1210 return;
1211 }
1212
1213 if (!ql_core_dump(qdev, qdev->mpi_coredump)) {
1214 QPRINTK(qdev, DRV, ERR, "Core is dumped!\n");
1215 qdev->core_is_dumped = 1;
1216 queue_delayed_work(qdev->workqueue,
1217 &qdev->mpi_core_to_log, 5 * HZ);
1218 }
1146 ql_soft_reset_mpi_risc(qdev); 1219 ql_soft_reset_mpi_risc(qdev);
1147} 1220}