1 /* 2 * Copyright (c) 2012 Intel Corporation. All rights reserved. 3 * Copyright (c) 2006 - 2012 QLogic Corporation. All rights reserved. 4 * Copyright (c) 2003, 2004, 2005, 2006 PathScale, Inc. All rights reserved. 5 * 6 * This software is available to you under a choice of one of two 7 * licenses. You may choose to be licensed under the terms of the GNU 8 * General Public License (GPL) Version 2, available from the file 9 * COPYING in the main directory of this source tree, or the 10 * OpenIB.org BSD license below: 11 * 12 * Redistribution and use in source and binary forms, with or 13 * without modification, are permitted provided that the following 14 * conditions are met: 15 * 16 * - Redistributions of source code must retain the above 17 * copyright notice, this list of conditions and the following 18 * disclaimer. 19 * 20 * - Redistributions in binary form must reproduce the above 21 * copyright notice, this list of conditions and the following 22 * disclaimer in the documentation and/or other materials 23 * provided with the distribution. 24 * 25 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 26 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 27 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 28 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 29 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 30 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 31 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 32 * SOFTWARE. 33 */ 34 35 #include <linux/delay.h> 36 #include <linux/pci.h> 37 #include <linux/vmalloc.h> 38 39 #include "qib.h" 40 41 /* 42 * Functions specific to the serial EEPROM on cards handled by ib_qib. 43 * The actual serail interface code is in qib_twsi.c. This file is a client 44 */ 45 46 /** 47 * qib_eeprom_read - receives bytes from the eeprom via I2C 48 * @dd: the qlogic_ib device 49 * @eeprom_offset: address to read from 50 * @buffer: where to store result 51 * @len: number of bytes to receive 52 */ 53 int qib_eeprom_read(struct qib_devdata *dd, u8 eeprom_offset, 54 void *buff, int len) 55 { 56 int ret; 57 58 ret = mutex_lock_interruptible(&dd->eep_lock); 59 if (!ret) { 60 ret = qib_twsi_reset(dd); 61 if (ret) 62 qib_dev_err(dd, "EEPROM Reset for read failed\n"); 63 else 64 ret = qib_twsi_blk_rd(dd, dd->twsi_eeprom_dev, 65 eeprom_offset, buff, len); 66 mutex_unlock(&dd->eep_lock); 67 } 68 69 return ret; 70 } 71 72 /* 73 * Actually update the eeprom, first doing write enable if 74 * needed, then restoring write enable state. 75 * Must be called with eep_lock held 76 */ 77 static int eeprom_write_with_enable(struct qib_devdata *dd, u8 offset, 78 const void *buf, int len) 79 { 80 int ret, pwen; 81 82 pwen = dd->f_eeprom_wen(dd, 1); 83 ret = qib_twsi_reset(dd); 84 if (ret) 85 qib_dev_err(dd, "EEPROM Reset for write failed\n"); 86 else 87 ret = qib_twsi_blk_wr(dd, dd->twsi_eeprom_dev, 88 offset, buf, len); 89 dd->f_eeprom_wen(dd, pwen); 90 return ret; 91 } 92 93 /** 94 * qib_eeprom_write - writes data to the eeprom via I2C 95 * @dd: the qlogic_ib device 96 * @eeprom_offset: where to place data 97 * @buffer: data to write 98 * @len: number of bytes to write 99 */ 100 int qib_eeprom_write(struct qib_devdata *dd, u8 eeprom_offset, 101 const void *buff, int len) 102 { 103 int ret; 104 105 ret = mutex_lock_interruptible(&dd->eep_lock); 106 if (!ret) { 107 ret = eeprom_write_with_enable(dd, eeprom_offset, buff, len); 108 mutex_unlock(&dd->eep_lock); 109 } 110 111 return ret; 112 } 113 114 static u8 flash_csum(struct qib_flash *ifp, int adjust) 115 { 116 u8 *ip = (u8 *) ifp; 117 u8 csum = 0, len; 118 119 /* 120 * Limit length checksummed to max length of actual data. 121 * Checksum of erased eeprom will still be bad, but we avoid 122 * reading past the end of the buffer we were passed. 123 */ 124 len = ifp->if_length; 125 if (len > sizeof(struct qib_flash)) 126 len = sizeof(struct qib_flash); 127 while (len--) 128 csum += *ip++; 129 csum -= ifp->if_csum; 130 csum = ~csum; 131 if (adjust) 132 ifp->if_csum = csum; 133 134 return csum; 135 } 136 137 /** 138 * qib_get_eeprom_info- get the GUID et al. from the TSWI EEPROM device 139 * @dd: the qlogic_ib device 140 * 141 * We have the capability to use the nguid field, and get 142 * the guid from the first chip's flash, to use for all of them. 143 */ 144 void qib_get_eeprom_info(struct qib_devdata *dd) 145 { 146 void *buf; 147 struct qib_flash *ifp; 148 __be64 guid; 149 int len, eep_stat; 150 u8 csum, *bguid; 151 int t = dd->unit; 152 struct qib_devdata *dd0 = qib_lookup(0); 153 154 if (t && dd0->nguid > 1 && t <= dd0->nguid) { 155 u8 oguid; 156 157 dd->base_guid = dd0->base_guid; 158 bguid = (u8 *) &dd->base_guid; 159 160 oguid = bguid[7]; 161 bguid[7] += t; 162 if (oguid > bguid[7]) { 163 if (bguid[6] == 0xff) { 164 if (bguid[5] == 0xff) { 165 qib_dev_err(dd, 166 "Can't set %s GUID from base, wraps to OUI!\n", 167 qib_get_unit_name(t)); 168 dd->base_guid = 0; 169 goto bail; 170 } 171 bguid[5]++; 172 } 173 bguid[6]++; 174 } 175 dd->nguid = 1; 176 goto bail; 177 } 178 179 /* 180 * Read full flash, not just currently used part, since it may have 181 * been written with a newer definition. 182 * */ 183 len = sizeof(struct qib_flash); 184 buf = vmalloc(len); 185 if (!buf) { 186 qib_dev_err(dd, 187 "Couldn't allocate memory to read %u bytes from eeprom for GUID\n", 188 len); 189 goto bail; 190 } 191 192 /* 193 * Use "public" eeprom read function, which does locking and 194 * figures out device. This will migrate to chip-specific. 195 */ 196 eep_stat = qib_eeprom_read(dd, 0, buf, len); 197 198 if (eep_stat) { 199 qib_dev_err(dd, "Failed reading GUID from eeprom\n"); 200 goto done; 201 } 202 ifp = (struct qib_flash *)buf; 203 204 csum = flash_csum(ifp, 0); 205 if (csum != ifp->if_csum) { 206 qib_devinfo(dd->pcidev, 207 "Bad I2C flash checksum: 0x%x, not 0x%x\n", 208 csum, ifp->if_csum); 209 goto done; 210 } 211 if (*(__be64 *) ifp->if_guid == cpu_to_be64(0) || 212 *(__be64 *) ifp->if_guid == ~cpu_to_be64(0)) { 213 qib_dev_err(dd, 214 "Invalid GUID %llx from flash; ignoring\n", 215 *(unsigned long long *) ifp->if_guid); 216 /* don't allow GUID if all 0 or all 1's */ 217 goto done; 218 } 219 220 /* complain, but allow it */ 221 if (*(u64 *) ifp->if_guid == 0x100007511000000ULL) 222 qib_devinfo(dd->pcidev, 223 "Warning, GUID %llx is default, probably not correct!\n", 224 *(unsigned long long *) ifp->if_guid); 225 226 bguid = ifp->if_guid; 227 if (!bguid[0] && !bguid[1] && !bguid[2]) { 228 /* 229 * Original incorrect GUID format in flash; fix in 230 * core copy, by shifting up 2 octets; don't need to 231 * change top octet, since both it and shifted are 0. 232 */ 233 bguid[1] = bguid[3]; 234 bguid[2] = bguid[4]; 235 bguid[3] = 0; 236 bguid[4] = 0; 237 guid = *(__be64 *) ifp->if_guid; 238 } else 239 guid = *(__be64 *) ifp->if_guid; 240 dd->base_guid = guid; 241 dd->nguid = ifp->if_numguid; 242 /* 243 * Things are slightly complicated by the desire to transparently 244 * support both the Pathscale 10-digit serial number and the QLogic 245 * 13-character version. 246 */ 247 if ((ifp->if_fversion > 1) && ifp->if_sprefix[0] && 248 ((u8 *) ifp->if_sprefix)[0] != 0xFF) { 249 char *snp = dd->serial; 250 251 /* 252 * This board has a Serial-prefix, which is stored 253 * elsewhere for backward-compatibility. 254 */ 255 memcpy(snp, ifp->if_sprefix, sizeof(ifp->if_sprefix)); 256 snp[sizeof(ifp->if_sprefix)] = '\0'; 257 len = strlen(snp); 258 snp += len; 259 len = sizeof(dd->serial) - len; 260 if (len > sizeof(ifp->if_serial)) 261 len = sizeof(ifp->if_serial); 262 memcpy(snp, ifp->if_serial, len); 263 } else { 264 memcpy(dd->serial, ifp->if_serial, sizeof(ifp->if_serial)); 265 } 266 if (!strstr(ifp->if_comment, "Tested successfully")) 267 qib_dev_err(dd, 268 "Board SN %s did not pass functional test: %s\n", 269 dd->serial, ifp->if_comment); 270 271 done: 272 vfree(buf); 273 274 bail:; 275 } 276 277