Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/geert/linux...
[linux-2.6] / drivers / net / qlge / qlge_mpi.c
1 #include "qlge.h"
2
3 static int ql_read_mbox_reg(struct ql_adapter *qdev, u32 reg, u32 *data)
4 {
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;
20 }
21
22 static int ql_get_mb_sts(struct ql_adapter *qdev, struct mbox_params *mbcp)
23 {
24         int i, status;
25
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;
36                 }
37         }
38         ql_sem_unlock(qdev, SEM_PROC_REG_MASK); /* does flush too */
39         return status;
40 }
41
42 static void ql_link_up(struct ql_adapter *qdev, struct mbox_params *mbcp)
43 {
44         mbcp->out_count = 2;
45
46         if (ql_get_mb_sts(qdev, mbcp))
47                 goto exit;
48
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);
56         }
57 exit:
58         /* Clear the MPI firmware status. */
59         ql_write32(qdev, CSR, CSR_CMD_CLR_R2PCI_INT);
60 }
61
62 static void ql_link_down(struct ql_adapter *qdev, struct mbox_params *mbcp)
63 {
64         mbcp->out_count = 3;
65
66         if (ql_get_mb_sts(qdev, mbcp)) {
67                 QPRINTK(qdev, DRV, ERR, "Firmware did not initialize!\n");
68                 goto exit;
69         }
70
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);
75         }
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);
81 }
82
83 static void ql_init_fw_done(struct ql_adapter *qdev, struct mbox_params *mbcp)
84 {
85         mbcp->out_count = 2;
86
87         if (ql_get_mb_sts(qdev, mbcp)) {
88                 QPRINTK(qdev, DRV, ERR, "Firmware did not initialize!\n");
89                 goto exit;
90         }
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);
99 }
100
101 void ql_mpi_work(struct work_struct *work)
102 {
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;
108
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);
114                 }
115
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;
136                 }
137         }
138         ql_enable_completion_interrupt(qdev, 0);
139 }
140
141 void ql_mpi_reset_work(struct work_struct *work)
142 {
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);
150 }