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