aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/qlge/qlge.h1
-rw-r--r--drivers/net/qlge/qlge_main.c1
-rw-r--r--drivers/net/qlge/qlge_mpi.c88
3 files changed, 62 insertions, 28 deletions
diff --git a/drivers/net/qlge/qlge.h b/drivers/net/qlge/qlge.h
index 8b3c37afe80a..2103fe6ff3a5 100644
--- a/drivers/net/qlge/qlge.h
+++ b/drivers/net/qlge/qlge.h
@@ -1407,6 +1407,7 @@ struct ql_adapter {
1407 1407
1408 u32 mailbox_in; 1408 u32 mailbox_in;
1409 u32 mailbox_out; 1409 u32 mailbox_out;
1410 struct mutex mpi_mutex;
1410 1411
1411 int tx_ring_size; 1412 int tx_ring_size;
1412 int rx_ring_size; 1413 int rx_ring_size;
diff --git a/drivers/net/qlge/qlge_main.c b/drivers/net/qlge/qlge_main.c
index 655f3c4322e0..b144b6becfea 100644
--- a/drivers/net/qlge/qlge_main.c
+++ b/drivers/net/qlge/qlge_main.c
@@ -3659,6 +3659,7 @@ static int __devinit ql_init_device(struct pci_dev *pdev,
3659 INIT_DELAYED_WORK(&qdev->asic_reset_work, ql_asic_reset_work); 3659 INIT_DELAYED_WORK(&qdev->asic_reset_work, ql_asic_reset_work);
3660 INIT_DELAYED_WORK(&qdev->mpi_reset_work, ql_mpi_reset_work); 3660 INIT_DELAYED_WORK(&qdev->mpi_reset_work, ql_mpi_reset_work);
3661 INIT_DELAYED_WORK(&qdev->mpi_work, ql_mpi_work); 3661 INIT_DELAYED_WORK(&qdev->mpi_work, ql_mpi_work);
3662 mutex_init(&qdev->mpi_mutex);
3662 3663
3663 if (!cards_found) { 3664 if (!cards_found) {
3664 dev_info(&pdev->dev, "%s\n", DRV_STRING); 3665 dev_info(&pdev->dev, "%s\n", DRV_STRING);
diff --git a/drivers/net/qlge/qlge_mpi.c b/drivers/net/qlge/qlge_mpi.c
index f9db78697e2b..a4b810d0d3d1 100644
--- a/drivers/net/qlge/qlge_mpi.c
+++ b/drivers/net/qlge/qlge_mpi.c
@@ -124,43 +124,75 @@ exit:
124 ql_write32(qdev, CSR, CSR_CMD_CLR_R2PCI_INT); 124 ql_write32(qdev, CSR, CSR_CMD_CLR_R2PCI_INT);
125} 125}
126 126
127/* Process an async event and clear it unless it's an
128 * error condition.
129 * This can get called iteratively from the mpi_work thread
130 * when events arrive via an interrupt.
131 * It also gets called when a mailbox command is polling for
132 * it's completion. */
133static int ql_mpi_handler(struct ql_adapter *qdev, struct mbox_params *mbcp)
134{
135 int status;
136
137 /* Just get mailbox zero for now. */
138 mbcp->out_count = 1;
139 status = ql_get_mb_sts(qdev, mbcp);
140 if (status) {
141 QPRINTK(qdev, DRV, ERR,
142 "Could not read MPI, resetting ASIC!\n");
143 ql_queue_asic_error(qdev);
144 goto end;
145 }
146
147 switch (mbcp->mbox_out[0]) {
148
149 case AEN_LINK_UP:
150 ql_link_up(qdev, mbcp);
151 break;
152
153 case AEN_LINK_DOWN:
154 ql_link_down(qdev, mbcp);
155 break;
156
157 case AEN_FW_INIT_DONE:
158 ql_init_fw_done(qdev, mbcp);
159 break;
160
161 case MB_CMD_STS_GOOD:
162 break;
163
164 case AEN_FW_INIT_FAIL:
165 case AEN_SYS_ERR:
166 case MB_CMD_STS_ERR:
167 ql_queue_fw_error(qdev);
168 break;
169
170 default:
171 QPRINTK(qdev, DRV, ERR,
172 "Unsupported AE %.08x.\n", mbcp->mbox_out[0]);
173 /* Clear the MPI firmware status. */
174 }
175end:
176 ql_write32(qdev, CSR, CSR_CMD_CLR_R2PCI_INT);
177 return status;
178}
179
127void ql_mpi_work(struct work_struct *work) 180void ql_mpi_work(struct work_struct *work)
128{ 181{
129 struct ql_adapter *qdev = 182 struct ql_adapter *qdev =
130 container_of(work, struct ql_adapter, mpi_work.work); 183 container_of(work, struct ql_adapter, mpi_work.work);
131 struct mbox_params mbc; 184 struct mbox_params mbc;
132 struct mbox_params *mbcp = &mbc; 185 struct mbox_params *mbcp = &mbc;
133 mbcp->out_count = 1;
134 186
135 while (ql_read32(qdev, STS) & STS_PI) { 187 mutex_lock(&qdev->mpi_mutex);
136 if (ql_get_mb_sts(qdev, mbcp)) {
137 QPRINTK(qdev, DRV, ERR,
138 "Could not read MPI, resetting ASIC!\n");
139 ql_queue_asic_error(qdev);
140 }
141 188
142 switch (mbcp->mbox_out[0]) { 189 while (ql_read32(qdev, STS) & STS_PI) {
143 case AEN_LINK_UP: 190 memset(mbcp, 0, sizeof(struct mbox_params));
144 ql_link_up(qdev, mbcp); 191 mbcp->out_count = 1;
145 break; 192 ql_mpi_handler(qdev, mbcp);
146 case AEN_LINK_DOWN:
147 ql_link_down(qdev, mbcp);
148 break;
149 case AEN_FW_INIT_DONE:
150 ql_init_fw_done(qdev, mbcp);
151 break;
152 case MB_CMD_STS_GOOD:
153 break;
154 case AEN_FW_INIT_FAIL:
155 case AEN_SYS_ERR:
156 case MB_CMD_STS_ERR:
157 ql_queue_fw_error(qdev);
158 default:
159 /* Clear the MPI firmware status. */
160 ql_write32(qdev, CSR, CSR_CMD_CLR_R2PCI_INT);
161 break;
162 }
163 } 193 }
194
195 mutex_unlock(&qdev->mpi_mutex);
164 ql_enable_completion_interrupt(qdev, 0); 196 ql_enable_completion_interrupt(qdev, 0);
165} 197}
166 198