linux/drivers/scsi/be2iscsi/be_mgmt.c
<<
>>
Prefs
   1/*
   2 * This file is part of the Emulex Linux Device Driver for Enterprise iSCSI
   3 * Host Bus Adapters. Refer to the README file included with this package
   4 * for driver version and adapter compatibility.
   5 *
   6 * Copyright (c) 2018 Broadcom. All Rights Reserved.
   7 * The term “Broadcom” refers to Broadcom Inc. and/or its subsidiaries.
   8 *
   9 * This program is free software; you can redistribute it and/or modify it
  10 * under the terms of version 2 of the GNU General Public License as published
  11 * by the Free Software Foundation.
  12 *
  13 * This program is distributed in the hope that it will be useful. ALL EXPRESS
  14 * OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING ANY
  15 * IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE,
  16 * OR NON-INFRINGEMENT, ARE DISCLAIMED, EXCEPT TO THE EXTENT THAT SUCH
  17 * DISCLAIMERS ARE HELD TO BE LEGALLY INVALID.
  18 * See the GNU General Public License for more details, a copy of which
  19 * can be found in the file COPYING included with this package.
  20 *
  21 * Contact Information:
  22 * linux-drivers@broadcom.com
  23 *
  24 */
  25
  26#include <linux/bsg-lib.h>
  27#include <scsi/scsi_transport_iscsi.h>
  28#include <scsi/scsi_bsg_iscsi.h>
  29#include "be_mgmt.h"
  30#include "be_iscsi.h"
  31#include "be_main.h"
  32
  33unsigned int mgmt_vendor_specific_fw_cmd(struct be_ctrl_info *ctrl,
  34                                         struct beiscsi_hba *phba,
  35                                         struct bsg_job *job,
  36                                         struct be_dma_mem *nonemb_cmd)
  37{
  38        struct be_mcc_wrb *wrb;
  39        struct be_sge *mcc_sge;
  40        unsigned int tag = 0;
  41        struct iscsi_bsg_request *bsg_req = job->request;
  42        struct be_bsg_vendor_cmd *req = nonemb_cmd->va;
  43        unsigned short region, sector_size, sector, offset;
  44
  45        nonemb_cmd->size = job->request_payload.payload_len;
  46        memset(nonemb_cmd->va, 0, nonemb_cmd->size);
  47        region =  bsg_req->rqst_data.h_vendor.vendor_cmd[1];
  48        sector_size =  bsg_req->rqst_data.h_vendor.vendor_cmd[2];
  49        sector =  bsg_req->rqst_data.h_vendor.vendor_cmd[3];
  50        offset =  bsg_req->rqst_data.h_vendor.vendor_cmd[4];
  51        req->region = region;
  52        req->sector = sector;
  53        req->offset = offset;
  54
  55        if (mutex_lock_interruptible(&ctrl->mbox_lock))
  56                return 0;
  57        switch (bsg_req->rqst_data.h_vendor.vendor_cmd[0]) {
  58        case BEISCSI_WRITE_FLASH:
  59                offset = sector * sector_size + offset;
  60                be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI,
  61                                   OPCODE_COMMON_WRITE_FLASH, sizeof(*req));
  62                sg_copy_to_buffer(job->request_payload.sg_list,
  63                                  job->request_payload.sg_cnt,
  64                                  nonemb_cmd->va + offset, job->request_len);
  65                break;
  66        case BEISCSI_READ_FLASH:
  67                be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI,
  68                           OPCODE_COMMON_READ_FLASH, sizeof(*req));
  69                break;
  70        default:
  71                beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG,
  72                            "BG_%d : Unsupported cmd = 0x%x\n\n",
  73                            bsg_req->rqst_data.h_vendor.vendor_cmd[0]);
  74
  75                mutex_unlock(&ctrl->mbox_lock);
  76                return -EPERM;
  77        }
  78
  79        wrb = alloc_mcc_wrb(phba, &tag);
  80        if (!wrb) {
  81                mutex_unlock(&ctrl->mbox_lock);
  82                return 0;
  83        }
  84
  85        mcc_sge = nonembedded_sgl(wrb);
  86        be_wrb_hdr_prepare(wrb, nonemb_cmd->size, false,
  87                           job->request_payload.sg_cnt);
  88        mcc_sge->pa_hi = cpu_to_le32(upper_32_bits(nonemb_cmd->dma));
  89        mcc_sge->pa_lo = cpu_to_le32(nonemb_cmd->dma & 0xFFFFFFFF);
  90        mcc_sge->len = cpu_to_le32(nonemb_cmd->size);
  91
  92        be_mcc_notify(phba, tag);
  93
  94        mutex_unlock(&ctrl->mbox_lock);
  95        return tag;
  96}
  97
  98/**
  99 * mgmt_open_connection()- Establish a TCP CXN
 100 * @phba: driver priv structure
 101 * @dst_addr: Destination Address
 102 * @beiscsi_ep: ptr to device endpoint struct
 103 * @nonemb_cmd: ptr to memory allocated for command
 104 *
 105 * return
 106 *      Success: Tag number of the MBX Command issued
 107 *      Failure: Error code
 108 **/
 109int mgmt_open_connection(struct beiscsi_hba *phba,
 110                         struct sockaddr *dst_addr,
 111                         struct beiscsi_endpoint *beiscsi_ep,
 112                         struct be_dma_mem *nonemb_cmd)
 113{
 114        struct hwi_controller *phwi_ctrlr;
 115        struct hwi_context_memory *phwi_context;
 116        struct sockaddr_in *daddr_in = (struct sockaddr_in *)dst_addr;
 117        struct sockaddr_in6 *daddr_in6 = (struct sockaddr_in6 *)dst_addr;
 118        struct be_ctrl_info *ctrl = &phba->ctrl;
 119        struct be_mcc_wrb *wrb;
 120        struct tcp_connect_and_offload_in_v1 *req;
 121        unsigned short def_hdr_id;
 122        unsigned short def_data_id;
 123        struct phys_addr template_address = { 0, 0 };
 124        struct phys_addr *ptemplate_address;
 125        unsigned int tag = 0;
 126        unsigned int i, ulp_num;
 127        unsigned short cid = beiscsi_ep->ep_cid;
 128        struct be_sge *sge;
 129
 130        if (dst_addr->sa_family != PF_INET && dst_addr->sa_family != PF_INET6) {
 131                beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG,
 132                            "BG_%d : unknown addr family %d\n",
 133                            dst_addr->sa_family);
 134                return 0;
 135        }
 136
 137        phwi_ctrlr = phba->phwi_ctrlr;
 138        phwi_context = phwi_ctrlr->phwi_ctxt;
 139
 140        ulp_num = phwi_ctrlr->wrb_context[BE_GET_CRI_FROM_CID(cid)].ulp_num;
 141
 142        def_hdr_id = (unsigned short)HWI_GET_DEF_HDRQ_ID(phba, ulp_num);
 143        def_data_id = (unsigned short)HWI_GET_DEF_BUFQ_ID(phba, ulp_num);
 144
 145        ptemplate_address = &template_address;
 146        ISCSI_GET_PDU_TEMPLATE_ADDRESS(phba, ptemplate_address);
 147        if (mutex_lock_interruptible(&ctrl->mbox_lock))
 148                return 0;
 149        wrb = alloc_mcc_wrb(phba, &tag);
 150        if (!wrb) {
 151                mutex_unlock(&ctrl->mbox_lock);
 152                return 0;
 153        }
 154
 155        sge = nonembedded_sgl(wrb);
 156        req = nonemb_cmd->va;
 157        memset(req, 0, sizeof(*req));
 158
 159        be_wrb_hdr_prepare(wrb, nonemb_cmd->size, false, 1);
 160        be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI,
 161                           OPCODE_COMMON_ISCSI_TCP_CONNECT_AND_OFFLOAD,
 162                           nonemb_cmd->size);
 163        if (dst_addr->sa_family == PF_INET) {
 164                __be32 s_addr = daddr_in->sin_addr.s_addr;
 165                req->ip_address.ip_type = BEISCSI_IP_TYPE_V4;
 166                req->ip_address.addr[0] = s_addr & 0x000000ff;
 167                req->ip_address.addr[1] = (s_addr & 0x0000ff00) >> 8;
 168                req->ip_address.addr[2] = (s_addr & 0x00ff0000) >> 16;
 169                req->ip_address.addr[3] = (s_addr & 0xff000000) >> 24;
 170                req->tcp_port = ntohs(daddr_in->sin_port);
 171                beiscsi_ep->dst_addr = daddr_in->sin_addr.s_addr;
 172                beiscsi_ep->dst_tcpport = ntohs(daddr_in->sin_port);
 173                beiscsi_ep->ip_type = BEISCSI_IP_TYPE_V4;
 174        } else {
 175                /* else its PF_INET6 family */
 176                req->ip_address.ip_type = BEISCSI_IP_TYPE_V6;
 177                memcpy(&req->ip_address.addr,
 178                       &daddr_in6->sin6_addr.in6_u.u6_addr8, 16);
 179                req->tcp_port = ntohs(daddr_in6->sin6_port);
 180                beiscsi_ep->dst_tcpport = ntohs(daddr_in6->sin6_port);
 181                memcpy(&beiscsi_ep->dst6_addr,
 182                       &daddr_in6->sin6_addr.in6_u.u6_addr8, 16);
 183                beiscsi_ep->ip_type = BEISCSI_IP_TYPE_V6;
 184        }
 185        req->cid = cid;
 186        i = phba->nxt_cqid++;
 187        if (phba->nxt_cqid == phba->num_cpus)
 188                phba->nxt_cqid = 0;
 189        req->cq_id = phwi_context->be_cq[i].id;
 190        beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG,
 191                    "BG_%d : i=%d cq_id=%d\n", i, req->cq_id);
 192        req->defq_id = def_hdr_id;
 193        req->hdr_ring_id = def_hdr_id;
 194        req->data_ring_id = def_data_id;
 195        req->do_offload = 1;
 196        req->dataout_template_pa.lo = ptemplate_address->lo;
 197        req->dataout_template_pa.hi = ptemplate_address->hi;
 198        sge->pa_hi = cpu_to_le32(upper_32_bits(nonemb_cmd->dma));
 199        sge->pa_lo = cpu_to_le32(nonemb_cmd->dma & 0xFFFFFFFF);
 200        sge->len = cpu_to_le32(nonemb_cmd->size);
 201
 202        if (!is_chip_be2_be3r(phba)) {
 203                req->hdr.version = MBX_CMD_VER1;
 204                req->tcp_window_size = 0x8000;
 205                req->tcp_window_scale_count = 2;
 206        }
 207
 208        be_mcc_notify(phba, tag);
 209        mutex_unlock(&ctrl->mbox_lock);
 210        return tag;
 211}
 212
 213/**
 214 * beiscsi_exec_nemb_cmd()- execute non-embedded MBX cmd
 215 * @phba: driver priv structure
 216 * @nonemb_cmd: DMA address of the MBX command to be issued
 217 * @cbfn: callback func on MCC completion
 218 * @resp_buf: buffer to copy the MBX cmd response
 219 * @resp_buf_len: response length to be copied
 220 *
 221 **/
 222static int beiscsi_exec_nemb_cmd(struct beiscsi_hba *phba,
 223                                 struct be_dma_mem *nonemb_cmd,
 224                                 void (*cbfn)(struct beiscsi_hba *,
 225                                              unsigned int),
 226                                 void *resp_buf, u32 resp_buf_len)
 227{
 228        struct be_ctrl_info *ctrl = &phba->ctrl;
 229        struct be_mcc_wrb *wrb;
 230        struct be_sge *sge;
 231        unsigned int tag;
 232        int rc = 0;
 233
 234        mutex_lock(&ctrl->mbox_lock);
 235        wrb = alloc_mcc_wrb(phba, &tag);
 236        if (!wrb) {
 237                mutex_unlock(&ctrl->mbox_lock);
 238                return -ENOMEM;
 239        }
 240
 241        sge = nonembedded_sgl(wrb);
 242        be_wrb_hdr_prepare(wrb, nonemb_cmd->size, false, 1);
 243        sge->pa_hi = cpu_to_le32(upper_32_bits(nonemb_cmd->dma));
 244        sge->pa_lo = cpu_to_le32(lower_32_bits(nonemb_cmd->dma));
 245        sge->len = cpu_to_le32(nonemb_cmd->size);
 246
 247        if (cbfn) {
 248                struct be_dma_mem *tag_mem;
 249
 250                set_bit(MCC_TAG_STATE_ASYNC, &ctrl->ptag_state[tag].tag_state);
 251                ctrl->ptag_state[tag].cbfn = cbfn;
 252                tag_mem = &phba->ctrl.ptag_state[tag].tag_mem_state;
 253
 254                /* store DMA mem to be freed in callback */
 255                tag_mem->size = nonemb_cmd->size;
 256                tag_mem->va = nonemb_cmd->va;
 257                tag_mem->dma = nonemb_cmd->dma;
 258        }
 259        be_mcc_notify(phba, tag);
 260        mutex_unlock(&ctrl->mbox_lock);
 261
 262        /* with cbfn set, its async cmd, don't wait */
 263        if (cbfn)
 264                return 0;
 265
 266        rc = beiscsi_mccq_compl_wait(phba, tag, NULL, nonemb_cmd);
 267
 268        /* copy the response, if any */
 269        if (resp_buf)
 270                memcpy(resp_buf, nonemb_cmd->va, resp_buf_len);
 271        return rc;
 272}
 273
 274static int beiscsi_prep_nemb_cmd(struct beiscsi_hba *phba,
 275                                 struct be_dma_mem *cmd,
 276                                 u8 subsystem, u8 opcode, u32 size)
 277{
 278        cmd->va = dma_alloc_coherent(&phba->ctrl.pdev->dev, size, &cmd->dma,
 279                                     GFP_KERNEL);
 280        if (!cmd->va) {
 281                beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG,
 282                            "BG_%d : Failed to allocate memory for if info\n");
 283                return -ENOMEM;
 284        }
 285        cmd->size = size;
 286        be_cmd_hdr_prepare(cmd->va, subsystem, opcode, size);
 287        beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG,
 288                    "BG_%d : subsystem %u cmd %u size %u\n",
 289                    subsystem, opcode, size);
 290        return 0;
 291}
 292
 293static void beiscsi_free_nemb_cmd(struct beiscsi_hba *phba,
 294                                  struct be_dma_mem *cmd, int rc)
 295{
 296        /*
 297         * If FW is busy the DMA buffer is saved with the tag. When the cmd
 298         * completes this buffer is freed.
 299         */
 300        if (rc == -EBUSY)
 301                return;
 302
 303        dma_free_coherent(&phba->ctrl.pdev->dev, cmd->size, cmd->va, cmd->dma);
 304}
 305
 306static void __beiscsi_eq_delay_compl(struct beiscsi_hba *phba, unsigned int tag)
 307{
 308        struct be_dma_mem *tag_mem;
 309
 310        /* status is ignored */
 311        __beiscsi_mcc_compl_status(phba, tag, NULL, NULL);
 312        tag_mem = &phba->ctrl.ptag_state[tag].tag_mem_state;
 313        if (tag_mem->size) {
 314                dma_free_coherent(&phba->pcidev->dev, tag_mem->size,
 315                                    tag_mem->va, tag_mem->dma);
 316                tag_mem->size = 0;
 317        }
 318}
 319
 320int beiscsi_modify_eq_delay(struct beiscsi_hba *phba,
 321                            struct be_set_eqd *set_eqd, int num)
 322{
 323        struct be_cmd_req_modify_eq_delay *req;
 324        struct be_dma_mem nonemb_cmd;
 325        int i, rc;
 326
 327        rc = beiscsi_prep_nemb_cmd(phba, &nonemb_cmd, CMD_SUBSYSTEM_COMMON,
 328                        OPCODE_COMMON_MODIFY_EQ_DELAY, sizeof(*req));
 329        if (rc)
 330                return rc;
 331
 332        req = nonemb_cmd.va;
 333        req->num_eq = cpu_to_le32(num);
 334        for (i = 0; i < num; i++) {
 335                req->delay[i].eq_id = cpu_to_le32(set_eqd[i].eq_id);
 336                req->delay[i].phase = 0;
 337                req->delay[i].delay_multiplier =
 338                                cpu_to_le32(set_eqd[i].delay_multiplier);
 339        }
 340
 341        rc = beiscsi_exec_nemb_cmd(phba, &nonemb_cmd, __beiscsi_eq_delay_compl,
 342                                   NULL, 0);
 343        if (rc) {
 344                /*
 345                 * Only free on failure. Async cmds are handled like -EBUSY
 346                 * where it's handled for us.
 347                 */
 348                beiscsi_free_nemb_cmd(phba, &nonemb_cmd, rc);
 349        }
 350        return rc;
 351}
 352
 353/**
 354 * beiscsi_get_initiator_name - read initiator name from flash
 355 * @phba: device priv structure
 356 * @name: buffer pointer
 357 * @cfg: fetch user configured
 358 *
 359 */
 360int beiscsi_get_initiator_name(struct beiscsi_hba *phba, char *name, bool cfg)
 361{
 362        struct be_dma_mem nonemb_cmd;
 363        struct be_cmd_hba_name resp;
 364        struct be_cmd_hba_name *req;
 365        int rc;
 366
 367        rc = beiscsi_prep_nemb_cmd(phba, &nonemb_cmd, CMD_SUBSYSTEM_ISCSI_INI,
 368                        OPCODE_ISCSI_INI_CFG_GET_HBA_NAME, sizeof(resp));
 369        if (rc)
 370                return rc;
 371
 372        req = nonemb_cmd.va;
 373        if (cfg)
 374                req->hdr.version = 1;
 375        rc = beiscsi_exec_nemb_cmd(phba, &nonemb_cmd, NULL,
 376                                   &resp, sizeof(resp));
 377        beiscsi_free_nemb_cmd(phba, &nonemb_cmd, rc);
 378        if (rc) {
 379                beiscsi_log(phba, KERN_ERR,
 380                            BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX,
 381                            "BS_%d : Initiator Name MBX Failed\n");
 382                return rc;
 383        }
 384        rc = sprintf(name, "%s\n", resp.initiator_name);
 385        return rc;
 386}
 387
 388unsigned int beiscsi_if_get_handle(struct beiscsi_hba *phba)
 389{
 390        struct be_ctrl_info *ctrl = &phba->ctrl;
 391        struct be_mcc_wrb *wrb;
 392        struct be_cmd_get_all_if_id_req *req;
 393        struct be_cmd_get_all_if_id_req *pbe_allid;
 394        unsigned int tag;
 395        int status = 0;
 396
 397        if (mutex_lock_interruptible(&ctrl->mbox_lock))
 398                return -EINTR;
 399        wrb = alloc_mcc_wrb(phba, &tag);
 400        if (!wrb) {
 401                mutex_unlock(&ctrl->mbox_lock);
 402                return -ENOMEM;
 403        }
 404
 405        req = embedded_payload(wrb);
 406        be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
 407        be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI,
 408                           OPCODE_COMMON_ISCSI_NTWK_GET_ALL_IF_ID,
 409                           sizeof(*req));
 410        be_mcc_notify(phba, tag);
 411        mutex_unlock(&ctrl->mbox_lock);
 412
 413        status = beiscsi_mccq_compl_wait(phba, tag, &wrb, NULL);
 414        if (status) {
 415                beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG,
 416                            "BG_%d : %s failed: %d\n", __func__, status);
 417                return -EBUSY;
 418        }
 419
 420        pbe_allid = embedded_payload(wrb);
 421        /* we now support only one interface per function */
 422        phba->interface_handle = pbe_allid->if_hndl_list[0];
 423
 424        return status;
 425}
 426
 427static inline bool beiscsi_if_zero_ip(u8 *ip, u32 ip_type)
 428{
 429        u32 len;
 430
 431        len = (ip_type < BEISCSI_IP_TYPE_V6) ? IP_V4_LEN : IP_V6_LEN;
 432        while (len && !ip[len - 1])
 433                len--;
 434        return (len == 0);
 435}
 436
 437static int beiscsi_if_mod_gw(struct beiscsi_hba *phba,
 438                             u32 action, u32 ip_type, u8 *gw)
 439{
 440        struct be_cmd_set_def_gateway_req *req;
 441        struct be_dma_mem nonemb_cmd;
 442        int rt_val;
 443
 444        rt_val = beiscsi_prep_nemb_cmd(phba, &nonemb_cmd, CMD_SUBSYSTEM_ISCSI,
 445                        OPCODE_COMMON_ISCSI_NTWK_MODIFY_DEFAULT_GATEWAY,
 446                        sizeof(*req));
 447        if (rt_val)
 448                return rt_val;
 449
 450        req = nonemb_cmd.va;
 451        req->action = action;
 452        req->ip_addr.ip_type = ip_type;
 453        memcpy(req->ip_addr.addr, gw,
 454               (ip_type < BEISCSI_IP_TYPE_V6) ? IP_V4_LEN : IP_V6_LEN);
 455        rt_val = beiscsi_exec_nemb_cmd(phba, &nonemb_cmd, NULL, NULL, 0);
 456        beiscsi_free_nemb_cmd(phba, &nonemb_cmd, rt_val);
 457        return rt_val;
 458}
 459
 460int beiscsi_if_set_gw(struct beiscsi_hba *phba, u32 ip_type, u8 *gw)
 461{
 462        struct be_cmd_get_def_gateway_resp gw_resp;
 463        int rt_val;
 464
 465        memset(&gw_resp, 0, sizeof(gw_resp));
 466        rt_val = beiscsi_if_get_gw(phba, ip_type, &gw_resp);
 467        if (rt_val) {
 468                beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG,
 469                            "BG_%d : Failed to Get Gateway Addr\n");
 470                return rt_val;
 471        }
 472
 473        if (!beiscsi_if_zero_ip(gw_resp.ip_addr.addr, ip_type)) {
 474                rt_val = beiscsi_if_mod_gw(phba, IP_ACTION_DEL, ip_type,
 475                                           gw_resp.ip_addr.addr);
 476                if (rt_val) {
 477                        beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG,
 478                                    "BG_%d : Failed to clear Gateway Addr Set\n");
 479                        return rt_val;
 480                }
 481        }
 482
 483        rt_val = beiscsi_if_mod_gw(phba, IP_ACTION_ADD, ip_type, gw);
 484        if (rt_val)
 485                beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG,
 486                            "BG_%d : Failed to Set Gateway Addr\n");
 487
 488        return rt_val;
 489}
 490
 491int beiscsi_if_get_gw(struct beiscsi_hba *phba, u32 ip_type,
 492                      struct be_cmd_get_def_gateway_resp *resp)
 493{
 494        struct be_cmd_get_def_gateway_req *req;
 495        struct be_dma_mem nonemb_cmd;
 496        int rc;
 497
 498        rc = beiscsi_prep_nemb_cmd(phba, &nonemb_cmd, CMD_SUBSYSTEM_ISCSI,
 499                        OPCODE_COMMON_ISCSI_NTWK_GET_DEFAULT_GATEWAY,
 500                        sizeof(*resp));
 501        if (rc)
 502                return rc;
 503
 504        req = nonemb_cmd.va;
 505        req->ip_type = ip_type;
 506
 507        rc = beiscsi_exec_nemb_cmd(phba, &nonemb_cmd, NULL, resp,
 508                                   sizeof(*resp));
 509        beiscsi_free_nemb_cmd(phba, &nonemb_cmd, rc);
 510        return rc;
 511}
 512
 513static int
 514beiscsi_if_clr_ip(struct beiscsi_hba *phba,
 515                  struct be_cmd_get_if_info_resp *if_info)
 516{
 517        struct be_cmd_set_ip_addr_req *req;
 518        struct be_dma_mem nonemb_cmd;
 519        int rc;
 520
 521        rc = beiscsi_prep_nemb_cmd(phba, &nonemb_cmd, CMD_SUBSYSTEM_ISCSI,
 522                        OPCODE_COMMON_ISCSI_NTWK_MODIFY_IP_ADDR,
 523                        sizeof(*req));
 524        if (rc)
 525                return rc;
 526
 527        req = nonemb_cmd.va;
 528        req->ip_params.record_entry_count = 1;
 529        req->ip_params.ip_record.action = IP_ACTION_DEL;
 530        req->ip_params.ip_record.interface_hndl =
 531                phba->interface_handle;
 532        req->ip_params.ip_record.ip_addr.size_of_structure =
 533                sizeof(struct be_ip_addr_subnet_format);
 534        req->ip_params.ip_record.ip_addr.ip_type = if_info->ip_addr.ip_type;
 535        memcpy(req->ip_params.ip_record.ip_addr.addr,
 536               if_info->ip_addr.addr,
 537               sizeof(if_info->ip_addr.addr));
 538        memcpy(req->ip_params.ip_record.ip_addr.subnet_mask,
 539               if_info->ip_addr.subnet_mask,
 540               sizeof(if_info->ip_addr.subnet_mask));
 541        rc = beiscsi_exec_nemb_cmd(phba, &nonemb_cmd, NULL, NULL, 0);
 542        if (rc < 0 || req->ip_params.ip_record.status) {
 543                beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG,
 544                            "BG_%d : failed to clear IP: rc %d status %d\n",
 545                            rc, req->ip_params.ip_record.status);
 546        }
 547        beiscsi_free_nemb_cmd(phba, &nonemb_cmd, rc);
 548        return rc;
 549}
 550
 551static int
 552beiscsi_if_set_ip(struct beiscsi_hba *phba, u8 *ip,
 553                  u8 *subnet, u32 ip_type)
 554{
 555        struct be_cmd_set_ip_addr_req *req;
 556        struct be_dma_mem nonemb_cmd;
 557        uint32_t ip_len;
 558        int rc;
 559
 560        rc = beiscsi_prep_nemb_cmd(phba, &nonemb_cmd, CMD_SUBSYSTEM_ISCSI,
 561                        OPCODE_COMMON_ISCSI_NTWK_MODIFY_IP_ADDR,
 562                        sizeof(*req));
 563        if (rc)
 564                return rc;
 565
 566        req = nonemb_cmd.va;
 567        req->ip_params.record_entry_count = 1;
 568        req->ip_params.ip_record.action = IP_ACTION_ADD;
 569        req->ip_params.ip_record.interface_hndl =
 570                phba->interface_handle;
 571        req->ip_params.ip_record.ip_addr.size_of_structure =
 572                sizeof(struct be_ip_addr_subnet_format);
 573        req->ip_params.ip_record.ip_addr.ip_type = ip_type;
 574        ip_len = (ip_type < BEISCSI_IP_TYPE_V6) ? IP_V4_LEN : IP_V6_LEN;
 575        memcpy(req->ip_params.ip_record.ip_addr.addr, ip, ip_len);
 576        if (subnet)
 577                memcpy(req->ip_params.ip_record.ip_addr.subnet_mask,
 578                       subnet, ip_len);
 579
 580        rc = beiscsi_exec_nemb_cmd(phba, &nonemb_cmd, NULL, NULL, 0);
 581        /**
 582         * In some cases, host needs to look into individual record status
 583         * even though FW reported success for that IOCTL.
 584         */
 585        if (rc < 0 || req->ip_params.ip_record.status) {
 586                __beiscsi_log(phba, KERN_ERR,
 587                            "BG_%d : failed to set IP: rc %d status %d\n",
 588                            rc, req->ip_params.ip_record.status);
 589                if (req->ip_params.ip_record.status)
 590                        rc = -EINVAL;
 591        }
 592        beiscsi_free_nemb_cmd(phba, &nonemb_cmd, rc);
 593        return rc;
 594}
 595
 596int beiscsi_if_en_static(struct beiscsi_hba *phba, u32 ip_type,
 597                         u8 *ip, u8 *subnet)
 598{
 599        struct be_cmd_get_if_info_resp *if_info;
 600        struct be_cmd_rel_dhcp_req *reldhcp;
 601        struct be_dma_mem nonemb_cmd;
 602        int rc;
 603
 604        rc = beiscsi_if_get_info(phba, ip_type, &if_info);
 605        if (rc)
 606                return rc;
 607
 608        if (if_info->dhcp_state) {
 609                rc = beiscsi_prep_nemb_cmd(phba, &nonemb_cmd,
 610                                CMD_SUBSYSTEM_ISCSI,
 611                                OPCODE_COMMON_ISCSI_NTWK_REL_STATELESS_IP_ADDR,
 612                                sizeof(*reldhcp));
 613                if (rc)
 614                        goto exit;
 615
 616                reldhcp = nonemb_cmd.va;
 617                reldhcp->interface_hndl = phba->interface_handle;
 618                reldhcp->ip_type = ip_type;
 619                rc = beiscsi_exec_nemb_cmd(phba, &nonemb_cmd, NULL, NULL, 0);
 620                beiscsi_free_nemb_cmd(phba, &nonemb_cmd, rc);
 621                if (rc < 0) {
 622                        beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG,
 623                                    "BG_%d : failed to release existing DHCP: %d\n",
 624                                    rc);
 625                        goto exit;
 626                }
 627        }
 628
 629        /* first delete any IP set */
 630        if (!beiscsi_if_zero_ip(if_info->ip_addr.addr, ip_type)) {
 631                rc = beiscsi_if_clr_ip(phba, if_info);
 632                if (rc)
 633                        goto exit;
 634        }
 635
 636        /* if ip == NULL then this is called just to release DHCP IP */
 637        if (ip)
 638                rc = beiscsi_if_set_ip(phba, ip, subnet, ip_type);
 639exit:
 640        kfree(if_info);
 641        return rc;
 642}
 643
 644int beiscsi_if_en_dhcp(struct beiscsi_hba *phba, u32 ip_type)
 645{
 646        struct be_cmd_get_def_gateway_resp gw_resp;
 647        struct be_cmd_get_if_info_resp *if_info;
 648        struct be_cmd_set_dhcp_req *dhcpreq;
 649        struct be_dma_mem nonemb_cmd;
 650        u8 *gw;
 651        int rc;
 652
 653        rc = beiscsi_if_get_info(phba, ip_type, &if_info);
 654        if (rc)
 655                return rc;
 656
 657        if (if_info->dhcp_state) {
 658                beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG,
 659                                "BG_%d : DHCP Already Enabled\n");
 660                goto exit;
 661        }
 662
 663        /* first delete any IP set */
 664        if (!beiscsi_if_zero_ip(if_info->ip_addr.addr, ip_type)) {
 665                rc = beiscsi_if_clr_ip(phba, if_info);
 666                if (rc)
 667                        goto exit;
 668        }
 669
 670        /* delete gateway settings if mode change is to DHCP */
 671        memset(&gw_resp, 0, sizeof(gw_resp));
 672        /* use ip_type provided in if_info */
 673        rc = beiscsi_if_get_gw(phba, if_info->ip_addr.ip_type, &gw_resp);
 674        if (rc) {
 675                beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG,
 676                            "BG_%d : Failed to Get Gateway Addr\n");
 677                goto exit;
 678        }
 679        gw = (u8 *)&gw_resp.ip_addr.addr;
 680        if (!beiscsi_if_zero_ip(gw, if_info->ip_addr.ip_type)) {
 681                rc = beiscsi_if_mod_gw(phba, IP_ACTION_DEL,
 682                                       if_info->ip_addr.ip_type, gw);
 683                if (rc) {
 684                        beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG,
 685                                    "BG_%d : Failed to clear Gateway Addr Set\n");
 686                        goto exit;
 687                }
 688        }
 689
 690        rc = beiscsi_prep_nemb_cmd(phba, &nonemb_cmd, CMD_SUBSYSTEM_ISCSI,
 691                        OPCODE_COMMON_ISCSI_NTWK_CONFIG_STATELESS_IP_ADDR,
 692                        sizeof(*dhcpreq));
 693        if (rc)
 694                goto exit;
 695
 696        dhcpreq = nonemb_cmd.va;
 697        dhcpreq->flags = 1; /* 1 - blocking; 0 - non-blocking */
 698        dhcpreq->retry_count = 1;
 699        dhcpreq->interface_hndl = phba->interface_handle;
 700        dhcpreq->ip_type = ip_type;
 701        rc = beiscsi_exec_nemb_cmd(phba, &nonemb_cmd, NULL, NULL, 0);
 702        beiscsi_free_nemb_cmd(phba, &nonemb_cmd, rc);
 703exit:
 704        kfree(if_info);
 705        return rc;
 706}
 707
 708/**
 709 * beiscsi_if_set_vlan()- Issue and wait for CMD completion
 710 * @phba: device private structure instance
 711 * @vlan_tag: VLAN tag
 712 *
 713 * Issue the MBX Cmd and wait for the completion of the
 714 * command.
 715 *
 716 * returns
 717 *      Success: 0
 718 *      Failure: Non-Xero Value
 719 **/
 720int beiscsi_if_set_vlan(struct beiscsi_hba *phba, uint16_t vlan_tag)
 721{
 722        int rc;
 723        unsigned int tag;
 724
 725        tag = be_cmd_set_vlan(phba, vlan_tag);
 726        if (!tag) {
 727                beiscsi_log(phba, KERN_ERR,
 728                            (BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX),
 729                            "BG_%d : VLAN Setting Failed\n");
 730                return -EBUSY;
 731        }
 732
 733        rc = beiscsi_mccq_compl_wait(phba, tag, NULL, NULL);
 734        if (rc) {
 735                beiscsi_log(phba, KERN_ERR,
 736                            (BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX),
 737                            "BS_%d : VLAN MBX Cmd Failed\n");
 738                return rc;
 739        }
 740        return rc;
 741}
 742
 743
 744int beiscsi_if_get_info(struct beiscsi_hba *phba, int ip_type,
 745                        struct be_cmd_get_if_info_resp **if_info)
 746{
 747        struct be_cmd_get_if_info_req *req;
 748        struct be_dma_mem nonemb_cmd;
 749        uint32_t ioctl_size = sizeof(struct be_cmd_get_if_info_resp);
 750        int rc;
 751
 752        rc = beiscsi_if_get_handle(phba);
 753        if (rc)
 754                return rc;
 755
 756        do {
 757                rc = beiscsi_prep_nemb_cmd(phba, &nonemb_cmd,
 758                                CMD_SUBSYSTEM_ISCSI,
 759                                OPCODE_COMMON_ISCSI_NTWK_GET_IF_INFO,
 760                                ioctl_size);
 761                if (rc)
 762                        return rc;
 763
 764                req = nonemb_cmd.va;
 765                req->interface_hndl = phba->interface_handle;
 766                req->ip_type = ip_type;
 767
 768                /* Allocate memory for if_info */
 769                *if_info = kzalloc(ioctl_size, GFP_KERNEL);
 770                if (!*if_info) {
 771                        beiscsi_log(phba, KERN_ERR,
 772                                    BEISCSI_LOG_INIT | BEISCSI_LOG_CONFIG,
 773                                    "BG_%d : Memory Allocation Failure\n");
 774
 775                                beiscsi_free_nemb_cmd(phba, &nonemb_cmd,
 776                                                      -ENOMEM);
 777                                return -ENOMEM;
 778                }
 779
 780                rc =  beiscsi_exec_nemb_cmd(phba, &nonemb_cmd, NULL, *if_info,
 781                                            ioctl_size);
 782
 783                /* Check if the error is because of Insufficent_Buffer */
 784                if (rc == -EAGAIN) {
 785
 786                        /* Get the new memory size */
 787                        ioctl_size = ((struct be_cmd_resp_hdr *)
 788                                      nonemb_cmd.va)->actual_resp_len;
 789                        ioctl_size += sizeof(struct be_cmd_req_hdr);
 790
 791                        beiscsi_free_nemb_cmd(phba, &nonemb_cmd, rc);
 792                        /* Free the virtual memory */
 793                        kfree(*if_info);
 794                } else {
 795                        beiscsi_free_nemb_cmd(phba, &nonemb_cmd, rc);
 796                        break;
 797                }
 798        } while (true);
 799        return rc;
 800}
 801
 802int mgmt_get_nic_conf(struct beiscsi_hba *phba,
 803                      struct be_cmd_get_nic_conf_resp *nic)
 804{
 805        struct be_dma_mem nonemb_cmd;
 806        int rc;
 807
 808        rc = beiscsi_prep_nemb_cmd(phba, &nonemb_cmd, CMD_SUBSYSTEM_ISCSI,
 809                        OPCODE_COMMON_ISCSI_NTWK_GET_NIC_CONFIG,
 810                        sizeof(*nic));
 811        if (rc)
 812                return rc;
 813
 814        rc = beiscsi_exec_nemb_cmd(phba, &nonemb_cmd, NULL, nic, sizeof(*nic));
 815        beiscsi_free_nemb_cmd(phba, &nonemb_cmd, rc);
 816        return rc;
 817}
 818
 819static void beiscsi_boot_process_compl(struct beiscsi_hba *phba,
 820                                       unsigned int tag)
 821{
 822        struct be_cmd_get_boot_target_resp *boot_resp;
 823        struct be_cmd_resp_logout_fw_sess *logo_resp;
 824        struct be_cmd_get_session_resp *sess_resp;
 825        struct be_mcc_wrb *wrb;
 826        struct boot_struct *bs;
 827        int boot_work, status;
 828
 829        if (!test_bit(BEISCSI_HBA_BOOT_WORK, &phba->state)) {
 830                __beiscsi_log(phba, KERN_ERR,
 831                              "BG_%d : %s no boot work %lx\n",
 832                              __func__, phba->state);
 833                return;
 834        }
 835
 836        if (phba->boot_struct.tag != tag) {
 837                __beiscsi_log(phba, KERN_ERR,
 838                              "BG_%d : %s tag mismatch %d:%d\n",
 839                              __func__, tag, phba->boot_struct.tag);
 840                return;
 841        }
 842        bs = &phba->boot_struct;
 843        boot_work = 1;
 844        status = 0;
 845        switch (bs->action) {
 846        case BEISCSI_BOOT_REOPEN_SESS:
 847                status = __beiscsi_mcc_compl_status(phba, tag, NULL, NULL);
 848                if (!status)
 849                        bs->action = BEISCSI_BOOT_GET_SHANDLE;
 850                else
 851                        bs->retry--;
 852                break;
 853        case BEISCSI_BOOT_GET_SHANDLE:
 854                status = __beiscsi_mcc_compl_status(phba, tag, &wrb, NULL);
 855                if (!status) {
 856                        boot_resp = embedded_payload(wrb);
 857                        bs->s_handle = boot_resp->boot_session_handle;
 858                }
 859                if (bs->s_handle == BE_BOOT_INVALID_SHANDLE) {
 860                        bs->action = BEISCSI_BOOT_REOPEN_SESS;
 861                        bs->retry--;
 862                } else {
 863                        bs->action = BEISCSI_BOOT_GET_SINFO;
 864                }
 865                break;
 866        case BEISCSI_BOOT_GET_SINFO:
 867                status = __beiscsi_mcc_compl_status(phba, tag, NULL,
 868                                                    &bs->nonemb_cmd);
 869                if (!status) {
 870                        sess_resp = bs->nonemb_cmd.va;
 871                        memcpy(&bs->boot_sess, &sess_resp->session_info,
 872                               sizeof(struct mgmt_session_info));
 873                        bs->action = BEISCSI_BOOT_LOGOUT_SESS;
 874                } else {
 875                        __beiscsi_log(phba, KERN_ERR,
 876                                      "BG_%d : get boot session info error : 0x%x\n",
 877                                      status);
 878                        boot_work = 0;
 879                }
 880                dma_free_coherent(&phba->ctrl.pdev->dev, bs->nonemb_cmd.size,
 881                                    bs->nonemb_cmd.va, bs->nonemb_cmd.dma);
 882                bs->nonemb_cmd.va = NULL;
 883                break;
 884        case BEISCSI_BOOT_LOGOUT_SESS:
 885                status = __beiscsi_mcc_compl_status(phba, tag, &wrb, NULL);
 886                if (!status) {
 887                        logo_resp = embedded_payload(wrb);
 888                        if (logo_resp->session_status != BE_SESS_STATUS_CLOSE) {
 889                                __beiscsi_log(phba, KERN_ERR,
 890                                              "BG_%d : FW boot session logout error : 0x%x\n",
 891                                              logo_resp->session_status);
 892                        }
 893                }
 894                /* continue to create boot_kset even if logout failed? */
 895                bs->action = BEISCSI_BOOT_CREATE_KSET;
 896                break;
 897        default:
 898                break;
 899        }
 900
 901        /* clear the tag so no other completion matches this tag */
 902        bs->tag = 0;
 903        if (!bs->retry) {
 904                boot_work = 0;
 905                __beiscsi_log(phba, KERN_ERR,
 906                              "BG_%d : failed to setup boot target: status %d action %d\n",
 907                              status, bs->action);
 908        }
 909        if (!boot_work) {
 910                /* wait for next event to start boot_work */
 911                clear_bit(BEISCSI_HBA_BOOT_WORK, &phba->state);
 912                return;
 913        }
 914        schedule_work(&phba->boot_work);
 915}
 916
 917/**
 918 * beiscsi_boot_logout_sess()- Logout from boot FW session
 919 * @phba: Device priv structure instance
 920 *
 921 * return
 922 *      the TAG used for MBOX Command
 923 *
 924 */
 925unsigned int beiscsi_boot_logout_sess(struct beiscsi_hba *phba)
 926{
 927        struct be_ctrl_info *ctrl = &phba->ctrl;
 928        struct be_mcc_wrb *wrb;
 929        struct be_cmd_req_logout_fw_sess *req;
 930        unsigned int tag;
 931
 932        mutex_lock(&ctrl->mbox_lock);
 933        wrb = alloc_mcc_wrb(phba, &tag);
 934        if (!wrb) {
 935                mutex_unlock(&ctrl->mbox_lock);
 936                return 0;
 937        }
 938
 939        req = embedded_payload(wrb);
 940        be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
 941        be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI_INI,
 942                           OPCODE_ISCSI_INI_SESSION_LOGOUT_TARGET,
 943                           sizeof(struct be_cmd_req_logout_fw_sess));
 944        /* Use the session handle copied into boot_sess */
 945        req->session_handle = phba->boot_struct.boot_sess.session_handle;
 946
 947        phba->boot_struct.tag = tag;
 948        set_bit(MCC_TAG_STATE_ASYNC, &ctrl->ptag_state[tag].tag_state);
 949        ctrl->ptag_state[tag].cbfn = beiscsi_boot_process_compl;
 950
 951        be_mcc_notify(phba, tag);
 952        mutex_unlock(&ctrl->mbox_lock);
 953
 954        return tag;
 955}
 956/**
 957 * beiscsi_boot_reopen_sess()- Reopen boot session
 958 * @phba: Device priv structure instance
 959 *
 960 * return
 961 *      the TAG used for MBOX Command
 962 *
 963 **/
 964unsigned int beiscsi_boot_reopen_sess(struct beiscsi_hba *phba)
 965{
 966        struct be_ctrl_info *ctrl = &phba->ctrl;
 967        struct be_mcc_wrb *wrb;
 968        struct be_cmd_reopen_session_req *req;
 969        unsigned int tag;
 970
 971        mutex_lock(&ctrl->mbox_lock);
 972        wrb = alloc_mcc_wrb(phba, &tag);
 973        if (!wrb) {
 974                mutex_unlock(&ctrl->mbox_lock);
 975                return 0;
 976        }
 977
 978        req = embedded_payload(wrb);
 979        be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
 980        be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI_INI,
 981                           OPCODE_ISCSI_INI_DRIVER_REOPEN_ALL_SESSIONS,
 982                           sizeof(struct be_cmd_reopen_session_resp));
 983        req->reopen_type = BE_REOPEN_BOOT_SESSIONS;
 984        req->session_handle = BE_BOOT_INVALID_SHANDLE;
 985
 986        phba->boot_struct.tag = tag;
 987        set_bit(MCC_TAG_STATE_ASYNC, &ctrl->ptag_state[tag].tag_state);
 988        ctrl->ptag_state[tag].cbfn = beiscsi_boot_process_compl;
 989
 990        be_mcc_notify(phba, tag);
 991        mutex_unlock(&ctrl->mbox_lock);
 992        return tag;
 993}
 994
 995
 996/**
 997 * beiscsi_boot_get_sinfo()- Get boot session info
 998 * @phba: device priv structure instance
 999 *
1000 * Fetches the boot_struct.s_handle info from FW.
1001 * return
1002 *      the TAG used for MBOX Command
1003 *
1004 **/
1005unsigned int beiscsi_boot_get_sinfo(struct beiscsi_hba *phba)
1006{
1007        struct be_ctrl_info *ctrl = &phba->ctrl;
1008        struct be_cmd_get_session_req *req;
1009        struct be_dma_mem *nonemb_cmd;
1010        struct be_mcc_wrb *wrb;
1011        struct be_sge *sge;
1012        unsigned int tag;
1013
1014        mutex_lock(&ctrl->mbox_lock);
1015        wrb = alloc_mcc_wrb(phba, &tag);
1016        if (!wrb) {
1017                mutex_unlock(&ctrl->mbox_lock);
1018                return 0;
1019        }
1020
1021        nonemb_cmd = &phba->boot_struct.nonemb_cmd;
1022        nonemb_cmd->size = sizeof(struct be_cmd_get_session_resp);
1023        nonemb_cmd->va = dma_alloc_coherent(&phba->ctrl.pdev->dev,
1024                                              nonemb_cmd->size,
1025                                              &nonemb_cmd->dma,
1026                                              GFP_KERNEL);
1027        if (!nonemb_cmd->va) {
1028                mutex_unlock(&ctrl->mbox_lock);
1029                return 0;
1030        }
1031
1032        req = nonemb_cmd->va;
1033        memset(req, 0, sizeof(*req));
1034        sge = nonembedded_sgl(wrb);
1035        be_wrb_hdr_prepare(wrb, sizeof(*req), false, 1);
1036        be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI_INI,
1037                           OPCODE_ISCSI_INI_SESSION_GET_A_SESSION,
1038                           sizeof(struct be_cmd_get_session_resp));
1039        req->session_handle = phba->boot_struct.s_handle;
1040        sge->pa_hi = cpu_to_le32(upper_32_bits(nonemb_cmd->dma));
1041        sge->pa_lo = cpu_to_le32(nonemb_cmd->dma & 0xFFFFFFFF);
1042        sge->len = cpu_to_le32(nonemb_cmd->size);
1043
1044        phba->boot_struct.tag = tag;
1045        set_bit(MCC_TAG_STATE_ASYNC, &ctrl->ptag_state[tag].tag_state);
1046        ctrl->ptag_state[tag].cbfn = beiscsi_boot_process_compl;
1047
1048        be_mcc_notify(phba, tag);
1049        mutex_unlock(&ctrl->mbox_lock);
1050        return tag;
1051}
1052
1053unsigned int __beiscsi_boot_get_shandle(struct beiscsi_hba *phba, int async)
1054{
1055        struct be_ctrl_info *ctrl = &phba->ctrl;
1056        struct be_mcc_wrb *wrb;
1057        struct be_cmd_get_boot_target_req *req;
1058        unsigned int tag;
1059
1060        mutex_lock(&ctrl->mbox_lock);
1061        wrb = alloc_mcc_wrb(phba, &tag);
1062        if (!wrb) {
1063                mutex_unlock(&ctrl->mbox_lock);
1064                return 0;
1065        }
1066
1067        req = embedded_payload(wrb);
1068        be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
1069        be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI_INI,
1070                           OPCODE_ISCSI_INI_BOOT_GET_BOOT_TARGET,
1071                           sizeof(struct be_cmd_get_boot_target_resp));
1072
1073        if (async) {
1074                phba->boot_struct.tag = tag;
1075                set_bit(MCC_TAG_STATE_ASYNC, &ctrl->ptag_state[tag].tag_state);
1076                ctrl->ptag_state[tag].cbfn = beiscsi_boot_process_compl;
1077        }
1078
1079        be_mcc_notify(phba, tag);
1080        mutex_unlock(&ctrl->mbox_lock);
1081        return tag;
1082}
1083
1084/**
1085 * beiscsi_boot_get_shandle()- Get boot session handle
1086 * @phba: device priv structure instance
1087 * @s_handle: session handle returned for boot session.
1088 *
1089 * return
1090 *      Success: 1
1091 *      Failure: negative
1092 *
1093 **/
1094int beiscsi_boot_get_shandle(struct beiscsi_hba *phba, unsigned int *s_handle)
1095{
1096        struct be_cmd_get_boot_target_resp *boot_resp;
1097        struct be_mcc_wrb *wrb;
1098        unsigned int tag;
1099        int rc;
1100
1101        *s_handle = BE_BOOT_INVALID_SHANDLE;
1102        /* get configured boot session count and handle */
1103        tag = __beiscsi_boot_get_shandle(phba, 0);
1104        if (!tag) {
1105                beiscsi_log(phba, KERN_ERR,
1106                            BEISCSI_LOG_CONFIG | BEISCSI_LOG_INIT,
1107                            "BG_%d : Getting Boot Target Info Failed\n");
1108                return -EAGAIN;
1109        }
1110
1111        rc = beiscsi_mccq_compl_wait(phba, tag, &wrb, NULL);
1112        if (rc) {
1113                beiscsi_log(phba, KERN_ERR,
1114                            BEISCSI_LOG_INIT | BEISCSI_LOG_CONFIG,
1115                            "BG_%d : MBX CMD get_boot_target Failed\n");
1116                return -EBUSY;
1117        }
1118
1119        boot_resp = embedded_payload(wrb);
1120        /* check if there are any boot targets configured */
1121        if (!boot_resp->boot_session_count) {
1122                __beiscsi_log(phba, KERN_INFO,
1123                              "BG_%d : No boot targets configured\n");
1124                return -ENXIO;
1125        }
1126
1127        /* only if FW has logged in to the boot target, s_handle is valid */
1128        *s_handle = boot_resp->boot_session_handle;
1129        return 1;
1130}
1131
1132/**
1133 * beiscsi_drvr_ver_disp()- Display the driver Name and Version
1134 * @dev: ptr to device not used.
1135 * @attr: device attribute, not used.
1136 * @buf: contains formatted text driver name and version
1137 *
1138 * return
1139 * size of the formatted string
1140 **/
1141ssize_t
1142beiscsi_drvr_ver_disp(struct device *dev, struct device_attribute *attr,
1143                       char *buf)
1144{
1145        return snprintf(buf, PAGE_SIZE, BE_NAME "\n");
1146}
1147
1148/**
1149 * beiscsi_fw_ver_disp()- Display Firmware Version
1150 * @dev: ptr to device not used.
1151 * @attr: device attribute, not used.
1152 * @buf: contains formatted text Firmware version
1153 *
1154 * return
1155 * size of the formatted string
1156 **/
1157ssize_t
1158beiscsi_fw_ver_disp(struct device *dev, struct device_attribute *attr,
1159                     char *buf)
1160{
1161        struct Scsi_Host *shost = class_to_shost(dev);
1162        struct beiscsi_hba *phba = iscsi_host_priv(shost);
1163
1164        return snprintf(buf, PAGE_SIZE, "%s\n", phba->fw_ver_str);
1165}
1166
1167/**
1168 * beiscsi_active_session_disp()- Display Sessions Active
1169 * @dev: ptr to device not used.
1170 * @attr: device attribute, not used.
1171 * @buf: contains formatted text Session Count
1172 *
1173 * return
1174 * size of the formatted string
1175 **/
1176ssize_t
1177beiscsi_active_session_disp(struct device *dev, struct device_attribute *attr,
1178                         char *buf)
1179{
1180        struct Scsi_Host *shost = class_to_shost(dev);
1181        struct beiscsi_hba *phba = iscsi_host_priv(shost);
1182        uint16_t avlbl_cids = 0, ulp_num, len = 0, total_cids = 0;
1183
1184        for (ulp_num = 0; ulp_num < BEISCSI_ULP_COUNT; ulp_num++) {
1185                if (test_bit(ulp_num, (void *)&phba->fw_config.ulp_supported)) {
1186                        avlbl_cids = BEISCSI_ULP_AVLBL_CID(phba, ulp_num);
1187                        total_cids = BEISCSI_GET_CID_COUNT(phba, ulp_num);
1188                        len += scnprintf(buf+len, PAGE_SIZE - len,
1189                                         "ULP%d : %d\n", ulp_num,
1190                                         (total_cids - avlbl_cids));
1191                } else
1192                        len += scnprintf(buf+len, PAGE_SIZE - len,
1193                                         "ULP%d : %d\n", ulp_num, 0);
1194        }
1195
1196        return len;
1197}
1198
1199/**
1200 * beiscsi_free_session_disp()- Display Avaliable Session
1201 * @dev: ptr to device not used.
1202 * @attr: device attribute, not used.
1203 * @buf: contains formatted text Session Count
1204 *
1205 * return
1206 * size of the formatted string
1207 **/
1208ssize_t
1209beiscsi_free_session_disp(struct device *dev, struct device_attribute *attr,
1210                       char *buf)
1211{
1212        struct Scsi_Host *shost = class_to_shost(dev);
1213        struct beiscsi_hba *phba = iscsi_host_priv(shost);
1214        uint16_t ulp_num, len = 0;
1215
1216        for (ulp_num = 0; ulp_num < BEISCSI_ULP_COUNT; ulp_num++) {
1217                if (test_bit(ulp_num, (void *)&phba->fw_config.ulp_supported))
1218                        len += scnprintf(buf+len, PAGE_SIZE - len,
1219                                         "ULP%d : %d\n", ulp_num,
1220                                         BEISCSI_ULP_AVLBL_CID(phba, ulp_num));
1221                else
1222                        len += scnprintf(buf+len, PAGE_SIZE - len,
1223                                         "ULP%d : %d\n", ulp_num, 0);
1224        }
1225
1226        return len;
1227}
1228
1229/**
1230 * beiscsi_adap_family_disp()- Display adapter family.
1231 * @dev: ptr to device to get priv structure
1232 * @attr: device attribute, not used.
1233 * @buf: contains formatted text driver name and version
1234 *
1235 * return
1236 * size of the formatted string
1237 **/
1238ssize_t
1239beiscsi_adap_family_disp(struct device *dev, struct device_attribute *attr,
1240                          char *buf)
1241{
1242        uint16_t dev_id = 0;
1243        struct Scsi_Host *shost = class_to_shost(dev);
1244        struct beiscsi_hba *phba = iscsi_host_priv(shost);
1245
1246        dev_id = phba->pcidev->device;
1247        switch (dev_id) {
1248        case BE_DEVICE_ID1:
1249        case OC_DEVICE_ID1:
1250        case OC_DEVICE_ID2:
1251                return snprintf(buf, PAGE_SIZE,
1252                                "Obsolete/Unsupported BE2 Adapter Family\n");
1253        case BE_DEVICE_ID2:
1254        case OC_DEVICE_ID3:
1255                return snprintf(buf, PAGE_SIZE, "BE3-R Adapter Family\n");
1256        case OC_SKH_ID1:
1257                return snprintf(buf, PAGE_SIZE, "Skyhawk-R Adapter Family\n");
1258        default:
1259                return snprintf(buf, PAGE_SIZE,
1260                                "Unknown Adapter Family: 0x%x\n", dev_id);
1261        }
1262}
1263
1264/**
1265 * beiscsi_phys_port_disp()- Display Physical Port Identifier
1266 * @dev: ptr to device not used.
1267 * @attr: device attribute, not used.
1268 * @buf: contains formatted text port identifier
1269 *
1270 * return
1271 * size of the formatted string
1272 **/
1273ssize_t
1274beiscsi_phys_port_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, "Port Identifier : %u\n",
1281                        phba->fw_config.phys_port);
1282}
1283
1284void beiscsi_offload_cxn_v0(struct beiscsi_offload_params *params,
1285                             struct wrb_handle *pwrb_handle,
1286                             struct be_mem_descriptor *mem_descr,
1287                             struct hwi_wrb_context *pwrb_context)
1288{
1289        struct iscsi_wrb *pwrb = pwrb_handle->pwrb;
1290
1291        AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb,
1292                      max_send_data_segment_length, pwrb,
1293                      params->dw[offsetof(struct amap_beiscsi_offload_params,
1294                      max_send_data_segment_length) / 32]);
1295        AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, type, pwrb,
1296                      BE_TGT_CTX_UPDT_CMD);
1297        AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb,
1298                      first_burst_length,
1299                      pwrb,
1300                      params->dw[offsetof(struct amap_beiscsi_offload_params,
1301                      first_burst_length) / 32]);
1302        AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, erl, pwrb,
1303                      (params->dw[offsetof(struct amap_beiscsi_offload_params,
1304                      erl) / 32] & OFFLD_PARAMS_ERL));
1305        AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, dde, pwrb,
1306                      (params->dw[offsetof(struct amap_beiscsi_offload_params,
1307                       dde) / 32] & OFFLD_PARAMS_DDE) >> 2);
1308        AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, hde, pwrb,
1309                      (params->dw[offsetof(struct amap_beiscsi_offload_params,
1310                      hde) / 32] & OFFLD_PARAMS_HDE) >> 3);
1311        AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, ir2t, pwrb,
1312                      (params->dw[offsetof(struct amap_beiscsi_offload_params,
1313                      ir2t) / 32] & OFFLD_PARAMS_IR2T) >> 4);
1314        AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, imd, pwrb,
1315                      (params->dw[offsetof(struct amap_beiscsi_offload_params,
1316                      imd) / 32] & OFFLD_PARAMS_IMD) >> 5);
1317        AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, stat_sn,
1318                      pwrb,
1319                      (params->dw[offsetof(struct amap_beiscsi_offload_params,
1320                      exp_statsn) / 32] + 1));
1321        AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, wrb_idx,
1322                      pwrb, pwrb_handle->wrb_index);
1323
1324        AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb,
1325                      max_burst_length, pwrb, params->dw[offsetof
1326                      (struct amap_beiscsi_offload_params,
1327                      max_burst_length) / 32]);
1328
1329        AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, ptr2nextwrb,
1330                      pwrb, pwrb_handle->wrb_index);
1331        if (pwrb_context->plast_wrb)
1332                AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb,
1333                              ptr2nextwrb,
1334                              pwrb_context->plast_wrb,
1335                              pwrb_handle->wrb_index);
1336        pwrb_context->plast_wrb = pwrb;
1337
1338        AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb,
1339                      session_state, pwrb, 0);
1340        AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, compltonack,
1341                      pwrb, 1);
1342        AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, notpredblq,
1343                      pwrb, 0);
1344        AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, mode, pwrb,
1345                      0);
1346
1347        mem_descr += ISCSI_MEM_GLOBAL_HEADER;
1348        AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb,
1349                      pad_buffer_addr_hi, pwrb,
1350                      mem_descr->mem_array[0].bus_address.u.a32.address_hi);
1351        AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb,
1352                      pad_buffer_addr_lo, pwrb,
1353                      mem_descr->mem_array[0].bus_address.u.a32.address_lo);
1354}
1355
1356void beiscsi_offload_cxn_v2(struct beiscsi_offload_params *params,
1357                             struct wrb_handle *pwrb_handle,
1358                             struct hwi_wrb_context *pwrb_context)
1359{
1360        struct iscsi_wrb *pwrb = pwrb_handle->pwrb;
1361
1362        AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2,
1363                      max_burst_length, pwrb, params->dw[offsetof
1364                      (struct amap_beiscsi_offload_params,
1365                      max_burst_length) / 32]);
1366        AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2,
1367                      type, pwrb,
1368                      BE_TGT_CTX_UPDT_CMD);
1369        AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2,
1370                      ptr2nextwrb,
1371                      pwrb, pwrb_handle->wrb_index);
1372        if (pwrb_context->plast_wrb)
1373                AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2,
1374                              ptr2nextwrb,
1375                              pwrb_context->plast_wrb,
1376                              pwrb_handle->wrb_index);
1377        pwrb_context->plast_wrb = pwrb;
1378
1379        AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2, wrb_idx,
1380                      pwrb, pwrb_handle->wrb_index);
1381        AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2,
1382                      max_send_data_segment_length, pwrb,
1383                      params->dw[offsetof(struct amap_beiscsi_offload_params,
1384                      max_send_data_segment_length) / 32]);
1385        AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2,
1386                      first_burst_length, pwrb,
1387                      params->dw[offsetof(struct amap_beiscsi_offload_params,
1388                      first_burst_length) / 32]);
1389        AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2,
1390                      max_recv_dataseg_len, pwrb,
1391                      params->dw[offsetof(struct amap_beiscsi_offload_params,
1392                      max_recv_data_segment_length) / 32]);
1393        AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2,
1394                      max_cxns, pwrb, BEISCSI_MAX_CXNS);
1395        AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2, erl, pwrb,
1396                      (params->dw[offsetof(struct amap_beiscsi_offload_params,
1397                      erl) / 32] & OFFLD_PARAMS_ERL));
1398        AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2, dde, pwrb,
1399                      (params->dw[offsetof(struct amap_beiscsi_offload_params,
1400                      dde) / 32] & OFFLD_PARAMS_DDE) >> 2);
1401        AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2, hde, pwrb,
1402                      (params->dw[offsetof(struct amap_beiscsi_offload_params,
1403                      hde) / 32] & OFFLD_PARAMS_HDE) >> 3);
1404        AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2,
1405                      ir2t, pwrb,
1406                      (params->dw[offsetof(struct amap_beiscsi_offload_params,
1407                      ir2t) / 32] & OFFLD_PARAMS_IR2T) >> 4);
1408        AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2, imd, pwrb,
1409                      (params->dw[offsetof(struct amap_beiscsi_offload_params,
1410                      imd) / 32] & OFFLD_PARAMS_IMD) >> 5);
1411        AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2,
1412                      data_seq_inorder,
1413                      pwrb,
1414                      (params->dw[offsetof(struct amap_beiscsi_offload_params,
1415                      data_seq_inorder) / 32] &
1416                      OFFLD_PARAMS_DATA_SEQ_INORDER) >> 6);
1417        AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2,
1418                      pdu_seq_inorder,
1419                      pwrb,
1420                      (params->dw[offsetof(struct amap_beiscsi_offload_params,
1421                      pdu_seq_inorder) / 32] &
1422                      OFFLD_PARAMS_PDU_SEQ_INORDER) >> 7);
1423        AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2, max_r2t,
1424                      pwrb,
1425                      (params->dw[offsetof(struct amap_beiscsi_offload_params,
1426                      max_r2t) / 32] &
1427                      OFFLD_PARAMS_MAX_R2T) >> 8);
1428        AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2, stat_sn,
1429                      pwrb,
1430                     (params->dw[offsetof(struct amap_beiscsi_offload_params,
1431                      exp_statsn) / 32] + 1));
1432}
1433
1434unsigned int beiscsi_invalidate_cxn(struct beiscsi_hba *phba,
1435                                    struct beiscsi_endpoint *beiscsi_ep)
1436{
1437        struct be_invalidate_connection_params_in *req;
1438        struct be_ctrl_info *ctrl = &phba->ctrl;
1439        struct be_mcc_wrb *wrb;
1440        unsigned int tag = 0;
1441
1442        mutex_lock(&ctrl->mbox_lock);
1443        wrb = alloc_mcc_wrb(phba, &tag);
1444        if (!wrb) {
1445                mutex_unlock(&ctrl->mbox_lock);
1446                return 0;
1447        }
1448
1449        req = embedded_payload(wrb);
1450        be_wrb_hdr_prepare(wrb, sizeof(union be_invalidate_connection_params),
1451                           true, 0);
1452        be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI_INI,
1453                           OPCODE_ISCSI_INI_DRIVER_INVALIDATE_CONNECTION,
1454                           sizeof(*req));
1455        req->session_handle = beiscsi_ep->fw_handle;
1456        req->cid = beiscsi_ep->ep_cid;
1457        if (beiscsi_ep->conn)
1458                req->cleanup_type = BE_CLEANUP_TYPE_INVALIDATE;
1459        else
1460                req->cleanup_type = BE_CLEANUP_TYPE_ISSUE_TCP_RST;
1461        /**
1462         * 0 - non-persistent targets
1463         * 1 - save session info on flash
1464         */
1465        req->save_cfg = 0;
1466        be_mcc_notify(phba, tag);
1467        mutex_unlock(&ctrl->mbox_lock);
1468        return tag;
1469}
1470
1471unsigned int beiscsi_upload_cxn(struct beiscsi_hba *phba,
1472                                struct beiscsi_endpoint *beiscsi_ep)
1473{
1474        struct be_ctrl_info *ctrl = &phba->ctrl;
1475        struct be_mcc_wrb *wrb;
1476        struct be_tcp_upload_params_in *req;
1477        unsigned int tag;
1478
1479        mutex_lock(&ctrl->mbox_lock);
1480        wrb = alloc_mcc_wrb(phba, &tag);
1481        if (!wrb) {
1482                mutex_unlock(&ctrl->mbox_lock);
1483                return 0;
1484        }
1485
1486        req = embedded_payload(wrb);
1487        be_wrb_hdr_prepare(wrb, sizeof(union be_tcp_upload_params), true, 0);
1488        be_cmd_hdr_prepare(&req->hdr, CMD_COMMON_TCP_UPLOAD,
1489                           OPCODE_COMMON_TCP_UPLOAD, sizeof(*req));
1490        req->id = beiscsi_ep->ep_cid;
1491        if (beiscsi_ep->conn)
1492                req->upload_type = BE_UPLOAD_TYPE_GRACEFUL;
1493        else
1494                req->upload_type = BE_UPLOAD_TYPE_ABORT;
1495        be_mcc_notify(phba, tag);
1496        mutex_unlock(&ctrl->mbox_lock);
1497        return tag;
1498}
1499
1500int beiscsi_mgmt_invalidate_icds(struct beiscsi_hba *phba,
1501                                 struct invldt_cmd_tbl *inv_tbl,
1502                                 unsigned int nents)
1503{
1504        struct be_ctrl_info *ctrl = &phba->ctrl;
1505        struct invldt_cmds_params_in *req;
1506        struct be_dma_mem nonemb_cmd;
1507        struct be_mcc_wrb *wrb;
1508        unsigned int i, tag;
1509        struct be_sge *sge;
1510        int rc;
1511
1512        if (!nents || nents > BE_INVLDT_CMD_TBL_SZ)
1513                return -EINVAL;
1514
1515        nonemb_cmd.size = sizeof(union be_invldt_cmds_params);
1516        nonemb_cmd.va = dma_alloc_coherent(&phba->ctrl.pdev->dev,
1517                                           nonemb_cmd.size, &nonemb_cmd.dma,
1518                                           GFP_KERNEL);
1519        if (!nonemb_cmd.va) {
1520                beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_EH,
1521                            "BM_%d : invldt_cmds_params alloc failed\n");
1522                return -ENOMEM;
1523        }
1524
1525        mutex_lock(&ctrl->mbox_lock);
1526        wrb = alloc_mcc_wrb(phba, &tag);
1527        if (!wrb) {
1528                mutex_unlock(&ctrl->mbox_lock);
1529                dma_free_coherent(&phba->ctrl.pdev->dev, nonemb_cmd.size,
1530                                    nonemb_cmd.va, nonemb_cmd.dma);
1531                return -ENOMEM;
1532        }
1533
1534        req = nonemb_cmd.va;
1535        be_wrb_hdr_prepare(wrb, nonemb_cmd.size, false, 1);
1536        be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI,
1537                        OPCODE_COMMON_ISCSI_ERROR_RECOVERY_INVALIDATE_COMMANDS,
1538                        sizeof(*req));
1539        req->ref_handle = 0;
1540        req->cleanup_type = CMD_ISCSI_COMMAND_INVALIDATE;
1541        for (i = 0; i < nents; i++) {
1542                req->table[i].icd = inv_tbl[i].icd;
1543                req->table[i].cid = inv_tbl[i].cid;
1544                req->icd_count++;
1545        }
1546        sge = nonembedded_sgl(wrb);
1547        sge->pa_hi = cpu_to_le32(upper_32_bits(nonemb_cmd.dma));
1548        sge->pa_lo = cpu_to_le32(lower_32_bits(nonemb_cmd.dma));
1549        sge->len = cpu_to_le32(nonemb_cmd.size);
1550
1551        be_mcc_notify(phba, tag);
1552        mutex_unlock(&ctrl->mbox_lock);
1553
1554        rc = beiscsi_mccq_compl_wait(phba, tag, NULL, &nonemb_cmd);
1555        if (rc != -EBUSY)
1556                dma_free_coherent(&phba->ctrl.pdev->dev, nonemb_cmd.size,
1557                                    nonemb_cmd.va, nonemb_cmd.dma);
1558        return rc;
1559}
1560