1 /******************************************************************************* 2 * 3 * Intel Ethernet Controller XL710 Family Linux Driver 4 * Copyright(c) 2013 - 2014 Intel Corporation. 5 * 6 * This program is free software; you can redistribute it and/or modify it 7 * under the terms and conditions of the GNU General Public License, 8 * version 2, as published by the Free Software Foundation. 9 * 10 * This program is distributed in the hope it will be useful, but WITHOUT 11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 13 * more details. 14 * 15 * You should have received a copy of the GNU General Public License along 16 * with this program. If not, see <http://www.gnu.org/licenses/>. 17 * 18 * The full GNU General Public License is included in this distribution in 19 * the file called "COPYING". 20 * 21 * Contact Information: 22 * e1000-devel Mailing List <e1000-devel@lists.sourceforge.net> 23 * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 24 * 25 ******************************************************************************/ 26 27 #include "i40e_prototype.h" 28 29 /** 30 * i40e_init_nvm_ops - Initialize NVM function pointers. 31 * @hw: pointer to the HW structure. 32 * 33 * Setups the function pointers and the NVM info structure. Should be called 34 * once per NVM initialization, e.g. inside the i40e_init_shared_code(). 35 * Please notice that the NVM term is used here (& in all methods covered 36 * in this file) as an equivalent of the FLASH part mapped into the SR. 37 * We are accessing FLASH always thru the Shadow RAM. 38 **/ 39 i40e_status i40e_init_nvm(struct i40e_hw *hw) 40 { 41 struct i40e_nvm_info *nvm = &hw->nvm; 42 i40e_status ret_code = 0; 43 u32 fla, gens; 44 u8 sr_size; 45 46 /* The SR size is stored regardless of the nvm programming mode 47 * as the blank mode may be used in the factory line. 48 */ 49 gens = rd32(hw, I40E_GLNVM_GENS); 50 sr_size = ((gens & I40E_GLNVM_GENS_SR_SIZE_MASK) >> 51 I40E_GLNVM_GENS_SR_SIZE_SHIFT); 52 /* Switching to words (sr_size contains power of 2KB). */ 53 nvm->sr_size = (1 << sr_size) * I40E_SR_WORDS_IN_1KB; 54 55 /* Check if we are in the normal or blank NVM programming mode. */ 56 fla = rd32(hw, I40E_GLNVM_FLA); 57 if (fla & I40E_GLNVM_FLA_LOCKED_MASK) { /* Normal programming mode. */ 58 /* Max NVM timeout. */ 59 nvm->timeout = I40E_MAX_NVM_TIMEOUT; 60 nvm->blank_nvm_mode = false; 61 } else { /* Blank programming mode. */ 62 nvm->blank_nvm_mode = true; 63 ret_code = I40E_ERR_NVM_BLANK_MODE; 64 hw_dbg(hw, "NVM init error: unsupported blank mode.\n"); 65 } 66 67 return ret_code; 68 } 69 70 /** 71 * i40e_acquire_nvm - Generic request for acquiring the NVM ownership. 72 * @hw: pointer to the HW structure. 73 * @access: NVM access type (read or write). 74 * 75 * This function will request NVM ownership for reading 76 * via the proper Admin Command. 77 **/ 78 i40e_status i40e_acquire_nvm(struct i40e_hw *hw, 79 enum i40e_aq_resource_access_type access) 80 { 81 i40e_status ret_code = 0; 82 u64 gtime, timeout; 83 u64 time = 0; 84 85 if (hw->nvm.blank_nvm_mode) 86 goto i40e_i40e_acquire_nvm_exit; 87 88 ret_code = i40e_aq_request_resource(hw, I40E_NVM_RESOURCE_ID, access, 89 0, &time, NULL); 90 /* Reading the Global Device Timer. */ 91 gtime = rd32(hw, I40E_GLVFGEN_TIMER); 92 93 /* Store the timeout. */ 94 hw->nvm.hw_semaphore_timeout = I40E_MS_TO_GTIME(time) + gtime; 95 96 if (ret_code) { 97 /* Set the polling timeout. */ 98 if (time > I40E_MAX_NVM_TIMEOUT) 99 timeout = I40E_MS_TO_GTIME(I40E_MAX_NVM_TIMEOUT) 100 + gtime; 101 else 102 timeout = hw->nvm.hw_semaphore_timeout; 103 /* Poll until the current NVM owner timeouts. */ 104 while (gtime < timeout) { 105 usleep_range(10000, 20000); 106 ret_code = i40e_aq_request_resource(hw, 107 I40E_NVM_RESOURCE_ID, 108 access, 0, &time, 109 NULL); 110 if (!ret_code) { 111 hw->nvm.hw_semaphore_timeout = 112 I40E_MS_TO_GTIME(time) + gtime; 113 break; 114 } 115 gtime = rd32(hw, I40E_GLVFGEN_TIMER); 116 } 117 if (ret_code) { 118 hw->nvm.hw_semaphore_timeout = 0; 119 hw->nvm.hw_semaphore_wait = 120 I40E_MS_TO_GTIME(time) + gtime; 121 hw_dbg(hw, "NVM acquire timed out, wait %llu ms before trying again.\n", 122 time); 123 } 124 } 125 126 i40e_i40e_acquire_nvm_exit: 127 return ret_code; 128 } 129 130 /** 131 * i40e_release_nvm - Generic request for releasing the NVM ownership. 132 * @hw: pointer to the HW structure. 133 * 134 * This function will release NVM resource via the proper Admin Command. 135 **/ 136 void i40e_release_nvm(struct i40e_hw *hw) 137 { 138 if (!hw->nvm.blank_nvm_mode) 139 i40e_aq_release_resource(hw, I40E_NVM_RESOURCE_ID, 0, NULL); 140 } 141 142 /** 143 * i40e_poll_sr_srctl_done_bit - Polls the GLNVM_SRCTL done bit. 144 * @hw: pointer to the HW structure. 145 * 146 * Polls the SRCTL Shadow RAM register done bit. 147 **/ 148 static i40e_status i40e_poll_sr_srctl_done_bit(struct i40e_hw *hw) 149 { 150 i40e_status ret_code = I40E_ERR_TIMEOUT; 151 u32 srctl, wait_cnt; 152 153 /* Poll the I40E_GLNVM_SRCTL until the done bit is set. */ 154 for (wait_cnt = 0; wait_cnt < I40E_SRRD_SRCTL_ATTEMPTS; wait_cnt++) { 155 srctl = rd32(hw, I40E_GLNVM_SRCTL); 156 if (srctl & I40E_GLNVM_SRCTL_DONE_MASK) { 157 ret_code = 0; 158 break; 159 } 160 udelay(5); 161 } 162 if (ret_code == I40E_ERR_TIMEOUT) 163 hw_dbg(hw, "Done bit in GLNVM_SRCTL not set"); 164 return ret_code; 165 } 166 167 /** 168 * i40e_read_nvm_word - Reads Shadow RAM 169 * @hw: pointer to the HW structure. 170 * @offset: offset of the Shadow RAM word to read (0x000000 - 0x001FFF). 171 * @data: word read from the Shadow RAM. 172 * 173 * Reads 16 bit word from the Shadow RAM using the GLNVM_SRCTL register. 174 **/ 175 i40e_status i40e_read_nvm_word(struct i40e_hw *hw, u16 offset, 176 u16 *data) 177 { 178 i40e_status ret_code = I40E_ERR_TIMEOUT; 179 u32 sr_reg; 180 181 if (offset >= hw->nvm.sr_size) { 182 hw_dbg(hw, "NVM read error: Offset beyond Shadow RAM limit.\n"); 183 ret_code = I40E_ERR_PARAM; 184 goto read_nvm_exit; 185 } 186 187 /* Poll the done bit first. */ 188 ret_code = i40e_poll_sr_srctl_done_bit(hw); 189 if (!ret_code) { 190 /* Write the address and start reading. */ 191 sr_reg = (u32)(offset << I40E_GLNVM_SRCTL_ADDR_SHIFT) | 192 (1 << I40E_GLNVM_SRCTL_START_SHIFT); 193 wr32(hw, I40E_GLNVM_SRCTL, sr_reg); 194 195 /* Poll I40E_GLNVM_SRCTL until the done bit is set. */ 196 ret_code = i40e_poll_sr_srctl_done_bit(hw); 197 if (!ret_code) { 198 sr_reg = rd32(hw, I40E_GLNVM_SRDATA); 199 *data = (u16)((sr_reg & 200 I40E_GLNVM_SRDATA_RDDATA_MASK) 201 >> I40E_GLNVM_SRDATA_RDDATA_SHIFT); 202 } 203 } 204 if (ret_code) 205 hw_dbg(hw, "NVM read error: Couldn't access Shadow RAM address: 0x%x\n", 206 offset); 207 208 read_nvm_exit: 209 return ret_code; 210 } 211 212 /** 213 * i40e_read_nvm_buffer - Reads Shadow RAM buffer. 214 * @hw: pointer to the HW structure. 215 * @offset: offset of the Shadow RAM word to read (0x000000 - 0x001FFF). 216 * @words: number of words to read (in) & 217 * number of words read before the NVM ownership timeout (out). 218 * @data: words read from the Shadow RAM. 219 * 220 * Reads 16 bit words (data buffer) from the SR using the i40e_read_nvm_srrd() 221 * method. The buffer read is preceded by the NVM ownership take 222 * and followed by the release. 223 **/ 224 i40e_status i40e_read_nvm_buffer(struct i40e_hw *hw, u16 offset, 225 u16 *words, u16 *data) 226 { 227 i40e_status ret_code = 0; 228 u16 index, word; 229 230 /* Loop thru the selected region. */ 231 for (word = 0; word < *words; word++) { 232 index = offset + word; 233 ret_code = i40e_read_nvm_word(hw, index, &data[word]); 234 if (ret_code) 235 break; 236 } 237 238 /* Update the number of words read from the Shadow RAM. */ 239 *words = word; 240 241 return ret_code; 242 } 243 244 /** 245 * i40e_calc_nvm_checksum - Calculates and returns the checksum 246 * @hw: pointer to hardware structure 247 * @checksum: pointer to the checksum 248 * 249 * This function calculate SW Checksum that covers the whole 64kB shadow RAM 250 * except the VPD and PCIe ALT Auto-load modules. The structure and size of VPD 251 * is customer specific and unknown. Therefore, this function skips all maximum 252 * possible size of VPD (1kB). 253 **/ 254 static i40e_status i40e_calc_nvm_checksum(struct i40e_hw *hw, 255 u16 *checksum) 256 { 257 i40e_status ret_code = 0; 258 u16 pcie_alt_module = 0; 259 u16 checksum_local = 0; 260 u16 vpd_module = 0; 261 u16 word = 0; 262 u32 i = 0; 263 264 /* read pointer to VPD area */ 265 ret_code = i40e_read_nvm_word(hw, I40E_SR_VPD_PTR, &vpd_module); 266 if (ret_code) { 267 ret_code = I40E_ERR_NVM_CHECKSUM; 268 goto i40e_calc_nvm_checksum_exit; 269 } 270 271 /* read pointer to PCIe Alt Auto-load module */ 272 ret_code = i40e_read_nvm_word(hw, I40E_SR_PCIE_ALT_AUTO_LOAD_PTR, 273 &pcie_alt_module); 274 if (ret_code) { 275 ret_code = I40E_ERR_NVM_CHECKSUM; 276 goto i40e_calc_nvm_checksum_exit; 277 } 278 279 /* Calculate SW checksum that covers the whole 64kB shadow RAM 280 * except the VPD and PCIe ALT Auto-load modules 281 */ 282 for (i = 0; i < hw->nvm.sr_size; i++) { 283 /* Skip Checksum word */ 284 if (i == I40E_SR_SW_CHECKSUM_WORD) 285 i++; 286 /* Skip VPD module (convert byte size to word count) */ 287 if (i == (u32)vpd_module) { 288 i += (I40E_SR_VPD_MODULE_MAX_SIZE / 2); 289 if (i >= hw->nvm.sr_size) 290 break; 291 } 292 /* Skip PCIe ALT module (convert byte size to word count) */ 293 if (i == (u32)pcie_alt_module) { 294 i += (I40E_SR_PCIE_ALT_MODULE_MAX_SIZE / 2); 295 if (i >= hw->nvm.sr_size) 296 break; 297 } 298 299 ret_code = i40e_read_nvm_word(hw, (u16)i, &word); 300 if (ret_code) { 301 ret_code = I40E_ERR_NVM_CHECKSUM; 302 goto i40e_calc_nvm_checksum_exit; 303 } 304 checksum_local += word; 305 } 306 307 *checksum = (u16)I40E_SR_SW_CHECKSUM_BASE - checksum_local; 308 309 i40e_calc_nvm_checksum_exit: 310 return ret_code; 311 } 312 313 /** 314 * i40e_validate_nvm_checksum - Validate EEPROM checksum 315 * @hw: pointer to hardware structure 316 * @checksum: calculated checksum 317 * 318 * Performs checksum calculation and validates the NVM SW checksum. If the 319 * caller does not need checksum, the value can be NULL. 320 **/ 321 i40e_status i40e_validate_nvm_checksum(struct i40e_hw *hw, 322 u16 *checksum) 323 { 324 i40e_status ret_code = 0; 325 u16 checksum_sr = 0; 326 u16 checksum_local = 0; 327 328 ret_code = i40e_acquire_nvm(hw, I40E_RESOURCE_READ); 329 if (ret_code) 330 goto i40e_validate_nvm_checksum_exit; 331 332 ret_code = i40e_calc_nvm_checksum(hw, &checksum_local); 333 if (ret_code) 334 goto i40e_validate_nvm_checksum_free; 335 336 /* Do not use i40e_read_nvm_word() because we do not want to take 337 * the synchronization semaphores twice here. 338 */ 339 i40e_read_nvm_word(hw, I40E_SR_SW_CHECKSUM_WORD, &checksum_sr); 340 341 /* Verify read checksum from EEPROM is the same as 342 * calculated checksum 343 */ 344 if (checksum_local != checksum_sr) 345 ret_code = I40E_ERR_NVM_CHECKSUM; 346 347 /* If the user cares, return the calculated checksum */ 348 if (checksum) 349 *checksum = checksum_local; 350 351 i40e_validate_nvm_checksum_free: 352 i40e_release_nvm(hw); 353 354 i40e_validate_nvm_checksum_exit: 355 return ret_code; 356 } 357