diff options
| -rw-r--r-- | drivers/net/bnx2.c | 49 |
1 files changed, 21 insertions, 28 deletions
diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c index cf4322d01823..4bfc80812926 100644 --- a/drivers/net/bnx2.c +++ b/drivers/net/bnx2.c | |||
| @@ -7730,24 +7730,27 @@ bnx2_read_vpd_fw_ver(struct bnx2 *bp) | |||
| 7730 | u8 *v0_str = NULL; | 7730 | u8 *v0_str = NULL; |
| 7731 | bool mn_match = false; | 7731 | bool mn_match = false; |
| 7732 | 7732 | ||
| 7733 | #define BNX2_VPD_NVRAM_OFFSET 0x300 | ||
| 7734 | #define BNX2_VPD_LEN 128 | ||
| 7733 | #define BNX2_MAX_VER_SLEN 30 | 7735 | #define BNX2_MAX_VER_SLEN 30 |
| 7734 | 7736 | ||
| 7735 | data = kmalloc(256, GFP_KERNEL); | 7737 | data = kmalloc(256, GFP_KERNEL); |
| 7736 | if (!data) | 7738 | if (!data) |
| 7737 | return; | 7739 | return; |
| 7738 | 7740 | ||
| 7739 | rc = bnx2_nvram_read(bp, 0x300, data + 128, 128); | 7741 | rc = bnx2_nvram_read(bp, BNX2_VPD_NVRAM_OFFSET, data + BNX2_VPD_LEN, |
| 7742 | BNX2_VPD_LEN); | ||
| 7740 | if (rc) | 7743 | if (rc) |
| 7741 | goto vpd_done; | 7744 | goto vpd_done; |
| 7742 | 7745 | ||
| 7743 | for (i = 0; i < 128; i += 4) { | 7746 | for (i = 0; i < BNX2_VPD_LEN; i += 4) { |
| 7744 | data[i] = data[i + 131]; | 7747 | data[i] = data[i + BNX2_VPD_LEN + 3]; |
| 7745 | data[i + 1] = data[i + 130]; | 7748 | data[i + 1] = data[i + BNX2_VPD_LEN + 2]; |
| 7746 | data[i + 2] = data[i + 129]; | 7749 | data[i + 2] = data[i + BNX2_VPD_LEN + 1]; |
| 7747 | data[i + 3] = data[i + 128]; | 7750 | data[i + 3] = data[i + BNX2_VPD_LEN]; |
| 7748 | } | 7751 | } |
| 7749 | 7752 | ||
| 7750 | for (i = 0; i < 128; ) { | 7753 | for (i = 0; i <= BNX2_VPD_LEN - 3; ) { |
| 7751 | unsigned char val = data[i]; | 7754 | unsigned char val = data[i]; |
| 7752 | unsigned int block_end; | 7755 | unsigned int block_end; |
| 7753 | 7756 | ||
| @@ -7762,39 +7765,29 @@ bnx2_read_vpd_fw_ver(struct bnx2 *bp) | |||
| 7762 | block_end = (i + 3 + (data[i + 1] + (data[i + 2] << 8))); | 7765 | block_end = (i + 3 + (data[i + 1] + (data[i + 2] << 8))); |
| 7763 | i += 3; | 7766 | i += 3; |
| 7764 | 7767 | ||
| 7765 | if (block_end > 128) | 7768 | if (block_end > BNX2_VPD_LEN) |
| 7766 | goto vpd_done; | 7769 | goto vpd_done; |
| 7767 | 7770 | ||
| 7768 | while (i < (block_end - 2)) { | 7771 | while (i < (block_end - 2)) { |
| 7769 | if (data[i] == 'M' && data[i + 1] == 'N') { | 7772 | int len = data[i + 2]; |
| 7770 | int mn_len = data[i + 2]; | ||
| 7771 | 7773 | ||
| 7772 | if (mn_len != 4) | 7774 | if (i + 3 + len > block_end) |
| 7773 | goto vpd_done; | 7775 | goto vpd_done; |
| 7774 | 7776 | ||
| 7775 | i += 3; | 7777 | if (data[i] == 'M' && data[i + 1] == 'N') { |
| 7776 | if (memcmp(&data[i], "1028", 4)) | 7778 | if (len != 4 || |
| 7779 | memcmp(&data[i + 3], "1028", 4)) | ||
| 7777 | goto vpd_done; | 7780 | goto vpd_done; |
| 7778 | mn_match = true; | 7781 | mn_match = true; |
| 7779 | i += 4; | ||
| 7780 | 7782 | ||
| 7781 | } else if (data[i] == 'V' && data[i + 1] == '0') { | 7783 | } else if (data[i] == 'V' && data[i + 1] == '0') { |
| 7782 | v0_len = data[i + 2]; | 7784 | if (len > BNX2_MAX_VER_SLEN) |
| 7783 | |||
| 7784 | i += 3; | ||
| 7785 | if (v0_len > BNX2_MAX_VER_SLEN || | ||
| 7786 | (v0_len + i) > 128) | ||
| 7787 | goto vpd_done; | 7785 | goto vpd_done; |
| 7788 | 7786 | ||
| 7789 | if (v0_len > BNX2_MAX_VER_SLEN) | 7787 | v0_len = len; |
| 7790 | v0_len = BNX2_MAX_VER_SLEN; | 7788 | v0_str = &data[i + 3]; |
| 7791 | |||
| 7792 | v0_str = &data[i]; | ||
| 7793 | i += data[i + 2]; | ||
| 7794 | |||
| 7795 | } else { | ||
| 7796 | i += 3 + data[i + 2]; | ||
| 7797 | } | 7789 | } |
| 7790 | i += 3 + len; | ||
| 7798 | 7791 | ||
| 7799 | if (mn_match && v0_str) { | 7792 | if (mn_match && v0_str) { |
| 7800 | memcpy(bp->fw_version, v0_str, v0_len); | 7793 | memcpy(bp->fw_version, v0_str, v0_len); |
