Merge tag 'ntb-4.6' of git://github.com/jonmason/ntb
[cascardo/linux.git] / drivers / scsi / be2iscsi / be_mgmt.c
1 /**
2  * Copyright (C) 2005 - 2015 Emulex
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  * Emulex
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;
165         int i;
166
167         mutex_lock(&ctrl->mbox_lock);
168         wrb = alloc_mcc_wrb(phba, &tag);
169         if (!wrb) {
170                 mutex_unlock(&ctrl->mbox_lock);
171                 return 0;
172         }
173
174         req = embedded_payload(wrb);
175         be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
176         be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
177                 OPCODE_COMMON_MODIFY_EQ_DELAY, sizeof(*req));
178
179         req->num_eq = cpu_to_le32(num);
180         for (i = 0; i < num; i++) {
181                 req->delay[i].eq_id = cpu_to_le32(set_eqd[i].eq_id);
182                 req->delay[i].phase = 0;
183                 req->delay[i].delay_multiplier =
184                                 cpu_to_le32(set_eqd[i].delay_multiplier);
185         }
186
187         be_mcc_notify(phba, tag);
188         mutex_unlock(&ctrl->mbox_lock);
189         return tag;
190 }
191
192 /**
193  * mgmt_reopen_session()- Reopen a session based on reopen_type
194  * @phba: Device priv structure instance
195  * @reopen_type: Type of reopen_session FW should do.
196  * @sess_handle: Session Handle of the session to be re-opened
197  *
198  * return
199  *      the TAG used for MBOX Command
200  *
201  **/
202 unsigned int mgmt_reopen_session(struct beiscsi_hba *phba,
203                                   unsigned int reopen_type,
204                                   unsigned int sess_handle)
205 {
206         struct be_ctrl_info *ctrl = &phba->ctrl;
207         struct be_mcc_wrb *wrb;
208         struct be_cmd_reopen_session_req *req;
209         unsigned int tag;
210
211         beiscsi_log(phba, KERN_INFO,
212                     BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX,
213                     "BG_%d : In bescsi_get_boot_target\n");
214
215         mutex_lock(&ctrl->mbox_lock);
216         wrb = alloc_mcc_wrb(phba, &tag);
217         if (!wrb) {
218                 mutex_unlock(&ctrl->mbox_lock);
219                 return 0;
220         }
221
222         req = embedded_payload(wrb);
223         be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
224         be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI_INI,
225                            OPCODE_ISCSI_INI_DRIVER_REOPEN_ALL_SESSIONS,
226                            sizeof(struct be_cmd_reopen_session_resp));
227
228         /* set the reopen_type,sess_handle */
229         req->reopen_type = reopen_type;
230         req->session_handle = sess_handle;
231
232         be_mcc_notify(phba, tag);
233         mutex_unlock(&ctrl->mbox_lock);
234         return tag;
235 }
236
237 unsigned int mgmt_get_boot_target(struct beiscsi_hba *phba)
238 {
239         struct be_ctrl_info *ctrl = &phba->ctrl;
240         struct be_mcc_wrb *wrb;
241         struct be_cmd_get_boot_target_req *req;
242         unsigned int tag;
243
244         beiscsi_log(phba, KERN_INFO,
245                     BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX,
246                     "BG_%d : In bescsi_get_boot_target\n");
247
248         mutex_lock(&ctrl->mbox_lock);
249         wrb = alloc_mcc_wrb(phba, &tag);
250         if (!wrb) {
251                 mutex_unlock(&ctrl->mbox_lock);
252                 return 0;
253         }
254
255         req = embedded_payload(wrb);
256         be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
257         be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI_INI,
258                            OPCODE_ISCSI_INI_BOOT_GET_BOOT_TARGET,
259                            sizeof(struct be_cmd_get_boot_target_resp));
260
261         be_mcc_notify(phba, tag);
262         mutex_unlock(&ctrl->mbox_lock);
263         return tag;
264 }
265
266 unsigned int mgmt_get_session_info(struct beiscsi_hba *phba,
267                                    u32 boot_session_handle,
268                                    struct be_dma_mem *nonemb_cmd)
269 {
270         struct be_ctrl_info *ctrl = &phba->ctrl;
271         struct be_mcc_wrb *wrb;
272         unsigned int tag;
273         struct  be_cmd_get_session_req *req;
274         struct be_cmd_get_session_resp *resp;
275         struct be_sge *sge;
276
277         beiscsi_log(phba, KERN_INFO,
278                     BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX,
279                     "BG_%d : In beiscsi_get_session_info\n");
280
281         mutex_lock(&ctrl->mbox_lock);
282         wrb = alloc_mcc_wrb(phba, &tag);
283         if (!wrb) {
284                 mutex_unlock(&ctrl->mbox_lock);
285                 return 0;
286         }
287
288         nonemb_cmd->size = sizeof(*resp);
289         req = nonemb_cmd->va;
290         memset(req, 0, sizeof(*req));
291         sge = nonembedded_sgl(wrb);
292         be_wrb_hdr_prepare(wrb, sizeof(*req), false, 1);
293         be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI_INI,
294                            OPCODE_ISCSI_INI_SESSION_GET_A_SESSION,
295                            sizeof(*resp));
296         req->session_handle = boot_session_handle;
297         sge->pa_hi = cpu_to_le32(upper_32_bits(nonemb_cmd->dma));
298         sge->pa_lo = cpu_to_le32(nonemb_cmd->dma & 0xFFFFFFFF);
299         sge->len = cpu_to_le32(nonemb_cmd->size);
300
301         be_mcc_notify(phba, tag);
302         mutex_unlock(&ctrl->mbox_lock);
303         return tag;
304 }
305
306 /**
307  * mgmt_get_port_name()- Get port name for the function
308  * @ctrl: ptr to Ctrl Info
309  * @phba: ptr to the dev priv structure
310  *
311  * Get the alphanumeric character for port
312  *
313  **/
314 int mgmt_get_port_name(struct be_ctrl_info *ctrl,
315                        struct beiscsi_hba *phba)
316 {
317         int ret = 0;
318         struct be_mcc_wrb *wrb;
319         struct be_cmd_get_port_name *ioctl;
320
321         mutex_lock(&ctrl->mbox_lock);
322         wrb = wrb_from_mbox(&ctrl->mbox_mem);
323         memset(wrb, 0, sizeof(*wrb));
324         ioctl = embedded_payload(wrb);
325
326         be_wrb_hdr_prepare(wrb, sizeof(*ioctl), true, 0);
327         be_cmd_hdr_prepare(&ioctl->h.req_hdr, CMD_SUBSYSTEM_COMMON,
328                            OPCODE_COMMON_GET_PORT_NAME,
329                            EMBED_MBX_MAX_PAYLOAD_SIZE);
330         ret = be_mbox_notify(ctrl);
331         phba->port_name = 0;
332         if (!ret) {
333                 phba->port_name = ioctl->p.resp.port_names >>
334                                   (phba->fw_config.phys_port * 8) & 0xff;
335         } else {
336                 beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_INIT,
337                             "BG_%d : GET_PORT_NAME ret 0x%x status 0x%x\n",
338                             ret, ioctl->h.resp_hdr.status);
339         }
340
341         if (phba->port_name == 0)
342                 phba->port_name = '?';
343
344         mutex_unlock(&ctrl->mbox_lock);
345         return ret;
346 }
347
348 /**
349  * mgmt_get_fw_config()- Get the FW config for the function
350  * @ctrl: ptr to Ctrl Info
351  * @phba: ptr to the dev priv structure
352  *
353  * Get the FW config and resources available for the function.
354  * The resources are created based on the count received here.
355  *
356  * return
357  *      Success: 0
358  *      Failure: Non-Zero Value
359  **/
360 int mgmt_get_fw_config(struct be_ctrl_info *ctrl,
361                                 struct beiscsi_hba *phba)
362 {
363         struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem);
364         struct be_fw_cfg *pfw_cfg = embedded_payload(wrb);
365         uint32_t cid_count, icd_count;
366         int status = -EINVAL;
367         uint8_t ulp_num = 0;
368
369         mutex_lock(&ctrl->mbox_lock);
370         memset(wrb, 0, sizeof(*wrb));
371         be_wrb_hdr_prepare(wrb, sizeof(*pfw_cfg), true, 0);
372
373         be_cmd_hdr_prepare(&pfw_cfg->hdr, CMD_SUBSYSTEM_COMMON,
374                            OPCODE_COMMON_QUERY_FIRMWARE_CONFIG,
375                            EMBED_MBX_MAX_PAYLOAD_SIZE);
376
377         if (be_mbox_notify(ctrl)) {
378                 beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT,
379                             "BG_%d : Failed in mgmt_get_fw_config\n");
380                 goto fail_init;
381         }
382
383         /* FW response formats depend on port id */
384         phba->fw_config.phys_port = pfw_cfg->phys_port;
385         if (phba->fw_config.phys_port >= BEISCSI_PHYS_PORT_MAX) {
386                 beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT,
387                             "BG_%d : invalid physical port id %d\n",
388                             phba->fw_config.phys_port);
389                 goto fail_init;
390         }
391
392         /* populate and check FW config against min and max values */
393         if (!is_chip_be2_be3r(phba)) {
394                 phba->fw_config.eqid_count = pfw_cfg->eqid_count;
395                 phba->fw_config.cqid_count = pfw_cfg->cqid_count;
396                 if (phba->fw_config.eqid_count == 0 ||
397                     phba->fw_config.eqid_count > 2048) {
398                         beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT,
399                                     "BG_%d : invalid EQ count %d\n",
400                                     phba->fw_config.eqid_count);
401                         goto fail_init;
402                 }
403                 if (phba->fw_config.cqid_count == 0 ||
404                     phba->fw_config.cqid_count > 4096) {
405                         beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT,
406                                     "BG_%d : invalid CQ count %d\n",
407                                     phba->fw_config.cqid_count);
408                         goto fail_init;
409                 }
410                 beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_INIT,
411                             "BG_%d : EQ_Count : %d CQ_Count : %d\n",
412                             phba->fw_config.eqid_count,
413                             phba->fw_config.cqid_count);
414         }
415
416         /**
417          * Check on which all ULP iSCSI Protocol is loaded.
418          * Set the Bit for those ULP. This set flag is used
419          * at all places in the code to check on which ULP
420          * iSCSi Protocol is loaded
421          **/
422         for (ulp_num = 0; ulp_num < BEISCSI_ULP_COUNT; ulp_num++) {
423                 if (pfw_cfg->ulp[ulp_num].ulp_mode &
424                     BEISCSI_ULP_ISCSI_INI_MODE) {
425                         set_bit(ulp_num, &phba->fw_config.ulp_supported);
426
427                         /* Get the CID, ICD and Chain count for each ULP */
428                         phba->fw_config.iscsi_cid_start[ulp_num] =
429                                 pfw_cfg->ulp[ulp_num].sq_base;
430                         phba->fw_config.iscsi_cid_count[ulp_num] =
431                                 pfw_cfg->ulp[ulp_num].sq_count;
432
433                         phba->fw_config.iscsi_icd_start[ulp_num] =
434                                 pfw_cfg->ulp[ulp_num].icd_base;
435                         phba->fw_config.iscsi_icd_count[ulp_num] =
436                                 pfw_cfg->ulp[ulp_num].icd_count;
437
438                         phba->fw_config.iscsi_chain_start[ulp_num] =
439                                 pfw_cfg->chain_icd[ulp_num].chain_base;
440                         phba->fw_config.iscsi_chain_count[ulp_num] =
441                                 pfw_cfg->chain_icd[ulp_num].chain_count;
442
443                         beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_INIT,
444                                     "BG_%d : Function loaded on ULP : %d\n"
445                                     "\tiscsi_cid_count : %d\n"
446                                     "\tiscsi_cid_start : %d\n"
447                                     "\t iscsi_icd_count : %d\n"
448                                     "\t iscsi_icd_start : %d\n",
449                                     ulp_num,
450                                     phba->fw_config.
451                                     iscsi_cid_count[ulp_num],
452                                     phba->fw_config.
453                                     iscsi_cid_start[ulp_num],
454                                     phba->fw_config.
455                                     iscsi_icd_count[ulp_num],
456                                     phba->fw_config.
457                                     iscsi_icd_start[ulp_num]);
458                 }
459         }
460
461         if (phba->fw_config.ulp_supported == 0) {
462                 beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT,
463                             "BG_%d : iSCSI initiator mode not set: ULP0 %x ULP1 %x\n",
464                             pfw_cfg->ulp[BEISCSI_ULP0].ulp_mode,
465                             pfw_cfg->ulp[BEISCSI_ULP1].ulp_mode);
466                 goto fail_init;
467         }
468
469         /**
470          * ICD is shared among ULPs. Use icd_count of any one loaded ULP
471          **/
472         for (ulp_num = 0; ulp_num < BEISCSI_ULP_COUNT; ulp_num++)
473                 if (test_bit(ulp_num, &phba->fw_config.ulp_supported))
474                         break;
475         icd_count = phba->fw_config.iscsi_icd_count[ulp_num];
476         if (icd_count == 0 || icd_count > 65536) {
477                 beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT,
478                             "BG_%d: invalid ICD count %d\n", icd_count);
479                 goto fail_init;
480         }
481
482         cid_count = BEISCSI_GET_CID_COUNT(phba, BEISCSI_ULP0) +
483                     BEISCSI_GET_CID_COUNT(phba, BEISCSI_ULP1);
484         if (cid_count == 0 || cid_count > 4096) {
485                 beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT,
486                             "BG_%d: invalid CID count %d\n", cid_count);
487                 goto fail_init;
488         }
489
490         /**
491          * Check FW is dual ULP aware i.e. can handle either
492          * of the protocols.
493          */
494         phba->fw_config.dual_ulp_aware = (pfw_cfg->function_mode &
495                                           BEISCSI_FUNC_DUA_MODE);
496
497         beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_INIT,
498                     "BG_%d : DUA Mode : 0x%x\n",
499                     phba->fw_config.dual_ulp_aware);
500
501         /* all set, continue using this FW config */
502         status = 0;
503 fail_init:
504         mutex_unlock(&ctrl->mbox_lock);
505         return status;
506 }
507
508 int mgmt_check_supported_fw(struct be_ctrl_info *ctrl,
509                                       struct beiscsi_hba *phba)
510 {
511         struct be_dma_mem nonemb_cmd;
512         struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem);
513         struct be_mgmt_controller_attributes *req;
514         struct be_sge *sge = nonembedded_sgl(wrb);
515         int status = 0;
516
517         nonemb_cmd.va = pci_alloc_consistent(ctrl->pdev,
518                                 sizeof(struct be_mgmt_controller_attributes),
519                                 &nonemb_cmd.dma);
520         if (nonemb_cmd.va == NULL) {
521                 beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT,
522                             "BG_%d : Failed to allocate memory for "
523                             "mgmt_check_supported_fw\n");
524                 return -ENOMEM;
525         }
526         nonemb_cmd.size = sizeof(struct be_mgmt_controller_attributes);
527         req = nonemb_cmd.va;
528         memset(req, 0, sizeof(*req));
529         mutex_lock(&ctrl->mbox_lock);
530         memset(wrb, 0, sizeof(*wrb));
531         be_wrb_hdr_prepare(wrb, sizeof(*req), false, 1);
532         be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
533                            OPCODE_COMMON_GET_CNTL_ATTRIBUTES, sizeof(*req));
534         sge->pa_hi = cpu_to_le32(upper_32_bits(nonemb_cmd.dma));
535         sge->pa_lo = cpu_to_le32(nonemb_cmd.dma & 0xFFFFFFFF);
536         sge->len = cpu_to_le32(nonemb_cmd.size);
537         status = be_mbox_notify(ctrl);
538         if (!status) {
539                 struct be_mgmt_controller_attributes_resp *resp = nonemb_cmd.va;
540                 beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_INIT,
541                             "BG_%d : Firmware Version of CMD : %s\n"
542                             "Firmware Version is : %s\n"
543                             "Developer Build, not performing version check...\n",
544                             resp->params.hba_attribs
545                             .flashrom_version_string,
546                             resp->params.hba_attribs.
547                             firmware_version_string);
548
549                 phba->fw_config.iscsi_features =
550                                 resp->params.hba_attribs.iscsi_features;
551                 beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_INIT,
552                             "BM_%d : phba->fw_config.iscsi_features = %d\n",
553                             phba->fw_config.iscsi_features);
554                 memcpy(phba->fw_ver_str, resp->params.hba_attribs.
555                        firmware_version_string, BEISCSI_VER_STRLEN);
556         } else
557                 beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT,
558                             "BG_%d :  Failed in mgmt_check_supported_fw\n");
559         mutex_unlock(&ctrl->mbox_lock);
560         if (nonemb_cmd.va)
561                 pci_free_consistent(ctrl->pdev, nonemb_cmd.size,
562                                     nonemb_cmd.va, nonemb_cmd.dma);
563
564         return status;
565 }
566
567 unsigned int mgmt_vendor_specific_fw_cmd(struct be_ctrl_info *ctrl,
568                                          struct beiscsi_hba *phba,
569                                          struct bsg_job *job,
570                                          struct be_dma_mem *nonemb_cmd)
571 {
572         struct be_cmd_resp_hdr *resp;
573         struct be_mcc_wrb *wrb;
574         struct be_sge *mcc_sge;
575         unsigned int tag = 0;
576         struct iscsi_bsg_request *bsg_req = job->request;
577         struct be_bsg_vendor_cmd *req = nonemb_cmd->va;
578         unsigned short region, sector_size, sector, offset;
579
580         nonemb_cmd->size = job->request_payload.payload_len;
581         memset(nonemb_cmd->va, 0, nonemb_cmd->size);
582         resp = nonemb_cmd->va;
583         region =  bsg_req->rqst_data.h_vendor.vendor_cmd[1];
584         sector_size =  bsg_req->rqst_data.h_vendor.vendor_cmd[2];
585         sector =  bsg_req->rqst_data.h_vendor.vendor_cmd[3];
586         offset =  bsg_req->rqst_data.h_vendor.vendor_cmd[4];
587         req->region = region;
588         req->sector = sector;
589         req->offset = offset;
590
591         if (mutex_lock_interruptible(&ctrl->mbox_lock))
592                 return 0;
593         switch (bsg_req->rqst_data.h_vendor.vendor_cmd[0]) {
594         case BEISCSI_WRITE_FLASH:
595                 offset = sector * sector_size + offset;
596                 be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI,
597                                    OPCODE_COMMON_WRITE_FLASH, sizeof(*req));
598                 sg_copy_to_buffer(job->request_payload.sg_list,
599                                   job->request_payload.sg_cnt,
600                                   nonemb_cmd->va + offset, job->request_len);
601                 break;
602         case BEISCSI_READ_FLASH:
603                 be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI,
604                            OPCODE_COMMON_READ_FLASH, sizeof(*req));
605                 break;
606         default:
607                 beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG,
608                             "BG_%d : Unsupported cmd = 0x%x\n\n",
609                             bsg_req->rqst_data.h_vendor.vendor_cmd[0]);
610
611                 mutex_unlock(&ctrl->mbox_lock);
612                 return -ENOSYS;
613         }
614
615         wrb = alloc_mcc_wrb(phba, &tag);
616         if (!wrb) {
617                 mutex_unlock(&ctrl->mbox_lock);
618                 return 0;
619         }
620
621         mcc_sge = nonembedded_sgl(wrb);
622         be_wrb_hdr_prepare(wrb, nonemb_cmd->size, false,
623                            job->request_payload.sg_cnt);
624         mcc_sge->pa_hi = cpu_to_le32(upper_32_bits(nonemb_cmd->dma));
625         mcc_sge->pa_lo = cpu_to_le32(nonemb_cmd->dma & 0xFFFFFFFF);
626         mcc_sge->len = cpu_to_le32(nonemb_cmd->size);
627
628         be_mcc_notify(phba, tag);
629
630         mutex_unlock(&ctrl->mbox_lock);
631         return tag;
632 }
633
634 /**
635  * mgmt_epfw_cleanup()- Inform FW to cleanup data structures.
636  * @phba: pointer to dev priv structure
637  * @ulp_num: ULP number.
638  *
639  * return
640  *      Success: 0
641  *      Failure: Non-Zero Value
642  **/
643 int mgmt_epfw_cleanup(struct beiscsi_hba *phba, unsigned short ulp_num)
644 {
645         struct be_ctrl_info *ctrl = &phba->ctrl;
646         struct be_mcc_wrb *wrb;
647         struct iscsi_cleanup_req *req;
648         unsigned int tag;
649         int status;
650
651         mutex_lock(&ctrl->mbox_lock);
652         wrb = alloc_mcc_wrb(phba, &tag);
653         if (!wrb) {
654                 mutex_unlock(&ctrl->mbox_lock);
655                 return -EBUSY;
656         }
657
658         req = embedded_payload(wrb);
659         be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
660         be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI,
661                            OPCODE_COMMON_ISCSI_CLEANUP, sizeof(*req));
662
663         req->chute = (1 << ulp_num);
664         req->hdr_ring_id = cpu_to_le16(HWI_GET_DEF_HDRQ_ID(phba, ulp_num));
665         req->data_ring_id = cpu_to_le16(HWI_GET_DEF_BUFQ_ID(phba, ulp_num));
666
667         be_mcc_notify(phba, tag);
668         status = be_mcc_compl_poll(phba, tag);
669         if (status)
670                 beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_INIT,
671                             "BG_%d : mgmt_epfw_cleanup , FAILED\n");
672         mutex_unlock(&ctrl->mbox_lock);
673         return status;
674 }
675
676 unsigned int  mgmt_invalidate_icds(struct beiscsi_hba *phba,
677                                 struct invalidate_command_table *inv_tbl,
678                                 unsigned int num_invalidate, unsigned int cid,
679                                 struct be_dma_mem *nonemb_cmd)
680
681 {
682         struct be_ctrl_info *ctrl = &phba->ctrl;
683         struct be_mcc_wrb *wrb;
684         struct be_sge *sge;
685         struct invalidate_commands_params_in *req;
686         unsigned int i, tag;
687
688         mutex_lock(&ctrl->mbox_lock);
689         wrb = alloc_mcc_wrb(phba, &tag);
690         if (!wrb) {
691                 mutex_unlock(&ctrl->mbox_lock);
692                 return 0;
693         }
694
695         req = nonemb_cmd->va;
696         memset(req, 0, sizeof(*req));
697         sge = nonembedded_sgl(wrb);
698
699         be_wrb_hdr_prepare(wrb, sizeof(*req), false, 1);
700         be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI,
701                         OPCODE_COMMON_ISCSI_ERROR_RECOVERY_INVALIDATE_COMMANDS,
702                         sizeof(*req));
703         req->ref_handle = 0;
704         req->cleanup_type = CMD_ISCSI_COMMAND_INVALIDATE;
705         for (i = 0; i < num_invalidate; i++) {
706                 req->table[i].icd = inv_tbl->icd;
707                 req->table[i].cid = inv_tbl->cid;
708                 req->icd_count++;
709                 inv_tbl++;
710         }
711         sge->pa_hi = cpu_to_le32(upper_32_bits(nonemb_cmd->dma));
712         sge->pa_lo = cpu_to_le32(nonemb_cmd->dma & 0xFFFFFFFF);
713         sge->len = cpu_to_le32(nonemb_cmd->size);
714
715         be_mcc_notify(phba, tag);
716         mutex_unlock(&ctrl->mbox_lock);
717         return tag;
718 }
719
720 unsigned int mgmt_invalidate_connection(struct beiscsi_hba *phba,
721                                          struct beiscsi_endpoint *beiscsi_ep,
722                                          unsigned short cid,
723                                          unsigned short issue_reset,
724                                          unsigned short savecfg_flag)
725 {
726         struct be_ctrl_info *ctrl = &phba->ctrl;
727         struct be_mcc_wrb *wrb;
728         struct iscsi_invalidate_connection_params_in *req;
729         unsigned int tag = 0;
730
731         mutex_lock(&ctrl->mbox_lock);
732         wrb = alloc_mcc_wrb(phba, &tag);
733         if (!wrb) {
734                 mutex_unlock(&ctrl->mbox_lock);
735                 return 0;
736         }
737
738         req = embedded_payload(wrb);
739         be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
740         be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI_INI,
741                            OPCODE_ISCSI_INI_DRIVER_INVALIDATE_CONNECTION,
742                            sizeof(*req));
743         req->session_handle = beiscsi_ep->fw_handle;
744         req->cid = cid;
745         if (issue_reset)
746                 req->cleanup_type = CMD_ISCSI_CONNECTION_ISSUE_TCP_RST;
747         else
748                 req->cleanup_type = CMD_ISCSI_CONNECTION_INVALIDATE;
749         req->save_cfg = savecfg_flag;
750         be_mcc_notify(phba, tag);
751         mutex_unlock(&ctrl->mbox_lock);
752         return tag;
753 }
754
755 unsigned int mgmt_upload_connection(struct beiscsi_hba *phba,
756                                 unsigned short cid, unsigned int upload_flag)
757 {
758         struct be_ctrl_info *ctrl = &phba->ctrl;
759         struct be_mcc_wrb *wrb;
760         struct tcp_upload_params_in *req;
761         unsigned int tag;
762
763         mutex_lock(&ctrl->mbox_lock);
764         wrb = alloc_mcc_wrb(phba, &tag);
765         if (!wrb) {
766                 mutex_unlock(&ctrl->mbox_lock);
767                 return 0;
768         }
769
770         req = embedded_payload(wrb);
771         be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
772         be_cmd_hdr_prepare(&req->hdr, CMD_COMMON_TCP_UPLOAD,
773                            OPCODE_COMMON_TCP_UPLOAD, sizeof(*req));
774         req->id = (unsigned short)cid;
775         req->upload_type = (unsigned char)upload_flag;
776         be_mcc_notify(phba, tag);
777         mutex_unlock(&ctrl->mbox_lock);
778         return tag;
779 }
780
781 /**
782  * mgmt_open_connection()- Establish a TCP CXN
783  * @dst_addr: Destination Address
784  * @beiscsi_ep: ptr to device endpoint struct
785  * @nonemb_cmd: ptr to memory allocated for command
786  *
787  * return
788  *      Success: Tag number of the MBX Command issued
789  *      Failure: Error code
790  **/
791 int mgmt_open_connection(struct beiscsi_hba *phba,
792                          struct sockaddr *dst_addr,
793                          struct beiscsi_endpoint *beiscsi_ep,
794                          struct be_dma_mem *nonemb_cmd)
795 {
796         struct hwi_controller *phwi_ctrlr;
797         struct hwi_context_memory *phwi_context;
798         struct sockaddr_in *daddr_in = (struct sockaddr_in *)dst_addr;
799         struct sockaddr_in6 *daddr_in6 = (struct sockaddr_in6 *)dst_addr;
800         struct be_ctrl_info *ctrl = &phba->ctrl;
801         struct be_mcc_wrb *wrb;
802         struct tcp_connect_and_offload_in_v1 *req;
803         unsigned short def_hdr_id;
804         unsigned short def_data_id;
805         struct phys_addr template_address = { 0, 0 };
806         struct phys_addr *ptemplate_address;
807         unsigned int tag = 0;
808         unsigned int i, ulp_num;
809         unsigned short cid = beiscsi_ep->ep_cid;
810         struct be_sge *sge;
811
812         if (dst_addr->sa_family != PF_INET && dst_addr->sa_family != PF_INET6) {
813                 beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG,
814                             "BG_%d : unknown addr family %d\n",
815                             dst_addr->sa_family);
816                 return -EINVAL;
817         }
818
819         phwi_ctrlr = phba->phwi_ctrlr;
820         phwi_context = phwi_ctrlr->phwi_ctxt;
821
822         ulp_num = phwi_ctrlr->wrb_context[BE_GET_CRI_FROM_CID(cid)].ulp_num;
823
824         def_hdr_id = (unsigned short)HWI_GET_DEF_HDRQ_ID(phba, ulp_num);
825         def_data_id = (unsigned short)HWI_GET_DEF_BUFQ_ID(phba, ulp_num);
826
827         ptemplate_address = &template_address;
828         ISCSI_GET_PDU_TEMPLATE_ADDRESS(phba, ptemplate_address);
829         if (mutex_lock_interruptible(&ctrl->mbox_lock))
830                 return 0;
831         wrb = alloc_mcc_wrb(phba, &tag);
832         if (!wrb) {
833                 mutex_unlock(&ctrl->mbox_lock);
834                 return 0;
835         }
836
837         sge = nonembedded_sgl(wrb);
838         req = nonemb_cmd->va;
839         memset(req, 0, sizeof(*req));
840
841         be_wrb_hdr_prepare(wrb, nonemb_cmd->size, false, 1);
842         be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI,
843                            OPCODE_COMMON_ISCSI_TCP_CONNECT_AND_OFFLOAD,
844                            nonemb_cmd->size);
845         if (dst_addr->sa_family == PF_INET) {
846                 __be32 s_addr = daddr_in->sin_addr.s_addr;
847                 req->ip_address.ip_type = BE2_IPV4;
848                 req->ip_address.addr[0] = s_addr & 0x000000ff;
849                 req->ip_address.addr[1] = (s_addr & 0x0000ff00) >> 8;
850                 req->ip_address.addr[2] = (s_addr & 0x00ff0000) >> 16;
851                 req->ip_address.addr[3] = (s_addr & 0xff000000) >> 24;
852                 req->tcp_port = ntohs(daddr_in->sin_port);
853                 beiscsi_ep->dst_addr = daddr_in->sin_addr.s_addr;
854                 beiscsi_ep->dst_tcpport = ntohs(daddr_in->sin_port);
855                 beiscsi_ep->ip_type = BE2_IPV4;
856         } else {
857                 /* else its PF_INET6 family */
858                 req->ip_address.ip_type = BE2_IPV6;
859                 memcpy(&req->ip_address.addr,
860                        &daddr_in6->sin6_addr.in6_u.u6_addr8, 16);
861                 req->tcp_port = ntohs(daddr_in6->sin6_port);
862                 beiscsi_ep->dst_tcpport = ntohs(daddr_in6->sin6_port);
863                 memcpy(&beiscsi_ep->dst6_addr,
864                        &daddr_in6->sin6_addr.in6_u.u6_addr8, 16);
865                 beiscsi_ep->ip_type = BE2_IPV6;
866         }
867         req->cid = cid;
868         i = phba->nxt_cqid++;
869         if (phba->nxt_cqid == phba->num_cpus)
870                 phba->nxt_cqid = 0;
871         req->cq_id = phwi_context->be_cq[i].id;
872         beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG,
873                     "BG_%d : i=%d cq_id=%d\n", i, req->cq_id);
874         req->defq_id = def_hdr_id;
875         req->hdr_ring_id = def_hdr_id;
876         req->data_ring_id = def_data_id;
877         req->do_offload = 1;
878         req->dataout_template_pa.lo = ptemplate_address->lo;
879         req->dataout_template_pa.hi = ptemplate_address->hi;
880         sge->pa_hi = cpu_to_le32(upper_32_bits(nonemb_cmd->dma));
881         sge->pa_lo = cpu_to_le32(nonemb_cmd->dma & 0xFFFFFFFF);
882         sge->len = cpu_to_le32(nonemb_cmd->size);
883
884         if (!is_chip_be2_be3r(phba)) {
885                 req->hdr.version = MBX_CMD_VER1;
886                 req->tcp_window_size = 0;
887                 req->tcp_window_scale_count = 2;
888         }
889
890         be_mcc_notify(phba, tag);
891         mutex_unlock(&ctrl->mbox_lock);
892         return tag;
893 }
894
895 unsigned int mgmt_get_all_if_id(struct beiscsi_hba *phba)
896 {
897         struct be_ctrl_info *ctrl = &phba->ctrl;
898         struct be_mcc_wrb *wrb;
899         struct be_cmd_get_all_if_id_req *req;
900         struct be_cmd_get_all_if_id_req *pbe_allid;
901         unsigned int tag;
902         int status = 0;
903
904         if (mutex_lock_interruptible(&ctrl->mbox_lock))
905                 return -EINTR;
906         wrb = alloc_mcc_wrb(phba, &tag);
907         if (!wrb) {
908                 mutex_unlock(&ctrl->mbox_lock);
909                 return -ENOMEM;
910         }
911
912         req = embedded_payload(wrb);
913         be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
914         be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI,
915                            OPCODE_COMMON_ISCSI_NTWK_GET_ALL_IF_ID,
916                            sizeof(*req));
917         be_mcc_notify(phba, tag);
918         mutex_unlock(&ctrl->mbox_lock);
919
920         status = beiscsi_mccq_compl_wait(phba, tag, &wrb, NULL);
921         if (status) {
922                 beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG,
923                             "BG_%d : Failed in mgmt_get_all_if_id\n");
924                 return -EBUSY;
925         }
926
927         pbe_allid = embedded_payload(wrb);
928         phba->interface_handle = pbe_allid->if_hndl_list[0];
929
930         return status;
931 }
932
933 /*
934  * mgmt_exec_nonemb_cmd()- Execute Non Embedded MBX Cmd
935  * @phba: Driver priv structure
936  * @nonemb_cmd: Address of the MBX command issued
937  * @resp_buf: Buffer to copy the MBX cmd response
938  * @resp_buf_len: respone lenght to be copied
939  *
940  **/
941 static int mgmt_exec_nonemb_cmd(struct beiscsi_hba *phba,
942                                 struct be_dma_mem *nonemb_cmd, void *resp_buf,
943                                 int resp_buf_len)
944 {
945         struct be_ctrl_info *ctrl = &phba->ctrl;
946         struct be_mcc_wrb *wrb;
947         struct be_sge *sge;
948         unsigned int tag;
949         int rc = 0;
950
951         mutex_lock(&ctrl->mbox_lock);
952         wrb = alloc_mcc_wrb(phba, &tag);
953         if (!wrb) {
954                 mutex_unlock(&ctrl->mbox_lock);
955                 rc = -ENOMEM;
956                 goto free_cmd;
957         }
958
959         sge = nonembedded_sgl(wrb);
960         be_wrb_hdr_prepare(wrb, nonemb_cmd->size, false, 1);
961         sge->pa_hi = cpu_to_le32(upper_32_bits(nonemb_cmd->dma));
962         sge->pa_lo = cpu_to_le32(lower_32_bits(nonemb_cmd->dma));
963         sge->len = cpu_to_le32(nonemb_cmd->size);
964
965         be_mcc_notify(phba, tag);
966         mutex_unlock(&ctrl->mbox_lock);
967
968         rc = beiscsi_mccq_compl_wait(phba, tag, NULL, nonemb_cmd);
969
970         if (resp_buf)
971                 memcpy(resp_buf, nonemb_cmd->va, resp_buf_len);
972
973         if (rc) {
974                 /* Check if the MBX Cmd needs to be re-issued */
975                 if (rc == -EAGAIN)
976                         return rc;
977
978                 beiscsi_log(phba, KERN_WARNING,
979                             BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX,
980                             "BG_%d : mgmt_exec_nonemb_cmd Failed status\n");
981
982                 if (rc != -EBUSY)
983                         goto free_cmd;
984                 else
985                         return rc;
986         }
987 free_cmd:
988         pci_free_consistent(ctrl->pdev, nonemb_cmd->size,
989                             nonemb_cmd->va, nonemb_cmd->dma);
990         return rc;
991 }
992
993 static int mgmt_alloc_cmd_data(struct beiscsi_hba *phba, struct be_dma_mem *cmd,
994                                int iscsi_cmd, int size)
995 {
996         cmd->va = pci_zalloc_consistent(phba->ctrl.pdev, size, &cmd->dma);
997         if (!cmd->va) {
998                 beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG,
999                             "BG_%d : Failed to allocate memory for if info\n");
1000                 return -ENOMEM;
1001         }
1002         cmd->size = size;
1003         be_cmd_hdr_prepare(cmd->va, CMD_SUBSYSTEM_ISCSI, iscsi_cmd, size);
1004         return 0;
1005 }
1006
1007 static int
1008 mgmt_static_ip_modify(struct beiscsi_hba *phba,
1009                       struct be_cmd_get_if_info_resp *if_info,
1010                       struct iscsi_iface_param_info *ip_param,
1011                       struct iscsi_iface_param_info *subnet_param,
1012                       uint32_t ip_action)
1013 {
1014         struct be_cmd_set_ip_addr_req *req;
1015         struct be_dma_mem nonemb_cmd;
1016         uint32_t ip_type;
1017         int rc;
1018
1019         rc = mgmt_alloc_cmd_data(phba, &nonemb_cmd,
1020                                  OPCODE_COMMON_ISCSI_NTWK_MODIFY_IP_ADDR,
1021                                  sizeof(*req));
1022         if (rc)
1023                 return rc;
1024
1025         ip_type = (ip_param->param == ISCSI_NET_PARAM_IPV6_ADDR) ?
1026                 BE2_IPV6 : BE2_IPV4 ;
1027
1028         req = nonemb_cmd.va;
1029         req->ip_params.record_entry_count = 1;
1030         req->ip_params.ip_record.action = ip_action;
1031         req->ip_params.ip_record.interface_hndl =
1032                 phba->interface_handle;
1033         req->ip_params.ip_record.ip_addr.size_of_structure =
1034                 sizeof(struct be_ip_addr_subnet_format);
1035         req->ip_params.ip_record.ip_addr.ip_type = ip_type;
1036
1037         if (ip_action == IP_ACTION_ADD) {
1038                 memcpy(req->ip_params.ip_record.ip_addr.addr, ip_param->value,
1039                        sizeof(req->ip_params.ip_record.ip_addr.addr));
1040
1041                 if (subnet_param)
1042                         memcpy(req->ip_params.ip_record.ip_addr.subnet_mask,
1043                                subnet_param->value,
1044                                sizeof(req->ip_params.ip_record.ip_addr.subnet_mask));
1045         } else {
1046                 memcpy(req->ip_params.ip_record.ip_addr.addr,
1047                        if_info->ip_addr.addr,
1048                        sizeof(req->ip_params.ip_record.ip_addr.addr));
1049
1050                 memcpy(req->ip_params.ip_record.ip_addr.subnet_mask,
1051                        if_info->ip_addr.subnet_mask,
1052                        sizeof(req->ip_params.ip_record.ip_addr.subnet_mask));
1053         }
1054
1055         rc = mgmt_exec_nonemb_cmd(phba, &nonemb_cmd, NULL, 0);
1056         if (rc < 0)
1057                 beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG,
1058                             "BG_%d : Failed to Modify existing IP Address\n");
1059         return rc;
1060 }
1061
1062 static int mgmt_modify_gateway(struct beiscsi_hba *phba, uint8_t *gt_addr,
1063                                uint32_t gtway_action, uint32_t param_len)
1064 {
1065         struct be_cmd_set_def_gateway_req *req;
1066         struct be_dma_mem nonemb_cmd;
1067         int rt_val;
1068
1069
1070         rt_val = mgmt_alloc_cmd_data(phba, &nonemb_cmd,
1071                                 OPCODE_COMMON_ISCSI_NTWK_MODIFY_DEFAULT_GATEWAY,
1072                                 sizeof(*req));
1073         if (rt_val)
1074                 return rt_val;
1075
1076         req = nonemb_cmd.va;
1077         req->action = gtway_action;
1078         req->ip_addr.ip_type = BE2_IPV4;
1079
1080         memcpy(req->ip_addr.addr, gt_addr, sizeof(req->ip_addr.addr));
1081
1082         return mgmt_exec_nonemb_cmd(phba, &nonemb_cmd, NULL, 0);
1083 }
1084
1085 int mgmt_set_ip(struct beiscsi_hba *phba,
1086                 struct iscsi_iface_param_info *ip_param,
1087                 struct iscsi_iface_param_info *subnet_param,
1088                 uint32_t boot_proto)
1089 {
1090         struct be_cmd_get_def_gateway_resp gtway_addr_set;
1091         struct be_cmd_get_if_info_resp *if_info;
1092         struct be_cmd_set_dhcp_req *dhcpreq;
1093         struct be_cmd_rel_dhcp_req *reldhcp;
1094         struct be_dma_mem nonemb_cmd;
1095         uint8_t *gtway_addr;
1096         uint32_t ip_type;
1097         int rc;
1098
1099         rc = mgmt_get_all_if_id(phba);
1100         if (rc)
1101                 return rc;
1102
1103         ip_type = (ip_param->param == ISCSI_NET_PARAM_IPV6_ADDR) ?
1104                 BE2_IPV6 : BE2_IPV4 ;
1105
1106         rc = mgmt_get_if_info(phba, ip_type, &if_info);
1107         if (rc)
1108                 return rc;
1109
1110         if (boot_proto == ISCSI_BOOTPROTO_DHCP) {
1111                 if (if_info->dhcp_state) {
1112                         beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG,
1113                                     "BG_%d : DHCP Already Enabled\n");
1114                         goto exit;
1115                 }
1116                 /* The ip_param->len is 1 in DHCP case. Setting
1117                    proper IP len as this it is used while
1118                    freeing the Static IP.
1119                  */
1120                 ip_param->len = (ip_param->param == ISCSI_NET_PARAM_IPV6_ADDR) ?
1121                                 IP_V6_LEN : IP_V4_LEN;
1122
1123         } else {
1124                 if (if_info->dhcp_state) {
1125
1126                         memset(if_info, 0, sizeof(*if_info));
1127                         rc = mgmt_alloc_cmd_data(phba, &nonemb_cmd,
1128                                 OPCODE_COMMON_ISCSI_NTWK_REL_STATELESS_IP_ADDR,
1129                                 sizeof(*reldhcp));
1130
1131                         if (rc)
1132                                 goto exit;
1133
1134                         reldhcp = nonemb_cmd.va;
1135                         reldhcp->interface_hndl = phba->interface_handle;
1136                         reldhcp->ip_type = ip_type;
1137
1138                         rc = mgmt_exec_nonemb_cmd(phba, &nonemb_cmd, NULL, 0);
1139                         if (rc < 0) {
1140                                 beiscsi_log(phba, KERN_WARNING,
1141                                             BEISCSI_LOG_CONFIG,
1142                                             "BG_%d : Failed to Delete existing dhcp\n");
1143                                 goto exit;
1144                         }
1145                 }
1146         }
1147
1148         /* Delete the Static IP Set */
1149         if (if_info->ip_addr.addr[0]) {
1150                 rc = mgmt_static_ip_modify(phba, if_info, ip_param, NULL,
1151                                            IP_ACTION_DEL);
1152                 if (rc)
1153                         goto exit;
1154         }
1155
1156         /* Delete the Gateway settings if mode change is to DHCP */
1157         if (boot_proto == ISCSI_BOOTPROTO_DHCP) {
1158                 memset(&gtway_addr_set, 0, sizeof(gtway_addr_set));
1159                 rc = mgmt_get_gateway(phba, BE2_IPV4, &gtway_addr_set);
1160                 if (rc) {
1161                         beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG,
1162                                     "BG_%d : Failed to Get Gateway Addr\n");
1163                         goto exit;
1164                 }
1165
1166                 if (gtway_addr_set.ip_addr.addr[0]) {
1167                         gtway_addr = (uint8_t *)&gtway_addr_set.ip_addr.addr;
1168                         rc = mgmt_modify_gateway(phba, gtway_addr,
1169                                                  IP_ACTION_DEL, IP_V4_LEN);
1170
1171                         if (rc) {
1172                                 beiscsi_log(phba, KERN_WARNING,
1173                                             BEISCSI_LOG_CONFIG,
1174                                             "BG_%d : Failed to clear Gateway Addr Set\n");
1175                                 goto exit;
1176                         }
1177                 }
1178         }
1179
1180         /* Set Adapter to DHCP/Static Mode */
1181         if (boot_proto == ISCSI_BOOTPROTO_DHCP) {
1182                 rc = mgmt_alloc_cmd_data(phba, &nonemb_cmd,
1183                         OPCODE_COMMON_ISCSI_NTWK_CONFIG_STATELESS_IP_ADDR,
1184                         sizeof(*dhcpreq));
1185                 if (rc)
1186                         goto exit;
1187
1188                 dhcpreq = nonemb_cmd.va;
1189                 dhcpreq->flags = BLOCKING;
1190                 dhcpreq->retry_count = 1;
1191                 dhcpreq->interface_hndl = phba->interface_handle;
1192                 dhcpreq->ip_type = BE2_DHCP_V4;
1193
1194                 rc = mgmt_exec_nonemb_cmd(phba, &nonemb_cmd, NULL, 0);
1195         } else {
1196                 rc = mgmt_static_ip_modify(phba, if_info, ip_param,
1197                                              subnet_param, IP_ACTION_ADD);
1198         }
1199
1200 exit:
1201         kfree(if_info);
1202         return rc;
1203 }
1204
1205 int mgmt_set_gateway(struct beiscsi_hba *phba,
1206                      struct iscsi_iface_param_info *gateway_param)
1207 {
1208         struct be_cmd_get_def_gateway_resp gtway_addr_set;
1209         uint8_t *gtway_addr;
1210         int rt_val;
1211
1212         memset(&gtway_addr_set, 0, sizeof(gtway_addr_set));
1213         rt_val = mgmt_get_gateway(phba, BE2_IPV4, &gtway_addr_set);
1214         if (rt_val) {
1215                 beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG,
1216                             "BG_%d : Failed to Get Gateway Addr\n");
1217                 return rt_val;
1218         }
1219
1220         if (gtway_addr_set.ip_addr.addr[0]) {
1221                 gtway_addr = (uint8_t *)&gtway_addr_set.ip_addr.addr;
1222                 rt_val = mgmt_modify_gateway(phba, gtway_addr, IP_ACTION_DEL,
1223                                              gateway_param->len);
1224                 if (rt_val) {
1225                         beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG,
1226                                     "BG_%d : Failed to clear Gateway Addr Set\n");
1227                         return rt_val;
1228                 }
1229         }
1230
1231         gtway_addr = (uint8_t *)&gateway_param->value;
1232         rt_val = mgmt_modify_gateway(phba, gtway_addr, IP_ACTION_ADD,
1233                                      gateway_param->len);
1234
1235         if (rt_val)
1236                 beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG,
1237                             "BG_%d : Failed to Set Gateway Addr\n");
1238
1239         return rt_val;
1240 }
1241
1242 int mgmt_get_gateway(struct beiscsi_hba *phba, int ip_type,
1243                      struct be_cmd_get_def_gateway_resp *gateway)
1244 {
1245         struct be_cmd_get_def_gateway_req *req;
1246         struct be_dma_mem nonemb_cmd;
1247         int rc;
1248
1249         rc = mgmt_alloc_cmd_data(phba, &nonemb_cmd,
1250                                  OPCODE_COMMON_ISCSI_NTWK_GET_DEFAULT_GATEWAY,
1251                                  sizeof(*gateway));
1252         if (rc)
1253                 return rc;
1254
1255         req = nonemb_cmd.va;
1256         req->ip_type = ip_type;
1257
1258         return mgmt_exec_nonemb_cmd(phba, &nonemb_cmd, gateway,
1259                                     sizeof(*gateway));
1260 }
1261
1262 int mgmt_get_if_info(struct beiscsi_hba *phba, int ip_type,
1263                      struct be_cmd_get_if_info_resp **if_info)
1264 {
1265         struct be_cmd_get_if_info_req *req;
1266         struct be_dma_mem nonemb_cmd;
1267         uint32_t ioctl_size = sizeof(struct be_cmd_get_if_info_resp);
1268         int rc;
1269
1270         rc = mgmt_get_all_if_id(phba);
1271         if (rc)
1272                 return rc;
1273
1274         do {
1275                 rc = mgmt_alloc_cmd_data(phba, &nonemb_cmd,
1276                                          OPCODE_COMMON_ISCSI_NTWK_GET_IF_INFO,
1277                                          ioctl_size);
1278                 if (rc)
1279                         return rc;
1280
1281                 req = nonemb_cmd.va;
1282                 req->interface_hndl = phba->interface_handle;
1283                 req->ip_type = ip_type;
1284
1285                 /* Allocate memory for if_info */
1286                 *if_info = kzalloc(ioctl_size, GFP_KERNEL);
1287                 if (!*if_info) {
1288                         beiscsi_log(phba, KERN_ERR,
1289                                     BEISCSI_LOG_INIT | BEISCSI_LOG_CONFIG,
1290                                     "BG_%d : Memory Allocation Failure\n");
1291
1292                                 /* Free the DMA memory for the IOCTL issuing */
1293                                 pci_free_consistent(phba->ctrl.pdev,
1294                                                     nonemb_cmd.size,
1295                                                     nonemb_cmd.va,
1296                                                     nonemb_cmd.dma);
1297                                 return -ENOMEM;
1298                 }
1299
1300                 rc =  mgmt_exec_nonemb_cmd(phba, &nonemb_cmd, *if_info,
1301                                            ioctl_size);
1302
1303                 /* Check if the error is because of Insufficent_Buffer */
1304                 if (rc == -EAGAIN) {
1305
1306                         /* Get the new memory size */
1307                         ioctl_size = ((struct be_cmd_resp_hdr *)
1308                                       nonemb_cmd.va)->actual_resp_len;
1309                         ioctl_size += sizeof(struct be_cmd_req_hdr);
1310
1311                         /* Free the previous allocated DMA memory */
1312                         pci_free_consistent(phba->ctrl.pdev, nonemb_cmd.size,
1313                                             nonemb_cmd.va,
1314                                             nonemb_cmd.dma);
1315
1316                         /* Free the virtual memory */
1317                         kfree(*if_info);
1318                 } else
1319                         break;
1320         } while (true);
1321         return rc;
1322 }
1323
1324 int mgmt_get_nic_conf(struct beiscsi_hba *phba,
1325                       struct be_cmd_get_nic_conf_resp *nic)
1326 {
1327         struct be_dma_mem nonemb_cmd;
1328         int rc;
1329
1330         rc = mgmt_alloc_cmd_data(phba, &nonemb_cmd,
1331                                  OPCODE_COMMON_ISCSI_NTWK_GET_NIC_CONFIG,
1332                                  sizeof(*nic));
1333         if (rc)
1334                 return rc;
1335
1336         return mgmt_exec_nonemb_cmd(phba, &nonemb_cmd, nic, sizeof(*nic));
1337 }
1338
1339
1340
1341 unsigned int be_cmd_get_initname(struct beiscsi_hba *phba)
1342 {
1343         unsigned int tag;
1344         struct be_mcc_wrb *wrb;
1345         struct be_cmd_hba_name *req;
1346         struct be_ctrl_info *ctrl = &phba->ctrl;
1347
1348         if (mutex_lock_interruptible(&ctrl->mbox_lock))
1349                 return 0;
1350         wrb = alloc_mcc_wrb(phba, &tag);
1351         if (!wrb) {
1352                 mutex_unlock(&ctrl->mbox_lock);
1353                 return 0;
1354         }
1355
1356         req = embedded_payload(wrb);
1357         be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
1358         be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI_INI,
1359                         OPCODE_ISCSI_INI_CFG_GET_HBA_NAME,
1360                         sizeof(*req));
1361
1362         be_mcc_notify(phba, tag);
1363         mutex_unlock(&ctrl->mbox_lock);
1364         return tag;
1365 }
1366
1367 /**
1368  * be_mgmt_get_boot_shandle()- Get the session handle
1369  * @phba: device priv structure instance
1370  * @s_handle: session handle returned for boot session.
1371  *
1372  * Get the boot target session handle. In case of
1373  * crashdump mode driver has to issue and MBX Cmd
1374  * for FW to login to boot target
1375  *
1376  * return
1377  *      Success: 0
1378  *      Failure: Non-Zero value
1379  *
1380  **/
1381 int be_mgmt_get_boot_shandle(struct beiscsi_hba *phba,
1382                               unsigned int *s_handle)
1383 {
1384         struct be_cmd_get_boot_target_resp *boot_resp;
1385         struct be_mcc_wrb *wrb;
1386         unsigned int tag;
1387         uint8_t boot_retry = 3;
1388         int rc;
1389
1390         do {
1391                 /* Get the Boot Target Session Handle and Count*/
1392                 tag = mgmt_get_boot_target(phba);
1393                 if (!tag) {
1394                         beiscsi_log(phba, KERN_ERR,
1395                                     BEISCSI_LOG_CONFIG | BEISCSI_LOG_INIT,
1396                                     "BG_%d : Getting Boot Target Info Failed\n");
1397                         return -EAGAIN;
1398                 }
1399
1400                 rc = beiscsi_mccq_compl_wait(phba, tag, &wrb, NULL);
1401                 if (rc) {
1402                         beiscsi_log(phba, KERN_ERR,
1403                                     BEISCSI_LOG_INIT | BEISCSI_LOG_CONFIG,
1404                                     "BG_%d : MBX CMD get_boot_target Failed\n");
1405                         return -EBUSY;
1406                 }
1407
1408                 boot_resp = embedded_payload(wrb);
1409
1410                 /* Check if the there are any Boot targets configured */
1411                 if (!boot_resp->boot_session_count) {
1412                         beiscsi_log(phba, KERN_INFO,
1413                                     BEISCSI_LOG_INIT | BEISCSI_LOG_CONFIG,
1414                                     "BG_%d  ;No boot targets configured\n");
1415                         return -ENXIO;
1416                 }
1417
1418                 /* FW returns the session handle of the boot session */
1419                 if (boot_resp->boot_session_handle != INVALID_SESS_HANDLE) {
1420                         *s_handle = boot_resp->boot_session_handle;
1421                         return 0;
1422                 }
1423
1424                 /* Issue MBX Cmd to FW to login to the boot target */
1425                 tag = mgmt_reopen_session(phba, BE_REOPEN_BOOT_SESSIONS,
1426                                           INVALID_SESS_HANDLE);
1427                 if (!tag) {
1428                         beiscsi_log(phba, KERN_ERR,
1429                                     BEISCSI_LOG_INIT | BEISCSI_LOG_CONFIG,
1430                                     "BG_%d : mgmt_reopen_session Failed\n");
1431                         return -EAGAIN;
1432                 }
1433
1434                 rc = beiscsi_mccq_compl_wait(phba, tag, NULL, NULL);
1435                 if (rc) {
1436                         beiscsi_log(phba, KERN_ERR,
1437                                     BEISCSI_LOG_INIT | BEISCSI_LOG_CONFIG,
1438                                     "BG_%d : mgmt_reopen_session Failed");
1439                         return rc;
1440                 }
1441         } while (--boot_retry);
1442
1443         /* Couldn't log into the boot target */
1444         beiscsi_log(phba, KERN_ERR,
1445                     BEISCSI_LOG_INIT | BEISCSI_LOG_CONFIG,
1446                     "BG_%d : Login to Boot Target Failed\n");
1447         return -ENXIO;
1448 }
1449
1450 /**
1451  * mgmt_set_vlan()- Issue and wait for CMD completion
1452  * @phba: device private structure instance
1453  * @vlan_tag: VLAN tag
1454  *
1455  * Issue the MBX Cmd and wait for the completion of the
1456  * command.
1457  *
1458  * returns
1459  *      Success: 0
1460  *      Failure: Non-Xero Value
1461  **/
1462 int mgmt_set_vlan(struct beiscsi_hba *phba,
1463                    uint16_t vlan_tag)
1464 {
1465         int rc;
1466         unsigned int tag;
1467
1468         tag = be_cmd_set_vlan(phba, vlan_tag);
1469         if (!tag) {
1470                 beiscsi_log(phba, KERN_ERR,
1471                             (BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX),
1472                             "BG_%d : VLAN Setting Failed\n");
1473                 return -EBUSY;
1474         }
1475
1476         rc = beiscsi_mccq_compl_wait(phba, tag, NULL, NULL);
1477         if (rc) {
1478                 beiscsi_log(phba, KERN_ERR,
1479                             (BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX),
1480                             "BS_%d : VLAN MBX Cmd Failed\n");
1481                 return rc;
1482         }
1483         return rc;
1484 }
1485
1486 /**
1487  * beiscsi_drvr_ver_disp()- Display the driver Name and Version
1488  * @dev: ptr to device not used.
1489  * @attr: device attribute, not used.
1490  * @buf: contains formatted text driver name and version
1491  *
1492  * return
1493  * size of the formatted string
1494  **/
1495 ssize_t
1496 beiscsi_drvr_ver_disp(struct device *dev, struct device_attribute *attr,
1497                        char *buf)
1498 {
1499         return snprintf(buf, PAGE_SIZE, BE_NAME "\n");
1500 }
1501
1502 /**
1503  * beiscsi_fw_ver_disp()- Display Firmware Version
1504  * @dev: ptr to device not used.
1505  * @attr: device attribute, not used.
1506  * @buf: contains formatted text Firmware version
1507  *
1508  * return
1509  * size of the formatted string
1510  **/
1511 ssize_t
1512 beiscsi_fw_ver_disp(struct device *dev, struct device_attribute *attr,
1513                      char *buf)
1514 {
1515         struct Scsi_Host *shost = class_to_shost(dev);
1516         struct beiscsi_hba *phba = iscsi_host_priv(shost);
1517
1518         return snprintf(buf, PAGE_SIZE, "%s\n", phba->fw_ver_str);
1519 }
1520
1521 /**
1522  * beiscsi_active_session_disp()- Display Sessions Active
1523  * @dev: ptr to device not used.
1524  * @attr: device attribute, not used.
1525  * @buf: contains formatted text Session Count
1526  *
1527  * return
1528  * size of the formatted string
1529  **/
1530 ssize_t
1531 beiscsi_active_session_disp(struct device *dev, struct device_attribute *attr,
1532                          char *buf)
1533 {
1534         struct Scsi_Host *shost = class_to_shost(dev);
1535         struct beiscsi_hba *phba = iscsi_host_priv(shost);
1536         uint16_t avlbl_cids = 0, ulp_num, len = 0, total_cids = 0;
1537
1538         for (ulp_num = 0; ulp_num < BEISCSI_ULP_COUNT; ulp_num++) {
1539                 if (test_bit(ulp_num, (void *)&phba->fw_config.ulp_supported)) {
1540                         avlbl_cids = BEISCSI_ULP_AVLBL_CID(phba, ulp_num);
1541                         total_cids = BEISCSI_GET_CID_COUNT(phba, ulp_num);
1542                         len += snprintf(buf+len, PAGE_SIZE - len,
1543                                         "ULP%d : %d\n", ulp_num,
1544                                         (total_cids - avlbl_cids));
1545                 } else
1546                         len += snprintf(buf+len, PAGE_SIZE - len,
1547                                         "ULP%d : %d\n", ulp_num, 0);
1548         }
1549
1550         return len;
1551 }
1552
1553 /**
1554  * beiscsi_free_session_disp()- Display Avaliable Session
1555  * @dev: ptr to device not used.
1556  * @attr: device attribute, not used.
1557  * @buf: contains formatted text Session Count
1558  *
1559  * return
1560  * size of the formatted string
1561  **/
1562 ssize_t
1563 beiscsi_free_session_disp(struct device *dev, struct device_attribute *attr,
1564                        char *buf)
1565 {
1566         struct Scsi_Host *shost = class_to_shost(dev);
1567         struct beiscsi_hba *phba = iscsi_host_priv(shost);
1568         uint16_t ulp_num, len = 0;
1569
1570         for (ulp_num = 0; ulp_num < BEISCSI_ULP_COUNT; ulp_num++) {
1571                 if (test_bit(ulp_num, (void *)&phba->fw_config.ulp_supported))
1572                         len += snprintf(buf+len, PAGE_SIZE - len,
1573                                         "ULP%d : %d\n", ulp_num,
1574                                         BEISCSI_ULP_AVLBL_CID(phba, ulp_num));
1575                 else
1576                         len += snprintf(buf+len, PAGE_SIZE - len,
1577                                         "ULP%d : %d\n", ulp_num, 0);
1578         }
1579
1580         return len;
1581 }
1582
1583 /**
1584  * beiscsi_adap_family_disp()- Display adapter family.
1585  * @dev: ptr to device to get priv structure
1586  * @attr: device attribute, not used.
1587  * @buf: contains formatted text driver name and version
1588  *
1589  * return
1590  * size of the formatted string
1591  **/
1592 ssize_t
1593 beiscsi_adap_family_disp(struct device *dev, struct device_attribute *attr,
1594                           char *buf)
1595 {
1596         uint16_t dev_id = 0;
1597         struct Scsi_Host *shost = class_to_shost(dev);
1598         struct beiscsi_hba *phba = iscsi_host_priv(shost);
1599
1600         dev_id = phba->pcidev->device;
1601         switch (dev_id) {
1602         case BE_DEVICE_ID1:
1603         case OC_DEVICE_ID1:
1604         case OC_DEVICE_ID2:
1605                 return snprintf(buf, PAGE_SIZE, "BE2 Adapter Family\n");
1606                 break;
1607         case BE_DEVICE_ID2:
1608         case OC_DEVICE_ID3:
1609                 return snprintf(buf, PAGE_SIZE, "BE3-R Adapter Family\n");
1610                 break;
1611         case OC_SKH_ID1:
1612                 return snprintf(buf, PAGE_SIZE, "Skyhawk-R Adapter Family\n");
1613                 break;
1614         default:
1615                 return snprintf(buf, PAGE_SIZE,
1616                                 "Unknown Adapter Family: 0x%x\n", dev_id);
1617                 break;
1618         }
1619 }
1620
1621 /**
1622  * beiscsi_phys_port()- Display Physical Port Identifier
1623  * @dev: ptr to device not used.
1624  * @attr: device attribute, not used.
1625  * @buf: contains formatted text port identifier
1626  *
1627  * return
1628  * size of the formatted string
1629  **/
1630 ssize_t
1631 beiscsi_phys_port_disp(struct device *dev, struct device_attribute *attr,
1632                          char *buf)
1633 {
1634         struct Scsi_Host *shost = class_to_shost(dev);
1635         struct beiscsi_hba *phba = iscsi_host_priv(shost);
1636
1637         return snprintf(buf, PAGE_SIZE, "Port Identifier : %d\n",
1638                         phba->fw_config.phys_port);
1639 }
1640
1641 void beiscsi_offload_cxn_v0(struct beiscsi_offload_params *params,
1642                              struct wrb_handle *pwrb_handle,
1643                              struct be_mem_descriptor *mem_descr,
1644                              struct hwi_wrb_context *pwrb_context)
1645 {
1646         struct iscsi_wrb *pwrb = pwrb_handle->pwrb;
1647
1648         memset(pwrb, 0, sizeof(*pwrb));
1649         AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb,
1650                       max_send_data_segment_length, pwrb,
1651                       params->dw[offsetof(struct amap_beiscsi_offload_params,
1652                       max_send_data_segment_length) / 32]);
1653         AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, type, pwrb,
1654                       BE_TGT_CTX_UPDT_CMD);
1655         AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb,
1656                       first_burst_length,
1657                       pwrb,
1658                       params->dw[offsetof(struct amap_beiscsi_offload_params,
1659                       first_burst_length) / 32]);
1660         AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, erl, pwrb,
1661                       (params->dw[offsetof(struct amap_beiscsi_offload_params,
1662                       erl) / 32] & OFFLD_PARAMS_ERL));
1663         AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, dde, pwrb,
1664                       (params->dw[offsetof(struct amap_beiscsi_offload_params,
1665                        dde) / 32] & OFFLD_PARAMS_DDE) >> 2);
1666         AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, hde, pwrb,
1667                       (params->dw[offsetof(struct amap_beiscsi_offload_params,
1668                       hde) / 32] & OFFLD_PARAMS_HDE) >> 3);
1669         AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, ir2t, pwrb,
1670                       (params->dw[offsetof(struct amap_beiscsi_offload_params,
1671                       ir2t) / 32] & OFFLD_PARAMS_IR2T) >> 4);
1672         AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, imd, pwrb,
1673                       (params->dw[offsetof(struct amap_beiscsi_offload_params,
1674                       imd) / 32] & OFFLD_PARAMS_IMD) >> 5);
1675         AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, stat_sn,
1676                       pwrb,
1677                       (params->dw[offsetof(struct amap_beiscsi_offload_params,
1678                       exp_statsn) / 32] + 1));
1679         AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, wrb_idx,
1680                       pwrb, pwrb_handle->wrb_index);
1681
1682         AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb,
1683                       max_burst_length, pwrb, params->dw[offsetof
1684                       (struct amap_beiscsi_offload_params,
1685                       max_burst_length) / 32]);
1686
1687         AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, ptr2nextwrb,
1688                       pwrb, pwrb_handle->wrb_index);
1689         if (pwrb_context->plast_wrb)
1690                 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb,
1691                               ptr2nextwrb,
1692                               pwrb_context->plast_wrb,
1693                               pwrb_handle->wrb_index);
1694         pwrb_context->plast_wrb = pwrb;
1695
1696         AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb,
1697                       session_state, pwrb, 0);
1698         AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, compltonack,
1699                       pwrb, 1);
1700         AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, notpredblq,
1701                       pwrb, 0);
1702         AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, mode, pwrb,
1703                       0);
1704
1705         mem_descr += ISCSI_MEM_GLOBAL_HEADER;
1706         AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb,
1707                       pad_buffer_addr_hi, pwrb,
1708                       mem_descr->mem_array[0].bus_address.u.a32.address_hi);
1709         AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb,
1710                       pad_buffer_addr_lo, pwrb,
1711                       mem_descr->mem_array[0].bus_address.u.a32.address_lo);
1712 }
1713
1714 void beiscsi_offload_cxn_v2(struct beiscsi_offload_params *params,
1715                              struct wrb_handle *pwrb_handle,
1716                              struct hwi_wrb_context *pwrb_context)
1717 {
1718         struct iscsi_wrb *pwrb = pwrb_handle->pwrb;
1719
1720         memset(pwrb, 0, sizeof(*pwrb));
1721
1722         AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2,
1723                       max_burst_length, pwrb, params->dw[offsetof
1724                       (struct amap_beiscsi_offload_params,
1725                       max_burst_length) / 32]);
1726         AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2,
1727                       type, pwrb,
1728                       BE_TGT_CTX_UPDT_CMD);
1729         AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2,
1730                       ptr2nextwrb,
1731                       pwrb, pwrb_handle->wrb_index);
1732         if (pwrb_context->plast_wrb)
1733                 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2,
1734                               ptr2nextwrb,
1735                               pwrb_context->plast_wrb,
1736                               pwrb_handle->wrb_index);
1737         pwrb_context->plast_wrb = pwrb;
1738
1739         AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2, wrb_idx,
1740                       pwrb, pwrb_handle->wrb_index);
1741         AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2,
1742                       max_send_data_segment_length, pwrb,
1743                       params->dw[offsetof(struct amap_beiscsi_offload_params,
1744                       max_send_data_segment_length) / 32]);
1745         AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2,
1746                       first_burst_length, pwrb,
1747                       params->dw[offsetof(struct amap_beiscsi_offload_params,
1748                       first_burst_length) / 32]);
1749         AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2,
1750                       max_recv_dataseg_len, pwrb,
1751                       params->dw[offsetof(struct amap_beiscsi_offload_params,
1752                       max_recv_data_segment_length) / 32]);
1753         AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2,
1754                       max_cxns, pwrb, BEISCSI_MAX_CXNS);
1755         AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2, erl, pwrb,
1756                       (params->dw[offsetof(struct amap_beiscsi_offload_params,
1757                       erl) / 32] & OFFLD_PARAMS_ERL));
1758         AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2, dde, pwrb,
1759                       (params->dw[offsetof(struct amap_beiscsi_offload_params,
1760                       dde) / 32] & OFFLD_PARAMS_DDE) >> 2);
1761         AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2, hde, pwrb,
1762                       (params->dw[offsetof(struct amap_beiscsi_offload_params,
1763                       hde) / 32] & OFFLD_PARAMS_HDE) >> 3);
1764         AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2,
1765                       ir2t, pwrb,
1766                       (params->dw[offsetof(struct amap_beiscsi_offload_params,
1767                       ir2t) / 32] & OFFLD_PARAMS_IR2T) >> 4);
1768         AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2, imd, pwrb,
1769                       (params->dw[offsetof(struct amap_beiscsi_offload_params,
1770                       imd) / 32] & OFFLD_PARAMS_IMD) >> 5);
1771         AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2,
1772                       data_seq_inorder,
1773                       pwrb,
1774                       (params->dw[offsetof(struct amap_beiscsi_offload_params,
1775                       data_seq_inorder) / 32] &
1776                       OFFLD_PARAMS_DATA_SEQ_INORDER) >> 6);
1777         AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2,
1778                       pdu_seq_inorder,
1779                       pwrb,
1780                       (params->dw[offsetof(struct amap_beiscsi_offload_params,
1781                       pdu_seq_inorder) / 32] &
1782                       OFFLD_PARAMS_PDU_SEQ_INORDER) >> 7);
1783         AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2, max_r2t,
1784                       pwrb,
1785                       (params->dw[offsetof(struct amap_beiscsi_offload_params,
1786                       max_r2t) / 32] &
1787                       OFFLD_PARAMS_MAX_R2T) >> 8);
1788         AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2, stat_sn,
1789                       pwrb,
1790                      (params->dw[offsetof(struct amap_beiscsi_offload_params,
1791                       exp_statsn) / 32] + 1));
1792 }
1793
1794 /**
1795  * beiscsi_logout_fw_sess()- Firmware Session Logout
1796  * @phba: Device priv structure instance
1797  * @fw_sess_handle: FW session handle
1798  *
1799  * Logout from the FW established sessions.
1800  * returns
1801  *  Success: 0
1802  *  Failure: Non-Zero Value
1803  *
1804  */
1805 int beiscsi_logout_fw_sess(struct beiscsi_hba *phba,
1806                 uint32_t fw_sess_handle)
1807 {
1808         struct be_ctrl_info *ctrl = &phba->ctrl;
1809         struct be_mcc_wrb *wrb;
1810         struct be_cmd_req_logout_fw_sess *req;
1811         struct be_cmd_resp_logout_fw_sess *resp;
1812         unsigned int tag;
1813         int rc;
1814
1815         beiscsi_log(phba, KERN_INFO,
1816                     BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX,
1817                     "BG_%d : In bescsi_logout_fwboot_sess\n");
1818
1819         mutex_lock(&ctrl->mbox_lock);
1820         wrb = alloc_mcc_wrb(phba, &tag);
1821         if (!wrb) {
1822                 mutex_unlock(&ctrl->mbox_lock);
1823                 beiscsi_log(phba, KERN_INFO,
1824                             BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX,
1825                             "BG_%d : MBX Tag Failure\n");
1826                 return -EINVAL;
1827         }
1828
1829         req = embedded_payload(wrb);
1830         be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
1831         be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI_INI,
1832                            OPCODE_ISCSI_INI_SESSION_LOGOUT_TARGET,
1833                            sizeof(struct be_cmd_req_logout_fw_sess));
1834
1835         /* Set the session handle */
1836         req->session_handle = fw_sess_handle;
1837         be_mcc_notify(phba, tag);
1838         mutex_unlock(&ctrl->mbox_lock);
1839
1840         rc = beiscsi_mccq_compl_wait(phba, tag, &wrb, NULL);
1841         if (rc) {
1842                 beiscsi_log(phba, KERN_ERR,
1843                             BEISCSI_LOG_INIT | BEISCSI_LOG_CONFIG,
1844                             "BG_%d : MBX CMD FW_SESSION_LOGOUT_TARGET Failed\n");
1845                 return -EBUSY;
1846         }
1847
1848         resp = embedded_payload(wrb);
1849         if (resp->session_status !=
1850                 BEISCSI_MGMT_SESSION_CLOSE) {
1851                 beiscsi_log(phba, KERN_ERR,
1852                             BEISCSI_LOG_INIT | BEISCSI_LOG_CONFIG,
1853                             "BG_%d : FW_SESSION_LOGOUT_TARGET resp : 0x%x\n",
1854                             resp->session_status);
1855                 rc = -EINVAL;
1856         }
1857
1858         return rc;
1859 }