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 * Setup 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 one 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: (in) number of words to read; (out) number of words actually read 217 * @data: words read from the Shadow RAM 218 * 219 * Reads 16 bit words (data buffer) from the SR using the i40e_read_nvm_srrd() 220 * method. The buffer read is preceded by the NVM ownership take 221 * and followed by the release. 222 **/ 223 i40e_status i40e_read_nvm_buffer(struct i40e_hw *hw, u16 offset, 224 u16 *words, u16 *data) 225 { 226 i40e_status ret_code = 0; 227 u16 index, word; 228 229 /* Loop thru the selected region */ 230 for (word = 0; word < *words; word++) { 231 index = offset + word; 232 ret_code = i40e_read_nvm_word(hw, index, &data[word]); 233 if (ret_code) 234 break; 235 } 236 237 /* Update the number of words read from the Shadow RAM */ 238 *words = word; 239 240 return ret_code; 241 } 242 243 /** 244 * i40e_calc_nvm_checksum - Calculates and returns the checksum 245 * @hw: pointer to hardware structure 246 * @checksum: pointer to the checksum 247 * 248 * This function calculates SW Checksum that covers the whole 64kB shadow RAM 249 * except the VPD and PCIe ALT Auto-load modules. The structure and size of VPD 250 * is customer specific and unknown. Therefore, this function skips all maximum 251 * possible size of VPD (1kB). 252 **/ 253 static i40e_status i40e_calc_nvm_checksum(struct i40e_hw *hw, 254 u16 *checksum) 255 { 256 i40e_status ret_code = 0; 257 u16 pcie_alt_module = 0; 258 u16 checksum_local = 0; 259 u16 vpd_module = 0; 260 u16 word = 0; 261 u32 i = 0; 262 263 /* read pointer to VPD area */ 264 ret_code = i40e_read_nvm_word(hw, I40E_SR_VPD_PTR, &vpd_module); 265 if (ret_code) { 266 ret_code = I40E_ERR_NVM_CHECKSUM; 267 goto i40e_calc_nvm_checksum_exit; 268 } 269 270 /* read pointer to PCIe Alt Auto-load module */ 271 ret_code = i40e_read_nvm_word(hw, I40E_SR_PCIE_ALT_AUTO_LOAD_PTR, 272 &pcie_alt_module); 273 if (ret_code) { 274 ret_code = I40E_ERR_NVM_CHECKSUM; 275 goto i40e_calc_nvm_checksum_exit; 276 } 277 278 /* Calculate SW checksum that covers the whole 64kB shadow RAM 279 * except the VPD and PCIe ALT Auto-load modules 280 */ 281 for (i = 0; i < hw->nvm.sr_size; i++) { 282 /* Skip Checksum word */ 283 if (i == I40E_SR_SW_CHECKSUM_WORD) 284 i++; 285 /* Skip VPD module (convert byte size to word count) */ 286 if (i == (u32)vpd_module) { 287 i += (I40E_SR_VPD_MODULE_MAX_SIZE / 2); 288 if (i >= hw->nvm.sr_size) 289 break; 290 } 291 /* Skip PCIe ALT module (convert byte size to word count) */ 292 if (i == (u32)pcie_alt_module) { 293 i += (I40E_SR_PCIE_ALT_MODULE_MAX_SIZE / 2); 294 if (i >= hw->nvm.sr_size) 295 break; 296 } 297 298 ret_code = i40e_read_nvm_word(hw, (u16)i, &word); 299 if (ret_code) { 300 ret_code = I40E_ERR_NVM_CHECKSUM; 301 goto i40e_calc_nvm_checksum_exit; 302 } 303 checksum_local += word; 304 } 305 306 *checksum = (u16)I40E_SR_SW_CHECKSUM_BASE - checksum_local; 307 308 i40e_calc_nvm_checksum_exit: 309 return ret_code; 310 } 311 312 /** 313 * i40e_validate_nvm_checksum - Validate EEPROM checksum 314 * @hw: pointer to hardware structure 315 * @checksum: calculated checksum 316 * 317 * Performs checksum calculation and validates the NVM SW checksum. If the 318 * caller does not need checksum, the value can be NULL. 319 **/ 320 i40e_status i40e_validate_nvm_checksum(struct i40e_hw *hw, 321 u16 *checksum) 322 { 323 i40e_status ret_code = 0; 324 u16 checksum_sr = 0; 325 u16 checksum_local = 0; 326 327 ret_code = i40e_acquire_nvm(hw, I40E_RESOURCE_READ); 328 if (ret_code) 329 goto i40e_validate_nvm_checksum_exit; 330 331 ret_code = i40e_calc_nvm_checksum(hw, &checksum_local); 332 if (ret_code) 333 goto i40e_validate_nvm_checksum_free; 334 335 /* Do not use i40e_read_nvm_word() because we do not want to take 336 * the synchronization semaphores twice here. 337 */ 338 i40e_read_nvm_word(hw, I40E_SR_SW_CHECKSUM_WORD, &checksum_sr); 339 340 /* Verify read checksum from EEPROM is the same as 341 * calculated checksum 342 */ 343 if (checksum_local != checksum_sr) 344 ret_code = I40E_ERR_NVM_CHECKSUM; 345 346 /* If the user cares, return the calculated checksum */ 347 if (checksum) 348 *checksum = checksum_local; 349 350 i40e_validate_nvm_checksum_free: 351 i40e_release_nvm(hw); 352 353 i40e_validate_nvm_checksum_exit: 354 return ret_code; 355 } 356