aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/qlge/qlge.h3
-rw-r--r--drivers/net/qlge/qlge_main.c4
-rw-r--r--drivers/net/qlge/qlge_mpi.c143
3 files changed, 149 insertions, 1 deletions
diff --git a/drivers/net/qlge/qlge.h b/drivers/net/qlge/qlge.h
index 6f9fd24bf384..9918106f2a53 100644
--- a/drivers/net/qlge/qlge.h
+++ b/drivers/net/qlge/qlge.h
@@ -1499,6 +1499,7 @@ struct ql_adapter {
1499 struct delayed_work mpi_reset_work; 1499 struct delayed_work mpi_reset_work;
1500 struct delayed_work mpi_work; 1500 struct delayed_work mpi_work;
1501 struct delayed_work mpi_port_cfg_work; 1501 struct delayed_work mpi_port_cfg_work;
1502 struct delayed_work mpi_idc_work;
1502 struct completion ide_completion; 1503 struct completion ide_completion;
1503 struct nic_operations *nic_ops; 1504 struct nic_operations *nic_ops;
1504 u16 device_id; 1505 u16 device_id;
@@ -1574,8 +1575,10 @@ void ql_queue_asic_error(struct ql_adapter *qdev);
1574u32 ql_enable_completion_interrupt(struct ql_adapter *qdev, u32 intr); 1575u32 ql_enable_completion_interrupt(struct ql_adapter *qdev, u32 intr);
1575void ql_set_ethtool_ops(struct net_device *ndev); 1576void ql_set_ethtool_ops(struct net_device *ndev);
1576int ql_read_xgmac_reg64(struct ql_adapter *qdev, u32 reg, u64 *data); 1577int ql_read_xgmac_reg64(struct ql_adapter *qdev, u32 reg, u64 *data);
1578void ql_mpi_idc_work(struct work_struct *work);
1577void ql_mpi_port_cfg_work(struct work_struct *work); 1579void ql_mpi_port_cfg_work(struct work_struct *work);
1578int ql_mb_get_fw_state(struct ql_adapter *qdev); 1580int ql_mb_get_fw_state(struct ql_adapter *qdev);
1581int ql_cam_route_initialize(struct ql_adapter *qdev);
1579 1582
1580#if 1 1583#if 1
1581#define QL_ALL_DUMP 1584#define QL_ALL_DUMP
diff --git a/drivers/net/qlge/qlge_main.c b/drivers/net/qlge/qlge_main.c
index 7c1ce5765759..d800ff40b32b 100644
--- a/drivers/net/qlge/qlge_main.c
+++ b/drivers/net/qlge/qlge_main.c
@@ -3014,7 +3014,7 @@ exit:
3014 return status; 3014 return status;
3015} 3015}
3016 3016
3017static int ql_cam_route_initialize(struct ql_adapter *qdev) 3017int ql_cam_route_initialize(struct ql_adapter *qdev)
3018{ 3018{
3019 int status; 3019 int status;
3020 3020
@@ -3195,6 +3195,7 @@ static int ql_adapter_down(struct ql_adapter *qdev)
3195 cancel_delayed_work_sync(&qdev->asic_reset_work); 3195 cancel_delayed_work_sync(&qdev->asic_reset_work);
3196 cancel_delayed_work_sync(&qdev->mpi_reset_work); 3196 cancel_delayed_work_sync(&qdev->mpi_reset_work);
3197 cancel_delayed_work_sync(&qdev->mpi_work); 3197 cancel_delayed_work_sync(&qdev->mpi_work);
3198 cancel_delayed_work_sync(&qdev->mpi_idc_work);
3198 cancel_delayed_work_sync(&qdev->mpi_port_cfg_work); 3199 cancel_delayed_work_sync(&qdev->mpi_port_cfg_work);
3199 3200
3200 /* The default queue at index 0 is always processed in 3201 /* The default queue at index 0 is always processed in
@@ -3782,6 +3783,7 @@ static int __devinit ql_init_device(struct pci_dev *pdev,
3782 INIT_DELAYED_WORK(&qdev->mpi_reset_work, ql_mpi_reset_work); 3783 INIT_DELAYED_WORK(&qdev->mpi_reset_work, ql_mpi_reset_work);
3783 INIT_DELAYED_WORK(&qdev->mpi_work, ql_mpi_work); 3784 INIT_DELAYED_WORK(&qdev->mpi_work, ql_mpi_work);
3784 INIT_DELAYED_WORK(&qdev->mpi_port_cfg_work, ql_mpi_port_cfg_work); 3785 INIT_DELAYED_WORK(&qdev->mpi_port_cfg_work, ql_mpi_port_cfg_work);
3786 INIT_DELAYED_WORK(&qdev->mpi_idc_work, ql_mpi_idc_work);
3785 mutex_init(&qdev->mpi_mutex); 3787 mutex_init(&qdev->mpi_mutex);
3786 init_completion(&qdev->ide_completion); 3788 init_completion(&qdev->ide_completion);
3787 3789
diff --git a/drivers/net/qlge/qlge_mpi.c b/drivers/net/qlge/qlge_mpi.c
index 3b4b494387aa..9f1fe542e271 100644
--- a/drivers/net/qlge/qlge_mpi.c
+++ b/drivers/net/qlge/qlge_mpi.c
@@ -138,6 +138,40 @@ end:
138 return status; 138 return status;
139} 139}
140 140
141/* We are being asked by firmware to accept
142 * a change to the port. This is only
143 * a change to max frame sizes (Tx/Rx), pause
144 * paramters, or loopback mode. We wake up a worker
145 * to handler processing this since a mailbox command
146 * will need to be sent to ACK the request.
147 */
148static int ql_idc_req_aen(struct ql_adapter *qdev)
149{
150 int status;
151 struct mbox_params *mbcp = &qdev->idc_mbc;
152
153 QPRINTK(qdev, DRV, ERR, "Enter!\n");
154 /* Get the status data and start up a thread to
155 * handle the request.
156 */
157 mbcp = &qdev->idc_mbc;
158 mbcp->out_count = 4;
159 status = ql_get_mb_sts(qdev, mbcp);
160 if (status) {
161 QPRINTK(qdev, DRV, ERR,
162 "Could not read MPI, resetting ASIC!\n");
163 ql_queue_asic_error(qdev);
164 } else {
165 /* Begin polled mode early so
166 * we don't get another interrupt
167 * when we leave mpi_worker.
168 */
169 ql_write32(qdev, INTR_MASK, (INTR_MASK_PI << 16));
170 queue_delayed_work(qdev->workqueue, &qdev->mpi_idc_work, 0);
171 }
172 return status;
173}
174
141/* Process an inter-device event completion. 175/* Process an inter-device event completion.
142 * If good, signal the caller's completion. 176 * If good, signal the caller's completion.
143 */ 177 */
@@ -175,6 +209,35 @@ static void ql_link_up(struct ql_adapter *qdev, struct mbox_params *mbcp)
175 qdev->link_status = mbcp->mbox_out[1]; 209 qdev->link_status = mbcp->mbox_out[1];
176 QPRINTK(qdev, DRV, ERR, "Link Up.\n"); 210 QPRINTK(qdev, DRV, ERR, "Link Up.\n");
177 211
212 /* If we're coming back from an IDC event
213 * then set up the CAM and frame routing.
214 */
215 if (test_bit(QL_CAM_RT_SET, &qdev->flags)) {
216 status = ql_cam_route_initialize(qdev);
217 if (status) {
218 QPRINTK(qdev, IFUP, ERR,
219 "Failed to init CAM/Routing tables.\n");
220 return;
221 } else
222 clear_bit(QL_CAM_RT_SET, &qdev->flags);
223 }
224
225 /* Queue up a worker to check the frame
226 * size information, and fix it if it's not
227 * to our liking.
228 */
229 if (!test_bit(QL_PORT_CFG, &qdev->flags)) {
230 QPRINTK(qdev, DRV, ERR, "Queue Port Config Worker!\n");
231 set_bit(QL_PORT_CFG, &qdev->flags);
232 /* Begin polled mode early so
233 * we don't get another interrupt
234 * when we leave mpi_worker dpc.
235 */
236 ql_write32(qdev, INTR_MASK, (INTR_MASK_PI << 16));
237 queue_delayed_work(qdev->workqueue,
238 &qdev->mpi_port_cfg_work, 0);
239 }
240
178 netif_carrier_on(qdev->ndev); 241 netif_carrier_on(qdev->ndev);
179} 242}
180 243
@@ -283,6 +346,15 @@ static int ql_mpi_handler(struct ql_adapter *qdev, struct mbox_params *mbcp)
283 status = ql_get_mb_sts(qdev, mbcp); 346 status = ql_get_mb_sts(qdev, mbcp);
284 return status; 347 return status;
285 348
349 /* We are being asked by firmware to accept
350 * a change to the port. This is only
351 * a change to max frame sizes (Tx/Rx), pause
352 * paramters, or loopback mode.
353 */
354 case AEN_IDC_REQ:
355 status = ql_idc_req_aen(qdev);
356 break;
357
286 /* Process and inbound IDC event. 358 /* Process and inbound IDC event.
287 * This will happen when we're trying to 359 * This will happen when we're trying to
288 * change tx/rx max frame size, change pause 360 * change tx/rx max frame size, change pause
@@ -451,6 +523,38 @@ int ql_mb_get_fw_state(struct ql_adapter *qdev)
451 return status; 523 return status;
452} 524}
453 525
526/* Send and ACK mailbox command to the firmware to
527 * let it continue with the change.
528 */
529int ql_mb_idc_ack(struct ql_adapter *qdev)
530{
531 struct mbox_params mbc;
532 struct mbox_params *mbcp = &mbc;
533 int status = 0;
534
535 memset(mbcp, 0, sizeof(struct mbox_params));
536
537 mbcp->in_count = 5;
538 mbcp->out_count = 1;
539
540 mbcp->mbox_in[0] = MB_CMD_IDC_ACK;
541 mbcp->mbox_in[1] = qdev->idc_mbc.mbox_out[1];
542 mbcp->mbox_in[2] = qdev->idc_mbc.mbox_out[2];
543 mbcp->mbox_in[3] = qdev->idc_mbc.mbox_out[3];
544 mbcp->mbox_in[4] = qdev->idc_mbc.mbox_out[4];
545
546 status = ql_mailbox_command(qdev, mbcp);
547 if (status)
548 return status;
549
550 if (mbcp->mbox_out[0] != MB_CMD_STS_GOOD) {
551 QPRINTK(qdev, DRV, ERR,
552 "Failed IDC ACK send.\n");
553 status = -EIO;
554 }
555 return status;
556}
557
454/* Get link settings and maximum frame size settings 558/* Get link settings and maximum frame size settings
455 * for the current port. 559 * for the current port.
456 * Most likely will block. 560 * Most likely will block.
@@ -627,6 +731,44 @@ err:
627 goto end; 731 goto end;
628} 732}
629 733
734/* Process an inter-device request. This is issues by
735 * the firmware in response to another function requesting
736 * a change to the port. We set a flag to indicate a change
737 * has been made and then send a mailbox command ACKing
738 * the change request.
739 */
740void ql_mpi_idc_work(struct work_struct *work)
741{
742 struct ql_adapter *qdev =
743 container_of(work, struct ql_adapter, mpi_idc_work.work);
744 int status;
745 struct mbox_params *mbcp = &qdev->idc_mbc;
746 u32 aen;
747
748 aen = mbcp->mbox_out[1] >> 16;
749
750 switch (aen) {
751 default:
752 QPRINTK(qdev, DRV, ERR,
753 "Bug: Unhandled IDC action.\n");
754 break;
755 case MB_CMD_PORT_RESET:
756 case MB_CMD_SET_PORT_CFG:
757 case MB_CMD_STOP_FW:
758 netif_carrier_off(qdev->ndev);
759 /* Signal the resulting link up AEN
760 * that the frame routing and mac addr
761 * needs to be set.
762 * */
763 set_bit(QL_CAM_RT_SET, &qdev->flags);
764 status = ql_mb_idc_ack(qdev);
765 if (status) {
766 QPRINTK(qdev, DRV, ERR,
767 "Bug: No pending IDC!\n");
768 }
769 }
770}
771
630void ql_mpi_work(struct work_struct *work) 772void ql_mpi_work(struct work_struct *work)
631{ 773{
632 struct ql_adapter *qdev = 774 struct ql_adapter *qdev =
@@ -652,5 +794,6 @@ void ql_mpi_reset_work(struct work_struct *work)
652 container_of(work, struct ql_adapter, mpi_reset_work.work); 794 container_of(work, struct ql_adapter, mpi_reset_work.work);
653 cancel_delayed_work_sync(&qdev->mpi_work); 795 cancel_delayed_work_sync(&qdev->mpi_work);
654 cancel_delayed_work_sync(&qdev->mpi_port_cfg_work); 796 cancel_delayed_work_sync(&qdev->mpi_port_cfg_work);
797 cancel_delayed_work_sync(&qdev->mpi_idc_work);
655 ql_soft_reset_mpi_risc(qdev); 798 ql_soft_reset_mpi_risc(qdev);
656} 799}