linux/drivers/scsi/bfa/bfad.c
<<
>>
Prefs
   1/*
   2 * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
   3 * All rights reserved
   4 * www.brocade.com
   5 *
   6 * Linux driver for Brocade Fibre Channel Host Bus Adapter.
   7 *
   8 * This program is free software; you can redistribute it and/or modify it
   9 * under the terms of the GNU General Public License (GPL) Version 2 as
  10 * published by the Free Software Foundation
  11 *
  12 * This program is distributed in the hope that it will be useful, but
  13 * WITHOUT ANY WARRANTY; without even the implied warranty of
  14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  15 * General Public License for more details.
  16 */
  17
  18/**
  19 *  bfad.c Linux driver PCI interface module.
  20 */
  21
  22#include <linux/module.h>
  23#include "bfad_drv.h"
  24#include "bfad_im.h"
  25#include "bfad_tm.h"
  26#include "bfad_ipfc.h"
  27#include "bfad_trcmod.h"
  28#include <fcb/bfa_fcb_vf.h>
  29#include <fcb/bfa_fcb_rport.h>
  30#include <fcb/bfa_fcb_port.h>
  31#include <fcb/bfa_fcb.h>
  32
  33BFA_TRC_FILE(LDRV, BFAD);
  34static DEFINE_MUTEX(bfad_mutex);
  35LIST_HEAD(bfad_list);
  36static int      bfad_inst;
  37int bfad_supported_fc4s;
  38
  39static char     *host_name;
  40static char     *os_name;
  41static char     *os_patch;
  42static int      num_rports;
  43static int      num_ios;
  44static int      num_tms;
  45static int      num_fcxps;
  46static int      num_ufbufs;
  47static int      reqq_size;
  48static int      rspq_size;
  49static int      num_sgpgs;
  50static int      rport_del_timeout = BFA_FCS_RPORT_DEF_DEL_TIMEOUT;
  51static int      bfa_io_max_sge = BFAD_IO_MAX_SGE;
  52static int      log_level = BFA_LOG_WARNING;
  53static int      ioc_auto_recover = BFA_TRUE;
  54static int      ipfc_enable = BFA_FALSE;
  55static int      ipfc_mtu = -1;
  56int             bfa_lun_queue_depth = BFAD_LUN_QUEUE_DEPTH;
  57int             bfa_linkup_delay = -1;
  58
  59module_param(os_name, charp, S_IRUGO | S_IWUSR);
  60module_param(os_patch, charp, S_IRUGO | S_IWUSR);
  61module_param(host_name, charp, S_IRUGO | S_IWUSR);
  62module_param(num_rports, int, S_IRUGO | S_IWUSR);
  63module_param(num_ios, int, S_IRUGO | S_IWUSR);
  64module_param(num_tms, int, S_IRUGO | S_IWUSR);
  65module_param(num_fcxps, int, S_IRUGO | S_IWUSR);
  66module_param(num_ufbufs, int, S_IRUGO | S_IWUSR);
  67module_param(reqq_size, int, S_IRUGO | S_IWUSR);
  68module_param(rspq_size, int, S_IRUGO | S_IWUSR);
  69module_param(num_sgpgs, int, S_IRUGO | S_IWUSR);
  70module_param(rport_del_timeout, int, S_IRUGO | S_IWUSR);
  71module_param(bfa_lun_queue_depth, int, S_IRUGO | S_IWUSR);
  72module_param(bfa_io_max_sge, int, S_IRUGO | S_IWUSR);
  73module_param(log_level, int, S_IRUGO | S_IWUSR);
  74module_param(ioc_auto_recover, int, S_IRUGO | S_IWUSR);
  75module_param(ipfc_enable, int, S_IRUGO | S_IWUSR);
  76module_param(ipfc_mtu, int, S_IRUGO | S_IWUSR);
  77module_param(bfa_linkup_delay, int, S_IRUGO | S_IWUSR);
  78
  79/*
  80 * Stores the module parm num_sgpgs value;
  81 * used to reset for bfad next instance.
  82 */
  83static int num_sgpgs_parm;
  84
  85static bfa_status_t
  86bfad_fc4_probe(struct bfad_s *bfad)
  87{
  88        int             rc;
  89
  90        rc = bfad_im_probe(bfad);
  91        if (rc != BFA_STATUS_OK)
  92                goto ext;
  93
  94        bfad_tm_probe(bfad);
  95
  96        if (ipfc_enable)
  97                bfad_ipfc_probe(bfad);
  98ext:
  99        return rc;
 100}
 101
 102static void
 103bfad_fc4_probe_undo(struct bfad_s *bfad)
 104{
 105        bfad_im_probe_undo(bfad);
 106        bfad_tm_probe_undo(bfad);
 107        if (ipfc_enable)
 108                bfad_ipfc_probe_undo(bfad);
 109}
 110
 111static void
 112bfad_fc4_probe_post(struct bfad_s *bfad)
 113{
 114        if (bfad->im)
 115                bfad_im_probe_post(bfad->im);
 116
 117        bfad_tm_probe_post(bfad);
 118        if (ipfc_enable)
 119                bfad_ipfc_probe_post(bfad);
 120}
 121
 122static bfa_status_t
 123bfad_fc4_port_new(struct bfad_s *bfad, struct bfad_port_s *port, int roles)
 124{
 125        int             rc = BFA_STATUS_FAILED;
 126
 127        if (roles & BFA_PORT_ROLE_FCP_IM)
 128                rc = bfad_im_port_new(bfad, port);
 129        if (rc != BFA_STATUS_OK)
 130                goto ext;
 131
 132        if (roles & BFA_PORT_ROLE_FCP_TM)
 133                rc = bfad_tm_port_new(bfad, port);
 134        if (rc != BFA_STATUS_OK)
 135                goto ext;
 136
 137        if ((roles & BFA_PORT_ROLE_FCP_IPFC) && ipfc_enable)
 138                rc = bfad_ipfc_port_new(bfad, port, port->pvb_type);
 139ext:
 140        return rc;
 141}
 142
 143static void
 144bfad_fc4_port_delete(struct bfad_s *bfad, struct bfad_port_s *port, int roles)
 145{
 146        if (roles & BFA_PORT_ROLE_FCP_IM)
 147                bfad_im_port_delete(bfad, port);
 148
 149        if (roles & BFA_PORT_ROLE_FCP_TM)
 150                bfad_tm_port_delete(bfad, port);
 151
 152        if ((roles & BFA_PORT_ROLE_FCP_IPFC) && ipfc_enable)
 153                bfad_ipfc_port_delete(bfad, port);
 154}
 155
 156/**
 157 *  BFA callbacks
 158 */
 159void
 160bfad_hcb_comp(void *arg, bfa_status_t status)
 161{
 162        struct bfad_hal_comp *fcomp = (struct bfad_hal_comp *)arg;
 163
 164        fcomp->status = status;
 165        complete(&fcomp->comp);
 166}
 167
 168/**
 169 * bfa_init callback
 170 */
 171void
 172bfa_cb_init(void *drv, bfa_status_t init_status)
 173{
 174        struct bfad_s  *bfad = drv;
 175
 176        if (init_status == BFA_STATUS_OK)
 177                bfad->bfad_flags |= BFAD_HAL_INIT_DONE;
 178
 179        complete(&bfad->comp);
 180}
 181
 182
 183
 184/**
 185 *  BFA_FCS callbacks
 186 */
 187static struct bfad_port_s *
 188bfad_get_drv_port(struct bfad_s *bfad, struct bfad_vf_s *vf_drv,
 189                  struct bfad_vport_s *vp_drv)
 190{
 191        return ((vp_drv) ? (&(vp_drv)->drv_port)
 192                : ((vf_drv) ? (&(vf_drv)->base_port) : (&(bfad)->pport)));
 193}
 194
 195struct bfad_port_s *
 196bfa_fcb_port_new(struct bfad_s *bfad, struct bfa_fcs_port_s *port,
 197                 enum bfa_port_role roles, struct bfad_vf_s *vf_drv,
 198                 struct bfad_vport_s *vp_drv)
 199{
 200        bfa_status_t    rc;
 201        struct bfad_port_s *port_drv;
 202
 203        if (!vp_drv && !vf_drv) {
 204                port_drv = &bfad->pport;
 205                port_drv->pvb_type = BFAD_PORT_PHYS_BASE;
 206        } else if (!vp_drv && vf_drv) {
 207                port_drv = &vf_drv->base_port;
 208                port_drv->pvb_type = BFAD_PORT_VF_BASE;
 209        } else if (vp_drv && !vf_drv) {
 210                port_drv = &vp_drv->drv_port;
 211                port_drv->pvb_type = BFAD_PORT_PHYS_VPORT;
 212        } else {
 213                port_drv = &vp_drv->drv_port;
 214                port_drv->pvb_type = BFAD_PORT_VF_VPORT;
 215        }
 216
 217        port_drv->fcs_port = port;
 218        port_drv->roles = roles;
 219        rc = bfad_fc4_port_new(bfad, port_drv, roles);
 220        if (rc != BFA_STATUS_OK) {
 221                bfad_fc4_port_delete(bfad, port_drv, roles);
 222                port_drv = NULL;
 223        }
 224
 225        return port_drv;
 226}
 227
 228void
 229bfa_fcb_port_delete(struct bfad_s *bfad, enum bfa_port_role roles,
 230                    struct bfad_vf_s *vf_drv, struct bfad_vport_s *vp_drv)
 231{
 232        struct bfad_port_s *port_drv;
 233
 234        /*
 235         * this will be only called from rmmod context
 236         */
 237        if (vp_drv && !vp_drv->comp_del) {
 238                port_drv = bfad_get_drv_port(bfad, vf_drv, vp_drv);
 239                bfa_trc(bfad, roles);
 240                bfad_fc4_port_delete(bfad, port_drv, roles);
 241        }
 242}
 243
 244void
 245bfa_fcb_port_online(struct bfad_s *bfad, enum bfa_port_role roles,
 246                    struct bfad_vf_s *vf_drv, struct bfad_vport_s *vp_drv)
 247{
 248        struct bfad_port_s *port_drv = bfad_get_drv_port(bfad, vf_drv, vp_drv);
 249
 250        if (roles & BFA_PORT_ROLE_FCP_IM)
 251                bfad_im_port_online(bfad, port_drv);
 252
 253        if (roles & BFA_PORT_ROLE_FCP_TM)
 254                bfad_tm_port_online(bfad, port_drv);
 255
 256        if ((roles & BFA_PORT_ROLE_FCP_IPFC) && ipfc_enable)
 257                bfad_ipfc_port_online(bfad, port_drv);
 258
 259        bfad->bfad_flags |= BFAD_PORT_ONLINE;
 260}
 261
 262void
 263bfa_fcb_port_offline(struct bfad_s *bfad, enum bfa_port_role roles,
 264                     struct bfad_vf_s *vf_drv, struct bfad_vport_s *vp_drv)
 265{
 266        struct bfad_port_s *port_drv = bfad_get_drv_port(bfad, vf_drv, vp_drv);
 267
 268        if (roles & BFA_PORT_ROLE_FCP_IM)
 269                bfad_im_port_offline(bfad, port_drv);
 270
 271        if (roles & BFA_PORT_ROLE_FCP_TM)
 272                bfad_tm_port_offline(bfad, port_drv);
 273
 274        if ((roles & BFA_PORT_ROLE_FCP_IPFC) && ipfc_enable)
 275                bfad_ipfc_port_offline(bfad, port_drv);
 276}
 277
 278void
 279bfa_fcb_vport_delete(struct bfad_vport_s *vport_drv)
 280{
 281        if (vport_drv->comp_del) {
 282                complete(vport_drv->comp_del);
 283                return;
 284        }
 285
 286        kfree(vport_drv);
 287}
 288
 289/**
 290 * FCS RPORT alloc callback, after successful PLOGI by FCS
 291 */
 292bfa_status_t
 293bfa_fcb_rport_alloc(struct bfad_s *bfad, struct bfa_fcs_rport_s **rport,
 294                    struct bfad_rport_s **rport_drv)
 295{
 296        bfa_status_t    rc = BFA_STATUS_OK;
 297
 298        *rport_drv = kzalloc(sizeof(struct bfad_rport_s), GFP_ATOMIC);
 299        if (*rport_drv == NULL) {
 300                rc = BFA_STATUS_ENOMEM;
 301                goto ext;
 302        }
 303
 304        *rport = &(*rport_drv)->fcs_rport;
 305
 306ext:
 307        return rc;
 308}
 309
 310
 311
 312void
 313bfad_hal_mem_release(struct bfad_s *bfad)
 314{
 315        int             i;
 316        struct bfa_meminfo_s *hal_meminfo = &bfad->meminfo;
 317        struct bfa_mem_elem_s *meminfo_elem;
 318
 319        for (i = 0; i < BFA_MEM_TYPE_MAX; i++) {
 320                meminfo_elem = &hal_meminfo->meminfo[i];
 321                if (meminfo_elem->kva != NULL) {
 322                        switch (meminfo_elem->mem_type) {
 323                        case BFA_MEM_TYPE_KVA:
 324                                vfree(meminfo_elem->kva);
 325                                break;
 326                        case BFA_MEM_TYPE_DMA:
 327                                dma_free_coherent(&bfad->pcidev->dev,
 328                                                meminfo_elem->mem_len,
 329                                                meminfo_elem->kva,
 330                                                (dma_addr_t) meminfo_elem->dma);
 331                                break;
 332                        default:
 333                                bfa_assert(0);
 334                                break;
 335                        }
 336                }
 337        }
 338
 339        memset(hal_meminfo, 0, sizeof(struct bfa_meminfo_s));
 340}
 341
 342void
 343bfad_update_hal_cfg(struct bfa_iocfc_cfg_s *bfa_cfg)
 344{
 345        if (num_rports > 0)
 346                bfa_cfg->fwcfg.num_rports = num_rports;
 347        if (num_ios > 0)
 348                bfa_cfg->fwcfg.num_ioim_reqs = num_ios;
 349        if (num_tms > 0)
 350                bfa_cfg->fwcfg.num_tskim_reqs = num_tms;
 351        if (num_fcxps > 0)
 352                bfa_cfg->fwcfg.num_fcxp_reqs = num_fcxps;
 353        if (num_ufbufs > 0)
 354                bfa_cfg->fwcfg.num_uf_bufs = num_ufbufs;
 355        if (reqq_size > 0)
 356                bfa_cfg->drvcfg.num_reqq_elems = reqq_size;
 357        if (rspq_size > 0)
 358                bfa_cfg->drvcfg.num_rspq_elems = rspq_size;
 359        if (num_sgpgs > 0)
 360                bfa_cfg->drvcfg.num_sgpgs = num_sgpgs;
 361
 362        /*
 363         * populate the hal values back to the driver for sysfs use.
 364         * otherwise, the default values will be shown as 0 in sysfs
 365         */
 366        num_rports = bfa_cfg->fwcfg.num_rports;
 367        num_ios    = bfa_cfg->fwcfg.num_ioim_reqs;
 368        num_tms    = bfa_cfg->fwcfg.num_tskim_reqs;
 369        num_fcxps  = bfa_cfg->fwcfg.num_fcxp_reqs;
 370        num_ufbufs = bfa_cfg->fwcfg.num_uf_bufs;
 371        reqq_size  = bfa_cfg->drvcfg.num_reqq_elems;
 372        rspq_size  = bfa_cfg->drvcfg.num_rspq_elems;
 373        num_sgpgs  = bfa_cfg->drvcfg.num_sgpgs;
 374}
 375
 376bfa_status_t
 377bfad_hal_mem_alloc(struct bfad_s *bfad)
 378{
 379        struct bfa_meminfo_s *hal_meminfo = &bfad->meminfo;
 380        struct bfa_mem_elem_s *meminfo_elem;
 381        bfa_status_t    rc = BFA_STATUS_OK;
 382        dma_addr_t      phys_addr;
 383        int             retry_count = 0;
 384        int             reset_value = 1;
 385        int             min_num_sgpgs = 512;
 386        void           *kva;
 387        int             i;
 388
 389        bfa_cfg_get_default(&bfad->ioc_cfg);
 390
 391retry:
 392        bfad_update_hal_cfg(&bfad->ioc_cfg);
 393        bfad->cfg_data.ioc_queue_depth = bfad->ioc_cfg.fwcfg.num_ioim_reqs;
 394        bfa_cfg_get_meminfo(&bfad->ioc_cfg, hal_meminfo);
 395
 396        for (i = 0; i < BFA_MEM_TYPE_MAX; i++) {
 397                meminfo_elem = &hal_meminfo->meminfo[i];
 398                switch (meminfo_elem->mem_type) {
 399                case BFA_MEM_TYPE_KVA:
 400                        kva = vmalloc(meminfo_elem->mem_len);
 401                        if (kva == NULL) {
 402                                bfad_hal_mem_release(bfad);
 403                                rc = BFA_STATUS_ENOMEM;
 404                                goto ext;
 405                        }
 406                        memset(kva, 0, meminfo_elem->mem_len);
 407                        meminfo_elem->kva = kva;
 408                        break;
 409                case BFA_MEM_TYPE_DMA:
 410                        kva = dma_alloc_coherent(&bfad->pcidev->dev,
 411                                        meminfo_elem->mem_len,
 412                                        &phys_addr, GFP_KERNEL);
 413                        if (kva == NULL) {
 414                                bfad_hal_mem_release(bfad);
 415                                /*
 416                                 * If we cannot allocate with default
 417                                 * num_sgpages try with half the value.
 418                                 */
 419                                if (num_sgpgs > min_num_sgpgs) {
 420                                        printk(KERN_INFO "bfad[%d]: memory"
 421                                                " allocation failed with"
 422                                                " num_sgpgs: %d\n",
 423                                                bfad->inst_no, num_sgpgs);
 424                                        nextLowerInt(&num_sgpgs);
 425                                        printk(KERN_INFO "bfad[%d]: trying to"
 426                                                " allocate memory with"
 427                                                " num_sgpgs: %d\n",
 428                                                bfad->inst_no, num_sgpgs);
 429                                        retry_count++;
 430                                        goto retry;
 431                                } else {
 432                                        if (num_sgpgs_parm > 0)
 433                                                num_sgpgs = num_sgpgs_parm;
 434                                        else {
 435                                                reset_value =
 436                                                        (1 << retry_count);
 437                                                num_sgpgs *= reset_value;
 438                                        }
 439                                        rc = BFA_STATUS_ENOMEM;
 440                                        goto ext;
 441                                }
 442                        }
 443
 444                        if (num_sgpgs_parm > 0)
 445                                num_sgpgs = num_sgpgs_parm;
 446                        else {
 447                                reset_value = (1 << retry_count);
 448                                num_sgpgs *= reset_value;
 449                        }
 450
 451                        memset(kva, 0, meminfo_elem->mem_len);
 452                        meminfo_elem->kva = kva;
 453                        meminfo_elem->dma = phys_addr;
 454                        break;
 455                default:
 456                        break;
 457
 458                }
 459        }
 460ext:
 461        return rc;
 462}
 463
 464/**
 465 * Create a vport under a vf.
 466 */
 467bfa_status_t
 468bfad_vport_create(struct bfad_s *bfad, u16 vf_id,
 469                  struct bfa_port_cfg_s *port_cfg)
 470{
 471        struct bfad_vport_s *vport;
 472        int             rc = BFA_STATUS_OK;
 473        unsigned long   flags;
 474        struct completion fcomp;
 475
 476        vport = kzalloc(sizeof(struct bfad_vport_s), GFP_KERNEL);
 477        if (!vport) {
 478                rc = BFA_STATUS_ENOMEM;
 479                goto ext;
 480        }
 481
 482        vport->drv_port.bfad = bfad;
 483        spin_lock_irqsave(&bfad->bfad_lock, flags);
 484        rc = bfa_fcs_vport_create(&vport->fcs_vport, &bfad->bfa_fcs, vf_id,
 485                                  port_cfg, vport);
 486        spin_unlock_irqrestore(&bfad->bfad_lock, flags);
 487
 488        if (rc != BFA_STATUS_OK)
 489                goto ext_free_vport;
 490
 491        if (port_cfg->roles & BFA_PORT_ROLE_FCP_IM) {
 492                rc = bfad_im_scsi_host_alloc(bfad, vport->drv_port.im_port);
 493                if (rc != BFA_STATUS_OK)
 494                        goto ext_free_fcs_vport;
 495        }
 496
 497        spin_lock_irqsave(&bfad->bfad_lock, flags);
 498        bfa_fcs_vport_start(&vport->fcs_vport);
 499        spin_unlock_irqrestore(&bfad->bfad_lock, flags);
 500
 501        return BFA_STATUS_OK;
 502
 503ext_free_fcs_vport:
 504        spin_lock_irqsave(&bfad->bfad_lock, flags);
 505        vport->comp_del = &fcomp;
 506        init_completion(vport->comp_del);
 507        bfa_fcs_vport_delete(&vport->fcs_vport);
 508        spin_unlock_irqrestore(&bfad->bfad_lock, flags);
 509        wait_for_completion(vport->comp_del);
 510ext_free_vport:
 511        kfree(vport);
 512ext:
 513        return rc;
 514}
 515
 516/**
 517 * Create a vf and its base vport implicitely.
 518 */
 519bfa_status_t
 520bfad_vf_create(struct bfad_s *bfad, u16 vf_id,
 521               struct bfa_port_cfg_s *port_cfg)
 522{
 523        struct bfad_vf_s *vf;
 524        int             rc = BFA_STATUS_OK;
 525
 526        vf = kzalloc(sizeof(struct bfad_vf_s), GFP_KERNEL);
 527        if (!vf) {
 528                rc = BFA_STATUS_FAILED;
 529                goto ext;
 530        }
 531
 532        rc = bfa_fcs_vf_create(&vf->fcs_vf, &bfad->bfa_fcs, vf_id, port_cfg,
 533                               vf);
 534        if (rc != BFA_STATUS_OK)
 535                kfree(vf);
 536ext:
 537        return rc;
 538}
 539
 540void
 541bfad_bfa_tmo(unsigned long data)
 542{
 543        struct bfad_s  *bfad = (struct bfad_s *)data;
 544        unsigned long   flags;
 545        struct list_head  doneq;
 546
 547        spin_lock_irqsave(&bfad->bfad_lock, flags);
 548
 549        bfa_timer_tick(&bfad->bfa);
 550
 551        bfa_comp_deq(&bfad->bfa, &doneq);
 552        spin_unlock_irqrestore(&bfad->bfad_lock, flags);
 553
 554        if (!list_empty(&doneq)) {
 555                bfa_comp_process(&bfad->bfa, &doneq);
 556                spin_lock_irqsave(&bfad->bfad_lock, flags);
 557                bfa_comp_free(&bfad->bfa, &doneq);
 558                spin_unlock_irqrestore(&bfad->bfad_lock, flags);
 559        }
 560
 561        mod_timer(&bfad->hal_tmo, jiffies + msecs_to_jiffies(BFA_TIMER_FREQ));
 562}
 563
 564void
 565bfad_init_timer(struct bfad_s *bfad)
 566{
 567        init_timer(&bfad->hal_tmo);
 568        bfad->hal_tmo.function = bfad_bfa_tmo;
 569        bfad->hal_tmo.data = (unsigned long)bfad;
 570
 571        mod_timer(&bfad->hal_tmo, jiffies + msecs_to_jiffies(BFA_TIMER_FREQ));
 572}
 573
 574int
 575bfad_pci_init(struct pci_dev *pdev, struct bfad_s *bfad)
 576{
 577        unsigned long   bar0_len;
 578        int             rc = -ENODEV;
 579
 580        if (pci_enable_device(pdev)) {
 581                BFA_PRINTF(BFA_ERR, "pci_enable_device fail %p\n", pdev);
 582                goto out;
 583        }
 584
 585        if (pci_request_regions(pdev, BFAD_DRIVER_NAME))
 586                goto out_disable_device;
 587
 588        pci_set_master(pdev);
 589
 590
 591        if (pci_set_dma_mask(pdev, DMA_BIT_MASK(64)) != 0)
 592                if (pci_set_dma_mask(pdev, DMA_BIT_MASK(32)) != 0) {
 593                        BFA_PRINTF(BFA_ERR, "pci_set_dma_mask fail %p\n", pdev);
 594                        goto out_release_region;
 595                }
 596
 597        bfad->pci_bar0_map = pci_resource_start(pdev, 0);
 598        bar0_len = pci_resource_len(pdev, 0);
 599        bfad->pci_bar0_kva = ioremap(bfad->pci_bar0_map, bar0_len);
 600
 601        if (bfad->pci_bar0_kva == NULL) {
 602                BFA_PRINTF(BFA_ERR, "Fail to map bar0\n");
 603                goto out_release_region;
 604        }
 605
 606        bfad->hal_pcidev.pci_slot = PCI_SLOT(pdev->devfn);
 607        bfad->hal_pcidev.pci_func = PCI_FUNC(pdev->devfn);
 608        bfad->hal_pcidev.pci_bar_kva = bfad->pci_bar0_kva;
 609        bfad->hal_pcidev.device_id = pdev->device;
 610        bfad->pci_name = pci_name(pdev);
 611
 612        bfad->pci_attr.vendor_id = pdev->vendor;
 613        bfad->pci_attr.device_id = pdev->device;
 614        bfad->pci_attr.ssid = pdev->subsystem_device;
 615        bfad->pci_attr.ssvid = pdev->subsystem_vendor;
 616        bfad->pci_attr.pcifn = PCI_FUNC(pdev->devfn);
 617
 618        bfad->pcidev = pdev;
 619        return 0;
 620
 621out_release_region:
 622        pci_release_regions(pdev);
 623out_disable_device:
 624        pci_disable_device(pdev);
 625out:
 626        return rc;
 627}
 628
 629void
 630bfad_pci_uninit(struct pci_dev *pdev, struct bfad_s *bfad)
 631{
 632#if defined(__ia64__)
 633        pci_iounmap(pdev, bfad->pci_bar0_kva);
 634#else
 635        iounmap(bfad->pci_bar0_kva);
 636#endif
 637        pci_release_regions(pdev);
 638        pci_disable_device(pdev);
 639        pci_set_drvdata(pdev, NULL);
 640}
 641
 642void
 643bfad_fcs_port_cfg(struct bfad_s *bfad)
 644{
 645        struct bfa_port_cfg_s port_cfg;
 646        struct bfa_pport_attr_s attr;
 647        char            symname[BFA_SYMNAME_MAXLEN];
 648
 649        sprintf(symname, "%s-%d", BFAD_DRIVER_NAME, bfad->inst_no);
 650        memcpy(port_cfg.sym_name.symname, symname, strlen(symname));
 651        bfa_pport_get_attr(&bfad->bfa, &attr);
 652        port_cfg.nwwn = attr.nwwn;
 653        port_cfg.pwwn = attr.pwwn;
 654
 655        bfa_fcs_cfg_base_port(&bfad->bfa_fcs, &port_cfg);
 656}
 657
 658bfa_status_t
 659bfad_drv_init(struct bfad_s *bfad)
 660{
 661        bfa_status_t    rc;
 662        unsigned long   flags;
 663        struct bfa_fcs_driver_info_s driver_info;
 664        int             i;
 665
 666        bfad->cfg_data.rport_del_timeout = rport_del_timeout;
 667        bfad->cfg_data.lun_queue_depth = bfa_lun_queue_depth;
 668        bfad->cfg_data.io_max_sge = bfa_io_max_sge;
 669        bfad->cfg_data.binding_method = FCP_PWWN_BINDING;
 670
 671        rc = bfad_hal_mem_alloc(bfad);
 672        if (rc != BFA_STATUS_OK) {
 673                printk(KERN_WARNING "bfad%d bfad_hal_mem_alloc failure\n",
 674                       bfad->inst_no);
 675                printk(KERN_WARNING
 676                        "Not enough memory to attach all Brocade HBA ports,"
 677                        " System may need more memory.\n");
 678                goto out_hal_mem_alloc_failure;
 679        }
 680
 681        bfa_init_log(&bfad->bfa, bfad->logmod);
 682        bfa_init_trc(&bfad->bfa, bfad->trcmod);
 683        bfa_init_aen(&bfad->bfa, bfad->aen);
 684        INIT_LIST_HEAD(&bfad->file_q);
 685        INIT_LIST_HEAD(&bfad->file_free_q);
 686        for (i = 0; i < BFAD_AEN_MAX_APPS; i++) {
 687                bfa_q_qe_init(&bfad->file_buf[i].qe);
 688                list_add_tail(&bfad->file_buf[i].qe, &bfad->file_free_q);
 689        }
 690        bfa_init_plog(&bfad->bfa, &bfad->plog_buf);
 691        bfa_plog_init(&bfad->plog_buf);
 692        bfa_plog_str(&bfad->plog_buf, BFA_PL_MID_DRVR, BFA_PL_EID_DRIVER_START,
 693                     0, "Driver Attach");
 694
 695        bfa_attach(&bfad->bfa, bfad, &bfad->ioc_cfg, &bfad->meminfo,
 696                   &bfad->hal_pcidev);
 697
 698        init_completion(&bfad->comp);
 699
 700        /*
 701         * Enable Interrupt and wait bfa_init completion
 702         */
 703        if (bfad_setup_intr(bfad)) {
 704                printk(KERN_WARNING "bfad%d: bfad_setup_intr failed\n",
 705                       bfad->inst_no);
 706                goto out_setup_intr_failure;
 707        }
 708
 709        spin_lock_irqsave(&bfad->bfad_lock, flags);
 710        bfa_init(&bfad->bfa);
 711        spin_unlock_irqrestore(&bfad->bfad_lock, flags);
 712
 713        /*
 714         * Set up interrupt handler for each vectors
 715         */
 716        if ((bfad->bfad_flags & BFAD_MSIX_ON)
 717            && bfad_install_msix_handler(bfad)) {
 718                printk(KERN_WARNING "%s: install_msix failed, bfad%d\n",
 719                       __FUNCTION__, bfad->inst_no);
 720        }
 721
 722        bfad_init_timer(bfad);
 723
 724        wait_for_completion(&bfad->comp);
 725
 726        memset(&driver_info, 0, sizeof(driver_info));
 727        strncpy(driver_info.version, BFAD_DRIVER_VERSION,
 728                sizeof(driver_info.version) - 1);
 729        if (host_name)
 730                strncpy(driver_info.host_machine_name, host_name,
 731                        sizeof(driver_info.host_machine_name) - 1);
 732        if (os_name)
 733                strncpy(driver_info.host_os_name, os_name,
 734                        sizeof(driver_info.host_os_name) - 1);
 735        if (os_patch)
 736                strncpy(driver_info.host_os_patch, os_patch,
 737                        sizeof(driver_info.host_os_patch) - 1);
 738
 739        strncpy(driver_info.os_device_name, bfad->pci_name,
 740                sizeof(driver_info.os_device_name - 1));
 741
 742        /*
 743         * FCS INIT
 744         */
 745        spin_lock_irqsave(&bfad->bfad_lock, flags);
 746        bfa_fcs_log_init(&bfad->bfa_fcs, bfad->logmod);
 747        bfa_fcs_trc_init(&bfad->bfa_fcs, bfad->trcmod);
 748        bfa_fcs_aen_init(&bfad->bfa_fcs, bfad->aen);
 749        bfa_fcs_init(&bfad->bfa_fcs, &bfad->bfa, bfad, BFA_FALSE);
 750        bfa_fcs_driver_info_init(&bfad->bfa_fcs, &driver_info);
 751        spin_unlock_irqrestore(&bfad->bfad_lock, flags);
 752
 753        bfad->bfad_flags |= BFAD_DRV_INIT_DONE;
 754        return BFA_STATUS_OK;
 755
 756out_setup_intr_failure:
 757        bfa_detach(&bfad->bfa);
 758        bfad_hal_mem_release(bfad);
 759out_hal_mem_alloc_failure:
 760        return BFA_STATUS_FAILED;
 761}
 762
 763void
 764bfad_drv_uninit(struct bfad_s *bfad)
 765{
 766        del_timer_sync(&bfad->hal_tmo);
 767        bfa_isr_disable(&bfad->bfa);
 768        bfa_detach(&bfad->bfa);
 769        bfad_remove_intr(bfad);
 770        bfa_assert(list_empty(&bfad->file_q));
 771        bfad_hal_mem_release(bfad);
 772}
 773
 774void
 775bfad_drv_start(struct bfad_s *bfad)
 776{
 777        unsigned long   flags;
 778
 779        spin_lock_irqsave(&bfad->bfad_lock, flags);
 780        bfa_start(&bfad->bfa);
 781        bfa_fcs_start(&bfad->bfa_fcs);
 782        bfad->bfad_flags |= BFAD_HAL_START_DONE;
 783        spin_unlock_irqrestore(&bfad->bfad_lock, flags);
 784
 785        bfad_fc4_probe_post(bfad);
 786}
 787
 788void
 789bfad_drv_stop(struct bfad_s *bfad)
 790{
 791        unsigned long   flags;
 792
 793        spin_lock_irqsave(&bfad->bfad_lock, flags);
 794        init_completion(&bfad->comp);
 795        bfad->pport.flags |= BFAD_PORT_DELETE;
 796        bfa_fcs_exit(&bfad->bfa_fcs);
 797        spin_unlock_irqrestore(&bfad->bfad_lock, flags);
 798        wait_for_completion(&bfad->comp);
 799
 800        spin_lock_irqsave(&bfad->bfad_lock, flags);
 801        init_completion(&bfad->comp);
 802        bfa_stop(&bfad->bfa);
 803        bfad->bfad_flags &= ~BFAD_HAL_START_DONE;
 804        spin_unlock_irqrestore(&bfad->bfad_lock, flags);
 805        wait_for_completion(&bfad->comp);
 806}
 807
 808bfa_status_t
 809bfad_cfg_pport(struct bfad_s *bfad, enum bfa_port_role role)
 810{
 811        int             rc = BFA_STATUS_OK;
 812
 813        /*
 814         * Allocate scsi_host for the physical port
 815         */
 816        if ((bfad_supported_fc4s & BFA_PORT_ROLE_FCP_IM)
 817            && (role & BFA_PORT_ROLE_FCP_IM)) {
 818                if (bfad->pport.im_port == NULL) {
 819                        rc = BFA_STATUS_FAILED;
 820                        goto out;
 821                }
 822
 823                rc = bfad_im_scsi_host_alloc(bfad, bfad->pport.im_port);
 824                if (rc != BFA_STATUS_OK)
 825                        goto out;
 826
 827                bfad->pport.roles |= BFA_PORT_ROLE_FCP_IM;
 828        }
 829
 830        bfad->bfad_flags |= BFAD_CFG_PPORT_DONE;
 831
 832out:
 833        return rc;
 834}
 835
 836void
 837bfad_uncfg_pport(struct bfad_s *bfad)
 838{
 839        if ((bfad->pport.roles & BFA_PORT_ROLE_FCP_IPFC) && ipfc_enable) {
 840                bfad_ipfc_port_delete(bfad, &bfad->pport);
 841                bfad->pport.roles &= ~BFA_PORT_ROLE_FCP_IPFC;
 842        }
 843
 844        if ((bfad_supported_fc4s & BFA_PORT_ROLE_FCP_IM)
 845            && (bfad->pport.roles & BFA_PORT_ROLE_FCP_IM)) {
 846                bfad_im_scsi_host_free(bfad, bfad->pport.im_port);
 847                bfad_im_port_clean(bfad->pport.im_port);
 848                kfree(bfad->pport.im_port);
 849                bfad->pport.roles &= ~BFA_PORT_ROLE_FCP_IM;
 850        }
 851
 852        bfad->bfad_flags &= ~BFAD_CFG_PPORT_DONE;
 853}
 854
 855void
 856bfad_drv_log_level_set(struct bfad_s *bfad)
 857{
 858        if (log_level > BFA_LOG_INVALID && log_level <= BFA_LOG_LEVEL_MAX)
 859                bfa_log_set_level_all(&bfad->log_data, log_level);
 860}
 861
 862 /*
 863  *  PCI_entry PCI driver entries * {
 864  */
 865
 866/**
 867 * PCI probe entry.
 868 */
 869int
 870bfad_pci_probe(struct pci_dev *pdev, const struct pci_device_id *pid)
 871{
 872        struct bfad_s  *bfad;
 873        int             error = -ENODEV, retval;
 874        char            buf[16];
 875
 876        /*
 877         * For single port cards - only claim function 0
 878         */
 879        if ((pdev->device == BFA_PCI_DEVICE_ID_FC_8G1P)
 880            && (PCI_FUNC(pdev->devfn) != 0))
 881                return -ENODEV;
 882
 883        BFA_TRACE(BFA_INFO, "bfad_pci_probe entry");
 884
 885        bfad = kzalloc(sizeof(struct bfad_s), GFP_KERNEL);
 886        if (!bfad) {
 887                error = -ENOMEM;
 888                goto out;
 889        }
 890
 891        bfad->trcmod = kzalloc(sizeof(struct bfa_trc_mod_s), GFP_KERNEL);
 892        if (!bfad->trcmod) {
 893                printk(KERN_WARNING "Error alloc trace buffer!\n");
 894                error = -ENOMEM;
 895                goto out_alloc_trace_failure;
 896        }
 897
 898        /*
 899         * LOG/TRACE INIT
 900         */
 901        bfa_trc_init(bfad->trcmod);
 902        bfa_trc(bfad, bfad_inst);
 903
 904        bfad->logmod = &bfad->log_data;
 905        sprintf(buf, "%d", bfad_inst);
 906        bfa_log_init(bfad->logmod, buf, bfa_os_printf);
 907
 908        bfad_drv_log_level_set(bfad);
 909
 910        bfad->aen = &bfad->aen_buf;
 911
 912        if (!(bfad_load_fwimg(pdev))) {
 913                printk(KERN_WARNING "bfad_load_fwimg failure!\n");
 914                kfree(bfad->trcmod);
 915                goto out_alloc_trace_failure;
 916        }
 917
 918        retval = bfad_pci_init(pdev, bfad);
 919        if (retval) {
 920                printk(KERN_WARNING "bfad_pci_init failure!\n");
 921                error = retval;
 922                goto out_pci_init_failure;
 923        }
 924
 925        mutex_lock(&bfad_mutex);
 926        bfad->inst_no = bfad_inst++;
 927        list_add_tail(&bfad->list_entry, &bfad_list);
 928        mutex_unlock(&bfad_mutex);
 929
 930        spin_lock_init(&bfad->bfad_lock);
 931        pci_set_drvdata(pdev, bfad);
 932
 933        bfad->ref_count = 0;
 934        bfad->pport.bfad = bfad;
 935
 936        retval = bfad_drv_init(bfad);
 937        if (retval != BFA_STATUS_OK)
 938                goto out_drv_init_failure;
 939        if (!(bfad->bfad_flags & BFAD_HAL_INIT_DONE)) {
 940                printk(KERN_WARNING "bfad%d: hal init failed\n", bfad->inst_no);
 941                goto ok;
 942        }
 943
 944        /*
 945         * PPORT FCS config
 946         */
 947        bfad_fcs_port_cfg(bfad);
 948
 949        retval = bfad_cfg_pport(bfad, BFA_PORT_ROLE_FCP_IM);
 950        if (retval != BFA_STATUS_OK)
 951                goto out_cfg_pport_failure;
 952
 953        /*
 954         * BFAD level FC4 (IM/TM/IPFC) specific resource allocation
 955         */
 956        retval = bfad_fc4_probe(bfad);
 957        if (retval != BFA_STATUS_OK) {
 958                printk(KERN_WARNING "bfad_fc4_probe failed\n");
 959                goto out_fc4_probe_failure;
 960        }
 961
 962        bfad_drv_start(bfad);
 963
 964        /*
 965         * If bfa_linkup_delay is set to -1 default; try to retrive the
 966         * value using the bfad_os_get_linkup_delay(); else use the
 967         * passed in module param value as the bfa_linkup_delay.
 968         */
 969        if (bfa_linkup_delay < 0) {
 970                bfa_linkup_delay = bfad_os_get_linkup_delay(bfad);
 971                bfad_os_rport_online_wait(bfad);
 972                bfa_linkup_delay = -1;
 973        } else {
 974                bfad_os_rport_online_wait(bfad);
 975        }
 976
 977        bfa_log(bfad->logmod, BFA_LOG_LINUX_DEVICE_CLAIMED, bfad->pci_name);
 978ok:
 979        return 0;
 980
 981out_fc4_probe_failure:
 982        bfad_fc4_probe_undo(bfad);
 983        bfad_uncfg_pport(bfad);
 984out_cfg_pport_failure:
 985        bfad_drv_uninit(bfad);
 986out_drv_init_failure:
 987        mutex_lock(&bfad_mutex);
 988        bfad_inst--;
 989        list_del(&bfad->list_entry);
 990        mutex_unlock(&bfad_mutex);
 991        bfad_pci_uninit(pdev, bfad);
 992out_pci_init_failure:
 993        kfree(bfad->trcmod);
 994out_alloc_trace_failure:
 995        kfree(bfad);
 996out:
 997        return error;
 998}
 999
