]> git.kernelconcepts.de Git - karo-tx-linux.git/blob - drivers/scsi/be2iscsi/be_mgmt.c
Merge remote-tracking branch 'asoc/fix/core' into asoc-linus
[karo-tx-linux.git] / drivers / scsi / be2iscsi / be_mgmt.c
1 /**
2  * Copyright (C) 2005 - 2013 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@emulex.com)
11  *
12  * Contact Information:
13  * linux-drivers@emulex.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 = 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_alloc_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         memset(cmd->va, 0, size);
910         cmd->size = size;
911         be_cmd_hdr_prepare(cmd->va, CMD_SUBSYSTEM_ISCSI, iscsi_cmd, size);
912         return 0;
913 }
914
915 static int
916 mgmt_static_ip_modify(struct beiscsi_hba *phba,
917                       struct be_cmd_get_if_info_resp *if_info,
918                       struct iscsi_iface_param_info *ip_param,
919                       struct iscsi_iface_param_info *subnet_param,
920                       uint32_t ip_action)
921 {
922         struct be_cmd_set_ip_addr_req *req;
923         struct be_dma_mem nonemb_cmd;
924         uint32_t ip_type;
925         int rc;
926
927         rc = mgmt_alloc_cmd_data(phba, &nonemb_cmd,
928                                  OPCODE_COMMON_ISCSI_NTWK_MODIFY_IP_ADDR,
929                                  sizeof(*req));
930         if (rc)
931                 return rc;
932
933         ip_type = (ip_param->param == ISCSI_NET_PARAM_IPV6_ADDR) ?
934                 BE2_IPV6 : BE2_IPV4 ;
935
936         req = nonemb_cmd.va;
937         req->ip_params.record_entry_count = 1;
938         req->ip_params.ip_record.action = ip_action;
939         req->ip_params.ip_record.interface_hndl =
940                 phba->interface_handle;
941         req->ip_params.ip_record.ip_addr.size_of_structure =
942                 sizeof(struct be_ip_addr_subnet_format);
943         req->ip_params.ip_record.ip_addr.ip_type = ip_type;
944
945         if (ip_action == IP_ACTION_ADD) {
946                 memcpy(req->ip_params.ip_record.ip_addr.addr, ip_param->value,
947                        ip_param->len);
948
949                 if (subnet_param)
950                         memcpy(req->ip_params.ip_record.ip_addr.subnet_mask,
951                                subnet_param->value, subnet_param->len);
952         } else {
953                 memcpy(req->ip_params.ip_record.ip_addr.addr,
954                        if_info->ip_addr.addr, ip_param->len);
955
956                 memcpy(req->ip_params.ip_record.ip_addr.subnet_mask,
957                        if_info->ip_addr.subnet_mask, ip_param->len);
958         }
959
960         rc = mgmt_exec_nonemb_cmd(phba, &nonemb_cmd, NULL, 0);
961         if (rc < 0)
962                 beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG,
963                             "BG_%d : Failed to Modify existing IP Address\n");
964         return rc;
965 }
966
967 static int mgmt_modify_gateway(struct beiscsi_hba *phba, uint8_t *gt_addr,
968                                uint32_t gtway_action, uint32_t param_len)
969 {
970         struct be_cmd_set_def_gateway_req *req;
971         struct be_dma_mem nonemb_cmd;
972         int rt_val;
973
974
975         rt_val = mgmt_alloc_cmd_data(phba, &nonemb_cmd,
976                                 OPCODE_COMMON_ISCSI_NTWK_MODIFY_DEFAULT_GATEWAY,
977                                 sizeof(*req));
978         if (rt_val)
979                 return rt_val;
980
981         req = nonemb_cmd.va;
982         req->action = gtway_action;
983         req->ip_addr.ip_type = BE2_IPV4;
984
985         memcpy(req->ip_addr.addr, gt_addr, param_len);
986
987         return mgmt_exec_nonemb_cmd(phba, &nonemb_cmd, NULL, 0);
988 }
989
990 int mgmt_set_ip(struct beiscsi_hba *phba,
991                 struct iscsi_iface_param_info *ip_param,
992                 struct iscsi_iface_param_info *subnet_param,
993                 uint32_t boot_proto)
994 {
995         struct be_cmd_get_def_gateway_resp gtway_addr_set;
996         struct be_cmd_get_if_info_resp *if_info;
997         struct be_cmd_set_dhcp_req *dhcpreq;
998         struct be_cmd_rel_dhcp_req *reldhcp;
999         struct be_dma_mem nonemb_cmd;
1000         uint8_t *gtway_addr;
1001         uint32_t ip_type;
1002         int rc;
1003
1004         if (mgmt_get_all_if_id(phba))
1005                 return -EIO;
1006
1007         ip_type = (ip_param->param == ISCSI_NET_PARAM_IPV6_ADDR) ?
1008                 BE2_IPV6 : BE2_IPV4 ;
1009
1010         rc = mgmt_get_if_info(phba, ip_type, &if_info);
1011         if (rc) {
1012                 kfree(if_info);
1013                 return rc;
1014         }
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                         return 0;
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                                 return rc;
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                                 return rc;
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                         return rc;
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                         return rc;
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                                 return rc;
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                         return rc;
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                 return mgmt_exec_nonemb_cmd(phba, &nonemb_cmd, NULL, 0);
1101         } else {
1102                 return mgmt_static_ip_modify(phba, if_info, ip_param,
1103                                              subnet_param, IP_ACTION_ADD);
1104         }
1105
1106         return rc;
1107 }
1108
1109 int mgmt_set_gateway(struct beiscsi_hba *phba,
1110                      struct iscsi_iface_param_info *gateway_param)
1111 {
1112         struct be_cmd_get_def_gateway_resp gtway_addr_set;
1113         uint8_t *gtway_addr;
1114         int rt_val;
1115
1116         memset(&gtway_addr_set, 0, sizeof(gtway_addr_set));
1117         rt_val = mgmt_get_gateway(phba, BE2_IPV4, &gtway_addr_set);
1118         if (rt_val) {
1119                 beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG,
1120                             "BG_%d : Failed to Get Gateway Addr\n");
1121                 return rt_val;
1122         }
1123
1124         if (gtway_addr_set.ip_addr.addr[0]) {
1125                 gtway_addr = (uint8_t *)&gtway_addr_set.ip_addr.addr;
1126                 rt_val = mgmt_modify_gateway(phba, gtway_addr, IP_ACTION_DEL,
1127                                              gateway_param->len);
1128                 if (rt_val) {
1129                         beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG,
1130                                     "BG_%d : Failed to clear Gateway Addr Set\n");
1131                         return rt_val;
1132                 }
1133         }
1134
1135         gtway_addr = (uint8_t *)&gateway_param->value;
1136         rt_val = mgmt_modify_gateway(phba, gtway_addr, IP_ACTION_ADD,
1137                                      gateway_param->len);
1138
1139         if (rt_val)
1140                 beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG,
1141                             "BG_%d : Failed to Set Gateway Addr\n");
1142
1143         return rt_val;
1144 }
1145
1146 int mgmt_get_gateway(struct beiscsi_hba *phba, int ip_type,
1147                      struct be_cmd_get_def_gateway_resp *gateway)
1148 {
1149         struct be_cmd_get_def_gateway_req *req;
1150         struct be_dma_mem nonemb_cmd;
1151         int rc;
1152
1153         rc = mgmt_alloc_cmd_data(phba, &nonemb_cmd,
1154                                  OPCODE_COMMON_ISCSI_NTWK_GET_DEFAULT_GATEWAY,
1155                                  sizeof(*gateway));
1156         if (rc)
1157                 return rc;
1158
1159         req = nonemb_cmd.va;
1160         req->ip_type = ip_type;
1161
1162         return mgmt_exec_nonemb_cmd(phba, &nonemb_cmd, gateway,
1163                                     sizeof(*gateway));
1164 }
1165
1166 int mgmt_get_if_info(struct beiscsi_hba *phba, int ip_type,
1167                      struct be_cmd_get_if_info_resp **if_info)
1168 {
1169         struct be_cmd_get_if_info_req *req;
1170         struct be_dma_mem nonemb_cmd;
1171         uint32_t ioctl_size = sizeof(struct be_cmd_get_if_info_resp);
1172         int rc;
1173
1174         if (mgmt_get_all_if_id(phba))
1175                 return -EIO;
1176
1177         do {
1178                 rc = mgmt_alloc_cmd_data(phba, &nonemb_cmd,
1179                                          OPCODE_COMMON_ISCSI_NTWK_GET_IF_INFO,
1180                                          ioctl_size);
1181                 if (rc)
1182                         return rc;
1183
1184                 req = nonemb_cmd.va;
1185                 req->interface_hndl = phba->interface_handle;
1186                 req->ip_type = ip_type;
1187
1188                 /* Allocate memory for if_info */
1189                 *if_info = kzalloc(ioctl_size, GFP_KERNEL);
1190                 if (!*if_info) {
1191                         beiscsi_log(phba, KERN_ERR,
1192                                     BEISCSI_LOG_INIT | BEISCSI_LOG_CONFIG,
1193                                     "BG_%d : Memory Allocation Failure\n");
1194
1195                                 /* Free the DMA memory for the IOCTL issuing */
1196                                 pci_free_consistent(phba->ctrl.pdev,
1197                                                     nonemb_cmd.size,
1198                                                     nonemb_cmd.va,
1199                                                     nonemb_cmd.dma);
1200                                 return -ENOMEM;
1201                 }
1202
1203                 rc =  mgmt_exec_nonemb_cmd(phba, &nonemb_cmd, *if_info,
1204                                            ioctl_size);
1205
1206                 /* Check if the error is because of Insufficent_Buffer */
1207                 if (rc == -EAGAIN) {
1208
1209                         /* Get the new memory size */
1210                         ioctl_size = ((struct be_cmd_resp_hdr *)
1211                                       nonemb_cmd.va)->actual_resp_len;
1212                         ioctl_size += sizeof(struct be_cmd_req_hdr);
1213
1214                         /* Free the previous allocated DMA memory */
1215                         pci_free_consistent(phba->ctrl.pdev, nonemb_cmd.size,
1216                                             nonemb_cmd.va,
1217                                             nonemb_cmd.dma);
1218
1219                         /* Free the virtual memory */
1220                         kfree(*if_info);
1221                 } else
1222                         break;
1223         } while (true);
1224         return rc;
1225 }
1226
1227 int mgmt_get_nic_conf(struct beiscsi_hba *phba,
1228                       struct be_cmd_get_nic_conf_resp *nic)
1229 {
1230         struct be_dma_mem nonemb_cmd;
1231         int rc;
1232
1233         rc = mgmt_alloc_cmd_data(phba, &nonemb_cmd,
1234                                  OPCODE_COMMON_ISCSI_NTWK_GET_NIC_CONFIG,
1235                                  sizeof(*nic));
1236         if (rc)
1237                 return rc;
1238
1239         return mgmt_exec_nonemb_cmd(phba, &nonemb_cmd, nic, sizeof(*nic));
1240 }
1241
1242
1243
1244 unsigned int be_cmd_get_initname(struct beiscsi_hba *phba)
1245 {
1246         unsigned int tag = 0;
1247         struct be_mcc_wrb *wrb;
1248         struct be_cmd_hba_name *req;
1249         struct be_ctrl_info *ctrl = &phba->ctrl;
1250
1251         spin_lock(&ctrl->mbox_lock);
1252         tag = alloc_mcc_tag(phba);
1253         if (!tag) {
1254                 spin_unlock(&ctrl->mbox_lock);
1255                 return tag;
1256         }
1257
1258         wrb = wrb_from_mccq(phba);
1259         req = embedded_payload(wrb);
1260         wrb->tag0 |= tag;
1261         be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
1262         be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI_INI,
1263                         OPCODE_ISCSI_INI_CFG_GET_HBA_NAME,
1264                         sizeof(*req));
1265
1266         be_mcc_notify(phba);
1267         spin_unlock(&ctrl->mbox_lock);
1268         return tag;
1269 }
1270
1271 unsigned int be_cmd_get_port_speed(struct beiscsi_hba *phba)
1272 {
1273         unsigned int tag = 0;
1274         struct be_mcc_wrb *wrb;
1275         struct be_cmd_ntwk_link_status_req *req;
1276         struct be_ctrl_info *ctrl = &phba->ctrl;
1277
1278         spin_lock(&ctrl->mbox_lock);
1279         tag = alloc_mcc_tag(phba);
1280         if (!tag) {
1281                 spin_unlock(&ctrl->mbox_lock);
1282                 return tag;
1283         }
1284
1285         wrb = wrb_from_mccq(phba);
1286         req = embedded_payload(wrb);
1287         wrb->tag0 |= tag;
1288         be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
1289         be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
1290                         OPCODE_COMMON_NTWK_LINK_STATUS_QUERY,
1291                         sizeof(*req));
1292
1293         be_mcc_notify(phba);
1294         spin_unlock(&ctrl->mbox_lock);
1295         return tag;
1296 }
1297
1298 /**
1299  * be_mgmt_get_boot_shandle()- Get the session handle
1300  * @phba: device priv structure instance
1301  * @s_handle: session handle returned for boot session.
1302  *
1303  * Get the boot target session handle. In case of
1304  * crashdump mode driver has to issue and MBX Cmd
1305  * for FW to login to boot target
1306  *
1307  * return
1308  *      Success: 0
1309  *      Failure: Non-Zero value
1310  *
1311  **/
1312 int be_mgmt_get_boot_shandle(struct beiscsi_hba *phba,
1313                               unsigned int *s_handle)
1314 {
1315         struct be_cmd_get_boot_target_resp *boot_resp;
1316         struct be_mcc_wrb *wrb;
1317         unsigned int tag;
1318         uint8_t boot_retry = 3;
1319         int rc;
1320
1321         do {
1322                 /* Get the Boot Target Session Handle and Count*/
1323                 tag = mgmt_get_boot_target(phba);
1324                 if (!tag) {
1325                         beiscsi_log(phba, KERN_ERR,
1326                                     BEISCSI_LOG_CONFIG | BEISCSI_LOG_INIT,
1327                                     "BG_%d : Getting Boot Target Info Failed\n");
1328                         return -EAGAIN;
1329                 }
1330
1331                 rc = beiscsi_mccq_compl(phba, tag, &wrb, NULL);
1332                 if (rc) {
1333                         beiscsi_log(phba, KERN_ERR,
1334                                     BEISCSI_LOG_INIT | BEISCSI_LOG_CONFIG,
1335                                     "BG_%d : MBX CMD get_boot_target Failed\n");
1336                         return -EBUSY;
1337                 }
1338
1339                 boot_resp = embedded_payload(wrb);
1340
1341                 /* Check if the there are any Boot targets configured */
1342                 if (!boot_resp->boot_session_count) {
1343                         beiscsi_log(phba, KERN_INFO,
1344                                     BEISCSI_LOG_INIT | BEISCSI_LOG_CONFIG,
1345                                     "BG_%d  ;No boot targets configured\n");
1346                         return -ENXIO;
1347                 }
1348
1349                 /* FW returns the session handle of the boot session */
1350                 if (boot_resp->boot_session_handle != INVALID_SESS_HANDLE) {
1351                         *s_handle = boot_resp->boot_session_handle;
1352                         return 0;
1353                 }
1354
1355                 /* Issue MBX Cmd to FW to login to the boot target */
1356                 tag = mgmt_reopen_session(phba, BE_REOPEN_BOOT_SESSIONS,
1357                                           INVALID_SESS_HANDLE);
1358                 if (!tag) {
1359                         beiscsi_log(phba, KERN_ERR,
1360                                     BEISCSI_LOG_INIT | BEISCSI_LOG_CONFIG,
1361                                     "BG_%d : mgmt_reopen_session Failed\n");
1362                         return -EAGAIN;
1363                 }
1364
1365                 rc = beiscsi_mccq_compl(phba, tag, NULL, NULL);
1366                 if (rc) {
1367                         beiscsi_log(phba, KERN_ERR,
1368                                     BEISCSI_LOG_INIT | BEISCSI_LOG_CONFIG,
1369                                     "BG_%d : mgmt_reopen_session Failed");
1370                         return rc;
1371                 }
1372         } while (--boot_retry);
1373
1374         /* Couldn't log into the boot target */
1375         beiscsi_log(phba, KERN_ERR,
1376                     BEISCSI_LOG_INIT | BEISCSI_LOG_CONFIG,
1377                     "BG_%d : Login to Boot Target Failed\n");
1378         return -ENXIO;
1379 }
1380
1381 /**
1382  * mgmt_set_vlan()- Issue and wait for CMD completion
1383  * @phba: device private structure instance
1384  * @vlan_tag: VLAN tag
1385  *
1386  * Issue the MBX Cmd and wait for the completion of the
1387  * command.
1388  *
1389  * returns
1390  *      Success: 0
1391  *      Failure: Non-Xero Value
1392  **/
1393 int mgmt_set_vlan(struct beiscsi_hba *phba,
1394                    uint16_t vlan_tag)
1395 {
1396         int rc;
1397         unsigned int tag;
1398
1399         tag = be_cmd_set_vlan(phba, vlan_tag);
1400         if (!tag) {
1401                 beiscsi_log(phba, KERN_ERR,
1402                             (BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX),
1403                             "BG_%d : VLAN Setting Failed\n");
1404                 return -EBUSY;
1405         }
1406
1407         rc = beiscsi_mccq_compl(phba, tag, NULL, NULL);
1408         if (rc) {
1409                 beiscsi_log(phba, KERN_ERR,
1410                             (BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX),
1411                             "BS_%d : VLAN MBX Cmd Failed\n");
1412                 return rc;
1413         }
1414         return rc;
1415 }
1416
1417 /**
1418  * beiscsi_drvr_ver_disp()- Display the driver Name and Version
1419  * @dev: ptr to device not used.
1420  * @attr: device attribute, not used.
1421  * @buf: contains formatted text driver name and version
1422  *
1423  * return
1424  * size of the formatted string
1425  **/
1426 ssize_t
1427 beiscsi_drvr_ver_disp(struct device *dev, struct device_attribute *attr,
1428                        char *buf)
1429 {
1430         return snprintf(buf, PAGE_SIZE, BE_NAME "\n");
1431 }
1432
1433 /**
1434  * beiscsi_fw_ver_disp()- Display Firmware Version
1435  * @dev: ptr to device not used.
1436  * @attr: device attribute, not used.
1437  * @buf: contains formatted text Firmware version
1438  *
1439  * return
1440  * size of the formatted string
1441  **/
1442 ssize_t
1443 beiscsi_fw_ver_disp(struct device *dev, struct device_attribute *attr,
1444                      char *buf)
1445 {
1446         struct Scsi_Host *shost = class_to_shost(dev);
1447         struct beiscsi_hba *phba = iscsi_host_priv(shost);
1448
1449         return snprintf(buf, PAGE_SIZE, "%s\n", phba->fw_ver_str);
1450 }
1451
1452 /**
1453  * beiscsi_active_session_disp()- Display Sessions Active
1454  * @dev: ptr to device not used.
1455  * @attr: device attribute, not used.
1456  * @buf: contains formatted text Session Count
1457  *
1458  * return
1459  * size of the formatted string
1460  **/
1461 ssize_t
1462 beiscsi_active_session_disp(struct device *dev, struct device_attribute *attr,
1463                          char *buf)
1464 {
1465         struct Scsi_Host *shost = class_to_shost(dev);
1466         struct beiscsi_hba *phba = iscsi_host_priv(shost);
1467         uint16_t avlbl_cids = 0, ulp_num, len = 0, total_cids = 0;
1468
1469         for (ulp_num = 0; ulp_num < BEISCSI_ULP_COUNT; ulp_num++) {
1470                 if (test_bit(ulp_num, (void *)&phba->fw_config.ulp_supported)) {
1471                         avlbl_cids = BEISCSI_ULP_AVLBL_CID(phba, ulp_num);
1472                         total_cids = BEISCSI_GET_CID_COUNT(phba, ulp_num);
1473                         len += snprintf(buf+len, PAGE_SIZE - len,
1474                                         "ULP%d : %d\n", ulp_num,
1475                                         (total_cids - avlbl_cids));
1476                 } else
1477                         len += snprintf(buf+len, PAGE_SIZE - len,
1478                                         "ULP%d : %d\n", ulp_num, 0);
1479         }
1480
1481         return len;
1482 }
1483
1484 /**
1485  * beiscsi_free_session_disp()- Display Avaliable Session
1486  * @dev: ptr to device not used.
1487  * @attr: device attribute, not used.
1488  * @buf: contains formatted text Session Count
1489  *
1490  * return
1491  * size of the formatted string
1492  **/
1493 ssize_t
1494 beiscsi_free_session_disp(struct device *dev, struct device_attribute *attr,
1495                        char *buf)
1496 {
1497         struct Scsi_Host *shost = class_to_shost(dev);
1498         struct beiscsi_hba *phba = iscsi_host_priv(shost);
1499         uint16_t ulp_num, len = 0;
1500
1501         for (ulp_num = 0; ulp_num < BEISCSI_ULP_COUNT; ulp_num++) {
1502                 if (test_bit(ulp_num, (void *)&phba->fw_config.ulp_supported))
1503                         len += snprintf(buf+len, PAGE_SIZE - len,
1504                                         "ULP%d : %d\n", ulp_num,
1505                                         BEISCSI_ULP_AVLBL_CID(phba, ulp_num));
1506                 else
1507                         len += snprintf(buf+len, PAGE_SIZE - len,
1508                                         "ULP%d : %d\n", ulp_num, 0);
1509         }
1510
1511         return len;
1512 }
1513
1514 /**
1515  * beiscsi_adap_family_disp()- Display adapter family.
1516  * @dev: ptr to device to get priv structure
1517  * @attr: device attribute, not used.
1518  * @buf: contains formatted text driver name and version
1519  *
1520  * return
1521  * size of the formatted string
1522  **/
1523 ssize_t
1524 beiscsi_adap_family_disp(struct device *dev, struct device_attribute *attr,
1525                           char *buf)
1526 {
1527         uint16_t dev_id = 0;
1528         struct Scsi_Host *shost = class_to_shost(dev);
1529         struct beiscsi_hba *phba = iscsi_host_priv(shost);
1530
1531         dev_id = phba->pcidev->device;
1532         switch (dev_id) {
1533         case BE_DEVICE_ID1:
1534         case OC_DEVICE_ID1:
1535         case OC_DEVICE_ID2:
1536                 return snprintf(buf, PAGE_SIZE, "BE2 Adapter Family\n");
1537                 break;
1538         case BE_DEVICE_ID2:
1539         case OC_DEVICE_ID3:
1540                 return snprintf(buf, PAGE_SIZE, "BE3-R Adapter Family\n");
1541                 break;
1542         case OC_SKH_ID1:
1543                 return snprintf(buf, PAGE_SIZE, "Skyhawk-R Adapter Family\n");
1544                 break;
1545         default:
1546                 return snprintf(buf, PAGE_SIZE,
1547                                 "Unknown Adapter Family: 0x%x\n", dev_id);
1548                 break;
1549         }
1550 }
1551
1552 /**
1553  * beiscsi_phys_port()- Display Physical Port Identifier
1554  * @dev: ptr to device not used.
1555  * @attr: device attribute, not used.
1556  * @buf: contains formatted text port identifier
1557  *
1558  * return
1559  * size of the formatted string
1560  **/
1561 ssize_t
1562 beiscsi_phys_port_disp(struct device *dev, struct device_attribute *attr,
1563                          char *buf)
1564 {
1565         struct Scsi_Host *shost = class_to_shost(dev);
1566         struct beiscsi_hba *phba = iscsi_host_priv(shost);
1567
1568         return snprintf(buf, PAGE_SIZE, "Port Identifier : %d\n",
1569                         phba->fw_config.phys_port);
1570 }
1571
1572 void beiscsi_offload_cxn_v0(struct beiscsi_offload_params *params,
1573                              struct wrb_handle *pwrb_handle,
1574                              struct be_mem_descriptor *mem_descr)
1575 {
1576         struct iscsi_wrb *pwrb = pwrb_handle->pwrb;
1577
1578         memset(pwrb, 0, sizeof(*pwrb));
1579         AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb,
1580                       max_send_data_segment_length, pwrb,
1581                       params->dw[offsetof(struct amap_beiscsi_offload_params,
1582                       max_send_data_segment_length) / 32]);
1583         AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, type, pwrb,
1584                       BE_TGT_CTX_UPDT_CMD);
1585         AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb,
1586                       first_burst_length,
1587                       pwrb,
1588                       params->dw[offsetof(struct amap_beiscsi_offload_params,
1589                       first_burst_length) / 32]);
1590         AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, erl, pwrb,
1591                       (params->dw[offsetof(struct amap_beiscsi_offload_params,
1592                       erl) / 32] & OFFLD_PARAMS_ERL));
1593         AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, dde, pwrb,
1594                       (params->dw[offsetof(struct amap_beiscsi_offload_params,
1595                        dde) / 32] & OFFLD_PARAMS_DDE) >> 2);
1596         AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, hde, pwrb,
1597                       (params->dw[offsetof(struct amap_beiscsi_offload_params,
1598                       hde) / 32] & OFFLD_PARAMS_HDE) >> 3);
1599         AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, ir2t, pwrb,
1600                       (params->dw[offsetof(struct amap_beiscsi_offload_params,
1601                       ir2t) / 32] & OFFLD_PARAMS_IR2T) >> 4);
1602         AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, imd, pwrb,
1603                       (params->dw[offsetof(struct amap_beiscsi_offload_params,
1604                       imd) / 32] & OFFLD_PARAMS_IMD) >> 5);
1605         AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, stat_sn,
1606                       pwrb,
1607                       (params->dw[offsetof(struct amap_beiscsi_offload_params,
1608                       exp_statsn) / 32] + 1));
1609         AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, wrb_idx,
1610                       pwrb, pwrb_handle->wrb_index);
1611
1612         AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb,
1613                       max_burst_length, pwrb, params->dw[offsetof
1614                       (struct amap_beiscsi_offload_params,
1615                       max_burst_length) / 32]);
1616
1617         AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, ptr2nextwrb,
1618                       pwrb, pwrb_handle->nxt_wrb_index);
1619         AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb,
1620                       session_state, pwrb, 0);
1621         AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, compltonack,
1622                       pwrb, 1);
1623         AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, notpredblq,
1624                       pwrb, 0);
1625         AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, mode, pwrb,
1626                       0);
1627
1628         mem_descr += ISCSI_MEM_GLOBAL_HEADER;
1629         AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb,
1630                       pad_buffer_addr_hi, pwrb,
1631                       mem_descr->mem_array[0].bus_address.u.a32.address_hi);
1632         AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb,
1633                       pad_buffer_addr_lo, pwrb,
1634                       mem_descr->mem_array[0].bus_address.u.a32.address_lo);
1635 }
1636
1637 void beiscsi_offload_cxn_v2(struct beiscsi_offload_params *params,
1638                              struct wrb_handle *pwrb_handle)
1639 {
1640         struct iscsi_wrb *pwrb = pwrb_handle->pwrb;
1641
1642         memset(pwrb, 0, sizeof(*pwrb));
1643
1644         AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2,
1645                       max_burst_length, pwrb, params->dw[offsetof
1646                       (struct amap_beiscsi_offload_params,
1647                       max_burst_length) / 32]);
1648         AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2,
1649                       type, pwrb,
1650                       BE_TGT_CTX_UPDT_CMD);
1651         AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2,
1652                       ptr2nextwrb,
1653                       pwrb, pwrb_handle->nxt_wrb_index);
1654         AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2, wrb_idx,
1655                       pwrb, pwrb_handle->wrb_index);
1656         AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2,
1657                       max_send_data_segment_length, pwrb,
1658                       params->dw[offsetof(struct amap_beiscsi_offload_params,
1659                       max_send_data_segment_length) / 32]);
1660         AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2,
1661                       first_burst_length, pwrb,
1662                       params->dw[offsetof(struct amap_beiscsi_offload_params,
1663                       first_burst_length) / 32]);
1664         AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2,
1665                       max_recv_dataseg_len, pwrb,
1666                       params->dw[offsetof(struct amap_beiscsi_offload_params,
1667                       max_recv_data_segment_length) / 32]);
1668         AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2,
1669                       max_cxns, pwrb, BEISCSI_MAX_CXNS);
1670         AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2, erl, pwrb,
1671                       (params->dw[offsetof(struct amap_beiscsi_offload_params,
1672                       erl) / 32] & OFFLD_PARAMS_ERL));
1673         AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2, dde, pwrb,
1674                       (params->dw[offsetof(struct amap_beiscsi_offload_params,
1675                       dde) / 32] & OFFLD_PARAMS_DDE) >> 2);
1676         AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2, hde, pwrb,
1677                       (params->dw[offsetof(struct amap_beiscsi_offload_params,
1678                       hde) / 32] & OFFLD_PARAMS_HDE) >> 3);
1679         AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2,
1680                       ir2t, pwrb,
1681                       (params->dw[offsetof(struct amap_beiscsi_offload_params,
1682                       ir2t) / 32] & OFFLD_PARAMS_IR2T) >> 4);
1683         AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2, imd, pwrb,
1684                       (params->dw[offsetof(struct amap_beiscsi_offload_params,
1685                       imd) / 32] & OFFLD_PARAMS_IMD) >> 5);
1686         AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2,
1687                       data_seq_inorder,
1688                       pwrb,
1689                       (params->dw[offsetof(struct amap_beiscsi_offload_params,
1690                       data_seq_inorder) / 32] &
1691                       OFFLD_PARAMS_DATA_SEQ_INORDER) >> 6);
1692         AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2,
1693                       pdu_seq_inorder,
1694                       pwrb,
1695                       (params->dw[offsetof(struct amap_beiscsi_offload_params,
1696                       pdu_seq_inorder) / 32] &
1697                       OFFLD_PARAMS_PDU_SEQ_INORDER) >> 7);
1698         AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2, max_r2t,
1699                       pwrb,
1700                       (params->dw[offsetof(struct amap_beiscsi_offload_params,
1701                       max_r2t) / 32] &
1702                       OFFLD_PARAMS_MAX_R2T) >> 8);
1703         AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2, stat_sn,
1704                       pwrb,
1705                      (params->dw[offsetof(struct amap_beiscsi_offload_params,
1706                       exp_statsn) / 32] + 1));
1707 }