xref: /openbmc/linux/drivers/scsi/qla4xxx/ql4_bsg.c (revision e3976af5)
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
qla4xxx_read_flash(struct bsg_job * bsg_job)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
qla4xxx_update_flash(struct bsg_job * bsg_job)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
qla4xxx_get_acb_state(struct bsg_job * bsg_job)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
qla4xxx_read_nvram(struct bsg_job * bsg_job)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
qla4xxx_update_nvram(struct bsg_job * bsg_job)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
qla4xxx_restore_defaults(struct bsg_job * bsg_job)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
qla4xxx_bsg_get_acb(struct bsg_job * bsg_job)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 
ql4xxx_execute_diag_cmd(struct bsg_job * bsg_job)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 
qla4_83xx_wait_for_loopback_config_comp(struct scsi_qla_host * ha,int wait_for_link)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 
qla4_83xx_pre_loopback_config(struct scsi_qla_host * ha,uint32_t * mbox_cmd)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 
qla4_83xx_post_loopback_config(struct scsi_qla_host * ha,uint32_t * mbox_cmd)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 
qla4xxx_execute_diag_loopback_cmd(struct bsg_job * bsg_job)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 
qla4xxx_execute_diag_test(struct bsg_job * bsg_job)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  **/
qla4xxx_process_vendor_specific(struct bsg_job * bsg_job)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  */
qla4xxx_bsg_request(struct bsg_job * bsg_job)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 }
873