1000/**
1001 * PCI remove entry.
1002 */
1003void
1004bfad_pci_remove(struct pci_dev *pdev)
1005{
1006        struct bfad_s  *bfad = pci_get_drvdata(pdev);
1007        unsigned long   flags;
1008
1009        bfa_trc(bfad, bfad->inst_no);
1010
1011        if ((bfad->bfad_flags & BFAD_DRV_INIT_DONE)
1012            && !(bfad->bfad_flags & BFAD_HAL_INIT_DONE)) {
1013
1014                spin_lock_irqsave(&bfad->bfad_lock, flags);
1015                init_completion(&bfad->comp);
1016                bfa_stop(&bfad->bfa);
1017                spin_unlock_irqrestore(&bfad->bfad_lock, flags);
1018                wait_for_completion(&bfad->comp);
1019
1020                bfad_remove_intr(bfad);
1021                del_timer_sync(&bfad->hal_tmo);
1022                goto hal_detach;
1023        } else if (!(bfad->bfad_flags & BFAD_DRV_INIT_DONE)) {
1024                goto remove_sysfs;
1025        }
1026
1027        if (bfad->bfad_flags & BFAD_HAL_START_DONE)
1028                bfad_drv_stop(bfad);
1029
1030        bfad_remove_intr(bfad);
1031
1032        del_timer_sync(&bfad->hal_tmo);
1033        bfad_fc4_probe_undo(bfad);
1034
1035        if (bfad->bfad_flags & BFAD_CFG_PPORT_DONE)
1036                bfad_uncfg_pport(bfad);
1037
1038hal_detach:
1039        spin_lock_irqsave(&bfad->bfad_lock, flags);
1040        bfa_detach(&bfad->bfa);
1041        spin_unlock_irqrestore(&bfad->bfad_lock, flags);
1042        bfad_hal_mem_release(bfad);
1043remove_sysfs:
1044
1045        mutex_lock(&bfad_mutex);
1046        bfad_inst--;
1047        list_del(&bfad->list_entry);
1048        mutex_unlock(&bfad_mutex);
1049        bfad_pci_uninit(pdev, bfad);
1050
1051        kfree(bfad->trcmod);
1052        kfree(bfad);
1053}
1054
1055
1056static struct pci_device_id bfad_id_table[] = {
1057        {
1058         .vendor = BFA_PCI_VENDOR_ID_BROCADE,
1059         .device = BFA_PCI_DEVICE_ID_FC_8G2P,
1060         .subvendor = PCI_ANY_ID,
1061         .subdevice = PCI_ANY_ID,
1062         },
1063        {
1064         .vendor = BFA_PCI_VENDOR_ID_BROCADE,
1065         .device = BFA_PCI_DEVICE_ID_FC_8G1P,
1066         .subvendor = PCI_ANY_ID,
1067         .subdevice = PCI_ANY_ID,
1068         },
1069        {
1070         .vendor = BFA_PCI_VENDOR_ID_BROCADE,
1071         .device = BFA_PCI_DEVICE_ID_CT,
1072         .subvendor = PCI_ANY_ID,
1073         .subdevice = PCI_ANY_ID,
1074         .class = (PCI_CLASS_SERIAL_FIBER << 8),
1075         .class_mask = ~0,
1076         },
1077
1078        {0, 0},
1079};
1080
1081MODULE_DEVICE_TABLE(pci, bfad_id_table);
1082
1083static struct pci_driver bfad_pci_driver = {
1084        .name = BFAD_DRIVER_NAME,
1085        .id_table = bfad_id_table,
1086        .probe = bfad_pci_probe,
1087        .remove = __devexit_p(bfad_pci_remove),
1088};
1089
1090/**
1091 *  Linux driver module functions
1092 */
1093bfa_status_t
1094bfad_fc4_module_init(void)
1095{
1096        int             rc;
1097
1098        rc = bfad_im_module_init();
1099        if (rc != BFA_STATUS_OK)
1100                goto ext;
1101
1102        bfad_tm_module_init();
1103        if (ipfc_enable)
1104                bfad_ipfc_module_init();
1105ext:
1106        return rc;
1107}
1108
1109void
1110bfad_fc4_module_exit(void)
1111{
1112        if (ipfc_enable)
1113                bfad_ipfc_module_exit();
1114        bfad_tm_module_exit();
1115        bfad_im_module_exit();
1116}
1117
1118/**
1119 * Driver module init.
1120 */
1121static int      __init
1122bfad_init(void)
1123{
1124        int             error = 0;
1125
1126        printk(KERN_INFO "Brocade BFA FC/FCOE SCSI driver - version: %s\n",
1127               BFAD_DRIVER_VERSION);
1128
1129        if (num_sgpgs > 0)
1130                num_sgpgs_parm = num_sgpgs;
1131
1132        error = bfad_fc4_module_init();
1133        if (error) {
1134                error = -ENOMEM;
1135                printk(KERN_WARNING "bfad_fc4_module_init failure\n");
1136                goto ext;
1137        }
1138
1139        if (!strcmp(FCPI_NAME, " fcpim"))
1140                bfad_supported_fc4s |= BFA_PORT_ROLE_FCP_IM;
1141        if (!strcmp(FCPT_NAME, " fcptm"))
1142                bfad_supported_fc4s |= BFA_PORT_ROLE_FCP_TM;
1143        if (!strcmp(IPFC_NAME, " ipfc"))
1144                bfad_supported_fc4s |= BFA_PORT_ROLE_FCP_IPFC;
1145
1146        bfa_ioc_auto_recover(ioc_auto_recover);
1147        bfa_fcs_rport_set_del_timeout(rport_del_timeout);
1148        error = pci_register_driver(&bfad_pci_driver);
1149
1150        if (error) {
1151                printk(KERN_WARNING "bfad pci_register_driver failure\n");
1152                goto ext;
1153        }
1154
1155        return 0;
1156
1157ext:
1158        bfad_fc4_module_exit();
1159        return error;
1160}
1161
1162/**
1163 * Driver module exit.
1164 */
1165static void     __exit
1166bfad_exit(void)
1167{
1168        pci_unregister_driver(&bfad_pci_driver);
1169        bfad_fc4_module_exit();
1170        bfad_free_fwimg();
1171}
1172
1173#define BFAD_PROTO_NAME FCPI_NAME FCPT_NAME IPFC_NAME
1174
1175module_init(bfad_init);
1176module_exit(bfad_exit);
1177MODULE_LICENSE("GPL");
1178MODULE_DESCRIPTION("Brocade Fibre Channel HBA Driver" BFAD_PROTO_NAME);
1179MODULE_AUTHOR("Brocade Communications Systems, Inc.");
1180MODULE_VERSION(BFAD_DRIVER_VERSION);
1181
1182
1183