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