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