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 goto bail; 187 188 /* 189 * Use "public" eeprom read function, which does locking and 190 * figures out device. This will migrate to chip-specific. 191 */ 192 eep_stat = qib_eeprom_read(dd, 0, buf, len); 193 194 if (eep_stat) { 195 qib_dev_err(dd, "Failed reading GUID from eeprom\n"); 196 goto done; 197 } 198 ifp = (struct qib_flash *)buf; 199 200 csum = flash_csum(ifp, 0); 201 if (csum != ifp->if_csum) { 202 qib_devinfo(dd->pcidev, 203 "Bad I2C flash checksum: 0x%x, not 0x%x\n", 204 csum, ifp->if_csum); 205 goto done; 206 } 207 if (*(__be64 *) ifp->if_guid == cpu_to_be64(0) || 208 *(__be64 *) ifp->if_guid == ~cpu_to_be64(0)) { 209 qib_dev_err(dd, 210 "Invalid GUID %llx from flash; ignoring\n", 211 *(unsigned long long *) ifp->if_guid); 212 /* don't allow GUID if all 0 or all 1's */ 213 goto done; 214 } 215 216 /* complain, but allow it */ 217 if (*(u64 *) ifp->if_guid == 0x100007511000000ULL) 218 qib_devinfo(dd->pcidev, 219 "Warning, GUID %llx is default, probably not correct!\n", 220 *(unsigned long long *) ifp->if_guid); 221 222 bguid = ifp->if_guid; 223 if (!bguid[0] && !bguid[1] && !bguid[2]) { 224 /* 225 * Original incorrect GUID format in flash; fix in 226 * core copy, by shifting up 2 octets; don't need to 227 * change top octet, since both it and shifted are 0. 228 */ 229 bguid[1] = bguid[3]; 230 bguid[2] = bguid[4]; 231 bguid[3] = 0; 232 bguid[4] = 0; 233 guid = *(__be64 *) ifp->if_guid; 234 } else 235 guid = *(__be64 *) ifp->if_guid; 236 dd->base_guid = guid; 237 dd->nguid = ifp->if_numguid; 238 /* 239 * Things are slightly complicated by the desire to transparently 240 * support both the Pathscale 10-digit serial number and the QLogic 241 * 13-character version. 242 */ 243 if ((ifp->if_fversion > 1) && ifp->if_sprefix[0] && 244 ((u8 *) ifp->if_sprefix)[0] != 0xFF) { 245 char *snp = dd->serial; 246 247 /* 248 * This board has a Serial-prefix, which is stored 249 * elsewhere for backward-compatibility. 250 */ 251 memcpy(snp, ifp->if_sprefix, sizeof(ifp->if_sprefix)); 252 snp[sizeof(ifp->if_sprefix)] = '\0'; 253 len = strlen(snp); 254 snp += len; 255 len = sizeof(dd->serial) - len; 256 if (len > sizeof(ifp->if_serial)) 257 len = sizeof(ifp->if_serial); 258 memcpy(snp, ifp->if_serial, len); 259 } else { 260 memcpy(dd->serial, ifp->if_serial, sizeof(ifp->if_serial)); 261 } 262 if (!strstr(ifp->if_comment, "Tested successfully")) 263 qib_dev_err(dd, 264 "Board SN %s did not pass functional test: %s\n", 265 dd->serial, ifp->if_comment); 266 267 done: 268 vfree(buf); 269 270 bail:; 271 } 272 273