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