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