]> git.karo-electronics.de Git - karo-tx-linux.git/blob - drivers/scsi/be2iscsi/be_mgmt.c
ca4016f20e76decc0c3731a692fc8030cedf4577
[karo-tx-linux.git] / drivers / scsi / be2iscsi / be_mgmt.c
1 /**
2  * Copyright (C) 2005 - 2015 Avago Technologies
3  * All rights reserved.
4  *
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.
9  *
10  * Written by: Jayamohan Kallickal (jayamohan.kallickal@avagotech.com)
11  *
12  * Contact Information:
13  * linux-drivers@avagotech.com
14  *
15  * Avago Technologies
16  * 3333 Susan Street
17  * Costa Mesa, CA 92626
18  */
19
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"
26
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"
61 };
62
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"
97 };
98
99 /*
100  * beiscsi_ue_detec()- Detect Unrecoverable Error on adapter
101  * @phba: Driver priv structure
102  *
103  * Read registers linked to UE and check for the UE status
104  **/
105 void beiscsi_ue_detect(struct beiscsi_hba *phba)
106 {
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;
110
111         if (phba->ue_detected)
112                 return;
113
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);
125
126         ue_lo = (ue_lo & ~ue_mask_lo);
127         ue_hi = (ue_hi & ~ue_mask_hi);
128
129
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");
135         }
136
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]);
144                 }
145         }
146
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]);
154                 }
155         }
156 }
157
158 int be_cmd_modify_eq_delay(struct beiscsi_hba *phba,
159                  struct be_set_eqd *set_eqd, int num)
160 {
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;
166
167         spin_lock(&ctrl->mbox_lock);
168         tag = alloc_mcc_tag(phba);
169         if (!tag) {
170                 spin_unlock(&ctrl->mbox_lock);
171                 return tag;
172         }
173
174         wrb = wrb_from_mccq(phba);
175         req = embedded_payload(wrb);
176
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));
181
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);
188         }
189
190         be_mcc_notify(phba);
191         spin_unlock(&ctrl->mbox_lock);
192         return tag;
193 }
194
195 /**
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
200  *
201  * return
202  *      the TAG used for MBOX Command
203  *
204  **/
205 unsigned int mgmt_reopen_session(struct beiscsi_hba *phba,
206                                   unsigned int reopen_type,
207                                   unsigned int sess_handle)
208 {
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;
213
214         beiscsi_log(phba, KERN_INFO,
215                     BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX,
216                     "BG_%d : In bescsi_get_boot_target\n");
217
218         spin_lock(&ctrl->mbox_lock);
219         tag = alloc_mcc_tag(phba);
220         if (!tag) {
221                 spin_unlock(&ctrl->mbox_lock);
222                 return tag;
223         }
224
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));
232
233         /* set the reopen_type,sess_handle */
234         req->reopen_type = reopen_type;
235         req->session_handle = sess_handle;
236
237         be_mcc_notify(phba);
238         spin_unlock(&ctrl->mbox_lock);
239         return tag;
240 }
241
242 unsigned int mgmt_get_boot_target(struct beiscsi_hba *phba)
243 {
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;
248
249         beiscsi_log(phba, KERN_INFO,
250                     BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX,
251                     "BG_%d : In bescsi_get_boot_target\n");
252
253         spin_lock(&ctrl->mbox_lock);
254         tag = alloc_mcc_tag(phba);
255         if (!tag) {
256                 spin_unlock(&ctrl->mbox_lock);
257                 return tag;
258         }
259
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));
267
268         be_mcc_notify(phba);
269         spin_unlock(&ctrl->mbox_lock);
270         return tag;
271 }
272
273 unsigned int mgmt_get_session_info(struct beiscsi_hba *phba,
274                                    u32 boot_session_handle,
275                                    struct be_dma_mem *nonemb_cmd)
276 {
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;
283
284         beiscsi_log(phba, KERN_INFO,
285                     BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX,
286                     "BG_%d : In beiscsi_get_session_info\n");
287
288         spin_lock(&ctrl->mbox_lock);
289         tag = alloc_mcc_tag(phba);
290         if (!tag) {
291                 spin_unlock(&ctrl->mbox_lock);
292                 return tag;
293         }
294
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;
301
302
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);
312
313         be_mcc_notify(phba);
314         spin_unlock(&ctrl->mbox_lock);
315         return tag;
316 }
317
318 /**
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
322  *
323  * Get the FW config and resources available for the function.
324  * The resources are created based on the count received here.
325  *
326  * return
327  *      Success: 0
328  *      Failure: Non-Zero Value
329  **/
330 int mgmt_get_fw_config(struct be_ctrl_info *ctrl,
331                                 struct beiscsi_hba *phba)
332 {
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;
336
337         spin_lock(&ctrl->mbox_lock);
338         memset(wrb, 0, sizeof(*wrb));
339
340         be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
341
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;
350
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;
354
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);
360                 }
361
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);
367
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)) {
371
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;
376
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;
381
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;
386
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]);
402                         }
403                 }
404
405                 phba->fw_config.dual_ulp_aware = (pfw_cfg->function_mode &
406                                                   BEISCSI_FUNC_DUA_MODE);
407
408                 beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_INIT,
409                             "BG_%d : DUA Mode : 0x%x\n",
410                             phba->fw_config.dual_ulp_aware);
411
412         } else {
413                 beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT,
414                             "BG_%d : Failed in mgmt_get_fw_config\n");
415                 status = -EINVAL;
416         }
417
418         spin_unlock(&ctrl->mbox_lock);
419         return status;
420 }
421
422 int mgmt_check_supported_fw(struct be_ctrl_info *ctrl,
423                                       struct beiscsi_hba *phba)
424 {
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;
430
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;
439         }
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);
462
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);
477
478         return status;
479 }
480
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)
485 {
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;
493
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);
505
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]);
523
524                 spin_unlock(&ctrl->mbox_lock);
525                 return -ENOSYS;
526         }
527
528         tag = alloc_mcc_tag(phba);
529         if (!tag) {
530                 spin_unlock(&ctrl->mbox_lock);
531                 return tag;
532         }
533
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;
542
543         be_mcc_notify(phba);
544
545         spin_unlock(&ctrl->mbox_lock);
546         return tag;
547 }
548
549 /**
550  * mgmt_epfw_cleanup()- Inform FW to cleanup data structures.
551  * @phba: pointer to dev priv structure
552  * @ulp_num: ULP number.
553  *
554  * return
555  *      Success: 0
556  *      Failure: Non-Zero Value
557  **/
558 int mgmt_epfw_cleanup(struct beiscsi_hba *phba, unsigned short ulp_num)
559 {
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;
564
565         spin_lock(&ctrl->mbox_lock);
566
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));
570
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));
574
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;
581 }
582
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)
587
588 {
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;
594
595         spin_lock(&ctrl->mbox_lock);
596         tag = alloc_mcc_tag(phba);
597         if (!tag) {
598                 spin_unlock(&ctrl->mbox_lock);
599                 return tag;
600         }
601
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;
607
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++;
619         }
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);
623
624         be_mcc_notify(phba);
625         spin_unlock(&ctrl->mbox_lock);
626         return tag;
627 }
628
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)
634 {
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;
639
640         spin_lock(&ctrl->mbox_lock);
641         tag = alloc_mcc_tag(phba);
642         if (!tag) {
643                 spin_unlock(&ctrl->mbox_lock);
644                 return tag;
645         }
646         wrb = wrb_from_mccq(phba);
647         wrb->tag0 |= tag;
648         req = embedded_payload(wrb);
649
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;
664 }
665
666 unsigned int mgmt_upload_connection(struct beiscsi_hba *phba,
667                                 unsigned short cid, unsigned int upload_flag)
668 {
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;
673
674         spin_lock(&ctrl->mbox_lock);
675         tag = alloc_mcc_tag(phba);
676         if (!tag) {
677                 spin_unlock(&ctrl->mbox_lock);
678                 return tag;
679         }
680         wrb = wrb_from_mccq(phba);
681         req = embedded_payload(wrb);
682         wrb->tag0 |= tag;
683
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;
692 }
693
694 /**
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
699  *
700  * return
701  *      Success: Tag number of the MBX Command issued
702  *      Failure: Error code
703  **/
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)
708 {
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;
724
725         phwi_ctrlr = phba->phwi_ctrlr;
726         phwi_context = phwi_ctrlr->phwi_ctxt;
727
728         ulp_num = phwi_ctrlr->wrb_context[BE_GET_CRI_FROM_CID(cid)].ulp_num;
729
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);
732
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;
740         }
741         wrb = wrb_from_mccq(phba);
742         sge = nonembedded_sgl(wrb);
743
744         req = nonemb_cmd->va;
745         memset(req, 0, sizeof(*req));
746         wrb->tag0 |= tag;
747
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;
779
780         }
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);
797
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;
802         }
803
804         be_mcc_notify(phba);
805         spin_unlock(&ctrl->mbox_lock);
806         return tag;
807 }
808
809 unsigned int mgmt_get_all_if_id(struct beiscsi_hba *phba)
810 {
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;
816
817         memset(wrb, 0, sizeof(*wrb));
818
819         spin_lock(&ctrl->mbox_lock);
820
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");
831         }
832         spin_unlock(&ctrl->mbox_lock);
833
834         return status;
835 }
836
837 /*
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
843  *
844  **/
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)
848 {
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;
854
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;
861         }
862
863         wrb = wrb_from_mccq(phba);
864         wrb->tag0 |= tag;
865         sge = nonembedded_sgl(wrb);
866
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);
871
872         be_mcc_notify(phba);
873         spin_unlock(&ctrl->mbox_lock);
874
875         rc = beiscsi_mccq_compl(phba, tag, NULL, nonemb_cmd);
876
877         if (resp_buf)
878                 memcpy(resp_buf, nonemb_cmd->va, resp_buf_len);
879
880         if (rc) {
881                 /* Check if the MBX Cmd needs to be re-issued */
882                 if (rc == -EAGAIN)
883                         return rc;
884
885                 beiscsi_log(phba, KERN_WARNING,
886                             BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX,
887                             "BG_%d : mgmt_exec_nonemb_cmd Failed status\n");
888
889                 if (rc != -EBUSY)
890                         goto free_cmd;
891                 else
892                         return rc;
893         }
894 free_cmd:
895         pci_free_consistent(ctrl->pdev, nonemb_cmd->size,
896                             nonemb_cmd->va, nonemb_cmd->dma);
897         return rc;
898 }
899
900 static int mgmt_alloc_cmd_data(struct beiscsi_hba *phba, struct be_dma_mem *cmd,
901                                int iscsi_cmd, int size)
902 {
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;
908         }
909         cmd->size = size;
910         be_cmd_hdr_prepare(cmd->va, CMD_SUBSYSTEM_ISCSI, iscsi_cmd, size);
911         return 0;
912 }
913
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)
920 {
921         struct be_cmd_set_ip_addr_req *req;
922         struct be_dma_mem nonemb_cmd;
923         uint32_t ip_type;
924         int rc;
925
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;
931
932         ip_type = (ip_param->param == ISCSI_NET_PARAM_IPV6_ADDR) ?
933                 BE2_IPV6 : BE2_IPV4 ;
934
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;
943
944         if (ip_action == IP_ACTION_ADD) {
945                 memcpy(req->ip_params.ip_record.ip_addr.addr, ip_param->value,
946                        sizeof(req->ip_params.ip_record.ip_addr.addr));
947
948                 if (subnet_param)
949                         memcpy(req->ip_params.ip_record.ip_addr.subnet_mask,
950                                subnet_param->value,
951                                sizeof(req->ip_params.ip_record.ip_addr.subnet_mask));
952         } else {
953                 memcpy(req->ip_params.ip_record.ip_addr.addr,
954                        if_info->ip_addr.addr,
955                        sizeof(req->ip_params.ip_record.ip_addr.addr));
956
957                 memcpy(req->ip_params.ip_record.ip_addr.subnet_mask,
958                        if_info->ip_addr.subnet_mask,
959                        sizeof(req->ip_params.ip_record.ip_addr.subnet_mask));
960         }
961
962         rc = mgmt_exec_nonemb_cmd(phba, &nonemb_cmd, NULL, 0);
963         if (rc < 0)
964                 beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG,
965                             "BG_%d : Failed to Modify existing IP Address\n");
966         return rc;
967 }
968
969 static int mgmt_modify_gateway(struct beiscsi_hba *phba, uint8_t *gt_addr,
970                                uint32_t gtway_action, uint32_t param_len)
971 {
972         struct be_cmd_set_def_gateway_req *req;
973         struct be_dma_mem nonemb_cmd;
974         int rt_val;
975
976
977         rt_val = mgmt_alloc_cmd_data(phba, &nonemb_cmd,
978                                 OPCODE_COMMON_ISCSI_NTWK_MODIFY_DEFAULT_GATEWAY,
979                                 sizeof(*req));
980         if (rt_val)
981                 return rt_val;
982
983         req = nonemb_cmd.va;
984         req->action = gtway_action;
985         req->ip_addr.ip_type = BE2_IPV4;
986
987         memcpy(req->ip_addr.addr, gt_addr, sizeof(req->ip_addr.addr));
988
989         return mgmt_exec_nonemb_cmd(phba, &nonemb_cmd, NULL, 0);
990 }
991
992 int mgmt_set_ip(struct beiscsi_hba *phba,
993                 struct iscsi_iface_param_info *ip_param,
994                 struct iscsi_iface_param_info *subnet_param,
995                 uint32_t boot_proto)
996 {
997         struct be_cmd_get_def_gateway_resp gtway_addr_set;
998         struct be_cmd_get_if_info_resp *if_info;
999         struct be_cmd_set_dhcp_req *dhcpreq;
1000         struct be_cmd_rel_dhcp_req *reldhcp;
1001         struct be_dma_mem nonemb_cmd;
1002         uint8_t *gtway_addr;
1003         uint32_t ip_type;
1004         int rc;
1005
1006         if (mgmt_get_all_if_id(phba))
1007                 return -EIO;
1008
1009         ip_type = (ip_param->param == ISCSI_NET_PARAM_IPV6_ADDR) ?
1010                 BE2_IPV6 : BE2_IPV4 ;
1011
1012         rc = mgmt_get_if_info(phba, ip_type, &if_info);
1013         if (rc)
1014                 return rc;
1015
1016         if (boot_proto == ISCSI_BOOTPROTO_DHCP) {
1017                 if (if_info->dhcp_state) {
1018                         beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG,
1019                                     "BG_%d : DHCP Already Enabled\n");
1020                         goto exit;
1021                 }
1022                 /* The ip_param->len is 1 in DHCP case. Setting
1023                    proper IP len as this it is used while
1024                    freeing the Static IP.
1025                  */
1026                 ip_param->len = (ip_param->param == ISCSI_NET_PARAM_IPV6_ADDR) ?
1027                                 IP_V6_LEN : IP_V4_LEN;
1028
1029         } else {
1030                 if (if_info->dhcp_state) {
1031
1032                         memset(if_info, 0, sizeof(*if_info));
1033                         rc = mgmt_alloc_cmd_data(phba, &nonemb_cmd,
1034                                 OPCODE_COMMON_ISCSI_NTWK_REL_STATELESS_IP_ADDR,
1035                                 sizeof(*reldhcp));
1036
1037                         if (rc)
1038                                 goto exit;
1039
1040                         reldhcp = nonemb_cmd.va;
1041                         reldhcp->interface_hndl = phba->interface_handle;
1042                         reldhcp->ip_type = ip_type;
1043
1044                         rc = mgmt_exec_nonemb_cmd(phba, &nonemb_cmd, NULL, 0);
1045                         if (rc < 0) {
1046                                 beiscsi_log(phba, KERN_WARNING,
1047                                             BEISCSI_LOG_CONFIG,
1048                                             "BG_%d : Failed to Delete existing dhcp\n");
1049                                 goto exit;
1050                         }
1051                 }
1052         }
1053
1054         /* Delete the Static IP Set */
1055         if (if_info->ip_addr.addr[0]) {
1056                 rc = mgmt_static_ip_modify(phba, if_info, ip_param, NULL,
1057                                            IP_ACTION_DEL);
1058                 if (rc)
1059                         goto exit;
1060         }
1061
1062         /* Delete the Gateway settings if mode change is to DHCP */
1063         if (boot_proto == ISCSI_BOOTPROTO_DHCP) {
1064                 memset(&gtway_addr_set, 0, sizeof(gtway_addr_set));
1065                 rc = mgmt_get_gateway(phba, BE2_IPV4, &gtway_addr_set);
1066                 if (rc) {
1067                         beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG,
1068                                     "BG_%d : Failed to Get Gateway Addr\n");
1069                         goto exit;
1070                 }
1071
1072                 if (gtway_addr_set.ip_addr.addr[0]) {
1073                         gtway_addr = (uint8_t *)&gtway_addr_set.ip_addr.addr;
1074                         rc = mgmt_modify_gateway(phba, gtway_addr,
1075                                                  IP_ACTION_DEL, IP_V4_LEN);
1076
1077                         if (rc) {
1078                                 beiscsi_log(phba, KERN_WARNING,
1079                                             BEISCSI_LOG_CONFIG,
1080                                             "BG_%d : Failed to clear Gateway Addr Set\n");
1081                                 goto exit;
1082                         }
1083                 }
1084         }
1085
1086         /* Set Adapter to DHCP/Static Mode */
1087         if (boot_proto == ISCSI_BOOTPROTO_DHCP) {
1088                 rc = mgmt_alloc_cmd_data(phba, &nonemb_cmd,
1089                         OPCODE_COMMON_ISCSI_NTWK_CONFIG_STATELESS_IP_ADDR,
1090                         sizeof(*dhcpreq));
1091                 if (rc)
1092                         goto exit;
1093
1094                 dhcpreq = nonemb_cmd.va;
1095                 dhcpreq->flags = BLOCKING;
1096                 dhcpreq->retry_count = 1;
1097                 dhcpreq->interface_hndl = phba->interface_handle;
1098                 dhcpreq->ip_type = BE2_DHCP_V4;
1099
1100                 rc = mgmt_exec_nonemb_cmd(phba, &nonemb_cmd, NULL, 0);
1101         } else {
1102                 rc = mgmt_static_ip_modify(phba, if_info, ip_param,
1103                                              subnet_param, IP_ACTION_ADD);
1104         }
1105
1106 exit:
1107         kfree(if_info);
1108         return rc;
1109 }
1110
1111 int mgmt_set_gateway(struct beiscsi_hba *phba,
1112                      struct iscsi_iface_param_info *gateway_param)
1113 {
1114         struct be_cmd_get_def_gateway_resp gtway_addr_set;
1115         uint8_t *gtway_addr;
1116         int rt_val;
1117
1118         memset(&gtway_addr_set, 0, sizeof(gtway_addr_set));
1119         rt_val = mgmt_get_gateway(phba, BE2_IPV4, &gtway_addr_set);
1120         if (rt_val) {
1121                 beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG,
1122                             "BG_%d : Failed to Get Gateway Addr\n");
1123                 return rt_val;
1124         }
1125
1126         if (gtway_addr_set.ip_addr.addr[0]) {
1127                 gtway_addr = (uint8_t *)&gtway_addr_set.ip_addr.addr;
1128                 rt_val = mgmt_modify_gateway(phba, gtway_addr, IP_ACTION_DEL,
1129                                              gateway_param->len);
1130                 if (rt_val) {
1131                         beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG,
1132                                     "BG_%d : Failed to clear Gateway Addr Set\n");
1133                         return rt_val;
1134                 }
1135         }
1136
1137         gtway_addr = (uint8_t *)&gateway_param->value;
1138         rt_val = mgmt_modify_gateway(phba, gtway_addr, IP_ACTION_ADD,
1139                                      gateway_param->len);
1140
1141         if (rt_val)
1142                 beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG,
1143                             "BG_%d : Failed to Set Gateway Addr\n");
1144
1145         return rt_val;
1146 }
1147
1148 int mgmt_get_gateway(struct beiscsi_hba *phba, int ip_type,
1149                      struct be_cmd_get_def_gateway_resp *gateway)
1150 {
1151         struct be_cmd_get_def_gateway_req *req;
1152         struct be_dma_mem nonemb_cmd;
1153         int rc;
1154
1155         rc = mgmt_alloc_cmd_data(phba, &nonemb_cmd,
1156                                  OPCODE_COMMON_ISCSI_NTWK_GET_DEFAULT_GATEWAY,
1157                                  sizeof(*gateway));
1158         if (rc)
1159                 return rc;
1160
1161         req = nonemb_cmd.va;
1162         req->ip_type = ip_type;
1163
1164         return mgmt_exec_nonemb_cmd(phba, &nonemb_cmd, gateway,
1165                                     sizeof(*gateway));
1166 }
1167
1168 int mgmt_get_if_info(struct beiscsi_hba *phba, int ip_type,
1169                      struct be_cmd_get_if_info_resp **if_info)
1170 {
1171         struct be_cmd_get_if_info_req *req;
1172         struct be_dma_mem nonemb_cmd;
1173         uint32_t ioctl_size = sizeof(struct be_cmd_get_if_info_resp);
1174         int rc;
1175
1176         if (mgmt_get_all_if_id(phba))
1177                 return -EIO;
1178
1179         do {
1180                 rc = mgmt_alloc_cmd_data(phba, &nonemb_cmd,
1181                                          OPCODE_COMMON_ISCSI_NTWK_GET_IF_INFO,
1182                                          ioctl_size);
1183                 if (rc)
1184                         return rc;
1185
1186                 req = nonemb_cmd.va;
1187                 req->interface_hndl = phba->interface_handle;
1188                 req->ip_type = ip_type;
1189
1190                 /* Allocate memory for if_info */
1191                 *if_info = kzalloc(ioctl_size, GFP_KERNEL);
1192                 if (!*if_info) {
1193                         beiscsi_log(phba, KERN_ERR,
1194                                     BEISCSI_LOG_INIT | BEISCSI_LOG_CONFIG,
1195                                     "BG_%d : Memory Allocation Failure\n");
1196
1197                                 /* Free the DMA memory for the IOCTL issuing */
1198                                 pci_free_consistent(phba->ctrl.pdev,
1199                                                     nonemb_cmd.size,
1200                                                     nonemb_cmd.va,
1201                                                     nonemb_cmd.dma);
1202                                 return -ENOMEM;
1203                 }
1204
1205                 rc =  mgmt_exec_nonemb_cmd(phba, &nonemb_cmd, *if_info,
1206                                            ioctl_size);
1207
1208                 /* Check if the error is because of Insufficent_Buffer */
1209                 if (rc == -EAGAIN) {
1210
1211                         /* Get the new memory size */
1212                         ioctl_size = ((struct be_cmd_resp_hdr *)
1213                                       nonemb_cmd.va)->actual_resp_len;
1214                         ioctl_size += sizeof(struct be_cmd_req_hdr);
1215
1216                         /* Free the previous allocated DMA memory */
1217                         pci_free_consistent(phba->ctrl.pdev, nonemb_cmd.size,
1218                                             nonemb_cmd.va,
1219                                             nonemb_cmd.dma);
1220
1221                         /* Free the virtual memory */
1222                         kfree(*if_info);
1223                 } else
1224                         break;
1225         } while (true);
1226         return rc;
1227 }
1228
1229 int mgmt_get_nic_conf(struct beiscsi_hba *phba,
1230                       struct be_cmd_get_nic_conf_resp *nic)
1231 {
1232         struct be_dma_mem nonemb_cmd;
1233         int rc;
1234
1235         rc = mgmt_alloc_cmd_data(phba, &nonemb_cmd,
1236                                  OPCODE_COMMON_ISCSI_NTWK_GET_NIC_CONFIG,
1237                                  sizeof(*nic));
1238         if (rc)
1239                 return rc;
1240
1241         return mgmt_exec_nonemb_cmd(phba, &nonemb_cmd, nic, sizeof(*nic));
1242 }
1243
1244
1245
1246 unsigned int be_cmd_get_initname(struct beiscsi_hba *phba)
1247 {
1248         unsigned int tag = 0;
1249         struct be_mcc_wrb *wrb;
1250         struct be_cmd_hba_name *req;
1251         struct be_ctrl_info *ctrl = &phba->ctrl;
1252
1253         spin_lock(&ctrl->mbox_lock);
1254         tag = alloc_mcc_tag(phba);
1255         if (!tag) {
1256                 spin_unlock(&ctrl->mbox_lock);
1257                 return tag;
1258         }
1259
1260         wrb = wrb_from_mccq(phba);
1261         req = embedded_payload(wrb);
1262         wrb->tag0 |= tag;
1263         be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
1264         be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI_INI,
1265                         OPCODE_ISCSI_INI_CFG_GET_HBA_NAME,
1266                         sizeof(*req));
1267
1268         be_mcc_notify(phba);
1269         spin_unlock(&ctrl->mbox_lock);
1270         return tag;
1271 }
1272
1273 unsigned int be_cmd_get_port_speed(struct beiscsi_hba *phba)
1274 {
1275         unsigned int tag = 0;
1276         struct be_mcc_wrb *wrb;
1277         struct be_cmd_ntwk_link_status_req *req;
1278         struct be_ctrl_info *ctrl = &phba->ctrl;
1279
1280         spin_lock(&ctrl->mbox_lock);
1281         tag = alloc_mcc_tag(phba);
1282         if (!tag) {
1283                 spin_unlock(&ctrl->mbox_lock);
1284                 return tag;
1285         }
1286
1287         wrb = wrb_from_mccq(phba);
1288         req = embedded_payload(wrb);
1289         wrb->tag0 |= tag;
1290         be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
1291         be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
1292                         OPCODE_COMMON_NTWK_LINK_STATUS_QUERY,
1293                         sizeof(*req));
1294
1295         be_mcc_notify(phba);
1296         spin_unlock(&ctrl->mbox_lock);
1297         return tag;
1298 }
1299
1300 /**
1301  * be_mgmt_get_boot_shandle()- Get the session handle
1302  * @phba: device priv structure instance
1303  * @s_handle: session handle returned for boot session.
1304  *
1305  * Get the boot target session handle. In case of
1306  * crashdump mode driver has to issue and MBX Cmd
1307  * for FW to login to boot target
1308  *
1309  * return
1310  *      Success: 0
1311  *      Failure: Non-Zero value
1312  *
1313  **/
1314 int be_mgmt_get_boot_shandle(struct beiscsi_hba *phba,
1315                               unsigned int *s_handle)
1316 {
1317         struct be_cmd_get_boot_target_resp *boot_resp;
1318         struct be_mcc_wrb *wrb;
1319         unsigned int tag;
1320         uint8_t boot_retry = 3;
1321         int rc;
1322
1323         do {
1324                 /* Get the Boot Target Session Handle and Count*/
1325                 tag = mgmt_get_boot_target(phba);
1326                 if (!tag) {
1327                         beiscsi_log(phba, KERN_ERR,
1328                                     BEISCSI_LOG_CONFIG | BEISCSI_LOG_INIT,
1329                                     "BG_%d : Getting Boot Target Info Failed\n");
1330                         return -EAGAIN;
1331                 }
1332
1333                 rc = beiscsi_mccq_compl(phba, tag, &wrb, NULL);
1334                 if (rc) {
1335                         beiscsi_log(phba, KERN_ERR,
1336                                     BEISCSI_LOG_INIT | BEISCSI_LOG_CONFIG,
1337                                     "BG_%d : MBX CMD get_boot_target Failed\n");
1338                         return -EBUSY;
1339                 }
1340
1341                 boot_resp = embedded_payload(wrb);
1342
1343                 /* Check if the there are any Boot targets configured */
1344                 if (!boot_resp->boot_session_count) {
1345                         beiscsi_log(phba, KERN_INFO,
1346                                     BEISCSI_LOG_INIT | BEISCSI_LOG_CONFIG,
1347                                     "BG_%d  ;No boot targets configured\n");
1348                         return -ENXIO;
1349                 }
1350
1351                 /* FW returns the session handle of the boot session */
1352                 if (boot_resp->boot_session_handle != INVALID_SESS_HANDLE) {
1353                         *s_handle = boot_resp->boot_session_handle;
1354                         return 0;
1355                 }
1356
1357                 /* Issue MBX Cmd to FW to login to the boot target */
1358                 tag = mgmt_reopen_session(phba, BE_REOPEN_BOOT_SESSIONS,
1359                                           INVALID_SESS_HANDLE);
1360                 if (!tag) {
1361                         beiscsi_log(phba, KERN_ERR,
1362                                     BEISCSI_LOG_INIT | BEISCSI_LOG_CONFIG,
1363                                     "BG_%d : mgmt_reopen_session Failed\n");
1364                         return -EAGAIN;
1365                 }
1366
1367                 rc = beiscsi_mccq_compl(phba, tag, NULL, NULL);
1368                 if (rc) {
1369                         beiscsi_log(phba, KERN_ERR,
1370                                     BEISCSI_LOG_INIT | BEISCSI_LOG_CONFIG,
1371                                     "BG_%d : mgmt_reopen_session Failed");
1372                         return rc;
1373                 }
1374         } while (--boot_retry);
1375
1376         /* Couldn't log into the boot target */
1377         beiscsi_log(phba, KERN_ERR,
1378                     BEISCSI_LOG_INIT | BEISCSI_LOG_CONFIG,
1379                     "BG_%d : Login to Boot Target Failed\n");
1380         return -ENXIO;
1381 }
1382
1383 /**
1384  * mgmt_set_vlan()- Issue and wait for CMD completion
1385  * @phba: device private structure instance
1386  * @vlan_tag: VLAN tag
1387  *
1388  * Issue the MBX Cmd and wait for the completion of the
1389  * command.
1390  *
1391  * returns
1392  *      Success: 0
1393  *      Failure: Non-Xero Value
1394  **/
1395 int mgmt_set_vlan(struct beiscsi_hba *phba,
1396                    uint16_t vlan_tag)
1397 {
1398         int rc;
1399         unsigned int tag;
1400
1401         tag = be_cmd_set_vlan(phba, vlan_tag);
1402         if (!tag) {
1403                 beiscsi_log(phba, KERN_ERR,
1404                             (BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX),
1405                             "BG_%d : VLAN Setting Failed\n");
1406                 return -EBUSY;
1407         }
1408
1409         rc = beiscsi_mccq_compl(phba, tag, NULL, NULL);
1410         if (rc) {
1411                 beiscsi_log(phba, KERN_ERR,
1412                             (BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX),
1413                             "BS_%d : VLAN MBX Cmd Failed\n");
1414                 return rc;
1415         }
1416         return rc;
1417 }
1418
1419 /**
1420  * beiscsi_drvr_ver_disp()- Display the driver Name and Version
1421  * @dev: ptr to device not used.
1422  * @attr: device attribute, not used.
1423  * @buf: contains formatted text driver name and version
1424  *
1425  * return
1426  * size of the formatted string
1427  **/
1428 ssize_t
1429 beiscsi_drvr_ver_disp(struct device *dev, struct device_attribute *attr,
1430                        char *buf)
1431 {
1432         return snprintf(buf, PAGE_SIZE, BE_NAME "\n");
1433 }
1434
1435 /**
1436  * beiscsi_fw_ver_disp()- Display Firmware Version
1437  * @dev: ptr to device not used.
1438  * @attr: device attribute, not used.
1439  * @buf: contains formatted text Firmware version
1440  *
1441  * return
1442  * size of the formatted string
1443  **/
1444 ssize_t
1445 beiscsi_fw_ver_disp(struct device *dev, struct device_attribute *attr,
1446                      char *buf)
1447 {
1448         struct Scsi_Host *shost = class_to_shost(dev);
1449         struct beiscsi_hba *phba = iscsi_host_priv(shost);
1450
1451         return snprintf(buf, PAGE_SIZE, "%s\n", phba->fw_ver_str);
1452 }
1453
1454 /**
1455  * beiscsi_active_session_disp()- Display Sessions Active
1456  * @dev: ptr to device not used.
1457  * @attr: device attribute, not used.
1458  * @buf: contains formatted text Session Count
1459  *
1460  * return
1461  * size of the formatted string
1462  **/
1463 ssize_t
1464 beiscsi_active_session_disp(struct device *dev, struct device_attribute *attr,
1465                          char *buf)
1466 {
1467         struct Scsi_Host *shost = class_to_shost(dev);
1468         struct beiscsi_hba *phba = iscsi_host_priv(shost);
1469         uint16_t avlbl_cids = 0, ulp_num, len = 0, total_cids = 0;
1470
1471         for (ulp_num = 0; ulp_num < BEISCSI_ULP_COUNT; ulp_num++) {
1472                 if (test_bit(ulp_num, (void *)&phba->fw_config.ulp_supported)) {
1473                         avlbl_cids = BEISCSI_ULP_AVLBL_CID(phba, ulp_num);
1474                         total_cids = BEISCSI_GET_CID_COUNT(phba, ulp_num);
1475                         len += snprintf(buf+len, PAGE_SIZE - len,
1476                                         "ULP%d : %d\n", ulp_num,
1477                                         (total_cids - avlbl_cids));
1478                 } else
1479                         len += snprintf(buf+len, PAGE_SIZE - len,
1480                                         "ULP%d : %d\n", ulp_num, 0);
1481         }
1482
1483         return len;
1484 }
1485
1486 /**
1487  * beiscsi_free_session_disp()- Display Avaliable Session
1488  * @dev: ptr to device not used.
1489  * @attr: device attribute, not used.
1490  * @buf: contains formatted text Session Count
1491  *
1492  * return
1493  * size of the formatted string
1494  **/
1495 ssize_t
1496 beiscsi_free_session_disp(struct device *dev, struct device_attribute *attr,
1497                        char *buf)
1498 {
1499         struct Scsi_Host *shost = class_to_shost(dev);
1500         struct beiscsi_hba *phba = iscsi_host_priv(shost);
1501         uint16_t ulp_num, len = 0;
1502
1503         for (ulp_num = 0; ulp_num < BEISCSI_ULP_COUNT; ulp_num++) {
1504                 if (test_bit(ulp_num, (void *)&phba->fw_config.ulp_supported))
1505                         len += snprintf(buf+len, PAGE_SIZE - len,
1506                                         "ULP%d : %d\n", ulp_num,
1507                                         BEISCSI_ULP_AVLBL_CID(phba, ulp_num));
1508                 else
1509                         len += snprintf(buf+len, PAGE_SIZE - len,
1510                                         "ULP%d : %d\n", ulp_num, 0);
1511         }
1512
1513         return len;
1514 }
1515
1516 /**
1517  * beiscsi_adap_family_disp()- Display adapter family.
1518  * @dev: ptr to device to get priv structure
1519  * @attr: device attribute, not used.
1520  * @buf: contains formatted text driver name and version
1521  *
1522  * return
1523  * size of the formatted string
1524  **/
1525 ssize_t
1526 beiscsi_adap_family_disp(struct device *dev, struct device_attribute *attr,
1527                           char *buf)
1528 {
1529         uint16_t dev_id = 0;
1530         struct Scsi_Host *shost = class_to_shost(dev);
1531         struct beiscsi_hba *phba = iscsi_host_priv(shost);
1532
1533         dev_id = phba->pcidev->device;
1534         switch (dev_id) {
1535         case BE_DEVICE_ID1:
1536         case OC_DEVICE_ID1:
1537         case OC_DEVICE_ID2:
1538                 return snprintf(buf, PAGE_SIZE, "BE2 Adapter Family\n");
1539                 break;
1540         case BE_DEVICE_ID2:
1541         case OC_DEVICE_ID3:
1542                 return snprintf(buf, PAGE_SIZE, "BE3-R Adapter Family\n");
1543                 break;
1544         case OC_SKH_ID1:
1545                 return snprintf(buf, PAGE_SIZE, "Skyhawk-R Adapter Family\n");
1546                 break;
1547         default:
1548                 return snprintf(buf, PAGE_SIZE,
1549                                 "Unknown Adapter Family: 0x%x\n", dev_id);
1550                 break;
1551         }
1552 }
1553
1554 /**
1555  * beiscsi_phys_port()- Display Physical Port Identifier
1556  * @dev: ptr to device not used.
1557  * @attr: device attribute, not used.
1558  * @buf: contains formatted text port identifier
1559  *
1560  * return
1561  * size of the formatted string
1562  **/
1563 ssize_t
1564 beiscsi_phys_port_disp(struct device *dev, struct device_attribute *attr,
1565                          char *buf)
1566 {
1567         struct Scsi_Host *shost = class_to_shost(dev);
1568         struct beiscsi_hba *phba = iscsi_host_priv(shost);
1569
1570         return snprintf(buf, PAGE_SIZE, "Port Identifier : %d\n",
1571                         phba->fw_config.phys_port);
1572 }
1573
1574 void beiscsi_offload_cxn_v0(struct beiscsi_offload_params *params,
1575                              struct wrb_handle *pwrb_handle,
1576                              struct be_mem_descriptor *mem_descr)
1577 {
1578         struct iscsi_wrb *pwrb = pwrb_handle->pwrb;
1579
1580         memset(pwrb, 0, sizeof(*pwrb));
1581         AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb,
1582                       max_send_data_segment_length, pwrb,
1583                       params->dw[offsetof(struct amap_beiscsi_offload_params,
1584                       max_send_data_segment_length) / 32]);
1585         AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, type, pwrb,
1586                       BE_TGT_CTX_UPDT_CMD);
1587         AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb,
1588                       first_burst_length,
1589                       pwrb,
1590                       params->dw[offsetof(struct amap_beiscsi_offload_params,
1591                       first_burst_length) / 32]);
1592         AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, erl, pwrb,
1593                       (params->dw[offsetof(struct amap_beiscsi_offload_params,
1594                       erl) / 32] & OFFLD_PARAMS_ERL));
1595         AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, dde, pwrb,
1596                       (params->dw[offsetof(struct amap_beiscsi_offload_params,
1597                        dde) / 32] & OFFLD_PARAMS_DDE) >> 2);
1598         AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, hde, pwrb,
1599                       (params->dw[offsetof(struct amap_beiscsi_offload_params,
1600                       hde) / 32] & OFFLD_PARAMS_HDE) >> 3);
1601         AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, ir2t, pwrb,
1602                       (params->dw[offsetof(struct amap_beiscsi_offload_params,
1603                       ir2t) / 32] & OFFLD_PARAMS_IR2T) >> 4);
1604         AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, imd, pwrb,
1605                       (params->dw[offsetof(struct amap_beiscsi_offload_params,
1606                       imd) / 32] & OFFLD_PARAMS_IMD) >> 5);
1607         AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, stat_sn,
1608                       pwrb,
1609                       (params->dw[offsetof(struct amap_beiscsi_offload_params,
1610                       exp_statsn) / 32] + 1));
1611         AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, wrb_idx,
1612                       pwrb, pwrb_handle->wrb_index);
1613
1614         AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb,
1615                       max_burst_length, pwrb, params->dw[offsetof
1616                       (struct amap_beiscsi_offload_params,
1617                       max_burst_length) / 32]);
1618
1619         AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, ptr2nextwrb,
1620                       pwrb, pwrb_handle->nxt_wrb_index);
1621         AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb,
1622                       session_state, pwrb, 0);
1623         AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, compltonack,
1624                       pwrb, 1);
1625         AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, notpredblq,
1626                       pwrb, 0);
1627         AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, mode, pwrb,
1628                       0);
1629
1630         mem_descr += ISCSI_MEM_GLOBAL_HEADER;
1631         AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb,
1632                       pad_buffer_addr_hi, pwrb,
1633                       mem_descr->mem_array[0].bus_address.u.a32.address_hi);
1634         AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb,
1635                       pad_buffer_addr_lo, pwrb,
1636                       mem_descr->mem_array[0].bus_address.u.a32.address_lo);
1637 }
1638
1639 void beiscsi_offload_cxn_v2(struct beiscsi_offload_params *params,
1640                              struct wrb_handle *pwrb_handle)
1641 {
1642         struct iscsi_wrb *pwrb = pwrb_handle->pwrb;
1643
1644         memset(pwrb, 0, sizeof(*pwrb));
1645
1646         AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2,
1647                       max_burst_length, pwrb, params->dw[offsetof
1648                       (struct amap_beiscsi_offload_params,
1649                       max_burst_length) / 32]);
1650         AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2,
1651                       type, pwrb,
1652                       BE_TGT_CTX_UPDT_CMD);
1653         AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2,
1654                       ptr2nextwrb,
1655                       pwrb, pwrb_handle->nxt_wrb_index);
1656         AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2, wrb_idx,
1657                       pwrb, pwrb_handle->wrb_index);
1658         AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2,
1659                       max_send_data_segment_length, pwrb,
1660                       params->dw[offsetof(struct amap_beiscsi_offload_params,
1661                       max_send_data_segment_length) / 32]);
1662         AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2,
1663                       first_burst_length, pwrb,
1664                       params->dw[offsetof(struct amap_beiscsi_offload_params,
1665                       first_burst_length) / 32]);
1666         AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2,
1667                       max_recv_dataseg_len, pwrb,
1668                       params->dw[offsetof(struct amap_beiscsi_offload_params,
1669                       max_recv_data_segment_length) / 32]);
1670         AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2,
1671                       max_cxns, pwrb, BEISCSI_MAX_CXNS);
1672         AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2, erl, pwrb,
1673                       (params->dw[offsetof(struct amap_beiscsi_offload_params,
1674                       erl) / 32] & OFFLD_PARAMS_ERL));
1675         AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2, dde, pwrb,
1676                       (params->dw[offsetof(struct amap_beiscsi_offload_params,
1677                       dde) / 32] & OFFLD_PARAMS_DDE) >> 2);
1678         AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2, hde, pwrb,
1679                       (params->dw[offsetof(struct amap_beiscsi_offload_params,
1680                       hde) / 32] & OFFLD_PARAMS_HDE) >> 3);
1681         AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2,
1682                       ir2t, pwrb,
1683                       (params->dw[offsetof(struct amap_beiscsi_offload_params,
1684                       ir2t) / 32] & OFFLD_PARAMS_IR2T) >> 4);
1685         AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2, imd, pwrb,
1686                       (params->dw[offsetof(struct amap_beiscsi_offload_params,
1687                       imd) / 32] & OFFLD_PARAMS_IMD) >> 5);
1688         AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2,
1689                       data_seq_inorder,
1690                       pwrb,
1691                       (params->dw[offsetof(struct amap_beiscsi_offload_params,
1692                       data_seq_inorder) / 32] &
1693                       OFFLD_PARAMS_DATA_SEQ_INORDER) >> 6);
1694         AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2,
1695                       pdu_seq_inorder,
1696                       pwrb,
1697                       (params->dw[offsetof(struct amap_beiscsi_offload_params,
1698                       pdu_seq_inorder) / 32] &
1699                       OFFLD_PARAMS_PDU_SEQ_INORDER) >> 7);
1700         AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2, max_r2t,
1701                       pwrb,
1702                       (params->dw[offsetof(struct amap_beiscsi_offload_params,
1703                       max_r2t) / 32] &
1704                       OFFLD_PARAMS_MAX_R2T) >> 8);
1705         AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2, stat_sn,
1706                       pwrb,
1707                      (params->dw[offsetof(struct amap_beiscsi_offload_params,
1708                       exp_statsn) / 32] + 1));
1709 }
1710
1711 /**
1712  * beiscsi_logout_fw_sess()- Firmware Session Logout
1713  * @phba: Device priv structure instance
1714  * @fw_sess_handle: FW session handle
1715  *
1716  * Logout from the FW established sessions.
1717  * returns
1718  *  Success: 0
1719  *  Failure: Non-Zero Value
1720  *
1721  */
1722 int beiscsi_logout_fw_sess(struct beiscsi_hba *phba,
1723                 uint32_t fw_sess_handle)
1724 {
1725         struct be_ctrl_info *ctrl = &phba->ctrl;
1726         struct be_mcc_wrb *wrb;
1727         struct be_cmd_req_logout_fw_sess *req;
1728         struct be_cmd_resp_logout_fw_sess *resp;
1729         unsigned int tag;
1730         int rc;
1731
1732         beiscsi_log(phba, KERN_INFO,
1733                     BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX,
1734                     "BG_%d : In bescsi_logout_fwboot_sess\n");
1735
1736         spin_lock(&ctrl->mbox_lock);
1737         tag = alloc_mcc_tag(phba);
1738         if (!tag) {
1739                 spin_unlock(&ctrl->mbox_lock);
1740                 beiscsi_log(phba, KERN_INFO,
1741                             BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX,
1742                             "BG_%d : MBX Tag Failure\n");
1743                 return -EINVAL;
1744         }
1745
1746         wrb = wrb_from_mccq(phba);
1747         req = embedded_payload(wrb);
1748         wrb->tag0 |= tag;
1749         be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
1750         be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI_INI,
1751                            OPCODE_ISCSI_INI_SESSION_LOGOUT_TARGET,
1752                            sizeof(struct be_cmd_req_logout_fw_sess));
1753
1754         /* Set the session handle */
1755         req->session_handle = fw_sess_handle;
1756         be_mcc_notify(phba);
1757         spin_unlock(&ctrl->mbox_lock);
1758
1759         rc = beiscsi_mccq_compl(phba, tag, &wrb, NULL);
1760         if (rc) {
1761                 beiscsi_log(phba, KERN_ERR,
1762                             BEISCSI_LOG_INIT | BEISCSI_LOG_CONFIG,
1763                             "BG_%d : MBX CMD FW_SESSION_LOGOUT_TARGET Failed\n");
1764                 return -EBUSY;
1765         }
1766
1767         resp = embedded_payload(wrb);
1768         if (resp->session_status !=
1769                 BEISCSI_MGMT_SESSION_CLOSE) {
1770                 beiscsi_log(phba, KERN_ERR,
1771                             BEISCSI_LOG_INIT | BEISCSI_LOG_CONFIG,
1772                             "BG_%d : FW_SESSION_LOGOUT_TARGET resp : 0x%x\n",
1773                             resp->session_status);
1774                 rc = -EINVAL;
1775         }
1776
1777         return rc;
1778 }