Merge branch 'fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/djbw/async_tx
[linux-2.6/linux-acpi-2.6/ibm-acpi-2.6.git] / drivers / net / qlge / qlge_mpi.c
blobfa31891b6e624bf00c47c78a4d9e986804c4728c
1 #include "qlge.h"
3 static int ql_read_mbox_reg(struct ql_adapter *qdev, u32 reg, u32 *data)
5 int status;
6 /* wait for reg to come ready */
7 status = ql_wait_reg_rdy(qdev, PROC_ADDR, PROC_ADDR_RDY, PROC_ADDR_ERR);
8 if (status)
9 goto exit;
10 /* set up for reg read */
11 ql_write32(qdev, PROC_ADDR, reg | PROC_ADDR_R);
12 /* wait for reg to come ready */
13 status = ql_wait_reg_rdy(qdev, PROC_ADDR, PROC_ADDR_RDY, PROC_ADDR_ERR);
14 if (status)
15 goto exit;
16 /* get the data */
17 *data = ql_read32(qdev, PROC_DATA);
18 exit:
19 return status;
22 static int ql_get_mb_sts(struct ql_adapter *qdev, struct mbox_params *mbcp)
24 int i, status;
26 status = ql_sem_spinlock(qdev, SEM_PROC_REG_MASK);
27 if (status)
28 return -EBUSY;
29 for (i = 0; i < mbcp->out_count; i++) {
30 status =
31 ql_read_mbox_reg(qdev, qdev->mailbox_out + i,
32 &mbcp->mbox_out[i]);
33 if (status) {
34 QPRINTK(qdev, DRV, ERR, "Failed mailbox read.\n");
35 break;
38 ql_sem_unlock(qdev, SEM_PROC_REG_MASK); /* does flush too */
39 return status;
42 static void ql_link_up(struct ql_adapter *qdev, struct mbox_params *mbcp)
44 mbcp->out_count = 2;
46 if (ql_get_mb_sts(qdev, mbcp))
47 goto exit;
49 qdev->link_status = mbcp->mbox_out[1];
50 QPRINTK(qdev, DRV, ERR, "Link Up.\n");
51 QPRINTK(qdev, DRV, INFO, "Link Status = 0x%.08x.\n", mbcp->mbox_out[1]);
52 if (!netif_carrier_ok(qdev->ndev)) {
53 QPRINTK(qdev, LINK, INFO, "Link is Up.\n");
54 netif_carrier_on(qdev->ndev);
55 netif_wake_queue(qdev->ndev);
57 exit:
58 /* Clear the MPI firmware status. */
59 ql_write32(qdev, CSR, CSR_CMD_CLR_R2PCI_INT);
62 static void ql_link_down(struct ql_adapter *qdev, struct mbox_params *mbcp)
64 mbcp->out_count = 3;
66 if (ql_get_mb_sts(qdev, mbcp)) {
67 QPRINTK(qdev, DRV, ERR, "Firmware did not initialize!\n");
68 goto exit;
71 if (netif_carrier_ok(qdev->ndev)) {
72 QPRINTK(qdev, LINK, INFO, "Link is Down.\n");
73 netif_carrier_off(qdev->ndev);
74 netif_stop_queue(qdev->ndev);
76 QPRINTK(qdev, DRV, ERR, "Link Down.\n");
77 QPRINTK(qdev, DRV, ERR, "Link Status = 0x%.08x.\n", mbcp->mbox_out[1]);
78 exit:
79 /* Clear the MPI firmware status. */
80 ql_write32(qdev, CSR, CSR_CMD_CLR_R2PCI_INT);
83 static void ql_init_fw_done(struct ql_adapter *qdev, struct mbox_params *mbcp)
85 mbcp->out_count = 2;
87 if (ql_get_mb_sts(qdev, mbcp)) {
88 QPRINTK(qdev, DRV, ERR, "Firmware did not initialize!\n");
89 goto exit;
91 QPRINTK(qdev, DRV, ERR, "Firmware initialized!\n");
92 QPRINTK(qdev, DRV, ERR, "Firmware status = 0x%.08x.\n",
93 mbcp->mbox_out[0]);
94 QPRINTK(qdev, DRV, ERR, "Firmware Revision = 0x%.08x.\n",
95 mbcp->mbox_out[1]);
96 exit:
97 /* Clear the MPI firmware status. */
98 ql_write32(qdev, CSR, CSR_CMD_CLR_R2PCI_INT);
101 void ql_mpi_work(struct work_struct *work)
103 struct ql_adapter *qdev =
104 container_of(work, struct ql_adapter, mpi_work.work);
105 struct mbox_params mbc;
106 struct mbox_params *mbcp = &mbc;
107 mbcp->out_count = 1;
109 while (ql_read32(qdev, STS) & STS_PI) {
110 if (ql_get_mb_sts(qdev, mbcp)) {
111 QPRINTK(qdev, DRV, ERR,
112 "Could not read MPI, resetting ASIC!\n");
113 ql_queue_asic_error(qdev);
116 switch (mbcp->mbox_out[0]) {
117 case AEN_LINK_UP:
118 ql_link_up(qdev, mbcp);
119 break;
120 case AEN_LINK_DOWN:
121 ql_link_down(qdev, mbcp);
122 break;
123 case AEN_FW_INIT_DONE:
124 ql_init_fw_done(qdev, mbcp);
125 break;
126 case MB_CMD_STS_GOOD:
127 break;
128 case AEN_FW_INIT_FAIL:
129 case AEN_SYS_ERR:
130 case MB_CMD_STS_ERR:
131 ql_queue_fw_error(qdev);
132 default:
133 /* Clear the MPI firmware status. */
134 ql_write32(qdev, CSR, CSR_CMD_CLR_R2PCI_INT);
135 break;
138 ql_enable_completion_interrupt(qdev, 0);
141 void ql_mpi_reset_work(struct work_struct *work)
143 struct ql_adapter *qdev =
144 container_of(work, struct ql_adapter, mpi_reset_work.work);
145 QPRINTK(qdev, DRV, ERR,
146 "Enter, qdev = %p..\n", qdev);
147 ql_write32(qdev, CSR, CSR_CMD_SET_RST);
148 msleep(50);
149 ql_write32(qdev, CSR, CSR_CMD_CLR_RST);