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