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