1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright(c) 2015-2020 Beijing WangXun Technology Co., Ltd. 3 * Copyright(c) 2010-2017 Intel Corporation 4 */ 5 6 #include "txgbe_hw.h" 7 #include "txgbe_mng.h" 8 #include "txgbe_eeprom.h" 9 10 /** 11 * txgbe_init_eeprom_params - Initialize EEPROM params 12 * @hw: pointer to hardware structure 13 * 14 * Initializes the EEPROM parameters txgbe_rom_info within the 15 * txgbe_hw struct in order to set up EEPROM access. 16 **/ 17 s32 txgbe_init_eeprom_params(struct txgbe_hw *hw) 18 { 19 struct txgbe_rom_info *eeprom = &hw->rom; 20 u32 eec; 21 u16 eeprom_size; 22 int err = 0; 23 24 DEBUGFUNC("txgbe_init_eeprom_params"); 25 26 if (eeprom->type != txgbe_eeprom_unknown) 27 return 0; 28 29 eeprom->type = txgbe_eeprom_none; 30 /* Set default semaphore delay to 10ms which is a well 31 * tested value 32 */ 33 eeprom->semaphore_delay = 10; /*ms*/ 34 /* Clear EEPROM page size, it will be initialized as needed */ 35 eeprom->word_page_size = 0; 36 37 /* 38 * Check for EEPROM present first. 39 * If not present leave as none 40 */ 41 eec = rd32(hw, TXGBE_SPISTAT); 42 if (!(eec & TXGBE_SPISTAT_BPFLASH)) { 43 eeprom->type = txgbe_eeprom_flash; 44 45 /* 46 * SPI EEPROM is assumed here. This code would need to 47 * change if a future EEPROM is not SPI. 48 */ 49 eeprom_size = 4096; 50 eeprom->word_size = eeprom_size >> 1; 51 } 52 53 eeprom->address_bits = 16; 54 55 err = eeprom->read32(hw, TXGBE_SW_REGION_PTR << 1, &eeprom->sw_addr); 56 if (err) { 57 DEBUGOUT("EEPROM read failed.\n"); 58 return err; 59 } 60 61 DEBUGOUT("eeprom params: type = %d, size = %d, address bits: " 62 "%d %d\n", eeprom->type, eeprom->word_size, 63 eeprom->address_bits, eeprom->sw_addr); 64 65 return 0; 66 } 67 68 /** 69 * txgbe_get_eeprom_semaphore - Get hardware semaphore 70 * @hw: pointer to hardware structure 71 * 72 * Sets the hardware semaphores so EEPROM access can occur for bit-bang method 73 **/ 74 s32 txgbe_get_eeprom_semaphore(struct txgbe_hw *hw) 75 { 76 s32 status = TXGBE_ERR_EEPROM; 77 u32 timeout = 2000; 78 u32 i; 79 u32 swsm; 80 81 DEBUGFUNC("txgbe_get_eeprom_semaphore"); 82 83 84 /* Get SMBI software semaphore between device drivers first */ 85 for (i = 0; i < timeout; i++) { 86 /* 87 * If the SMBI bit is 0 when we read it, then the bit will be 88 * set and we have the semaphore 89 */ 90 swsm = rd32(hw, TXGBE_SWSEM); 91 if (!(swsm & TXGBE_SWSEM_PF)) { 92 status = 0; 93 break; 94 } 95 usec_delay(50); 96 } 97 98 if (i == timeout) { 99 DEBUGOUT("Driver can't access the eeprom - SMBI Semaphore " 100 "not granted.\n"); 101 /* 102 * this release is particularly important because our attempts 103 * above to get the semaphore may have succeeded, and if there 104 * was a timeout, we should unconditionally clear the semaphore 105 * bits to free the driver to make progress 106 */ 107 txgbe_release_eeprom_semaphore(hw); 108 109 usec_delay(50); 110 /* 111 * one last try 112 * If the SMBI bit is 0 when we read it, then the bit will be 113 * set and we have the semaphore 114 */ 115 swsm = rd32(hw, TXGBE_SWSEM); 116 if (!(swsm & TXGBE_SWSEM_PF)) 117 status = 0; 118 } 119 120 /* Now get the semaphore between SW/FW through the SWESMBI bit */ 121 if (status == 0) { 122 for (i = 0; i < timeout; i++) { 123 /* Set the SW EEPROM semaphore bit to request access */ 124 wr32m(hw, TXGBE_MNGSWSYNC, 125 TXGBE_MNGSWSYNC_REQ, TXGBE_MNGSWSYNC_REQ); 126 127 /* 128 * If we set the bit successfully then we got the 129 * semaphore. 130 */ 131 swsm = rd32(hw, TXGBE_MNGSWSYNC); 132 if (swsm & TXGBE_MNGSWSYNC_REQ) 133 break; 134 135 usec_delay(50); 136 } 137 138 /* 139 * Release semaphores and return error if SW EEPROM semaphore 140 * was not granted because we don't have access to the EEPROM 141 */ 142 if (i >= timeout) { 143 DEBUGOUT("SWESMBI Software EEPROM semaphore not granted.\n"); 144 txgbe_release_eeprom_semaphore(hw); 145 status = TXGBE_ERR_EEPROM; 146 } 147 } else { 148 DEBUGOUT("Software semaphore SMBI between device drivers " 149 "not granted.\n"); 150 } 151 152 return status; 153 } 154 155 /** 156 * txgbe_release_eeprom_semaphore - Release hardware semaphore 157 * @hw: pointer to hardware structure 158 * 159 * This function clears hardware semaphore bits. 160 **/ 161 void txgbe_release_eeprom_semaphore(struct txgbe_hw *hw) 162 { 163 DEBUGFUNC("txgbe_release_eeprom_semaphore"); 164 165 wr32m(hw, TXGBE_MNGSWSYNC, TXGBE_MNGSWSYNC_REQ, 0); 166 wr32m(hw, TXGBE_SWSEM, TXGBE_SWSEM_PF, 0); 167 txgbe_flush(hw); 168 } 169 170 /** 171 * txgbe_ee_read - Read EEPROM word using a host interface cmd 172 * @hw: pointer to hardware structure 173 * @offset: offset of word in the EEPROM to read 174 * @data: word read from the EEPROM 175 * 176 * Reads a 16 bit word from the EEPROM using the hostif. 177 **/ 178 s32 txgbe_ee_read16(struct txgbe_hw *hw, u32 offset, 179 u16 *data) 180 { 181 const u32 mask = TXGBE_MNGSEM_SWMBX | TXGBE_MNGSEM_SWFLASH; 182 u32 addr = (offset << 1); 183 int err; 184 185 err = hw->mac.acquire_swfw_sync(hw, mask); 186 if (err) 187 return err; 188 189 err = txgbe_hic_sr_read(hw, addr, (u8 *)data, 2); 190 191 hw->mac.release_swfw_sync(hw, mask); 192 193 return err; 194 } 195 196 /** 197 * txgbe_ee_readw_buffer- Read EEPROM word(s) using hostif 198 * @hw: pointer to hardware structure 199 * @offset: offset of word in the EEPROM to read 200 * @words: number of words 201 * @data: word(s) read from the EEPROM 202 * 203 * Reads a 16 bit word(s) from the EEPROM using the hostif. 204 **/ 205 s32 txgbe_ee_readw_buffer(struct txgbe_hw *hw, 206 u32 offset, u32 words, void *data) 207 { 208 const u32 mask = TXGBE_MNGSEM_SWMBX | TXGBE_MNGSEM_SWFLASH; 209 u32 addr = (offset << 1); 210 u32 len = (words << 1); 211 u8 *buf = (u8 *)data; 212 int err; 213 214 err = hw->mac.acquire_swfw_sync(hw, mask); 215 if (err) 216 return err; 217 218 while (len) { 219 u32 seg = (len <= TXGBE_PMMBX_DATA_SIZE 220 ? len : TXGBE_PMMBX_DATA_SIZE); 221 222 err = txgbe_hic_sr_read(hw, addr, buf, seg); 223 if (err) 224 break; 225 226 len -= seg; 227 addr += seg; 228 buf += seg; 229 } 230 231 hw->mac.release_swfw_sync(hw, mask); 232 return err; 233 } 234 235 236 s32 txgbe_ee_readw_sw(struct txgbe_hw *hw, u32 offset, 237 u16 *data) 238 { 239 const u32 mask = TXGBE_MNGSEM_SWMBX | TXGBE_MNGSEM_SWFLASH; 240 u32 addr = hw->rom.sw_addr + (offset << 1); 241 int err; 242 243 err = hw->mac.acquire_swfw_sync(hw, mask); 244 if (err) 245 return err; 246 247 err = txgbe_hic_sr_read(hw, addr, (u8 *)data, 2); 248 249 hw->mac.release_swfw_sync(hw, mask); 250 251 return err; 252 } 253 254 /** 255 * txgbe_ee_read32 - Read EEPROM word using a host interface cmd 256 * @hw: pointer to hardware structure 257 * @offset: offset of word in the EEPROM to read 258 * @data: word read from the EEPROM 259 * 260 * Reads a 32 bit word from the EEPROM using the hostif. 261 **/ 262 s32 txgbe_ee_read32(struct txgbe_hw *hw, u32 addr, u32 *data) 263 { 264 const u32 mask = TXGBE_MNGSEM_SWMBX | TXGBE_MNGSEM_SWFLASH; 265 int err; 266 267 err = hw->mac.acquire_swfw_sync(hw, mask); 268 if (err) 269 return err; 270 271 err = txgbe_hic_sr_read(hw, addr, (u8 *)data, 4); 272 273 hw->mac.release_swfw_sync(hw, mask); 274 275 return err; 276 } 277 278 /** 279 * txgbe_ee_write - Write EEPROM word using hostif 280 * @hw: pointer to hardware structure 281 * @offset: offset of word in the EEPROM to write 282 * @data: word write to the EEPROM 283 * 284 * Write a 16 bit word to the EEPROM using the hostif. 285 **/ 286 s32 txgbe_ee_write16(struct txgbe_hw *hw, u32 offset, 287 u16 data) 288 { 289 const u32 mask = TXGBE_MNGSEM_SWMBX | TXGBE_MNGSEM_SWFLASH; 290 u32 addr = (offset << 1); 291 int err; 292 293 DEBUGFUNC("\n"); 294 295 err = hw->mac.acquire_swfw_sync(hw, mask); 296 if (err) 297 return err; 298 299 err = txgbe_hic_sr_write(hw, addr, (u8 *)&data, 2); 300 301 hw->mac.release_swfw_sync(hw, mask); 302 303 return err; 304 } 305 306 /** 307 * txgbe_ee_writew_buffer - Write EEPROM word(s) using hostif 308 * @hw: pointer to hardware structure 309 * @offset: offset of word in the EEPROM to write 310 * @words: number of words 311 * @data: word(s) write to the EEPROM 312 * 313 * Write a 16 bit word(s) to the EEPROM using the hostif. 314 **/ 315 s32 txgbe_ee_writew_buffer(struct txgbe_hw *hw, 316 u32 offset, u32 words, void *data) 317 { 318 const u32 mask = TXGBE_MNGSEM_SWMBX | TXGBE_MNGSEM_SWFLASH; 319 u32 addr = (offset << 1); 320 u32 len = (words << 1); 321 u8 *buf = (u8 *)data; 322 int err; 323 324 err = hw->mac.acquire_swfw_sync(hw, mask); 325 if (err) 326 return err; 327 328 while (len) { 329 u32 seg = (len <= TXGBE_PMMBX_DATA_SIZE 330 ? len : TXGBE_PMMBX_DATA_SIZE); 331 332 err = txgbe_hic_sr_write(hw, addr, buf, seg); 333 if (err) 334 break; 335 336 len -= seg; 337 buf += seg; 338 } 339 340 hw->mac.release_swfw_sync(hw, mask); 341 return err; 342 } 343 344 s32 txgbe_ee_writew_sw(struct txgbe_hw *hw, u32 offset, 345 u16 data) 346 { 347 const u32 mask = TXGBE_MNGSEM_SWMBX | TXGBE_MNGSEM_SWFLASH; 348 u32 addr = hw->rom.sw_addr + (offset << 1); 349 int err; 350 351 DEBUGFUNC("\n"); 352 353 err = hw->mac.acquire_swfw_sync(hw, mask); 354 if (err) 355 return err; 356 357 err = txgbe_hic_sr_write(hw, addr, (u8 *)&data, 2); 358 359 hw->mac.release_swfw_sync(hw, mask); 360 361 return err; 362 } 363 364 /** 365 * txgbe_ee_write32 - Read EEPROM word using a host interface cmd 366 * @hw: pointer to hardware structure 367 * @offset: offset of word in the EEPROM to read 368 * @data: word read from the EEPROM 369 * 370 * Reads a 32 bit word from the EEPROM using the hostif. 371 **/ 372 s32 txgbe_ee_write32(struct txgbe_hw *hw, u32 addr, u32 data) 373 { 374 const u32 mask = TXGBE_MNGSEM_SWMBX | TXGBE_MNGSEM_SWFLASH; 375 int err; 376 377 err = hw->mac.acquire_swfw_sync(hw, mask); 378 if (err) 379 return err; 380 381 err = txgbe_hic_sr_write(hw, addr, (u8 *)&data, 4); 382 383 hw->mac.release_swfw_sync(hw, mask); 384 385 return err; 386 } 387 388 /** 389 * txgbe_calc_eeprom_checksum - Calculates and returns the checksum 390 * @hw: pointer to hardware structure 391 * 392 * Returns a negative error code on error, or the 16-bit checksum 393 **/ 394 #define BUFF_SIZE 64 395 s32 txgbe_calc_eeprom_checksum(struct txgbe_hw *hw) 396 { 397 u16 checksum = 0, read_checksum = 0; 398 int i, j, seg; 399 int err; 400 u16 buffer[BUFF_SIZE]; 401 402 DEBUGFUNC("txgbe_calc_eeprom_checksum"); 403 404 err = hw->rom.readw_sw(hw, TXGBE_EEPROM_CHECKSUM, &read_checksum); 405 if (err) { 406 DEBUGOUT("EEPROM read failed\n"); 407 return err; 408 } 409 410 for (i = 0; i < TXGBE_EE_CSUM_MAX; i += seg) { 411 seg = (i + BUFF_SIZE < TXGBE_EE_CSUM_MAX 412 ? BUFF_SIZE : TXGBE_EE_CSUM_MAX - i); 413 err = hw->rom.readw_buffer(hw, i, seg, buffer); 414 if (err) 415 return err; 416 for (j = 0; j < seg; j++) 417 checksum += buffer[j]; 418 } 419 420 checksum = (u16)TXGBE_EEPROM_SUM - checksum + read_checksum; 421 422 return (s32)checksum; 423 } 424 425 /** 426 * txgbe_validate_eeprom_checksum - Validate EEPROM checksum 427 * @hw: pointer to hardware structure 428 * @checksum_val: calculated checksum 429 * 430 * Performs checksum calculation and validates the EEPROM checksum. If the 431 * caller does not need checksum_val, the value can be NULL. 432 **/ 433 s32 txgbe_validate_eeprom_checksum(struct txgbe_hw *hw, 434 u16 *checksum_val) 435 { 436 u16 checksum; 437 u16 read_checksum = 0; 438 int err; 439 440 DEBUGFUNC("txgbe_validate_eeprom_checksum"); 441 442 /* Read the first word from the EEPROM. If this times out or fails, do 443 * not continue or we could be in for a very long wait while every 444 * EEPROM read fails 445 */ 446 err = hw->rom.read16(hw, 0, &checksum); 447 if (err) { 448 DEBUGOUT("EEPROM read failed\n"); 449 return err; 450 } 451 452 err = hw->rom.calc_checksum(hw); 453 if (err < 0) 454 return err; 455 456 checksum = (u16)(err & 0xffff); 457 458 err = hw->rom.readw_sw(hw, TXGBE_EEPROM_CHECKSUM, &read_checksum); 459 if (err) { 460 DEBUGOUT("EEPROM read failed\n"); 461 return err; 462 } 463 464 /* Verify read checksum from EEPROM is the same as 465 * calculated checksum 466 */ 467 if (read_checksum != checksum) { 468 err = TXGBE_ERR_EEPROM_CHECKSUM; 469 DEBUGOUT("EEPROM checksum error\n"); 470 } 471 472 /* If the user cares, return the calculated checksum */ 473 if (checksum_val) 474 *checksum_val = checksum; 475 476 return err; 477 } 478 479 /** 480 * txgbe_update_eeprom_checksum - Updates the EEPROM checksum 481 * @hw: pointer to hardware structure 482 **/ 483 s32 txgbe_update_eeprom_checksum(struct txgbe_hw *hw) 484 { 485 s32 status; 486 u16 checksum; 487 488 DEBUGFUNC("txgbe_update_eeprom_checksum"); 489 490 /* Read the first word from the EEPROM. If this times out or fails, do 491 * not continue or we could be in for a very long wait while every 492 * EEPROM read fails 493 */ 494 status = hw->rom.read16(hw, 0, &checksum); 495 if (status) { 496 DEBUGOUT("EEPROM read failed\n"); 497 return status; 498 } 499 500 status = hw->rom.calc_checksum(hw); 501 if (status < 0) 502 return status; 503 504 checksum = (u16)(status & 0xffff); 505 506 status = hw->rom.writew_sw(hw, TXGBE_EEPROM_CHECKSUM, checksum); 507 508 return status; 509 } 510 511