Merge tag 'trace-v5.19' of git://git.kernel.org/pub/scm/linux/kernel/git/rostedt...
[linux-2.6-microblaze.git] / drivers / scsi / qla4xxx / ql4_bsg.c
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * QLogic iSCSI HBA Driver
4  * Copyright (c) 2011-2013 QLogic Corporation
5  */
6
7 #include "ql4_def.h"
8 #include "ql4_glbl.h"
9 #include "ql4_bsg.h"
10
11 static int
12 qla4xxx_read_flash(struct bsg_job *bsg_job)
13 {
14         struct Scsi_Host *host = iscsi_job_to_shost(bsg_job);
15         struct scsi_qla_host *ha = to_qla_host(host);
16         struct iscsi_bsg_reply *bsg_reply = bsg_job->reply;
17         struct iscsi_bsg_request *bsg_req = bsg_job->request;
18         uint32_t offset = 0;
19         uint32_t length = 0;
20         dma_addr_t flash_dma;
21         uint8_t *flash = NULL;
22         int rval = -EINVAL;
23
24         bsg_reply->reply_payload_rcv_len = 0;
25
26         if (unlikely(pci_channel_offline(ha->pdev)))
27                 goto leave;
28
29         if (ql4xxx_reset_active(ha)) {
30                 ql4_printk(KERN_ERR, ha, "%s: reset active\n", __func__);
31                 rval = -EBUSY;
32                 goto leave;
33         }
34
35         if (ha->flash_state != QLFLASH_WAITING) {
36                 ql4_printk(KERN_ERR, ha, "%s: another flash operation "
37                            "active\n", __func__);
38                 rval = -EBUSY;
39                 goto leave;
40         }
41
42         ha->flash_state = QLFLASH_READING;
43         offset = bsg_req->rqst_data.h_vendor.vendor_cmd[1];
44         length = bsg_job->reply_payload.payload_len;
45
46         flash = dma_alloc_coherent(&ha->pdev->dev, length, &flash_dma,
47                                    GFP_KERNEL);
48         if (!flash) {
49                 ql4_printk(KERN_ERR, ha, "%s: dma alloc failed for flash "
50                            "data\n", __func__);
51                 rval = -ENOMEM;
52                 goto leave;
53         }
54
55         rval = qla4xxx_get_flash(ha, flash_dma, offset, length);
56         if (rval) {
57                 ql4_printk(KERN_ERR, ha, "%s: get flash failed\n", __func__);
58                 bsg_reply->result = DID_ERROR << 16;
59                 rval = -EIO;
60         } else {
61                 bsg_reply->reply_payload_rcv_len =
62                         sg_copy_from_buffer(bsg_job->reply_payload.sg_list,
63                                             bsg_job->reply_payload.sg_cnt,
64                                             flash, length);
65                 bsg_reply->result = DID_OK << 16;
66         }
67
68         bsg_job_done(bsg_job, bsg_reply->result,
69                      bsg_reply->reply_payload_rcv_len);
70         dma_free_coherent(&ha->pdev->dev, length, flash, flash_dma);
71 leave:
72         ha->flash_state = QLFLASH_WAITING;
73         return rval;
74 }
75
76 static int
77 qla4xxx_update_flash(struct bsg_job *bsg_job)
78 {
79         struct Scsi_Host *host = iscsi_job_to_shost(bsg_job);
80         struct scsi_qla_host *ha = to_qla_host(host);
81         struct iscsi_bsg_reply *bsg_reply = bsg_job->reply;
82         struct iscsi_bsg_request *bsg_req = bsg_job->request;
83         uint32_t length = 0;
84         uint32_t offset = 0;
85         uint32_t options = 0;
86         dma_addr_t flash_dma;
87         uint8_t *flash = NULL;
88         int rval = -EINVAL;
89
90         bsg_reply->reply_payload_rcv_len = 0;
91
92         if (unlikely(pci_channel_offline(ha->pdev)))
93                 goto leave;
94
95         if (ql4xxx_reset_active(ha)) {
96                 ql4_printk(KERN_ERR, ha, "%s: reset active\n", __func__);
97                 rval = -EBUSY;
98                 goto leave;
99         }
100
101         if (ha->flash_state != QLFLASH_WAITING) {
102                 ql4_printk(KERN_ERR, ha, "%s: another flash operation "
103                            "active\n", __func__);
104                 rval = -EBUSY;
105                 goto leave;
106         }
107
108         ha->flash_state = QLFLASH_WRITING;
109         length = bsg_job->request_payload.payload_len;
110         offset = bsg_req->rqst_data.h_vendor.vendor_cmd[1];
111         options = bsg_req->rqst_data.h_vendor.vendor_cmd[2];
112
113         flash = dma_alloc_coherent(&ha->pdev->dev, length, &flash_dma,
114                                    GFP_KERNEL);
115         if (!flash) {
116                 ql4_printk(KERN_ERR, ha, "%s: dma alloc failed for flash "
117                            "data\n", __func__);
118                 rval = -ENOMEM;
119                 goto leave;
120         }
121
122         sg_copy_to_buffer(bsg_job->request_payload.sg_list,
123                           bsg_job->request_payload.sg_cnt, flash, length);
124
125         rval = qla4xxx_set_flash(ha, flash_dma, offset, length, options);
126         if (rval) {
127                 ql4_printk(KERN_ERR, ha, "%s: set flash failed\n", __func__);
128                 bsg_reply->result = DID_ERROR << 16;
129                 rval = -EIO;
130         } else
131                 bsg_reply->result = DID_OK << 16;
132
133         bsg_job_done(bsg_job, bsg_reply->result,
134                      bsg_reply->reply_payload_rcv_len);
135         dma_free_coherent(&ha->pdev->dev, length, flash, flash_dma);
136 leave:
137         ha->flash_state = QLFLASH_WAITING;
138         return rval;
139 }
140
141 static int
142 qla4xxx_get_acb_state(struct bsg_job *bsg_job)
143 {
144         struct Scsi_Host *host = iscsi_job_to_shost(bsg_job);
145         struct scsi_qla_host *ha = to_qla_host(host);
146         struct iscsi_bsg_request *bsg_req = bsg_job->request;
147         struct iscsi_bsg_reply *bsg_reply = bsg_job->reply;
148         uint32_t status[MBOX_REG_COUNT];
149         uint32_t acb_idx;
150         uint32_t ip_idx;
151         int rval = -EINVAL;
152
153         bsg_reply->reply_payload_rcv_len = 0;
154
155         if (unlikely(pci_channel_offline(ha->pdev)))
156                 goto leave;
157
158         /* Only 4022 and above adapters are supported */
159         if (is_qla4010(ha))
160                 goto leave;
161
162         if (ql4xxx_reset_active(ha)) {
163                 ql4_printk(KERN_ERR, ha, "%s: reset active\n", __func__);
164                 rval = -EBUSY;
165                 goto leave;
166         }
167
168         if (bsg_job->reply_payload.payload_len < sizeof(status)) {
169                 ql4_printk(KERN_ERR, ha, "%s: invalid payload len %d\n",
170                            __func__, bsg_job->reply_payload.payload_len);
171                 rval = -EINVAL;
172                 goto leave;
173         }
174
175         acb_idx = bsg_req->rqst_data.h_vendor.vendor_cmd[1];
176         ip_idx = bsg_req->rqst_data.h_vendor.vendor_cmd[2];
177
178         rval = qla4xxx_get_ip_state(ha, acb_idx, ip_idx, status);
179         if (rval) {
180                 ql4_printk(KERN_ERR, ha, "%s: get ip state failed\n",
181                            __func__);
182                 bsg_reply->result = DID_ERROR << 16;
183                 rval = -EIO;
184         } else {
185                 bsg_reply->reply_payload_rcv_len =
186                         sg_copy_from_buffer(bsg_job->reply_payload.sg_list,
187                                             bsg_job->reply_payload.sg_cnt,
188                                             status, sizeof(status));
189                 bsg_reply->result = DID_OK << 16;
190         }
191
192         bsg_job_done(bsg_job, bsg_reply->result,
193                      bsg_reply->reply_payload_rcv_len);
194 leave:
195         return rval;
196 }
197
198 static int
199 qla4xxx_read_nvram(struct bsg_job *bsg_job)
200 {
201         struct Scsi_Host *host = iscsi_job_to_shost(bsg_job);
202         struct scsi_qla_host *ha = to_qla_host(host);
203         struct iscsi_bsg_request *bsg_req = bsg_job->request;
204         struct iscsi_bsg_reply *bsg_reply = bsg_job->reply;
205         uint32_t offset = 0;
206         uint32_t len = 0;
207         uint32_t total_len = 0;
208         dma_addr_t nvram_dma;
209         uint8_t *nvram = NULL;
210         int rval = -EINVAL;
211
212         bsg_reply->reply_payload_rcv_len = 0;
213
214         if (unlikely(pci_channel_offline(ha->pdev)))
215                 goto leave;
216
217         /* Only 40xx adapters are supported */
218         if (!(is_qla4010(ha) || is_qla4022(ha) || is_qla4032(ha)))
219                 goto leave;
220
221         if (ql4xxx_reset_active(ha)) {
222                 ql4_printk(KERN_ERR, ha, "%s: reset active\n", __func__);
223                 rval = -EBUSY;
224                 goto leave;
225         }
226
227         offset = bsg_req->rqst_data.h_vendor.vendor_cmd[1];
228         len = bsg_job->reply_payload.payload_len;
229         total_len = offset + len;
230
231         /* total len should not be greater than max NVRAM size */
232         if ((is_qla4010(ha) && total_len > QL4010_NVRAM_SIZE) ||
233             ((is_qla4022(ha) || is_qla4032(ha)) &&
234              total_len > QL40X2_NVRAM_SIZE)) {
235                 ql4_printk(KERN_ERR, ha, "%s: offset+len greater than max"
236                            " nvram size, offset=%d len=%d\n",
237                            __func__, offset, len);
238                 goto leave;
239         }
240
241         nvram = dma_alloc_coherent(&ha->pdev->dev, len, &nvram_dma,
242                                    GFP_KERNEL);
243         if (!nvram) {
244                 ql4_printk(KERN_ERR, ha, "%s: dma alloc failed for nvram "
245                            "data\n", __func__);
246                 rval = -ENOMEM;
247                 goto leave;
248         }
249
250         rval = qla4xxx_get_nvram(ha, nvram_dma, offset, len);
251         if (rval) {
252                 ql4_printk(KERN_ERR, ha, "%s: get nvram failed\n", __func__);
253                 bsg_reply->result = DID_ERROR << 16;
254                 rval = -EIO;
255         } else {
256                 bsg_reply->reply_payload_rcv_len =
257                         sg_copy_from_buffer(bsg_job->reply_payload.sg_list,
258                                             bsg_job->reply_payload.sg_cnt,
259                                             nvram, len);
260                 bsg_reply->result = DID_OK << 16;
261         }
262
263         bsg_job_done(bsg_job, bsg_reply->result,
264                      bsg_reply->reply_payload_rcv_len);
265         dma_free_coherent(&ha->pdev->dev, len, nvram, nvram_dma);
266 leave:
267         return rval;
268 }
269
270 static int
271 qla4xxx_update_nvram(struct bsg_job *bsg_job)
272 {
273         struct Scsi_Host *host = iscsi_job_to_shost(bsg_job);
274         struct scsi_qla_host *ha = to_qla_host(host);
275         struct iscsi_bsg_request *bsg_req = bsg_job->request;
276         struct iscsi_bsg_reply *bsg_reply = bsg_job->reply;
277         uint32_t offset = 0;
278         uint32_t len = 0;
279         uint32_t total_len = 0;
280         dma_addr_t nvram_dma;
281         uint8_t *nvram = NULL;
282         int rval = -EINVAL;
283
284         bsg_reply->reply_payload_rcv_len = 0;
285
286         if (unlikely(pci_channel_offline(ha->pdev)))
287                 goto leave;
288
289         if (!(is_qla4010(ha) || is_qla4022(ha) || is_qla4032(ha)))
290                 goto leave;
291
292         if (ql4xxx_reset_active(ha)) {
293                 ql4_printk(KERN_ERR, ha, "%s: reset active\n", __func__);
294                 rval = -EBUSY;
295                 goto leave;
296         }
297
298         offset = bsg_req->rqst_data.h_vendor.vendor_cmd[1];
299         len = bsg_job->request_payload.payload_len;
300         total_len = offset + len;
301
302         /* total len should not be greater than max NVRAM size */
303         if ((is_qla4010(ha) && total_len > QL4010_NVRAM_SIZE) ||
304             ((is_qla4022(ha) || is_qla4032(ha)) &&
305              total_len > QL40X2_NVRAM_SIZE)) {
306                 ql4_printk(KERN_ERR, ha, "%s: offset+len greater than max"
307                            " nvram size, offset=%d len=%d\n",
308                            __func__, offset, len);
309                 goto leave;
310         }
311
312         nvram = dma_alloc_coherent(&ha->pdev->dev, len, &nvram_dma,
313                                    GFP_KERNEL);
314         if (!nvram) {
315                 ql4_printk(KERN_ERR, ha, "%s: dma alloc failed for flash "
316                            "data\n", __func__);
317                 rval = -ENOMEM;
318                 goto leave;
319         }
320
321         sg_copy_to_buffer(bsg_job->request_payload.sg_list,
322                           bsg_job->request_payload.sg_cnt, nvram, len);
323
324         rval = qla4xxx_set_nvram(ha, nvram_dma, offset, len);
325         if (rval) {
326                 ql4_printk(KERN_ERR, ha, "%s: set nvram failed\n", __func__);
327                 bsg_reply->result = DID_ERROR << 16;
328                 rval = -EIO;
329         } else
330                 bsg_reply->result = DID_OK << 16;
331
332         bsg_job_done(bsg_job, bsg_reply->result,
333                      bsg_reply->reply_payload_rcv_len);
334         dma_free_coherent(&ha->pdev->dev, len, nvram, nvram_dma);
335 leave:
336         return rval;
337 }
338
339 static int
340 qla4xxx_restore_defaults(struct bsg_job *bsg_job)
341 {
342         struct Scsi_Host *host = iscsi_job_to_shost(bsg_job);
343         struct scsi_qla_host *ha = to_qla_host(host);
344         struct iscsi_bsg_request *bsg_req = bsg_job->request;
345         struct iscsi_bsg_reply *bsg_reply = bsg_job->reply;
346         uint32_t region = 0;
347         uint32_t field0 = 0;
348         uint32_t field1 = 0;
349         int rval = -EINVAL;
350
351         bsg_reply->reply_payload_rcv_len = 0;
352
353         if (unlikely(pci_channel_offline(ha->pdev)))
354                 goto leave;
355
356         if (is_qla4010(ha))
357                 goto leave;
358
359         if (ql4xxx_reset_active(ha)) {
360                 ql4_printk(KERN_ERR, ha, "%s: reset active\n", __func__);
361                 rval = -EBUSY;
362                 goto leave;
363         }
364
365         region = bsg_req->rqst_data.h_vendor.vendor_cmd[1];
366         field0 = bsg_req->rqst_data.h_vendor.vendor_cmd[2];
367         field1 = bsg_req->rqst_data.h_vendor.vendor_cmd[3];
368
369         rval = qla4xxx_restore_factory_defaults(ha, region, field0, field1);
370         if (rval) {
371                 ql4_printk(KERN_ERR, ha, "%s: set nvram failed\n", __func__);
372                 bsg_reply->result = DID_ERROR << 16;
373                 rval = -EIO;
374         } else
375                 bsg_reply->result = DID_OK << 16;
376
377         bsg_job_done(bsg_job, bsg_reply->result,
378                      bsg_reply->reply_payload_rcv_len);
379 leave:
380         return rval;
381 }
382
383 static int
384 qla4xxx_bsg_get_acb(struct bsg_job *bsg_job)
385 {
386         struct Scsi_Host *host = iscsi_job_to_shost(bsg_job);
387         struct scsi_qla_host *ha = to_qla_host(host);
388         struct iscsi_bsg_request *bsg_req = bsg_job->request;
389         struct iscsi_bsg_reply *bsg_reply = bsg_job->reply;
390         uint32_t acb_type = 0;
391         uint32_t len = 0;
392         dma_addr_t acb_dma;
393         uint8_t *acb = NULL;
394         int rval = -EINVAL;
395
396         bsg_reply->reply_payload_rcv_len = 0;
397
398         if (unlikely(pci_channel_offline(ha->pdev)))
399                 goto leave;
400
401         /* Only 4022 and above adapters are supported */
402         if (is_qla4010(ha))
403                 goto leave;
404
405         if (ql4xxx_reset_active(ha)) {
406                 ql4_printk(KERN_ERR, ha, "%s: reset active\n", __func__);
407                 rval = -EBUSY;
408                 goto leave;
409         }
410
411         acb_type = bsg_req->rqst_data.h_vendor.vendor_cmd[1];
412         len = bsg_job->reply_payload.payload_len;
413         if (len < sizeof(struct addr_ctrl_blk)) {
414                 ql4_printk(KERN_ERR, ha, "%s: invalid acb len %d\n",
415                            __func__, len);
416                 rval = -EINVAL;
417                 goto leave;
418         }
419
420         acb = dma_alloc_coherent(&ha->pdev->dev, len, &acb_dma, GFP_KERNEL);
421         if (!acb) {
422                 ql4_printk(KERN_ERR, ha, "%s: dma alloc failed for acb "
423                            "data\n", __func__);
424                 rval = -ENOMEM;
425                 goto leave;
426         }
427
428         rval = qla4xxx_get_acb(ha, acb_dma, acb_type, len);
429         if (rval) {
430                 ql4_printk(KERN_ERR, ha, "%s: get acb failed\n", __func__);
431                 bsg_reply->result = DID_ERROR << 16;
432                 rval = -EIO;
433         } else {
434                 bsg_reply->reply_payload_rcv_len =
435                         sg_copy_from_buffer(bsg_job->reply_payload.sg_list,
436                                             bsg_job->reply_payload.sg_cnt,
437                                             acb, len);
438                 bsg_reply->result = DID_OK << 16;
439         }
440
441         bsg_job_done(bsg_job, bsg_reply->result,
442                      bsg_reply->reply_payload_rcv_len);
443         dma_free_coherent(&ha->pdev->dev, len, acb, acb_dma);
444 leave:
445         return rval;
446 }
447
448 static void ql4xxx_execute_diag_cmd(struct bsg_job *bsg_job)
449 {
450         struct Scsi_Host *host = iscsi_job_to_shost(bsg_job);
451         struct scsi_qla_host *ha = to_qla_host(host);
452         struct iscsi_bsg_request *bsg_req = bsg_job->request;
453         struct iscsi_bsg_reply *bsg_reply = bsg_job->reply;
454         uint8_t *rsp_ptr = NULL;
455         uint32_t mbox_cmd[MBOX_REG_COUNT];
456         uint32_t mbox_sts[MBOX_REG_COUNT];
457         int status = QLA_ERROR;
458
459         DEBUG2(ql4_printk(KERN_INFO, ha, "%s: in\n", __func__));
460
461         if (test_bit(DPC_RESET_HA, &ha->dpc_flags)) {
462                 ql4_printk(KERN_INFO, ha, "%s: Adapter reset in progress. Invalid Request\n",
463                            __func__);
464                 bsg_reply->result = DID_ERROR << 16;
465                 goto exit_diag_mem_test;
466         }
467
468         bsg_reply->reply_payload_rcv_len = 0;
469         memcpy(mbox_cmd, &bsg_req->rqst_data.h_vendor.vendor_cmd[1],
470                sizeof(uint32_t) * MBOX_REG_COUNT);
471
472         DEBUG2(ql4_printk(KERN_INFO, ha,
473                           "%s: mbox_cmd: %08X %08X %08X %08X %08X %08X %08X %08X\n",
474                           __func__, mbox_cmd[0], mbox_cmd[1], mbox_cmd[2],
475                           mbox_cmd[3], mbox_cmd[4], mbox_cmd[5], mbox_cmd[6],
476                           mbox_cmd[7]));
477
478         status = qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, 8, &mbox_cmd[0],
479                                          &mbox_sts[0]);
480
481         DEBUG2(ql4_printk(KERN_INFO, ha,
482                           "%s: mbox_sts: %08X %08X %08X %08X %08X %08X %08X %08X\n",
483                           __func__, mbox_sts[0], mbox_sts[1], mbox_sts[2],
484                           mbox_sts[3], mbox_sts[4], mbox_sts[5], mbox_sts[6],
485                           mbox_sts[7]));
486
487         if (status == QLA_SUCCESS)
488                 bsg_reply->result = DID_OK << 16;
489         else
490                 bsg_reply->result = DID_ERROR << 16;
491
492         /* Send mbox_sts to application */
493         bsg_job->reply_len = sizeof(struct iscsi_bsg_reply) + sizeof(mbox_sts);
494         rsp_ptr = ((uint8_t *)bsg_reply) + sizeof(struct iscsi_bsg_reply);
495         memcpy(rsp_ptr, mbox_sts, sizeof(mbox_sts));
496
497 exit_diag_mem_test:
498         DEBUG2(ql4_printk(KERN_INFO, ha,
499                           "%s: bsg_reply->result = x%x, status = %s\n",
500                           __func__, bsg_reply->result, STATUS(status)));
501
502         bsg_job_done(bsg_job, bsg_reply->result,
503                      bsg_reply->reply_payload_rcv_len);
504 }
505
506 static int qla4_83xx_wait_for_loopback_config_comp(struct scsi_qla_host *ha,
507                                                    int wait_for_link)
508 {
509         int status = QLA_SUCCESS;
510
511         if (!wait_for_completion_timeout(&ha->idc_comp, (IDC_COMP_TOV * HZ))) {
512                 ql4_printk(KERN_INFO, ha, "%s: IDC Complete notification not received, Waiting for another %d timeout",
513                            __func__, ha->idc_extend_tmo);
514                 if (ha->idc_extend_tmo) {
515                         if (!wait_for_completion_timeout(&ha->idc_comp,
516                                                 (ha->idc_extend_tmo * HZ))) {
517                                 ha->notify_idc_comp = 0;
518                                 ha->notify_link_up_comp = 0;
519                                 ql4_printk(KERN_WARNING, ha, "%s: Aborting: IDC Complete notification not received",
520                                            __func__);
521                                 status = QLA_ERROR;
522                                 goto exit_wait;
523                         } else {
524                                 DEBUG2(ql4_printk(KERN_INFO, ha,
525                                                   "%s: IDC Complete notification received\n",
526                                                   __func__));
527                         }
528                 }
529         } else {
530                 DEBUG2(ql4_printk(KERN_INFO, ha,
531                                   "%s: IDC Complete notification received\n",
532                                   __func__));
533         }
534         ha->notify_idc_comp = 0;
535
536         if (wait_for_link) {
537                 if (!wait_for_completion_timeout(&ha->link_up_comp,
538                                                  (IDC_COMP_TOV * HZ))) {
539                         ha->notify_link_up_comp = 0;
540                         ql4_printk(KERN_WARNING, ha, "%s: Aborting: LINK UP notification not received",
541                                    __func__);
542                         status = QLA_ERROR;
543                         goto exit_wait;
544                 } else {
545                         DEBUG2(ql4_printk(KERN_INFO, ha,
546                                           "%s: LINK UP notification received\n",
547                                           __func__));
548                 }
549                 ha->notify_link_up_comp = 0;
550         }
551
552 exit_wait:
553         return status;
554 }
555
556 static int qla4_83xx_pre_loopback_config(struct scsi_qla_host *ha,
557                                          uint32_t *mbox_cmd)
558 {
559         uint32_t config = 0;
560         int status = QLA_SUCCESS;
561
562         DEBUG2(ql4_printk(KERN_INFO, ha, "%s: in\n", __func__));
563
564         status = qla4_83xx_get_port_config(ha, &config);
565         if (status != QLA_SUCCESS)
566                 goto exit_pre_loopback_config;
567
568         DEBUG2(ql4_printk(KERN_INFO, ha, "%s: Default port config=%08X\n",
569                           __func__, config));
570
571         if ((config & ENABLE_INTERNAL_LOOPBACK) ||
572             (config & ENABLE_EXTERNAL_LOOPBACK)) {
573                 ql4_printk(KERN_INFO, ha, "%s: Loopback diagnostics already in progress. Invalid request\n",
574                            __func__);
575                 goto exit_pre_loopback_config;
576         }
577
578         if (mbox_cmd[1] == QL_DIAG_CMD_TEST_INT_LOOPBACK)
579                 config |= ENABLE_INTERNAL_LOOPBACK;
580
581         if (mbox_cmd[1] == QL_DIAG_CMD_TEST_EXT_LOOPBACK)
582                 config |= ENABLE_EXTERNAL_LOOPBACK;
583
584         config &= ~ENABLE_DCBX;
585
586         DEBUG2(ql4_printk(KERN_INFO, ha, "%s: New port config=%08X\n",
587                           __func__, config));
588
589         ha->notify_idc_comp = 1;
590         ha->notify_link_up_comp = 1;
591
592         /* get the link state */
593         qla4xxx_get_firmware_state(ha);
594
595         status = qla4_83xx_set_port_config(ha, &config);
596         if (status != QLA_SUCCESS) {
597                 ha->notify_idc_comp = 0;
598                 ha->notify_link_up_comp = 0;
599                 goto exit_pre_loopback_config;
600         }
601 exit_pre_loopback_config:
602         DEBUG2(ql4_printk(KERN_INFO, ha, "%s: status = %s\n", __func__,
603                           STATUS(status)));
604         return status;
605 }
606
607 static int qla4_83xx_post_loopback_config(struct scsi_qla_host *ha,
608                                           uint32_t *mbox_cmd)
609 {
610         int status = QLA_SUCCESS;
611         uint32_t config = 0;
612
613         DEBUG2(ql4_printk(KERN_INFO, ha, "%s: in\n", __func__));
614
615         status = qla4_83xx_get_port_config(ha, &config);
616         if (status != QLA_SUCCESS)
617                 goto exit_post_loopback_config;
618
619         DEBUG2(ql4_printk(KERN_INFO, ha, "%s: port config=%08X\n", __func__,
620                           config));
621
622         if (mbox_cmd[1] == QL_DIAG_CMD_TEST_INT_LOOPBACK)
623                 config &= ~ENABLE_INTERNAL_LOOPBACK;
624         else if (mbox_cmd[1] == QL_DIAG_CMD_TEST_EXT_LOOPBACK)
625                 config &= ~ENABLE_EXTERNAL_LOOPBACK;
626
627         config |= ENABLE_DCBX;
628
629         DEBUG2(ql4_printk(KERN_INFO, ha,
630                           "%s: Restore default port config=%08X\n", __func__,
631                           config));
632
633         ha->notify_idc_comp = 1;
634         if (ha->addl_fw_state & FW_ADDSTATE_LINK_UP)
635                 ha->notify_link_up_comp = 1;
636
637         status = qla4_83xx_set_port_config(ha, &config);
638         if (status != QLA_SUCCESS) {
639                 ql4_printk(KERN_INFO, ha, "%s: Scheduling adapter reset\n",
640                            __func__);
641                 set_bit(DPC_RESET_HA, &ha->dpc_flags);
642                 clear_bit(AF_LOOPBACK, &ha->flags);
643                 goto exit_post_loopback_config;
644         }
645
646 exit_post_loopback_config:
647         DEBUG2(ql4_printk(KERN_INFO, ha, "%s: status = %s\n", __func__,
648                           STATUS(status)));
649         return status;
650 }
651
652 static void qla4xxx_execute_diag_loopback_cmd(struct bsg_job *bsg_job)
653 {
654         struct Scsi_Host *host = iscsi_job_to_shost(bsg_job);
655         struct scsi_qla_host *ha = to_qla_host(host);
656         struct iscsi_bsg_request *bsg_req = bsg_job->request;
657         struct iscsi_bsg_reply *bsg_reply = bsg_job->reply;
658         uint8_t *rsp_ptr = NULL;
659         uint32_t mbox_cmd[MBOX_REG_COUNT];
660         uint32_t mbox_sts[MBOX_REG_COUNT];
661         int wait_for_link = 1;
662         int status = QLA_ERROR;
663
664         DEBUG2(ql4_printk(KERN_INFO, ha, "%s: in\n", __func__));
665
666         bsg_reply->reply_payload_rcv_len = 0;
667
668         if (test_bit(AF_LOOPBACK, &ha->flags)) {
669                 ql4_printk(KERN_INFO, ha, "%s: Loopback Diagnostics already in progress. Invalid Request\n",
670                            __func__);
671                 bsg_reply->result = DID_ERROR << 16;
672                 goto exit_loopback_cmd;
673         }
674
675         if (test_bit(DPC_RESET_HA, &ha->dpc_flags)) {
676                 ql4_printk(KERN_INFO, ha, "%s: Adapter reset in progress. Invalid Request\n",
677                            __func__);
678                 bsg_reply->result = DID_ERROR << 16;
679                 goto exit_loopback_cmd;
680         }
681
682         memcpy(mbox_cmd, &bsg_req->rqst_data.h_vendor.vendor_cmd[1],
683                sizeof(uint32_t) * MBOX_REG_COUNT);
684
685         if (is_qla8032(ha) || is_qla8042(ha)) {
686                 status = qla4_83xx_pre_loopback_config(ha, mbox_cmd);
687                 if (status != QLA_SUCCESS) {
688                         bsg_reply->result = DID_ERROR << 16;
689                         goto exit_loopback_cmd;
690                 }
691
692                 status = qla4_83xx_wait_for_loopback_config_comp(ha,
693                                                                  wait_for_link);
694                 if (status != QLA_SUCCESS) {
695                         bsg_reply->result = DID_TIME_OUT << 16;
696                         goto restore;
697                 }
698         }
699
700         DEBUG2(ql4_printk(KERN_INFO, ha,
701                           "%s: mbox_cmd: %08X %08X %08X %08X %08X %08X %08X %08X\n",
702                           __func__, mbox_cmd[0], mbox_cmd[1], mbox_cmd[2],
703                           mbox_cmd[3], mbox_cmd[4], mbox_cmd[5], mbox_cmd[6],
704                           mbox_cmd[7]));
705
706         status = qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, 8, &mbox_cmd[0],
707                                 &mbox_sts[0]);
708
709         if (status == QLA_SUCCESS)
710                 bsg_reply->result = DID_OK << 16;
711         else
712                 bsg_reply->result = DID_ERROR << 16;
713
714         DEBUG2(ql4_printk(KERN_INFO, ha,
715                           "%s: mbox_sts: %08X %08X %08X %08X %08X %08X %08X %08X\n",
716                           __func__, mbox_sts[0], mbox_sts[1], mbox_sts[2],
717                           mbox_sts[3], mbox_sts[4], mbox_sts[5], mbox_sts[6],
718                           mbox_sts[7]));
719
720         /* Send mbox_sts to application */
721         bsg_job->reply_len = sizeof(struct iscsi_bsg_reply) + sizeof(mbox_sts);
722         rsp_ptr = ((uint8_t *)bsg_reply) + sizeof(struct iscsi_bsg_reply);
723         memcpy(rsp_ptr, mbox_sts, sizeof(mbox_sts));
724 restore:
725         if (is_qla8032(ha) || is_qla8042(ha)) {
726                 status = qla4_83xx_post_loopback_config(ha, mbox_cmd);
727                 if (status != QLA_SUCCESS) {
728                         bsg_reply->result = DID_ERROR << 16;
729                         goto exit_loopback_cmd;
730                 }
731
732                 /* for pre_loopback_config() wait for LINK UP only
733                  * if PHY LINK is UP */
734                 if (!(ha->addl_fw_state & FW_ADDSTATE_LINK_UP))
735                         wait_for_link = 0;
736
737                 status = qla4_83xx_wait_for_loopback_config_comp(ha,
738                                                                  wait_for_link);
739                 if (status != QLA_SUCCESS) {
740                         bsg_reply->result = DID_TIME_OUT << 16;
741                         goto exit_loopback_cmd;
742                 }
743         }
744 exit_loopback_cmd:
745         DEBUG2(ql4_printk(KERN_INFO, ha,
746                           "%s: bsg_reply->result = x%x, status = %s\n",
747                           __func__, bsg_reply->result, STATUS(status)));
748         bsg_job_done(bsg_job, bsg_reply->result,
749                      bsg_reply->reply_payload_rcv_len);
750 }
751
752 static int qla4xxx_execute_diag_test(struct bsg_job *bsg_job)
753 {
754         struct Scsi_Host *host = iscsi_job_to_shost(bsg_job);
755         struct scsi_qla_host *ha = to_qla_host(host);
756         struct iscsi_bsg_request *bsg_req = bsg_job->request;
757         uint32_t diag_cmd;
758         int rval = -EINVAL;
759
760         DEBUG2(ql4_printk(KERN_INFO, ha, "%s: in\n", __func__));
761
762         diag_cmd = bsg_req->rqst_data.h_vendor.vendor_cmd[1];
763         if (diag_cmd == MBOX_CMD_DIAG_TEST) {
764                 switch (bsg_req->rqst_data.h_vendor.vendor_cmd[2]) {
765                 case QL_DIAG_CMD_TEST_DDR_SIZE:
766                 case QL_DIAG_CMD_TEST_DDR_RW:
767                 case QL_DIAG_CMD_TEST_ONCHIP_MEM_RW:
768                 case QL_DIAG_CMD_TEST_NVRAM:
769                 case QL_DIAG_CMD_TEST_FLASH_ROM:
770                 case QL_DIAG_CMD_TEST_DMA_XFER:
771                 case QL_DIAG_CMD_SELF_DDR_RW:
772                 case QL_DIAG_CMD_SELF_ONCHIP_MEM_RW:
773                         /* Execute diag test for adapter RAM/FLASH */
774                         ql4xxx_execute_diag_cmd(bsg_job);
775                         /* Always return success as we want to sent bsg_reply
776                          * to Application */
777                         rval = QLA_SUCCESS;
778                         break;
779
780                 case QL_DIAG_CMD_TEST_INT_LOOPBACK:
781                 case QL_DIAG_CMD_TEST_EXT_LOOPBACK:
782                         /* Execute diag test for Network */
783                         qla4xxx_execute_diag_loopback_cmd(bsg_job);
784                         /* Always return success as we want to sent bsg_reply
785                          * to Application */
786                         rval = QLA_SUCCESS;
787                         break;
788                 default:
789                         ql4_printk(KERN_ERR, ha, "%s: Invalid diag test: 0x%x\n",
790                                    __func__,
791                                    bsg_req->rqst_data.h_vendor.vendor_cmd[2]);
792                 }
793         } else if ((diag_cmd == MBOX_CMD_SET_LED_CONFIG) ||
794                    (diag_cmd == MBOX_CMD_GET_LED_CONFIG)) {
795                 ql4xxx_execute_diag_cmd(bsg_job);
796                 rval = QLA_SUCCESS;
797         } else {
798                 ql4_printk(KERN_ERR, ha, "%s: Invalid diag cmd: 0x%x\n",
799                            __func__, diag_cmd);
800         }
801
802         return rval;
803 }
804
805 /**
806  * qla4xxx_process_vendor_specific - handle vendor specific bsg request
807  * @bsg_job: iscsi_bsg_job to handle
808  **/
809 int qla4xxx_process_vendor_specific(struct bsg_job *bsg_job)
810 {
811         struct iscsi_bsg_reply *bsg_reply = bsg_job->reply;
812         struct iscsi_bsg_request *bsg_req = bsg_job->request;
813         struct Scsi_Host *host = iscsi_job_to_shost(bsg_job);
814         struct scsi_qla_host *ha = to_qla_host(host);
815
816         switch (bsg_req->rqst_data.h_vendor.vendor_cmd[0]) {
817         case QLISCSI_VND_READ_FLASH:
818                 return qla4xxx_read_flash(bsg_job);
819
820         case QLISCSI_VND_UPDATE_FLASH:
821                 return qla4xxx_update_flash(bsg_job);
822
823         case QLISCSI_VND_GET_ACB_STATE:
824                 return qla4xxx_get_acb_state(bsg_job);
825
826         case QLISCSI_VND_READ_NVRAM:
827                 return qla4xxx_read_nvram(bsg_job);
828
829         case QLISCSI_VND_UPDATE_NVRAM:
830                 return qla4xxx_update_nvram(bsg_job);
831
832         case QLISCSI_VND_RESTORE_DEFAULTS:
833                 return qla4xxx_restore_defaults(bsg_job);
834
835         case QLISCSI_VND_GET_ACB:
836                 return qla4xxx_bsg_get_acb(bsg_job);
837
838         case QLISCSI_VND_DIAG_TEST:
839                 return qla4xxx_execute_diag_test(bsg_job);
840
841         default:
842                 ql4_printk(KERN_ERR, ha, "%s: invalid BSG vendor command: "
843                            "0x%x\n", __func__, bsg_req->msgcode);
844                 bsg_reply->result = (DID_ERROR << 16);
845                 bsg_reply->reply_payload_rcv_len = 0;
846                 bsg_job_done(bsg_job, bsg_reply->result,
847                              bsg_reply->reply_payload_rcv_len);
848                 return -ENOSYS;
849         }
850 }
851
852 /**
853  * qla4xxx_bsg_request - handle bsg request from ISCSI transport
854  * @bsg_job: iscsi_bsg_job to handle
855  */
856 int qla4xxx_bsg_request(struct bsg_job *bsg_job)
857 {
858         struct iscsi_bsg_request *bsg_req = bsg_job->request;
859         struct Scsi_Host *host = iscsi_job_to_shost(bsg_job);
860         struct scsi_qla_host *ha = to_qla_host(host);
861
862         switch (bsg_req->msgcode) {
863         case ISCSI_BSG_HST_VENDOR:
864                 return qla4xxx_process_vendor_specific(bsg_job);
865
866         default:
867                 ql4_printk(KERN_ERR, ha, "%s: invalid BSG command: 0x%x\n",
868                            __func__, bsg_req->msgcode);
869         }
870
871         return -ENOSYS;
872 }