linux/drivers/scsi/be2iscsi/be_cmds.c
<<
>>
Prefs
   1/**
   2 * Copyright (C) 2005 - 2011 Emulex
   3 * All rights reserved.
   4 *
   5 * This program is free software; you can redistribute it and/or
   6 * modify it under the terms of the GNU General Public License version 2
   7 * as published by the Free Software Foundation.  The full GNU General
   8 * Public License is included in this distribution in the file called COPYING.
   9 *
  10 * Contact Information:
  11 * linux-drivers@emulex.com
  12 *
  13 * Emulex
  14 * 3333 Susan Street
  15 * Costa Mesa, CA 92626
  16 */
  17
  18#include "be.h"
  19#include "be_mgmt.h"
  20#include "be_main.h"
  21
  22int beiscsi_pci_soft_reset(struct beiscsi_hba *phba)
  23{
  24        u32 sreset;
  25        u8 *pci_reset_offset = 0;
  26        u8 *pci_online0_offset = 0;
  27        u8 *pci_online1_offset = 0;
  28        u32 pconline0 = 0;
  29        u32 pconline1 = 0;
  30        u32 i;
  31
  32        pci_reset_offset = (u8 *)phba->pci_va + BE2_SOFT_RESET;
  33        pci_online0_offset = (u8 *)phba->pci_va + BE2_PCI_ONLINE0;
  34        pci_online1_offset = (u8 *)phba->pci_va + BE2_PCI_ONLINE1;
  35        sreset = readl((void *)pci_reset_offset);
  36        sreset |= BE2_SET_RESET;
  37        writel(sreset, (void *)pci_reset_offset);
  38
  39        i = 0;
  40        while (sreset & BE2_SET_RESET) {
  41                if (i > 64)
  42                        break;
  43                msleep(100);
  44                sreset = readl((void *)pci_reset_offset);
  45                i++;
  46        }
  47
  48        if (sreset & BE2_SET_RESET) {
  49                printk(KERN_ERR "Soft Reset  did not deassert\n");
  50                return -EIO;
  51        }
  52        pconline1 = BE2_MPU_IRAM_ONLINE;
  53        writel(pconline0, (void *)pci_online0_offset);
  54        writel(pconline1, (void *)pci_online1_offset);
  55
  56        sreset = BE2_SET_RESET;
  57        writel(sreset, (void *)pci_reset_offset);
  58
  59        i = 0;
  60        while (sreset & BE2_SET_RESET) {
  61                if (i > 64)
  62                        break;
  63                msleep(1);
  64                sreset = readl((void *)pci_reset_offset);
  65                i++;
  66        }
  67        if (sreset & BE2_SET_RESET) {
  68                printk(KERN_ERR "MPU Online Soft Reset did not deassert\n");
  69                return -EIO;
  70        }
  71        return 0;
  72}
  73
  74int be_chk_reset_complete(struct beiscsi_hba *phba)
  75{
  76        unsigned int num_loop;
  77        u8 *mpu_sem = 0;
  78        u32 status;
  79
  80        num_loop = 1000;
  81        mpu_sem = (u8 *)phba->csr_va + MPU_EP_SEMAPHORE;
  82        msleep(5000);
  83
  84        while (num_loop) {
  85                status = readl((void *)mpu_sem);
  86
  87                if ((status & 0x80000000) || (status & 0x0000FFFF) == 0xC000)
  88                        break;
  89                msleep(60);
  90                num_loop--;
  91        }
  92
  93        if ((status & 0x80000000) || (!num_loop)) {
  94                printk(KERN_ERR "Failed in be_chk_reset_complete"
  95                "status = 0x%x\n", status);
  96                return -EIO;
  97        }
  98
  99        return 0;
 100}
 101
 102void be_mcc_notify(struct beiscsi_hba *phba)
 103{
 104        struct be_queue_info *mccq = &phba->ctrl.mcc_obj.q;
 105        u32 val = 0;
 106
 107        val |= mccq->id & DB_MCCQ_RING_ID_MASK;
 108        val |= 1 << DB_MCCQ_NUM_POSTED_SHIFT;
 109        iowrite32(val, phba->db_va + DB_MCCQ_OFFSET);
 110}
 111
 112unsigned int alloc_mcc_tag(struct beiscsi_hba *phba)
 113{
 114        unsigned int tag = 0;
 115
 116        if (phba->ctrl.mcc_tag_available) {
 117                tag = phba->ctrl.mcc_tag[phba->ctrl.mcc_alloc_index];
 118                phba->ctrl.mcc_tag[phba->ctrl.mcc_alloc_index] = 0;
 119                phba->ctrl.mcc_numtag[tag] = 0;
 120        }
 121        if (tag) {
 122                phba->ctrl.mcc_tag_available--;
 123                if (phba->ctrl.mcc_alloc_index == (MAX_MCC_CMD - 1))
 124                        phba->ctrl.mcc_alloc_index = 0;
 125                else
 126                        phba->ctrl.mcc_alloc_index++;
 127        }
 128        return tag;
 129}
 130
 131void free_mcc_tag(struct be_ctrl_info *ctrl, unsigned int tag)
 132{
 133        spin_lock(&ctrl->mbox_lock);
 134        tag = tag & 0x000000FF;
 135        ctrl->mcc_tag[ctrl->mcc_free_index] = tag;
 136        if (ctrl->mcc_free_index == (MAX_MCC_CMD - 1))
 137                ctrl->mcc_free_index = 0;
 138        else
 139                ctrl->mcc_free_index++;
 140        ctrl->mcc_tag_available++;
 141        spin_unlock(&ctrl->mbox_lock);
 142}
 143
 144bool is_link_state_evt(u32 trailer)
 145{
 146        return (((trailer >> ASYNC_TRAILER_EVENT_CODE_SHIFT) &
 147                  ASYNC_TRAILER_EVENT_CODE_MASK) ==
 148                  ASYNC_EVENT_CODE_LINK_STATE);
 149}
 150
 151static inline bool be_mcc_compl_is_new(struct be_mcc_compl *compl)
 152{
 153        if (compl->flags != 0) {
 154                compl->flags = le32_to_cpu(compl->flags);
 155                WARN_ON((compl->flags & CQE_FLAGS_VALID_MASK) == 0);
 156                return true;
 157        } else
 158                return false;
 159}
 160
 161static inline void be_mcc_compl_use(struct be_mcc_compl *compl)
 162{
 163        compl->flags = 0;
 164}
 165
 166static int be_mcc_compl_process(struct be_ctrl_info *ctrl,
 167                                struct be_mcc_compl *compl)
 168{
 169        u16 compl_status, extd_status;
 170
 171        be_dws_le_to_cpu(compl, 4);
 172
 173        compl_status = (compl->status >> CQE_STATUS_COMPL_SHIFT) &
 174                                        CQE_STATUS_COMPL_MASK;
 175        if (compl_status != MCC_STATUS_SUCCESS) {
 176                extd_status = (compl->status >> CQE_STATUS_EXTD_SHIFT) &
 177                                                CQE_STATUS_EXTD_MASK;
 178                dev_err(&ctrl->pdev->dev,
 179                        "error in cmd completion: status(compl/extd)=%d/%d\n",
 180                        compl_status, extd_status);
 181                return -EBUSY;
 182        }
 183        return 0;
 184}
 185
 186int be_mcc_compl_process_isr(struct be_ctrl_info *ctrl,
 187                                    struct be_mcc_compl *compl)
 188{
 189        u16 compl_status, extd_status;
 190        unsigned short tag;
 191
 192        be_dws_le_to_cpu(compl, 4);
 193
 194        compl_status = (compl->status >> CQE_STATUS_COMPL_SHIFT) &
 195                                        CQE_STATUS_COMPL_MASK;
 196        /* The ctrl.mcc_numtag[tag] is filled with
 197         * [31] = valid, [30:24] = Rsvd, [23:16] = wrb, [15:8] = extd_status,
 198         * [7:0] = compl_status
 199         */
 200        tag = (compl->tag0 & 0x000000FF);
 201        extd_status = (compl->status >> CQE_STATUS_EXTD_SHIFT) &
 202                                        CQE_STATUS_EXTD_MASK;
 203
 204        ctrl->mcc_numtag[tag]  = 0x80000000;
 205        ctrl->mcc_numtag[tag] |= (compl->tag0 & 0x00FF0000);
 206        ctrl->mcc_numtag[tag] |= (extd_status & 0x000000FF) << 8;
 207        ctrl->mcc_numtag[tag] |= (compl_status & 0x000000FF);
 208        wake_up_interruptible(&ctrl->mcc_wait[tag]);
 209        return 0;
 210}
 211
 212static struct be_mcc_compl *be_mcc_compl_get(struct beiscsi_hba *phba)
 213{
 214        struct be_queue_info *mcc_cq = &phba->ctrl.mcc_obj.cq;
 215        struct be_mcc_compl *compl = queue_tail_node(mcc_cq);
 216
 217        if (be_mcc_compl_is_new(compl)) {
 218                queue_tail_inc(mcc_cq);
 219                return compl;
 220        }
 221        return NULL;
 222}
 223
 224static void be2iscsi_fail_session(struct iscsi_cls_session *cls_session)
 225{
 226        iscsi_session_failure(cls_session->dd_data, ISCSI_ERR_CONN_FAILED);
 227}
 228
 229void beiscsi_async_link_state_process(struct beiscsi_hba *phba,
 230                struct be_async_event_link_state *evt)
 231{
 232        switch (evt->port_link_status) {
 233        case ASYNC_EVENT_LINK_DOWN:
 234                SE_DEBUG(DBG_LVL_1, "Link Down on Physical Port %d\n",
 235                                     evt->physical_port);
 236                phba->state |= BE_ADAPTER_LINK_DOWN;
 237                iscsi_host_for_each_session(phba->shost,
 238                                            be2iscsi_fail_session);
 239                break;
 240        case ASYNC_EVENT_LINK_UP:
 241                phba->state = BE_ADAPTER_UP;
 242                SE_DEBUG(DBG_LVL_1, "Link UP on Physical Port %d\n",
 243                                                evt->physical_port);
 244                break;
 245        default:
 246                SE_DEBUG(DBG_LVL_1, "Unexpected Async Notification %d on"
 247                                    "Physical Port %d\n",
 248                                     evt->port_link_status,
 249                                     evt->physical_port);
 250        }
 251}
 252
 253static void beiscsi_cq_notify(struct beiscsi_hba *phba, u16 qid, bool arm,
 254                       u16 num_popped)
 255{
 256        u32 val = 0;
 257        val |= qid & DB_CQ_RING_ID_MASK;
 258        if (arm)
 259                val |= 1 << DB_CQ_REARM_SHIFT;
 260        val |= num_popped << DB_CQ_NUM_POPPED_SHIFT;
 261        iowrite32(val, phba->db_va + DB_CQ_OFFSET);
 262}
 263
 264
 265int beiscsi_process_mcc(struct beiscsi_hba *phba)
 266{
 267        struct be_mcc_compl *compl;
 268        int num = 0, status = 0;
 269        struct be_ctrl_info *ctrl = &phba->ctrl;
 270
 271        spin_lock_bh(&phba->ctrl.mcc_cq_lock);
 272        while ((compl = be_mcc_compl_get(phba))) {
 273                if (compl->flags & CQE_FLAGS_ASYNC_MASK) {
 274                        /* Interpret flags as an async trailer */
 275                        if (is_link_state_evt(compl->flags))
 276                                /* Interpret compl as a async link evt */
 277                                beiscsi_async_link_state_process(phba,
 278                                   (struct be_async_event_link_state *) compl);
 279                        else
 280                                SE_DEBUG(DBG_LVL_1,
 281                                         " Unsupported Async Event, flags"
 282                                         " = 0x%08x\n", compl->flags);
 283
 284                } else if (compl->flags & CQE_FLAGS_COMPLETED_MASK) {
 285                                status = be_mcc_compl_process(ctrl, compl);
 286                                atomic_dec(&phba->ctrl.mcc_obj.q.used);
 287                }
 288                be_mcc_compl_use(compl);
 289                num++;
 290        }
 291
 292        if (num)
 293                beiscsi_cq_notify(phba, phba->ctrl.mcc_obj.cq.id, true, num);
 294
 295        spin_unlock_bh(&phba->ctrl.mcc_cq_lock);
 296        return status;
 297}
 298
 299/* Wait till no more pending mcc requests are present */
 300static int be_mcc_wait_compl(struct beiscsi_hba *phba)
 301{
 302        int i, status;
 303        for (i = 0; i < mcc_timeout; i++) {
 304                status = beiscsi_process_mcc(phba);
 305                if (status)
 306                        return status;
 307
 308                if (atomic_read(&phba->ctrl.mcc_obj.q.used) == 0)
 309                        break;
 310                udelay(100);
 311        }
 312        if (i == mcc_timeout) {
 313                dev_err(&phba->pcidev->dev, "mccq poll timed out\n");
 314                return -EBUSY;
 315        }
 316        return 0;
 317}
 318
 319/* Notify MCC requests and wait for completion */
 320int be_mcc_notify_wait(struct beiscsi_hba *phba)
 321{
 322        be_mcc_notify(phba);
 323        return be_mcc_wait_compl(phba);
 324}
 325
 326static int be_mbox_db_ready_wait(struct be_ctrl_info *ctrl)
 327{
 328#define long_delay 2000
 329        void __iomem *db = ctrl->db + MPU_MAILBOX_DB_OFFSET;
 330        int cnt = 0, wait = 5;  /* in usecs */
 331        u32 ready;
 332
 333        do {
 334                ready = ioread32(db) & MPU_MAILBOX_DB_RDY_MASK;
 335                if (ready)
 336                        break;
 337
 338                if (cnt > 12000000) {
 339                        dev_err(&ctrl->pdev->dev, "mbox_db poll timed out\n");
 340                        return -EBUSY;
 341                }
 342
 343                if (cnt > 50) {
 344                        wait = long_delay;
 345                        mdelay(long_delay / 1000);
 346                } else
 347                        udelay(wait);
 348                cnt += wait;
 349        } while (true);
 350        return 0;
 351}
 352
 353int be_mbox_notify(struct be_ctrl_info *ctrl)
 354{
 355        int status;
 356        u32 val = 0;
 357        void __iomem *db = ctrl->db + MPU_MAILBOX_DB_OFFSET;
 358        struct be_dma_mem *mbox_mem = &ctrl->mbox_mem;
 359        struct be_mcc_mailbox *mbox = mbox_mem->va;
 360        struct be_mcc_compl *compl = &mbox->compl;
 361
 362        val &= ~MPU_MAILBOX_DB_RDY_MASK;
 363        val |= MPU_MAILBOX_DB_HI_MASK;
 364        val |= (upper_32_bits(mbox_mem->dma) >> 2) << 2;
 365        iowrite32(val, db);
 366
 367        status = be_mbox_db_ready_wait(ctrl);
 368        if (status != 0) {
 369                SE_DEBUG(DBG_LVL_1, " be_mbox_db_ready_wait failed\n");
 370                return status;
 371        }
 372        val = 0;
 373        val &= ~MPU_MAILBOX_DB_RDY_MASK;
 374        val &= ~MPU_MAILBOX_DB_HI_MASK;
 375        val |= (u32) (mbox_mem->dma >> 4) << 2;
 376        iowrite32(val, db);
 377
 378        status = be_mbox_db_ready_wait(ctrl);
 379        if (status != 0) {
 380                SE_DEBUG(DBG_LVL_1, " be_mbox_db_ready_wait failed\n");
 381                return status;
 382        }
 383        if (be_mcc_compl_is_new(compl)) {
 384                status = be_mcc_compl_process(ctrl, &mbox->compl);
 385                be_mcc_compl_use(compl);
 386                if (status) {
 387                        SE_DEBUG(DBG_LVL_1, "After be_mcc_compl_process\n");
 388                        return status;
 389                }
 390        } else {
 391                dev_err(&ctrl->pdev->dev, "invalid mailbox completion\n");
 392                return -EBUSY;
 393        }
 394        return 0;
 395}
 396
 397/*
 398 * Insert the mailbox address into the doorbell in two steps
 399 * Polls on the mbox doorbell till a command completion (or a timeout) occurs
 400 */
 401static int be_mbox_notify_wait(struct beiscsi_hba *phba)
 402{
 403        int status;
 404        u32 val = 0;
 405        void __iomem *db = phba->ctrl.db + MPU_MAILBOX_DB_OFFSET;
 406        struct be_dma_mem *mbox_mem = &phba->ctrl.mbox_mem;
 407        struct be_mcc_mailbox *mbox = mbox_mem->va;
 408        struct be_mcc_compl *compl = &mbox->compl;
 409        struct be_ctrl_info *ctrl = &phba->ctrl;
 410
 411        val |= MPU_MAILBOX_DB_HI_MASK;
 412        /* at bits 2 - 31 place mbox dma addr msb bits 34 - 63 */
 413        val |= (upper_32_bits(mbox_mem->dma) >> 2) << 2;
 414        iowrite32(val, db);
 415
 416        /* wait for ready to be set */
 417        status = be_mbox_db_ready_wait(ctrl);
 418        if (status != 0)
 419                return status;
 420
 421        val = 0;
 422        /* at bits 2 - 31 place mbox dma addr lsb bits 4 - 33 */
 423        val |= (u32)(mbox_mem->dma >> 4) << 2;
 424        iowrite32(val, db);
 425
 426        status = be_mbox_db_ready_wait(ctrl);
 427        if (status != 0)
 428                return status;
 429
 430        /* A cq entry has been made now */
 431        if (be_mcc_compl_is_new(compl)) {
 432                status = be_mcc_compl_process(ctrl, &mbox->compl);
 433                be_mcc_compl_use(compl);
 434                if (status)
 435                        return status;
 436        } else {
 437                dev_err(&phba->pcidev->dev, "invalid mailbox completion\n");
 438                return -EBUSY;
 439        }
 440        return 0;
 441}
 442
 443void be_wrb_hdr_prepare(struct be_mcc_wrb *wrb, int payload_len,
 444                                bool embedded, u8 sge_cnt)
 445{
 446        if (embedded)
 447                wrb->embedded |= MCC_WRB_EMBEDDED_MASK;
 448        else
 449                wrb->embedded |= (sge_cnt & MCC_WRB_SGE_CNT_MASK) <<
 450                                                MCC_WRB_SGE_CNT_SHIFT;
 451        wrb->payload_length = payload_len;
 452        be_dws_cpu_to_le(wrb, 8);
 453}
 454
 455void be_cmd_hdr_prepare(struct be_cmd_req_hdr *req_hdr,
 456                        u8 subsystem, u8 opcode, int cmd_len)
 457{
 458        req_hdr->opcode = opcode;
 459        req_hdr->subsystem = subsystem;
 460        req_hdr->request_length = cpu_to_le32(cmd_len - sizeof(*req_hdr));
 461        req_hdr->timeout = 120;
 462}
 463
 464static void be_cmd_page_addrs_prepare(struct phys_addr *pages, u32 max_pages,
 465                                                        struct be_dma_mem *mem)
 466{
 467        int i, buf_pages;
 468        u64 dma = (u64) mem->dma;
 469
 470        buf_pages = min(PAGES_4K_SPANNED(mem->va, mem->size), max_pages);
 471        for (i = 0; i < buf_pages; i++) {
 472                pages[i].lo = cpu_to_le32(dma & 0xFFFFFFFF);
 473                pages[i].hi = cpu_to_le32(upper_32_bits(dma));
 474                dma += PAGE_SIZE_4K;
 475        }
 476}
 477
 478static u32 eq_delay_to_mult(u32 usec_delay)
 479{
 480#define MAX_INTR_RATE 651042
 481        const u32 round = 10;
 482        u32 multiplier;
 483
 484        if (usec_delay == 0)
 485                multiplier = 0;
 486        else {
 487                u32 interrupt_rate = 1000000 / usec_delay;
 488                if (interrupt_rate == 0)
 489                        multiplier = 1023;
 490                else {
 491                        multiplier = (MAX_INTR_RATE - interrupt_rate) * round;
 492                        multiplier /= interrupt_rate;
 493                        multiplier = (multiplier + round / 2) / round;
 494                        multiplier = min(multiplier, (u32) 1023);
 495                }
 496        }
 497        return multiplier;
 498}
 499
 500struct be_mcc_wrb *wrb_from_mbox(struct be_dma_mem *mbox_mem)
 501{
 502        return &((struct be_mcc_mailbox *)(mbox_mem->va))->wrb;
 503}
 504
 505struct be_mcc_wrb *wrb_from_mccq(struct beiscsi_hba *phba)
 506{
 507        struct be_queue_info *mccq = &phba->ctrl.mcc_obj.q;
 508        struct be_mcc_wrb *wrb;
 509
 510        BUG_ON(atomic_read(&mccq->used) >= mccq->len);
 511        wrb = queue_head_node(mccq);
 512        memset(wrb, 0, sizeof(*wrb));
 513        wrb->tag0 = (mccq->head & 0x000000FF) << 16;
 514        queue_head_inc(mccq);
 515        atomic_inc(&mccq->used);
 516        return wrb;
 517}
 518
 519
 520int beiscsi_cmd_eq_create(struct be_ctrl_info *ctrl,
 521                          struct be_queue_info *eq, int eq_delay)
 522{
 523        struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem);
 524        struct be_cmd_req_eq_create *req = embedded_payload(wrb);
 525        struct be_cmd_resp_eq_create *resp = embedded_payload(wrb);
 526        struct be_dma_mem *q_mem = &eq->dma_mem;
 527        int status;
 528
 529        SE_DEBUG(DBG_LVL_8, "In beiscsi_cmd_eq_create\n");
 530        spin_lock(&ctrl->mbox_lock);
 531        memset(wrb, 0, sizeof(*wrb));
 532
 533        be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
 534
 535        be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
 536                        OPCODE_COMMON_EQ_CREATE, sizeof(*req));
 537
 538        req->num_pages = cpu_to_le16(PAGES_4K_SPANNED(q_mem->va, q_mem->size));
 539
 540        AMAP_SET_BITS(struct amap_eq_context, func, req->context,
 541                                                PCI_FUNC(ctrl->pdev->devfn));
 542        AMAP_SET_BITS(struct amap_eq_context, valid, req->context, 1);
 543        AMAP_SET_BITS(struct amap_eq_context, size, req->context, 0);
 544        AMAP_SET_BITS(struct amap_eq_context, count, req->context,
 545                                        __ilog2_u32(eq->len / 256));
 546        AMAP_SET_BITS(struct amap_eq_context, delaymult, req->context,
 547                                        eq_delay_to_mult(eq_delay));
 548        be_dws_cpu_to_le(req->context, sizeof(req->context));
 549
 550        be_cmd_page_addrs_prepare(req->pages, ARRAY_SIZE(req->pages), q_mem);
 551
 552        status = be_mbox_notify(ctrl);
 553        if (!status) {
 554                eq->id = le16_to_cpu(resp->eq_id);
 555                eq->created = true;
 556        }
 557        spin_unlock(&ctrl->mbox_lock);
 558        return status;
 559}
 560
 561int be_cmd_fw_initialize(struct be_ctrl_info *ctrl)
 562{
 563        struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem);
 564        int status;
 565        u8 *endian_check;
 566
 567        SE_DEBUG(DBG_LVL_8, "In be_cmd_fw_initialize\n");
 568        spin_lock(&ctrl->mbox_lock);
 569        memset(wrb, 0, sizeof(*wrb));
 570
 571        endian_check = (u8 *) wrb;
 572        *endian_check++ = 0xFF;
 573        *endian_check++ = 0x12;
 574        *endian_check++ = 0x34;
 575        *endian_check++ = 0xFF;
 576        *endian_check++ = 0xFF;
 577        *endian_check++ = 0x56;
 578        *endian_check++ = 0x78;
 579        *endian_check++ = 0xFF;
 580        be_dws_cpu_to_le(wrb, sizeof(*wrb));
 581
 582        status = be_mbox_notify(ctrl);
 583        if (status)
 584                SE_DEBUG(DBG_LVL_1, "be_cmd_fw_initialize Failed\n");
 585
 586        spin_unlock(&ctrl->mbox_lock);
 587        return status;
 588}
 589
 590int beiscsi_cmd_cq_create(struct be_ctrl_info *ctrl,
 591                          struct be_queue_info *cq, struct be_queue_info *eq,
 592                          bool sol_evts, bool no_delay, int coalesce_wm)
 593{
 594        struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem);
 595        struct be_cmd_req_cq_create *req = embedded_payload(wrb);
 596        struct be_cmd_resp_cq_create *resp = embedded_payload(wrb);
 597        struct be_dma_mem *q_mem = &cq->dma_mem;
 598        void *ctxt = &req->context;
 599        int status;
 600
 601        SE_DEBUG(DBG_LVL_8, "In beiscsi_cmd_cq_create\n");
 602        spin_lock(&ctrl->mbox_lock);
 603        memset(wrb, 0, sizeof(*wrb));
 604
 605        be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
 606
 607        be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
 608                        OPCODE_COMMON_CQ_CREATE, sizeof(*req));
 609        if (!q_mem->va)
 610                SE_DEBUG(DBG_LVL_1, "uninitialized q_mem->va\n");
 611
 612        req->num_pages = cpu_to_le16(PAGES_4K_SPANNED(q_mem->va, q_mem->size));
 613
 614        AMAP_SET_BITS(struct amap_cq_context, coalescwm, ctxt, coalesce_wm);
 615        AMAP_SET_BITS(struct amap_cq_context, nodelay, ctxt, no_delay);
 616        AMAP_SET_BITS(struct amap_cq_context, count, ctxt,
 617                      __ilog2_u32(cq->len / 256));
 618        AMAP_SET_BITS(struct amap_cq_context, valid, ctxt, 1);
 619        AMAP_SET_BITS(struct amap_cq_context, solevent, ctxt, sol_evts);
 620        AMAP_SET_BITS(struct amap_cq_context, eventable, ctxt, 1);
 621        AMAP_SET_BITS(struct amap_cq_context, eqid, ctxt, eq->id);
 622        AMAP_SET_BITS(struct amap_cq_context, armed, ctxt, 1);
 623        AMAP_SET_BITS(struct amap_cq_context, func, ctxt,
 624                      PCI_FUNC(ctrl->pdev->devfn));
 625        be_dws_cpu_to_le(ctxt, sizeof(req->context));
 626
 627        be_cmd_page_addrs_prepare(req->pages, ARRAY_SIZE(req->pages), q_mem);
 628
 629        status = be_mbox_notify(ctrl);
 630        if (!status) {
 631                cq->id = le16_to_cpu(resp->cq_id);
 632                cq->created = true;
 633        } else
 634                SE_DEBUG(DBG_LVL_1, "In be_cmd_cq_create, status=ox%08x\n",
 635                        status);
 636        spin_unlock(&ctrl->mbox_lock);
 637
 638        return status;
 639}
 640
 641static u32 be_encoded_q_len(int q_len)
 642{
 643        u32 len_encoded = fls(q_len);   /* log2(len) + 1 */
 644        if (len_encoded == 16)
 645                len_encoded = 0;
 646        return len_encoded;
 647}
 648
 649int beiscsi_cmd_mccq_create(struct beiscsi_hba *phba,
 650                        struct be_queue_info *mccq,
 651                        struct be_queue_info *cq)
 652{
 653        struct be_mcc_wrb *wrb;
 654        struct be_cmd_req_mcc_create *req;
 655        struct be_dma_mem *q_mem = &mccq->dma_mem;
 656        struct be_ctrl_info *ctrl;
 657        void *ctxt;
 658        int status;
 659
 660        spin_lock(&phba->ctrl.mbox_lock);
 661        ctrl = &phba->ctrl;
 662        wrb = wrb_from_mbox(&ctrl->mbox_mem);
 663        memset(wrb, 0, sizeof(*wrb));
 664        req = embedded_payload(wrb);
 665        ctxt = &req->context;
 666
 667        be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
 668
 669        be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
 670                        OPCODE_COMMON_MCC_CREATE, sizeof(*req));
 671
 672        req->num_pages = PAGES_4K_SPANNED(q_mem->va, q_mem->size);
 673
 674        AMAP_SET_BITS(struct amap_mcc_context, fid, ctxt,
 675                      PCI_FUNC(phba->pcidev->devfn));
 676        AMAP_SET_BITS(struct amap_mcc_context, valid, ctxt, 1);
 677        AMAP_SET_BITS(struct amap_mcc_context, ring_size, ctxt,
 678                be_encoded_q_len(mccq->len));
 679        AMAP_SET_BITS(struct amap_mcc_context, cq_id, ctxt, cq->id);
 680
 681        be_dws_cpu_to_le(ctxt, sizeof(req->context));
 682
 683        be_cmd_page_addrs_prepare(req->pages, ARRAY_SIZE(req->pages), q_mem);
 684
 685        status = be_mbox_notify_wait(phba);
 686        if (!status) {
 687                struct be_cmd_resp_mcc_create *resp = embedded_payload(wrb);
 688                mccq->id = le16_to_cpu(resp->id);
 689                mccq->created = true;
 690        }
 691        spin_unlock(&phba->ctrl.mbox_lock);
 692
 693        return status;
 694}
 695
 696int beiscsi_cmd_q_destroy(struct be_ctrl_info *ctrl, struct be_queue_info *q,
 697                          int queue_type)
 698{
 699        struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem);
 700        struct be_cmd_req_q_destroy *req = embedded_payload(wrb);
 701        u8 subsys = 0, opcode = 0;
 702        int status;
 703
 704        SE_DEBUG(DBG_LVL_8, "In beiscsi_cmd_q_destroy\n");
 705        spin_lock(&ctrl->mbox_lock);
 706        memset(wrb, 0, sizeof(*wrb));
 707        be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
 708
 709        switch (queue_type) {
 710        case QTYPE_EQ:
 711                subsys = CMD_SUBSYSTEM_COMMON;
 712                opcode = OPCODE_COMMON_EQ_DESTROY;
 713                break;
 714        case QTYPE_CQ:
 715                subsys = CMD_SUBSYSTEM_COMMON;
 716                opcode = OPCODE_COMMON_CQ_DESTROY;
 717                break;
 718        case QTYPE_MCCQ:
 719                subsys = CMD_SUBSYSTEM_COMMON;
 720                opcode = OPCODE_COMMON_MCC_DESTROY;
 721                break;
 722        case QTYPE_WRBQ:
 723                subsys = CMD_SUBSYSTEM_ISCSI;
 724                opcode = OPCODE_COMMON_ISCSI_WRBQ_DESTROY;
 725                break;
 726        case QTYPE_DPDUQ:
 727                subsys = CMD_SUBSYSTEM_ISCSI;
 728                opcode = OPCODE_COMMON_ISCSI_DEFQ_DESTROY;
 729                break;
 730        case QTYPE_SGL:
 731                subsys = CMD_SUBSYSTEM_ISCSI;
 732                opcode = OPCODE_COMMON_ISCSI_CFG_REMOVE_SGL_PAGES;
 733                break;
 734        default:
 735                spin_unlock(&ctrl->mbox_lock);
 736                BUG();
 737                return -ENXIO;
 738        }
 739        be_cmd_hdr_prepare(&req->hdr, subsys, opcode, sizeof(*req));
 740        if (queue_type != QTYPE_SGL)
 741                req->id = cpu_to_le16(q->id);
 742
 743        status = be_mbox_notify(ctrl);
 744
 745        spin_unlock(&ctrl->mbox_lock);
 746        return status;
 747}
 748
 749int be_cmd_create_default_pdu_queue(struct be_ctrl_info *ctrl,
 750                                    struct be_queue_info *cq,
 751                                    struct be_queue_info *dq, int length,
 752                                    int entry_size)
 753{
 754        struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem);
 755        struct be_defq_create_req *req = embedded_payload(wrb);
 756        struct be_dma_mem *q_mem = &dq->dma_mem;
 757        void *ctxt = &req->context;
 758        int status;
 759
 760        SE_DEBUG(DBG_LVL_8, "In be_cmd_create_default_pdu_queue\n");
 761        spin_lock(&ctrl->mbox_lock);
 762        memset(wrb, 0, sizeof(*wrb));
 763
 764        be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
 765
 766        be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI,
 767                           OPCODE_COMMON_ISCSI_DEFQ_CREATE, sizeof(*req));
 768
 769        req->num_pages = PAGES_4K_SPANNED(q_mem->va, q_mem->size);
 770        AMAP_SET_BITS(struct amap_be_default_pdu_context, rx_pdid, ctxt, 0);
 771        AMAP_SET_BITS(struct amap_be_default_pdu_context, rx_pdid_valid, ctxt,
 772                      1);
 773        AMAP_SET_BITS(struct amap_be_default_pdu_context, pci_func_id, ctxt,
 774                      PCI_FUNC(ctrl->pdev->devfn));
 775        AMAP_SET_BITS(struct amap_be_default_pdu_context, ring_size, ctxt,
 776                      be_encoded_q_len(length / sizeof(struct phys_addr)));
 777        AMAP_SET_BITS(struct amap_be_default_pdu_context, default_buffer_size,
 778                      ctxt, entry_size);
 779        AMAP_SET_BITS(struct amap_be_default_pdu_context, cq_id_recv, ctxt,
 780                      cq->id);
 781
 782        be_dws_cpu_to_le(ctxt, sizeof(req->context));
 783
 784        be_cmd_page_addrs_prepare(req->pages, ARRAY_SIZE(req->pages), q_mem);
 785
 786        status = be_mbox_notify(ctrl);
 787        if (!status) {
 788                struct be_defq_create_resp *resp = embedded_payload(wrb);
 789
 790                dq->id = le16_to_cpu(resp->id);
 791                dq->created = true;
 792        }
 793        spin_unlock(&ctrl->mbox_lock);
 794
 795        return status;
 796}
 797
 798int be_cmd_wrbq_create(struct be_ctrl_info *ctrl, struct be_dma_mem *q_mem,
 799                       struct be_queue_info *wrbq)
 800{
 801        struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem);
 802        struct be_wrbq_create_req *req = embedded_payload(wrb);
 803        struct be_wrbq_create_resp *resp = embedded_payload(wrb);
 804        int status;
 805
 806        spin_lock(&ctrl->mbox_lock);
 807        memset(wrb, 0, sizeof(*wrb));
 808
 809        be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
 810
 811        be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI,
 812                OPCODE_COMMON_ISCSI_WRBQ_CREATE, sizeof(*req));
 813        req->num_pages = PAGES_4K_SPANNED(q_mem->va, q_mem->size);
 814        be_cmd_page_addrs_prepare(req->pages, ARRAY_SIZE(req->pages), q_mem);
 815
 816        status = be_mbox_notify(ctrl);
 817        if (!status) {
 818                wrbq->id = le16_to_cpu(resp->cid);
 819                wrbq->created = true;
 820        }
 821        spin_unlock(&ctrl->mbox_lock);
 822        return status;
 823}
 824
 825int be_cmd_iscsi_post_sgl_pages(struct be_ctrl_info *ctrl,
 826                                struct be_dma_mem *q_mem,
 827                                u32 page_offset, u32 num_pages)
 828{
 829        struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem);
 830        struct be_post_sgl_pages_req *req = embedded_payload(wrb);
 831        int status;
 832        unsigned int curr_pages;
 833        u32 internal_page_offset = 0;
 834        u32 temp_num_pages = num_pages;
 835
 836        if (num_pages == 0xff)
 837                num_pages = 1;
 838
 839        spin_lock(&ctrl->mbox_lock);
 840        do {
 841                memset(wrb, 0, sizeof(*wrb));
 842                be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
 843                be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI,
 844                                   OPCODE_COMMON_ISCSI_CFG_POST_SGL_PAGES,
 845                                   sizeof(*req));
 846                curr_pages = BE_NUMBER_OF_FIELD(struct be_post_sgl_pages_req,
 847                                                pages);
 848                req->num_pages = min(num_pages, curr_pages);
 849                req->page_offset = page_offset;
 850                be_cmd_page_addrs_prepare(req->pages, req->num_pages, q_mem);
 851                q_mem->dma = q_mem->dma + (req->num_pages * PAGE_SIZE);
 852                internal_page_offset += req->num_pages;
 853                page_offset += req->num_pages;
 854                num_pages -= req->num_pages;
 855
 856                if (temp_num_pages == 0xff)
 857                        req->num_pages = temp_num_pages;
 858
 859                status = be_mbox_notify(ctrl);
 860                if (status) {
 861                        SE_DEBUG(DBG_LVL_1,
 862                                 "FW CMD to map iscsi frags failed.\n");
 863                        goto error;
 864                }
 865        } while (num_pages > 0);
 866error:
 867        spin_unlock(&ctrl->mbox_lock);
 868        if (status != 0)
 869                beiscsi_cmd_q_destroy(ctrl, NULL, QTYPE_SGL);
 870        return status;
 871}
 872
 873int beiscsi_cmd_reset_function(struct beiscsi_hba  *phba)
 874{
 875        struct be_ctrl_info *ctrl = &phba->ctrl;
 876        struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem);
 877        struct be_post_sgl_pages_req *req = embedded_payload(wrb);
 878        int status;
 879
 880        spin_lock(&ctrl->mbox_lock);
 881
 882        req = embedded_payload(wrb);
 883        be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
 884        be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
 885                           OPCODE_COMMON_FUNCTION_RESET, sizeof(*req));
 886        status = be_mbox_notify_wait(phba);
 887
 888        spin_unlock(&ctrl->mbox_lock);
 889        return status;
 890}
 891
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.