diff options
Diffstat (limited to 'drivers/net/netxen')
-rw-r--r-- | drivers/net/netxen/netxen_nic.h | 22 | ||||
-rw-r--r-- | drivers/net/netxen/netxen_nic_ctx.c | 13 | ||||
-rw-r--r-- | drivers/net/netxen/netxen_nic_hdr.h | 1 | ||||
-rw-r--r-- | drivers/net/netxen/netxen_nic_hw.c | 9 | ||||
-rw-r--r-- | drivers/net/netxen/netxen_nic_init.c | 116 | ||||
-rw-r--r-- | drivers/net/netxen/netxen_nic_main.c | 170 |
6 files changed, 239 insertions, 92 deletions
diff --git a/drivers/net/netxen/netxen_nic.h b/drivers/net/netxen/netxen_nic.h index 970cedeb5f37..a9c1fcca5e75 100644 --- a/drivers/net/netxen/netxen_nic.h +++ b/drivers/net/netxen/netxen_nic.h | |||
@@ -60,7 +60,18 @@ | |||
60 | #define _NETXEN_NIC_LINUX_SUBVERSION 30 | 60 | #define _NETXEN_NIC_LINUX_SUBVERSION 30 |
61 | #define NETXEN_NIC_LINUX_VERSIONID "4.0.30" | 61 | #define NETXEN_NIC_LINUX_VERSIONID "4.0.30" |
62 | 62 | ||
63 | #define NETXEN_VERSION_CODE(a, b, c) (((a) << 16) + ((b) << 8) + (c)) | 63 | #define NETXEN_VERSION_CODE(a, b, c) (((a) << 24) + ((b) << 16) + (c)) |
64 | #define _major(v) (((v) >> 24) & 0xff) | ||
65 | #define _minor(v) (((v) >> 16) & 0xff) | ||
66 | #define _build(v) ((v) & 0xffff) | ||
67 | |||
68 | /* version in image has weird encoding: | ||
69 | * 7:0 - major | ||
70 | * 15:8 - minor | ||
71 | * 31:16 - build (little endian) | ||
72 | */ | ||
73 | #define NETXEN_DECODE_VERSION(v) \ | ||
74 | NETXEN_VERSION_CODE(((v) & 0xff), (((v) >> 8) & 0xff), ((v) >> 16)) | ||
64 | 75 | ||
65 | #define NETXEN_NUM_FLASH_SECTORS (64) | 76 | #define NETXEN_NUM_FLASH_SECTORS (64) |
66 | #define NETXEN_FLASH_SECTOR_SIZE (64 * 1024) | 77 | #define NETXEN_FLASH_SECTOR_SIZE (64 * 1024) |
@@ -199,6 +210,7 @@ | |||
199 | #define NETXEN_CTX_SIGNATURE 0xdee0 | 210 | #define NETXEN_CTX_SIGNATURE 0xdee0 |
200 | #define NETXEN_CTX_SIGNATURE_V2 0x0002dee0 | 211 | #define NETXEN_CTX_SIGNATURE_V2 0x0002dee0 |
201 | #define NETXEN_CTX_RESET 0xbad0 | 212 | #define NETXEN_CTX_RESET 0xbad0 |
213 | #define NETXEN_CTX_D3_RESET 0xacc0 | ||
202 | #define NETXEN_RCV_PRODUCER(ringid) (ringid) | 214 | #define NETXEN_RCV_PRODUCER(ringid) (ringid) |
203 | 215 | ||
204 | #define PHAN_PEG_RCV_INITIALIZED 0xff01 | 216 | #define PHAN_PEG_RCV_INITIALIZED 0xff01 |
@@ -614,6 +626,7 @@ struct netxen_new_user_info { | |||
614 | #define NX_P2_MN_ROMIMAGE 0 | 626 | #define NX_P2_MN_ROMIMAGE 0 |
615 | #define NX_P3_CT_ROMIMAGE 1 | 627 | #define NX_P3_CT_ROMIMAGE 1 |
616 | #define NX_P3_MN_ROMIMAGE 2 | 628 | #define NX_P3_MN_ROMIMAGE 2 |
629 | #define NX_FLASH_ROMIMAGE 3 | ||
617 | 630 | ||
618 | #define NETXEN_USER_START_OLD NETXEN_PXE_START /* for backward compatibility */ | 631 | #define NETXEN_USER_START_OLD NETXEN_PXE_START /* for backward compatibility */ |
619 | 632 | ||
@@ -761,6 +774,8 @@ struct nx_host_tx_ring { | |||
761 | u32 crb_cmd_consumer; | 774 | u32 crb_cmd_consumer; |
762 | u32 num_desc; | 775 | u32 num_desc; |
763 | 776 | ||
777 | struct netdev_queue *txq; | ||
778 | |||
764 | struct netxen_cmd_buffer *cmd_buf_arr; | 779 | struct netxen_cmd_buffer *cmd_buf_arr; |
765 | struct cmd_desc_type0 *desc_head; | 780 | struct cmd_desc_type0 *desc_head; |
766 | dma_addr_t phys_addr; | 781 | dma_addr_t phys_addr; |
@@ -1239,11 +1254,11 @@ struct netxen_adapter { | |||
1239 | u8 mc_enabled; | 1254 | u8 mc_enabled; |
1240 | u8 max_mc_count; | 1255 | u8 max_mc_count; |
1241 | u8 rss_supported; | 1256 | u8 rss_supported; |
1242 | u8 resv2; | 1257 | u8 link_changed; |
1243 | u32 resv3; | 1258 | u32 resv3; |
1244 | 1259 | ||
1245 | u8 has_link_events; | 1260 | u8 has_link_events; |
1246 | u8 resv1; | 1261 | u8 fw_type; |
1247 | u16 tx_context_id; | 1262 | u16 tx_context_id; |
1248 | u16 mtu; | 1263 | u16 mtu; |
1249 | u16 is_up; | 1264 | u16 is_up; |
@@ -1387,6 +1402,7 @@ void netxen_free_adapter_offload(struct netxen_adapter *adapter); | |||
1387 | int netxen_initialize_adapter_offload(struct netxen_adapter *adapter); | 1402 | int netxen_initialize_adapter_offload(struct netxen_adapter *adapter); |
1388 | int netxen_phantom_init(struct netxen_adapter *adapter, int pegtune_val); | 1403 | int netxen_phantom_init(struct netxen_adapter *adapter, int pegtune_val); |
1389 | int netxen_load_firmware(struct netxen_adapter *adapter); | 1404 | int netxen_load_firmware(struct netxen_adapter *adapter); |
1405 | int netxen_need_fw_reset(struct netxen_adapter *adapter); | ||
1390 | void netxen_request_firmware(struct netxen_adapter *adapter); | 1406 | void netxen_request_firmware(struct netxen_adapter *adapter); |
1391 | void netxen_release_firmware(struct netxen_adapter *adapter); | 1407 | void netxen_release_firmware(struct netxen_adapter *adapter); |
1392 | int netxen_pinit_from_rom(struct netxen_adapter *adapter, int verbose); | 1408 | int netxen_pinit_from_rom(struct netxen_adapter *adapter, int verbose); |
diff --git a/drivers/net/netxen/netxen_nic_ctx.c b/drivers/net/netxen/netxen_nic_ctx.c index 4754f5cffad0..9f8ae4719e2f 100644 --- a/drivers/net/netxen/netxen_nic_ctx.c +++ b/drivers/net/netxen/netxen_nic_ctx.c | |||
@@ -684,10 +684,8 @@ int netxen_alloc_hw_resources(struct netxen_adapter *adapter) | |||
684 | goto err_out_free; | 684 | goto err_out_free; |
685 | } else { | 685 | } else { |
686 | err = netxen_init_old_ctx(adapter); | 686 | err = netxen_init_old_ctx(adapter); |
687 | if (err) { | 687 | if (err) |
688 | netxen_free_hw_resources(adapter); | 688 | goto err_out_free; |
689 | return err; | ||
690 | } | ||
691 | } | 689 | } |
692 | 690 | ||
693 | return 0; | 691 | return 0; |
@@ -708,15 +706,18 @@ void netxen_free_hw_resources(struct netxen_adapter *adapter) | |||
708 | int port = adapter->portnum; | 706 | int port = adapter->portnum; |
709 | 707 | ||
710 | if (adapter->fw_major >= 4) { | 708 | if (adapter->fw_major >= 4) { |
711 | nx_fw_cmd_destroy_tx_ctx(adapter); | ||
712 | nx_fw_cmd_destroy_rx_ctx(adapter); | 709 | nx_fw_cmd_destroy_rx_ctx(adapter); |
710 | nx_fw_cmd_destroy_tx_ctx(adapter); | ||
713 | } else { | 711 | } else { |
714 | netxen_api_lock(adapter); | 712 | netxen_api_lock(adapter); |
715 | NXWR32(adapter, CRB_CTX_SIGNATURE_REG(port), | 713 | NXWR32(adapter, CRB_CTX_SIGNATURE_REG(port), |
716 | NETXEN_CTX_RESET | port); | 714 | NETXEN_CTX_D3_RESET | port); |
717 | netxen_api_unlock(adapter); | 715 | netxen_api_unlock(adapter); |
718 | } | 716 | } |
719 | 717 | ||
718 | /* Allow dma queues to drain after context reset */ | ||
719 | msleep(20); | ||
720 | |||
720 | recv_ctx = &adapter->recv_ctx; | 721 | recv_ctx = &adapter->recv_ctx; |
721 | 722 | ||
722 | if (recv_ctx->hwctx != NULL) { | 723 | if (recv_ctx->hwctx != NULL) { |
diff --git a/drivers/net/netxen/netxen_nic_hdr.h b/drivers/net/netxen/netxen_nic_hdr.h index 3cc047844af3..824103675648 100644 --- a/drivers/net/netxen/netxen_nic_hdr.h +++ b/drivers/net/netxen/netxen_nic_hdr.h | |||
@@ -853,6 +853,7 @@ enum { | |||
853 | #define NX_PEG_TUNE_CAPABILITY (NETXEN_CAM_RAM(0x02c)) | 853 | #define NX_PEG_TUNE_CAPABILITY (NETXEN_CAM_RAM(0x02c)) |
854 | 854 | ||
855 | #define NETXEN_CAM_RAM_DMA_WATCHDOG_CTRL (0x14) | 855 | #define NETXEN_CAM_RAM_DMA_WATCHDOG_CTRL (0x14) |
856 | #define NETXEN_PEG_ALIVE_COUNTER (NETXEN_CAM_RAM(0xb0)) | ||
856 | 857 | ||
857 | #define ISR_MSI_INT_TRIGGER(FUNC) (NETXEN_PCIX_PS_REG(PCIX_MSI_F(FUNC))) | 858 | #define ISR_MSI_INT_TRIGGER(FUNC) (NETXEN_PCIX_PS_REG(PCIX_MSI_F(FUNC))) |
858 | #define ISR_LEGACY_INT_TRIGGERED(VAL) (((VAL) & 0x300) == 0x200) | 859 | #define ISR_LEGACY_INT_TRIGGERED(VAL) (((VAL) & 0x300) == 0x200) |
diff --git a/drivers/net/netxen/netxen_nic_hw.c b/drivers/net/netxen/netxen_nic_hw.c index ce3b89d2cbb6..b9123d445c96 100644 --- a/drivers/net/netxen/netxen_nic_hw.c +++ b/drivers/net/netxen/netxen_nic_hw.c | |||
@@ -461,13 +461,14 @@ netxen_send_cmd_descs(struct netxen_adapter *adapter, | |||
461 | i = 0; | 461 | i = 0; |
462 | 462 | ||
463 | tx_ring = adapter->tx_ring; | 463 | tx_ring = adapter->tx_ring; |
464 | netif_tx_lock_bh(adapter->netdev); | 464 | __netif_tx_lock_bh(tx_ring->txq); |
465 | 465 | ||
466 | producer = tx_ring->producer; | 466 | producer = tx_ring->producer; |
467 | consumer = tx_ring->sw_consumer; | 467 | consumer = tx_ring->sw_consumer; |
468 | 468 | ||
469 | if (nr_desc >= find_diff_among(producer, consumer, tx_ring->num_desc)) { | 469 | if (nr_desc >= netxen_tx_avail(tx_ring)) { |
470 | netif_tx_unlock_bh(adapter->netdev); | 470 | netif_tx_stop_queue(tx_ring->txq); |
471 | __netif_tx_unlock_bh(tx_ring->txq); | ||
471 | return -EBUSY; | 472 | return -EBUSY; |
472 | } | 473 | } |
473 | 474 | ||
@@ -490,7 +491,7 @@ netxen_send_cmd_descs(struct netxen_adapter *adapter, | |||
490 | 491 | ||
491 | netxen_nic_update_cmd_producer(adapter, tx_ring); | 492 | netxen_nic_update_cmd_producer(adapter, tx_ring); |
492 | 493 | ||
493 | netif_tx_unlock_bh(adapter->netdev); | 494 | __netif_tx_unlock_bh(tx_ring->txq); |
494 | 495 | ||
495 | return 0; | 496 | return 0; |
496 | } | 497 | } |
diff --git a/drivers/net/netxen/netxen_nic_init.c b/drivers/net/netxen/netxen_nic_init.c index 055bb61d6e77..5d3343ef3d86 100644 --- a/drivers/net/netxen/netxen_nic_init.c +++ b/drivers/net/netxen/netxen_nic_init.c | |||
@@ -214,6 +214,7 @@ int netxen_alloc_sw_resources(struct netxen_adapter *adapter) | |||
214 | adapter->tx_ring = tx_ring; | 214 | adapter->tx_ring = tx_ring; |
215 | 215 | ||
216 | tx_ring->num_desc = adapter->num_txd; | 216 | tx_ring->num_desc = adapter->num_txd; |
217 | tx_ring->txq = netdev_get_tx_queue(netdev, 0); | ||
217 | 218 | ||
218 | cmd_buf_arr = vmalloc(TX_BUFF_RINGSIZE(tx_ring)); | 219 | cmd_buf_arr = vmalloc(TX_BUFF_RINGSIZE(tx_ring)); |
219 | if (cmd_buf_arr == NULL) { | 220 | if (cmd_buf_arr == NULL) { |
@@ -684,11 +685,84 @@ int netxen_pinit_from_rom(struct netxen_adapter *adapter, int verbose) | |||
684 | } | 685 | } |
685 | 686 | ||
686 | int | 687 | int |
688 | netxen_need_fw_reset(struct netxen_adapter *adapter) | ||
689 | { | ||
690 | u32 count, old_count; | ||
691 | u32 val, version, major, minor, build; | ||
692 | int i, timeout; | ||
693 | u8 fw_type; | ||
694 | |||
695 | /* NX2031 firmware doesn't support heartbit */ | ||
696 | if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) | ||
697 | return 1; | ||
698 | |||
699 | /* last attempt had failed */ | ||
700 | if (NXRD32(adapter, CRB_CMDPEG_STATE) == PHAN_INITIALIZE_FAILED) | ||
701 | return 1; | ||
702 | |||
703 | old_count = count = NXRD32(adapter, NETXEN_PEG_ALIVE_COUNTER); | ||
704 | |||
705 | for (i = 0; i < 10; i++) { | ||
706 | |||
707 | timeout = msleep_interruptible(200); | ||
708 | if (timeout) { | ||
709 | NXWR32(adapter, CRB_CMDPEG_STATE, | ||
710 | PHAN_INITIALIZE_FAILED); | ||
711 | return -EINTR; | ||
712 | } | ||
713 | |||
714 | count = NXRD32(adapter, NETXEN_PEG_ALIVE_COUNTER); | ||
715 | if (count != old_count) | ||
716 | break; | ||
717 | } | ||
718 | |||
719 | /* firmware is dead */ | ||
720 | if (count == old_count) | ||
721 | return 1; | ||
722 | |||
723 | /* check if we have got newer or different file firmware */ | ||
724 | if (adapter->fw) { | ||
725 | |||
726 | const struct firmware *fw = adapter->fw; | ||
727 | |||
728 | val = cpu_to_le32(*(u32 *)&fw->data[NX_FW_VERSION_OFFSET]); | ||
729 | version = NETXEN_DECODE_VERSION(val); | ||
730 | |||
731 | major = NXRD32(adapter, NETXEN_FW_VERSION_MAJOR); | ||
732 | minor = NXRD32(adapter, NETXEN_FW_VERSION_MINOR); | ||
733 | build = NXRD32(adapter, NETXEN_FW_VERSION_SUB); | ||
734 | |||
735 | if (version > NETXEN_VERSION_CODE(major, minor, build)) | ||
736 | return 1; | ||
737 | |||
738 | if (version == NETXEN_VERSION_CODE(major, minor, build)) { | ||
739 | |||
740 | val = NXRD32(adapter, NETXEN_MIU_MN_CONTROL); | ||
741 | fw_type = (val & 0x4) ? | ||
742 | NX_P3_CT_ROMIMAGE : NX_P3_MN_ROMIMAGE; | ||
743 | |||
744 | if (adapter->fw_type != fw_type) | ||
745 | return 1; | ||
746 | } | ||
747 | } | ||
748 | |||
749 | return 0; | ||
750 | } | ||
751 | |||
752 | static char *fw_name[] = { | ||
753 | "nxromimg.bin", "nx3fwct.bin", "nx3fwmn.bin", "flash", | ||
754 | }; | ||
755 | |||
756 | int | ||
687 | netxen_load_firmware(struct netxen_adapter *adapter) | 757 | netxen_load_firmware(struct netxen_adapter *adapter) |
688 | { | 758 | { |
689 | u64 *ptr64; | 759 | u64 *ptr64; |
690 | u32 i, flashaddr, size; | 760 | u32 i, flashaddr, size; |
691 | const struct firmware *fw = adapter->fw; | 761 | const struct firmware *fw = adapter->fw; |
762 | struct pci_dev *pdev = adapter->pdev; | ||
763 | |||
764 | dev_info(&pdev->dev, "loading firmware from %s\n", | ||
765 | fw_name[adapter->fw_type]); | ||
692 | 766 | ||
693 | if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) | 767 | if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) |
694 | NXWR32(adapter, NETXEN_ROMUSB_GLB_CAS_RST, 1); | 768 | NXWR32(adapter, NETXEN_ROMUSB_GLB_CAS_RST, 1); |
@@ -756,7 +830,7 @@ static int | |||
756 | netxen_validate_firmware(struct netxen_adapter *adapter, const char *fwname) | 830 | netxen_validate_firmware(struct netxen_adapter *adapter, const char *fwname) |
757 | { | 831 | { |
758 | __le32 val; | 832 | __le32 val; |
759 | u32 major, minor, build, ver, min_ver, bios; | 833 | u32 ver, min_ver, bios; |
760 | struct pci_dev *pdev = adapter->pdev; | 834 | struct pci_dev *pdev = adapter->pdev; |
761 | const struct firmware *fw = adapter->fw; | 835 | const struct firmware *fw = adapter->fw; |
762 | 836 | ||
@@ -768,21 +842,18 @@ netxen_validate_firmware(struct netxen_adapter *adapter, const char *fwname) | |||
768 | return -EINVAL; | 842 | return -EINVAL; |
769 | 843 | ||
770 | val = cpu_to_le32(*(u32 *)&fw->data[NX_FW_VERSION_OFFSET]); | 844 | val = cpu_to_le32(*(u32 *)&fw->data[NX_FW_VERSION_OFFSET]); |
771 | major = (__force u32)val & 0xff; | ||
772 | minor = ((__force u32)val >> 8) & 0xff; | ||
773 | build = (__force u32)val >> 16; | ||
774 | 845 | ||
775 | if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) | 846 | if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) |
776 | min_ver = NETXEN_VERSION_CODE(4, 0, 216); | 847 | min_ver = NETXEN_VERSION_CODE(4, 0, 216); |
777 | else | 848 | else |
778 | min_ver = NETXEN_VERSION_CODE(3, 4, 216); | 849 | min_ver = NETXEN_VERSION_CODE(3, 4, 216); |
779 | 850 | ||
780 | ver = NETXEN_VERSION_CODE(major, minor, build); | 851 | ver = NETXEN_DECODE_VERSION(val); |
781 | 852 | ||
782 | if ((major > _NETXEN_NIC_LINUX_MAJOR) || (ver < min_ver)) { | 853 | if ((_major(ver) > _NETXEN_NIC_LINUX_MAJOR) || (ver < min_ver)) { |
783 | dev_err(&pdev->dev, | 854 | dev_err(&pdev->dev, |
784 | "%s: firmware version %d.%d.%d unsupported\n", | 855 | "%s: firmware version %d.%d.%d unsupported\n", |
785 | fwname, major, minor, build); | 856 | fwname, _major(ver), _minor(ver), _build(ver)); |
786 | return -EINVAL; | 857 | return -EINVAL; |
787 | } | 858 | } |
788 | 859 | ||
@@ -798,22 +869,21 @@ netxen_validate_firmware(struct netxen_adapter *adapter, const char *fwname) | |||
798 | if (netxen_rom_fast_read(adapter, | 869 | if (netxen_rom_fast_read(adapter, |
799 | NX_FW_VERSION_OFFSET, (int *)&val)) | 870 | NX_FW_VERSION_OFFSET, (int *)&val)) |
800 | return -EIO; | 871 | return -EIO; |
801 | major = (__force u32)val & 0xff; | 872 | val = NETXEN_DECODE_VERSION(val); |
802 | minor = ((__force u32)val >> 8) & 0xff; | 873 | if (val > ver) { |
803 | build = (__force u32)val >> 16; | 874 | dev_info(&pdev->dev, "%s: firmware is older than flash\n", |
804 | if (NETXEN_VERSION_CODE(major, minor, build) > ver) | 875 | fwname); |
805 | return -EINVAL; | 876 | return -EINVAL; |
877 | } | ||
806 | 878 | ||
807 | NXWR32(adapter, NETXEN_CAM_RAM(0x1fc), NETXEN_BDINFO_MAGIC); | 879 | NXWR32(adapter, NETXEN_CAM_RAM(0x1fc), NETXEN_BDINFO_MAGIC); |
808 | return 0; | 880 | return 0; |
809 | } | 881 | } |
810 | 882 | ||
811 | static char *fw_name[] = { "nxromimg.bin", "nx3fwct.bin", "nx3fwmn.bin" }; | ||
812 | |||
813 | void netxen_request_firmware(struct netxen_adapter *adapter) | 883 | void netxen_request_firmware(struct netxen_adapter *adapter) |
814 | { | 884 | { |
815 | u32 capability, flashed_ver; | 885 | u32 capability, flashed_ver; |
816 | int fw_type; | 886 | u8 fw_type; |
817 | struct pci_dev *pdev = adapter->pdev; | 887 | struct pci_dev *pdev = adapter->pdev; |
818 | int rc = 0; | 888 | int rc = 0; |
819 | 889 | ||
@@ -830,6 +900,8 @@ request_mn: | |||
830 | 900 | ||
831 | netxen_rom_fast_read(adapter, | 901 | netxen_rom_fast_read(adapter, |
832 | NX_FW_VERSION_OFFSET, (int *)&flashed_ver); | 902 | NX_FW_VERSION_OFFSET, (int *)&flashed_ver); |
903 | flashed_ver = NETXEN_DECODE_VERSION(flashed_ver); | ||
904 | |||
833 | if (flashed_ver >= NETXEN_VERSION_CODE(4, 0, 220)) { | 905 | if (flashed_ver >= NETXEN_VERSION_CODE(4, 0, 220)) { |
834 | capability = NXRD32(adapter, NX_PEG_TUNE_CAPABILITY); | 906 | capability = NXRD32(adapter, NX_PEG_TUNE_CAPABILITY); |
835 | if (capability & NX_PEG_TUNE_MN_PRESENT) { | 907 | if (capability & NX_PEG_TUNE_MN_PRESENT) { |
@@ -838,6 +910,10 @@ request_mn: | |||
838 | } | 910 | } |
839 | } | 911 | } |
840 | 912 | ||
913 | fw_type = NX_FLASH_ROMIMAGE; | ||
914 | adapter->fw = NULL; | ||
915 | goto done; | ||
916 | |||
841 | request_fw: | 917 | request_fw: |
842 | rc = request_firmware(&adapter->fw, fw_name[fw_type], &pdev->dev); | 918 | rc = request_firmware(&adapter->fw, fw_name[fw_type], &pdev->dev); |
843 | if (rc != 0) { | 919 | if (rc != 0) { |
@@ -846,6 +922,7 @@ request_fw: | |||
846 | goto request_mn; | 922 | goto request_mn; |
847 | } | 923 | } |
848 | 924 | ||
925 | fw_type = NX_FLASH_ROMIMAGE; | ||
849 | adapter->fw = NULL; | 926 | adapter->fw = NULL; |
850 | goto done; | 927 | goto done; |
851 | } | 928 | } |
@@ -859,16 +936,13 @@ request_fw: | |||
859 | goto request_mn; | 936 | goto request_mn; |
860 | } | 937 | } |
861 | 938 | ||
939 | fw_type = NX_FLASH_ROMIMAGE; | ||
862 | adapter->fw = NULL; | 940 | adapter->fw = NULL; |
863 | goto done; | 941 | goto done; |
864 | } | 942 | } |
865 | 943 | ||
866 | done: | 944 | done: |
867 | if (adapter->fw) | 945 | adapter->fw_type = fw_type; |
868 | dev_info(&pdev->dev, "loading firmware from file %s\n", | ||
869 | fw_name[fw_type]); | ||
870 | else | ||
871 | dev_info(&pdev->dev, "loading firmware from flash\n"); | ||
872 | } | 946 | } |
873 | 947 | ||
874 | 948 | ||
@@ -1327,10 +1401,10 @@ int netxen_process_cmd_ring(struct netxen_adapter *adapter) | |||
1327 | smp_mb(); | 1401 | smp_mb(); |
1328 | 1402 | ||
1329 | if (netif_queue_stopped(netdev) && netif_carrier_ok(netdev)) { | 1403 | if (netif_queue_stopped(netdev) && netif_carrier_ok(netdev)) { |
1330 | netif_tx_lock(netdev); | 1404 | __netif_tx_lock(tx_ring->txq, smp_processor_id()); |
1331 | if (netxen_tx_avail(tx_ring) > TX_STOP_THRESH) | 1405 | if (netxen_tx_avail(tx_ring) > TX_STOP_THRESH) |
1332 | netif_wake_queue(netdev); | 1406 | netif_wake_queue(netdev); |
1333 | netif_tx_unlock(netdev); | 1407 | __netif_tx_unlock(tx_ring->txq); |
1334 | } | 1408 | } |
1335 | } | 1409 | } |
1336 | /* | 1410 | /* |
diff --git a/drivers/net/netxen/netxen_nic_main.c b/drivers/net/netxen/netxen_nic_main.c index 2919a2d12bf4..28f270f5ac78 100644 --- a/drivers/net/netxen/netxen_nic_main.c +++ b/drivers/net/netxen/netxen_nic_main.c | |||
@@ -94,10 +94,6 @@ static struct pci_device_id netxen_pci_tbl[] __devinitdata = { | |||
94 | 94 | ||
95 | MODULE_DEVICE_TABLE(pci, netxen_pci_tbl); | 95 | MODULE_DEVICE_TABLE(pci, netxen_pci_tbl); |
96 | 96 | ||
97 | static struct workqueue_struct *netxen_workq; | ||
98 | #define SCHEDULE_WORK(tp) queue_work(netxen_workq, tp) | ||
99 | #define FLUSH_SCHEDULED_WORK() flush_workqueue(netxen_workq) | ||
100 | |||
101 | static void netxen_watchdog(unsigned long); | 97 | static void netxen_watchdog(unsigned long); |
102 | 98 | ||
103 | static uint32_t crb_cmd_producer[4] = { | 99 | static uint32_t crb_cmd_producer[4] = { |
@@ -171,6 +167,8 @@ netxen_free_sds_rings(struct netxen_recv_context *recv_ctx) | |||
171 | { | 167 | { |
172 | if (recv_ctx->sds_rings != NULL) | 168 | if (recv_ctx->sds_rings != NULL) |
173 | kfree(recv_ctx->sds_rings); | 169 | kfree(recv_ctx->sds_rings); |
170 | |||
171 | recv_ctx->sds_rings = NULL; | ||
174 | } | 172 | } |
175 | 173 | ||
176 | static int | 174 | static int |
@@ -193,6 +191,21 @@ netxen_napi_add(struct netxen_adapter *adapter, struct net_device *netdev) | |||
193 | } | 191 | } |
194 | 192 | ||
195 | static void | 193 | static void |
194 | netxen_napi_del(struct netxen_adapter *adapter) | ||
195 | { | ||
196 | int ring; | ||
197 | struct nx_host_sds_ring *sds_ring; | ||
198 | struct netxen_recv_context *recv_ctx = &adapter->recv_ctx; | ||
199 | |||
200 | for (ring = 0; ring < adapter->max_sds_rings; ring++) { | ||
201 | sds_ring = &recv_ctx->sds_rings[ring]; | ||
202 | netif_napi_del(&sds_ring->napi); | ||
203 | } | ||
204 | |||
205 | netxen_free_sds_rings(&adapter->recv_ctx); | ||
206 | } | ||
207 | |||
208 | static void | ||
196 | netxen_napi_enable(struct netxen_adapter *adapter) | 209 | netxen_napi_enable(struct netxen_adapter *adapter) |
197 | { | 210 | { |
198 | int ring; | 211 | int ring; |
@@ -215,13 +228,13 @@ netxen_napi_disable(struct netxen_adapter *adapter) | |||
215 | 228 | ||
216 | for (ring = 0; ring < adapter->max_sds_rings; ring++) { | 229 | for (ring = 0; ring < adapter->max_sds_rings; ring++) { |
217 | sds_ring = &recv_ctx->sds_rings[ring]; | 230 | sds_ring = &recv_ctx->sds_rings[ring]; |
218 | napi_disable(&sds_ring->napi); | ||
219 | netxen_nic_disable_int(sds_ring); | 231 | netxen_nic_disable_int(sds_ring); |
220 | synchronize_irq(sds_ring->irq); | 232 | napi_synchronize(&sds_ring->napi); |
233 | napi_disable(&sds_ring->napi); | ||
221 | } | 234 | } |
222 | } | 235 | } |
223 | 236 | ||
224 | static int nx_set_dma_mask(struct netxen_adapter *adapter, uint8_t revision_id) | 237 | static int nx_set_dma_mask(struct netxen_adapter *adapter) |
225 | { | 238 | { |
226 | struct pci_dev *pdev = adapter->pdev; | 239 | struct pci_dev *pdev = adapter->pdev; |
227 | uint64_t mask, cmask; | 240 | uint64_t mask, cmask; |
@@ -229,19 +242,17 @@ static int nx_set_dma_mask(struct netxen_adapter *adapter, uint8_t revision_id) | |||
229 | adapter->pci_using_dac = 0; | 242 | adapter->pci_using_dac = 0; |
230 | 243 | ||
231 | mask = DMA_BIT_MASK(32); | 244 | mask = DMA_BIT_MASK(32); |
232 | /* | ||
233 | * Consistent DMA mask is set to 32 bit because it cannot be set to | ||
234 | * 35 bits. For P3 also leave it at 32 bits for now. Only the rings | ||
235 | * come off this pool. | ||
236 | */ | ||
237 | cmask = DMA_BIT_MASK(32); | 245 | cmask = DMA_BIT_MASK(32); |
238 | 246 | ||
247 | if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) { | ||
239 | #ifndef CONFIG_IA64 | 248 | #ifndef CONFIG_IA64 |
240 | if (revision_id >= NX_P3_B0) | ||
241 | mask = DMA_BIT_MASK(39); | ||
242 | else if (revision_id == NX_P2_C1) | ||
243 | mask = DMA_BIT_MASK(35); | 249 | mask = DMA_BIT_MASK(35); |
244 | #endif | 250 | #endif |
251 | } else { | ||
252 | mask = DMA_BIT_MASK(39); | ||
253 | cmask = mask; | ||
254 | } | ||
255 | |||
245 | if (pci_set_dma_mask(pdev, mask) == 0 && | 256 | if (pci_set_dma_mask(pdev, mask) == 0 && |
246 | pci_set_consistent_dma_mask(pdev, cmask) == 0) { | 257 | pci_set_consistent_dma_mask(pdev, cmask) == 0) { |
247 | adapter->pci_using_dac = 1; | 258 | adapter->pci_using_dac = 1; |
@@ -256,13 +267,13 @@ static int | |||
256 | nx_update_dma_mask(struct netxen_adapter *adapter) | 267 | nx_update_dma_mask(struct netxen_adapter *adapter) |
257 | { | 268 | { |
258 | int change, shift, err; | 269 | int change, shift, err; |
259 | uint64_t mask, old_mask; | 270 | uint64_t mask, old_mask, old_cmask; |
260 | struct pci_dev *pdev = adapter->pdev; | 271 | struct pci_dev *pdev = adapter->pdev; |
261 | 272 | ||
262 | change = 0; | 273 | change = 0; |
263 | 274 | ||
264 | shift = NXRD32(adapter, CRB_DMA_SHIFT); | 275 | shift = NXRD32(adapter, CRB_DMA_SHIFT); |
265 | if (shift >= 32) | 276 | if (shift > 32) |
266 | return 0; | 277 | return 0; |
267 | 278 | ||
268 | if (NX_IS_REVISION_P3(adapter->ahw.revision_id) && (shift > 9)) | 279 | if (NX_IS_REVISION_P3(adapter->ahw.revision_id) && (shift > 9)) |
@@ -272,14 +283,29 @@ nx_update_dma_mask(struct netxen_adapter *adapter) | |||
272 | 283 | ||
273 | if (change) { | 284 | if (change) { |
274 | old_mask = pdev->dma_mask; | 285 | old_mask = pdev->dma_mask; |
275 | mask = (1ULL<<(32+shift)) - 1; | 286 | old_cmask = pdev->dev.coherent_dma_mask; |
287 | |||
288 | mask = DMA_BIT_MASK(32+shift); | ||
276 | 289 | ||
277 | err = pci_set_dma_mask(pdev, mask); | 290 | err = pci_set_dma_mask(pdev, mask); |
278 | if (err) | 291 | if (err) |
279 | return pci_set_dma_mask(pdev, old_mask); | 292 | goto err_out; |
293 | |||
294 | if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) { | ||
295 | |||
296 | err = pci_set_consistent_dma_mask(pdev, mask); | ||
297 | if (err) | ||
298 | goto err_out; | ||
299 | } | ||
300 | dev_info(&pdev->dev, "using %d-bit dma mask\n", 32+shift); | ||
280 | } | 301 | } |
281 | 302 | ||
282 | return 0; | 303 | return 0; |
304 | |||
305 | err_out: | ||
306 | pci_set_dma_mask(pdev, old_mask); | ||
307 | pci_set_consistent_dma_mask(pdev, old_cmask); | ||
308 | return err; | ||
283 | } | 309 | } |
284 | 310 | ||
285 | static void netxen_check_options(struct netxen_adapter *adapter) | 311 | static void netxen_check_options(struct netxen_adapter *adapter) |
@@ -718,6 +744,10 @@ netxen_start_firmware(struct netxen_adapter *adapter, int request_fw) | |||
718 | if (request_fw) | 744 | if (request_fw) |
719 | netxen_request_firmware(adapter); | 745 | netxen_request_firmware(adapter); |
720 | 746 | ||
747 | err = netxen_need_fw_reset(adapter); | ||
748 | if (err <= 0) | ||
749 | return err; | ||
750 | |||
721 | if (first_boot != 0x55555555) { | 751 | if (first_boot != 0x55555555) { |
722 | NXWR32(adapter, CRB_CMDPEG_STATE, 0); | 752 | NXWR32(adapter, CRB_CMDPEG_STATE, 0); |
723 | netxen_pinit_from_rom(adapter, 0); | 753 | netxen_pinit_from_rom(adapter, 0); |
@@ -829,11 +859,11 @@ netxen_nic_up(struct netxen_adapter *adapter, struct net_device *netdev) | |||
829 | 859 | ||
830 | adapter->ahw.linkup = 0; | 860 | adapter->ahw.linkup = 0; |
831 | 861 | ||
832 | netxen_napi_enable(adapter); | ||
833 | |||
834 | if (adapter->max_sds_rings > 1) | 862 | if (adapter->max_sds_rings > 1) |
835 | netxen_config_rss(adapter, 1); | 863 | netxen_config_rss(adapter, 1); |
836 | 864 | ||
865 | netxen_napi_enable(adapter); | ||
866 | |||
837 | if (adapter->capabilities & NX_FW_CAPABILITY_LINK_NOTIFICATION) | 867 | if (adapter->capabilities & NX_FW_CAPABILITY_LINK_NOTIFICATION) |
838 | netxen_linkevent_request(adapter, 1); | 868 | netxen_linkevent_request(adapter, 1); |
839 | else | 869 | else |
@@ -847,8 +877,9 @@ netxen_nic_up(struct netxen_adapter *adapter, struct net_device *netdev) | |||
847 | static void | 877 | static void |
848 | netxen_nic_down(struct netxen_adapter *adapter, struct net_device *netdev) | 878 | netxen_nic_down(struct netxen_adapter *adapter, struct net_device *netdev) |
849 | { | 879 | { |
880 | spin_lock(&adapter->tx_clean_lock); | ||
850 | netif_carrier_off(netdev); | 881 | netif_carrier_off(netdev); |
851 | netif_stop_queue(netdev); | 882 | netif_tx_disable(netdev); |
852 | 883 | ||
853 | if (adapter->stop_port) | 884 | if (adapter->stop_port) |
854 | adapter->stop_port(adapter); | 885 | adapter->stop_port(adapter); |
@@ -859,8 +890,8 @@ netxen_nic_down(struct netxen_adapter *adapter, struct net_device *netdev) | |||
859 | netxen_napi_disable(adapter); | 890 | netxen_napi_disable(adapter); |
860 | 891 | ||
861 | netxen_release_tx_buffers(adapter); | 892 | netxen_release_tx_buffers(adapter); |
893 | spin_unlock(&adapter->tx_clean_lock); | ||
862 | 894 | ||
863 | FLUSH_SCHEDULED_WORK(); | ||
864 | del_timer_sync(&adapter->watchdog_timer); | 895 | del_timer_sync(&adapter->watchdog_timer); |
865 | } | 896 | } |
866 | 897 | ||
@@ -875,10 +906,12 @@ netxen_nic_attach(struct netxen_adapter *adapter) | |||
875 | struct nx_host_tx_ring *tx_ring; | 906 | struct nx_host_tx_ring *tx_ring; |
876 | 907 | ||
877 | err = netxen_init_firmware(adapter); | 908 | err = netxen_init_firmware(adapter); |
878 | if (err != 0) { | 909 | if (err) |
879 | printk(KERN_ERR "Failed to init firmware\n"); | 910 | return err; |
880 | return -EIO; | 911 | |
881 | } | 912 | err = netxen_napi_add(adapter, netdev); |
913 | if (err) | ||
914 | return err; | ||
882 | 915 | ||
883 | if (adapter->fw_major < 4) | 916 | if (adapter->fw_major < 4) |
884 | adapter->max_rds_rings = 3; | 917 | adapter->max_rds_rings = 3; |
@@ -939,9 +972,10 @@ err_out_free_sw: | |||
939 | static void | 972 | static void |
940 | netxen_nic_detach(struct netxen_adapter *adapter) | 973 | netxen_nic_detach(struct netxen_adapter *adapter) |
941 | { | 974 | { |
942 | netxen_release_rx_buffers(adapter); | ||
943 | netxen_free_hw_resources(adapter); | 975 | netxen_free_hw_resources(adapter); |
976 | netxen_release_rx_buffers(adapter); | ||
944 | netxen_nic_free_irq(adapter); | 977 | netxen_nic_free_irq(adapter); |
978 | netxen_napi_del(adapter); | ||
945 | netxen_free_sw_resources(adapter); | 979 | netxen_free_sw_resources(adapter); |
946 | 980 | ||
947 | adapter->is_up = 0; | 981 | adapter->is_up = 0; |
@@ -1000,7 +1034,7 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
1000 | revision_id = pdev->revision; | 1034 | revision_id = pdev->revision; |
1001 | adapter->ahw.revision_id = revision_id; | 1035 | adapter->ahw.revision_id = revision_id; |
1002 | 1036 | ||
1003 | err = nx_set_dma_mask(adapter, revision_id); | 1037 | err = nx_set_dma_mask(adapter); |
1004 | if (err) | 1038 | if (err) |
1005 | goto err_out_free_netdev; | 1039 | goto err_out_free_netdev; |
1006 | 1040 | ||
@@ -1086,9 +1120,6 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
1086 | 1120 | ||
1087 | netdev->irq = adapter->msix_entries[0].vector; | 1121 | netdev->irq = adapter->msix_entries[0].vector; |
1088 | 1122 | ||
1089 | if (netxen_napi_add(adapter, netdev)) | ||
1090 | goto err_out_disable_msi; | ||
1091 | |||
1092 | init_timer(&adapter->watchdog_timer); | 1123 | init_timer(&adapter->watchdog_timer); |
1093 | adapter->watchdog_timer.function = &netxen_watchdog; | 1124 | adapter->watchdog_timer.function = &netxen_watchdog; |
1094 | adapter->watchdog_timer.data = (unsigned long)adapter; | 1125 | adapter->watchdog_timer.data = (unsigned long)adapter; |
@@ -1158,6 +1189,9 @@ static void __devexit netxen_nic_remove(struct pci_dev *pdev) | |||
1158 | 1189 | ||
1159 | unregister_netdev(netdev); | 1190 | unregister_netdev(netdev); |
1160 | 1191 | ||
1192 | cancel_work_sync(&adapter->watchdog_task); | ||
1193 | cancel_work_sync(&adapter->tx_timeout_task); | ||
1194 | |||
1161 | if (adapter->is_up == NETXEN_ADAPTER_UP_MAGIC) { | 1195 | if (adapter->is_up == NETXEN_ADAPTER_UP_MAGIC) { |
1162 | netxen_nic_detach(adapter); | 1196 | netxen_nic_detach(adapter); |
1163 | } | 1197 | } |
@@ -1166,7 +1200,6 @@ static void __devexit netxen_nic_remove(struct pci_dev *pdev) | |||
1166 | netxen_free_adapter_offload(adapter); | 1200 | netxen_free_adapter_offload(adapter); |
1167 | 1201 | ||
1168 | netxen_teardown_intr(adapter); | 1202 | netxen_teardown_intr(adapter); |
1169 | netxen_free_sds_rings(&adapter->recv_ctx); | ||
1170 | 1203 | ||
1171 | netxen_cleanup_pci_map(adapter); | 1204 | netxen_cleanup_pci_map(adapter); |
1172 | 1205 | ||
@@ -1192,6 +1225,9 @@ netxen_nic_suspend(struct pci_dev *pdev, pm_message_t state) | |||
1192 | if (netif_running(netdev)) | 1225 | if (netif_running(netdev)) |
1193 | netxen_nic_down(adapter, netdev); | 1226 | netxen_nic_down(adapter, netdev); |
1194 | 1227 | ||
1228 | cancel_work_sync(&adapter->watchdog_task); | ||
1229 | cancel_work_sync(&adapter->tx_timeout_task); | ||
1230 | |||
1195 | if (adapter->is_up == NETXEN_ADAPTER_UP_MAGIC) | 1231 | if (adapter->is_up == NETXEN_ADAPTER_UP_MAGIC) |
1196 | netxen_nic_detach(adapter); | 1232 | netxen_nic_detach(adapter); |
1197 | 1233 | ||
@@ -1529,10 +1565,7 @@ static int netxen_nic_check_temp(struct netxen_adapter *adapter) | |||
1529 | printk(KERN_ALERT | 1565 | printk(KERN_ALERT |
1530 | "%s: Device temperature %d degrees C exceeds" | 1566 | "%s: Device temperature %d degrees C exceeds" |
1531 | " maximum allowed. Hardware has been shut down.\n", | 1567 | " maximum allowed. Hardware has been shut down.\n", |
1532 | netxen_nic_driver_name, temp_val); | 1568 | netdev->name, temp_val); |
1533 | |||
1534 | netif_carrier_off(netdev); | ||
1535 | netif_stop_queue(netdev); | ||
1536 | rv = 1; | 1569 | rv = 1; |
1537 | } else if (temp_state == NX_TEMP_WARN) { | 1570 | } else if (temp_state == NX_TEMP_WARN) { |
1538 | if (adapter->temp == NX_TEMP_NORMAL) { | 1571 | if (adapter->temp == NX_TEMP_NORMAL) { |
@@ -1540,13 +1573,13 @@ static int netxen_nic_check_temp(struct netxen_adapter *adapter) | |||
1540 | "%s: Device temperature %d degrees C " | 1573 | "%s: Device temperature %d degrees C " |
1541 | "exceeds operating range." | 1574 | "exceeds operating range." |
1542 | " Immediate action needed.\n", | 1575 | " Immediate action needed.\n", |
1543 | netxen_nic_driver_name, temp_val); | 1576 | netdev->name, temp_val); |
1544 | } | 1577 | } |
1545 | } else { | 1578 | } else { |
1546 | if (adapter->temp == NX_TEMP_WARN) { | 1579 | if (adapter->temp == NX_TEMP_WARN) { |
1547 | printk(KERN_INFO | 1580 | printk(KERN_INFO |
1548 | "%s: Device temperature is now %d degrees C" | 1581 | "%s: Device temperature is now %d degrees C" |
1549 | " in normal range.\n", netxen_nic_driver_name, | 1582 | " in normal range.\n", netdev->name, |
1550 | temp_val); | 1583 | temp_val); |
1551 | } | 1584 | } |
1552 | } | 1585 | } |
@@ -1566,10 +1599,7 @@ void netxen_advert_link_change(struct netxen_adapter *adapter, int linkup) | |||
1566 | netif_carrier_off(netdev); | 1599 | netif_carrier_off(netdev); |
1567 | netif_stop_queue(netdev); | 1600 | netif_stop_queue(netdev); |
1568 | } | 1601 | } |
1569 | 1602 | adapter->link_changed = !adapter->has_link_events; | |
1570 | if (!adapter->has_link_events) | ||
1571 | netxen_nic_set_link_parameters(adapter); | ||
1572 | |||
1573 | } else if (!adapter->ahw.linkup && linkup) { | 1603 | } else if (!adapter->ahw.linkup && linkup) { |
1574 | printk(KERN_INFO "%s: %s NIC Link is up\n", | 1604 | printk(KERN_INFO "%s: %s NIC Link is up\n", |
1575 | netxen_nic_driver_name, netdev->name); | 1605 | netxen_nic_driver_name, netdev->name); |
@@ -1578,9 +1608,7 @@ void netxen_advert_link_change(struct netxen_adapter *adapter, int linkup) | |||
1578 | netif_carrier_on(netdev); | 1608 | netif_carrier_on(netdev); |
1579 | netif_wake_queue(netdev); | 1609 | netif_wake_queue(netdev); |
1580 | } | 1610 | } |
1581 | 1611 | adapter->link_changed = !adapter->has_link_events; | |
1582 | if (!adapter->has_link_events) | ||
1583 | netxen_nic_set_link_parameters(adapter); | ||
1584 | } | 1612 | } |
1585 | } | 1613 | } |
1586 | 1614 | ||
@@ -1607,11 +1635,36 @@ static void netxen_nic_handle_phy_intr(struct netxen_adapter *adapter) | |||
1607 | netxen_advert_link_change(adapter, linkup); | 1635 | netxen_advert_link_change(adapter, linkup); |
1608 | } | 1636 | } |
1609 | 1637 | ||
1638 | static void netxen_nic_thermal_shutdown(struct netxen_adapter *adapter) | ||
1639 | { | ||
1640 | struct net_device *netdev = adapter->netdev; | ||
1641 | |||
1642 | netif_device_detach(netdev); | ||
1643 | netxen_nic_down(adapter, netdev); | ||
1644 | netxen_nic_detach(adapter); | ||
1645 | } | ||
1646 | |||
1610 | static void netxen_watchdog(unsigned long v) | 1647 | static void netxen_watchdog(unsigned long v) |
1611 | { | 1648 | { |
1612 | struct netxen_adapter *adapter = (struct netxen_adapter *)v; | 1649 | struct netxen_adapter *adapter = (struct netxen_adapter *)v; |
1613 | 1650 | ||
1614 | SCHEDULE_WORK(&adapter->watchdog_task); | 1651 | if (netxen_nic_check_temp(adapter)) |
1652 | goto do_sched; | ||
1653 | |||
1654 | if (!adapter->has_link_events) { | ||
1655 | netxen_nic_handle_phy_intr(adapter); | ||
1656 | |||
1657 | if (adapter->link_changed) | ||
1658 | goto do_sched; | ||
1659 | } | ||
1660 | |||
1661 | if (netif_running(adapter->netdev)) | ||
1662 | mod_timer(&adapter->watchdog_timer, jiffies + 2 * HZ); | ||
1663 | |||
1664 | return; | ||
1665 | |||
1666 | do_sched: | ||
1667 | schedule_work(&adapter->watchdog_task); | ||
1615 | } | 1668 | } |
1616 | 1669 | ||
1617 | void netxen_watchdog_task(struct work_struct *work) | 1670 | void netxen_watchdog_task(struct work_struct *work) |
@@ -1619,11 +1672,13 @@ void netxen_watchdog_task(struct work_struct *work) | |||
1619 | struct netxen_adapter *adapter = | 1672 | struct netxen_adapter *adapter = |
1620 | container_of(work, struct netxen_adapter, watchdog_task); | 1673 | container_of(work, struct netxen_adapter, watchdog_task); |
1621 | 1674 | ||
1622 | if ((adapter->portnum == 0) && netxen_nic_check_temp(adapter)) | 1675 | if (adapter->temp == NX_TEMP_PANIC) { |
1676 | netxen_nic_thermal_shutdown(adapter); | ||
1623 | return; | 1677 | return; |
1678 | } | ||
1624 | 1679 | ||
1625 | if (!adapter->has_link_events) | 1680 | if (adapter->link_changed) |
1626 | netxen_nic_handle_phy_intr(adapter); | 1681 | netxen_nic_set_link_parameters(adapter); |
1627 | 1682 | ||
1628 | if (netif_running(adapter->netdev)) | 1683 | if (netif_running(adapter->netdev)) |
1629 | mod_timer(&adapter->watchdog_timer, jiffies + 2 * HZ); | 1684 | mod_timer(&adapter->watchdog_timer, jiffies + 2 * HZ); |
@@ -1631,9 +1686,8 @@ void netxen_watchdog_task(struct work_struct *work) | |||
1631 | 1686 | ||
1632 | static void netxen_tx_timeout(struct net_device *netdev) | 1687 | static void netxen_tx_timeout(struct net_device *netdev) |
1633 | { | 1688 | { |
1634 | struct netxen_adapter *adapter = (struct netxen_adapter *) | 1689 | struct netxen_adapter *adapter = netdev_priv(netdev); |
1635 | netdev_priv(netdev); | 1690 | schedule_work(&adapter->tx_timeout_task); |
1636 | SCHEDULE_WORK(&adapter->tx_timeout_task); | ||
1637 | } | 1691 | } |
1638 | 1692 | ||
1639 | static void netxen_tx_timeout_task(struct work_struct *work) | 1693 | static void netxen_tx_timeout_task(struct work_struct *work) |
@@ -1641,6 +1695,9 @@ static void netxen_tx_timeout_task(struct work_struct *work) | |||
1641 | struct netxen_adapter *adapter = | 1695 | struct netxen_adapter *adapter = |
1642 | container_of(work, struct netxen_adapter, tx_timeout_task); | 1696 | container_of(work, struct netxen_adapter, tx_timeout_task); |
1643 | 1697 | ||
1698 | if (!netif_running(adapter->netdev)) | ||
1699 | return; | ||
1700 | |||
1644 | printk(KERN_ERR "%s %s: transmit timeout, resetting.\n", | 1701 | printk(KERN_ERR "%s %s: transmit timeout, resetting.\n", |
1645 | netxen_nic_driver_name, adapter->netdev->name); | 1702 | netxen_nic_driver_name, adapter->netdev->name); |
1646 | 1703 | ||
@@ -1753,7 +1810,8 @@ static int netxen_nic_poll(struct napi_struct *napi, int budget) | |||
1753 | 1810 | ||
1754 | if ((work_done < budget) && tx_complete) { | 1811 | if ((work_done < budget) && tx_complete) { |
1755 | napi_complete(&sds_ring->napi); | 1812 | napi_complete(&sds_ring->napi); |
1756 | netxen_nic_enable_int(sds_ring); | 1813 | if (netif_running(adapter->netdev)) |
1814 | netxen_nic_enable_int(sds_ring); | ||
1757 | } | 1815 | } |
1758 | 1816 | ||
1759 | return work_done; | 1817 | return work_done; |
@@ -1786,9 +1844,6 @@ static int __init netxen_init_module(void) | |||
1786 | { | 1844 | { |
1787 | printk(KERN_INFO "%s\n", netxen_nic_driver_string); | 1845 | printk(KERN_INFO "%s\n", netxen_nic_driver_string); |
1788 | 1846 | ||
1789 | if ((netxen_workq = create_singlethread_workqueue("netxen")) == NULL) | ||
1790 | return -ENOMEM; | ||
1791 | |||
1792 | return pci_register_driver(&netxen_driver); | 1847 | return pci_register_driver(&netxen_driver); |
1793 | } | 1848 | } |
1794 | 1849 | ||
@@ -1797,7 +1852,6 @@ module_init(netxen_init_module); | |||
1797 | static void __exit netxen_exit_module(void) | 1852 | static void __exit netxen_exit_module(void) |
1798 | { | 1853 | { |
1799 | pci_unregister_driver(&netxen_driver); | 1854 | pci_unregister_driver(&netxen_driver); |
1800 | destroy_workqueue(netxen_workq); | ||
1801 | } | 1855 | } |
1802 | 1856 | ||
1803 | module_exit(netxen_exit_module); | 1857 | module_exit(netxen_exit_module); |