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