aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDon Skidmore <donald.c.skidmore@intel.com>2014-11-29 00:22:48 -0500
committerJeff Kirsher <jeffrey.t.kirsher@intel.com>2014-12-05 12:13:07 -0500
commit735c35afed09f07c57abc9171f40202ec5f1630f (patch)
tree15f07297122613e7700de40361d856e1289ed917
parent28abba05d9d03b4f9a35621f7bbeac78352bfcf2 (diff)
ixgbe: cleanup checksum to allow error results
Currently the shared code checksum calculation function only returns a u16 and cannot return an error code. Unfortunately a variety of errors can happen that completely prevent the calculation of a checksum. So, change the function return value from a u16 to an s32 and return a negative value on error, or the positive checksum value when there is no error. Signed-off-by: Don Skidmore <donald.c.skidmore@intel.com> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
-rw-r--r--drivers/net/ethernet/intel/ixgbe/ixgbe_common.c86
-rw-r--r--drivers/net/ethernet/intel/ixgbe/ixgbe_common.h2
-rw-r--r--drivers/net/ethernet/intel/ixgbe/ixgbe_type.h2
-rw-r--r--drivers/net/ethernet/intel/ixgbe/ixgbe_x540.c59
4 files changed, 96 insertions, 53 deletions
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_common.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_common.c
index 2c77539b20db..7633ba1d4e27 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_common.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_common.c
@@ -1625,7 +1625,7 @@ static void ixgbe_release_eeprom(struct ixgbe_hw *hw)
1625 * ixgbe_calc_eeprom_checksum_generic - Calculates and returns the checksum 1625 * ixgbe_calc_eeprom_checksum_generic - Calculates and returns the checksum
1626 * @hw: pointer to hardware structure 1626 * @hw: pointer to hardware structure
1627 **/ 1627 **/
1628u16 ixgbe_calc_eeprom_checksum_generic(struct ixgbe_hw *hw) 1628s32 ixgbe_calc_eeprom_checksum_generic(struct ixgbe_hw *hw)
1629{ 1629{
1630 u16 i; 1630 u16 i;
1631 u16 j; 1631 u16 j;
@@ -1636,7 +1636,7 @@ u16 ixgbe_calc_eeprom_checksum_generic(struct ixgbe_hw *hw)
1636 1636
1637 /* Include 0x0-0x3F in the checksum */ 1637 /* Include 0x0-0x3F in the checksum */
1638 for (i = 0; i < IXGBE_EEPROM_CHECKSUM; i++) { 1638 for (i = 0; i < IXGBE_EEPROM_CHECKSUM; i++) {
1639 if (hw->eeprom.ops.read(hw, i, &word) != 0) { 1639 if (hw->eeprom.ops.read(hw, i, &word)) {
1640 hw_dbg(hw, "EEPROM read failed\n"); 1640 hw_dbg(hw, "EEPROM read failed\n");
1641 break; 1641 break;
1642 } 1642 }
@@ -1645,24 +1645,35 @@ u16 ixgbe_calc_eeprom_checksum_generic(struct ixgbe_hw *hw)
1645 1645
1646 /* Include all data from pointers except for the fw pointer */ 1646 /* Include all data from pointers except for the fw pointer */
1647 for (i = IXGBE_PCIE_ANALOG_PTR; i < IXGBE_FW_PTR; i++) { 1647 for (i = IXGBE_PCIE_ANALOG_PTR; i < IXGBE_FW_PTR; i++) {
1648 hw->eeprom.ops.read(hw, i, &pointer); 1648 if (hw->eeprom.ops.read(hw, i, &pointer)) {
1649 hw_dbg(hw, "EEPROM read failed\n");
1650 return IXGBE_ERR_EEPROM;
1651 }
1652
1653 /* If the pointer seems invalid */
1654 if (pointer == 0xFFFF || pointer == 0)
1655 continue;
1656
1657 if (hw->eeprom.ops.read(hw, pointer, &length)) {
1658 hw_dbg(hw, "EEPROM read failed\n");
1659 return IXGBE_ERR_EEPROM;
1660 }
1649 1661
1650 /* Make sure the pointer seems valid */ 1662 if (length == 0xFFFF || length == 0)
1651 if (pointer != 0xFFFF && pointer != 0) { 1663 continue;
1652 hw->eeprom.ops.read(hw, pointer, &length);
1653 1664
1654 if (length != 0xFFFF && length != 0) { 1665 for (j = pointer + 1; j <= pointer + length; j++) {
1655 for (j = pointer+1; j <= pointer+length; j++) { 1666 if (hw->eeprom.ops.read(hw, j, &word)) {
1656 hw->eeprom.ops.read(hw, j, &word); 1667 hw_dbg(hw, "EEPROM read failed\n");
1657 checksum += word; 1668 return IXGBE_ERR_EEPROM;
1658 }
1659 } 1669 }
1670 checksum += word;
1660 } 1671 }
1661 } 1672 }
1662 1673
1663 checksum = (u16)IXGBE_EEPROM_SUM - checksum; 1674 checksum = (u16)IXGBE_EEPROM_SUM - checksum;
1664 1675
1665 return checksum; 1676 return (s32)checksum;
1666} 1677}
1667 1678
1668/** 1679/**
@@ -1686,26 +1697,33 @@ s32 ixgbe_validate_eeprom_checksum_generic(struct ixgbe_hw *hw,
1686 * EEPROM read fails 1697 * EEPROM read fails
1687 */ 1698 */
1688 status = hw->eeprom.ops.read(hw, 0, &checksum); 1699 status = hw->eeprom.ops.read(hw, 0, &checksum);
1700 if (status) {
1701 hw_dbg(hw, "EEPROM read failed\n");
1702 return status;
1703 }
1689 1704
1690 if (status == 0) { 1705 status = hw->eeprom.ops.calc_checksum(hw);
1691 checksum = hw->eeprom.ops.calc_checksum(hw); 1706 if (status < 0)
1707 return status;
1692 1708
1693 hw->eeprom.ops.read(hw, IXGBE_EEPROM_CHECKSUM, &read_checksum); 1709 checksum = (u16)(status & 0xffff);
1694 1710
1695 /* 1711 status = hw->eeprom.ops.read(hw, IXGBE_EEPROM_CHECKSUM, &read_checksum);
1696 * Verify read checksum from EEPROM is the same as 1712 if (status) {
1697 * calculated checksum
1698 */
1699 if (read_checksum != checksum)
1700 status = IXGBE_ERR_EEPROM_CHECKSUM;
1701
1702 /* If the user cares, return the calculated checksum */
1703 if (checksum_val)
1704 *checksum_val = checksum;
1705 } else {
1706 hw_dbg(hw, "EEPROM read failed\n"); 1713 hw_dbg(hw, "EEPROM read failed\n");
1714 return status;
1707 } 1715 }
1708 1716
1717 /* Verify read checksum from EEPROM is the same as
1718 * calculated checksum
1719 */
1720 if (read_checksum != checksum)
1721 status = IXGBE_ERR_EEPROM_CHECKSUM;
1722
1723 /* If the user cares, return the calculated checksum */
1724 if (checksum_val)
1725 *checksum_val = checksum;
1726
1709 return status; 1727 return status;
1710} 1728}
1711 1729
@@ -1724,15 +1742,19 @@ s32 ixgbe_update_eeprom_checksum_generic(struct ixgbe_hw *hw)
1724 * EEPROM read fails 1742 * EEPROM read fails
1725 */ 1743 */
1726 status = hw->eeprom.ops.read(hw, 0, &checksum); 1744 status = hw->eeprom.ops.read(hw, 0, &checksum);
1727 1745 if (status) {
1728 if (status == 0) {
1729 checksum = hw->eeprom.ops.calc_checksum(hw);
1730 status = hw->eeprom.ops.write(hw, IXGBE_EEPROM_CHECKSUM,
1731 checksum);
1732 } else {
1733 hw_dbg(hw, "EEPROM read failed\n"); 1746 hw_dbg(hw, "EEPROM read failed\n");
1747 return status;
1734 } 1748 }
1735 1749
1750 status = hw->eeprom.ops.calc_checksum(hw);
1751 if (status < 0)
1752 return status;
1753
1754 checksum = (u16)(status & 0xffff);
1755
1756 status = hw->eeprom.ops.write(hw, IXGBE_EEPROM_CHECKSUM, checksum);
1757
1736 return status; 1758 return status;
1737} 1759}
1738 1760
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_common.h b/drivers/net/ethernet/intel/ixgbe/ixgbe_common.h
index 62dc8c5ae3db..fdf42c1be20d 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_common.h
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_common.h
@@ -64,7 +64,7 @@ s32 ixgbe_read_eeprom_bit_bang_generic(struct ixgbe_hw *hw, u16 offset,
64 u16 *data); 64 u16 *data);
65s32 ixgbe_read_eeprom_buffer_bit_bang_generic(struct ixgbe_hw *hw, u16 offset, 65s32 ixgbe_read_eeprom_buffer_bit_bang_generic(struct ixgbe_hw *hw, u16 offset,
66 u16 words, u16 *data); 66 u16 words, u16 *data);
67u16 ixgbe_calc_eeprom_checksum_generic(struct ixgbe_hw *hw); 67s32 ixgbe_calc_eeprom_checksum_generic(struct ixgbe_hw *hw);
68s32 ixgbe_validate_eeprom_checksum_generic(struct ixgbe_hw *hw, 68s32 ixgbe_validate_eeprom_checksum_generic(struct ixgbe_hw *hw,
69 u16 *checksum_val); 69 u16 *checksum_val);
70s32 ixgbe_update_eeprom_checksum_generic(struct ixgbe_hw *hw); 70s32 ixgbe_update_eeprom_checksum_generic(struct ixgbe_hw *hw);
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_type.h b/drivers/net/ethernet/intel/ixgbe/ixgbe_type.h
index 14b43b9f49db..20673b314f4a 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_type.h
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_type.h
@@ -2871,7 +2871,7 @@ struct ixgbe_eeprom_operations {
2871 s32 (*write_buffer)(struct ixgbe_hw *, u16, u16, u16 *); 2871 s32 (*write_buffer)(struct ixgbe_hw *, u16, u16, u16 *);
2872 s32 (*validate_checksum)(struct ixgbe_hw *, u16 *); 2872 s32 (*validate_checksum)(struct ixgbe_hw *, u16 *);
2873 s32 (*update_checksum)(struct ixgbe_hw *); 2873 s32 (*update_checksum)(struct ixgbe_hw *);
2874 u16 (*calc_checksum)(struct ixgbe_hw *); 2874 s32 (*calc_checksum)(struct ixgbe_hw *);
2875}; 2875};
2876 2876
2877struct ixgbe_mac_operations { 2877struct ixgbe_mac_operations {
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_x540.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_x540.c
index d88f75fbd832..4b0b1cc77eb4 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_x540.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_x540.c
@@ -316,7 +316,7 @@ static s32 ixgbe_write_eewr_buffer_X540(struct ixgbe_hw *hw,
316 * 316 *
317 * @hw: pointer to hardware structure 317 * @hw: pointer to hardware structure
318 **/ 318 **/
319static u16 ixgbe_calc_eeprom_checksum_X540(struct ixgbe_hw *hw) 319static s32 ixgbe_calc_eeprom_checksum_X540(struct ixgbe_hw *hw)
320{ 320{
321 u16 i; 321 u16 i;
322 u16 j; 322 u16 j;
@@ -324,6 +324,8 @@ static u16 ixgbe_calc_eeprom_checksum_X540(struct ixgbe_hw *hw)
324 u16 length = 0; 324 u16 length = 0;
325 u16 pointer = 0; 325 u16 pointer = 0;
326 u16 word = 0; 326 u16 word = 0;
327 u16 checksum_last_word = IXGBE_EEPROM_CHECKSUM;
328 u16 ptr_start = IXGBE_PCIE_ANALOG_PTR;
327 329
328 /* 330 /*
329 * Do not use hw->eeprom.ops.read because we do not want to take 331 * Do not use hw->eeprom.ops.read because we do not want to take
@@ -332,10 +334,10 @@ static u16 ixgbe_calc_eeprom_checksum_X540(struct ixgbe_hw *hw)
332 */ 334 */
333 335
334 /* Include 0x0-0x3F in the checksum */ 336 /* Include 0x0-0x3F in the checksum */
335 for (i = 0; i < IXGBE_EEPROM_CHECKSUM; i++) { 337 for (i = 0; i < checksum_last_word; i++) {
336 if (ixgbe_read_eerd_generic(hw, i, &word) != 0) { 338 if (ixgbe_read_eerd_generic(hw, i, &word)) {
337 hw_dbg(hw, "EEPROM read failed\n"); 339 hw_dbg(hw, "EEPROM read failed\n");
338 break; 340 return IXGBE_ERR_EEPROM;
339 } 341 }
340 checksum += word; 342 checksum += word;
341 } 343 }
@@ -344,11 +346,11 @@ static u16 ixgbe_calc_eeprom_checksum_X540(struct ixgbe_hw *hw)
344 * Include all data from pointers 0x3, 0x6-0xE. This excludes the 346 * Include all data from pointers 0x3, 0x6-0xE. This excludes the
345 * FW, PHY module, and PCIe Expansion/Option ROM pointers. 347 * FW, PHY module, and PCIe Expansion/Option ROM pointers.
346 */ 348 */
347 for (i = IXGBE_PCIE_ANALOG_PTR; i < IXGBE_FW_PTR; i++) { 349 for (i = ptr_start; i < IXGBE_FW_PTR; i++) {
348 if (i == IXGBE_PHY_PTR || i == IXGBE_OPTION_ROM_PTR) 350 if (i == IXGBE_PHY_PTR || i == IXGBE_OPTION_ROM_PTR)
349 continue; 351 continue;
350 352
351 if (ixgbe_read_eerd_generic(hw, i, &pointer) != 0) { 353 if (ixgbe_read_eerd_generic(hw, i, &pointer)) {
352 hw_dbg(hw, "EEPROM read failed\n"); 354 hw_dbg(hw, "EEPROM read failed\n");
353 break; 355 break;
354 } 356 }
@@ -358,8 +360,9 @@ static u16 ixgbe_calc_eeprom_checksum_X540(struct ixgbe_hw *hw)
358 pointer >= hw->eeprom.word_size) 360 pointer >= hw->eeprom.word_size)
359 continue; 361 continue;
360 362
361 if (ixgbe_read_eerd_generic(hw, pointer, &length) != 0) { 363 if (ixgbe_read_eerd_generic(hw, pointer, &length)) {
362 hw_dbg(hw, "EEPROM read failed\n"); 364 hw_dbg(hw, "EEPROM read failed\n");
365 return IXGBE_ERR_EEPROM;
363 break; 366 break;
364 } 367 }
365 368
@@ -368,10 +371,10 @@ static u16 ixgbe_calc_eeprom_checksum_X540(struct ixgbe_hw *hw)
368 (pointer + length) >= hw->eeprom.word_size) 371 (pointer + length) >= hw->eeprom.word_size)
369 continue; 372 continue;
370 373
371 for (j = pointer+1; j <= pointer+length; j++) { 374 for (j = pointer + 1; j <= pointer + length; j++) {
372 if (ixgbe_read_eerd_generic(hw, j, &word) != 0) { 375 if (ixgbe_read_eerd_generic(hw, j, &word)) {
373 hw_dbg(hw, "EEPROM read failed\n"); 376 hw_dbg(hw, "EEPROM read failed\n");
374 break; 377 return IXGBE_ERR_EEPROM;
375 } 378 }
376 checksum += word; 379 checksum += word;
377 } 380 }
@@ -379,7 +382,7 @@ static u16 ixgbe_calc_eeprom_checksum_X540(struct ixgbe_hw *hw)
379 382
380 checksum = (u16)IXGBE_EEPROM_SUM - checksum; 383 checksum = (u16)IXGBE_EEPROM_SUM - checksum;
381 384
382 return checksum; 385 return (s32)checksum;
383} 386}
384 387
385/** 388/**
@@ -410,23 +413,34 @@ static s32 ixgbe_validate_eeprom_checksum_X540(struct ixgbe_hw *hw,
410 if (hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM)) 413 if (hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM))
411 return IXGBE_ERR_SWFW_SYNC; 414 return IXGBE_ERR_SWFW_SYNC;
412 415
413 checksum = hw->eeprom.ops.calc_checksum(hw); 416 status = hw->eeprom.ops.calc_checksum(hw);
417 if (status < 0)
418 goto out;
419
420 checksum = (u16)(status & 0xffff);
414 421
415 /* Do not use hw->eeprom.ops.read because we do not want to take 422 /* Do not use hw->eeprom.ops.read because we do not want to take
416 * the synchronization semaphores twice here. 423 * the synchronization semaphores twice here.
417 */ 424 */
418 status = ixgbe_read_eerd_generic(hw, IXGBE_EEPROM_CHECKSUM, 425 status = ixgbe_read_eerd_generic(hw, IXGBE_EEPROM_CHECKSUM,
419 &read_checksum); 426 &read_checksum);
427 if (status)
428 goto out;
420 429
421 hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_EEP_SM); 430 /* Verify read checksum from EEPROM is the same as
431 * calculated checksum
432 */
433 if (read_checksum != checksum) {
434 hw_dbg(hw, "Invalid EEPROM checksum");
435 status = IXGBE_ERR_EEPROM_CHECKSUM;
436 }
422 437
423 /* If the user cares, return the calculated checksum */ 438 /* If the user cares, return the calculated checksum */
424 if (checksum_val) 439 if (checksum_val)
425 *checksum_val = checksum; 440 *checksum_val = checksum;
426 441
427 /* Verify read and calculated checksums are the same */ 442out:
428 if (read_checksum != checksum) 443 hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_EEP_SM);
429 return IXGBE_ERR_EEPROM_CHECKSUM;
430 444
431 return status; 445 return status;
432} 446}
@@ -457,15 +471,22 @@ static s32 ixgbe_update_eeprom_checksum_X540(struct ixgbe_hw *hw)
457 if (hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM)) 471 if (hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM))
458 return IXGBE_ERR_SWFW_SYNC; 472 return IXGBE_ERR_SWFW_SYNC;
459 473
460 checksum = hw->eeprom.ops.calc_checksum(hw); 474 status = hw->eeprom.ops.calc_checksum(hw);
475 if (status < 0)
476 goto out;
477
478 checksum = (u16)(status & 0xffff);
461 479
462 /* Do not use hw->eeprom.ops.write because we do not want to 480 /* Do not use hw->eeprom.ops.write because we do not want to
463 * take the synchronization semaphores twice here. 481 * take the synchronization semaphores twice here.
464 */ 482 */
465 status = ixgbe_write_eewr_generic(hw, IXGBE_EEPROM_CHECKSUM, checksum); 483 status = ixgbe_write_eewr_generic(hw, IXGBE_EEPROM_CHECKSUM, checksum);
466 if (!status) 484 if (status)
467 status = ixgbe_update_flash_X540(hw); 485 goto out;
486
487 status = ixgbe_update_flash_X540(hw);
468 488
489out:
469 hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_EEP_SM); 490 hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_EEP_SM);
470 return status; 491 return status;
471} 492}