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