diff options
author | Benjamin Herrenschmidt <benh@kernel.crashing.org> | 2009-12-09 01:14:38 -0500 |
---|---|---|
committer | Benjamin Herrenschmidt <benh@kernel.crashing.org> | 2009-12-09 01:14:38 -0500 |
commit | bcd6acd51f3d4d1ada201e9bc5c40a31d6d80c71 (patch) | |
tree | 2f6dffd2d3e4dd67355a224de7e7a960335a92fd /drivers/net/netxen/netxen_nic_init.c | |
parent | 11c34c7deaeeebcee342cbc35e1bb2a6711b2431 (diff) | |
parent | 3ff6a468b45b5dfeb0e903e56f4eb27d34b2437c (diff) |
Merge commit 'origin/master' into next
Conflicts:
include/linux/kvm.h
Diffstat (limited to 'drivers/net/netxen/netxen_nic_init.c')
-rw-r--r-- | drivers/net/netxen/netxen_nic_init.c | 363 |
1 files changed, 274 insertions, 89 deletions
diff --git a/drivers/net/netxen/netxen_nic_init.c b/drivers/net/netxen/netxen_nic_init.c index e40b914d6faf..80a667460514 100644 --- a/drivers/net/netxen/netxen_nic_init.c +++ b/drivers/net/netxen/netxen_nic_init.c | |||
@@ -46,6 +46,7 @@ static unsigned int crb_addr_xform[NETXEN_MAX_CRB_XFORM]; | |||
46 | static void | 46 | static void |
47 | netxen_post_rx_buffers_nodb(struct netxen_adapter *adapter, | 47 | netxen_post_rx_buffers_nodb(struct netxen_adapter *adapter, |
48 | struct nx_host_rds_ring *rds_ring); | 48 | struct nx_host_rds_ring *rds_ring); |
49 | static int netxen_p3_has_mn(struct netxen_adapter *adapter); | ||
49 | 50 | ||
50 | static void crb_addr_transform_setup(void) | 51 | static void crb_addr_transform_setup(void) |
51 | { | 52 | { |
@@ -437,7 +438,7 @@ int netxen_rom_fast_read(struct netxen_adapter *adapter, int addr, int *valp) | |||
437 | #define NETXEN_BOARDNUM 0x400c | 438 | #define NETXEN_BOARDNUM 0x400c |
438 | #define NETXEN_CHIPNUM 0x4010 | 439 | #define NETXEN_CHIPNUM 0x4010 |
439 | 440 | ||
440 | int netxen_pinit_from_rom(struct netxen_adapter *adapter, int verbose) | 441 | int netxen_pinit_from_rom(struct netxen_adapter *adapter) |
441 | { | 442 | { |
442 | int addr, val; | 443 | int addr, val; |
443 | int i, n, init_delay = 0; | 444 | int i, n, init_delay = 0; |
@@ -450,21 +451,6 @@ int netxen_pinit_from_rom(struct netxen_adapter *adapter, int verbose) | |||
450 | NXWR32(adapter, NETXEN_ROMUSB_GLB_SW_RESET, 0xffffffff); | 451 | NXWR32(adapter, NETXEN_ROMUSB_GLB_SW_RESET, 0xffffffff); |
451 | netxen_rom_unlock(adapter); | 452 | netxen_rom_unlock(adapter); |
452 | 453 | ||
453 | if (verbose) { | ||
454 | if (netxen_rom_fast_read(adapter, NETXEN_BOARDTYPE, &val) == 0) | ||
455 | printk("P2 ROM board type: 0x%08x\n", val); | ||
456 | else | ||
457 | printk("Could not read board type\n"); | ||
458 | if (netxen_rom_fast_read(adapter, NETXEN_BOARDNUM, &val) == 0) | ||
459 | printk("P2 ROM board num: 0x%08x\n", val); | ||
460 | else | ||
461 | printk("Could not read board number\n"); | ||
462 | if (netxen_rom_fast_read(adapter, NETXEN_CHIPNUM, &val) == 0) | ||
463 | printk("P2 ROM chip num: 0x%08x\n", val); | ||
464 | else | ||
465 | printk("Could not read chip number\n"); | ||
466 | } | ||
467 | |||
468 | if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) { | 454 | if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) { |
469 | if (netxen_rom_fast_read(adapter, 0, &n) != 0 || | 455 | if (netxen_rom_fast_read(adapter, 0, &n) != 0 || |
470 | (n != 0xcafecafe) || | 456 | (n != 0xcafecafe) || |
@@ -486,11 +472,7 @@ int netxen_pinit_from_rom(struct netxen_adapter *adapter, int verbose) | |||
486 | n &= ~0x80000000; | 472 | n &= ~0x80000000; |
487 | } | 473 | } |
488 | 474 | ||
489 | if (n < 1024) { | 475 | if (n >= 1024) { |
490 | if (verbose) | ||
491 | printk(KERN_DEBUG "%s: %d CRB init values found" | ||
492 | " in ROM.\n", netxen_nic_driver_name, n); | ||
493 | } else { | ||
494 | printk(KERN_ERR "%s:n=0x%x Error! NetXen card flash not" | 476 | printk(KERN_ERR "%s:n=0x%x Error! NetXen card flash not" |
495 | " initialized.\n", __func__, n); | 477 | " initialized.\n", __func__, n); |
496 | return -EIO; | 478 | return -EIO; |
@@ -502,6 +484,7 @@ int netxen_pinit_from_rom(struct netxen_adapter *adapter, int verbose) | |||
502 | netxen_nic_driver_name); | 484 | netxen_nic_driver_name); |
503 | return -ENOMEM; | 485 | return -ENOMEM; |
504 | } | 486 | } |
487 | |||
505 | for (i = 0; i < n; i++) { | 488 | for (i = 0; i < n; i++) { |
506 | if (netxen_rom_fast_read(adapter, 8*i + 4*offset, &val) != 0 || | 489 | if (netxen_rom_fast_read(adapter, 8*i + 4*offset, &val) != 0 || |
507 | netxen_rom_fast_read(adapter, 8*i + 4*offset + 4, &addr) != 0) { | 490 | netxen_rom_fast_read(adapter, 8*i + 4*offset + 4, &addr) != 0) { |
@@ -512,11 +495,8 @@ int netxen_pinit_from_rom(struct netxen_adapter *adapter, int verbose) | |||
512 | buf[i].addr = addr; | 495 | buf[i].addr = addr; |
513 | buf[i].data = val; | 496 | buf[i].data = val; |
514 | 497 | ||
515 | if (verbose) | ||
516 | printk(KERN_DEBUG "%s: PCI: 0x%08x == 0x%08x\n", | ||
517 | netxen_nic_driver_name, | ||
518 | (u32)netxen_decode_crb_addr(addr), val); | ||
519 | } | 498 | } |
499 | |||
520 | for (i = 0; i < n; i++) { | 500 | for (i = 0; i < n; i++) { |
521 | 501 | ||
522 | off = netxen_decode_crb_addr(buf[i].addr); | 502 | off = netxen_decode_crb_addr(buf[i].addr); |
@@ -526,6 +506,10 @@ int netxen_pinit_from_rom(struct netxen_adapter *adapter, int verbose) | |||
526 | continue; | 506 | continue; |
527 | } | 507 | } |
528 | off += NETXEN_PCI_CRBSPACE; | 508 | off += NETXEN_PCI_CRBSPACE; |
509 | |||
510 | if (off & 1) | ||
511 | continue; | ||
512 | |||
529 | /* skipping cold reboot MAGIC */ | 513 | /* skipping cold reboot MAGIC */ |
530 | if (off == NETXEN_CAM_RAM(0x1fc)) | 514 | if (off == NETXEN_CAM_RAM(0x1fc)) |
531 | continue; | 515 | continue; |
@@ -544,7 +528,10 @@ int netxen_pinit_from_rom(struct netxen_adapter *adapter, int verbose) | |||
544 | continue; | 528 | continue; |
545 | if (off == (ROMUSB_GLB + 0x1c)) /* MS clock */ | 529 | if (off == (ROMUSB_GLB + 0x1c)) /* MS clock */ |
546 | continue; | 530 | continue; |
547 | if (off == (NETXEN_CRB_PEG_NET_1 + 0x18)) | 531 | if ((off & 0x0ff00000) == NETXEN_CRB_DDR_NET) |
532 | continue; | ||
533 | if (off == (NETXEN_CRB_PEG_NET_1 + 0x18) && | ||
534 | !NX_IS_REVISION_P3P(adapter->ahw.revision_id)) | ||
548 | buf[i].data = 0x1020; | 535 | buf[i].data = 0x1020; |
549 | /* skip the function enable register */ | 536 | /* skip the function enable register */ |
550 | if (off == NETXEN_PCIE_REG(PCIE_SETUP_FUNCTION)) | 537 | if (off == NETXEN_PCIE_REG(PCIE_SETUP_FUNCTION)) |
@@ -605,6 +592,172 @@ int netxen_pinit_from_rom(struct netxen_adapter *adapter, int verbose) | |||
605 | return 0; | 592 | return 0; |
606 | } | 593 | } |
607 | 594 | ||
595 | static struct uni_table_desc *nx_get_table_desc(const u8 *unirom, int section) | ||
596 | { | ||
597 | uint32_t i; | ||
598 | struct uni_table_desc *directory = (struct uni_table_desc *) &unirom[0]; | ||
599 | __le32 entries = cpu_to_le32(directory->num_entries); | ||
600 | |||
601 | for (i = 0; i < entries; i++) { | ||
602 | |||
603 | __le32 offs = cpu_to_le32(directory->findex) + | ||
604 | (i * cpu_to_le32(directory->entry_size)); | ||
605 | __le32 tab_type = cpu_to_le32(*((u32 *)&unirom[offs] + 8)); | ||
606 | |||
607 | if (tab_type == section) | ||
608 | return (struct uni_table_desc *) &unirom[offs]; | ||
609 | } | ||
610 | |||
611 | return NULL; | ||
612 | } | ||
613 | |||
614 | static int | ||
615 | nx_set_product_offs(struct netxen_adapter *adapter) | ||
616 | { | ||
617 | struct uni_table_desc *ptab_descr; | ||
618 | const u8 *unirom = adapter->fw->data; | ||
619 | uint32_t i; | ||
620 | __le32 entries; | ||
621 | |||
622 | ptab_descr = nx_get_table_desc(unirom, NX_UNI_DIR_SECT_PRODUCT_TBL); | ||
623 | if (ptab_descr == NULL) | ||
624 | return -1; | ||
625 | |||
626 | entries = cpu_to_le32(ptab_descr->num_entries); | ||
627 | |||
628 | for (i = 0; i < entries; i++) { | ||
629 | |||
630 | __le32 flags, file_chiprev, offs; | ||
631 | u8 chiprev = adapter->ahw.revision_id; | ||
632 | int mn_present = netxen_p3_has_mn(adapter); | ||
633 | uint32_t flagbit; | ||
634 | |||
635 | offs = cpu_to_le32(ptab_descr->findex) + | ||
636 | (i * cpu_to_le32(ptab_descr->entry_size)); | ||
637 | flags = cpu_to_le32(*((int *)&unirom[offs] + NX_UNI_FLAGS_OFF)); | ||
638 | file_chiprev = cpu_to_le32(*((int *)&unirom[offs] + | ||
639 | NX_UNI_CHIP_REV_OFF)); | ||
640 | |||
641 | flagbit = mn_present ? 1 : 2; | ||
642 | |||
643 | if ((chiprev == file_chiprev) && | ||
644 | ((1ULL << flagbit) & flags)) { | ||
645 | adapter->file_prd_off = offs; | ||
646 | return 0; | ||
647 | } | ||
648 | } | ||
649 | |||
650 | return -1; | ||
651 | } | ||
652 | |||
653 | |||
654 | static struct uni_data_desc *nx_get_data_desc(struct netxen_adapter *adapter, | ||
655 | u32 section, u32 idx_offset) | ||
656 | { | ||
657 | const u8 *unirom = adapter->fw->data; | ||
658 | int idx = cpu_to_le32(*((int *)&unirom[adapter->file_prd_off] + | ||
659 | idx_offset)); | ||
660 | struct uni_table_desc *tab_desc; | ||
661 | __le32 offs; | ||
662 | |||
663 | tab_desc = nx_get_table_desc(unirom, section); | ||
664 | |||
665 | if (tab_desc == NULL) | ||
666 | return NULL; | ||
667 | |||
668 | offs = cpu_to_le32(tab_desc->findex) + | ||
669 | (cpu_to_le32(tab_desc->entry_size) * idx); | ||
670 | |||
671 | return (struct uni_data_desc *)&unirom[offs]; | ||
672 | } | ||
673 | |||
674 | static u8 * | ||
675 | nx_get_bootld_offs(struct netxen_adapter *adapter) | ||
676 | { | ||
677 | u32 offs = NETXEN_BOOTLD_START; | ||
678 | |||
679 | if (adapter->fw_type == NX_UNIFIED_ROMIMAGE) | ||
680 | offs = cpu_to_le32((nx_get_data_desc(adapter, | ||
681 | NX_UNI_DIR_SECT_BOOTLD, | ||
682 | NX_UNI_BOOTLD_IDX_OFF))->findex); | ||
683 | |||
684 | return (u8 *)&adapter->fw->data[offs]; | ||
685 | } | ||
686 | |||
687 | static u8 * | ||
688 | nx_get_fw_offs(struct netxen_adapter *adapter) | ||
689 | { | ||
690 | u32 offs = NETXEN_IMAGE_START; | ||
691 | |||
692 | if (adapter->fw_type == NX_UNIFIED_ROMIMAGE) | ||
693 | offs = cpu_to_le32((nx_get_data_desc(adapter, | ||
694 | NX_UNI_DIR_SECT_FW, | ||
695 | NX_UNI_FIRMWARE_IDX_OFF))->findex); | ||
696 | |||
697 | return (u8 *)&adapter->fw->data[offs]; | ||
698 | } | ||
699 | |||
700 | static __le32 | ||
701 | nx_get_fw_size(struct netxen_adapter *adapter) | ||
702 | { | ||
703 | if (adapter->fw_type == NX_UNIFIED_ROMIMAGE) | ||
704 | return cpu_to_le32((nx_get_data_desc(adapter, | ||
705 | NX_UNI_DIR_SECT_FW, | ||
706 | NX_UNI_FIRMWARE_IDX_OFF))->size); | ||
707 | else | ||
708 | return cpu_to_le32( | ||
709 | *(u32 *)&adapter->fw->data[NX_FW_SIZE_OFFSET]); | ||
710 | } | ||
711 | |||
712 | static __le32 | ||
713 | nx_get_fw_version(struct netxen_adapter *adapter) | ||
714 | { | ||
715 | struct uni_data_desc *fw_data_desc; | ||
716 | const struct firmware *fw = adapter->fw; | ||
717 | __le32 major, minor, sub; | ||
718 | const u8 *ver_str; | ||
719 | int i, ret = 0; | ||
720 | |||
721 | if (adapter->fw_type == NX_UNIFIED_ROMIMAGE) { | ||
722 | |||
723 | fw_data_desc = nx_get_data_desc(adapter, | ||
724 | NX_UNI_DIR_SECT_FW, NX_UNI_FIRMWARE_IDX_OFF); | ||
725 | ver_str = fw->data + cpu_to_le32(fw_data_desc->findex) + | ||
726 | cpu_to_le32(fw_data_desc->size) - 17; | ||
727 | |||
728 | for (i = 0; i < 12; i++) { | ||
729 | if (!strncmp(&ver_str[i], "REV=", 4)) { | ||
730 | ret = sscanf(&ver_str[i+4], "%u.%u.%u ", | ||
731 | &major, &minor, &sub); | ||
732 | break; | ||
733 | } | ||
734 | } | ||
735 | |||
736 | if (ret != 3) | ||
737 | return 0; | ||
738 | |||
739 | return major + (minor << 8) + (sub << 16); | ||
740 | |||
741 | } else | ||
742 | return cpu_to_le32(*(u32 *)&fw->data[NX_FW_VERSION_OFFSET]); | ||
743 | } | ||
744 | |||
745 | static __le32 | ||
746 | nx_get_bios_version(struct netxen_adapter *adapter) | ||
747 | { | ||
748 | const struct firmware *fw = adapter->fw; | ||
749 | __le32 bios_ver, prd_off = adapter->file_prd_off; | ||
750 | |||
751 | if (adapter->fw_type == NX_UNIFIED_ROMIMAGE) { | ||
752 | bios_ver = cpu_to_le32(*((u32 *) (&fw->data[prd_off]) | ||
753 | + NX_UNI_BIOS_VERSION_OFF)); | ||
754 | return (bios_ver << 24) + ((bios_ver >> 8) & 0xff00) + | ||
755 | (bios_ver >> 24); | ||
756 | } else | ||
757 | return cpu_to_le32(*(u32 *)&fw->data[NX_BIOS_VERSION_OFFSET]); | ||
758 | |||
759 | } | ||
760 | |||
608 | int | 761 | int |
609 | netxen_need_fw_reset(struct netxen_adapter *adapter) | 762 | netxen_need_fw_reset(struct netxen_adapter *adapter) |
610 | { | 763 | { |
@@ -644,9 +797,8 @@ netxen_need_fw_reset(struct netxen_adapter *adapter) | |||
644 | /* check if we have got newer or different file firmware */ | 797 | /* check if we have got newer or different file firmware */ |
645 | if (adapter->fw) { | 798 | if (adapter->fw) { |
646 | 799 | ||
647 | const struct firmware *fw = adapter->fw; | 800 | val = nx_get_fw_version(adapter); |
648 | 801 | ||
649 | val = cpu_to_le32(*(u32 *)&fw->data[NX_FW_VERSION_OFFSET]); | ||
650 | version = NETXEN_DECODE_VERSION(val); | 802 | version = NETXEN_DECODE_VERSION(val); |
651 | 803 | ||
652 | major = NXRD32(adapter, NETXEN_FW_VERSION_MAJOR); | 804 | major = NXRD32(adapter, NETXEN_FW_VERSION_MAJOR); |
@@ -656,7 +808,8 @@ netxen_need_fw_reset(struct netxen_adapter *adapter) | |||
656 | if (version > NETXEN_VERSION_CODE(major, minor, build)) | 808 | if (version > NETXEN_VERSION_CODE(major, minor, build)) |
657 | return 1; | 809 | return 1; |
658 | 810 | ||
659 | if (version == NETXEN_VERSION_CODE(major, minor, build)) { | 811 | if (version == NETXEN_VERSION_CODE(major, minor, build) && |
812 | adapter->fw_type != NX_UNIFIED_ROMIMAGE) { | ||
660 | 813 | ||
661 | val = NXRD32(adapter, NETXEN_MIU_MN_CONTROL); | 814 | val = NXRD32(adapter, NETXEN_MIU_MN_CONTROL); |
662 | fw_type = (val & 0x4) ? | 815 | fw_type = (val & 0x4) ? |
@@ -671,7 +824,11 @@ netxen_need_fw_reset(struct netxen_adapter *adapter) | |||
671 | } | 824 | } |
672 | 825 | ||
673 | static char *fw_name[] = { | 826 | static char *fw_name[] = { |
674 | "nxromimg.bin", "nx3fwct.bin", "nx3fwmn.bin", "flash", | 827 | NX_P2_MN_ROMIMAGE_NAME, |
828 | NX_P3_CT_ROMIMAGE_NAME, | ||
829 | NX_P3_MN_ROMIMAGE_NAME, | ||
830 | NX_UNIFIED_ROMIMAGE_NAME, | ||
831 | NX_FLASH_ROMIMAGE_NAME, | ||
675 | }; | 832 | }; |
676 | 833 | ||
677 | int | 834 | int |
@@ -693,26 +850,28 @@ netxen_load_firmware(struct netxen_adapter *adapter) | |||
693 | 850 | ||
694 | size = (NETXEN_IMAGE_START - NETXEN_BOOTLD_START) / 8; | 851 | size = (NETXEN_IMAGE_START - NETXEN_BOOTLD_START) / 8; |
695 | 852 | ||
696 | ptr64 = (u64 *)&fw->data[NETXEN_BOOTLD_START]; | 853 | ptr64 = (u64 *)nx_get_bootld_offs(adapter); |
697 | flashaddr = NETXEN_BOOTLD_START; | 854 | flashaddr = NETXEN_BOOTLD_START; |
698 | 855 | ||
699 | for (i = 0; i < size; i++) { | 856 | for (i = 0; i < size; i++) { |
700 | data = cpu_to_le64(ptr64[i]); | 857 | data = cpu_to_le64(ptr64[i]); |
701 | adapter->pci_mem_write(adapter, flashaddr, &data, 8); | 858 | |
859 | if (adapter->pci_mem_write(adapter, flashaddr, data)) | ||
860 | return -EIO; | ||
861 | |||
702 | flashaddr += 8; | 862 | flashaddr += 8; |
703 | } | 863 | } |
704 | 864 | ||
705 | size = *(u32 *)&fw->data[NX_FW_SIZE_OFFSET]; | 865 | size = (__force u32)nx_get_fw_size(adapter) / 8; |
706 | size = (__force u32)cpu_to_le32(size) / 8; | ||
707 | 866 | ||
708 | ptr64 = (u64 *)&fw->data[NETXEN_IMAGE_START]; | 867 | ptr64 = (u64 *)nx_get_fw_offs(adapter); |
709 | flashaddr = NETXEN_IMAGE_START; | 868 | flashaddr = NETXEN_IMAGE_START; |
710 | 869 | ||
711 | for (i = 0; i < size; i++) { | 870 | for (i = 0; i < size; i++) { |
712 | data = cpu_to_le64(ptr64[i]); | 871 | data = cpu_to_le64(ptr64[i]); |
713 | 872 | ||
714 | if (adapter->pci_mem_write(adapter, | 873 | if (adapter->pci_mem_write(adapter, |
715 | flashaddr, &data, 8)) | 874 | flashaddr, data)) |
716 | return -EIO; | 875 | return -EIO; |
717 | 876 | ||
718 | flashaddr += 8; | 877 | flashaddr += 8; |
@@ -726,17 +885,17 @@ netxen_load_firmware(struct netxen_adapter *adapter) | |||
726 | 885 | ||
727 | for (i = 0; i < size; i++) { | 886 | for (i = 0; i < size; i++) { |
728 | if (netxen_rom_fast_read(adapter, | 887 | if (netxen_rom_fast_read(adapter, |
729 | flashaddr, &lo) != 0) | 888 | flashaddr, (int *)&lo) != 0) |
730 | return -EIO; | 889 | return -EIO; |
731 | if (netxen_rom_fast_read(adapter, | 890 | if (netxen_rom_fast_read(adapter, |
732 | flashaddr + 4, &hi) != 0) | 891 | flashaddr + 4, (int *)&hi) != 0) |
733 | return -EIO; | 892 | return -EIO; |
734 | 893 | ||
735 | /* hi, lo are already in host endian byteorder */ | 894 | /* hi, lo are already in host endian byteorder */ |
736 | data = (((u64)hi << 32) | lo); | 895 | data = (((u64)hi << 32) | lo); |
737 | 896 | ||
738 | if (adapter->pci_mem_write(adapter, | 897 | if (adapter->pci_mem_write(adapter, |
739 | flashaddr, &data, 8)) | 898 | flashaddr, data)) |
740 | return -EIO; | 899 | return -EIO; |
741 | 900 | ||
742 | flashaddr += 8; | 901 | flashaddr += 8; |
@@ -744,7 +903,10 @@ netxen_load_firmware(struct netxen_adapter *adapter) | |||
744 | } | 903 | } |
745 | msleep(1); | 904 | msleep(1); |
746 | 905 | ||
747 | if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) | 906 | if (NX_IS_REVISION_P3P(adapter->ahw.revision_id)) { |
907 | NXWR32(adapter, NETXEN_CRB_PEG_NET_0 + 0x18, 0x1020); | ||
908 | NXWR32(adapter, NETXEN_ROMUSB_GLB_SW_RESET, 0x80001e); | ||
909 | } else if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) | ||
748 | NXWR32(adapter, NETXEN_ROMUSB_GLB_SW_RESET, 0x80001d); | 910 | NXWR32(adapter, NETXEN_ROMUSB_GLB_SW_RESET, 0x80001d); |
749 | else { | 911 | else { |
750 | NXWR32(adapter, NETXEN_ROMUSB_GLB_CHIP_CLK_CTRL, 0x3fff); | 912 | NXWR32(adapter, NETXEN_ROMUSB_GLB_CHIP_CLK_CTRL, 0x3fff); |
@@ -755,21 +917,31 @@ netxen_load_firmware(struct netxen_adapter *adapter) | |||
755 | } | 917 | } |
756 | 918 | ||
757 | static int | 919 | static int |
758 | netxen_validate_firmware(struct netxen_adapter *adapter, const char *fwname) | 920 | netxen_validate_firmware(struct netxen_adapter *adapter) |
759 | { | 921 | { |
760 | __le32 val; | 922 | __le32 val; |
761 | u32 ver, min_ver, bios; | 923 | u32 ver, min_ver, bios, min_size; |
762 | struct pci_dev *pdev = adapter->pdev; | 924 | struct pci_dev *pdev = adapter->pdev; |
763 | const struct firmware *fw = adapter->fw; | 925 | const struct firmware *fw = adapter->fw; |
926 | u8 fw_type = adapter->fw_type; | ||
764 | 927 | ||
765 | if (fw->size < NX_FW_MIN_SIZE) | 928 | if (fw_type == NX_UNIFIED_ROMIMAGE) { |
766 | return -EINVAL; | 929 | if (nx_set_product_offs(adapter)) |
930 | return -EINVAL; | ||
931 | |||
932 | min_size = NX_UNI_FW_MIN_SIZE; | ||
933 | } else { | ||
934 | val = cpu_to_le32(*(u32 *)&fw->data[NX_FW_MAGIC_OFFSET]); | ||
935 | if ((__force u32)val != NETXEN_BDINFO_MAGIC) | ||
936 | return -EINVAL; | ||
937 | |||
938 | min_size = NX_FW_MIN_SIZE; | ||
939 | } | ||
767 | 940 | ||
768 | val = cpu_to_le32(*(u32 *)&fw->data[NX_FW_MAGIC_OFFSET]); | 941 | if (fw->size < min_size) |
769 | if ((__force u32)val != NETXEN_BDINFO_MAGIC) | ||
770 | return -EINVAL; | 942 | return -EINVAL; |
771 | 943 | ||
772 | val = cpu_to_le32(*(u32 *)&fw->data[NX_FW_VERSION_OFFSET]); | 944 | val = nx_get_fw_version(adapter); |
773 | 945 | ||
774 | if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) | 946 | if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) |
775 | min_ver = NETXEN_VERSION_CODE(4, 0, 216); | 947 | min_ver = NETXEN_VERSION_CODE(4, 0, 216); |
@@ -781,15 +953,15 @@ netxen_validate_firmware(struct netxen_adapter *adapter, const char *fwname) | |||
781 | if ((_major(ver) > _NETXEN_NIC_LINUX_MAJOR) || (ver < min_ver)) { | 953 | if ((_major(ver) > _NETXEN_NIC_LINUX_MAJOR) || (ver < min_ver)) { |
782 | dev_err(&pdev->dev, | 954 | dev_err(&pdev->dev, |
783 | "%s: firmware version %d.%d.%d unsupported\n", | 955 | "%s: firmware version %d.%d.%d unsupported\n", |
784 | fwname, _major(ver), _minor(ver), _build(ver)); | 956 | fw_name[fw_type], _major(ver), _minor(ver), _build(ver)); |
785 | return -EINVAL; | 957 | return -EINVAL; |
786 | } | 958 | } |
787 | 959 | ||
788 | val = cpu_to_le32(*(u32 *)&fw->data[NX_BIOS_VERSION_OFFSET]); | 960 | val = nx_get_bios_version(adapter); |
789 | netxen_rom_fast_read(adapter, NX_BIOS_VERSION_OFFSET, (int *)&bios); | 961 | netxen_rom_fast_read(adapter, NX_BIOS_VERSION_OFFSET, (int *)&bios); |
790 | if ((__force u32)val != bios) { | 962 | if ((__force u32)val != bios) { |
791 | dev_err(&pdev->dev, "%s: firmware bios is incompatible\n", | 963 | dev_err(&pdev->dev, "%s: firmware bios is incompatible\n", |
792 | fwname); | 964 | fw_name[fw_type]); |
793 | return -EINVAL; | 965 | return -EINVAL; |
794 | } | 966 | } |
795 | 967 | ||
@@ -800,7 +972,7 @@ netxen_validate_firmware(struct netxen_adapter *adapter, const char *fwname) | |||
800 | val = NETXEN_DECODE_VERSION(val); | 972 | val = NETXEN_DECODE_VERSION(val); |
801 | if (val > ver) { | 973 | if (val > ver) { |
802 | dev_info(&pdev->dev, "%s: firmware is older than flash\n", | 974 | dev_info(&pdev->dev, "%s: firmware is older than flash\n", |
803 | fwname); | 975 | fw_name[fw_type]); |
804 | return -EINVAL; | 976 | return -EINVAL; |
805 | } | 977 | } |
806 | 978 | ||
@@ -808,6 +980,41 @@ netxen_validate_firmware(struct netxen_adapter *adapter, const char *fwname) | |||
808 | return 0; | 980 | return 0; |
809 | } | 981 | } |
810 | 982 | ||
983 | static void | ||
984 | nx_get_next_fwtype(struct netxen_adapter *adapter) | ||
985 | { | ||
986 | u8 fw_type; | ||
987 | |||
988 | switch (adapter->fw_type) { | ||
989 | case NX_UNKNOWN_ROMIMAGE: | ||
990 | fw_type = NX_UNIFIED_ROMIMAGE; | ||
991 | break; | ||
992 | |||
993 | case NX_UNIFIED_ROMIMAGE: | ||
994 | if (NX_IS_REVISION_P3P(adapter->ahw.revision_id)) | ||
995 | fw_type = NX_FLASH_ROMIMAGE; | ||
996 | else if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) | ||
997 | fw_type = NX_P2_MN_ROMIMAGE; | ||
998 | else if (netxen_p3_has_mn(adapter)) | ||
999 | fw_type = NX_P3_MN_ROMIMAGE; | ||
1000 | else | ||
1001 | fw_type = NX_P3_CT_ROMIMAGE; | ||
1002 | break; | ||
1003 | |||
1004 | case NX_P3_MN_ROMIMAGE: | ||
1005 | fw_type = NX_P3_CT_ROMIMAGE; | ||
1006 | break; | ||
1007 | |||
1008 | case NX_P2_MN_ROMIMAGE: | ||
1009 | case NX_P3_CT_ROMIMAGE: | ||
1010 | default: | ||
1011 | fw_type = NX_FLASH_ROMIMAGE; | ||
1012 | break; | ||
1013 | } | ||
1014 | |||
1015 | adapter->fw_type = fw_type; | ||
1016 | } | ||
1017 | |||
811 | static int | 1018 | static int |
812 | netxen_p3_has_mn(struct netxen_adapter *adapter) | 1019 | netxen_p3_has_mn(struct netxen_adapter *adapter) |
813 | { | 1020 | { |
@@ -829,49 +1036,29 @@ netxen_p3_has_mn(struct netxen_adapter *adapter) | |||
829 | 1036 | ||
830 | void netxen_request_firmware(struct netxen_adapter *adapter) | 1037 | void netxen_request_firmware(struct netxen_adapter *adapter) |
831 | { | 1038 | { |
832 | u8 fw_type; | ||
833 | struct pci_dev *pdev = adapter->pdev; | 1039 | struct pci_dev *pdev = adapter->pdev; |
834 | int rc = 0; | 1040 | int rc = 0; |
835 | 1041 | ||
836 | if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) { | 1042 | adapter->fw_type = NX_UNKNOWN_ROMIMAGE; |
837 | fw_type = NX_P2_MN_ROMIMAGE; | ||
838 | goto request_fw; | ||
839 | } | ||
840 | |||
841 | fw_type = netxen_p3_has_mn(adapter) ? | ||
842 | NX_P3_MN_ROMIMAGE : NX_P3_CT_ROMIMAGE; | ||
843 | 1043 | ||
844 | request_fw: | 1044 | next: |
845 | rc = request_firmware(&adapter->fw, fw_name[fw_type], &pdev->dev); | 1045 | nx_get_next_fwtype(adapter); |
846 | if (rc != 0) { | ||
847 | if (fw_type == NX_P3_MN_ROMIMAGE) { | ||
848 | msleep(1); | ||
849 | fw_type = NX_P3_CT_ROMIMAGE; | ||
850 | goto request_fw; | ||
851 | } | ||
852 | 1046 | ||
853 | fw_type = NX_FLASH_ROMIMAGE; | 1047 | if (adapter->fw_type == NX_FLASH_ROMIMAGE) { |
854 | adapter->fw = NULL; | 1048 | adapter->fw = NULL; |
855 | goto done; | 1049 | } else { |
856 | } | 1050 | rc = request_firmware(&adapter->fw, |
857 | 1051 | fw_name[adapter->fw_type], &pdev->dev); | |
858 | rc = netxen_validate_firmware(adapter, fw_name[fw_type]); | 1052 | if (rc != 0) |
859 | if (rc != 0) { | 1053 | goto next; |
860 | release_firmware(adapter->fw); | 1054 | |
861 | 1055 | rc = netxen_validate_firmware(adapter); | |
862 | if (fw_type == NX_P3_MN_ROMIMAGE) { | 1056 | if (rc != 0) { |
1057 | release_firmware(adapter->fw); | ||
863 | msleep(1); | 1058 | msleep(1); |
864 | fw_type = NX_P3_CT_ROMIMAGE; | 1059 | goto next; |
865 | goto request_fw; | ||
866 | } | 1060 | } |
867 | |||
868 | fw_type = NX_FLASH_ROMIMAGE; | ||
869 | adapter->fw = NULL; | ||
870 | goto done; | ||
871 | } | 1061 | } |
872 | |||
873 | done: | ||
874 | adapter->fw_type = fw_type; | ||
875 | } | 1062 | } |
876 | 1063 | ||
877 | 1064 | ||
@@ -1506,10 +1693,8 @@ netxen_post_rx_buffers(struct netxen_adapter *adapter, u32 ringid, | |||
1506 | (rds_ring->num_desc - 1))); | 1693 | (rds_ring->num_desc - 1))); |
1507 | netxen_set_msg_ctxid(msg, adapter->portnum); | 1694 | netxen_set_msg_ctxid(msg, adapter->portnum); |
1508 | netxen_set_msg_opcode(msg, NETXEN_RCV_PRODUCER(ringid)); | 1695 | netxen_set_msg_opcode(msg, NETXEN_RCV_PRODUCER(ringid)); |
1509 | read_lock(&adapter->adapter_lock); | 1696 | NXWRIO(adapter, DB_NORMALIZE(adapter, |
1510 | writel(msg, DB_NORMALIZE(adapter, | 1697 | NETXEN_RCV_PRODUCER_OFFSET), msg); |
1511 | NETXEN_RCV_PRODUCER_OFFSET)); | ||
1512 | read_unlock(&adapter->adapter_lock); | ||
1513 | } | 1698 | } |
1514 | } | 1699 | } |
1515 | } | 1700 | } |