Linux 3.17-rc2
[linux/fpc-iii.git] / drivers / scsi / be2iscsi / be_mgmt.c
blob665afcb74a56cdc1f9de12ea0bf21a973fc1cbc6
1 /**
2 * Copyright (C) 2005 - 2013 Emulex
3 * All rights reserved.
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License version 2
7 * as published by the Free Software Foundation. The full GNU General
8 * Public License is included in this distribution in the file called COPYING.
10 * Written by: Jayamohan Kallickal (jayamohan.kallickal@emulex.com)
12 * Contact Information:
13 * linux-drivers@emulex.com
15 * Emulex
16 * 3333 Susan Street
17 * Costa Mesa, CA 92626
20 #include <linux/bsg-lib.h>
21 #include <scsi/scsi_transport_iscsi.h>
22 #include <scsi/scsi_bsg_iscsi.h>
23 #include "be_mgmt.h"
24 #include "be_iscsi.h"
25 #include "be_main.h"
27 /* UE Status Low CSR */
28 static const char * const desc_ue_status_low[] = {
29 "CEV",
30 "CTX",
31 "DBUF",
32 "ERX",
33 "Host",
34 "MPU",
35 "NDMA",
36 "PTC ",
37 "RDMA ",
38 "RXF ",
39 "RXIPS ",
40 "RXULP0 ",
41 "RXULP1 ",
42 "RXULP2 ",
43 "TIM ",
44 "TPOST ",
45 "TPRE ",
46 "TXIPS ",
47 "TXULP0 ",
48 "TXULP1 ",
49 "UC ",
50 "WDMA ",
51 "TXULP2 ",
52 "HOST1 ",
53 "P0_OB_LINK ",
54 "P1_OB_LINK ",
55 "HOST_GPIO ",
56 "MBOX ",
57 "AXGMAC0",
58 "AXGMAC1",
59 "JTAG",
60 "MPU_INTPEND"
63 /* UE Status High CSR */
64 static const char * const desc_ue_status_hi[] = {
65 "LPCMEMHOST",
66 "MGMT_MAC",
67 "PCS0ONLINE",
68 "MPU_IRAM",
69 "PCS1ONLINE",
70 "PCTL0",
71 "PCTL1",
72 "PMEM",
73 "RR",
74 "TXPB",
75 "RXPP",
76 "XAUI",
77 "TXP",
78 "ARM",
79 "IPC",
80 "HOST2",
81 "HOST3",
82 "HOST4",
83 "HOST5",
84 "HOST6",
85 "HOST7",
86 "HOST8",
87 "HOST9",
88 "NETC",
89 "Unknown",
90 "Unknown",
91 "Unknown",
92 "Unknown",
93 "Unknown",
94 "Unknown",
95 "Unknown",
96 "Unknown"
100 * beiscsi_ue_detec()- Detect Unrecoverable Error on adapter
101 * @phba: Driver priv structure
103 * Read registers linked to UE and check for the UE status
105 void beiscsi_ue_detect(struct beiscsi_hba *phba)
107 uint32_t ue_hi = 0, ue_lo = 0;
108 uint32_t ue_mask_hi = 0, ue_mask_lo = 0;
109 uint8_t i = 0;
111 if (phba->ue_detected)
112 return;
114 pci_read_config_dword(phba->pcidev,
115 PCICFG_UE_STATUS_LOW, &ue_lo);
116 pci_read_config_dword(phba->pcidev,
117 PCICFG_UE_STATUS_MASK_LOW,
118 &ue_mask_lo);
119 pci_read_config_dword(phba->pcidev,
120 PCICFG_UE_STATUS_HIGH,
121 &ue_hi);
122 pci_read_config_dword(phba->pcidev,
123 PCICFG_UE_STATUS_MASK_HI,
124 &ue_mask_hi);
126 ue_lo = (ue_lo & ~ue_mask_lo);
127 ue_hi = (ue_hi & ~ue_mask_hi);
130 if (ue_lo || ue_hi) {
131 phba->ue_detected = true;
132 beiscsi_log(phba, KERN_ERR,
133 BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX,
134 "BG_%d : Error detected on the adapter\n");
137 if (ue_lo) {
138 for (i = 0; ue_lo; ue_lo >>= 1, i++) {
139 if (ue_lo & 1)
140 beiscsi_log(phba, KERN_ERR,
141 BEISCSI_LOG_CONFIG,
142 "BG_%d : UE_LOW %s bit set\n",
143 desc_ue_status_low[i]);
147 if (ue_hi) {
148 for (i = 0; ue_hi; ue_hi >>= 1, i++) {
149 if (ue_hi & 1)
150 beiscsi_log(phba, KERN_ERR,
151 BEISCSI_LOG_CONFIG,
152 "BG_%d : UE_HIGH %s bit set\n",
153 desc_ue_status_hi[i]);
158 int be_cmd_modify_eq_delay(struct beiscsi_hba *phba,
159 struct be_set_eqd *set_eqd, int num)
161 struct be_ctrl_info *ctrl = &phba->ctrl;
162 struct be_mcc_wrb *wrb;
163 struct be_cmd_req_modify_eq_delay *req;
164 unsigned int tag = 0;
165 int i;
167 spin_lock(&ctrl->mbox_lock);
168 tag = alloc_mcc_tag(phba);
169 if (!tag) {
170 spin_unlock(&ctrl->mbox_lock);
171 return tag;
174 wrb = wrb_from_mccq(phba);
175 req = embedded_payload(wrb);
177 wrb->tag0 |= tag;
178 be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
179 be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
180 OPCODE_COMMON_MODIFY_EQ_DELAY, sizeof(*req));
182 req->num_eq = cpu_to_le32(num);
183 for (i = 0; i < num; i++) {
184 req->delay[i].eq_id = cpu_to_le32(set_eqd[i].eq_id);
185 req->delay[i].phase = 0;
186 req->delay[i].delay_multiplier =
187 cpu_to_le32(set_eqd[i].delay_multiplier);
190 be_mcc_notify(phba);
191 spin_unlock(&ctrl->mbox_lock);
192 return tag;
196 * mgmt_reopen_session()- Reopen a session based on reopen_type
197 * @phba: Device priv structure instance
198 * @reopen_type: Type of reopen_session FW should do.
199 * @sess_handle: Session Handle of the session to be re-opened
201 * return
202 * the TAG used for MBOX Command
205 unsigned int mgmt_reopen_session(struct beiscsi_hba *phba,
206 unsigned int reopen_type,
207 unsigned int sess_handle)
209 struct be_ctrl_info *ctrl = &phba->ctrl;
210 struct be_mcc_wrb *wrb;
211 struct be_cmd_reopen_session_req *req;
212 unsigned int tag = 0;
214 beiscsi_log(phba, KERN_INFO,
215 BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX,
216 "BG_%d : In bescsi_get_boot_target\n");
218 spin_lock(&ctrl->mbox_lock);
219 tag = alloc_mcc_tag(phba);
220 if (!tag) {
221 spin_unlock(&ctrl->mbox_lock);
222 return tag;
225 wrb = wrb_from_mccq(phba);
226 req = embedded_payload(wrb);
227 wrb->tag0 |= tag;
228 be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
229 be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI_INI,
230 OPCODE_ISCSI_INI_DRIVER_REOPEN_ALL_SESSIONS,
231 sizeof(struct be_cmd_reopen_session_resp));
233 /* set the reopen_type,sess_handle */
234 req->reopen_type = reopen_type;
235 req->session_handle = sess_handle;
237 be_mcc_notify(phba);
238 spin_unlock(&ctrl->mbox_lock);
239 return tag;
242 unsigned int mgmt_get_boot_target(struct beiscsi_hba *phba)
244 struct be_ctrl_info *ctrl = &phba->ctrl;
245 struct be_mcc_wrb *wrb;
246 struct be_cmd_get_boot_target_req *req;
247 unsigned int tag = 0;
249 beiscsi_log(phba, KERN_INFO,
250 BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX,
251 "BG_%d : In bescsi_get_boot_target\n");
253 spin_lock(&ctrl->mbox_lock);
254 tag = alloc_mcc_tag(phba);
255 if (!tag) {
256 spin_unlock(&ctrl->mbox_lock);
257 return tag;
260 wrb = wrb_from_mccq(phba);
261 req = embedded_payload(wrb);
262 wrb->tag0 |= tag;
263 be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
264 be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI_INI,
265 OPCODE_ISCSI_INI_BOOT_GET_BOOT_TARGET,
266 sizeof(struct be_cmd_get_boot_target_resp));
268 be_mcc_notify(phba);
269 spin_unlock(&ctrl->mbox_lock);
270 return tag;
273 unsigned int mgmt_get_session_info(struct beiscsi_hba *phba,
274 u32 boot_session_handle,
275 struct be_dma_mem *nonemb_cmd)
277 struct be_ctrl_info *ctrl = &phba->ctrl;
278 struct be_mcc_wrb *wrb;
279 unsigned int tag = 0;
280 struct be_cmd_get_session_req *req;
281 struct be_cmd_get_session_resp *resp;
282 struct be_sge *sge;
284 beiscsi_log(phba, KERN_INFO,
285 BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX,
286 "BG_%d : In beiscsi_get_session_info\n");
288 spin_lock(&ctrl->mbox_lock);
289 tag = alloc_mcc_tag(phba);
290 if (!tag) {
291 spin_unlock(&ctrl->mbox_lock);
292 return tag;
295 nonemb_cmd->size = sizeof(*resp);
296 req = nonemb_cmd->va;
297 memset(req, 0, sizeof(*req));
298 wrb = wrb_from_mccq(phba);
299 sge = nonembedded_sgl(wrb);
300 wrb->tag0 |= tag;
303 wrb->tag0 |= tag;
304 be_wrb_hdr_prepare(wrb, sizeof(*req), false, 1);
305 be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI_INI,
306 OPCODE_ISCSI_INI_SESSION_GET_A_SESSION,
307 sizeof(*resp));
308 req->session_handle = boot_session_handle;
309 sge->pa_hi = cpu_to_le32(upper_32_bits(nonemb_cmd->dma));
310 sge->pa_lo = cpu_to_le32(nonemb_cmd->dma & 0xFFFFFFFF);
311 sge->len = cpu_to_le32(nonemb_cmd->size);
313 be_mcc_notify(phba);
314 spin_unlock(&ctrl->mbox_lock);
315 return tag;
319 * mgmt_get_fw_config()- Get the FW config for the function
320 * @ctrl: ptr to Ctrl Info
321 * @phba: ptr to the dev priv structure
323 * Get the FW config and resources available for the function.
324 * The resources are created based on the count received here.
326 * return
327 * Success: 0
328 * Failure: Non-Zero Value
330 int mgmt_get_fw_config(struct be_ctrl_info *ctrl,
331 struct beiscsi_hba *phba)
333 struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem);
334 struct be_fw_cfg *req = embedded_payload(wrb);
335 int status = 0;
337 spin_lock(&ctrl->mbox_lock);
338 memset(wrb, 0, sizeof(*wrb));
340 be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
342 be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
343 OPCODE_COMMON_QUERY_FIRMWARE_CONFIG,
344 EMBED_MBX_MAX_PAYLOAD_SIZE);
345 status = be_mbox_notify(ctrl);
346 if (!status) {
347 uint8_t ulp_num = 0;
348 struct be_fw_cfg *pfw_cfg;
349 pfw_cfg = req;
351 if (!is_chip_be2_be3r(phba)) {
352 phba->fw_config.eqid_count = pfw_cfg->eqid_count;
353 phba->fw_config.cqid_count = pfw_cfg->cqid_count;
355 beiscsi_log(phba, KERN_INFO,
356 BEISCSI_LOG_INIT,
357 "BG_%d : EQ_Count : %d CQ_Count : %d\n",
358 phba->fw_config.eqid_count,
359 phba->fw_config.cqid_count);
362 for (ulp_num = 0; ulp_num < BEISCSI_ULP_COUNT; ulp_num++)
363 if (pfw_cfg->ulp[ulp_num].ulp_mode &
364 BEISCSI_ULP_ISCSI_INI_MODE)
365 set_bit(ulp_num,
366 &phba->fw_config.ulp_supported);
368 phba->fw_config.phys_port = pfw_cfg->phys_port;
369 for (ulp_num = 0; ulp_num < BEISCSI_ULP_COUNT; ulp_num++) {
370 if (test_bit(ulp_num, &phba->fw_config.ulp_supported)) {
372 phba->fw_config.iscsi_cid_start[ulp_num] =
373 pfw_cfg->ulp[ulp_num].sq_base;
374 phba->fw_config.iscsi_cid_count[ulp_num] =
375 pfw_cfg->ulp[ulp_num].sq_count;
377 phba->fw_config.iscsi_icd_start[ulp_num] =
378 pfw_cfg->ulp[ulp_num].icd_base;
379 phba->fw_config.iscsi_icd_count[ulp_num] =
380 pfw_cfg->ulp[ulp_num].icd_count;
382 phba->fw_config.iscsi_chain_start[ulp_num] =
383 pfw_cfg->chain_icd[ulp_num].chain_base;
384 phba->fw_config.iscsi_chain_count[ulp_num] =
385 pfw_cfg->chain_icd[ulp_num].chain_count;
387 beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_INIT,
388 "BG_%d : Function loaded on ULP : %d\n"
389 "\tiscsi_cid_count : %d\n"
390 "\tiscsi_cid_start : %d\n"
391 "\t iscsi_icd_count : %d\n"
392 "\t iscsi_icd_start : %d\n",
393 ulp_num,
394 phba->fw_config.
395 iscsi_cid_count[ulp_num],
396 phba->fw_config.
397 iscsi_cid_start[ulp_num],
398 phba->fw_config.
399 iscsi_icd_count[ulp_num],
400 phba->fw_config.
401 iscsi_icd_start[ulp_num]);
405 phba->fw_config.dual_ulp_aware = (pfw_cfg->function_mode &
406 BEISCSI_FUNC_DUA_MODE);
408 beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_INIT,
409 "BG_%d : DUA Mode : 0x%x\n",
410 phba->fw_config.dual_ulp_aware);
412 } else {
413 beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT,
414 "BG_%d : Failed in mgmt_get_fw_config\n");
415 status = -EINVAL;
418 spin_unlock(&ctrl->mbox_lock);
419 return status;
422 int mgmt_check_supported_fw(struct be_ctrl_info *ctrl,
423 struct beiscsi_hba *phba)
425 struct be_dma_mem nonemb_cmd;
426 struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem);
427 struct be_mgmt_controller_attributes *req;
428 struct be_sge *sge = nonembedded_sgl(wrb);
429 int status = 0;
431 nonemb_cmd.va = pci_alloc_consistent(ctrl->pdev,
432 sizeof(struct be_mgmt_controller_attributes),
433 &nonemb_cmd.dma);
434 if (nonemb_cmd.va == NULL) {
435 beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT,
436 "BG_%d : Failed to allocate memory for "
437 "mgmt_check_supported_fw\n");
438 return -ENOMEM;
440 nonemb_cmd.size = sizeof(struct be_mgmt_controller_attributes);
441 req = nonemb_cmd.va;
442 memset(req, 0, sizeof(*req));
443 spin_lock(&ctrl->mbox_lock);
444 memset(wrb, 0, sizeof(*wrb));
445 be_wrb_hdr_prepare(wrb, sizeof(*req), false, 1);
446 be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
447 OPCODE_COMMON_GET_CNTL_ATTRIBUTES, sizeof(*req));
448 sge->pa_hi = cpu_to_le32(upper_32_bits(nonemb_cmd.dma));
449 sge->pa_lo = cpu_to_le32(nonemb_cmd.dma & 0xFFFFFFFF);
450 sge->len = cpu_to_le32(nonemb_cmd.size);
451 status = be_mbox_notify(ctrl);
452 if (!status) {
453 struct be_mgmt_controller_attributes_resp *resp = nonemb_cmd.va;
454 beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_INIT,
455 "BG_%d : Firmware Version of CMD : %s\n"
456 "Firmware Version is : %s\n"
457 "Developer Build, not performing version check...\n",
458 resp->params.hba_attribs
459 .flashrom_version_string,
460 resp->params.hba_attribs.
461 firmware_version_string);
463 phba->fw_config.iscsi_features =
464 resp->params.hba_attribs.iscsi_features;
465 beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_INIT,
466 "BM_%d : phba->fw_config.iscsi_features = %d\n",
467 phba->fw_config.iscsi_features);
468 memcpy(phba->fw_ver_str, resp->params.hba_attribs.
469 firmware_version_string, BEISCSI_VER_STRLEN);
470 } else
471 beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT,
472 "BG_%d : Failed in mgmt_check_supported_fw\n");
473 spin_unlock(&ctrl->mbox_lock);
474 if (nonemb_cmd.va)
475 pci_free_consistent(ctrl->pdev, nonemb_cmd.size,
476 nonemb_cmd.va, nonemb_cmd.dma);
478 return status;
481 unsigned int mgmt_vendor_specific_fw_cmd(struct be_ctrl_info *ctrl,
482 struct beiscsi_hba *phba,
483 struct bsg_job *job,
484 struct be_dma_mem *nonemb_cmd)
486 struct be_cmd_resp_hdr *resp;
487 struct be_mcc_wrb *wrb;
488 struct be_sge *mcc_sge;
489 unsigned int tag = 0;
490 struct iscsi_bsg_request *bsg_req = job->request;
491 struct be_bsg_vendor_cmd *req = nonemb_cmd->va;
492 unsigned short region, sector_size, sector, offset;
494 nonemb_cmd->size = job->request_payload.payload_len;
495 memset(nonemb_cmd->va, 0, nonemb_cmd->size);
496 resp = nonemb_cmd->va;
497 region = bsg_req->rqst_data.h_vendor.vendor_cmd[1];
498 sector_size = bsg_req->rqst_data.h_vendor.vendor_cmd[2];
499 sector = bsg_req->rqst_data.h_vendor.vendor_cmd[3];
500 offset = bsg_req->rqst_data.h_vendor.vendor_cmd[4];
501 req->region = region;
502 req->sector = sector;
503 req->offset = offset;
504 spin_lock(&ctrl->mbox_lock);
506 switch (bsg_req->rqst_data.h_vendor.vendor_cmd[0]) {
507 case BEISCSI_WRITE_FLASH:
508 offset = sector * sector_size + offset;
509 be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI,
510 OPCODE_COMMON_WRITE_FLASH, sizeof(*req));
511 sg_copy_to_buffer(job->request_payload.sg_list,
512 job->request_payload.sg_cnt,
513 nonemb_cmd->va + offset, job->request_len);
514 break;
515 case BEISCSI_READ_FLASH:
516 be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI,
517 OPCODE_COMMON_READ_FLASH, sizeof(*req));
518 break;
519 default:
520 beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG,
521 "BG_%d : Unsupported cmd = 0x%x\n\n",
522 bsg_req->rqst_data.h_vendor.vendor_cmd[0]);
524 spin_unlock(&ctrl->mbox_lock);
525 return -ENOSYS;
528 tag = alloc_mcc_tag(phba);
529 if (!tag) {
530 spin_unlock(&ctrl->mbox_lock);
531 return tag;
534 wrb = wrb_from_mccq(phba);
535 mcc_sge = nonembedded_sgl(wrb);
536 be_wrb_hdr_prepare(wrb, nonemb_cmd->size, false,
537 job->request_payload.sg_cnt);
538 mcc_sge->pa_hi = cpu_to_le32(upper_32_bits(nonemb_cmd->dma));
539 mcc_sge->pa_lo = cpu_to_le32(nonemb_cmd->dma & 0xFFFFFFFF);
540 mcc_sge->len = cpu_to_le32(nonemb_cmd->size);
541 wrb->tag0 |= tag;
543 be_mcc_notify(phba);
545 spin_unlock(&ctrl->mbox_lock);
546 return tag;
550 * mgmt_epfw_cleanup()- Inform FW to cleanup data structures.
551 * @phba: pointer to dev priv structure
552 * @ulp_num: ULP number.
554 * return
555 * Success: 0
556 * Failure: Non-Zero Value
558 int mgmt_epfw_cleanup(struct beiscsi_hba *phba, unsigned short ulp_num)
560 struct be_ctrl_info *ctrl = &phba->ctrl;
561 struct be_mcc_wrb *wrb = wrb_from_mccq(phba);
562 struct iscsi_cleanup_req *req = embedded_payload(wrb);
563 int status = 0;
565 spin_lock(&ctrl->mbox_lock);
567 be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
568 be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI,
569 OPCODE_COMMON_ISCSI_CLEANUP, sizeof(*req));
571 req->chute = (1 << ulp_num);
572 req->hdr_ring_id = cpu_to_le16(HWI_GET_DEF_HDRQ_ID(phba, ulp_num));
573 req->data_ring_id = cpu_to_le16(HWI_GET_DEF_BUFQ_ID(phba, ulp_num));
575 status = be_mcc_notify_wait(phba);
576 if (status)
577 beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_INIT,
578 "BG_%d : mgmt_epfw_cleanup , FAILED\n");
579 spin_unlock(&ctrl->mbox_lock);
580 return status;
583 unsigned int mgmt_invalidate_icds(struct beiscsi_hba *phba,
584 struct invalidate_command_table *inv_tbl,
585 unsigned int num_invalidate, unsigned int cid,
586 struct be_dma_mem *nonemb_cmd)
589 struct be_ctrl_info *ctrl = &phba->ctrl;
590 struct be_mcc_wrb *wrb;
591 struct be_sge *sge;
592 struct invalidate_commands_params_in *req;
593 unsigned int i, tag = 0;
595 spin_lock(&ctrl->mbox_lock);
596 tag = alloc_mcc_tag(phba);
597 if (!tag) {
598 spin_unlock(&ctrl->mbox_lock);
599 return tag;
602 req = nonemb_cmd->va;
603 memset(req, 0, sizeof(*req));
604 wrb = wrb_from_mccq(phba);
605 sge = nonembedded_sgl(wrb);
606 wrb->tag0 |= tag;
608 be_wrb_hdr_prepare(wrb, sizeof(*req), false, 1);
609 be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI,
610 OPCODE_COMMON_ISCSI_ERROR_RECOVERY_INVALIDATE_COMMANDS,
611 sizeof(*req));
612 req->ref_handle = 0;
613 req->cleanup_type = CMD_ISCSI_COMMAND_INVALIDATE;
614 for (i = 0; i < num_invalidate; i++) {
615 req->table[i].icd = inv_tbl->icd;
616 req->table[i].cid = inv_tbl->cid;
617 req->icd_count++;
618 inv_tbl++;
620 sge->pa_hi = cpu_to_le32(upper_32_bits(nonemb_cmd->dma));
621 sge->pa_lo = cpu_to_le32(nonemb_cmd->dma & 0xFFFFFFFF);
622 sge->len = cpu_to_le32(nonemb_cmd->size);
624 be_mcc_notify(phba);
625 spin_unlock(&ctrl->mbox_lock);
626 return tag;
629 unsigned int mgmt_invalidate_connection(struct beiscsi_hba *phba,
630 struct beiscsi_endpoint *beiscsi_ep,
631 unsigned short cid,
632 unsigned short issue_reset,
633 unsigned short savecfg_flag)
635 struct be_ctrl_info *ctrl = &phba->ctrl;
636 struct be_mcc_wrb *wrb;
637 struct iscsi_invalidate_connection_params_in *req;
638 unsigned int tag = 0;
640 spin_lock(&ctrl->mbox_lock);
641 tag = alloc_mcc_tag(phba);
642 if (!tag) {
643 spin_unlock(&ctrl->mbox_lock);
644 return tag;
646 wrb = wrb_from_mccq(phba);
647 wrb->tag0 |= tag;
648 req = embedded_payload(wrb);
650 be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
651 be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI_INI,
652 OPCODE_ISCSI_INI_DRIVER_INVALIDATE_CONNECTION,
653 sizeof(*req));
654 req->session_handle = beiscsi_ep->fw_handle;
655 req->cid = cid;
656 if (issue_reset)
657 req->cleanup_type = CMD_ISCSI_CONNECTION_ISSUE_TCP_RST;
658 else
659 req->cleanup_type = CMD_ISCSI_CONNECTION_INVALIDATE;
660 req->save_cfg = savecfg_flag;
661 be_mcc_notify(phba);
662 spin_unlock(&ctrl->mbox_lock);
663 return tag;
666 unsigned int mgmt_upload_connection(struct beiscsi_hba *phba,
667 unsigned short cid, unsigned int upload_flag)
669 struct be_ctrl_info *ctrl = &phba->ctrl;
670 struct be_mcc_wrb *wrb;
671 struct tcp_upload_params_in *req;
672 unsigned int tag = 0;
674 spin_lock(&ctrl->mbox_lock);
675 tag = alloc_mcc_tag(phba);
676 if (!tag) {
677 spin_unlock(&ctrl->mbox_lock);
678 return tag;
680 wrb = wrb_from_mccq(phba);
681 req = embedded_payload(wrb);
682 wrb->tag0 |= tag;
684 be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
685 be_cmd_hdr_prepare(&req->hdr, CMD_COMMON_TCP_UPLOAD,
686 OPCODE_COMMON_TCP_UPLOAD, sizeof(*req));
687 req->id = (unsigned short)cid;
688 req->upload_type = (unsigned char)upload_flag;
689 be_mcc_notify(phba);
690 spin_unlock(&ctrl->mbox_lock);
691 return tag;
695 * mgmt_open_connection()- Establish a TCP CXN
696 * @dst_addr: Destination Address
697 * @beiscsi_ep: ptr to device endpoint struct
698 * @nonemb_cmd: ptr to memory allocated for command
700 * return
701 * Success: Tag number of the MBX Command issued
702 * Failure: Error code
704 int mgmt_open_connection(struct beiscsi_hba *phba,
705 struct sockaddr *dst_addr,
706 struct beiscsi_endpoint *beiscsi_ep,
707 struct be_dma_mem *nonemb_cmd)
709 struct hwi_controller *phwi_ctrlr;
710 struct hwi_context_memory *phwi_context;
711 struct sockaddr_in *daddr_in = (struct sockaddr_in *)dst_addr;
712 struct sockaddr_in6 *daddr_in6 = (struct sockaddr_in6 *)dst_addr;
713 struct be_ctrl_info *ctrl = &phba->ctrl;
714 struct be_mcc_wrb *wrb;
715 struct tcp_connect_and_offload_in_v1 *req;
716 unsigned short def_hdr_id;
717 unsigned short def_data_id;
718 struct phys_addr template_address = { 0, 0 };
719 struct phys_addr *ptemplate_address;
720 unsigned int tag = 0;
721 unsigned int i, ulp_num;
722 unsigned short cid = beiscsi_ep->ep_cid;
723 struct be_sge *sge;
725 phwi_ctrlr = phba->phwi_ctrlr;
726 phwi_context = phwi_ctrlr->phwi_ctxt;
728 ulp_num = phwi_ctrlr->wrb_context[BE_GET_CRI_FROM_CID(cid)].ulp_num;
730 def_hdr_id = (unsigned short)HWI_GET_DEF_HDRQ_ID(phba, ulp_num);
731 def_data_id = (unsigned short)HWI_GET_DEF_BUFQ_ID(phba, ulp_num);
733 ptemplate_address = &template_address;
734 ISCSI_GET_PDU_TEMPLATE_ADDRESS(phba, ptemplate_address);
735 spin_lock(&ctrl->mbox_lock);
736 tag = alloc_mcc_tag(phba);
737 if (!tag) {
738 spin_unlock(&ctrl->mbox_lock);
739 return tag;
741 wrb = wrb_from_mccq(phba);
742 sge = nonembedded_sgl(wrb);
744 req = nonemb_cmd->va;
745 memset(req, 0, sizeof(*req));
746 wrb->tag0 |= tag;
748 be_wrb_hdr_prepare(wrb, nonemb_cmd->size, false, 1);
749 be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI,
750 OPCODE_COMMON_ISCSI_TCP_CONNECT_AND_OFFLOAD,
751 nonemb_cmd->size);
752 if (dst_addr->sa_family == PF_INET) {
753 __be32 s_addr = daddr_in->sin_addr.s_addr;
754 req->ip_address.ip_type = BE2_IPV4;
755 req->ip_address.addr[0] = s_addr & 0x000000ff;
756 req->ip_address.addr[1] = (s_addr & 0x0000ff00) >> 8;
757 req->ip_address.addr[2] = (s_addr & 0x00ff0000) >> 16;
758 req->ip_address.addr[3] = (s_addr & 0xff000000) >> 24;
759 req->tcp_port = ntohs(daddr_in->sin_port);
760 beiscsi_ep->dst_addr = daddr_in->sin_addr.s_addr;
761 beiscsi_ep->dst_tcpport = ntohs(daddr_in->sin_port);
762 beiscsi_ep->ip_type = BE2_IPV4;
763 } else if (dst_addr->sa_family == PF_INET6) {
764 req->ip_address.ip_type = BE2_IPV6;
765 memcpy(&req->ip_address.addr,
766 &daddr_in6->sin6_addr.in6_u.u6_addr8, 16);
767 req->tcp_port = ntohs(daddr_in6->sin6_port);
768 beiscsi_ep->dst_tcpport = ntohs(daddr_in6->sin6_port);
769 memcpy(&beiscsi_ep->dst6_addr,
770 &daddr_in6->sin6_addr.in6_u.u6_addr8, 16);
771 beiscsi_ep->ip_type = BE2_IPV6;
772 } else{
773 beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG,
774 "BG_%d : unknown addr family %d\n",
775 dst_addr->sa_family);
776 spin_unlock(&ctrl->mbox_lock);
777 free_mcc_tag(&phba->ctrl, tag);
778 return -EINVAL;
781 req->cid = cid;
782 i = phba->nxt_cqid++;
783 if (phba->nxt_cqid == phba->num_cpus)
784 phba->nxt_cqid = 0;
785 req->cq_id = phwi_context->be_cq[i].id;
786 beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG,
787 "BG_%d : i=%d cq_id=%d\n", i, req->cq_id);
788 req->defq_id = def_hdr_id;
789 req->hdr_ring_id = def_hdr_id;
790 req->data_ring_id = def_data_id;
791 req->do_offload = 1;
792 req->dataout_template_pa.lo = ptemplate_address->lo;
793 req->dataout_template_pa.hi = ptemplate_address->hi;
794 sge->pa_hi = cpu_to_le32(upper_32_bits(nonemb_cmd->dma));
795 sge->pa_lo = cpu_to_le32(nonemb_cmd->dma & 0xFFFFFFFF);
796 sge->len = cpu_to_le32(nonemb_cmd->size);
798 if (!is_chip_be2_be3r(phba)) {
799 req->hdr.version = MBX_CMD_VER1;
800 req->tcp_window_size = 0;
801 req->tcp_window_scale_count = 2;
804 be_mcc_notify(phba);
805 spin_unlock(&ctrl->mbox_lock);
806 return tag;
809 unsigned int mgmt_get_all_if_id(struct beiscsi_hba *phba)
811 struct be_ctrl_info *ctrl = &phba->ctrl;
812 struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem);
813 struct be_cmd_get_all_if_id_req *req = embedded_payload(wrb);
814 struct be_cmd_get_all_if_id_req *pbe_allid = req;
815 int status = 0;
817 memset(wrb, 0, sizeof(*wrb));
819 spin_lock(&ctrl->mbox_lock);
821 be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
822 be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI,
823 OPCODE_COMMON_ISCSI_NTWK_GET_ALL_IF_ID,
824 sizeof(*req));
825 status = be_mbox_notify(ctrl);
826 if (!status)
827 phba->interface_handle = pbe_allid->if_hndl_list[0];
828 else {
829 beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG,
830 "BG_%d : Failed in mgmt_get_all_if_id\n");
832 spin_unlock(&ctrl->mbox_lock);
834 return status;
838 * mgmt_exec_nonemb_cmd()- Execute Non Embedded MBX Cmd
839 * @phba: Driver priv structure
840 * @nonemb_cmd: Address of the MBX command issued
841 * @resp_buf: Buffer to copy the MBX cmd response
842 * @resp_buf_len: respone lenght to be copied
845 static int mgmt_exec_nonemb_cmd(struct beiscsi_hba *phba,
846 struct be_dma_mem *nonemb_cmd, void *resp_buf,
847 int resp_buf_len)
849 struct be_ctrl_info *ctrl = &phba->ctrl;
850 struct be_mcc_wrb *wrb;
851 struct be_sge *sge;
852 unsigned int tag;
853 int rc = 0;
855 spin_lock(&ctrl->mbox_lock);
856 tag = alloc_mcc_tag(phba);
857 if (!tag) {
858 spin_unlock(&ctrl->mbox_lock);
859 rc = -ENOMEM;
860 goto free_cmd;
863 wrb = wrb_from_mccq(phba);
864 wrb->tag0 |= tag;
865 sge = nonembedded_sgl(wrb);
867 be_wrb_hdr_prepare(wrb, nonemb_cmd->size, false, 1);
868 sge->pa_hi = cpu_to_le32(upper_32_bits(nonemb_cmd->dma));
869 sge->pa_lo = cpu_to_le32(lower_32_bits(nonemb_cmd->dma));
870 sge->len = cpu_to_le32(nonemb_cmd->size);
872 be_mcc_notify(phba);
873 spin_unlock(&ctrl->mbox_lock);
875 rc = beiscsi_mccq_compl(phba, tag, NULL, nonemb_cmd);
877 if (resp_buf)
878 memcpy(resp_buf, nonemb_cmd->va, resp_buf_len);
880 if (rc) {
881 /* Check if the MBX Cmd needs to be re-issued */
882 if (rc == -EAGAIN)
883 return rc;
885 beiscsi_log(phba, KERN_WARNING,
886 BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX,
887 "BG_%d : mgmt_exec_nonemb_cmd Failed status\n");
889 if (rc != -EBUSY)
890 goto free_cmd;
891 else
892 return rc;
894 free_cmd:
895 pci_free_consistent(ctrl->pdev, nonemb_cmd->size,
896 nonemb_cmd->va, nonemb_cmd->dma);
897 return rc;
900 static int mgmt_alloc_cmd_data(struct beiscsi_hba *phba, struct be_dma_mem *cmd,
901 int iscsi_cmd, int size)
903 cmd->va = pci_zalloc_consistent(phba->ctrl.pdev, size, &cmd->dma);
904 if (!cmd->va) {
905 beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG,
906 "BG_%d : Failed to allocate memory for if info\n");
907 return -ENOMEM;
909 cmd->size = size;
910 be_cmd_hdr_prepare(cmd->va, CMD_SUBSYSTEM_ISCSI, iscsi_cmd, size);
911 return 0;
914 static int
915 mgmt_static_ip_modify(struct beiscsi_hba *phba,
916 struct be_cmd_get_if_info_resp *if_info,
917 struct iscsi_iface_param_info *ip_param,
918 struct iscsi_iface_param_info *subnet_param,
919 uint32_t ip_action)
921 struct be_cmd_set_ip_addr_req *req;
922 struct be_dma_mem nonemb_cmd;
923 uint32_t ip_type;
924 int rc;
926 rc = mgmt_alloc_cmd_data(phba, &nonemb_cmd,
927 OPCODE_COMMON_ISCSI_NTWK_MODIFY_IP_ADDR,
928 sizeof(*req));
929 if (rc)
930 return rc;
932 ip_type = (ip_param->param == ISCSI_NET_PARAM_IPV6_ADDR) ?
933 BE2_IPV6 : BE2_IPV4 ;
935 req = nonemb_cmd.va;
936 req->ip_params.record_entry_count = 1;
937 req->ip_params.ip_record.action = ip_action;
938 req->ip_params.ip_record.interface_hndl =
939 phba->interface_handle;
940 req->ip_params.ip_record.ip_addr.size_of_structure =
941 sizeof(struct be_ip_addr_subnet_format);
942 req->ip_params.ip_record.ip_addr.ip_type = ip_type;
944 if (ip_action == IP_ACTION_ADD) {
945 memcpy(req->ip_params.ip_record.ip_addr.addr, ip_param->value,
946 ip_param->len);
948 if (subnet_param)
949 memcpy(req->ip_params.ip_record.ip_addr.subnet_mask,
950 subnet_param->value, subnet_param->len);
951 } else {
952 memcpy(req->ip_params.ip_record.ip_addr.addr,
953 if_info->ip_addr.addr, ip_param->len);
955 memcpy(req->ip_params.ip_record.ip_addr.subnet_mask,
956 if_info->ip_addr.subnet_mask, ip_param->len);
959 rc = mgmt_exec_nonemb_cmd(phba, &nonemb_cmd, NULL, 0);
960 if (rc < 0)
961 beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG,
962 "BG_%d : Failed to Modify existing IP Address\n");
963 return rc;
966 static int mgmt_modify_gateway(struct beiscsi_hba *phba, uint8_t *gt_addr,
967 uint32_t gtway_action, uint32_t param_len)
969 struct be_cmd_set_def_gateway_req *req;
970 struct be_dma_mem nonemb_cmd;
971 int rt_val;
974 rt_val = mgmt_alloc_cmd_data(phba, &nonemb_cmd,
975 OPCODE_COMMON_ISCSI_NTWK_MODIFY_DEFAULT_GATEWAY,
976 sizeof(*req));
977 if (rt_val)
978 return rt_val;
980 req = nonemb_cmd.va;
981 req->action = gtway_action;
982 req->ip_addr.ip_type = BE2_IPV4;
984 memcpy(req->ip_addr.addr, gt_addr, param_len);
986 return mgmt_exec_nonemb_cmd(phba, &nonemb_cmd, NULL, 0);
989 int mgmt_set_ip(struct beiscsi_hba *phba,
990 struct iscsi_iface_param_info *ip_param,
991 struct iscsi_iface_param_info *subnet_param,
992 uint32_t boot_proto)
994 struct be_cmd_get_def_gateway_resp gtway_addr_set;
995 struct be_cmd_get_if_info_resp *if_info;
996 struct be_cmd_set_dhcp_req *dhcpreq;
997 struct be_cmd_rel_dhcp_req *reldhcp;
998 struct be_dma_mem nonemb_cmd;
999 uint8_t *gtway_addr;
1000 uint32_t ip_type;
1001 int rc;
1003 if (mgmt_get_all_if_id(phba))
1004 return -EIO;
1006 ip_type = (ip_param->param == ISCSI_NET_PARAM_IPV6_ADDR) ?
1007 BE2_IPV6 : BE2_IPV4 ;
1009 rc = mgmt_get_if_info(phba, ip_type, &if_info);
1010 if (rc)
1011 return rc;
1013 if (boot_proto == ISCSI_BOOTPROTO_DHCP) {
1014 if (if_info->dhcp_state) {
1015 beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG,
1016 "BG_%d : DHCP Already Enabled\n");
1017 goto exit;
1019 /* The ip_param->len is 1 in DHCP case. Setting
1020 proper IP len as this it is used while
1021 freeing the Static IP.
1023 ip_param->len = (ip_param->param == ISCSI_NET_PARAM_IPV6_ADDR) ?
1024 IP_V6_LEN : IP_V4_LEN;
1026 } else {
1027 if (if_info->dhcp_state) {
1029 memset(if_info, 0, sizeof(*if_info));
1030 rc = mgmt_alloc_cmd_data(phba, &nonemb_cmd,
1031 OPCODE_COMMON_ISCSI_NTWK_REL_STATELESS_IP_ADDR,
1032 sizeof(*reldhcp));
1034 if (rc)
1035 goto exit;
1037 reldhcp = nonemb_cmd.va;
1038 reldhcp->interface_hndl = phba->interface_handle;
1039 reldhcp->ip_type = ip_type;
1041 rc = mgmt_exec_nonemb_cmd(phba, &nonemb_cmd, NULL, 0);
1042 if (rc < 0) {
1043 beiscsi_log(phba, KERN_WARNING,
1044 BEISCSI_LOG_CONFIG,
1045 "BG_%d : Failed to Delete existing dhcp\n");
1046 goto exit;
1051 /* Delete the Static IP Set */
1052 if (if_info->ip_addr.addr[0]) {
1053 rc = mgmt_static_ip_modify(phba, if_info, ip_param, NULL,
1054 IP_ACTION_DEL);
1055 if (rc)
1056 goto exit;
1059 /* Delete the Gateway settings if mode change is to DHCP */
1060 if (boot_proto == ISCSI_BOOTPROTO_DHCP) {
1061 memset(&gtway_addr_set, 0, sizeof(gtway_addr_set));
1062 rc = mgmt_get_gateway(phba, BE2_IPV4, &gtway_addr_set);
1063 if (rc) {
1064 beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG,
1065 "BG_%d : Failed to Get Gateway Addr\n");
1066 goto exit;
1069 if (gtway_addr_set.ip_addr.addr[0]) {
1070 gtway_addr = (uint8_t *)&gtway_addr_set.ip_addr.addr;
1071 rc = mgmt_modify_gateway(phba, gtway_addr,
1072 IP_ACTION_DEL, IP_V4_LEN);
1074 if (rc) {
1075 beiscsi_log(phba, KERN_WARNING,
1076 BEISCSI_LOG_CONFIG,
1077 "BG_%d : Failed to clear Gateway Addr Set\n");
1078 goto exit;
1083 /* Set Adapter to DHCP/Static Mode */
1084 if (boot_proto == ISCSI_BOOTPROTO_DHCP) {
1085 rc = mgmt_alloc_cmd_data(phba, &nonemb_cmd,
1086 OPCODE_COMMON_ISCSI_NTWK_CONFIG_STATELESS_IP_ADDR,
1087 sizeof(*dhcpreq));
1088 if (rc)
1089 goto exit;
1091 dhcpreq = nonemb_cmd.va;
1092 dhcpreq->flags = BLOCKING;
1093 dhcpreq->retry_count = 1;
1094 dhcpreq->interface_hndl = phba->interface_handle;
1095 dhcpreq->ip_type = BE2_DHCP_V4;
1097 rc = mgmt_exec_nonemb_cmd(phba, &nonemb_cmd, NULL, 0);
1098 } else {
1099 rc = mgmt_static_ip_modify(phba, if_info, ip_param,
1100 subnet_param, IP_ACTION_ADD);
1103 exit:
1104 kfree(if_info);
1105 return rc;
1108 int mgmt_set_gateway(struct beiscsi_hba *phba,
1109 struct iscsi_iface_param_info *gateway_param)
1111 struct be_cmd_get_def_gateway_resp gtway_addr_set;
1112 uint8_t *gtway_addr;
1113 int rt_val;
1115 memset(&gtway_addr_set, 0, sizeof(gtway_addr_set));
1116 rt_val = mgmt_get_gateway(phba, BE2_IPV4, &gtway_addr_set);
1117 if (rt_val) {
1118 beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG,
1119 "BG_%d : Failed to Get Gateway Addr\n");
1120 return rt_val;
1123 if (gtway_addr_set.ip_addr.addr[0]) {
1124 gtway_addr = (uint8_t *)&gtway_addr_set.ip_addr.addr;
1125 rt_val = mgmt_modify_gateway(phba, gtway_addr, IP_ACTION_DEL,
1126 gateway_param->len);
1127 if (rt_val) {
1128 beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG,
1129 "BG_%d : Failed to clear Gateway Addr Set\n");
1130 return rt_val;
1134 gtway_addr = (uint8_t *)&gateway_param->value;
1135 rt_val = mgmt_modify_gateway(phba, gtway_addr, IP_ACTION_ADD,
1136 gateway_param->len);
1138 if (rt_val)
1139 beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG,
1140 "BG_%d : Failed to Set Gateway Addr\n");
1142 return rt_val;
1145 int mgmt_get_gateway(struct beiscsi_hba *phba, int ip_type,
1146 struct be_cmd_get_def_gateway_resp *gateway)
1148 struct be_cmd_get_def_gateway_req *req;
1149 struct be_dma_mem nonemb_cmd;
1150 int rc;
1152 rc = mgmt_alloc_cmd_data(phba, &nonemb_cmd,
1153 OPCODE_COMMON_ISCSI_NTWK_GET_DEFAULT_GATEWAY,
1154 sizeof(*gateway));
1155 if (rc)
1156 return rc;
1158 req = nonemb_cmd.va;
1159 req->ip_type = ip_type;
1161 return mgmt_exec_nonemb_cmd(phba, &nonemb_cmd, gateway,
1162 sizeof(*gateway));
1165 int mgmt_get_if_info(struct beiscsi_hba *phba, int ip_type,
1166 struct be_cmd_get_if_info_resp **if_info)
1168 struct be_cmd_get_if_info_req *req;
1169 struct be_dma_mem nonemb_cmd;
1170 uint32_t ioctl_size = sizeof(struct be_cmd_get_if_info_resp);
1171 int rc;
1173 if (mgmt_get_all_if_id(phba))
1174 return -EIO;
1176 do {
1177 rc = mgmt_alloc_cmd_data(phba, &nonemb_cmd,
1178 OPCODE_COMMON_ISCSI_NTWK_GET_IF_INFO,
1179 ioctl_size);
1180 if (rc)
1181 return rc;
1183 req = nonemb_cmd.va;
1184 req->interface_hndl = phba->interface_handle;
1185 req->ip_type = ip_type;
1187 /* Allocate memory for if_info */
1188 *if_info = kzalloc(ioctl_size, GFP_KERNEL);
1189 if (!*if_info) {
1190 beiscsi_log(phba, KERN_ERR,
1191 BEISCSI_LOG_INIT | BEISCSI_LOG_CONFIG,
1192 "BG_%d : Memory Allocation Failure\n");
1194 /* Free the DMA memory for the IOCTL issuing */
1195 pci_free_consistent(phba->ctrl.pdev,
1196 nonemb_cmd.size,
1197 nonemb_cmd.va,
1198 nonemb_cmd.dma);
1199 return -ENOMEM;
1202 rc = mgmt_exec_nonemb_cmd(phba, &nonemb_cmd, *if_info,
1203 ioctl_size);
1205 /* Check if the error is because of Insufficent_Buffer */
1206 if (rc == -EAGAIN) {
1208 /* Get the new memory size */
1209 ioctl_size = ((struct be_cmd_resp_hdr *)
1210 nonemb_cmd.va)->actual_resp_len;
1211 ioctl_size += sizeof(struct be_cmd_req_hdr);
1213 /* Free the previous allocated DMA memory */
1214 pci_free_consistent(phba->ctrl.pdev, nonemb_cmd.size,
1215 nonemb_cmd.va,
1216 nonemb_cmd.dma);
1218 /* Free the virtual memory */
1219 kfree(*if_info);
1220 } else
1221 break;
1222 } while (true);
1223 return rc;
1226 int mgmt_get_nic_conf(struct beiscsi_hba *phba,
1227 struct be_cmd_get_nic_conf_resp *nic)
1229 struct be_dma_mem nonemb_cmd;
1230 int rc;
1232 rc = mgmt_alloc_cmd_data(phba, &nonemb_cmd,
1233 OPCODE_COMMON_ISCSI_NTWK_GET_NIC_CONFIG,
1234 sizeof(*nic));
1235 if (rc)
1236 return rc;
1238 return mgmt_exec_nonemb_cmd(phba, &nonemb_cmd, nic, sizeof(*nic));
1243 unsigned int be_cmd_get_initname(struct beiscsi_hba *phba)
1245 unsigned int tag = 0;
1246 struct be_mcc_wrb *wrb;
1247 struct be_cmd_hba_name *req;
1248 struct be_ctrl_info *ctrl = &phba->ctrl;
1250 spin_lock(&ctrl->mbox_lock);
1251 tag = alloc_mcc_tag(phba);
1252 if (!tag) {
1253 spin_unlock(&ctrl->mbox_lock);
1254 return tag;
1257 wrb = wrb_from_mccq(phba);
1258 req = embedded_payload(wrb);
1259 wrb->tag0 |= tag;
1260 be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
1261 be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI_INI,
1262 OPCODE_ISCSI_INI_CFG_GET_HBA_NAME,
1263 sizeof(*req));
1265 be_mcc_notify(phba);
1266 spin_unlock(&ctrl->mbox_lock);
1267 return tag;
1270 unsigned int be_cmd_get_port_speed(struct beiscsi_hba *phba)
1272 unsigned int tag = 0;
1273 struct be_mcc_wrb *wrb;
1274 struct be_cmd_ntwk_link_status_req *req;
1275 struct be_ctrl_info *ctrl = &phba->ctrl;
1277 spin_lock(&ctrl->mbox_lock);
1278 tag = alloc_mcc_tag(phba);
1279 if (!tag) {
1280 spin_unlock(&ctrl->mbox_lock);
1281 return tag;
1284 wrb = wrb_from_mccq(phba);
1285 req = embedded_payload(wrb);
1286 wrb->tag0 |= tag;
1287 be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
1288 be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
1289 OPCODE_COMMON_NTWK_LINK_STATUS_QUERY,
1290 sizeof(*req));
1292 be_mcc_notify(phba);
1293 spin_unlock(&ctrl->mbox_lock);
1294 return tag;
1298 * be_mgmt_get_boot_shandle()- Get the session handle
1299 * @phba: device priv structure instance
1300 * @s_handle: session handle returned for boot session.
1302 * Get the boot target session handle. In case of
1303 * crashdump mode driver has to issue and MBX Cmd
1304 * for FW to login to boot target
1306 * return
1307 * Success: 0
1308 * Failure: Non-Zero value
1311 int be_mgmt_get_boot_shandle(struct beiscsi_hba *phba,
1312 unsigned int *s_handle)
1314 struct be_cmd_get_boot_target_resp *boot_resp;
1315 struct be_mcc_wrb *wrb;
1316 unsigned int tag;
1317 uint8_t boot_retry = 3;
1318 int rc;
1320 do {
1321 /* Get the Boot Target Session Handle and Count*/
1322 tag = mgmt_get_boot_target(phba);
1323 if (!tag) {
1324 beiscsi_log(phba, KERN_ERR,
1325 BEISCSI_LOG_CONFIG | BEISCSI_LOG_INIT,
1326 "BG_%d : Getting Boot Target Info Failed\n");
1327 return -EAGAIN;
1330 rc = beiscsi_mccq_compl(phba, tag, &wrb, NULL);
1331 if (rc) {
1332 beiscsi_log(phba, KERN_ERR,
1333 BEISCSI_LOG_INIT | BEISCSI_LOG_CONFIG,
1334 "BG_%d : MBX CMD get_boot_target Failed\n");
1335 return -EBUSY;
1338 boot_resp = embedded_payload(wrb);
1340 /* Check if the there are any Boot targets configured */
1341 if (!boot_resp->boot_session_count) {
1342 beiscsi_log(phba, KERN_INFO,
1343 BEISCSI_LOG_INIT | BEISCSI_LOG_CONFIG,
1344 "BG_%d ;No boot targets configured\n");
1345 return -ENXIO;
1348 /* FW returns the session handle of the boot session */
1349 if (boot_resp->boot_session_handle != INVALID_SESS_HANDLE) {
1350 *s_handle = boot_resp->boot_session_handle;
1351 return 0;
1354 /* Issue MBX Cmd to FW to login to the boot target */
1355 tag = mgmt_reopen_session(phba, BE_REOPEN_BOOT_SESSIONS,
1356 INVALID_SESS_HANDLE);
1357 if (!tag) {
1358 beiscsi_log(phba, KERN_ERR,
1359 BEISCSI_LOG_INIT | BEISCSI_LOG_CONFIG,
1360 "BG_%d : mgmt_reopen_session Failed\n");
1361 return -EAGAIN;
1364 rc = beiscsi_mccq_compl(phba, tag, NULL, NULL);
1365 if (rc) {
1366 beiscsi_log(phba, KERN_ERR,
1367 BEISCSI_LOG_INIT | BEISCSI_LOG_CONFIG,
1368 "BG_%d : mgmt_reopen_session Failed");
1369 return rc;
1371 } while (--boot_retry);
1373 /* Couldn't log into the boot target */
1374 beiscsi_log(phba, KERN_ERR,
1375 BEISCSI_LOG_INIT | BEISCSI_LOG_CONFIG,
1376 "BG_%d : Login to Boot Target Failed\n");
1377 return -ENXIO;
1381 * mgmt_set_vlan()- Issue and wait for CMD completion
1382 * @phba: device private structure instance
1383 * @vlan_tag: VLAN tag
1385 * Issue the MBX Cmd and wait for the completion of the
1386 * command.
1388 * returns
1389 * Success: 0
1390 * Failure: Non-Xero Value
1392 int mgmt_set_vlan(struct beiscsi_hba *phba,
1393 uint16_t vlan_tag)
1395 int rc;
1396 unsigned int tag;
1398 tag = be_cmd_set_vlan(phba, vlan_tag);
1399 if (!tag) {
1400 beiscsi_log(phba, KERN_ERR,
1401 (BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX),
1402 "BG_%d : VLAN Setting Failed\n");
1403 return -EBUSY;
1406 rc = beiscsi_mccq_compl(phba, tag, NULL, NULL);
1407 if (rc) {
1408 beiscsi_log(phba, KERN_ERR,
1409 (BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX),
1410 "BS_%d : VLAN MBX Cmd Failed\n");
1411 return rc;
1413 return rc;
1417 * beiscsi_drvr_ver_disp()- Display the driver Name and Version
1418 * @dev: ptr to device not used.
1419 * @attr: device attribute, not used.
1420 * @buf: contains formatted text driver name and version
1422 * return
1423 * size of the formatted string
1425 ssize_t
1426 beiscsi_drvr_ver_disp(struct device *dev, struct device_attribute *attr,
1427 char *buf)
1429 return snprintf(buf, PAGE_SIZE, BE_NAME "\n");
1433 * beiscsi_fw_ver_disp()- Display Firmware Version
1434 * @dev: ptr to device not used.
1435 * @attr: device attribute, not used.
1436 * @buf: contains formatted text Firmware version
1438 * return
1439 * size of the formatted string
1441 ssize_t
1442 beiscsi_fw_ver_disp(struct device *dev, struct device_attribute *attr,
1443 char *buf)
1445 struct Scsi_Host *shost = class_to_shost(dev);
1446 struct beiscsi_hba *phba = iscsi_host_priv(shost);
1448 return snprintf(buf, PAGE_SIZE, "%s\n", phba->fw_ver_str);
1452 * beiscsi_active_session_disp()- Display Sessions Active
1453 * @dev: ptr to device not used.
1454 * @attr: device attribute, not used.
1455 * @buf: contains formatted text Session Count
1457 * return
1458 * size of the formatted string
1460 ssize_t
1461 beiscsi_active_session_disp(struct device *dev, struct device_attribute *attr,
1462 char *buf)
1464 struct Scsi_Host *shost = class_to_shost(dev);
1465 struct beiscsi_hba *phba = iscsi_host_priv(shost);
1466 uint16_t avlbl_cids = 0, ulp_num, len = 0, total_cids = 0;
1468 for (ulp_num = 0; ulp_num < BEISCSI_ULP_COUNT; ulp_num++) {
1469 if (test_bit(ulp_num, (void *)&phba->fw_config.ulp_supported)) {
1470 avlbl_cids = BEISCSI_ULP_AVLBL_CID(phba, ulp_num);
1471 total_cids = BEISCSI_GET_CID_COUNT(phba, ulp_num);
1472 len += snprintf(buf+len, PAGE_SIZE - len,
1473 "ULP%d : %d\n", ulp_num,
1474 (total_cids - avlbl_cids));
1475 } else
1476 len += snprintf(buf+len, PAGE_SIZE - len,
1477 "ULP%d : %d\n", ulp_num, 0);
1480 return len;
1484 * beiscsi_free_session_disp()- Display Avaliable Session
1485 * @dev: ptr to device not used.
1486 * @attr: device attribute, not used.
1487 * @buf: contains formatted text Session Count
1489 * return
1490 * size of the formatted string
1492 ssize_t
1493 beiscsi_free_session_disp(struct device *dev, struct device_attribute *attr,
1494 char *buf)
1496 struct Scsi_Host *shost = class_to_shost(dev);
1497 struct beiscsi_hba *phba = iscsi_host_priv(shost);
1498 uint16_t ulp_num, len = 0;
1500 for (ulp_num = 0; ulp_num < BEISCSI_ULP_COUNT; ulp_num++) {
1501 if (test_bit(ulp_num, (void *)&phba->fw_config.ulp_supported))
1502 len += snprintf(buf+len, PAGE_SIZE - len,
1503 "ULP%d : %d\n", ulp_num,
1504 BEISCSI_ULP_AVLBL_CID(phba, ulp_num));
1505 else
1506 len += snprintf(buf+len, PAGE_SIZE - len,
1507 "ULP%d : %d\n", ulp_num, 0);
1510 return len;
1514 * beiscsi_adap_family_disp()- Display adapter family.
1515 * @dev: ptr to device to get priv structure
1516 * @attr: device attribute, not used.
1517 * @buf: contains formatted text driver name and version
1519 * return
1520 * size of the formatted string
1522 ssize_t
1523 beiscsi_adap_family_disp(struct device *dev, struct device_attribute *attr,
1524 char *buf)
1526 uint16_t dev_id = 0;
1527 struct Scsi_Host *shost = class_to_shost(dev);
1528 struct beiscsi_hba *phba = iscsi_host_priv(shost);
1530 dev_id = phba->pcidev->device;
1531 switch (dev_id) {
1532 case BE_DEVICE_ID1:
1533 case OC_DEVICE_ID1:
1534 case OC_DEVICE_ID2:
1535 return snprintf(buf, PAGE_SIZE, "BE2 Adapter Family\n");
1536 break;
1537 case BE_DEVICE_ID2:
1538 case OC_DEVICE_ID3:
1539 return snprintf(buf, PAGE_SIZE, "BE3-R Adapter Family\n");
1540 break;
1541 case OC_SKH_ID1:
1542 return snprintf(buf, PAGE_SIZE, "Skyhawk-R Adapter Family\n");
1543 break;
1544 default:
1545 return snprintf(buf, PAGE_SIZE,
1546 "Unknown Adapter Family: 0x%x\n", dev_id);
1547 break;
1552 * beiscsi_phys_port()- Display Physical Port Identifier
1553 * @dev: ptr to device not used.
1554 * @attr: device attribute, not used.
1555 * @buf: contains formatted text port identifier
1557 * return
1558 * size of the formatted string
1560 ssize_t
1561 beiscsi_phys_port_disp(struct device *dev, struct device_attribute *attr,
1562 char *buf)
1564 struct Scsi_Host *shost = class_to_shost(dev);
1565 struct beiscsi_hba *phba = iscsi_host_priv(shost);
1567 return snprintf(buf, PAGE_SIZE, "Port Identifier : %d\n",
1568 phba->fw_config.phys_port);
1571 void beiscsi_offload_cxn_v0(struct beiscsi_offload_params *params,
1572 struct wrb_handle *pwrb_handle,
1573 struct be_mem_descriptor *mem_descr)
1575 struct iscsi_wrb *pwrb = pwrb_handle->pwrb;
1577 memset(pwrb, 0, sizeof(*pwrb));
1578 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb,
1579 max_send_data_segment_length, pwrb,
1580 params->dw[offsetof(struct amap_beiscsi_offload_params,
1581 max_send_data_segment_length) / 32]);
1582 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, type, pwrb,
1583 BE_TGT_CTX_UPDT_CMD);
1584 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb,
1585 first_burst_length,
1586 pwrb,
1587 params->dw[offsetof(struct amap_beiscsi_offload_params,
1588 first_burst_length) / 32]);
1589 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, erl, pwrb,
1590 (params->dw[offsetof(struct amap_beiscsi_offload_params,
1591 erl) / 32] & OFFLD_PARAMS_ERL));
1592 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, dde, pwrb,
1593 (params->dw[offsetof(struct amap_beiscsi_offload_params,
1594 dde) / 32] & OFFLD_PARAMS_DDE) >> 2);
1595 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, hde, pwrb,
1596 (params->dw[offsetof(struct amap_beiscsi_offload_params,
1597 hde) / 32] & OFFLD_PARAMS_HDE) >> 3);
1598 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, ir2t, pwrb,
1599 (params->dw[offsetof(struct amap_beiscsi_offload_params,
1600 ir2t) / 32] & OFFLD_PARAMS_IR2T) >> 4);
1601 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, imd, pwrb,
1602 (params->dw[offsetof(struct amap_beiscsi_offload_params,
1603 imd) / 32] & OFFLD_PARAMS_IMD) >> 5);
1604 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, stat_sn,
1605 pwrb,
1606 (params->dw[offsetof(struct amap_beiscsi_offload_params,
1607 exp_statsn) / 32] + 1));
1608 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, wrb_idx,
1609 pwrb, pwrb_handle->wrb_index);
1611 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb,
1612 max_burst_length, pwrb, params->dw[offsetof
1613 (struct amap_beiscsi_offload_params,
1614 max_burst_length) / 32]);
1616 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, ptr2nextwrb,
1617 pwrb, pwrb_handle->nxt_wrb_index);
1618 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb,
1619 session_state, pwrb, 0);
1620 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, compltonack,
1621 pwrb, 1);
1622 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, notpredblq,
1623 pwrb, 0);
1624 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, mode, pwrb,
1627 mem_descr += ISCSI_MEM_GLOBAL_HEADER;
1628 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb,
1629 pad_buffer_addr_hi, pwrb,
1630 mem_descr->mem_array[0].bus_address.u.a32.address_hi);
1631 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb,
1632 pad_buffer_addr_lo, pwrb,
1633 mem_descr->mem_array[0].bus_address.u.a32.address_lo);
1636 void beiscsi_offload_cxn_v2(struct beiscsi_offload_params *params,
1637 struct wrb_handle *pwrb_handle)
1639 struct iscsi_wrb *pwrb = pwrb_handle->pwrb;
1641 memset(pwrb, 0, sizeof(*pwrb));
1643 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2,
1644 max_burst_length, pwrb, params->dw[offsetof
1645 (struct amap_beiscsi_offload_params,
1646 max_burst_length) / 32]);
1647 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2,
1648 type, pwrb,
1649 BE_TGT_CTX_UPDT_CMD);
1650 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2,
1651 ptr2nextwrb,
1652 pwrb, pwrb_handle->nxt_wrb_index);
1653 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2, wrb_idx,
1654 pwrb, pwrb_handle->wrb_index);
1655 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2,
1656 max_send_data_segment_length, pwrb,
1657 params->dw[offsetof(struct amap_beiscsi_offload_params,
1658 max_send_data_segment_length) / 32]);
1659 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2,
1660 first_burst_length, pwrb,
1661 params->dw[offsetof(struct amap_beiscsi_offload_params,
1662 first_burst_length) / 32]);
1663 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2,
1664 max_recv_dataseg_len, pwrb,
1665 params->dw[offsetof(struct amap_beiscsi_offload_params,
1666 max_recv_data_segment_length) / 32]);
1667 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2,
1668 max_cxns, pwrb, BEISCSI_MAX_CXNS);
1669 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2, erl, pwrb,
1670 (params->dw[offsetof(struct amap_beiscsi_offload_params,
1671 erl) / 32] & OFFLD_PARAMS_ERL));
1672 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2, dde, pwrb,
1673 (params->dw[offsetof(struct amap_beiscsi_offload_params,
1674 dde) / 32] & OFFLD_PARAMS_DDE) >> 2);
1675 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2, hde, pwrb,
1676 (params->dw[offsetof(struct amap_beiscsi_offload_params,
1677 hde) / 32] & OFFLD_PARAMS_HDE) >> 3);
1678 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2,
1679 ir2t, pwrb,
1680 (params->dw[offsetof(struct amap_beiscsi_offload_params,
1681 ir2t) / 32] & OFFLD_PARAMS_IR2T) >> 4);
1682 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2, imd, pwrb,
1683 (params->dw[offsetof(struct amap_beiscsi_offload_params,
1684 imd) / 32] & OFFLD_PARAMS_IMD) >> 5);
1685 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2,
1686 data_seq_inorder,
1687 pwrb,
1688 (params->dw[offsetof(struct amap_beiscsi_offload_params,
1689 data_seq_inorder) / 32] &
1690 OFFLD_PARAMS_DATA_SEQ_INORDER) >> 6);
1691 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2,
1692 pdu_seq_inorder,
1693 pwrb,
1694 (params->dw[offsetof(struct amap_beiscsi_offload_params,
1695 pdu_seq_inorder) / 32] &
1696 OFFLD_PARAMS_PDU_SEQ_INORDER) >> 7);
1697 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2, max_r2t,
1698 pwrb,
1699 (params->dw[offsetof(struct amap_beiscsi_offload_params,
1700 max_r2t) / 32] &
1701 OFFLD_PARAMS_MAX_R2T) >> 8);
1702 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2, stat_sn,
1703 pwrb,
1704 (params->dw[offsetof(struct amap_beiscsi_offload_params,
1705 exp_statsn) / 32] + 1));