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