1fcf3ce44SJohn Forte /* 2fcf3ce44SJohn Forte * CDDL HEADER START 3fcf3ce44SJohn Forte * 4fcf3ce44SJohn Forte * The contents of this file are subject to the terms of the 5fcf3ce44SJohn Forte * Common Development and Distribution License (the "License"). 6fcf3ce44SJohn Forte * You may not use this file except in compliance with the License. 7fcf3ce44SJohn Forte * 8fcf3ce44SJohn Forte * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9fcf3ce44SJohn Forte * or http://www.opensolaris.org/os/licensing. 10fcf3ce44SJohn Forte * See the License for the specific language governing permissions 11fcf3ce44SJohn Forte * and limitations under the License. 12fcf3ce44SJohn Forte * 13fcf3ce44SJohn Forte * When distributing Covered Code, include this CDDL HEADER in each 14fcf3ce44SJohn Forte * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15fcf3ce44SJohn Forte * If applicable, add the following below this CDDL HEADER, with the 16fcf3ce44SJohn Forte * fields enclosed by brackets "[]" replaced with your own identifying 17fcf3ce44SJohn Forte * information: Portions Copyright [yyyy] [name of copyright owner] 18fcf3ce44SJohn Forte * 19fcf3ce44SJohn Forte * CDDL HEADER END 20fcf3ce44SJohn Forte */ 21fcf3ce44SJohn Forte 22*5dfd244aSDaniel Beauregard /* Copyright 2009 QLogic Corporation */ 23fcf3ce44SJohn Forte 24fcf3ce44SJohn Forte /* 25*5dfd244aSDaniel Beauregard * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 26fcf3ce44SJohn Forte * Use is subject to license terms. 27fcf3ce44SJohn Forte */ 28fcf3ce44SJohn Forte 29*5dfd244aSDaniel Beauregard #pragma ident "Copyright 2009 QLogic Corporation; ql_hba_fru.c" 30fcf3ce44SJohn Forte 31fcf3ce44SJohn Forte /* 32fcf3ce44SJohn Forte * ISP2xxx Solaris Fibre Channel Adapter (FCA) driver source file. 33fcf3ce44SJohn Forte * 34fcf3ce44SJohn Forte * *********************************************************************** 35fcf3ce44SJohn Forte * * ** 36fcf3ce44SJohn Forte * * NOTICE ** 37*5dfd244aSDaniel Beauregard * * COPYRIGHT (C) 1996-2009 QLOGIC CORPORATION ** 38fcf3ce44SJohn Forte * * ALL RIGHTS RESERVED ** 39fcf3ce44SJohn Forte * * ** 40fcf3ce44SJohn Forte * *********************************************************************** 41fcf3ce44SJohn Forte * 42fcf3ce44SJohn Forte */ 43fcf3ce44SJohn Forte 44fcf3ce44SJohn Forte /* 45fcf3ce44SJohn Forte * Determine HBA FRU card information for T11 FC-HBA 46fcf3ce44SJohn Forte */ 47fcf3ce44SJohn Forte 48fcf3ce44SJohn Forte #include <ql_apps.h> 49fcf3ce44SJohn Forte #include <ql_api.h> 50fcf3ce44SJohn Forte #include <ql_debug.h> 51fcf3ce44SJohn Forte #include <ql_ioctl.h> 52fcf3ce44SJohn Forte #include <ql_xioctl.h> 53fcf3ce44SJohn Forte 54fcf3ce44SJohn Forte /* 55fcf3ce44SJohn Forte * Temporary define until LV headers are updated 56fcf3ce44SJohn Forte */ 57fcf3ce44SJohn Forte #ifndef FC_HBA_PORTSPEED_8GBIT 58fcf3ce44SJohn Forte #define FC_HBA_PORTSPEED_8GBIT 16 /* 8 GBit/sec */ 59fcf3ce44SJohn Forte #endif 60fcf3ce44SJohn Forte 61fcf3ce44SJohn Forte /* Local prototypes */ 62fcf3ce44SJohn Forte static uint32_t ql_get_basedev_len(ql_adapter_state_t *, uint32_t *, 63fcf3ce44SJohn Forte uint32_t *); 64fcf3ce44SJohn Forte static ql_adapter_state_t *ql_search_basedev(ql_adapter_state_t *, uint32_t); 65fcf3ce44SJohn Forte 66fcf3ce44SJohn Forte /* Local structures */ 67fcf3ce44SJohn Forte static struct ql_known_models { 68fcf3ce44SJohn Forte uint16_t ssid; /* Subsystem ID */ 69fcf3ce44SJohn Forte uint16_t ssvid; /* Subsystem Vendor ID */ 70fcf3ce44SJohn Forte char model[256]; 71fcf3ce44SJohn Forte char model_description[256]; 72fcf3ce44SJohn Forte 73fcf3ce44SJohn Forte } models[] = { 74fcf3ce44SJohn Forte { 75fcf3ce44SJohn Forte /* QLogic */ 76fcf3ce44SJohn Forte 0x2, 0x1077, "QLA2200", "QLogic PCI to 1Gb FC, Single Channel" 77fcf3ce44SJohn Forte }, { 78fcf3ce44SJohn Forte /* QLogic */ 79fcf3ce44SJohn Forte 0x9, 0x1077, "QLA2300", "QLogic PCI to 2Gb FC, Single Channel" 80fcf3ce44SJohn Forte }, { 81fcf3ce44SJohn Forte /* QLA2200, SUN2200 Amber */ 82fcf3ce44SJohn Forte 0x4082, 0x1077, "375-3019-xx", "X6799A" 83fcf3ce44SJohn Forte }, { 84fcf3ce44SJohn Forte /* QLA2212, SUN2212 Crystal+ */ 85fcf3ce44SJohn Forte 0x4083, 0x1077, "375-3030-xx", "X6727A" 86fcf3ce44SJohn Forte }, { 87fcf3ce44SJohn Forte /* QCP2202, SUNQCP2202 Diamond */ 88fcf3ce44SJohn Forte 0x4084, 0x1077, "375-0118-xx", "X6748A" 89fcf3ce44SJohn Forte }, { 90fcf3ce44SJohn Forte /* QLA2202FS, SUN2202FS Ivory */ 91fcf3ce44SJohn Forte 0x4085, 0x1077, "375-3048-xx", "X6757A" 92fcf3ce44SJohn Forte }, { 93fcf3ce44SJohn Forte /* QLogic */ 94fcf3ce44SJohn Forte 0x100, 0x1077, "QLA2340", 95fcf3ce44SJohn Forte "QLogic 133MHz PCI-X to 2Gb FC, Single Channel" 96fcf3ce44SJohn Forte }, { 97fcf3ce44SJohn Forte /* QLogic */ 98fcf3ce44SJohn Forte 0x101, 0x1077, "QLA2342", 99fcf3ce44SJohn Forte "QLogic 133MHz PCI-X to 2Gb FC, Dual Channel" 100fcf3ce44SJohn Forte }, { 101fcf3ce44SJohn Forte /* QLogic */ 102fcf3ce44SJohn Forte 0x102, 0x1077, "QLA2344", 103fcf3ce44SJohn Forte "QLogic 133MHz PCI-X to 2Gb FC, Quad Channel" 104fcf3ce44SJohn Forte }, { 105fcf3ce44SJohn Forte /* QLogic */ 106fcf3ce44SJohn Forte 0x103, 0x1077, "QCP2342", "QLogic cPCI to 2Gb FC, Dual Channel" 107fcf3ce44SJohn Forte }, { 108fcf3ce44SJohn Forte /* QLogic */ 109fcf3ce44SJohn Forte 0x104, 0x1077, "QSB2340", "QLogic SBUS to 2Gb FC, Single Channel" 110fcf3ce44SJohn Forte }, { 111fcf3ce44SJohn Forte /* QLogic */ 112fcf3ce44SJohn Forte 0x105, 0x1077, "QSB2342", "QLogic SBUS to 2Gb FC, Dual Channel" 113fcf3ce44SJohn Forte }, { 114fcf3ce44SJohn Forte /* QLA2310, SUN-66MHz PCI-X to 2Gb FC, Single Channel, Amber 2 */ 115fcf3ce44SJohn Forte 0x0106, 0x1077, "375-3102-xx", "SG-XPCI1FC-QF2 (X6767A)" 116fcf3ce44SJohn Forte }, { 117fcf3ce44SJohn Forte /* QLogic */ 118fcf3ce44SJohn Forte 0x109, 0x1077, "QCP2340", "QLogic cPCI to 2Gb FC, Single Channel" 119fcf3ce44SJohn Forte }, { 120fcf3ce44SJohn Forte /* QLA2342, SUN-133MHz PCI-X to 2Gb FC, Dualchannel, Crystal 2A */ 121fcf3ce44SJohn Forte 0x010A, 0x1077, "375-3108-xx", "SG-XPCI2FC-QF2 (X6768A)" 122fcf3ce44SJohn Forte }, { 123fcf3ce44SJohn Forte /* QLogic */ 124fcf3ce44SJohn Forte 0x115, 0x1077, "QLA2360", 125fcf3ce44SJohn Forte "QLogic 133MHz PCI-X to 2Gb FC, Single Channel" 126fcf3ce44SJohn Forte }, { 127fcf3ce44SJohn Forte /* QLogic */ 128fcf3ce44SJohn Forte 0x116, 0x1077, "QLA2362", 129fcf3ce44SJohn Forte "QLogic 133MHz PCI-X to 2Gb FC, Dual Channel" 130fcf3ce44SJohn Forte }, { 131fcf3ce44SJohn Forte /* QLogic */ 132fcf3ce44SJohn Forte 0x117, 0x1077, "QLE2360", 133fcf3ce44SJohn Forte "QLogic PCI-Express to 2Gb FC, Single Channel" 134fcf3ce44SJohn Forte }, { 135fcf3ce44SJohn Forte /* QLogic */ 136fcf3ce44SJohn Forte 0x118, 0x1077, "QLE2362", 137fcf3ce44SJohn Forte "QLogic PCI Express to 2Gb FC, Dual Channel" 138fcf3ce44SJohn Forte }, { 139fcf3ce44SJohn Forte /* QLogic */ 140fcf3ce44SJohn Forte 0x119, 0x1077, "QLA200", 141fcf3ce44SJohn Forte "QLogic 133MHz PCI-X to 2Gb FC, Single Channel" 142fcf3ce44SJohn Forte }, { 143fcf3ce44SJohn Forte /* QLogic */ 144fcf3ce44SJohn Forte 0x11c, 0x1077, "QLA200P", 145fcf3ce44SJohn Forte "QLogic 133MHz PCI-X to 2Gb FC, Single Channel" 146fcf3ce44SJohn Forte }, { 147fcf3ce44SJohn Forte /* QLogic */ 148fcf3ce44SJohn Forte 0x12f, 0x1077, "QLA210", 149fcf3ce44SJohn Forte "QLogic 133MHz PCI-X to 2Gb FC, Single Channel" 150fcf3ce44SJohn Forte }, { 151fcf3ce44SJohn Forte /* QLogic */ 152fcf3ce44SJohn Forte 0x130, 0x1077, "EMC250-051-900", 153fcf3ce44SJohn Forte "QLogic 133MHz PCI-X to 2Gb FC, Single Channel" 154fcf3ce44SJohn Forte }, { 155fcf3ce44SJohn Forte /* QLA210, SUN-133MHz PCI-X to 2Gb FC, Single Channel, Prism */ 156fcf3ce44SJohn Forte 0x132, 0x1077, "375-32X3-01", "SG-PCI1FC-QLC" 157fcf3ce44SJohn Forte }, { 158fcf3ce44SJohn Forte /* QLogic */ 159fcf3ce44SJohn Forte 0x13e, 0x1077, "QLE210", 160fcf3ce44SJohn Forte "QLogic PCI Express 2Gb FC, Single Channel" 161fcf3ce44SJohn Forte }, { 162fcf3ce44SJohn Forte /* Sun */ 163fcf3ce44SJohn Forte 0x149, 0x1077, "QLA2340", 164fcf3ce44SJohn Forte "SUN - 133MHz PCI-X to 2Gb FC, Single Channel" 165fcf3ce44SJohn Forte }, { 166fcf3ce44SJohn Forte /* HP */ 167fcf3ce44SJohn Forte 0x100, 0x0e11, "QLA2340-HP", "PCIX to 2Gb FC, Single Channel" 168fcf3ce44SJohn Forte }, { 169fcf3ce44SJohn Forte /* HP */ 170fcf3ce44SJohn Forte 0x101, 0x0e11, "QLA2342-HP", "PCIX to 2Gb FC, Dual Channel" 171fcf3ce44SJohn Forte }, { 172fcf3ce44SJohn Forte /* HP */ 173fcf3ce44SJohn Forte 0x103, 0x0e11, "QLA2312-HP", 174fcf3ce44SJohn Forte "HP Bladed Server Balcony Card - HP BalcnL" 175fcf3ce44SJohn Forte }, { 176fcf3ce44SJohn Forte /* HP */ 177fcf3ce44SJohn Forte 0x104, 0x0e11, "QLA2312-HP", "HP Bladed Server - HP MezzF" 178fcf3ce44SJohn Forte }, { 179fcf3ce44SJohn Forte /* HP */ 180fcf3ce44SJohn Forte 0x105, 0x0e11, "QLA2312-HP", "HP Bladed Server - HP BalcnL" 181fcf3ce44SJohn Forte }, { 182fcf3ce44SJohn Forte /* HP */ 183fcf3ce44SJohn Forte 0x106, 0x0e11, "QLA2312-HP", "HP Bladed Server - HP BalcnF" 184fcf3ce44SJohn Forte }, { 185fcf3ce44SJohn Forte /* HP */ 186fcf3ce44SJohn Forte 0x107, 0x0e11, "QLA2312-HP", "HP Bladed Server" 187fcf3ce44SJohn Forte }, { 188fcf3ce44SJohn Forte /* HP */ 189fcf3ce44SJohn Forte 0x108, 0x0e11, "QLA2312-HP", "HP Bladed Server" 190fcf3ce44SJohn Forte }, { 191fcf3ce44SJohn Forte /* IBM FCEC */ 192fcf3ce44SJohn Forte 0x27d, 0x1014, "IBM-FCEC", 193fcf3ce44SJohn Forte "IBM eServer Blade Center FC Expansion Card" 194fcf3ce44SJohn Forte }, { 195fcf3ce44SJohn Forte /* IBM FCEC */ 196fcf3ce44SJohn Forte 0x2fb, 0x1014, "IBM-FCEC", 197fcf3ce44SJohn Forte "IBM eServer Blade Center FC SFF Expansion Card" 198fcf3ce44SJohn Forte }, { 199fcf3ce44SJohn Forte /* Intel */ 200fcf3ce44SJohn Forte 0x34ba, 0x8086, "Intel SBFCM", 201fcf3ce44SJohn Forte "Intel Server FC Expansion Card SBFCM" 202fcf3ce44SJohn Forte }, { 203fcf3ce44SJohn Forte /* Intel */ 204fcf3ce44SJohn Forte 0x34a0, 0x8086, "Intel SBEFCM", 205fcf3ce44SJohn Forte "Intel Server SFF FC Expansion Card SBFCM" 206fcf3ce44SJohn Forte }, { 207fcf3ce44SJohn Forte /* FCI/O */ 208fcf3ce44SJohn Forte 0x1051, 0x1734, "FCI/O-CARD2Gb/s", 209fcf3ce44SJohn Forte "FSC-Quanta FC I/O-Card 2GBit/s" 210fcf3ce44SJohn Forte }, { 211fcf3ce44SJohn Forte /* Dell */ 212fcf3ce44SJohn Forte 0x18a, 0x1028, "FCI/O-CARD2Gb/s", "Dell Glacier Blade Server" 213fcf3ce44SJohn Forte }, { 214fcf3ce44SJohn Forte /* end of list */ 215fcf3ce44SJohn Forte 0, 0, 0, 0, 0, 0 216fcf3ce44SJohn Forte } }; 217fcf3ce44SJohn Forte 218fcf3ce44SJohn Forte /* 219fcf3ce44SJohn Forte * ql_populate_hba_fru_details 220fcf3ce44SJohn Forte * Sets up HBA fru information for UL utilities 221fcf3ce44SJohn Forte * (cfgadm, fcinfo, et. al.) 222fcf3ce44SJohn Forte * 223fcf3ce44SJohn Forte * Input: 224fcf3ce44SJohn Forte * ha = adapter state structure 225fcf3ce44SJohn Forte * port_info = ptr to LV port strcture. 226fcf3ce44SJohn Forte * 227fcf3ce44SJohn Forte * Returns: 228fcf3ce44SJohn Forte * 229fcf3ce44SJohn Forte * Context: 230fcf3ce44SJohn Forte * Kernel context. 231fcf3ce44SJohn Forte */ 232fcf3ce44SJohn Forte void 233fcf3ce44SJohn Forte ql_populate_hba_fru_details(ql_adapter_state_t *ha, 234fcf3ce44SJohn Forte fc_fca_port_info_t *port_info) 235fcf3ce44SJohn Forte { 236fcf3ce44SJohn Forte fca_port_attrs_t *attrs = &port_info->pi_attrs; 237fcf3ce44SJohn Forte uint16_t chip = ha->device_id; 238fcf3ce44SJohn Forte uint16_t model = ha->subsys_id; 239fcf3ce44SJohn Forte uint16_t ssdevid = ha->subven_id; 240fcf3ce44SJohn Forte size_t vlen; 241fcf3ce44SJohn Forte int32_t i; 242fcf3ce44SJohn Forte 243*5dfd244aSDaniel Beauregard QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 244fcf3ce44SJohn Forte 245fcf3ce44SJohn Forte attrs = &port_info->pi_attrs; 246fcf3ce44SJohn Forte 247fcf3ce44SJohn Forte /* Constants */ 248fcf3ce44SJohn Forte (void) snprintf(attrs->manufacturer, FCHBA_MANUFACTURER_LEN, 249fcf3ce44SJohn Forte "QLogic Corp."); 250fcf3ce44SJohn Forte (void) snprintf(attrs->driver_name, FCHBA_DRIVER_NAME_LEN, 251fcf3ce44SJohn Forte "%s", QL_NAME); 252fcf3ce44SJohn Forte (void) snprintf(attrs->driver_version, FCHBA_DRIVER_VERSION_LEN, 253fcf3ce44SJohn Forte "%s", ha->adapter_stats->revlvl.qlddv); 254fcf3ce44SJohn Forte 255fcf3ce44SJohn Forte if ((i = ql_vpd_lookup(ha, (uint8_t *)VPD_TAG_SN, (uint8_t *) 256fcf3ce44SJohn Forte attrs->serial_number, FCHBA_SERIAL_NUMBER_LEN)) == -1) { 257fcf3ce44SJohn Forte attrs->serial_number[0] = '\0'; 258fcf3ce44SJohn Forte } 259fcf3ce44SJohn Forte attrs->hardware_version[0] = '\0'; 260fcf3ce44SJohn Forte 261fcf3ce44SJohn Forte /* Dynamic data */ 262fcf3ce44SJohn Forte (void) snprintf(attrs->firmware_version, FCHBA_FIRMWARE_VERSION_LEN, 263fcf3ce44SJohn Forte "%02d.%02d.%02d", ha->fw_major_version, ha->fw_minor_version, 264fcf3ce44SJohn Forte ha->fw_subminor_version); 265fcf3ce44SJohn Forte 266fcf3ce44SJohn Forte CACHE_LOCK(ha); 267fcf3ce44SJohn Forte 268fcf3ce44SJohn Forte /* Report FCode / BIOS / EFI version(s). */ 269fcf3ce44SJohn Forte if (ha->fcache != NULL) { 270fcf3ce44SJohn Forte uint32_t types = FTYPE_BIOS|FTYPE_FCODE|FTYPE_EFI; 271fcf3ce44SJohn Forte ql_fcache_t *fptr = ha->fcache; 272fcf3ce44SJohn Forte int8_t *orv = &*attrs->option_rom_version; 273fcf3ce44SJohn Forte 274fcf3ce44SJohn Forte while ((fptr != NULL) && (types != 0)) { 275fcf3ce44SJohn Forte /* Get the next image */ 276fcf3ce44SJohn Forte if ((fptr = ql_get_fbuf(ha->fcache, types)) != NULL) { 277fcf3ce44SJohn Forte 278fcf3ce44SJohn Forte switch (fptr->type) { 279fcf3ce44SJohn Forte case FTYPE_FCODE: 280fcf3ce44SJohn Forte (void) snprintf(orv, 281fcf3ce44SJohn Forte FCHBA_OPTION_ROM_VERSION_LEN, 282fcf3ce44SJohn Forte "%s fcode: %s;", orv, fptr->verstr); 283fcf3ce44SJohn Forte break; 284fcf3ce44SJohn Forte case FTYPE_BIOS: 285fcf3ce44SJohn Forte (void) snprintf(orv, 286fcf3ce44SJohn Forte FCHBA_OPTION_ROM_VERSION_LEN, 287fcf3ce44SJohn Forte "%s BIOS: %s;", orv, fptr->verstr); 288fcf3ce44SJohn Forte break; 289fcf3ce44SJohn Forte case FTYPE_EFI: 290fcf3ce44SJohn Forte (void) snprintf(orv, 291fcf3ce44SJohn Forte FCHBA_OPTION_ROM_VERSION_LEN, 292fcf3ce44SJohn Forte "%s EFI: %s;", orv, fptr->verstr); 293fcf3ce44SJohn Forte break; 294fcf3ce44SJohn Forte default: 295fcf3ce44SJohn Forte EL(ha, "ignoring ftype: %xh\n", 296fcf3ce44SJohn Forte fptr->type); 297fcf3ce44SJohn Forte break; 298fcf3ce44SJohn Forte } 299fcf3ce44SJohn Forte types &= ~(fptr->type); 300fcf3ce44SJohn Forte } 301fcf3ce44SJohn Forte } 302fcf3ce44SJohn Forte } 303fcf3ce44SJohn Forte 304fcf3ce44SJohn Forte CACHE_UNLOCK(ha); 305fcf3ce44SJohn Forte 306fcf3ce44SJohn Forte if (strlen(attrs->option_rom_version) == 0) { 307fcf3ce44SJohn Forte int rval = -1; 308fcf3ce44SJohn Forte uint32_t i = 0; 309fcf3ce44SJohn Forte caddr_t fcode_ver_buf = NULL; 310fcf3ce44SJohn Forte 311fcf3ce44SJohn Forte if (CFG_IST(ha, CFG_CTRL_2200)) { 312fcf3ce44SJohn Forte /*LINTED [Solaris DDI_DEV_T_ANY Lint warning]*/ 313fcf3ce44SJohn Forte rval = ddi_getlongprop(DDI_DEV_T_ANY, ha->dip, 314fcf3ce44SJohn Forte DDI_PROP_DONTPASS | DDI_PROP_CANSLEEP, "version", 315fcf3ce44SJohn Forte (caddr_t)&fcode_ver_buf, (int32_t *)&i); 316fcf3ce44SJohn Forte } 317fcf3ce44SJohn Forte 318fcf3ce44SJohn Forte (void) snprintf(attrs->option_rom_version, 319fcf3ce44SJohn Forte FCHBA_OPTION_ROM_VERSION_LEN, "%s", 320fcf3ce44SJohn Forte (rval == DDI_PROP_SUCCESS ? fcode_ver_buf : 321fcf3ce44SJohn Forte "No boot image detected")); 322fcf3ce44SJohn Forte 323fcf3ce44SJohn Forte if (fcode_ver_buf != NULL) { 324fcf3ce44SJohn Forte kmem_free(fcode_ver_buf, (size_t)i); 325fcf3ce44SJohn Forte } 326fcf3ce44SJohn Forte 327fcf3ce44SJohn Forte } 328fcf3ce44SJohn Forte 329fcf3ce44SJohn Forte attrs->vendor_specific_id = ha->adapter_features; 330*5dfd244aSDaniel Beauregard attrs->max_frame_size = CFG_IST(ha, CFG_CTRL_242581) ? 331fcf3ce44SJohn Forte (ha->init_ctrl_blk.cb24.max_frame_length[1] << 8 | 332fcf3ce44SJohn Forte ha->init_ctrl_blk.cb24.max_frame_length[0]) : 333fcf3ce44SJohn Forte (ha->init_ctrl_blk.cb.max_frame_length[1] << 8 | 334fcf3ce44SJohn Forte ha->init_ctrl_blk.cb.max_frame_length[0]); 335fcf3ce44SJohn Forte attrs->supported_cos = 0x10000000; /* Class 3 only */ 336fcf3ce44SJohn Forte 337fcf3ce44SJohn Forte switch (chip & 0xFF00) { 338fcf3ce44SJohn Forte case 0x2200: 339fcf3ce44SJohn Forte attrs->supported_speed = FC_HBA_PORTSPEED_1GBIT; 340fcf3ce44SJohn Forte break; 341fcf3ce44SJohn Forte case 0x2300: 342fcf3ce44SJohn Forte attrs->supported_speed = FC_HBA_PORTSPEED_2GBIT | 343fcf3ce44SJohn Forte FC_HBA_PORTSPEED_1GBIT; 344fcf3ce44SJohn Forte break; 345fcf3ce44SJohn Forte case 0x2400: 346fcf3ce44SJohn Forte case 0x8400: 347fcf3ce44SJohn Forte attrs->supported_speed = FC_HBA_PORTSPEED_4GBIT | 348fcf3ce44SJohn Forte FC_HBA_PORTSPEED_2GBIT | FC_HBA_PORTSPEED_1GBIT; 349fcf3ce44SJohn Forte break; 350*5dfd244aSDaniel Beauregard case 0x8001: 351*5dfd244aSDaniel Beauregard attrs->supported_speed = FC_HBA_PORTSPEED_10GBIT; 352*5dfd244aSDaniel Beauregard break; 353fcf3ce44SJohn Forte case 0x2500: 354fcf3ce44SJohn Forte attrs->supported_speed = FC_HBA_PORTSPEED_8GBIT | 355fcf3ce44SJohn Forte FC_HBA_PORTSPEED_4GBIT | FC_HBA_PORTSPEED_2GBIT | 356fcf3ce44SJohn Forte FC_HBA_PORTSPEED_1GBIT; 357fcf3ce44SJohn Forte 358fcf3ce44SJohn Forte /* 359fcf3ce44SJohn Forte * Correct supported speeds based on type of 360fcf3ce44SJohn Forte * sfp that is present 361fcf3ce44SJohn Forte */ 362fcf3ce44SJohn Forte switch (ha->sfp_stat) { 363fcf3ce44SJohn Forte case 2: 364fcf3ce44SJohn Forte case 4: 365fcf3ce44SJohn Forte /* 4GB sfp */ 366fcf3ce44SJohn Forte attrs->supported_speed &= ~FC_HBA_PORTSPEED_8GBIT; 367fcf3ce44SJohn Forte break; 368fcf3ce44SJohn Forte case 3: 369fcf3ce44SJohn Forte case 5: 370fcf3ce44SJohn Forte /* 8GB sfp */ 371fcf3ce44SJohn Forte attrs->supported_speed &= ~FC_HBA_PORTSPEED_1GBIT; 372fcf3ce44SJohn Forte break; 373fcf3ce44SJohn Forte default: 374fcf3ce44SJohn Forte EL(ha, "sfp_stat: %xh\n", ha->sfp_stat); 375fcf3ce44SJohn Forte break; 376fcf3ce44SJohn Forte 377fcf3ce44SJohn Forte } 378fcf3ce44SJohn Forte 379fcf3ce44SJohn Forte break; 380fcf3ce44SJohn Forte case 0x5400: 381fcf3ce44SJohn Forte if (model == 0x13e) { 382fcf3ce44SJohn Forte /* QLE210 */ 383fcf3ce44SJohn Forte attrs->supported_speed = FC_HBA_PORTSPEED_2GBIT; 384fcf3ce44SJohn Forte } else { 385fcf3ce44SJohn Forte attrs->supported_speed = FC_HBA_PORTSPEED_4GBIT; 386fcf3ce44SJohn Forte } 387fcf3ce44SJohn Forte break; 388fcf3ce44SJohn Forte case 0x6300: 389fcf3ce44SJohn Forte attrs->supported_speed = FC_HBA_PORTSPEED_2GBIT; 390fcf3ce44SJohn Forte break; 391fcf3ce44SJohn Forte default: 392fcf3ce44SJohn Forte attrs->supported_speed = FC_HBA_PORTSPEED_UNKNOWN; 393fcf3ce44SJohn Forte break; 394fcf3ce44SJohn Forte } 395fcf3ce44SJohn Forte 396fcf3ce44SJohn Forte /* Use parent dip as adapter identifier */ 397fcf3ce44SJohn Forte attrs->hba_fru_details.low = 0x514C6F6769630000; /* QLogic */ 398fcf3ce44SJohn Forte 399fcf3ce44SJohn Forte if (ha->fru_hba_index == 0) { 400fcf3ce44SJohn Forte EL(ha, "unable to generate high_fru details from " 401fcf3ce44SJohn Forte "device path: %s\n", ha->devpath); 402fcf3ce44SJohn Forte attrs->hba_fru_details.low = 0; 403fcf3ce44SJohn Forte attrs->hba_fru_details.high = 0; 404fcf3ce44SJohn Forte attrs->hba_fru_details.port_index = 0; 405fcf3ce44SJohn Forte } else { 406fcf3ce44SJohn Forte attrs->hba_fru_details.high = ha->fru_hba_index; 407fcf3ce44SJohn Forte attrs->hba_fru_details.port_index = ha->fru_port_index; 408fcf3ce44SJohn Forte } 409fcf3ce44SJohn Forte 410fcf3ce44SJohn Forte /* 411fcf3ce44SJohn Forte * Populate the model info. Legacy (22xx, 23xx, 63xx) do not 412fcf3ce44SJohn Forte * have vpd info, so use the hard coded table. Anything else 413fcf3ce44SJohn Forte * has VPD (or is suppose to have VPD), so use that. For both 414fcf3ce44SJohn Forte * cases, if the model isn't found, use defaults. 415fcf3ce44SJohn Forte */ 416fcf3ce44SJohn Forte 417fcf3ce44SJohn Forte switch (chip & 0xFF00) { 418fcf3ce44SJohn Forte case 0x2200: 419fcf3ce44SJohn Forte case 0x2300: 420fcf3ce44SJohn Forte case 0x6300: 421fcf3ce44SJohn Forte /* Table based data */ 422fcf3ce44SJohn Forte for (i = 0; models[i].ssid; i++) { 423fcf3ce44SJohn Forte if ((model == models[i].ssid) && 424fcf3ce44SJohn Forte (ssdevid == models[i].ssvid)) { 425fcf3ce44SJohn Forte break; 426fcf3ce44SJohn Forte } 427fcf3ce44SJohn Forte } 428fcf3ce44SJohn Forte 429fcf3ce44SJohn Forte if (models[i].ssid) { 430fcf3ce44SJohn Forte (void) snprintf(attrs->model, FCHBA_MODEL_LEN, "%s", 431fcf3ce44SJohn Forte models[i].model); 432fcf3ce44SJohn Forte (void) snprintf(attrs->model_description, 433fcf3ce44SJohn Forte FCHBA_MODEL_DESCRIPTION_LEN, "%s", 434fcf3ce44SJohn Forte models[i].model_description); 435fcf3ce44SJohn Forte } else { 436fcf3ce44SJohn Forte (void) snprintf(attrs->model, FCHBA_MODEL_LEN, 437fcf3ce44SJohn Forte "%x", chip); 438fcf3ce44SJohn Forte (void) snprintf(attrs->model_description, 439fcf3ce44SJohn Forte FCHBA_MODEL_DESCRIPTION_LEN, "%x", chip); 440fcf3ce44SJohn Forte } 441fcf3ce44SJohn Forte 442fcf3ce44SJohn Forte /* Special model handling for RoHS version of the HBA */ 443fcf3ce44SJohn Forte if (models[i].ssid == 0x10a && ha->adapInfo[10] == 444fcf3ce44SJohn Forte (uint8_t)0x36) { 445fcf3ce44SJohn Forte (void) snprintf(attrs->model, FCHBA_MODEL_LEN, "%s", 446fcf3ce44SJohn Forte "375-3363-xx"); 447fcf3ce44SJohn Forte (void) snprintf(attrs->model_description, 448fcf3ce44SJohn Forte FCHBA_MODEL_DESCRIPTION_LEN, "%s", 449fcf3ce44SJohn Forte "SG-XPCI2FC-QF2-Z"); 450fcf3ce44SJohn Forte } 451fcf3ce44SJohn Forte break; 452fcf3ce44SJohn Forte 453fcf3ce44SJohn Forte case 0x2400: 454fcf3ce44SJohn Forte case 0x2500: 455fcf3ce44SJohn Forte case 0x5400: 456fcf3ce44SJohn Forte case 0x8400: 457*5dfd244aSDaniel Beauregard case 0x8000: 458fcf3ce44SJohn Forte default: 459fcf3ce44SJohn Forte if ((i = ql_vpd_lookup(ha, (uint8_t *)VPD_TAG_PN, 460fcf3ce44SJohn Forte (uint8_t *)attrs->model, FCHBA_MODEL_LEN)) >= 0) { 461fcf3ce44SJohn Forte (void) ql_vpd_lookup(ha, (uint8_t *)VPD_TAG_PRODID, 462fcf3ce44SJohn Forte (uint8_t *)attrs->model_description, 463fcf3ce44SJohn Forte FCHBA_MODEL_DESCRIPTION_LEN); 464fcf3ce44SJohn Forte } else { 465fcf3ce44SJohn Forte (void) snprintf(attrs->model, FCHBA_MODEL_LEN, 466fcf3ce44SJohn Forte "%x", chip); 467fcf3ce44SJohn Forte (void) snprintf(attrs->model_description, 468fcf3ce44SJohn Forte FCHBA_MODEL_DESCRIPTION_LEN, "%x", chip); 469fcf3ce44SJohn Forte } 470fcf3ce44SJohn Forte break; 471fcf3ce44SJohn Forte } 472fcf3ce44SJohn Forte 473fcf3ce44SJohn Forte /* 474fcf3ce44SJohn Forte * Populate the LV symbolic node and port name strings 475fcf3ce44SJohn Forte * 476fcf3ce44SJohn Forte * Symbolic node name format is: 477fcf3ce44SJohn Forte * <hostname> 478fcf3ce44SJohn Forte * 479fcf3ce44SJohn Forte * Symbolic port name format is: 480fcf3ce44SJohn Forte * <driver_name>(<instance>,<vp index>) 481fcf3ce44SJohn Forte */ 482fcf3ce44SJohn Forte vlen = (strlen(utsname.nodename) > FCHBA_SYMB_NAME_LEN ? 483fcf3ce44SJohn Forte FCHBA_SYMB_NAME_LEN : strlen(utsname.nodename)); 484fcf3ce44SJohn Forte (void) snprintf((int8_t *)attrs->sym_node_name, vlen, "%s", 485fcf3ce44SJohn Forte utsname.nodename); 486fcf3ce44SJohn Forte 487fcf3ce44SJohn Forte vlen = (strlen(QL_NAME) + 9 > FCHBA_SYMB_NAME_LEN ? 488fcf3ce44SJohn Forte FCHBA_SYMB_NAME_LEN : strlen(QL_NAME) + 9); 489fcf3ce44SJohn Forte (void) snprintf((int8_t *)attrs->sym_port_name, vlen, 490fcf3ce44SJohn Forte "%s(%d,%d)", QL_NAME, ha->instance, ha->vp_index); 491fcf3ce44SJohn Forte 492*5dfd244aSDaniel Beauregard QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 493fcf3ce44SJohn Forte } 494fcf3ce44SJohn Forte 495fcf3ce44SJohn Forte /* 496fcf3ce44SJohn Forte * ql_setup_fruinfo 497fcf3ce44SJohn Forte * Generates common id's for instances on the same 498fcf3ce44SJohn Forte * physical HBA. 499fcf3ce44SJohn Forte * 500fcf3ce44SJohn Forte * Input: 501fcf3ce44SJohn Forte * ha = adapter state structure 502fcf3ce44SJohn Forte * 503fcf3ce44SJohn Forte * Returns: 504fcf3ce44SJohn Forte * 505fcf3ce44SJohn Forte * Context: 506fcf3ce44SJohn Forte * Kernel context. 507fcf3ce44SJohn Forte */ 508fcf3ce44SJohn Forte void 509fcf3ce44SJohn Forte ql_setup_fruinfo(ql_adapter_state_t *ha) 510fcf3ce44SJohn Forte { 511fcf3ce44SJohn Forte uint32_t mybasedev_len; 512fcf3ce44SJohn Forte ql_adapter_state_t *base_ha = NULL; 513fcf3ce44SJohn Forte 514*5dfd244aSDaniel Beauregard QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 515fcf3ce44SJohn Forte 516fcf3ce44SJohn Forte /* 517fcf3ce44SJohn Forte * To generate common id for instances residing on the 518fcf3ce44SJohn Forte * the same HBA, the devpath for each instance is parsed 519fcf3ce44SJohn Forte * and those instances which have matching base devpaths are 520fcf3ce44SJohn Forte * given same hba_index, and each port on the same hba are 521fcf3ce44SJohn Forte * then assigned unique port_indexs based on the devpath. 522fcf3ce44SJohn Forte */ 523fcf3ce44SJohn Forte 524fcf3ce44SJohn Forte /* 525fcf3ce44SJohn Forte * Get this ha's basedev path and its port index 526fcf3ce44SJohn Forte */ 527fcf3ce44SJohn Forte if (ql_get_basedev_len(ha, &mybasedev_len, &ha->fru_port_index) == 0) { 528fcf3ce44SJohn Forte 529fcf3ce44SJohn Forte GLOBAL_STATE_LOCK(); 530fcf3ce44SJohn Forte 531fcf3ce44SJohn Forte /* 532fcf3ce44SJohn Forte * Search for this basedev against all of the 533fcf3ce44SJohn Forte * ha in the ql_hba global list. If found one 534fcf3ce44SJohn Forte * then we are part of other adapter in the 535fcf3ce44SJohn Forte * ql_hba list and hence use that ha's hba_index. 536fcf3ce44SJohn Forte * If not create a new one from the global hba index. 537fcf3ce44SJohn Forte */ 538fcf3ce44SJohn Forte base_ha = ql_search_basedev(ha, mybasedev_len); 539fcf3ce44SJohn Forte if (base_ha != NULL && base_ha->fru_hba_index != 0) { 540fcf3ce44SJohn Forte ha->fru_hba_index = base_ha->fru_hba_index; 541fcf3ce44SJohn Forte } else { 542fcf3ce44SJohn Forte ha->fru_hba_index = ql_gfru_hba_index++; 543fcf3ce44SJohn Forte } 544fcf3ce44SJohn Forte 545fcf3ce44SJohn Forte GLOBAL_STATE_UNLOCK(); 546fcf3ce44SJohn Forte 547fcf3ce44SJohn Forte } else { 548fcf3ce44SJohn Forte ha->fru_hba_index = 0; 549fcf3ce44SJohn Forte ha->fru_port_index = 0; 550fcf3ce44SJohn Forte } 551fcf3ce44SJohn Forte 552*5dfd244aSDaniel Beauregard QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 553fcf3ce44SJohn Forte } 554fcf3ce44SJohn Forte 555fcf3ce44SJohn Forte /* 556fcf3ce44SJohn Forte * ql_get_basedev_len 557fcf3ce44SJohn Forte * 558fcf3ce44SJohn Forte * Gets the length of the base device name in the 559fcf3ce44SJohn Forte * devpath of the current instance. 560fcf3ce44SJohn Forte * 561fcf3ce44SJohn Forte * Input: 562fcf3ce44SJohn Forte * ha - adapter state pointer. 563fcf3ce44SJohn Forte * basedev_len - pointer to the integer which 564fcf3ce44SJohn Forte * holds the calculated length. 565fcf3ce44SJohn Forte * port_index - pointer to the integer which 566fcf3ce44SJohn Forte * contains the port index of 567fcf3ce44SJohn Forte * for this device. 568fcf3ce44SJohn Forte * Returns: 569fcf3ce44SJohn Forte * 0 if successfully parsed, -1 otherwise. 570fcf3ce44SJohn Forte * 571fcf3ce44SJohn Forte * Context: 572fcf3ce44SJohn Forte * Kernel context. 573fcf3ce44SJohn Forte */ 574fcf3ce44SJohn Forte static uint32_t 575fcf3ce44SJohn Forte ql_get_basedev_len(ql_adapter_state_t *ha, uint32_t *basedev_len, 576fcf3ce44SJohn Forte uint32_t *port_index) 577fcf3ce44SJohn Forte { 578fcf3ce44SJohn Forte int32_t dev_off; 579fcf3ce44SJohn Forte int32_t port_off; 580fcf3ce44SJohn Forte int8_t *devstr; 581fcf3ce44SJohn Forte 582*5dfd244aSDaniel Beauregard QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 583fcf3ce44SJohn Forte 584fcf3ce44SJohn Forte if (ha->devpath == NULL) { 585fcf3ce44SJohn Forte return ((uint32_t)-1); 586fcf3ce44SJohn Forte } 587fcf3ce44SJohn Forte 588fcf3ce44SJohn Forte dev_off = (int32_t)(strlen(ha->devpath) - 1); 589fcf3ce44SJohn Forte port_off = -1; 590fcf3ce44SJohn Forte 591fcf3ce44SJohn Forte /* Until we reach the first char or a '@' char in the path */ 592fcf3ce44SJohn Forte while ((dev_off >= 0) && (ha->devpath[dev_off] != '@')) { 593fcf3ce44SJohn Forte 594fcf3ce44SJohn Forte if (ha->devpath[dev_off] == ',') { 595fcf3ce44SJohn Forte port_off = dev_off + 1; 596fcf3ce44SJohn Forte } 597fcf3ce44SJohn Forte 598fcf3ce44SJohn Forte dev_off--; 599fcf3ce44SJohn Forte } 600fcf3ce44SJohn Forte 601fcf3ce44SJohn Forte if (dev_off < 0) { 602fcf3ce44SJohn Forte EL(ha, "Invalid device path '%s'. Cannot get basedev\n", 603fcf3ce44SJohn Forte ha->devpath); 604fcf3ce44SJohn Forte return ((uint32_t)-1); 605fcf3ce44SJohn Forte } 606fcf3ce44SJohn Forte 607fcf3ce44SJohn Forte if (port_off == -1) { 608fcf3ce44SJohn Forte *port_index = 0; 609fcf3ce44SJohn Forte *basedev_len = (uint32_t)strlen(ha->devpath); 610fcf3ce44SJohn Forte } else { 611fcf3ce44SJohn Forte /* Get the port index */ 612fcf3ce44SJohn Forte devstr = ha->devpath + port_off; 613fcf3ce44SJohn Forte *port_index = stoi(&devstr); 614fcf3ce44SJohn Forte if (*port_index == 0) { 615fcf3ce44SJohn Forte EL(ha, "Invalid device path '%s'. Cannot get " 616fcf3ce44SJohn Forte "port_index\n", ha->devpath); 617fcf3ce44SJohn Forte return ((uint32_t)-1); 618fcf3ce44SJohn Forte } 619fcf3ce44SJohn Forte 620fcf3ce44SJohn Forte *basedev_len = (uint32_t)(port_off - 1); 621fcf3ce44SJohn Forte } 622fcf3ce44SJohn Forte 623*5dfd244aSDaniel Beauregard QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 624fcf3ce44SJohn Forte 625fcf3ce44SJohn Forte return (0); 626fcf3ce44SJohn Forte } 627fcf3ce44SJohn Forte 628fcf3ce44SJohn Forte /* 629fcf3ce44SJohn Forte * ql_search_basedev 630fcf3ce44SJohn Forte * Searches the list of ha instances to find which 631fcf3ce44SJohn Forte * ha instance has same base device path as input's. 632fcf3ce44SJohn Forte * 633fcf3ce44SJohn Forte * Input: 634fcf3ce44SJohn Forte * myha = current adapter state pointer. 635fcf3ce44SJohn Forte * mybasedev_len = Length of the base device in the 636fcf3ce44SJohn Forte * device path name. 637fcf3ce44SJohn Forte * 638fcf3ce44SJohn Forte * Returns: 639fcf3ce44SJohn Forte * If match = ptr to matching ha structure. 640fcf3ce44SJohn Forte * If no match = NULL ptr. 641fcf3ce44SJohn Forte * 642fcf3ce44SJohn Forte * Context: 643fcf3ce44SJohn Forte * Kernel context. 644fcf3ce44SJohn Forte */ 645fcf3ce44SJohn Forte static ql_adapter_state_t * 646fcf3ce44SJohn Forte ql_search_basedev(ql_adapter_state_t *myha, uint32_t mybasedev_len) 647fcf3ce44SJohn Forte { 648fcf3ce44SJohn Forte ql_link_t *link; 649fcf3ce44SJohn Forte ql_adapter_state_t *ha; 650fcf3ce44SJohn Forte uint32_t basedev_len, port_index; 651fcf3ce44SJohn Forte 652*5dfd244aSDaniel Beauregard QL_PRINT_3(CE_CONT, "(%d): started\n", myha->instance); 653fcf3ce44SJohn Forte 654fcf3ce44SJohn Forte for (link = ql_hba.first; link != NULL; link = link->next) { 655fcf3ce44SJohn Forte 656fcf3ce44SJohn Forte ha = link->base_address; 657fcf3ce44SJohn Forte 658fcf3ce44SJohn Forte if (ha == NULL) { 659fcf3ce44SJohn Forte EL(myha, "null ha link detected!\n"); 660fcf3ce44SJohn Forte return (NULL); 661fcf3ce44SJohn Forte } 662fcf3ce44SJohn Forte 663fcf3ce44SJohn Forte if (ha == myha) { 664fcf3ce44SJohn Forte continue; 665fcf3ce44SJohn Forte } 666fcf3ce44SJohn Forte 667fcf3ce44SJohn Forte if (ql_get_basedev_len(ha, &basedev_len, &port_index) != 0) { 668fcf3ce44SJohn Forte if (ha->devpath == NULL) { 669fcf3ce44SJohn Forte EL(myha, "Device path NULL. Unable to get " 670fcf3ce44SJohn Forte "the basedev\n"); 671fcf3ce44SJohn Forte } else { 672fcf3ce44SJohn Forte EL(myha, "Invalid device path '%s'. Cannot " 673fcf3ce44SJohn Forte "get the hba index and port index\n", 674fcf3ce44SJohn Forte ha->devpath); 675fcf3ce44SJohn Forte } 676fcf3ce44SJohn Forte continue; 677fcf3ce44SJohn Forte } 678fcf3ce44SJohn Forte 679fcf3ce44SJohn Forte /* 680fcf3ce44SJohn Forte * If both the basedev len do not match, then it 681fcf3ce44SJohn Forte * is obvious that both are not pointing to the 682fcf3ce44SJohn Forte * same base device. 683fcf3ce44SJohn Forte */ 684fcf3ce44SJohn Forte if ((basedev_len == mybasedev_len) && (strncmp(myha->devpath, 685fcf3ce44SJohn Forte ha->devpath, basedev_len) == 0)) { 686fcf3ce44SJohn Forte 687fcf3ce44SJohn Forte /* We found the ha with same basedev */ 688*5dfd244aSDaniel Beauregard QL_PRINT_3(CE_CONT, "(%d): found, done\n", 689fcf3ce44SJohn Forte myha->instance); 690fcf3ce44SJohn Forte return (ha); 691fcf3ce44SJohn Forte } 692fcf3ce44SJohn Forte } 693fcf3ce44SJohn Forte 694*5dfd244aSDaniel Beauregard QL_PRINT_3(CE_CONT, "(%d): not found, done\n", myha->instance); 695fcf3ce44SJohn Forte 696fcf3ce44SJohn Forte return (NULL); 697fcf3ce44SJohn Forte } 698