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