diff options
author | Andrea Bastoni <bastoni@cs.unc.edu> | 2010-05-30 19:16:45 -0400 |
---|---|---|
committer | Andrea Bastoni <bastoni@cs.unc.edu> | 2010-05-30 19:16:45 -0400 |
commit | ada47b5fe13d89735805b566185f4885f5a3f750 (patch) | |
tree | 644b88f8a71896307d71438e9b3af49126ffb22b /drivers/net/netxen/netxen_nic_init.c | |
parent | 43e98717ad40a4ae64545b5ba047c7b86aa44f4f (diff) | |
parent | 3280f21d43ee541f97f8cda5792150d2dbec20d5 (diff) |
Merge branch 'wip-2.6.34' into old-private-masterarchived-private-master
Diffstat (limited to 'drivers/net/netxen/netxen_nic_init.c')
-rw-r--r-- | drivers/net/netxen/netxen_nic_init.c | 383 |
1 files changed, 292 insertions, 91 deletions
diff --git a/drivers/net/netxen/netxen_nic_init.c b/drivers/net/netxen/netxen_nic_init.c index 8a0904368e08..02876f59cbb2 100644 --- a/drivers/net/netxen/netxen_nic_init.c +++ b/drivers/net/netxen/netxen_nic_init.c | |||
@@ -19,12 +19,13 @@ | |||
19 | * MA 02111-1307, USA. | 19 | * MA 02111-1307, USA. |
20 | * | 20 | * |
21 | * The full GNU General Public License is included in this distribution | 21 | * The full GNU General Public License is included in this distribution |
22 | * in the file called LICENSE. | 22 | * in the file called "COPYING". |
23 | * | 23 | * |
24 | */ | 24 | */ |
25 | 25 | ||
26 | #include <linux/netdevice.h> | 26 | #include <linux/netdevice.h> |
27 | #include <linux/delay.h> | 27 | #include <linux/delay.h> |
28 | #include <linux/slab.h> | ||
28 | #include "netxen_nic.h" | 29 | #include "netxen_nic.h" |
29 | #include "netxen_nic_hw.h" | 30 | #include "netxen_nic_hw.h" |
30 | 31 | ||
@@ -46,6 +47,7 @@ static unsigned int crb_addr_xform[NETXEN_MAX_CRB_XFORM]; | |||
46 | static void | 47 | static void |
47 | netxen_post_rx_buffers_nodb(struct netxen_adapter *adapter, | 48 | netxen_post_rx_buffers_nodb(struct netxen_adapter *adapter, |
48 | struct nx_host_rds_ring *rds_ring); | 49 | struct nx_host_rds_ring *rds_ring); |
50 | static int netxen_p3_has_mn(struct netxen_adapter *adapter); | ||
49 | 51 | ||
50 | static void crb_addr_transform_setup(void) | 52 | static void crb_addr_transform_setup(void) |
51 | { | 53 | { |
@@ -183,6 +185,8 @@ skip_rds: | |||
183 | 185 | ||
184 | tx_ring = adapter->tx_ring; | 186 | tx_ring = adapter->tx_ring; |
185 | vfree(tx_ring->cmd_buf_arr); | 187 | vfree(tx_ring->cmd_buf_arr); |
188 | kfree(tx_ring); | ||
189 | adapter->tx_ring = NULL; | ||
186 | } | 190 | } |
187 | 191 | ||
188 | int netxen_alloc_sw_resources(struct netxen_adapter *adapter) | 192 | int netxen_alloc_sw_resources(struct netxen_adapter *adapter) |
@@ -437,7 +441,7 @@ int netxen_rom_fast_read(struct netxen_adapter *adapter, int addr, int *valp) | |||
437 | #define NETXEN_BOARDNUM 0x400c | 441 | #define NETXEN_BOARDNUM 0x400c |
438 | #define NETXEN_CHIPNUM 0x4010 | 442 | #define NETXEN_CHIPNUM 0x4010 |
439 | 443 | ||
440 | int netxen_pinit_from_rom(struct netxen_adapter *adapter, int verbose) | 444 | int netxen_pinit_from_rom(struct netxen_adapter *adapter) |
441 | { | 445 | { |
442 | int addr, val; | 446 | int addr, val; |
443 | int i, n, init_delay = 0; | 447 | int i, n, init_delay = 0; |
@@ -450,21 +454,6 @@ int netxen_pinit_from_rom(struct netxen_adapter *adapter, int verbose) | |||
450 | NXWR32(adapter, NETXEN_ROMUSB_GLB_SW_RESET, 0xffffffff); | 454 | NXWR32(adapter, NETXEN_ROMUSB_GLB_SW_RESET, 0xffffffff); |
451 | netxen_rom_unlock(adapter); | 455 | netxen_rom_unlock(adapter); |
452 | 456 | ||
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)) { | 457 | if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) { |
469 | if (netxen_rom_fast_read(adapter, 0, &n) != 0 || | 458 | if (netxen_rom_fast_read(adapter, 0, &n) != 0 || |
470 | (n != 0xcafecafe) || | 459 | (n != 0xcafecafe) || |
@@ -486,11 +475,7 @@ int netxen_pinit_from_rom(struct netxen_adapter *adapter, int verbose) | |||
486 | n &= ~0x80000000; | 475 | n &= ~0x80000000; |
487 | } | 476 | } |
488 | 477 | ||
489 | if (n < 1024) { | 478 | 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" | 479 | printk(KERN_ERR "%s:n=0x%x Error! NetXen card flash not" |
495 | " initialized.\n", __func__, n); | 480 | " initialized.\n", __func__, n); |
496 | return -EIO; | 481 | return -EIO; |
@@ -502,6 +487,7 @@ int netxen_pinit_from_rom(struct netxen_adapter *adapter, int verbose) | |||
502 | netxen_nic_driver_name); | 487 | netxen_nic_driver_name); |
503 | return -ENOMEM; | 488 | return -ENOMEM; |
504 | } | 489 | } |
490 | |||
505 | for (i = 0; i < n; i++) { | 491 | for (i = 0; i < n; i++) { |
506 | if (netxen_rom_fast_read(adapter, 8*i + 4*offset, &val) != 0 || | 492 | 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) { | 493 | netxen_rom_fast_read(adapter, 8*i + 4*offset + 4, &addr) != 0) { |
@@ -512,11 +498,8 @@ int netxen_pinit_from_rom(struct netxen_adapter *adapter, int verbose) | |||
512 | buf[i].addr = addr; | 498 | buf[i].addr = addr; |
513 | buf[i].data = val; | 499 | buf[i].data = val; |
514 | 500 | ||
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 | } | 501 | } |
502 | |||
520 | for (i = 0; i < n; i++) { | 503 | for (i = 0; i < n; i++) { |
521 | 504 | ||
522 | off = netxen_decode_crb_addr(buf[i].addr); | 505 | off = netxen_decode_crb_addr(buf[i].addr); |
@@ -526,6 +509,10 @@ int netxen_pinit_from_rom(struct netxen_adapter *adapter, int verbose) | |||
526 | continue; | 509 | continue; |
527 | } | 510 | } |
528 | off += NETXEN_PCI_CRBSPACE; | 511 | off += NETXEN_PCI_CRBSPACE; |
512 | |||
513 | if (off & 1) | ||
514 | continue; | ||
515 | |||
529 | /* skipping cold reboot MAGIC */ | 516 | /* skipping cold reboot MAGIC */ |
530 | if (off == NETXEN_CAM_RAM(0x1fc)) | 517 | if (off == NETXEN_CAM_RAM(0x1fc)) |
531 | continue; | 518 | continue; |
@@ -546,7 +533,8 @@ int netxen_pinit_from_rom(struct netxen_adapter *adapter, int verbose) | |||
546 | continue; | 533 | continue; |
547 | if ((off & 0x0ff00000) == NETXEN_CRB_DDR_NET) | 534 | if ((off & 0x0ff00000) == NETXEN_CRB_DDR_NET) |
548 | continue; | 535 | continue; |
549 | if (off == (NETXEN_CRB_PEG_NET_1 + 0x18)) | 536 | if (off == (NETXEN_CRB_PEG_NET_1 + 0x18) && |
537 | !NX_IS_REVISION_P3P(adapter->ahw.revision_id)) | ||
550 | buf[i].data = 0x1020; | 538 | buf[i].data = 0x1020; |
551 | /* skip the function enable register */ | 539 | /* skip the function enable register */ |
552 | if (off == NETXEN_PCIE_REG(PCIE_SETUP_FUNCTION)) | 540 | if (off == NETXEN_PCIE_REG(PCIE_SETUP_FUNCTION)) |
@@ -607,6 +595,180 @@ int netxen_pinit_from_rom(struct netxen_adapter *adapter, int verbose) | |||
607 | return 0; | 595 | return 0; |
608 | } | 596 | } |
609 | 597 | ||
598 | static struct uni_table_desc *nx_get_table_desc(const u8 *unirom, int section) | ||
599 | { | ||
600 | uint32_t i; | ||
601 | struct uni_table_desc *directory = (struct uni_table_desc *) &unirom[0]; | ||
602 | __le32 entries = cpu_to_le32(directory->num_entries); | ||
603 | |||
604 | for (i = 0; i < entries; i++) { | ||
605 | |||
606 | __le32 offs = cpu_to_le32(directory->findex) + | ||
607 | (i * cpu_to_le32(directory->entry_size)); | ||
608 | __le32 tab_type = cpu_to_le32(*((u32 *)&unirom[offs] + 8)); | ||
609 | |||
610 | if (tab_type == section) | ||
611 | return (struct uni_table_desc *) &unirom[offs]; | ||
612 | } | ||
613 | |||
614 | return NULL; | ||
615 | } | ||
616 | |||
617 | static int | ||
618 | nx_set_product_offs(struct netxen_adapter *adapter) | ||
619 | { | ||
620 | struct uni_table_desc *ptab_descr; | ||
621 | const u8 *unirom = adapter->fw->data; | ||
622 | uint32_t i; | ||
623 | __le32 entries; | ||
624 | |||
625 | int mn_present = (NX_IS_REVISION_P2(adapter->ahw.revision_id)) ? | ||
626 | 1 : netxen_p3_has_mn(adapter); | ||
627 | |||
628 | ptab_descr = nx_get_table_desc(unirom, NX_UNI_DIR_SECT_PRODUCT_TBL); | ||
629 | if (ptab_descr == NULL) | ||
630 | return -1; | ||
631 | |||
632 | entries = cpu_to_le32(ptab_descr->num_entries); | ||
633 | |||
634 | nomn: | ||
635 | for (i = 0; i < entries; i++) { | ||
636 | |||
637 | __le32 flags, file_chiprev, offs; | ||
638 | u8 chiprev = adapter->ahw.revision_id; | ||
639 | uint32_t flagbit; | ||
640 | |||
641 | offs = cpu_to_le32(ptab_descr->findex) + | ||
642 | (i * cpu_to_le32(ptab_descr->entry_size)); | ||
643 | flags = cpu_to_le32(*((int *)&unirom[offs] + NX_UNI_FLAGS_OFF)); | ||
644 | file_chiprev = cpu_to_le32(*((int *)&unirom[offs] + | ||
645 | NX_UNI_CHIP_REV_OFF)); | ||
646 | |||
647 | flagbit = mn_present ? 1 : 2; | ||
648 | |||
649 | if ((chiprev == file_chiprev) && | ||
650 | ((1ULL << flagbit) & flags)) { | ||
651 | adapter->file_prd_off = offs; | ||
652 | return 0; | ||
653 | } | ||
654 | } | ||
655 | |||
656 | if (mn_present && NX_IS_REVISION_P3(adapter->ahw.revision_id)) { | ||
657 | mn_present = 0; | ||
658 | goto nomn; | ||
659 | } | ||
660 | |||
661 | return -1; | ||
662 | } | ||
663 | |||
664 | |||
665 | static struct uni_data_desc *nx_get_data_desc(struct netxen_adapter *adapter, | ||
666 | u32 section, u32 idx_offset) | ||
667 | { | ||
668 | const u8 *unirom = adapter->fw->data; | ||
669 | int idx = cpu_to_le32(*((int *)&unirom[adapter->file_prd_off] + | ||
670 | idx_offset)); | ||
671 | struct uni_table_desc *tab_desc; | ||
672 | __le32 offs; | ||
673 | |||
674 | tab_desc = nx_get_table_desc(unirom, section); | ||
675 | |||
676 | if (tab_desc == NULL) | ||
677 | return NULL; | ||
678 | |||
679 | offs = cpu_to_le32(tab_desc->findex) + | ||
680 | (cpu_to_le32(tab_desc->entry_size) * idx); | ||
681 | |||
682 | return (struct uni_data_desc *)&unirom[offs]; | ||
683 | } | ||
684 | |||
685 | static u8 * | ||
686 | nx_get_bootld_offs(struct netxen_adapter *adapter) | ||
687 | { | ||
688 | u32 offs = NETXEN_BOOTLD_START; | ||
689 | |||
690 | if (adapter->fw_type == NX_UNIFIED_ROMIMAGE) | ||
691 | offs = cpu_to_le32((nx_get_data_desc(adapter, | ||
692 | NX_UNI_DIR_SECT_BOOTLD, | ||
693 | NX_UNI_BOOTLD_IDX_OFF))->findex); | ||
694 | |||
695 | return (u8 *)&adapter->fw->data[offs]; | ||
696 | } | ||
697 | |||
698 | static u8 * | ||
699 | nx_get_fw_offs(struct netxen_adapter *adapter) | ||
700 | { | ||
701 | u32 offs = NETXEN_IMAGE_START; | ||
702 | |||
703 | if (adapter->fw_type == NX_UNIFIED_ROMIMAGE) | ||
704 | offs = cpu_to_le32((nx_get_data_desc(adapter, | ||
705 | NX_UNI_DIR_SECT_FW, | ||
706 | NX_UNI_FIRMWARE_IDX_OFF))->findex); | ||
707 | |||
708 | return (u8 *)&adapter->fw->data[offs]; | ||
709 | } | ||
710 | |||
711 | static __le32 | ||
712 | nx_get_fw_size(struct netxen_adapter *adapter) | ||
713 | { | ||
714 | if (adapter->fw_type == NX_UNIFIED_ROMIMAGE) | ||
715 | return cpu_to_le32((nx_get_data_desc(adapter, | ||
716 | NX_UNI_DIR_SECT_FW, | ||
717 | NX_UNI_FIRMWARE_IDX_OFF))->size); | ||
718 | else | ||
719 | return cpu_to_le32( | ||
720 | *(u32 *)&adapter->fw->data[NX_FW_SIZE_OFFSET]); | ||
721 | } | ||
722 | |||
723 | static __le32 | ||
724 | nx_get_fw_version(struct netxen_adapter *adapter) | ||
725 | { | ||
726 | struct uni_data_desc *fw_data_desc; | ||
727 | const struct firmware *fw = adapter->fw; | ||
728 | __le32 major, minor, sub; | ||
729 | const u8 *ver_str; | ||
730 | int i, ret = 0; | ||
731 | |||
732 | if (adapter->fw_type == NX_UNIFIED_ROMIMAGE) { | ||
733 | |||
734 | fw_data_desc = nx_get_data_desc(adapter, | ||
735 | NX_UNI_DIR_SECT_FW, NX_UNI_FIRMWARE_IDX_OFF); | ||
736 | ver_str = fw->data + cpu_to_le32(fw_data_desc->findex) + | ||
737 | cpu_to_le32(fw_data_desc->size) - 17; | ||
738 | |||
739 | for (i = 0; i < 12; i++) { | ||
740 | if (!strncmp(&ver_str[i], "REV=", 4)) { | ||
741 | ret = sscanf(&ver_str[i+4], "%u.%u.%u ", | ||
742 | &major, &minor, &sub); | ||
743 | break; | ||
744 | } | ||
745 | } | ||
746 | |||
747 | if (ret != 3) | ||
748 | return 0; | ||
749 | |||
750 | return major + (minor << 8) + (sub << 16); | ||
751 | |||
752 | } else | ||
753 | return cpu_to_le32(*(u32 *)&fw->data[NX_FW_VERSION_OFFSET]); | ||
754 | } | ||
755 | |||
756 | static __le32 | ||
757 | nx_get_bios_version(struct netxen_adapter *adapter) | ||
758 | { | ||
759 | const struct firmware *fw = adapter->fw; | ||
760 | __le32 bios_ver, prd_off = adapter->file_prd_off; | ||
761 | |||
762 | if (adapter->fw_type == NX_UNIFIED_ROMIMAGE) { | ||
763 | bios_ver = cpu_to_le32(*((u32 *) (&fw->data[prd_off]) | ||
764 | + NX_UNI_BIOS_VERSION_OFF)); | ||
765 | return (bios_ver << 16) + ((bios_ver >> 8) & 0xff00) + | ||
766 | (bios_ver >> 24); | ||
767 | } else | ||
768 | return cpu_to_le32(*(u32 *)&fw->data[NX_BIOS_VERSION_OFFSET]); | ||
769 | |||
770 | } | ||
771 | |||
610 | int | 772 | int |
611 | netxen_need_fw_reset(struct netxen_adapter *adapter) | 773 | netxen_need_fw_reset(struct netxen_adapter *adapter) |
612 | { | 774 | { |
@@ -619,11 +781,14 @@ netxen_need_fw_reset(struct netxen_adapter *adapter) | |||
619 | if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) | 781 | if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) |
620 | return 1; | 782 | return 1; |
621 | 783 | ||
784 | if (adapter->need_fw_reset) | ||
785 | return 1; | ||
786 | |||
622 | /* last attempt had failed */ | 787 | /* last attempt had failed */ |
623 | if (NXRD32(adapter, CRB_CMDPEG_STATE) == PHAN_INITIALIZE_FAILED) | 788 | if (NXRD32(adapter, CRB_CMDPEG_STATE) == PHAN_INITIALIZE_FAILED) |
624 | return 1; | 789 | return 1; |
625 | 790 | ||
626 | old_count = count = NXRD32(adapter, NETXEN_PEG_ALIVE_COUNTER); | 791 | old_count = NXRD32(adapter, NETXEN_PEG_ALIVE_COUNTER); |
627 | 792 | ||
628 | for (i = 0; i < 10; i++) { | 793 | for (i = 0; i < 10; i++) { |
629 | 794 | ||
@@ -646,9 +811,8 @@ netxen_need_fw_reset(struct netxen_adapter *adapter) | |||
646 | /* check if we have got newer or different file firmware */ | 811 | /* check if we have got newer or different file firmware */ |
647 | if (adapter->fw) { | 812 | if (adapter->fw) { |
648 | 813 | ||
649 | const struct firmware *fw = adapter->fw; | 814 | val = nx_get_fw_version(adapter); |
650 | 815 | ||
651 | val = cpu_to_le32(*(u32 *)&fw->data[NX_FW_VERSION_OFFSET]); | ||
652 | version = NETXEN_DECODE_VERSION(val); | 816 | version = NETXEN_DECODE_VERSION(val); |
653 | 817 | ||
654 | major = NXRD32(adapter, NETXEN_FW_VERSION_MAJOR); | 818 | major = NXRD32(adapter, NETXEN_FW_VERSION_MAJOR); |
@@ -658,7 +822,8 @@ netxen_need_fw_reset(struct netxen_adapter *adapter) | |||
658 | if (version > NETXEN_VERSION_CODE(major, minor, build)) | 822 | if (version > NETXEN_VERSION_CODE(major, minor, build)) |
659 | return 1; | 823 | return 1; |
660 | 824 | ||
661 | if (version == NETXEN_VERSION_CODE(major, minor, build)) { | 825 | if (version == NETXEN_VERSION_CODE(major, minor, build) && |
826 | adapter->fw_type != NX_UNIFIED_ROMIMAGE) { | ||
662 | 827 | ||
663 | val = NXRD32(adapter, NETXEN_MIU_MN_CONTROL); | 828 | val = NXRD32(adapter, NETXEN_MIU_MN_CONTROL); |
664 | fw_type = (val & 0x4) ? | 829 | fw_type = (val & 0x4) ? |
@@ -673,7 +838,11 @@ netxen_need_fw_reset(struct netxen_adapter *adapter) | |||
673 | } | 838 | } |
674 | 839 | ||
675 | static char *fw_name[] = { | 840 | static char *fw_name[] = { |
676 | "nxromimg.bin", "nx3fwct.bin", "nx3fwmn.bin", "flash", | 841 | NX_P2_MN_ROMIMAGE_NAME, |
842 | NX_P3_CT_ROMIMAGE_NAME, | ||
843 | NX_P3_MN_ROMIMAGE_NAME, | ||
844 | NX_UNIFIED_ROMIMAGE_NAME, | ||
845 | NX_FLASH_ROMIMAGE_NAME, | ||
677 | }; | 846 | }; |
678 | 847 | ||
679 | int | 848 | int |
@@ -695,26 +864,28 @@ netxen_load_firmware(struct netxen_adapter *adapter) | |||
695 | 864 | ||
696 | size = (NETXEN_IMAGE_START - NETXEN_BOOTLD_START) / 8; | 865 | size = (NETXEN_IMAGE_START - NETXEN_BOOTLD_START) / 8; |
697 | 866 | ||
698 | ptr64 = (u64 *)&fw->data[NETXEN_BOOTLD_START]; | 867 | ptr64 = (u64 *)nx_get_bootld_offs(adapter); |
699 | flashaddr = NETXEN_BOOTLD_START; | 868 | flashaddr = NETXEN_BOOTLD_START; |
700 | 869 | ||
701 | for (i = 0; i < size; i++) { | 870 | for (i = 0; i < size; i++) { |
702 | data = cpu_to_le64(ptr64[i]); | 871 | data = cpu_to_le64(ptr64[i]); |
703 | adapter->pci_mem_write(adapter, flashaddr, &data, 8); | 872 | |
873 | if (adapter->pci_mem_write(adapter, flashaddr, data)) | ||
874 | return -EIO; | ||
875 | |||
704 | flashaddr += 8; | 876 | flashaddr += 8; |
705 | } | 877 | } |
706 | 878 | ||
707 | size = *(u32 *)&fw->data[NX_FW_SIZE_OFFSET]; | 879 | size = (__force u32)nx_get_fw_size(adapter) / 8; |
708 | size = (__force u32)cpu_to_le32(size) / 8; | ||
709 | 880 | ||
710 | ptr64 = (u64 *)&fw->data[NETXEN_IMAGE_START]; | 881 | ptr64 = (u64 *)nx_get_fw_offs(adapter); |
711 | flashaddr = NETXEN_IMAGE_START; | 882 | flashaddr = NETXEN_IMAGE_START; |
712 | 883 | ||
713 | for (i = 0; i < size; i++) { | 884 | for (i = 0; i < size; i++) { |
714 | data = cpu_to_le64(ptr64[i]); | 885 | data = cpu_to_le64(ptr64[i]); |
715 | 886 | ||
716 | if (adapter->pci_mem_write(adapter, | 887 | if (adapter->pci_mem_write(adapter, |
717 | flashaddr, &data, 8)) | 888 | flashaddr, data)) |
718 | return -EIO; | 889 | return -EIO; |
719 | 890 | ||
720 | flashaddr += 8; | 891 | flashaddr += 8; |
@@ -728,17 +899,17 @@ netxen_load_firmware(struct netxen_adapter *adapter) | |||
728 | 899 | ||
729 | for (i = 0; i < size; i++) { | 900 | for (i = 0; i < size; i++) { |
730 | if (netxen_rom_fast_read(adapter, | 901 | if (netxen_rom_fast_read(adapter, |
731 | flashaddr, &lo) != 0) | 902 | flashaddr, (int *)&lo) != 0) |
732 | return -EIO; | 903 | return -EIO; |
733 | if (netxen_rom_fast_read(adapter, | 904 | if (netxen_rom_fast_read(adapter, |
734 | flashaddr + 4, &hi) != 0) | 905 | flashaddr + 4, (int *)&hi) != 0) |
735 | return -EIO; | 906 | return -EIO; |
736 | 907 | ||
737 | /* hi, lo are already in host endian byteorder */ | 908 | /* hi, lo are already in host endian byteorder */ |
738 | data = (((u64)hi << 32) | lo); | 909 | data = (((u64)hi << 32) | lo); |
739 | 910 | ||
740 | if (adapter->pci_mem_write(adapter, | 911 | if (adapter->pci_mem_write(adapter, |
741 | flashaddr, &data, 8)) | 912 | flashaddr, data)) |
742 | return -EIO; | 913 | return -EIO; |
743 | 914 | ||
744 | flashaddr += 8; | 915 | flashaddr += 8; |
@@ -746,7 +917,10 @@ netxen_load_firmware(struct netxen_adapter *adapter) | |||
746 | } | 917 | } |
747 | msleep(1); | 918 | msleep(1); |
748 | 919 | ||
749 | if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) | 920 | if (NX_IS_REVISION_P3P(adapter->ahw.revision_id)) { |
921 | NXWR32(adapter, NETXEN_CRB_PEG_NET_0 + 0x18, 0x1020); | ||
922 | NXWR32(adapter, NETXEN_ROMUSB_GLB_SW_RESET, 0x80001e); | ||
923 | } else if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) | ||
750 | NXWR32(adapter, NETXEN_ROMUSB_GLB_SW_RESET, 0x80001d); | 924 | NXWR32(adapter, NETXEN_ROMUSB_GLB_SW_RESET, 0x80001d); |
751 | else { | 925 | else { |
752 | NXWR32(adapter, NETXEN_ROMUSB_GLB_CHIP_CLK_CTRL, 0x3fff); | 926 | NXWR32(adapter, NETXEN_ROMUSB_GLB_CHIP_CLK_CTRL, 0x3fff); |
@@ -757,21 +931,31 @@ netxen_load_firmware(struct netxen_adapter *adapter) | |||
757 | } | 931 | } |
758 | 932 | ||
759 | static int | 933 | static int |
760 | netxen_validate_firmware(struct netxen_adapter *adapter, const char *fwname) | 934 | netxen_validate_firmware(struct netxen_adapter *adapter) |
761 | { | 935 | { |
762 | __le32 val; | 936 | __le32 val; |
763 | u32 ver, min_ver, bios; | 937 | u32 ver, min_ver, bios, min_size; |
764 | struct pci_dev *pdev = adapter->pdev; | 938 | struct pci_dev *pdev = adapter->pdev; |
765 | const struct firmware *fw = adapter->fw; | 939 | const struct firmware *fw = adapter->fw; |
940 | u8 fw_type = adapter->fw_type; | ||
766 | 941 | ||
767 | if (fw->size < NX_FW_MIN_SIZE) | 942 | if (fw_type == NX_UNIFIED_ROMIMAGE) { |
768 | return -EINVAL; | 943 | if (nx_set_product_offs(adapter)) |
944 | return -EINVAL; | ||
769 | 945 | ||
770 | val = cpu_to_le32(*(u32 *)&fw->data[NX_FW_MAGIC_OFFSET]); | 946 | min_size = NX_UNI_FW_MIN_SIZE; |
771 | if ((__force u32)val != NETXEN_BDINFO_MAGIC) | 947 | } else { |
948 | val = cpu_to_le32(*(u32 *)&fw->data[NX_FW_MAGIC_OFFSET]); | ||
949 | if ((__force u32)val != NETXEN_BDINFO_MAGIC) | ||
950 | return -EINVAL; | ||
951 | |||
952 | min_size = NX_FW_MIN_SIZE; | ||
953 | } | ||
954 | |||
955 | if (fw->size < min_size) | ||
772 | return -EINVAL; | 956 | return -EINVAL; |
773 | 957 | ||
774 | val = cpu_to_le32(*(u32 *)&fw->data[NX_FW_VERSION_OFFSET]); | 958 | val = nx_get_fw_version(adapter); |
775 | 959 | ||
776 | if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) | 960 | if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) |
777 | min_ver = NETXEN_VERSION_CODE(4, 0, 216); | 961 | min_ver = NETXEN_VERSION_CODE(4, 0, 216); |
@@ -783,15 +967,15 @@ netxen_validate_firmware(struct netxen_adapter *adapter, const char *fwname) | |||
783 | if ((_major(ver) > _NETXEN_NIC_LINUX_MAJOR) || (ver < min_ver)) { | 967 | if ((_major(ver) > _NETXEN_NIC_LINUX_MAJOR) || (ver < min_ver)) { |
784 | dev_err(&pdev->dev, | 968 | dev_err(&pdev->dev, |
785 | "%s: firmware version %d.%d.%d unsupported\n", | 969 | "%s: firmware version %d.%d.%d unsupported\n", |
786 | fwname, _major(ver), _minor(ver), _build(ver)); | 970 | fw_name[fw_type], _major(ver), _minor(ver), _build(ver)); |
787 | return -EINVAL; | 971 | return -EINVAL; |
788 | } | 972 | } |
789 | 973 | ||
790 | val = cpu_to_le32(*(u32 *)&fw->data[NX_BIOS_VERSION_OFFSET]); | 974 | val = nx_get_bios_version(adapter); |
791 | netxen_rom_fast_read(adapter, NX_BIOS_VERSION_OFFSET, (int *)&bios); | 975 | netxen_rom_fast_read(adapter, NX_BIOS_VERSION_OFFSET, (int *)&bios); |
792 | if ((__force u32)val != bios) { | 976 | if ((__force u32)val != bios) { |
793 | dev_err(&pdev->dev, "%s: firmware bios is incompatible\n", | 977 | dev_err(&pdev->dev, "%s: firmware bios is incompatible\n", |
794 | fwname); | 978 | fw_name[fw_type]); |
795 | return -EINVAL; | 979 | return -EINVAL; |
796 | } | 980 | } |
797 | 981 | ||
@@ -802,7 +986,7 @@ netxen_validate_firmware(struct netxen_adapter *adapter, const char *fwname) | |||
802 | val = NETXEN_DECODE_VERSION(val); | 986 | val = NETXEN_DECODE_VERSION(val); |
803 | if (val > ver) { | 987 | if (val > ver) { |
804 | dev_info(&pdev->dev, "%s: firmware is older than flash\n", | 988 | dev_info(&pdev->dev, "%s: firmware is older than flash\n", |
805 | fwname); | 989 | fw_name[fw_type]); |
806 | return -EINVAL; | 990 | return -EINVAL; |
807 | } | 991 | } |
808 | 992 | ||
@@ -810,12 +994,51 @@ netxen_validate_firmware(struct netxen_adapter *adapter, const char *fwname) | |||
810 | return 0; | 994 | return 0; |
811 | } | 995 | } |
812 | 996 | ||
997 | static void | ||
998 | nx_get_next_fwtype(struct netxen_adapter *adapter) | ||
999 | { | ||
1000 | u8 fw_type; | ||
1001 | |||
1002 | switch (adapter->fw_type) { | ||
1003 | case NX_UNKNOWN_ROMIMAGE: | ||
1004 | fw_type = NX_UNIFIED_ROMIMAGE; | ||
1005 | break; | ||
1006 | |||
1007 | case NX_UNIFIED_ROMIMAGE: | ||
1008 | if (NX_IS_REVISION_P3P(adapter->ahw.revision_id)) | ||
1009 | fw_type = NX_FLASH_ROMIMAGE; | ||
1010 | else if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) | ||
1011 | fw_type = NX_P2_MN_ROMIMAGE; | ||
1012 | else if (netxen_p3_has_mn(adapter)) | ||
1013 | fw_type = NX_P3_MN_ROMIMAGE; | ||
1014 | else | ||
1015 | fw_type = NX_P3_CT_ROMIMAGE; | ||
1016 | break; | ||
1017 | |||
1018 | case NX_P3_MN_ROMIMAGE: | ||
1019 | fw_type = NX_P3_CT_ROMIMAGE; | ||
1020 | break; | ||
1021 | |||
1022 | case NX_P2_MN_ROMIMAGE: | ||
1023 | case NX_P3_CT_ROMIMAGE: | ||
1024 | default: | ||
1025 | fw_type = NX_FLASH_ROMIMAGE; | ||
1026 | break; | ||
1027 | } | ||
1028 | |||
1029 | adapter->fw_type = fw_type; | ||
1030 | } | ||
1031 | |||
813 | static int | 1032 | static int |
814 | netxen_p3_has_mn(struct netxen_adapter *adapter) | 1033 | netxen_p3_has_mn(struct netxen_adapter *adapter) |
815 | { | 1034 | { |
816 | u32 capability, flashed_ver; | 1035 | u32 capability, flashed_ver; |
817 | capability = 0; | 1036 | capability = 0; |
818 | 1037 | ||
1038 | /* NX2031 always had MN */ | ||
1039 | if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) | ||
1040 | return 1; | ||
1041 | |||
819 | netxen_rom_fast_read(adapter, | 1042 | netxen_rom_fast_read(adapter, |
820 | NX_FW_VERSION_OFFSET, (int *)&flashed_ver); | 1043 | NX_FW_VERSION_OFFSET, (int *)&flashed_ver); |
821 | flashed_ver = NETXEN_DECODE_VERSION(flashed_ver); | 1044 | flashed_ver = NETXEN_DECODE_VERSION(flashed_ver); |
@@ -831,49 +1054,29 @@ netxen_p3_has_mn(struct netxen_adapter *adapter) | |||
831 | 1054 | ||
832 | void netxen_request_firmware(struct netxen_adapter *adapter) | 1055 | void netxen_request_firmware(struct netxen_adapter *adapter) |
833 | { | 1056 | { |
834 | u8 fw_type; | ||
835 | struct pci_dev *pdev = adapter->pdev; | 1057 | struct pci_dev *pdev = adapter->pdev; |
836 | int rc = 0; | 1058 | int rc = 0; |
837 | 1059 | ||
838 | if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) { | 1060 | adapter->fw_type = NX_UNKNOWN_ROMIMAGE; |
839 | fw_type = NX_P2_MN_ROMIMAGE; | ||
840 | goto request_fw; | ||
841 | } | ||
842 | 1061 | ||
843 | fw_type = netxen_p3_has_mn(adapter) ? | 1062 | next: |
844 | NX_P3_MN_ROMIMAGE : NX_P3_CT_ROMIMAGE; | 1063 | nx_get_next_fwtype(adapter); |
845 | 1064 | ||
846 | request_fw: | 1065 | if (adapter->fw_type == NX_FLASH_ROMIMAGE) { |
847 | rc = request_firmware(&adapter->fw, fw_name[fw_type], &pdev->dev); | ||
848 | if (rc != 0) { | ||
849 | if (fw_type == NX_P3_MN_ROMIMAGE) { | ||
850 | msleep(1); | ||
851 | fw_type = NX_P3_CT_ROMIMAGE; | ||
852 | goto request_fw; | ||
853 | } | ||
854 | |||
855 | fw_type = NX_FLASH_ROMIMAGE; | ||
856 | adapter->fw = NULL; | 1066 | adapter->fw = NULL; |
857 | goto done; | 1067 | } else { |
858 | } | 1068 | rc = request_firmware(&adapter->fw, |
859 | 1069 | fw_name[adapter->fw_type], &pdev->dev); | |
860 | rc = netxen_validate_firmware(adapter, fw_name[fw_type]); | 1070 | if (rc != 0) |
861 | if (rc != 0) { | 1071 | goto next; |
862 | release_firmware(adapter->fw); | 1072 | |
863 | 1073 | rc = netxen_validate_firmware(adapter); | |
864 | if (fw_type == NX_P3_MN_ROMIMAGE) { | 1074 | if (rc != 0) { |
1075 | release_firmware(adapter->fw); | ||
865 | msleep(1); | 1076 | msleep(1); |
866 | fw_type = NX_P3_CT_ROMIMAGE; | 1077 | goto next; |
867 | goto request_fw; | ||
868 | } | 1078 | } |
869 | |||
870 | fw_type = NX_FLASH_ROMIMAGE; | ||
871 | adapter->fw = NULL; | ||
872 | goto done; | ||
873 | } | 1079 | } |
874 | |||
875 | done: | ||
876 | adapter->fw_type = fw_type; | ||
877 | } | 1080 | } |
878 | 1081 | ||
879 | 1082 | ||
@@ -1508,10 +1711,8 @@ netxen_post_rx_buffers(struct netxen_adapter *adapter, u32 ringid, | |||
1508 | (rds_ring->num_desc - 1))); | 1711 | (rds_ring->num_desc - 1))); |
1509 | netxen_set_msg_ctxid(msg, adapter->portnum); | 1712 | netxen_set_msg_ctxid(msg, adapter->portnum); |
1510 | netxen_set_msg_opcode(msg, NETXEN_RCV_PRODUCER(ringid)); | 1713 | netxen_set_msg_opcode(msg, NETXEN_RCV_PRODUCER(ringid)); |
1511 | read_lock(&adapter->adapter_lock); | 1714 | NXWRIO(adapter, DB_NORMALIZE(adapter, |
1512 | writel(msg, DB_NORMALIZE(adapter, | 1715 | NETXEN_RCV_PRODUCER_OFFSET), msg); |
1513 | NETXEN_RCV_PRODUCER_OFFSET)); | ||
1514 | read_unlock(&adapter->adapter_lock); | ||
1515 | } | 1716 | } |
1516 | } | 1717 | } |
1517 | } | 1718 | } |