linux/drivers/scsi/bfa/bfad_attr.c
<<
>>
Prefs
   1/*
   2 * Copyright (c) 2005-2010 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 *  bfa_attr.c Linux driver configuration interface module.
  20 */
  21
  22#include "bfad_drv.h"
  23#include "bfad_im.h"
  24
  25/*
  26 * FC transport template entry, get SCSI target port ID.
  27 */
  28static void
  29bfad_im_get_starget_port_id(struct scsi_target *starget)
  30{
  31        struct Scsi_Host *shost;
  32        struct bfad_im_port_s *im_port;
  33        struct bfad_s         *bfad;
  34        struct bfad_itnim_s   *itnim = NULL;
  35        u32        fc_id = -1;
  36        unsigned long   flags;
  37
  38        shost = dev_to_shost(starget->dev.parent);
  39        im_port = (struct bfad_im_port_s *) shost->hostdata[0];
  40        bfad = im_port->bfad;
  41        spin_lock_irqsave(&bfad->bfad_lock, flags);
  42
  43        itnim = bfad_get_itnim(im_port, starget->id);
  44        if (itnim)
  45                fc_id = bfa_fcs_itnim_get_fcid(&itnim->fcs_itnim);
  46
  47        fc_starget_port_id(starget) = fc_id;
  48        spin_unlock_irqrestore(&bfad->bfad_lock, flags);
  49}
  50
  51/*
  52 * FC transport template entry, get SCSI target nwwn.
  53 */
  54static void
  55bfad_im_get_starget_node_name(struct scsi_target *starget)
  56{
  57        struct Scsi_Host *shost;
  58        struct bfad_im_port_s *im_port;
  59        struct bfad_s         *bfad;
  60        struct bfad_itnim_s   *itnim = NULL;
  61        u64             node_name = 0;
  62        unsigned long   flags;
  63
  64        shost = dev_to_shost(starget->dev.parent);
  65        im_port = (struct bfad_im_port_s *) shost->hostdata[0];
  66        bfad = im_port->bfad;
  67        spin_lock_irqsave(&bfad->bfad_lock, flags);
  68
  69        itnim = bfad_get_itnim(im_port, starget->id);
  70        if (itnim)
  71                node_name = bfa_fcs_itnim_get_nwwn(&itnim->fcs_itnim);
  72
  73        fc_starget_node_name(starget) = cpu_to_be64(node_name);
  74        spin_unlock_irqrestore(&bfad->bfad_lock, flags);
  75}
  76
  77/*
  78 * FC transport template entry, get SCSI target pwwn.
  79 */
  80static void
  81bfad_im_get_starget_port_name(struct scsi_target *starget)
  82{
  83        struct Scsi_Host *shost;
  84        struct bfad_im_port_s *im_port;
  85        struct bfad_s         *bfad;
  86        struct bfad_itnim_s   *itnim = NULL;
  87        u64             port_name = 0;
  88        unsigned long   flags;
  89
  90        shost = dev_to_shost(starget->dev.parent);
  91        im_port = (struct bfad_im_port_s *) shost->hostdata[0];
  92        bfad = im_port->bfad;
  93        spin_lock_irqsave(&bfad->bfad_lock, flags);
  94
  95        itnim = bfad_get_itnim(im_port, starget->id);
  96        if (itnim)
  97                port_name = bfa_fcs_itnim_get_pwwn(&itnim->fcs_itnim);
  98
  99        fc_starget_port_name(starget) = cpu_to_be64(port_name);
 100        spin_unlock_irqrestore(&bfad->bfad_lock, flags);
 101}
 102
 103/*
 104 * FC transport template entry, get SCSI host port ID.
 105 */
 106static void
 107bfad_im_get_host_port_id(struct Scsi_Host *shost)
 108{
 109        struct bfad_im_port_s *im_port =
 110                        (struct bfad_im_port_s *) shost->hostdata[0];
 111        struct bfad_port_s    *port = im_port->port;
 112
 113        fc_host_port_id(shost) =
 114                        bfa_hton3b(bfa_fcs_lport_get_fcid(port->fcs_port));
 115}
 116
 117/*
 118 * FC transport template entry, get SCSI host port type.
 119 */
 120static void
 121bfad_im_get_host_port_type(struct Scsi_Host *shost)
 122{
 123        struct bfad_im_port_s *im_port =
 124                        (struct bfad_im_port_s *) shost->hostdata[0];
 125        struct bfad_s         *bfad = im_port->bfad;
 126        struct bfa_lport_attr_s port_attr;
 127
 128        bfa_fcs_lport_get_attr(&bfad->bfa_fcs.fabric.bport, &port_attr);
 129
 130        switch (port_attr.port_type) {
 131        case BFA_PORT_TYPE_NPORT:
 132                fc_host_port_type(shost) = FC_PORTTYPE_NPORT;
 133                break;
 134        case BFA_PORT_TYPE_NLPORT:
 135                fc_host_port_type(shost) = FC_PORTTYPE_NLPORT;
 136                break;
 137        case BFA_PORT_TYPE_P2P:
 138                fc_host_port_type(shost) = FC_PORTTYPE_PTP;
 139                break;
 140        case BFA_PORT_TYPE_LPORT:
 141                fc_host_port_type(shost) = FC_PORTTYPE_LPORT;
 142                break;
 143        default:
 144                fc_host_port_type(shost) = FC_PORTTYPE_UNKNOWN;
 145                break;
 146        }
 147}
 148
 149/*
 150 * FC transport template entry, get SCSI host port state.
 151 */
 152static void
 153bfad_im_get_host_port_state(struct Scsi_Host *shost)
 154{
 155        struct bfad_im_port_s *im_port =
 156                        (struct bfad_im_port_s *) shost->hostdata[0];
 157        struct bfad_s         *bfad = im_port->bfad;
 158        struct bfa_port_attr_s attr;
 159
 160        bfa_fcport_get_attr(&bfad->bfa, &attr);
 161
 162        switch (attr.port_state) {
 163        case BFA_PORT_ST_LINKDOWN:
 164                fc_host_port_state(shost) = FC_PORTSTATE_LINKDOWN;
 165                break;
 166        case BFA_PORT_ST_LINKUP:
 167                fc_host_port_state(shost) = FC_PORTSTATE_ONLINE;
 168                break;
 169        case BFA_PORT_ST_DISABLED:
 170        case BFA_PORT_ST_STOPPED:
 171        case BFA_PORT_ST_IOCDOWN:
 172        case BFA_PORT_ST_IOCDIS:
 173                fc_host_port_state(shost) = FC_PORTSTATE_OFFLINE;
 174                break;
 175        case BFA_PORT_ST_UNINIT:
 176        case BFA_PORT_ST_ENABLING_QWAIT:
 177        case BFA_PORT_ST_ENABLING:
 178        case BFA_PORT_ST_DISABLING_QWAIT:
 179        case BFA_PORT_ST_DISABLING:
 180        default:
 181                fc_host_port_state(shost) = FC_PORTSTATE_UNKNOWN;
 182                break;
 183        }
 184}
 185
 186/*
 187 * FC transport template entry, get SCSI host active fc4s.
 188 */
 189static void
 190bfad_im_get_host_active_fc4s(struct Scsi_Host *shost)
 191{
 192        struct bfad_im_port_s *im_port =
 193                        (struct bfad_im_port_s *) shost->hostdata[0];
 194        struct bfad_port_s    *port = im_port->port;
 195
 196        memset(fc_host_active_fc4s(shost), 0,
 197               sizeof(fc_host_active_fc4s(shost)));
 198
 199        if (port->supported_fc4s & BFA_LPORT_ROLE_FCP_IM)
 200                fc_host_active_fc4s(shost)[2] = 1;
 201
 202        fc_host_active_fc4s(shost)[7] = 1;
 203}
 204
 205/*
 206 * FC transport template entry, get SCSI host link speed.
 207 */
 208static void
 209bfad_im_get_host_speed(struct Scsi_Host *shost)
 210{
 211        struct bfad_im_port_s *im_port =
 212                        (struct bfad_im_port_s *) shost->hostdata[0];
 213        struct bfad_s         *bfad = im_port->bfad;
 214        struct bfa_port_attr_s attr;
 215
 216        bfa_fcport_get_attr(&bfad->bfa, &attr);
 217        switch (attr.speed) {
 218        case BFA_PORT_SPEED_10GBPS:
 219                fc_host_speed(shost) = FC_PORTSPEED_10GBIT;
 220                break;
 221        case BFA_PORT_SPEED_16GBPS:
 222                fc_host_speed(shost) = FC_PORTSPEED_16GBIT;
 223                break;
 224        case BFA_PORT_SPEED_8GBPS:
 225                fc_host_speed(shost) = FC_PORTSPEED_8GBIT;
 226                break;
 227        case BFA_PORT_SPEED_4GBPS:
 228                fc_host_speed(shost) = FC_PORTSPEED_4GBIT;
 229                break;
 230        case BFA_PORT_SPEED_2GBPS:
 231                fc_host_speed(shost) = FC_PORTSPEED_2GBIT;
 232                break;
 233        case BFA_PORT_SPEED_1GBPS:
 234                fc_host_speed(shost) = FC_PORTSPEED_1GBIT;
 235                break;
 236        default:
 237                fc_host_speed(shost) = FC_PORTSPEED_UNKNOWN;
 238                break;
 239        }
 240}
 241
 242/*
 243 * FC transport template entry, get SCSI host port type.
 244 */
 245static void
 246bfad_im_get_host_fabric_name(struct Scsi_Host *shost)
 247{
 248        struct bfad_im_port_s *im_port =
 249                        (struct bfad_im_port_s *) shost->hostdata[0];
 250        struct bfad_port_s    *port = im_port->port;
 251        wwn_t           fabric_nwwn = 0;
 252
 253        fabric_nwwn = bfa_fcs_lport_get_fabric_name(port->fcs_port);
 254
 255        fc_host_fabric_name(shost) = cpu_to_be64(fabric_nwwn);
 256
 257}
 258
 259/*
 260 * FC transport template entry, get BFAD statistics.
 261 */
 262static struct fc_host_statistics *
 263bfad_im_get_stats(struct Scsi_Host *shost)
 264{
 265        struct bfad_im_port_s *im_port =
 266                        (struct bfad_im_port_s *) shost->hostdata[0];
 267        struct bfad_s         *bfad = im_port->bfad;
 268        struct bfad_hal_comp fcomp;
 269        union bfa_port_stats_u *fcstats;
 270        struct fc_host_statistics *hstats;
 271        bfa_status_t    rc;
 272        unsigned long   flags;
 273
 274        fcstats = kzalloc(sizeof(union bfa_port_stats_u), GFP_KERNEL);
 275        if (fcstats == NULL)
 276                return NULL;
 277
 278        hstats = &bfad->link_stats;
 279        init_completion(&fcomp.comp);
 280        spin_lock_irqsave(&bfad->bfad_lock, flags);
 281        memset(hstats, 0, sizeof(struct fc_host_statistics));
 282        rc = bfa_port_get_stats(BFA_FCPORT(&bfad->bfa),
 283                                fcstats, bfad_hcb_comp, &fcomp);
 284        spin_unlock_irqrestore(&bfad->bfad_lock, flags);
 285        if (rc != BFA_STATUS_OK)
 286                return NULL;
 287
 288        wait_for_completion(&fcomp.comp);
 289
 290        /* Fill the fc_host_statistics structure */
 291        hstats->seconds_since_last_reset = fcstats->fc.secs_reset;
 292        hstats->tx_frames = fcstats->fc.tx_frames;
 293        hstats->tx_words  = fcstats->fc.tx_words;
 294        hstats->rx_frames = fcstats->fc.rx_frames;
 295        hstats->rx_words  = fcstats->fc.rx_words;
 296        hstats->lip_count = fcstats->fc.lip_count;
 297        hstats->nos_count = fcstats->fc.nos_count;
 298        hstats->error_frames = fcstats->fc.error_frames;
 299        hstats->dumped_frames = fcstats->fc.dropped_frames;
 300        hstats->link_failure_count = fcstats->fc.link_failures;
 301        hstats->loss_of_sync_count = fcstats->fc.loss_of_syncs;
 302        hstats->loss_of_signal_count = fcstats->fc.loss_of_signals;
 303        hstats->prim_seq_protocol_err_count = fcstats->fc.primseq_errs;
 304        hstats->invalid_crc_count = fcstats->fc.invalid_crcs;
 305
 306        kfree(fcstats);
 307        return hstats;
 308}
 309
 310/*
 311 * FC transport template entry, reset BFAD statistics.
 312 */
 313static void
 314bfad_im_reset_stats(struct Scsi_Host *shost)
 315{
 316        struct bfad_im_port_s *im_port =
 317                        (struct bfad_im_port_s *) shost->hostdata[0];
 318        struct bfad_s         *bfad = im_port->bfad;
 319        struct bfad_hal_comp fcomp;
 320        unsigned long   flags;
 321        bfa_status_t    rc;
 322
 323        init_completion(&fcomp.comp);
 324        spin_lock_irqsave(&bfad->bfad_lock, flags);
 325        rc = bfa_port_clear_stats(BFA_FCPORT(&bfad->bfa), bfad_hcb_comp,
 326                                        &fcomp);
 327        spin_unlock_irqrestore(&bfad->bfad_lock, flags);
 328
 329        if (rc != BFA_STATUS_OK)
 330                return;
 331
 332        wait_for_completion(&fcomp.comp);
 333
 334        return;
 335}
 336
 337/*
 338 * FC transport template entry, set rport loss timeout.
 339 * Update dev_loss_tmo based on the value pushed down by the stack
 340 * In case it is lesser than path_tov of driver, set it to path_tov + 1
 341 * to ensure that the driver times out before the application
 342 */
 343static void
 344bfad_im_set_rport_loss_tmo(struct fc_rport *rport, u32 timeout)
 345{
 346        struct bfad_itnim_data_s *itnim_data = rport->dd_data;
 347        struct bfad_itnim_s   *itnim = itnim_data->itnim;
 348        struct bfad_s         *bfad = itnim->im->bfad;
 349        uint16_t path_tov = bfa_fcpim_path_tov_get(&bfad->bfa);
 350
 351        rport->dev_loss_tmo = timeout;
 352        if (timeout < path_tov)
 353                rport->dev_loss_tmo = path_tov + 1;
 354}
 355
 356static int
 357bfad_im_vport_create(struct fc_vport *fc_vport, bool disable)
 358{
 359        char *vname = fc_vport->symbolic_name;
 360        struct Scsi_Host *shost = fc_vport->shost;
 361        struct bfad_im_port_s *im_port =
 362                (struct bfad_im_port_s *) shost->hostdata[0];
 363        struct bfad_s *bfad = im_port->bfad;
 364        struct bfa_lport_cfg_s port_cfg;
 365        struct bfad_vport_s *vp;
 366        int status = 0, rc;
 367        unsigned long flags;
 368
 369        memset(&port_cfg, 0, sizeof(port_cfg));
 370        u64_to_wwn(fc_vport->node_name, (u8 *)&port_cfg.nwwn);
 371        u64_to_wwn(fc_vport->port_name, (u8 *)&port_cfg.pwwn);
 372        if (strlen(vname) > 0)
 373                strcpy((char *)&port_cfg.sym_name, vname);
 374        port_cfg.roles = BFA_LPORT_ROLE_FCP_IM;
 375
 376        spin_lock_irqsave(&bfad->bfad_lock, flags);
 377        list_for_each_entry(vp, &bfad->pbc_vport_list, list_entry) {
 378                if (port_cfg.pwwn ==
 379                                vp->fcs_vport.lport.port_cfg.pwwn) {
 380                        port_cfg.preboot_vp =
 381                                vp->fcs_vport.lport.port_cfg.preboot_vp;
 382                        break;
 383                }
 384        }
 385        spin_unlock_irqrestore(&bfad->bfad_lock, flags);
 386
 387        rc = bfad_vport_create(bfad, 0, &port_cfg, &fc_vport->dev);
 388        if (rc == BFA_STATUS_OK) {
 389                struct bfad_vport_s *vport;
 390                struct bfa_fcs_vport_s *fcs_vport;
 391                struct Scsi_Host *vshost;
 392
 393                spin_lock_irqsave(&bfad->bfad_lock, flags);
 394                fcs_vport = bfa_fcs_vport_lookup(&bfad->bfa_fcs, 0,
 395                                        port_cfg.pwwn);
 396                spin_unlock_irqrestore(&bfad->bfad_lock, flags);
 397                if (fcs_vport == NULL)
 398                        return VPCERR_BAD_WWN;
 399
 400                fc_vport_set_state(fc_vport, FC_VPORT_ACTIVE);
 401                if (disable) {
 402                        spin_lock_irqsave(&bfad->bfad_lock, flags);
 403                        bfa_fcs_vport_stop(fcs_vport);
 404                        spin_unlock_irqrestore(&bfad->bfad_lock, flags);
 405                        fc_vport_set_state(fc_vport, FC_VPORT_DISABLED);
 406                }
 407
 408                vport = fcs_vport->vport_drv;
 409                vshost = vport->drv_port.im_port->shost;
 410                fc_host_node_name(vshost) = wwn_to_u64((u8 *)&port_cfg.nwwn);
 411                fc_host_port_name(vshost) = wwn_to_u64((u8 *)&port_cfg.pwwn);
 412                fc_host_supported_classes(vshost) = FC_COS_CLASS3;
 413
 414                memset(fc_host_supported_fc4s(vshost), 0,
 415                        sizeof(fc_host_supported_fc4s(vshost)));
 416
 417                /* For FCP type 0x08 */
 418                if (supported_fc4s & BFA_LPORT_ROLE_FCP_IM)
 419                        fc_host_supported_fc4s(vshost)[2] = 1;
 420
 421                /* For fibre channel services type 0x20 */
 422                fc_host_supported_fc4s(vshost)[7] = 1;
 423
 424                fc_host_supported_speeds(vshost) =
 425                                bfad_im_supported_speeds(&bfad->bfa);
 426                fc_host_maxframe_size(vshost) =
 427                                bfa_fcport_get_maxfrsize(&bfad->bfa);
 428
 429                fc_vport->dd_data = vport;
 430                vport->drv_port.im_port->fc_vport = fc_vport;
 431        } else if (rc == BFA_STATUS_INVALID_WWN)
 432                return VPCERR_BAD_WWN;
 433        else if (rc == BFA_STATUS_VPORT_EXISTS)
 434                return VPCERR_BAD_WWN;
 435        else if (rc == BFA_STATUS_VPORT_MAX)
 436                return VPCERR_NO_FABRIC_SUPP;
 437        else if (rc == BFA_STATUS_VPORT_WWN_BP)
 438                return VPCERR_BAD_WWN;
 439        else
 440                return FC_VPORT_FAILED;
 441
 442        return status;
 443}
 444
 445int
 446bfad_im_issue_fc_host_lip(struct Scsi_Host *shost)
 447{
 448        struct bfad_im_port_s *im_port =
 449                        (struct bfad_im_port_s *) shost->hostdata[0];
 450        struct bfad_s *bfad = im_port->bfad;
 451        struct bfad_hal_comp fcomp;
 452        unsigned long flags;
 453        uint32_t status;
 454
 455        init_completion(&fcomp.comp);
 456        spin_lock_irqsave(&bfad->bfad_lock, flags);
 457        status = bfa_port_disable(&bfad->bfa.modules.port,
 458                                        bfad_hcb_comp, &fcomp);
 459        spin_unlock_irqrestore(&bfad->bfad_lock, flags);
 460
 461        if (status != BFA_STATUS_OK)
 462                return -EIO;
 463
 464        wait_for_completion(&fcomp.comp);
 465        if (fcomp.status != BFA_STATUS_OK)
 466                return -EIO;
 467
 468        spin_lock_irqsave(&bfad->bfad_lock, flags);
 469        status = bfa_port_enable(&bfad->bfa.modules.port,
 470                                        bfad_hcb_comp, &fcomp);
 471        spin_unlock_irqrestore(&bfad->bfad_lock, flags);
 472        if (status != BFA_STATUS_OK)
 473                return -EIO;
 474
 475        wait_for_completion(&fcomp.comp);
 476        if (fcomp.status != BFA_STATUS_OK)
 477                return -EIO;
 478
 479        return 0;
 480}
 481
 482static int
 483bfad_im_vport_delete(struct fc_vport *fc_vport)
 484{
 485        struct bfad_vport_s *vport = (struct bfad_vport_s *)fc_vport->dd_data;
 486        struct bfad_im_port_s *im_port =
 487                        (struct bfad_im_port_s *) vport->drv_port.im_port;
 488        struct bfad_s *bfad = im_port->bfad;
 489        struct bfad_port_s *port;
 490        struct bfa_fcs_vport_s *fcs_vport;
 491        struct Scsi_Host *vshost;
 492        wwn_t   pwwn;
 493        int rc;
 494        unsigned long flags;
 495        struct completion fcomp;
 496
 497        if (im_port->flags & BFAD_PORT_DELETE) {
 498                bfad_scsi_host_free(bfad, im_port);
 499                list_del(&vport->list_entry);
 500                kfree(vport);
 501                return 0;
 502        }
 503
 504        port = im_port->port;
 505
 506        vshost = vport->drv_port.im_port->shost;
 507        u64_to_wwn(fc_host_port_name(vshost), (u8 *)&pwwn);
 508
 509        spin_lock_irqsave(&bfad->bfad_lock, flags);
 510        fcs_vport = bfa_fcs_vport_lookup(&bfad->bfa_fcs, 0, pwwn);
 511        spin_unlock_irqrestore(&bfad->bfad_lock, flags);
 512
 513        if (fcs_vport == NULL)
 514                return VPCERR_BAD_WWN;
 515
 516        vport->drv_port.flags |= BFAD_PORT_DELETE;
 517
 518        vport->comp_del = &fcomp;
 519        init_completion(vport->comp_del);
 520
 521        spin_lock_irqsave(&bfad->bfad_lock, flags);
 522        rc = bfa_fcs_vport_delete(&vport->fcs_vport);
 523        spin_unlock_irqrestore(&bfad->bfad_lock, flags);
 524
 525        if (rc == BFA_STATUS_PBC) {
 526                vport->drv_port.flags &= ~BFAD_PORT_DELETE;
 527                vport->comp_del = NULL;
 528                return -1;
 529        }
 530
 531        wait_for_completion(vport->comp_del);
 532
 533        bfad_scsi_host_free(bfad, im_port);
 534        list_del(&vport->list_entry);
 535        kfree(vport);
 536
 537        return 0;
 538}
 539
 540static int
 541bfad_im_vport_disable(struct fc_vport *fc_vport, bool disable)
 542{
 543        struct bfad_vport_s *vport;
 544        struct bfad_s *bfad;
 545        struct bfa_fcs_vport_s *fcs_vport;
 546        struct Scsi_Host *vshost;
 547        wwn_t   pwwn;
 548        unsigned long flags;
 549
 550        vport = (struct bfad_vport_s *)fc_vport->dd_data;
 551        bfad = vport->drv_port.bfad;
 552        vshost = vport->drv_port.im_port->shost;
 553        u64_to_wwn(fc_host_port_name(vshost), (u8 *)&pwwn);
 554
 555        spin_lock_irqsave(&bfad->bfad_lock, flags);
 556        fcs_vport = bfa_fcs_vport_lookup(&bfad->bfa_fcs, 0, pwwn);
 557        spin_unlock_irqrestore(&bfad->bfad_lock, flags);
 558
 559        if (fcs_vport == NULL)
 560                return VPCERR_BAD_WWN;
 561
 562        if (disable) {
 563                bfa_fcs_vport_stop(fcs_vport);
 564                fc_vport_set_state(fc_vport, FC_VPORT_DISABLED);
 565        } else {
 566                bfa_fcs_vport_start(fcs_vport);
 567                fc_vport_set_state(fc_vport, FC_VPORT_ACTIVE);
 568        }
 569
 570        return 0;
 571}
 572
 573void
 574bfad_im_vport_set_symbolic_name(struct fc_vport *fc_vport)
 575{
 576        struct bfad_vport_s *vport = (struct bfad_vport_s *)fc_vport->dd_data;
 577        struct bfad_im_port_s *im_port =
 578                        (struct bfad_im_port_s *)vport->drv_port.im_port;
 579        struct bfad_s *bfad = im_port->bfad;
 580        struct Scsi_Host *vshost = vport->drv_port.im_port->shost;
 581        char *sym_name = fc_vport->symbolic_name;
 582        struct bfa_fcs_vport_s *fcs_vport;
 583        wwn_t   pwwn;
 584        unsigned long flags;
 585
 586        u64_to_wwn(fc_host_port_name(vshost), (u8 *)&pwwn);
 587
 588        spin_lock_irqsave(&bfad->bfad_lock, flags);
 589        fcs_vport = bfa_fcs_vport_lookup(&bfad->bfa_fcs, 0, pwwn);
 590        spin_unlock_irqrestore(&bfad->bfad_lock, flags);
 591
 592        if (fcs_vport == NULL)
 593                return;
 594
 595        spin_lock_irqsave(&bfad->bfad_lock, flags);
 596        if (strlen(sym_name) > 0)
 597                bfa_fcs_lport_set_symname(&fcs_vport->lport, sym_name);
 598        spin_unlock_irqrestore(&bfad->bfad_lock, flags);
 599}
 600
 601struct fc_function_template bfad_im_fc_function_template = {
 602
 603        /* Target dynamic attributes */
 604        .get_starget_port_id = bfad_im_get_starget_port_id,
 605        .show_starget_port_id = 1,
 606        .get_starget_node_name = bfad_im_get_starget_node_name,
 607        .show_starget_node_name = 1,
 608        .get_starget_port_name = bfad_im_get_starget_port_name,
 609        .show_starget_port_name = 1,
 610
 611        /* Host dynamic attribute */
 612        .get_host_port_id = bfad_im_get_host_port_id,
 613        .show_host_port_id = 1,
 614
 615        /* Host fixed attributes */
 616        .show_host_node_name = 1,
 617        .show_host_port_name = 1,
 618        .show_host_supported_classes = 1,
 619        .show_host_supported_fc4s = 1,
 620        .show_host_supported_speeds = 1,
 621        .show_host_maxframe_size = 1,
 622
 623        /* More host dynamic attributes */
 624        .show_host_port_type = 1,
 625        .get_host_port_type = bfad_im_get_host_port_type,
 626        .show_host_port_state = 1,
 627        .get_host_port_state = bfad_im_get_host_port_state,
 628        .show_host_active_fc4s = 1,
 629        .get_host_active_fc4s = bfad_im_get_host_active_fc4s,
 630        .show_host_speed = 1,
 631        .get_host_speed = bfad_im_get_host_speed,
 632        .show_host_fabric_name = 1,
 633        .get_host_fabric_name = bfad_im_get_host_fabric_name,
 634
 635        .show_host_symbolic_name = 1,
 636
 637        /* Statistics */
 638        .get_fc_host_stats = bfad_im_get_stats,
 639        .reset_fc_host_stats = bfad_im_reset_stats,
 640
 641        /* Allocation length for host specific data */
 642        .dd_fcrport_size = sizeof(struct bfad_itnim_data_s *),
 643
 644        /* Remote port fixed attributes */
 645        .show_rport_maxframe_size = 1,
 646        .show_rport_supported_classes = 1,
 647        .show_rport_dev_loss_tmo = 1,
 648        .set_rport_dev_loss_tmo = bfad_im_set_rport_loss_tmo,
 649        .issue_fc_host_lip = bfad_im_issue_fc_host_lip,
 650        .vport_create = bfad_im_vport_create,
 651        .vport_delete = bfad_im_vport_delete,
 652        .vport_disable = bfad_im_vport_disable,
 653        .set_vport_symbolic_name = bfad_im_vport_set_symbolic_name,
 654        .bsg_request = bfad_im_bsg_request,
 655        .bsg_timeout = bfad_im_bsg_timeout,
 656};
 657
 658struct fc_function_template bfad_im_vport_fc_function_template = {
 659
 660        /* Target dynamic attributes */
 661        .get_starget_port_id = bfad_im_get_starget_port_id,
 662        .show_starget_port_id = 1,
 663        .get_starget_node_name = bfad_im_get_starget_node_name,
 664        .show_starget_node_name = 1,
 665        .get_starget_port_name = bfad_im_get_starget_port_name,
 666        .show_starget_port_name = 1,
 667
 668        /* Host dynamic attribute */
 669        .get_host_port_id = bfad_im_get_host_port_id,
 670        .show_host_port_id = 1,
 671
 672        /* Host fixed attributes */
 673        .show_host_node_name = 1,
 674        .show_host_port_name = 1,
 675        .show_host_supported_classes = 1,
 676        .show_host_supported_fc4s = 1,
 677        .show_host_supported_speeds = 1,
 678        .show_host_maxframe_size = 1,
 679
 680        /* More host dynamic attributes */
 681        .show_host_port_type = 1,
 682        .get_host_port_type = bfad_im_get_host_port_type,
 683        .show_host_port_state = 1,
 684        .get_host_port_state = bfad_im_get_host_port_state,
 685        .show_host_active_fc4s = 1,
 686        .get_host_active_fc4s = bfad_im_get_host_active_fc4s,
 687        .show_host_speed = 1,
 688        .get_host_speed = bfad_im_get_host_speed,
 689        .show_host_fabric_name = 1,
 690        .get_host_fabric_name = bfad_im_get_host_fabric_name,
 691
 692        .show_host_symbolic_name = 1,
 693
 694        /* Statistics */
 695        .get_fc_host_stats = bfad_im_get_stats,
 696        .reset_fc_host_stats = bfad_im_reset_stats,
 697
 698        /* Allocation length for host specific data */
 699        .dd_fcrport_size = sizeof(struct bfad_itnim_data_s *),
 700
 701        /* Remote port fixed attributes */
 702        .show_rport_maxframe_size = 1,
 703        .show_rport_supported_classes = 1,
 704        .show_rport_dev_loss_tmo = 1,
 705        .set_rport_dev_loss_tmo = bfad_im_set_rport_loss_tmo,
 706};
 707
 708/*
 709 *  Scsi_Host_attrs SCSI host attributes
 710 */
 711static ssize_t
 712bfad_im_serial_num_show(struct device *dev, struct device_attribute *attr,
 713                         char *buf)
 714{
 715        struct Scsi_Host *shost = class_to_shost(dev);
 716        struct bfad_im_port_s *im_port =
 717                        (struct bfad_im_port_s *) shost->hostdata[0];
 718        struct bfad_s *bfad = im_port->bfad;
 719        char serial_num[BFA_ADAPTER_SERIAL_NUM_LEN];
 720
 721        bfa_get_adapter_serial_num(&bfad->bfa, serial_num);
 722        return snprintf(buf, PAGE_SIZE, "%s\n", serial_num);
 723}
 724
 725static ssize_t
 726bfad_im_model_show(struct device *dev, struct device_attribute *attr,
 727                        char *buf)
 728{
 729        struct Scsi_Host *shost = class_to_shost(dev);
 730        struct bfad_im_port_s *im_port =
 731                        (struct bfad_im_port_s *) shost->hostdata[0];
 732        struct bfad_s *bfad = im_port->bfad;
 733        char model[BFA_ADAPTER_MODEL_NAME_LEN];
 734
 735        bfa_get_adapter_model(&bfad->bfa, model);
 736        return snprintf(buf, PAGE_SIZE, "%s\n", model);
 737}
 738
 739static ssize_t
 740bfad_im_model_desc_show(struct device *dev, struct device_attribute *attr,
 741                                 char *buf)
 742{
 743        struct Scsi_Host *shost = class_to_shost(dev);
 744        struct bfad_im_port_s *im_port =
 745                        (struct bfad_im_port_s *) shost->hostdata[0];
 746        struct bfad_s *bfad = im_port->bfad;
 747        char model[BFA_ADAPTER_MODEL_NAME_LEN];
 748        char model_descr[BFA_ADAPTER_MODEL_DESCR_LEN];
 749        int nports = 0;
 750
 751        bfa_get_adapter_model(&bfad->bfa, model);
 752        nports = bfa_get_nports(&bfad->bfa);
 753        if (!strcmp(model, "Brocade-425"))
 754                snprintf(model_descr, BFA_ADAPTER_MODEL_DESCR_LEN,
 755                        "Brocade 4Gbps PCIe dual port FC HBA");
 756        else if (!strcmp(model, "Brocade-825"))
 757                snprintf(model_descr, BFA_ADAPTER_MODEL_DESCR_LEN,
 758                        "Brocade 8Gbps PCIe dual port FC HBA");
 759        else if (!strcmp(model, "Brocade-42B"))
 760                snprintf(model_descr, BFA_ADAPTER_MODEL_DESCR_LEN,
 761                        "Brocade 4Gbps PCIe dual port FC HBA for HP");
 762        else if (!strcmp(model, "Brocade-82B"))
 763                snprintf(model_descr, BFA_ADAPTER_MODEL_DESCR_LEN,
 764                        "Brocade 8Gbps PCIe dual port FC HBA for HP");
 765        else if (!strcmp(model, "Brocade-1010"))
 766                snprintf(model_descr, BFA_ADAPTER_MODEL_DESCR_LEN,
 767                        "Brocade 10Gbps single port CNA");
 768        else if (!strcmp(model, "Brocade-1020"))
 769                snprintf(model_descr, BFA_ADAPTER_MODEL_DESCR_LEN,
 770                        "Brocade 10Gbps dual port CNA");
 771        else if (!strcmp(model, "Brocade-1007"))
 772                snprintf(model_descr, BFA_ADAPTER_MODEL_DESCR_LEN,
 773                        "Brocade 10Gbps CNA for IBM Blade Center");
 774        else if (!strcmp(model, "Brocade-415"))
 775                snprintf(model_descr, BFA_ADAPTER_MODEL_DESCR_LEN,
 776                        "Brocade 4Gbps PCIe single port FC HBA");
 777        else if (!strcmp(model, "Brocade-815"))
 778                snprintf(model_descr, BFA_ADAPTER_MODEL_DESCR_LEN,
 779                        "Brocade 8Gbps PCIe single port FC HBA");
 780        else if (!strcmp(model, "Brocade-41B"))
 781                snprintf(model_descr, BFA_ADAPTER_MODEL_DESCR_LEN,
 782                        "Brocade 4Gbps PCIe single port FC HBA for HP");
 783        else if (!strcmp(model, "Brocade-81B"))
 784                snprintf(model_descr, BFA_ADAPTER_MODEL_DESCR_LEN,
 785                        "Brocade 8Gbps PCIe single port FC HBA for HP");
 786        else if (!strcmp(model, "Brocade-804"))
 787                snprintf(model_descr, BFA_ADAPTER_MODEL_DESCR_LEN,
 788                        "Brocade 8Gbps FC HBA for HP Bladesystem C-class");
 789        else if (!strcmp(model, "Brocade-1741"))
 790                snprintf(model_descr, BFA_ADAPTER_MODEL_DESCR_LEN,
 791                        "Brocade 10Gbps CNA for Dell M-Series Blade Servers");
 792        else if (strstr(model, "Brocade-1860")) {
 793                if (nports == 1 && bfa_ioc_is_cna(&bfad->bfa.ioc))
 794                        snprintf(model_descr, BFA_ADAPTER_MODEL_DESCR_LEN,
 795                                "Brocade 10Gbps single port CNA");
 796                else if (nports == 1 && !bfa_ioc_is_cna(&bfad->bfa.ioc))
 797                        snprintf(model_descr, BFA_ADAPTER_MODEL_DESCR_LEN,
 798                                "Brocade 16Gbps PCIe single port FC HBA");
 799                else if (nports == 2 && bfa_ioc_is_cna(&bfad->bfa.ioc))
 800                        snprintf(model_descr, BFA_ADAPTER_MODEL_DESCR_LEN,
 801                                "Brocade 10Gbps dual port CNA");
 802                else if (nports == 2 && !bfa_ioc_is_cna(&bfad->bfa.ioc))
 803                        snprintf(model_descr, BFA_ADAPTER_MODEL_DESCR_LEN,
 804                                "Brocade 16Gbps PCIe dual port FC HBA");
 805        } else if (!strcmp(model, "Brocade-1867")) {
 806                if (nports == 1 && !bfa_ioc_is_cna(&bfad->bfa.ioc))
 807                        snprintf(model_descr, BFA_ADAPTER_MODEL_DESCR_LEN,
 808                                "Brocade 16Gbps PCIe single port FC HBA for IBM");
 809                else if (nports == 2 && !bfa_ioc_is_cna(&bfad->bfa.ioc))
 810                        snprintf(model_descr, BFA_ADAPTER_MODEL_DESCR_LEN,
 811                                "Brocade 16Gbps PCIe dual port FC HBA for IBM");
 812        } else
 813                snprintf(model_descr, BFA_ADAPTER_MODEL_DESCR_LEN,
 814                        "Invalid Model");
 815
 816        return snprintf(buf, PAGE_SIZE, "%s\n", model_descr);
 817}
 818
 819static ssize_t
 820bfad_im_node_name_show(struct device *dev, struct device_attribute *attr,
 821                                 char *buf)
 822{
 823        struct Scsi_Host *shost = class_to_shost(dev);
 824        struct bfad_im_port_s *im_port =
 825                        (struct bfad_im_port_s *) shost->hostdata[0];
 826        struct bfad_port_s    *port = im_port->port;
 827        u64        nwwn;
 828
 829        nwwn = bfa_fcs_lport_get_nwwn(port->fcs_port);
 830        return snprintf(buf, PAGE_SIZE, "0x%llx\n", cpu_to_be64(nwwn));
 831}
 832
 833static ssize_t
 834bfad_im_symbolic_name_show(struct device *dev, struct device_attribute *attr,
 835                                 char *buf)
 836{
 837        struct Scsi_Host *shost = class_to_shost(dev);
 838        struct bfad_im_port_s *im_port =
 839                        (struct bfad_im_port_s *) shost->hostdata[0];
 840        struct bfad_s *bfad = im_port->bfad;
 841        struct bfa_lport_attr_s port_attr;
 842        char symname[BFA_SYMNAME_MAXLEN];
 843
 844        bfa_fcs_lport_get_attr(&bfad->bfa_fcs.fabric.bport, &port_attr);
 845        strncpy(symname, port_attr.port_cfg.sym_name.symname,
 846                        BFA_SYMNAME_MAXLEN);
 847        return snprintf(buf, PAGE_SIZE, "%s\n", symname);
 848}
 849
 850static ssize_t
 851bfad_im_hw_version_show(struct device *dev, struct device_attribute *attr,
 852                                char *buf)
 853{
 854        struct Scsi_Host *shost = class_to_shost(dev);
 855        struct bfad_im_port_s *im_port =
 856                        (struct bfad_im_port_s *) shost->hostdata[0];
 857        struct bfad_s *bfad = im_port->bfad;
 858        char hw_ver[BFA_VERSION_LEN];
 859
 860        bfa_get_pci_chip_rev(&bfad->bfa, hw_ver);
 861        return snprintf(buf, PAGE_SIZE, "%s\n", hw_ver);
 862}
 863
 864static ssize_t
 865bfad_im_drv_version_show(struct device *dev, struct device_attribute *attr,
 866                                char *buf)
 867{
 868        return snprintf(buf, PAGE_SIZE, "%s\n", BFAD_DRIVER_VERSION);
 869}
 870
 871static ssize_t
 872bfad_im_optionrom_version_show(struct device *dev,
 873                         struct device_attribute *attr, char *buf)
 874{
 875        struct Scsi_Host *shost = class_to_shost(dev);
 876        struct bfad_im_port_s *im_port =
 877                        (struct bfad_im_port_s *) shost->hostdata[0];
 878        struct bfad_s *bfad = im_port->bfad;
 879        char optrom_ver[BFA_VERSION_LEN];
 880
 881        bfa_get_adapter_optrom_ver(&bfad->bfa, optrom_ver);
 882        return snprintf(buf, PAGE_SIZE, "%s\n", optrom_ver);
 883}
 884
 885static ssize_t
 886bfad_im_fw_version_show(struct device *dev, struct device_attribute *attr,
 887                                 char *buf)
 888{
 889        struct Scsi_Host *shost = class_to_shost(dev);
 890        struct bfad_im_port_s *im_port =
 891                        (struct bfad_im_port_s *) shost->hostdata[0];
 892        struct bfad_s *bfad = im_port->bfad;
 893        char fw_ver[BFA_VERSION_LEN];
 894
 895        bfa_get_adapter_fw_ver(&bfad->bfa, fw_ver);
 896        return snprintf(buf, PAGE_SIZE, "%s\n", fw_ver);
 897}
 898
 899static ssize_t
 900bfad_im_num_of_ports_show(struct device *dev, struct device_attribute *attr,
 901                                char *buf)
 902{
 903        struct Scsi_Host *shost = class_to_shost(dev);
 904        struct bfad_im_port_s *im_port =
 905                        (struct bfad_im_port_s *) shost->hostdata[0];
 906        struct bfad_s *bfad = im_port->bfad;
 907
 908        return snprintf(buf, PAGE_SIZE, "%d\n",
 909                        bfa_get_nports(&bfad->bfa));
 910}
 911
 912static ssize_t
 913bfad_im_drv_name_show(struct device *dev, struct device_attribute *attr,
 914                                char *buf)
 915{
 916        return snprintf(buf, PAGE_SIZE, "%s\n", BFAD_DRIVER_NAME);
 917}
 918
 919static ssize_t
 920bfad_im_num_of_discovered_ports_show(struct device *dev,
 921                        struct device_attribute *attr, char *buf)
 922{
 923        struct Scsi_Host *shost = class_to_shost(dev);
 924        struct bfad_im_port_s *im_port =
 925                        (struct bfad_im_port_s *) shost->hostdata[0];
 926        struct bfad_port_s    *port = im_port->port;
 927        struct bfad_s         *bfad = im_port->bfad;
 928        int        nrports = 2048;
 929        struct bfa_rport_qualifier_s *rports = NULL;
 930        unsigned long   flags;
 931
 932        rports = kzalloc(sizeof(struct bfa_rport_qualifier_s) * nrports,
 933                         GFP_ATOMIC);
 934        if (rports == NULL)
 935                return snprintf(buf, PAGE_SIZE, "Failed\n");
 936
 937        spin_lock_irqsave(&bfad->bfad_lock, flags);
 938        bfa_fcs_lport_get_rport_quals(port->fcs_port, rports, &nrports);
 939        spin_unlock_irqrestore(&bfad->bfad_lock, flags);
 940        kfree(rports);
 941
 942        return snprintf(buf, PAGE_SIZE, "%d\n", nrports);
 943}
 944
 945static          DEVICE_ATTR(serial_number, S_IRUGO,
 946                                bfad_im_serial_num_show, NULL);
 947static          DEVICE_ATTR(model, S_IRUGO, bfad_im_model_show, NULL);
 948static          DEVICE_ATTR(model_description, S_IRUGO,
 949                                bfad_im_model_desc_show, NULL);
 950static          DEVICE_ATTR(node_name, S_IRUGO, bfad_im_node_name_show, NULL);
 951static          DEVICE_ATTR(symbolic_name, S_IRUGO,
 952                                bfad_im_symbolic_name_show, NULL);
 953static          DEVICE_ATTR(hardware_version, S_IRUGO,
 954                                bfad_im_hw_version_show, NULL);
 955static          DEVICE_ATTR(driver_version, S_IRUGO,
 956                                bfad_im_drv_version_show, NULL);
 957static          DEVICE_ATTR(option_rom_version, S_IRUGO,
 958                                bfad_im_optionrom_version_show, NULL);
 959static          DEVICE_ATTR(firmware_version, S_IRUGO,
 960                                bfad_im_fw_version_show, NULL);
 961static          DEVICE_ATTR(number_of_ports, S_IRUGO,
 962                                bfad_im_num_of_ports_show, NULL);
 963static          DEVICE_ATTR(driver_name, S_IRUGO, bfad_im_drv_name_show, NULL);
 964static          DEVICE_ATTR(number_of_discovered_ports, S_IRUGO,
 965                                bfad_im_num_of_discovered_ports_show, NULL);
 966
 967struct device_attribute *bfad_im_host_attrs[] = {
 968        &dev_attr_serial_number,
 969        &dev_attr_model,
 970        &dev_attr_model_description,
 971        &dev_attr_node_name,
 972        &dev_attr_symbolic_name,
 973        &dev_attr_hardware_version,
 974        &dev_attr_driver_version,
 975        &dev_attr_option_rom_version,
 976        &dev_attr_firmware_version,
 977        &dev_attr_number_of_ports,
 978        &dev_attr_driver_name,
 979        &dev_attr_number_of_discovered_ports,
 980        NULL,
 981};
 982
 983struct device_attribute *bfad_im_vport_attrs[] = {
 984        &dev_attr_serial_number,
 985        &dev_attr_model,
 986        &dev_attr_model_description,
 987        &dev_attr_node_name,
 988        &dev_attr_symbolic_name,
 989        &dev_attr_hardware_version,
 990        &dev_attr_driver_version,
 991        &dev_attr_option_rom_version,
 992        &dev_attr_firmware_version,
 993        &dev_attr_number_of_ports,
 994        &dev_attr_driver_name,
 995        &dev_attr_number_of_discovered_ports,
 996        NULL,
 997};
 998
 999
1000