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