diff options
Diffstat (limited to 'drivers/net/netxen')
-rw-r--r-- | drivers/net/netxen/Makefile | 2 | ||||
-rw-r--r-- | drivers/net/netxen/netxen_nic.h | 84 | ||||
-rw-r--r-- | drivers/net/netxen/netxen_nic_ctx.c | 16 | ||||
-rw-r--r-- | drivers/net/netxen/netxen_nic_ethtool.c | 225 | ||||
-rw-r--r-- | drivers/net/netxen/netxen_nic_hdr.h | 81 | ||||
-rw-r--r-- | drivers/net/netxen/netxen_nic_hw.c | 1048 | ||||
-rw-r--r-- | drivers/net/netxen/netxen_nic_hw.h | 2 | ||||
-rw-r--r-- | drivers/net/netxen/netxen_nic_init.c | 383 | ||||
-rw-r--r-- | drivers/net/netxen/netxen_nic_main.c | 603 |
9 files changed, 1437 insertions, 1007 deletions
diff --git a/drivers/net/netxen/Makefile b/drivers/net/netxen/Makefile index 11d94e2434e4..861a0590b1f4 100644 --- a/drivers/net/netxen/Makefile +++ b/drivers/net/netxen/Makefile | |||
@@ -18,7 +18,7 @@ | |||
18 | # MA 02111-1307, USA. | 18 | # MA 02111-1307, USA. |
19 | # | 19 | # |
20 | # The full GNU General Public License is included in this distribution | 20 | # The full GNU General Public License is included in this distribution |
21 | # in the file called LICENSE. | 21 | # in the file called "COPYING". |
22 | # | 22 | # |
23 | # | 23 | # |
24 | 24 | ||
diff --git a/drivers/net/netxen/netxen_nic.h b/drivers/net/netxen/netxen_nic.h index e1237b802872..0f703838e21a 100644 --- a/drivers/net/netxen/netxen_nic.h +++ b/drivers/net/netxen/netxen_nic.h | |||
@@ -19,7 +19,7 @@ | |||
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 | ||
@@ -53,8 +53,8 @@ | |||
53 | 53 | ||
54 | #define _NETXEN_NIC_LINUX_MAJOR 4 | 54 | #define _NETXEN_NIC_LINUX_MAJOR 4 |
55 | #define _NETXEN_NIC_LINUX_MINOR 0 | 55 | #define _NETXEN_NIC_LINUX_MINOR 0 |
56 | #define _NETXEN_NIC_LINUX_SUBVERSION 50 | 56 | #define _NETXEN_NIC_LINUX_SUBVERSION 73 |
57 | #define NETXEN_NIC_LINUX_VERSIONID "4.0.50" | 57 | #define NETXEN_NIC_LINUX_VERSIONID "4.0.73" |
58 | 58 | ||
59 | #define NETXEN_VERSION_CODE(a, b, c) (((a) << 24) + ((b) << 16) + (c)) | 59 | #define NETXEN_VERSION_CODE(a, b, c) (((a) << 24) + ((b) << 16) + (c)) |
60 | #define _major(v) (((v) >> 24) & 0xff) | 60 | #define _major(v) (((v) >> 24) & 0xff) |
@@ -74,8 +74,6 @@ | |||
74 | #define NETXEN_FLASH_TOTAL_SIZE (NETXEN_NUM_FLASH_SECTORS \ | 74 | #define NETXEN_FLASH_TOTAL_SIZE (NETXEN_NUM_FLASH_SECTORS \ |
75 | * NETXEN_FLASH_SECTOR_SIZE) | 75 | * NETXEN_FLASH_SECTOR_SIZE) |
76 | 76 | ||
77 | #define PHAN_VENDOR_ID 0x4040 | ||
78 | |||
79 | #define RCV_DESC_RINGSIZE(rds_ring) \ | 77 | #define RCV_DESC_RINGSIZE(rds_ring) \ |
80 | (sizeof(struct rcv_desc) * (rds_ring)->num_desc) | 78 | (sizeof(struct rcv_desc) * (rds_ring)->num_desc) |
81 | #define RCV_BUFF_RINGSIZE(rds_ring) \ | 79 | #define RCV_BUFF_RINGSIZE(rds_ring) \ |
@@ -117,9 +115,11 @@ | |||
117 | #define NX_P3_B0 0x40 | 115 | #define NX_P3_B0 0x40 |
118 | #define NX_P3_B1 0x41 | 116 | #define NX_P3_B1 0x41 |
119 | #define NX_P3_B2 0x42 | 117 | #define NX_P3_B2 0x42 |
118 | #define NX_P3P_A0 0x50 | ||
120 | 119 | ||
121 | #define NX_IS_REVISION_P2(REVISION) (REVISION <= NX_P2_C1) | 120 | #define NX_IS_REVISION_P2(REVISION) (REVISION <= NX_P2_C1) |
122 | #define NX_IS_REVISION_P3(REVISION) (REVISION >= NX_P3_A0) | 121 | #define NX_IS_REVISION_P3(REVISION) (REVISION >= NX_P3_A0) |
122 | #define NX_IS_REVISION_P3P(REVISION) (REVISION >= NX_P3P_A0) | ||
123 | 123 | ||
124 | #define FIRST_PAGE_GROUP_START 0 | 124 | #define FIRST_PAGE_GROUP_START 0 |
125 | #define FIRST_PAGE_GROUP_END 0x100000 | 125 | #define FIRST_PAGE_GROUP_END 0x100000 |
@@ -419,6 +419,34 @@ struct status_desc { | |||
419 | __le64 status_desc_data[2]; | 419 | __le64 status_desc_data[2]; |
420 | } __attribute__ ((aligned(16))); | 420 | } __attribute__ ((aligned(16))); |
421 | 421 | ||
422 | /* UNIFIED ROMIMAGE *************************/ | ||
423 | #define NX_UNI_FW_MIN_SIZE 0xc8000 | ||
424 | #define NX_UNI_DIR_SECT_PRODUCT_TBL 0x0 | ||
425 | #define NX_UNI_DIR_SECT_BOOTLD 0x6 | ||
426 | #define NX_UNI_DIR_SECT_FW 0x7 | ||
427 | |||
428 | /*Offsets */ | ||
429 | #define NX_UNI_CHIP_REV_OFF 10 | ||
430 | #define NX_UNI_FLAGS_OFF 11 | ||
431 | #define NX_UNI_BIOS_VERSION_OFF 12 | ||
432 | #define NX_UNI_BOOTLD_IDX_OFF 27 | ||
433 | #define NX_UNI_FIRMWARE_IDX_OFF 29 | ||
434 | |||
435 | struct uni_table_desc{ | ||
436 | uint32_t findex; | ||
437 | uint32_t num_entries; | ||
438 | uint32_t entry_size; | ||
439 | uint32_t reserved[5]; | ||
440 | }; | ||
441 | |||
442 | struct uni_data_desc{ | ||
443 | uint32_t findex; | ||
444 | uint32_t size; | ||
445 | uint32_t reserved[5]; | ||
446 | }; | ||
447 | |||
448 | /* UNIFIED ROMIMAGE *************************/ | ||
449 | |||
422 | /* The version of the main data structure */ | 450 | /* The version of the main data structure */ |
423 | #define NETXEN_BDINFO_VERSION 1 | 451 | #define NETXEN_BDINFO_VERSION 1 |
424 | 452 | ||
@@ -485,7 +513,15 @@ struct status_desc { | |||
485 | #define NX_P2_MN_ROMIMAGE 0 | 513 | #define NX_P2_MN_ROMIMAGE 0 |
486 | #define NX_P3_CT_ROMIMAGE 1 | 514 | #define NX_P3_CT_ROMIMAGE 1 |
487 | #define NX_P3_MN_ROMIMAGE 2 | 515 | #define NX_P3_MN_ROMIMAGE 2 |
488 | #define NX_FLASH_ROMIMAGE 3 | 516 | #define NX_UNIFIED_ROMIMAGE 3 |
517 | #define NX_FLASH_ROMIMAGE 4 | ||
518 | #define NX_UNKNOWN_ROMIMAGE 0xff | ||
519 | |||
520 | #define NX_P2_MN_ROMIMAGE_NAME "nxromimg.bin" | ||
521 | #define NX_P3_CT_ROMIMAGE_NAME "nx3fwct.bin" | ||
522 | #define NX_P3_MN_ROMIMAGE_NAME "nx3fwmn.bin" | ||
523 | #define NX_UNIFIED_ROMIMAGE_NAME "phanfw.bin" | ||
524 | #define NX_FLASH_ROMIMAGE_NAME "flash" | ||
489 | 525 | ||
490 | extern char netxen_nic_driver_name[]; | 526 | extern char netxen_nic_driver_name[]; |
491 | 527 | ||
@@ -543,13 +579,16 @@ struct netxen_hardware_context { | |||
543 | void __iomem *pci_base1; | 579 | void __iomem *pci_base1; |
544 | void __iomem *pci_base2; | 580 | void __iomem *pci_base2; |
545 | void __iomem *db_base; | 581 | void __iomem *db_base; |
582 | void __iomem *ocm_win_crb; | ||
583 | |||
546 | unsigned long db_len; | 584 | unsigned long db_len; |
547 | unsigned long pci_len0; | 585 | unsigned long pci_len0; |
548 | 586 | ||
549 | int qdr_sn_window; | 587 | u32 ocm_win; |
550 | int ddr_mn_window; | 588 | u32 crb_win; |
551 | u32 mn_win_crb; | 589 | |
552 | u32 ms_win_crb; | 590 | rwlock_t crb_lock; |
591 | spinlock_t mem_lock; | ||
553 | 592 | ||
554 | u8 cut_through; | 593 | u8 cut_through; |
555 | u8 revision_id; | 594 | u8 revision_id; |
@@ -1039,6 +1078,9 @@ typedef struct { | |||
1039 | #define LINKEVENT_LINKSPEED_MBPS 0 | 1078 | #define LINKEVENT_LINKSPEED_MBPS 0 |
1040 | #define LINKEVENT_LINKSPEED_ENCODED 1 | 1079 | #define LINKEVENT_LINKSPEED_ENCODED 1 |
1041 | 1080 | ||
1081 | #define AUTO_FW_RESET_ENABLED 0xEF10AF12 | ||
1082 | #define AUTO_FW_RESET_DISABLED 0xDCBAAF12 | ||
1083 | |||
1042 | /* firmware response header: | 1084 | /* firmware response header: |
1043 | * 63:58 - message type | 1085 | * 63:58 - message type |
1044 | * 57:56 - owner | 1086 | * 57:56 - owner |
@@ -1086,6 +1128,7 @@ typedef struct { | |||
1086 | #define NETXEN_NIC_MSIX_ENABLED 0x04 | 1128 | #define NETXEN_NIC_MSIX_ENABLED 0x04 |
1087 | #define NETXEN_NIC_LRO_ENABLED 0x08 | 1129 | #define NETXEN_NIC_LRO_ENABLED 0x08 |
1088 | #define NETXEN_NIC_BRIDGE_ENABLED 0X10 | 1130 | #define NETXEN_NIC_BRIDGE_ENABLED 0X10 |
1131 | #define NETXEN_NIC_DIAG_ENABLED 0x20 | ||
1089 | #define NETXEN_IS_MSI_FAMILY(adapter) \ | 1132 | #define NETXEN_IS_MSI_FAMILY(adapter) \ |
1090 | ((adapter)->flags & (NETXEN_NIC_MSI_ENABLED | NETXEN_NIC_MSIX_ENABLED)) | 1133 | ((adapter)->flags & (NETXEN_NIC_MSI_ENABLED | NETXEN_NIC_MSIX_ENABLED)) |
1091 | 1134 | ||
@@ -1115,10 +1158,6 @@ struct netxen_adapter { | |||
1115 | struct pci_dev *pdev; | 1158 | struct pci_dev *pdev; |
1116 | struct list_head mac_list; | 1159 | struct list_head mac_list; |
1117 | 1160 | ||
1118 | u32 curr_window; | ||
1119 | u32 crb_win; | ||
1120 | rwlock_t adapter_lock; | ||
1121 | |||
1122 | spinlock_t tx_clean_lock; | 1161 | spinlock_t tx_clean_lock; |
1123 | 1162 | ||
1124 | u16 num_txd; | 1163 | u16 num_txd; |
@@ -1182,11 +1221,10 @@ struct netxen_adapter { | |||
1182 | u32 (*crb_read)(struct netxen_adapter *, ulong); | 1221 | u32 (*crb_read)(struct netxen_adapter *, ulong); |
1183 | int (*crb_write)(struct netxen_adapter *, ulong, u32); | 1222 | int (*crb_write)(struct netxen_adapter *, ulong, u32); |
1184 | 1223 | ||
1185 | int (*pci_mem_read)(struct netxen_adapter *, u64, void *, int); | 1224 | int (*pci_mem_read)(struct netxen_adapter *, u64, u64 *); |
1186 | int (*pci_mem_write)(struct netxen_adapter *, u64, void *, int); | 1225 | int (*pci_mem_write)(struct netxen_adapter *, u64, u64); |
1187 | 1226 | ||
1188 | unsigned long (*pci_set_window)(struct netxen_adapter *, | 1227 | int (*pci_set_window)(struct netxen_adapter *, u64, u32 *); |
1189 | unsigned long long); | ||
1190 | 1228 | ||
1191 | u32 (*io_read)(struct netxen_adapter *, void __iomem *); | 1229 | u32 (*io_read)(struct netxen_adapter *, void __iomem *); |
1192 | void (*io_write)(struct netxen_adapter *, void __iomem *, u32); | 1230 | void (*io_write)(struct netxen_adapter *, void __iomem *, u32); |
@@ -1205,12 +1243,10 @@ struct netxen_adapter { | |||
1205 | 1243 | ||
1206 | struct work_struct tx_timeout_task; | 1244 | struct work_struct tx_timeout_task; |
1207 | 1245 | ||
1208 | struct net_device_stats net_stats; | ||
1209 | |||
1210 | nx_nic_intr_coalesce_t coal; | 1246 | nx_nic_intr_coalesce_t coal; |
1211 | 1247 | ||
1212 | unsigned long state; | 1248 | unsigned long state; |
1213 | u32 resv5; | 1249 | __le32 file_prd_off; /*File fw product offset*/ |
1214 | u32 fw_version; | 1250 | u32 fw_version; |
1215 | const struct firmware *fw; | 1251 | const struct firmware *fw; |
1216 | }; | 1252 | }; |
@@ -1273,7 +1309,7 @@ int netxen_load_firmware(struct netxen_adapter *adapter); | |||
1273 | int netxen_need_fw_reset(struct netxen_adapter *adapter); | 1309 | int netxen_need_fw_reset(struct netxen_adapter *adapter); |
1274 | void netxen_request_firmware(struct netxen_adapter *adapter); | 1310 | void netxen_request_firmware(struct netxen_adapter *adapter); |
1275 | void netxen_release_firmware(struct netxen_adapter *adapter); | 1311 | void netxen_release_firmware(struct netxen_adapter *adapter); |
1276 | int netxen_pinit_from_rom(struct netxen_adapter *adapter, int verbose); | 1312 | int netxen_pinit_from_rom(struct netxen_adapter *adapter); |
1277 | 1313 | ||
1278 | int netxen_rom_fast_read(struct netxen_adapter *adapter, int addr, int *valp); | 1314 | int netxen_rom_fast_read(struct netxen_adapter *adapter, int addr, int *valp); |
1279 | int netxen_rom_fast_read_words(struct netxen_adapter *adapter, int addr, | 1315 | int netxen_rom_fast_read_words(struct netxen_adapter *adapter, int addr, |
@@ -1391,8 +1427,8 @@ static inline u32 netxen_tx_avail(struct nx_host_tx_ring *tx_ring) | |||
1391 | 1427 | ||
1392 | } | 1428 | } |
1393 | 1429 | ||
1394 | int netxen_get_flash_mac_addr(struct netxen_adapter *adapter, __le64 *mac); | 1430 | int netxen_get_flash_mac_addr(struct netxen_adapter *adapter, u64 *mac); |
1395 | int netxen_p3_get_mac_addr(struct netxen_adapter *adapter, __le64 *mac); | 1431 | int netxen_p3_get_mac_addr(struct netxen_adapter *adapter, u64 *mac); |
1396 | extern void netxen_change_ringparam(struct netxen_adapter *adapter); | 1432 | extern void netxen_change_ringparam(struct netxen_adapter *adapter); |
1397 | extern int netxen_rom_fast_read(struct netxen_adapter *adapter, int addr, | 1433 | extern int netxen_rom_fast_read(struct netxen_adapter *adapter, int addr, |
1398 | int *valp); | 1434 | int *valp); |
diff --git a/drivers/net/netxen/netxen_nic_ctx.c b/drivers/net/netxen/netxen_nic_ctx.c index 9cb8f6878047..f26e54716c88 100644 --- a/drivers/net/netxen/netxen_nic_ctx.c +++ b/drivers/net/netxen/netxen_nic_ctx.c | |||
@@ -19,7 +19,7 @@ | |||
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 | ||
@@ -669,13 +669,15 @@ int netxen_alloc_hw_resources(struct netxen_adapter *adapter) | |||
669 | } | 669 | } |
670 | sds_ring->desc_head = (struct status_desc *)addr; | 670 | sds_ring->desc_head = (struct status_desc *)addr; |
671 | 671 | ||
672 | sds_ring->crb_sts_consumer = | 672 | if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) { |
673 | netxen_get_ioaddr(adapter, | 673 | sds_ring->crb_sts_consumer = |
674 | recv_crb_registers[port].crb_sts_consumer[ring]); | 674 | netxen_get_ioaddr(adapter, |
675 | recv_crb_registers[port].crb_sts_consumer[ring]); | ||
675 | 676 | ||
676 | sds_ring->crb_intr_mask = | 677 | sds_ring->crb_intr_mask = |
677 | netxen_get_ioaddr(adapter, | 678 | netxen_get_ioaddr(adapter, |
678 | recv_crb_registers[port].sw_int_mask[ring]); | 679 | recv_crb_registers[port].sw_int_mask[ring]); |
680 | } | ||
679 | } | 681 | } |
680 | 682 | ||
681 | 683 | ||
diff --git a/drivers/net/netxen/netxen_nic_ethtool.c b/drivers/net/netxen/netxen_nic_ethtool.c index 714f38791a9a..f8499e56cbee 100644 --- a/drivers/net/netxen/netxen_nic_ethtool.c +++ b/drivers/net/netxen/netxen_nic_ethtool.c | |||
@@ -19,7 +19,7 @@ | |||
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 | ||
@@ -66,7 +66,7 @@ static const char netxen_nic_gstrings_test[][ETH_GSTRING_LEN] = { | |||
66 | 66 | ||
67 | #define NETXEN_NIC_TEST_LEN ARRAY_SIZE(netxen_nic_gstrings_test) | 67 | #define NETXEN_NIC_TEST_LEN ARRAY_SIZE(netxen_nic_gstrings_test) |
68 | 68 | ||
69 | #define NETXEN_NIC_REGS_COUNT 42 | 69 | #define NETXEN_NIC_REGS_COUNT 30 |
70 | #define NETXEN_NIC_REGS_LEN (NETXEN_NIC_REGS_COUNT * sizeof(__le32)) | 70 | #define NETXEN_NIC_REGS_LEN (NETXEN_NIC_REGS_COUNT * sizeof(__le32)) |
71 | #define NETXEN_MAX_EEPROM_LEN 1024 | 71 | #define NETXEN_MAX_EEPROM_LEN 1024 |
72 | 72 | ||
@@ -85,11 +85,9 @@ netxen_nic_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *drvinfo) | |||
85 | 85 | ||
86 | strncpy(drvinfo->driver, netxen_nic_driver_name, 32); | 86 | strncpy(drvinfo->driver, netxen_nic_driver_name, 32); |
87 | strncpy(drvinfo->version, NETXEN_NIC_LINUX_VERSIONID, 32); | 87 | strncpy(drvinfo->version, NETXEN_NIC_LINUX_VERSIONID, 32); |
88 | read_lock(&adapter->adapter_lock); | ||
89 | fw_major = NXRD32(adapter, NETXEN_FW_VERSION_MAJOR); | 88 | fw_major = NXRD32(adapter, NETXEN_FW_VERSION_MAJOR); |
90 | fw_minor = NXRD32(adapter, NETXEN_FW_VERSION_MINOR); | 89 | fw_minor = NXRD32(adapter, NETXEN_FW_VERSION_MINOR); |
91 | fw_build = NXRD32(adapter, NETXEN_FW_VERSION_SUB); | 90 | fw_build = NXRD32(adapter, NETXEN_FW_VERSION_SUB); |
92 | read_unlock(&adapter->adapter_lock); | ||
93 | sprintf(drvinfo->fw_version, "%d.%d.%d", fw_major, fw_minor, fw_build); | 91 | sprintf(drvinfo->fw_version, "%d.%d.%d", fw_major, fw_minor, fw_build); |
94 | 92 | ||
95 | strncpy(drvinfo->bus_info, pci_name(adapter->pdev), 32); | 93 | strncpy(drvinfo->bus_info, pci_name(adapter->pdev), 32); |
@@ -259,18 +257,18 @@ netxen_nic_set_settings(struct net_device *dev, struct ethtool_cmd *ecmd) | |||
259 | /* read which mode */ | 257 | /* read which mode */ |
260 | if (adapter->ahw.port_type == NETXEN_NIC_GBE) { | 258 | if (adapter->ahw.port_type == NETXEN_NIC_GBE) { |
261 | /* autonegotiation */ | 259 | /* autonegotiation */ |
262 | if (adapter->phy_write | 260 | if (adapter->phy_write && |
263 | && adapter->phy_write(adapter, | 261 | adapter->phy_write(adapter, |
264 | NETXEN_NIU_GB_MII_MGMT_ADDR_AUTONEG, | 262 | NETXEN_NIU_GB_MII_MGMT_ADDR_AUTONEG, |
265 | ecmd->autoneg) != 0) | 263 | ecmd->autoneg) != 0) |
266 | return -EIO; | 264 | return -EIO; |
267 | else | 265 | else |
268 | adapter->link_autoneg = ecmd->autoneg; | 266 | adapter->link_autoneg = ecmd->autoneg; |
269 | 267 | ||
270 | if (adapter->phy_read | 268 | if (adapter->phy_read && |
271 | && adapter->phy_read(adapter, | 269 | adapter->phy_read(adapter, |
272 | NETXEN_NIU_GB_MII_MGMT_ADDR_PHY_STATUS, | 270 | NETXEN_NIU_GB_MII_MGMT_ADDR_PHY_STATUS, |
273 | &status) != 0) | 271 | &status) != 0) |
274 | return -EIO; | 272 | return -EIO; |
275 | 273 | ||
276 | /* speed */ | 274 | /* speed */ |
@@ -290,10 +288,10 @@ netxen_nic_set_settings(struct net_device *dev, struct ethtool_cmd *ecmd) | |||
290 | netxen_clear_phy_duplex(status); | 288 | netxen_clear_phy_duplex(status); |
291 | if (ecmd->duplex == DUPLEX_FULL) | 289 | if (ecmd->duplex == DUPLEX_FULL) |
292 | netxen_set_phy_duplex(status); | 290 | netxen_set_phy_duplex(status); |
293 | if (adapter->phy_write | 291 | if (adapter->phy_write && |
294 | && adapter->phy_write(adapter, | 292 | adapter->phy_write(adapter, |
295 | NETXEN_NIU_GB_MII_MGMT_ADDR_PHY_STATUS, | 293 | NETXEN_NIU_GB_MII_MGMT_ADDR_PHY_STATUS, |
296 | *((int *)&status)) != 0) | 294 | *((int *)&status)) != 0) |
297 | return -EIO; | 295 | return -EIO; |
298 | else { | 296 | else { |
299 | adapter->link_speed = ecmd->speed; | 297 | adapter->link_speed = ecmd->speed; |
@@ -314,150 +312,91 @@ static int netxen_nic_get_regs_len(struct net_device *dev) | |||
314 | return NETXEN_NIC_REGS_LEN; | 312 | return NETXEN_NIC_REGS_LEN; |
315 | } | 313 | } |
316 | 314 | ||
317 | struct netxen_niu_regs { | ||
318 | __u32 reg[NETXEN_NIC_REGS_COUNT]; | ||
319 | }; | ||
320 | |||
321 | static struct netxen_niu_regs niu_registers[] = { | ||
322 | { | ||
323 | /* GB Mode */ | ||
324 | { | ||
325 | NETXEN_NIU_GB_SERDES_RESET, | ||
326 | NETXEN_NIU_GB0_MII_MODE, | ||
327 | NETXEN_NIU_GB1_MII_MODE, | ||
328 | NETXEN_NIU_GB2_MII_MODE, | ||
329 | NETXEN_NIU_GB3_MII_MODE, | ||
330 | NETXEN_NIU_GB0_GMII_MODE, | ||
331 | NETXEN_NIU_GB1_GMII_MODE, | ||
332 | NETXEN_NIU_GB2_GMII_MODE, | ||
333 | NETXEN_NIU_GB3_GMII_MODE, | ||
334 | NETXEN_NIU_REMOTE_LOOPBACK, | ||
335 | NETXEN_NIU_GB0_HALF_DUPLEX, | ||
336 | NETXEN_NIU_GB1_HALF_DUPLEX, | ||
337 | NETXEN_NIU_RESET_SYS_FIFOS, | ||
338 | NETXEN_NIU_GB_CRC_DROP, | ||
339 | NETXEN_NIU_GB_DROP_WRONGADDR, | ||
340 | NETXEN_NIU_TEST_MUX_CTL, | ||
341 | |||
342 | NETXEN_NIU_GB_MAC_CONFIG_0(0), | ||
343 | NETXEN_NIU_GB_MAC_CONFIG_1(0), | ||
344 | NETXEN_NIU_GB_HALF_DUPLEX_CTRL(0), | ||
345 | NETXEN_NIU_GB_MAX_FRAME_SIZE(0), | ||
346 | NETXEN_NIU_GB_TEST_REG(0), | ||
347 | NETXEN_NIU_GB_MII_MGMT_CONFIG(0), | ||
348 | NETXEN_NIU_GB_MII_MGMT_COMMAND(0), | ||
349 | NETXEN_NIU_GB_MII_MGMT_ADDR(0), | ||
350 | NETXEN_NIU_GB_MII_MGMT_CTRL(0), | ||
351 | NETXEN_NIU_GB_MII_MGMT_STATUS(0), | ||
352 | NETXEN_NIU_GB_MII_MGMT_INDICATE(0), | ||
353 | NETXEN_NIU_GB_INTERFACE_CTRL(0), | ||
354 | NETXEN_NIU_GB_INTERFACE_STATUS(0), | ||
355 | NETXEN_NIU_GB_STATION_ADDR_0(0), | ||
356 | NETXEN_NIU_GB_STATION_ADDR_1(0), | ||
357 | -1, | ||
358 | } | ||
359 | }, | ||
360 | { | ||
361 | /* XG Mode */ | ||
362 | { | ||
363 | NETXEN_NIU_XG_SINGLE_TERM, | ||
364 | NETXEN_NIU_XG_DRIVE_HI, | ||
365 | NETXEN_NIU_XG_DRIVE_LO, | ||
366 | NETXEN_NIU_XG_DTX, | ||
367 | NETXEN_NIU_XG_DEQ, | ||
368 | NETXEN_NIU_XG_WORD_ALIGN, | ||
369 | NETXEN_NIU_XG_RESET, | ||
370 | NETXEN_NIU_XG_POWER_DOWN, | ||
371 | NETXEN_NIU_XG_RESET_PLL, | ||
372 | NETXEN_NIU_XG_SERDES_LOOPBACK, | ||
373 | NETXEN_NIU_XG_DO_BYTE_ALIGN, | ||
374 | NETXEN_NIU_XG_TX_ENABLE, | ||
375 | NETXEN_NIU_XG_RX_ENABLE, | ||
376 | NETXEN_NIU_XG_STATUS, | ||
377 | NETXEN_NIU_XG_PAUSE_THRESHOLD, | ||
378 | NETXEN_NIU_XGE_CONFIG_0, | ||
379 | NETXEN_NIU_XGE_CONFIG_1, | ||
380 | NETXEN_NIU_XGE_IPG, | ||
381 | NETXEN_NIU_XGE_STATION_ADDR_0_HI, | ||
382 | NETXEN_NIU_XGE_STATION_ADDR_0_1, | ||
383 | NETXEN_NIU_XGE_STATION_ADDR_1_LO, | ||
384 | NETXEN_NIU_XGE_STATUS, | ||
385 | NETXEN_NIU_XGE_MAX_FRAME_SIZE, | ||
386 | NETXEN_NIU_XGE_PAUSE_FRAME_VALUE, | ||
387 | NETXEN_NIU_XGE_TX_BYTE_CNT, | ||
388 | NETXEN_NIU_XGE_TX_FRAME_CNT, | ||
389 | NETXEN_NIU_XGE_RX_BYTE_CNT, | ||
390 | NETXEN_NIU_XGE_RX_FRAME_CNT, | ||
391 | NETXEN_NIU_XGE_AGGR_ERROR_CNT, | ||
392 | NETXEN_NIU_XGE_MULTICAST_FRAME_CNT, | ||
393 | NETXEN_NIU_XGE_UNICAST_FRAME_CNT, | ||
394 | NETXEN_NIU_XGE_CRC_ERROR_CNT, | ||
395 | NETXEN_NIU_XGE_OVERSIZE_FRAME_ERR, | ||
396 | NETXEN_NIU_XGE_UNDERSIZE_FRAME_ERR, | ||
397 | NETXEN_NIU_XGE_LOCAL_ERROR_CNT, | ||
398 | NETXEN_NIU_XGE_REMOTE_ERROR_CNT, | ||
399 | NETXEN_NIU_XGE_CONTROL_CHAR_CNT, | ||
400 | NETXEN_NIU_XGE_PAUSE_FRAME_CNT, | ||
401 | -1, | ||
402 | } | ||
403 | } | ||
404 | }; | ||
405 | |||
406 | static void | 315 | static void |
407 | netxen_nic_get_regs(struct net_device *dev, struct ethtool_regs *regs, void *p) | 316 | netxen_nic_get_regs(struct net_device *dev, struct ethtool_regs *regs, void *p) |
408 | { | 317 | { |
409 | struct netxen_adapter *adapter = netdev_priv(dev); | 318 | struct netxen_adapter *adapter = netdev_priv(dev); |
410 | __u32 mode, *regs_buff = p; | 319 | struct netxen_recv_context *recv_ctx = &adapter->recv_ctx; |
411 | int i, window; | 320 | struct nx_host_sds_ring *sds_ring; |
321 | u32 *regs_buff = p; | ||
322 | int ring, i = 0; | ||
323 | int port = adapter->physical_port; | ||
412 | 324 | ||
413 | memset(p, 0, NETXEN_NIC_REGS_LEN); | 325 | memset(p, 0, NETXEN_NIC_REGS_LEN); |
326 | |||
414 | regs->version = (1 << 24) | (adapter->ahw.revision_id << 16) | | 327 | regs->version = (1 << 24) | (adapter->ahw.revision_id << 16) | |
415 | (adapter->pdev)->device; | 328 | (adapter->pdev)->device; |
416 | /* which mode */ | ||
417 | regs_buff[0] = NXRD32(adapter, NETXEN_NIU_MODE); | ||
418 | mode = regs_buff[0]; | ||
419 | |||
420 | /* Common registers to all the modes */ | ||
421 | regs_buff[2] = NXRD32(adapter, NETXEN_NIU_STRAP_VALUE_SAVE_HIGHER); | ||
422 | /* GB/XGB Mode */ | ||
423 | mode = (mode / 2) - 1; | ||
424 | window = 0; | ||
425 | if (mode <= 1) { | ||
426 | for (i = 3; niu_registers[mode].reg[i - 3] != -1; i++) { | ||
427 | /* GB: port specific registers */ | ||
428 | if (mode == 0 && i >= 19) | ||
429 | window = adapter->physical_port * | ||
430 | NETXEN_NIC_PORT_WINDOW; | ||
431 | |||
432 | regs_buff[i] = NXRD32(adapter, | ||
433 | niu_registers[mode].reg[i - 3] + window); | ||
434 | } | ||
435 | 329 | ||
330 | if (adapter->is_up != NETXEN_ADAPTER_UP_MAGIC) | ||
331 | return; | ||
332 | |||
333 | regs_buff[i++] = NXRD32(adapter, CRB_CMDPEG_STATE); | ||
334 | regs_buff[i++] = NXRD32(adapter, CRB_RCVPEG_STATE); | ||
335 | regs_buff[i++] = NXRD32(adapter, CRB_FW_CAPABILITIES_1); | ||
336 | regs_buff[i++] = NXRDIO(adapter, adapter->crb_int_state_reg); | ||
337 | regs_buff[i++] = NXRD32(adapter, NX_CRB_DEV_REF_COUNT); | ||
338 | regs_buff[i++] = NXRD32(adapter, NX_CRB_DEV_STATE); | ||
339 | regs_buff[i++] = NXRD32(adapter, NETXEN_PEG_ALIVE_COUNTER); | ||
340 | regs_buff[i++] = NXRD32(adapter, NETXEN_PEG_HALT_STATUS1); | ||
341 | regs_buff[i++] = NXRD32(adapter, NETXEN_PEG_HALT_STATUS2); | ||
342 | |||
343 | regs_buff[i++] = NXRD32(adapter, NETXEN_CRB_PEG_NET_0+0x3c); | ||
344 | regs_buff[i++] = NXRD32(adapter, NETXEN_CRB_PEG_NET_1+0x3c); | ||
345 | regs_buff[i++] = NXRD32(adapter, NETXEN_CRB_PEG_NET_2+0x3c); | ||
346 | regs_buff[i++] = NXRD32(adapter, NETXEN_CRB_PEG_NET_3+0x3c); | ||
347 | |||
348 | if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) { | ||
349 | |||
350 | regs_buff[i++] = NXRD32(adapter, NETXEN_CRB_PEG_NET_4+0x3c); | ||
351 | i += 2; | ||
352 | |||
353 | regs_buff[i++] = NXRD32(adapter, CRB_XG_STATE_P3); | ||
354 | regs_buff[i++] = le32_to_cpu(*(adapter->tx_ring->hw_consumer)); | ||
355 | |||
356 | } else { | ||
357 | i++; | ||
358 | |||
359 | regs_buff[i++] = NXRD32(adapter, | ||
360 | NETXEN_NIU_XGE_CONFIG_0+(0x10000*port)); | ||
361 | regs_buff[i++] = NXRD32(adapter, | ||
362 | NETXEN_NIU_XGE_CONFIG_1+(0x10000*port)); | ||
363 | |||
364 | regs_buff[i++] = NXRD32(adapter, CRB_XG_STATE); | ||
365 | regs_buff[i++] = NXRDIO(adapter, | ||
366 | adapter->tx_ring->crb_cmd_consumer); | ||
367 | } | ||
368 | |||
369 | regs_buff[i++] = NXRDIO(adapter, adapter->tx_ring->crb_cmd_producer); | ||
370 | |||
371 | regs_buff[i++] = NXRDIO(adapter, | ||
372 | recv_ctx->rds_rings[0].crb_rcv_producer); | ||
373 | regs_buff[i++] = NXRDIO(adapter, | ||
374 | recv_ctx->rds_rings[1].crb_rcv_producer); | ||
375 | |||
376 | regs_buff[i++] = adapter->max_sds_rings; | ||
377 | |||
378 | for (ring = 0; ring < adapter->max_sds_rings; ring++) { | ||
379 | sds_ring = &(recv_ctx->sds_rings[ring]); | ||
380 | regs_buff[i++] = NXRDIO(adapter, | ||
381 | sds_ring->crb_sts_consumer); | ||
436 | } | 382 | } |
437 | } | 383 | } |
438 | 384 | ||
439 | static u32 netxen_nic_test_link(struct net_device *dev) | 385 | static u32 netxen_nic_test_link(struct net_device *dev) |
440 | { | 386 | { |
441 | struct netxen_adapter *adapter = netdev_priv(dev); | 387 | struct netxen_adapter *adapter = netdev_priv(dev); |
442 | __u32 status; | 388 | u32 val, port; |
443 | int val; | ||
444 | 389 | ||
445 | /* read which mode */ | 390 | port = adapter->physical_port; |
446 | if (adapter->ahw.port_type == NETXEN_NIC_GBE) { | 391 | if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) { |
447 | if (adapter->phy_read | 392 | val = NXRD32(adapter, CRB_XG_STATE_P3); |
448 | && adapter->phy_read(adapter, | 393 | val = XG_LINK_STATE_P3(adapter->ahw.pci_func, val); |
449 | NETXEN_NIU_GB_MII_MGMT_ADDR_PHY_STATUS, | 394 | return (val == XG_LINK_UP_P3) ? 0 : 1; |
450 | &status) != 0) | 395 | } else { |
451 | return -EIO; | ||
452 | else { | ||
453 | val = netxen_get_phy_link(status); | ||
454 | return !val; | ||
455 | } | ||
456 | } else if (adapter->ahw.port_type == NETXEN_NIC_XGBE) { | ||
457 | val = NXRD32(adapter, CRB_XG_STATE); | 396 | val = NXRD32(adapter, CRB_XG_STATE); |
397 | val = (val >> port*8) & 0xff; | ||
458 | return (val == XG_LINK_UP) ? 0 : 1; | 398 | return (val == XG_LINK_UP) ? 0 : 1; |
459 | } | 399 | } |
460 | return -EIO; | ||
461 | } | 400 | } |
462 | 401 | ||
463 | static int | 402 | static int |
@@ -690,8 +629,8 @@ static int netxen_nic_reg_test(struct net_device *dev) | |||
690 | u32 data_read, data_written; | 629 | u32 data_read, data_written; |
691 | 630 | ||
692 | data_read = NXRD32(adapter, NETXEN_PCIX_PH_REG(0)); | 631 | data_read = NXRD32(adapter, NETXEN_PCIX_PH_REG(0)); |
693 | if ((data_read & 0xffff) != PHAN_VENDOR_ID) | 632 | if ((data_read & 0xffff) != adapter->pdev->vendor) |
694 | return 1; | 633 | return 1; |
695 | 634 | ||
696 | data_written = (u32)0xa5a5a5a5; | 635 | data_written = (u32)0xa5a5a5a5; |
697 | 636 | ||
diff --git a/drivers/net/netxen/netxen_nic_hdr.h b/drivers/net/netxen/netxen_nic_hdr.h index 17bb3818d84e..622e4c8be937 100644 --- a/drivers/net/netxen/netxen_nic_hdr.h +++ b/drivers/net/netxen/netxen_nic_hdr.h | |||
@@ -19,7 +19,7 @@ | |||
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 | ||
@@ -664,40 +664,51 @@ enum { | |||
664 | #define NETXEN_NIU_AP_STATION_ADDR_0(I) (NETXEN_CRB_NIU+0xa0040+(I)*0x10000) | 664 | #define NETXEN_NIU_AP_STATION_ADDR_0(I) (NETXEN_CRB_NIU+0xa0040+(I)*0x10000) |
665 | #define NETXEN_NIU_AP_STATION_ADDR_1(I) (NETXEN_CRB_NIU+0xa0044+(I)*0x10000) | 665 | #define NETXEN_NIU_AP_STATION_ADDR_1(I) (NETXEN_CRB_NIU+0xa0044+(I)*0x10000) |
666 | 666 | ||
667 | |||
668 | #define TEST_AGT_CTRL (0x00) | ||
669 | |||
670 | #define TA_CTL_START 1 | ||
671 | #define TA_CTL_ENABLE 2 | ||
672 | #define TA_CTL_WRITE 4 | ||
673 | #define TA_CTL_BUSY 8 | ||
674 | |||
667 | /* | 675 | /* |
668 | * Register offsets for MN | 676 | * Register offsets for MN |
669 | */ | 677 | */ |
670 | #define MIU_CONTROL (0x000) | 678 | #define MIU_TEST_AGT_BASE (0x90) |
671 | #define MIU_TEST_AGT_CTRL (0x090) | 679 | |
672 | #define MIU_TEST_AGT_ADDR_LO (0x094) | 680 | #define MIU_TEST_AGT_ADDR_LO (0x04) |
673 | #define MIU_TEST_AGT_ADDR_HI (0x098) | 681 | #define MIU_TEST_AGT_ADDR_HI (0x08) |
674 | #define MIU_TEST_AGT_WRDATA_LO (0x0a0) | 682 | #define MIU_TEST_AGT_WRDATA_LO (0x10) |
675 | #define MIU_TEST_AGT_WRDATA_HI (0x0a4) | 683 | #define MIU_TEST_AGT_WRDATA_HI (0x14) |
676 | #define MIU_TEST_AGT_WRDATA(i) (0x0a0+(4*(i))) | 684 | #define MIU_TEST_AGT_WRDATA_UPPER_LO (0x20) |
677 | #define MIU_TEST_AGT_RDDATA_LO (0x0a8) | 685 | #define MIU_TEST_AGT_WRDATA_UPPER_HI (0x24) |
678 | #define MIU_TEST_AGT_RDDATA_HI (0x0ac) | 686 | #define MIU_TEST_AGT_WRDATA(i) (0x10+(0x10*((i)>>1))+(4*((i)&1))) |
679 | #define MIU_TEST_AGT_RDDATA(i) (0x0a8+(4*(i))) | 687 | #define MIU_TEST_AGT_RDDATA_LO (0x18) |
680 | #define MIU_TEST_AGT_ADDR_MASK 0xfffffff8 | 688 | #define MIU_TEST_AGT_RDDATA_HI (0x1c) |
681 | #define MIU_TEST_AGT_UPPER_ADDR(off) (0) | 689 | #define MIU_TEST_AGT_RDDATA_UPPER_LO (0x28) |
682 | 690 | #define MIU_TEST_AGT_RDDATA_UPPER_HI (0x2c) | |
683 | /* MIU_TEST_AGT_CTRL flags. work for SIU as well */ | 691 | #define MIU_TEST_AGT_RDDATA(i) (0x18+(0x10*((i)>>1))+(4*((i)&1))) |
684 | #define MIU_TA_CTL_START 1 | 692 | |
685 | #define MIU_TA_CTL_ENABLE 2 | 693 | #define MIU_TEST_AGT_ADDR_MASK 0xfffffff8 |
686 | #define MIU_TA_CTL_WRITE 4 | 694 | #define MIU_TEST_AGT_UPPER_ADDR(off) (0) |
687 | #define MIU_TA_CTL_BUSY 8 | 695 | |
688 | 696 | /* | |
689 | #define SIU_TEST_AGT_CTRL (0x060) | 697 | * Register offsets for MS |
690 | #define SIU_TEST_AGT_ADDR_LO (0x064) | 698 | */ |
691 | #define SIU_TEST_AGT_ADDR_HI (0x078) | 699 | #define SIU_TEST_AGT_BASE (0x60) |
692 | #define SIU_TEST_AGT_WRDATA_LO (0x068) | 700 | |
693 | #define SIU_TEST_AGT_WRDATA_HI (0x06c) | 701 | #define SIU_TEST_AGT_ADDR_LO (0x04) |
694 | #define SIU_TEST_AGT_WRDATA(i) (0x068+(4*(i))) | 702 | #define SIU_TEST_AGT_ADDR_HI (0x18) |
695 | #define SIU_TEST_AGT_RDDATA_LO (0x070) | 703 | #define SIU_TEST_AGT_WRDATA_LO (0x08) |
696 | #define SIU_TEST_AGT_RDDATA_HI (0x074) | 704 | #define SIU_TEST_AGT_WRDATA_HI (0x0c) |
697 | #define SIU_TEST_AGT_RDDATA(i) (0x070+(4*(i))) | 705 | #define SIU_TEST_AGT_WRDATA(i) (0x08+(4*(i))) |
698 | 706 | #define SIU_TEST_AGT_RDDATA_LO (0x10) | |
699 | #define SIU_TEST_AGT_ADDR_MASK 0x3ffff8 | 707 | #define SIU_TEST_AGT_RDDATA_HI (0x14) |
700 | #define SIU_TEST_AGT_UPPER_ADDR(off) ((off)>>22) | 708 | #define SIU_TEST_AGT_RDDATA(i) (0x10+(4*(i))) |
709 | |||
710 | #define SIU_TEST_AGT_ADDR_MASK 0x3ffff8 | ||
711 | #define SIU_TEST_AGT_UPPER_ADDR(off) ((off)>>22) | ||
701 | 712 | ||
702 | /* XG Link status */ | 713 | /* XG Link status */ |
703 | #define XG_LINK_UP 0x10 | 714 | #define XG_LINK_UP 0x10 |
@@ -859,6 +870,9 @@ enum { | |||
859 | (PCIX_SN_WINDOW_F0 + (0x20 * (func))) :\ | 870 | (PCIX_SN_WINDOW_F0 + (0x20 * (func))) :\ |
860 | (PCIX_SN_WINDOW_F4 + (0x10 * ((func)-4)))) | 871 | (PCIX_SN_WINDOW_F4 + (0x10 * ((func)-4)))) |
861 | 872 | ||
873 | #define PCIX_OCM_WINDOW (0x10800) | ||
874 | #define PCIX_OCM_WINDOW_REG(func) (PCIX_OCM_WINDOW + 0x20 * (func)) | ||
875 | |||
862 | #define PCIX_TARGET_STATUS (0x10118) | 876 | #define PCIX_TARGET_STATUS (0x10118) |
863 | #define PCIX_TARGET_STATUS_F1 (0x10160) | 877 | #define PCIX_TARGET_STATUS_F1 (0x10160) |
864 | #define PCIX_TARGET_STATUS_F2 (0x10164) | 878 | #define PCIX_TARGET_STATUS_F2 (0x10164) |
@@ -955,7 +969,8 @@ enum { | |||
955 | #define NX_DEV_READY 3 | 969 | #define NX_DEV_READY 3 |
956 | #define NX_DEV_NEED_RESET 4 | 970 | #define NX_DEV_NEED_RESET 4 |
957 | #define NX_DEV_NEED_QUISCENT 5 | 971 | #define NX_DEV_NEED_QUISCENT 5 |
958 | #define NX_DEV_FAILED 6 | 972 | #define NX_DEV_NEED_AER 6 |
973 | #define NX_DEV_FAILED 7 | ||
959 | 974 | ||
960 | #define NX_RCODE_DRIVER_INFO 0x20000000 | 975 | #define NX_RCODE_DRIVER_INFO 0x20000000 |
961 | #define NX_RCODE_DRIVER_CAN_RELOAD 0x40000000 | 976 | #define NX_RCODE_DRIVER_CAN_RELOAD 0x40000000 |
diff --git a/drivers/net/netxen/netxen_nic_hw.c b/drivers/net/netxen/netxen_nic_hw.c index 52a3798d8d94..b1cf46a0c48c 100644 --- a/drivers/net/netxen/netxen_nic_hw.c +++ b/drivers/net/netxen/netxen_nic_hw.c | |||
@@ -19,10 +19,11 @@ | |||
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/slab.h> | ||
26 | #include "netxen_nic.h" | 27 | #include "netxen_nic.h" |
27 | #include "netxen_nic_hw.h" | 28 | #include "netxen_nic_hw.h" |
28 | 29 | ||
@@ -31,6 +32,7 @@ | |||
31 | #define MASK(n) ((1ULL<<(n))-1) | 32 | #define MASK(n) ((1ULL<<(n))-1) |
32 | #define MN_WIN(addr) (((addr & 0x1fc0000) >> 1) | ((addr >> 25) & 0x3ff)) | 33 | #define MN_WIN(addr) (((addr & 0x1fc0000) >> 1) | ((addr >> 25) & 0x3ff)) |
33 | #define OCM_WIN(addr) (((addr & 0x1ff0000) >> 1) | ((addr >> 25) & 0x3ff)) | 34 | #define OCM_WIN(addr) (((addr & 0x1ff0000) >> 1) | ((addr >> 25) & 0x3ff)) |
35 | #define OCM_WIN_P3P(addr) (addr & 0xffc0000) | ||
34 | #define MS_WIN(addr) (addr & 0x0ffc0000) | 36 | #define MS_WIN(addr) (addr & 0x0ffc0000) |
35 | 37 | ||
36 | #define GET_MEM_OFFS_2M(addr) (addr & MASK(18)) | 38 | #define GET_MEM_OFFS_2M(addr) (addr & MASK(18)) |
@@ -41,6 +43,11 @@ | |||
41 | #define CRB_HI(off) ((crb_hub_agt[CRB_BLK(off)] << 20) | ((off) & 0xf0000)) | 43 | #define CRB_HI(off) ((crb_hub_agt[CRB_BLK(off)] << 20) | ((off) & 0xf0000)) |
42 | #define CRB_INDIRECT_2M (0x1e0000UL) | 44 | #define CRB_INDIRECT_2M (0x1e0000UL) |
43 | 45 | ||
46 | static void netxen_nic_io_write_128M(struct netxen_adapter *adapter, | ||
47 | void __iomem *addr, u32 data); | ||
48 | static u32 netxen_nic_io_read_128M(struct netxen_adapter *adapter, | ||
49 | void __iomem *addr); | ||
50 | |||
44 | #ifndef readq | 51 | #ifndef readq |
45 | static inline u64 readq(void __iomem *addr) | 52 | static inline u64 readq(void __iomem *addr) |
46 | { | 53 | { |
@@ -326,7 +333,7 @@ netxen_pcie_sem_lock(struct netxen_adapter *adapter, int sem, u32 id_reg) | |||
326 | if (done == 1) | 333 | if (done == 1) |
327 | break; | 334 | break; |
328 | if (++timeout >= NETXEN_PCIE_SEM_TIMEOUT) | 335 | if (++timeout >= NETXEN_PCIE_SEM_TIMEOUT) |
329 | return -1; | 336 | return -EIO; |
330 | msleep(1); | 337 | msleep(1); |
331 | } | 338 | } |
332 | 339 | ||
@@ -339,8 +346,7 @@ netxen_pcie_sem_lock(struct netxen_adapter *adapter, int sem, u32 id_reg) | |||
339 | void | 346 | void |
340 | netxen_pcie_sem_unlock(struct netxen_adapter *adapter, int sem) | 347 | netxen_pcie_sem_unlock(struct netxen_adapter *adapter, int sem) |
341 | { | 348 | { |
342 | int val; | 349 | NXRD32(adapter, NETXEN_PCIE_REG(PCIE_SEM_UNLOCK(sem))); |
343 | val = NXRD32(adapter, NETXEN_PCIE_REG(PCIE_SEM_UNLOCK(sem))); | ||
344 | } | 350 | } |
345 | 351 | ||
346 | int netxen_niu_xg_init_port(struct netxen_adapter *adapter, int port) | 352 | int netxen_niu_xg_init_port(struct netxen_adapter *adapter, int port) |
@@ -534,7 +540,7 @@ void netxen_p2_nic_set_multi(struct net_device *netdev) | |||
534 | struct netxen_adapter *adapter = netdev_priv(netdev); | 540 | struct netxen_adapter *adapter = netdev_priv(netdev); |
535 | struct dev_mc_list *mc_ptr; | 541 | struct dev_mc_list *mc_ptr; |
536 | u8 null_addr[6]; | 542 | u8 null_addr[6]; |
537 | int index = 0; | 543 | int i; |
538 | 544 | ||
539 | memset(null_addr, 0, 6); | 545 | memset(null_addr, 0, 6); |
540 | 546 | ||
@@ -549,7 +555,7 @@ void netxen_p2_nic_set_multi(struct net_device *netdev) | |||
549 | return; | 555 | return; |
550 | } | 556 | } |
551 | 557 | ||
552 | if (netdev->mc_count == 0) { | 558 | if (netdev_mc_empty(netdev)) { |
553 | adapter->set_promisc(adapter, | 559 | adapter->set_promisc(adapter, |
554 | NETXEN_NIU_NON_PROMISC_MODE); | 560 | NETXEN_NIU_NON_PROMISC_MODE); |
555 | netxen_nic_disable_mcast_filter(adapter); | 561 | netxen_nic_disable_mcast_filter(adapter); |
@@ -558,23 +564,20 @@ void netxen_p2_nic_set_multi(struct net_device *netdev) | |||
558 | 564 | ||
559 | adapter->set_promisc(adapter, NETXEN_NIU_ALLMULTI_MODE); | 565 | adapter->set_promisc(adapter, NETXEN_NIU_ALLMULTI_MODE); |
560 | if (netdev->flags & IFF_ALLMULTI || | 566 | if (netdev->flags & IFF_ALLMULTI || |
561 | netdev->mc_count > adapter->max_mc_count) { | 567 | netdev_mc_count(netdev) > adapter->max_mc_count) { |
562 | netxen_nic_disable_mcast_filter(adapter); | 568 | netxen_nic_disable_mcast_filter(adapter); |
563 | return; | 569 | return; |
564 | } | 570 | } |
565 | 571 | ||
566 | netxen_nic_enable_mcast_filter(adapter); | 572 | netxen_nic_enable_mcast_filter(adapter); |
567 | 573 | ||
568 | for (mc_ptr = netdev->mc_list; mc_ptr; mc_ptr = mc_ptr->next, index++) | 574 | i = 0; |
569 | netxen_nic_set_mcast_addr(adapter, index, mc_ptr->dmi_addr); | 575 | netdev_for_each_mc_addr(mc_ptr, netdev) |
570 | 576 | netxen_nic_set_mcast_addr(adapter, i++, mc_ptr->dmi_addr); | |
571 | if (index != netdev->mc_count) | ||
572 | printk(KERN_WARNING "%s: %s multicast address count mismatch\n", | ||
573 | netxen_nic_driver_name, netdev->name); | ||
574 | 577 | ||
575 | /* Clear out remaining addresses */ | 578 | /* Clear out remaining addresses */ |
576 | for (; index < adapter->max_mc_count; index++) | 579 | while (i < adapter->max_mc_count) |
577 | netxen_nic_set_mcast_addr(adapter, index, null_addr); | 580 | netxen_nic_set_mcast_addr(adapter, i++, null_addr); |
578 | } | 581 | } |
579 | 582 | ||
580 | static int | 583 | static int |
@@ -685,6 +688,9 @@ void netxen_p3_nic_set_multi(struct net_device *netdev) | |||
685 | struct list_head *head; | 688 | struct list_head *head; |
686 | nx_mac_list_t *cur; | 689 | nx_mac_list_t *cur; |
687 | 690 | ||
691 | if (adapter->is_up != NETXEN_ADAPTER_UP_MAGIC) | ||
692 | return; | ||
693 | |||
688 | list_splice_tail_init(&adapter->mac_list, &del_list); | 694 | list_splice_tail_init(&adapter->mac_list, &del_list); |
689 | 695 | ||
690 | nx_p3_nic_add_mac(adapter, adapter->mac_addr, &del_list); | 696 | nx_p3_nic_add_mac(adapter, adapter->mac_addr, &del_list); |
@@ -696,16 +702,14 @@ void netxen_p3_nic_set_multi(struct net_device *netdev) | |||
696 | } | 702 | } |
697 | 703 | ||
698 | if ((netdev->flags & IFF_ALLMULTI) || | 704 | if ((netdev->flags & IFF_ALLMULTI) || |
699 | (netdev->mc_count > adapter->max_mc_count)) { | 705 | (netdev_mc_count(netdev) > adapter->max_mc_count)) { |
700 | mode = VPORT_MISS_MODE_ACCEPT_MULTI; | 706 | mode = VPORT_MISS_MODE_ACCEPT_MULTI; |
701 | goto send_fw_cmd; | 707 | goto send_fw_cmd; |
702 | } | 708 | } |
703 | 709 | ||
704 | if (netdev->mc_count > 0) { | 710 | if (!netdev_mc_empty(netdev)) { |
705 | for (mc_ptr = netdev->mc_list; mc_ptr; | 711 | netdev_for_each_mc_addr(mc_ptr, netdev) |
706 | mc_ptr = mc_ptr->next) { | ||
707 | nx_p3_nic_add_mac(adapter, mc_ptr->dmi_addr, &del_list); | 712 | nx_p3_nic_add_mac(adapter, mc_ptr->dmi_addr, &del_list); |
708 | } | ||
709 | } | 713 | } |
710 | 714 | ||
711 | send_fw_cmd: | 715 | send_fw_cmd: |
@@ -769,17 +773,20 @@ int netxen_p3_nic_set_mac_addr(struct netxen_adapter *adapter, u8 *addr) | |||
769 | int netxen_config_intr_coalesce(struct netxen_adapter *adapter) | 773 | int netxen_config_intr_coalesce(struct netxen_adapter *adapter) |
770 | { | 774 | { |
771 | nx_nic_req_t req; | 775 | nx_nic_req_t req; |
772 | u64 word; | 776 | u64 word[6]; |
773 | int rv; | 777 | int rv, i; |
774 | 778 | ||
775 | memset(&req, 0, sizeof(nx_nic_req_t)); | 779 | memset(&req, 0, sizeof(nx_nic_req_t)); |
780 | memset(word, 0, sizeof(word)); | ||
776 | 781 | ||
777 | req.qhdr = cpu_to_le64(NX_HOST_REQUEST << 23); | 782 | req.qhdr = cpu_to_le64(NX_HOST_REQUEST << 23); |
778 | 783 | ||
779 | word = NETXEN_CONFIG_INTR_COALESCE | ((u64)adapter->portnum << 16); | 784 | word[0] = NETXEN_CONFIG_INTR_COALESCE | ((u64)adapter->portnum << 16); |
780 | req.req_hdr = cpu_to_le64(word); | 785 | req.req_hdr = cpu_to_le64(word[0]); |
781 | 786 | ||
782 | memcpy(&req.words[0], &adapter->coal, sizeof(adapter->coal)); | 787 | memcpy(&word[0], &adapter->coal, sizeof(adapter->coal)); |
788 | for (i = 0; i < 6; i++) | ||
789 | req.words[i] = cpu_to_le64(word[i]); | ||
783 | 790 | ||
784 | rv = netxen_send_cmd_descs(adapter, (struct cmd_desc_type0 *)&req, 1); | 791 | rv = netxen_send_cmd_descs(adapter, (struct cmd_desc_type0 *)&req, 1); |
785 | if (rv != 0) { | 792 | if (rv != 0) { |
@@ -1025,7 +1032,7 @@ static int netxen_get_flash_block(struct netxen_adapter *adapter, int base, | |||
1025 | return 0; | 1032 | return 0; |
1026 | } | 1033 | } |
1027 | 1034 | ||
1028 | int netxen_get_flash_mac_addr(struct netxen_adapter *adapter, __le64 *mac) | 1035 | int netxen_get_flash_mac_addr(struct netxen_adapter *adapter, u64 *mac) |
1029 | { | 1036 | { |
1030 | __le32 *pmac = (__le32 *) mac; | 1037 | __le32 *pmac = (__le32 *) mac; |
1031 | u32 offset; | 1038 | u32 offset; |
@@ -1050,7 +1057,7 @@ int netxen_get_flash_mac_addr(struct netxen_adapter *adapter, __le64 *mac) | |||
1050 | return 0; | 1057 | return 0; |
1051 | } | 1058 | } |
1052 | 1059 | ||
1053 | int netxen_p3_get_mac_addr(struct netxen_adapter *adapter, __le64 *mac) | 1060 | int netxen_p3_get_mac_addr(struct netxen_adapter *adapter, u64 *mac) |
1054 | { | 1061 | { |
1055 | uint32_t crbaddr, mac_hi, mac_lo; | 1062 | uint32_t crbaddr, mac_hi, mac_lo; |
1056 | int pci_func = adapter->ahw.pci_func; | 1063 | int pci_func = adapter->ahw.pci_func; |
@@ -1073,89 +1080,71 @@ int netxen_p3_get_mac_addr(struct netxen_adapter *adapter, __le64 *mac) | |||
1073 | * Changes the CRB window to the specified window. | 1080 | * Changes the CRB window to the specified window. |
1074 | */ | 1081 | */ |
1075 | static void | 1082 | static void |
1076 | netxen_nic_pci_change_crbwindow_128M(struct netxen_adapter *adapter, u32 wndw) | 1083 | netxen_nic_pci_set_crbwindow_128M(struct netxen_adapter *adapter, |
1084 | u32 window) | ||
1077 | { | 1085 | { |
1078 | void __iomem *offset; | 1086 | void __iomem *offset; |
1079 | u32 tmp; | 1087 | int count = 10; |
1080 | int count = 0; | 1088 | u8 func = adapter->ahw.pci_func; |
1081 | uint8_t func = adapter->ahw.pci_func; | ||
1082 | 1089 | ||
1083 | if (adapter->curr_window == wndw) | 1090 | if (adapter->ahw.crb_win == window) |
1084 | return; | 1091 | return; |
1085 | /* | 1092 | |
1086 | * Move the CRB window. | ||
1087 | * We need to write to the "direct access" region of PCI | ||
1088 | * to avoid a race condition where the window register has | ||
1089 | * not been successfully written across CRB before the target | ||
1090 | * register address is received by PCI. The direct region bypasses | ||
1091 | * the CRB bus. | ||
1092 | */ | ||
1093 | offset = PCI_OFFSET_SECOND_RANGE(adapter, | 1093 | offset = PCI_OFFSET_SECOND_RANGE(adapter, |
1094 | NETXEN_PCIX_PH_REG(PCIE_CRB_WINDOW_REG(func))); | 1094 | NETXEN_PCIX_PH_REG(PCIE_CRB_WINDOW_REG(func))); |
1095 | 1095 | ||
1096 | if (wndw & 0x1) | 1096 | writel(window, offset); |
1097 | wndw = NETXEN_WINDOW_ONE; | 1097 | do { |
1098 | if (window == readl(offset)) | ||
1099 | break; | ||
1098 | 1100 | ||
1099 | writel(wndw, offset); | 1101 | if (printk_ratelimit()) |
1102 | dev_warn(&adapter->pdev->dev, | ||
1103 | "failed to set CRB window to %d\n", | ||
1104 | (window == NETXEN_WINDOW_ONE)); | ||
1105 | udelay(1); | ||
1100 | 1106 | ||
1101 | /* MUST make sure window is set before we forge on... */ | 1107 | } while (--count > 0); |
1102 | while ((tmp = readl(offset)) != wndw) { | ||
1103 | printk(KERN_WARNING "%s: %s WARNING: CRB window value not " | ||
1104 | "registered properly: 0x%08x.\n", | ||
1105 | netxen_nic_driver_name, __func__, tmp); | ||
1106 | mdelay(1); | ||
1107 | if (count >= 10) | ||
1108 | break; | ||
1109 | count++; | ||
1110 | } | ||
1111 | 1108 | ||
1112 | if (wndw == NETXEN_WINDOW_ONE) | 1109 | if (count > 0) |
1113 | adapter->curr_window = 1; | 1110 | adapter->ahw.crb_win = window; |
1114 | else | ||
1115 | adapter->curr_window = 0; | ||
1116 | } | 1111 | } |
1117 | 1112 | ||
1118 | /* | 1113 | /* |
1119 | * Return -1 if off is not valid, | 1114 | * Returns < 0 if off is not valid, |
1120 | * 1 if window access is needed. 'off' is set to offset from | 1115 | * 1 if window access is needed. 'off' is set to offset from |
1121 | * CRB space in 128M pci map | 1116 | * CRB space in 128M pci map |
1122 | * 0 if no window access is needed. 'off' is set to 2M addr | 1117 | * 0 if no window access is needed. 'off' is set to 2M addr |
1123 | * In: 'off' is offset from base in 128M pci map | 1118 | * In: 'off' is offset from base in 128M pci map |
1124 | */ | 1119 | */ |
1125 | static int | 1120 | static int |
1126 | netxen_nic_pci_get_crb_addr_2M(struct netxen_adapter *adapter, ulong *off) | 1121 | netxen_nic_pci_get_crb_addr_2M(struct netxen_adapter *adapter, |
1122 | ulong off, void __iomem **addr) | ||
1127 | { | 1123 | { |
1128 | crb_128M_2M_sub_block_map_t *m; | 1124 | crb_128M_2M_sub_block_map_t *m; |
1129 | 1125 | ||
1130 | 1126 | ||
1131 | if (*off >= NETXEN_CRB_MAX) | 1127 | if ((off >= NETXEN_CRB_MAX) || (off < NETXEN_PCI_CRBSPACE)) |
1132 | return -1; | 1128 | return -EINVAL; |
1133 | |||
1134 | if (*off >= NETXEN_PCI_CAMQM && (*off < NETXEN_PCI_CAMQM_2M_END)) { | ||
1135 | *off = (*off - NETXEN_PCI_CAMQM) + NETXEN_PCI_CAMQM_2M_BASE + | ||
1136 | (ulong)adapter->ahw.pci_base0; | ||
1137 | return 0; | ||
1138 | } | ||
1139 | |||
1140 | if (*off < NETXEN_PCI_CRBSPACE) | ||
1141 | return -1; | ||
1142 | 1129 | ||
1143 | *off -= NETXEN_PCI_CRBSPACE; | 1130 | off -= NETXEN_PCI_CRBSPACE; |
1144 | 1131 | ||
1145 | /* | 1132 | /* |
1146 | * Try direct map | 1133 | * Try direct map |
1147 | */ | 1134 | */ |
1148 | m = &crb_128M_2M_map[CRB_BLK(*off)].sub_block[CRB_SUBBLK(*off)]; | 1135 | m = &crb_128M_2M_map[CRB_BLK(off)].sub_block[CRB_SUBBLK(off)]; |
1149 | 1136 | ||
1150 | if (m->valid && (m->start_128M <= *off) && (m->end_128M > *off)) { | 1137 | if (m->valid && (m->start_128M <= off) && (m->end_128M > off)) { |
1151 | *off = *off + m->start_2M - m->start_128M + | 1138 | *addr = adapter->ahw.pci_base0 + m->start_2M + |
1152 | (ulong)adapter->ahw.pci_base0; | 1139 | (off - m->start_128M); |
1153 | return 0; | 1140 | return 0; |
1154 | } | 1141 | } |
1155 | 1142 | ||
1156 | /* | 1143 | /* |
1157 | * Not in direct map, use crb window | 1144 | * Not in direct map, use crb window |
1158 | */ | 1145 | */ |
1146 | *addr = adapter->ahw.pci_base0 + CRB_INDIRECT_2M + | ||
1147 | (off & MASK(16)); | ||
1159 | return 1; | 1148 | return 1; |
1160 | } | 1149 | } |
1161 | 1150 | ||
@@ -1165,52 +1154,78 @@ netxen_nic_pci_get_crb_addr_2M(struct netxen_adapter *adapter, ulong *off) | |||
1165 | * side effect: lock crb window | 1154 | * side effect: lock crb window |
1166 | */ | 1155 | */ |
1167 | static void | 1156 | static void |
1168 | netxen_nic_pci_set_crbwindow_2M(struct netxen_adapter *adapter, ulong *off) | 1157 | netxen_nic_pci_set_crbwindow_2M(struct netxen_adapter *adapter, ulong off) |
1169 | { | 1158 | { |
1170 | u32 win_read; | 1159 | u32 window; |
1160 | void __iomem *addr = adapter->ahw.pci_base0 + CRB_WINDOW_2M; | ||
1171 | 1161 | ||
1172 | adapter->crb_win = CRB_HI(*off); | 1162 | off -= NETXEN_PCI_CRBSPACE; |
1173 | writel(adapter->crb_win, (adapter->ahw.pci_base0 + CRB_WINDOW_2M)); | 1163 | |
1174 | /* | 1164 | window = CRB_HI(off); |
1175 | * Read back value to make sure write has gone through before trying | 1165 | |
1176 | * to use it. | 1166 | if (adapter->ahw.crb_win == window) |
1177 | */ | 1167 | return; |
1178 | win_read = readl(adapter->ahw.pci_base0 + CRB_WINDOW_2M); | 1168 | |
1179 | if (win_read != adapter->crb_win) { | 1169 | writel(window, addr); |
1180 | printk(KERN_ERR "%s: Written crbwin (0x%x) != " | 1170 | if (readl(addr) != window) { |
1181 | "Read crbwin (0x%x), off=0x%lx\n", | 1171 | if (printk_ratelimit()) |
1182 | __func__, adapter->crb_win, win_read, *off); | 1172 | dev_warn(&adapter->pdev->dev, |
1173 | "failed to set CRB window to %d off 0x%lx\n", | ||
1174 | window, off); | ||
1183 | } | 1175 | } |
1184 | *off = (*off & MASK(16)) + CRB_INDIRECT_2M + | 1176 | adapter->ahw.crb_win = window; |
1185 | (ulong)adapter->ahw.pci_base0; | 1177 | } |
1178 | |||
1179 | static void __iomem * | ||
1180 | netxen_nic_map_indirect_address_128M(struct netxen_adapter *adapter, | ||
1181 | ulong win_off, void __iomem **mem_ptr) | ||
1182 | { | ||
1183 | ulong off = win_off; | ||
1184 | void __iomem *addr; | ||
1185 | resource_size_t mem_base; | ||
1186 | |||
1187 | if (ADDR_IN_WINDOW1(win_off)) | ||
1188 | off = NETXEN_CRB_NORMAL(win_off); | ||
1189 | |||
1190 | addr = pci_base_offset(adapter, off); | ||
1191 | if (addr) | ||
1192 | return addr; | ||
1193 | |||
1194 | if (adapter->ahw.pci_len0 == 0) | ||
1195 | off -= NETXEN_PCI_CRBSPACE; | ||
1196 | |||
1197 | mem_base = pci_resource_start(adapter->pdev, 0); | ||
1198 | *mem_ptr = ioremap(mem_base + (off & PAGE_MASK), PAGE_SIZE); | ||
1199 | if (*mem_ptr) | ||
1200 | addr = *mem_ptr + (off & (PAGE_SIZE - 1)); | ||
1201 | |||
1202 | return addr; | ||
1186 | } | 1203 | } |
1187 | 1204 | ||
1188 | static int | 1205 | static int |
1189 | netxen_nic_hw_write_wx_128M(struct netxen_adapter *adapter, ulong off, u32 data) | 1206 | netxen_nic_hw_write_wx_128M(struct netxen_adapter *adapter, ulong off, u32 data) |
1190 | { | 1207 | { |
1191 | unsigned long flags; | 1208 | unsigned long flags; |
1192 | void __iomem *addr; | 1209 | void __iomem *addr, *mem_ptr = NULL; |
1193 | |||
1194 | if (ADDR_IN_WINDOW1(off)) | ||
1195 | addr = NETXEN_CRB_NORMALIZE(adapter, off); | ||
1196 | else | ||
1197 | addr = pci_base_offset(adapter, off); | ||
1198 | 1210 | ||
1199 | BUG_ON(!addr); | 1211 | addr = netxen_nic_map_indirect_address_128M(adapter, off, &mem_ptr); |
1212 | if (!addr) | ||
1213 | return -EIO; | ||
1200 | 1214 | ||
1201 | if (ADDR_IN_WINDOW1(off)) { /* Window 1 */ | 1215 | if (ADDR_IN_WINDOW1(off)) { /* Window 1 */ |
1202 | read_lock(&adapter->adapter_lock); | 1216 | netxen_nic_io_write_128M(adapter, addr, data); |
1203 | writel(data, addr); | 1217 | } else { /* Window 0 */ |
1204 | read_unlock(&adapter->adapter_lock); | 1218 | write_lock_irqsave(&adapter->ahw.crb_lock, flags); |
1205 | } else { /* Window 0 */ | 1219 | netxen_nic_pci_set_crbwindow_128M(adapter, 0); |
1206 | write_lock_irqsave(&adapter->adapter_lock, flags); | ||
1207 | addr = pci_base_offset(adapter, off); | ||
1208 | netxen_nic_pci_change_crbwindow_128M(adapter, 0); | ||
1209 | writel(data, addr); | 1220 | writel(data, addr); |
1210 | netxen_nic_pci_change_crbwindow_128M(adapter, 1); | 1221 | netxen_nic_pci_set_crbwindow_128M(adapter, |
1211 | write_unlock_irqrestore(&adapter->adapter_lock, flags); | 1222 | NETXEN_WINDOW_ONE); |
1223 | write_unlock_irqrestore(&adapter->ahw.crb_lock, flags); | ||
1212 | } | 1224 | } |
1213 | 1225 | ||
1226 | if (mem_ptr) | ||
1227 | iounmap(mem_ptr); | ||
1228 | |||
1214 | return 0; | 1229 | return 0; |
1215 | } | 1230 | } |
1216 | 1231 | ||
@@ -1218,28 +1233,27 @@ static u32 | |||
1218 | netxen_nic_hw_read_wx_128M(struct netxen_adapter *adapter, ulong off) | 1233 | netxen_nic_hw_read_wx_128M(struct netxen_adapter *adapter, ulong off) |
1219 | { | 1234 | { |
1220 | unsigned long flags; | 1235 | unsigned long flags; |
1221 | void __iomem *addr; | 1236 | void __iomem *addr, *mem_ptr = NULL; |
1222 | u32 data; | 1237 | u32 data; |
1223 | 1238 | ||
1224 | if (ADDR_IN_WINDOW1(off)) | 1239 | addr = netxen_nic_map_indirect_address_128M(adapter, off, &mem_ptr); |
1225 | addr = NETXEN_CRB_NORMALIZE(adapter, off); | 1240 | if (!addr) |
1226 | else | 1241 | return -EIO; |
1227 | addr = pci_base_offset(adapter, off); | ||
1228 | |||
1229 | BUG_ON(!addr); | ||
1230 | 1242 | ||
1231 | if (ADDR_IN_WINDOW1(off)) { /* Window 1 */ | 1243 | if (ADDR_IN_WINDOW1(off)) { /* Window 1 */ |
1232 | read_lock(&adapter->adapter_lock); | 1244 | data = netxen_nic_io_read_128M(adapter, addr); |
1245 | } else { /* Window 0 */ | ||
1246 | write_lock_irqsave(&adapter->ahw.crb_lock, flags); | ||
1247 | netxen_nic_pci_set_crbwindow_128M(adapter, 0); | ||
1233 | data = readl(addr); | 1248 | data = readl(addr); |
1234 | read_unlock(&adapter->adapter_lock); | 1249 | netxen_nic_pci_set_crbwindow_128M(adapter, |
1235 | } else { /* Window 0 */ | 1250 | NETXEN_WINDOW_ONE); |
1236 | write_lock_irqsave(&adapter->adapter_lock, flags); | 1251 | write_unlock_irqrestore(&adapter->ahw.crb_lock, flags); |
1237 | netxen_nic_pci_change_crbwindow_128M(adapter, 0); | ||
1238 | data = readl(addr); | ||
1239 | netxen_nic_pci_change_crbwindow_128M(adapter, 1); | ||
1240 | write_unlock_irqrestore(&adapter->adapter_lock, flags); | ||
1241 | } | 1252 | } |
1242 | 1253 | ||
1254 | if (mem_ptr) | ||
1255 | iounmap(mem_ptr); | ||
1256 | |||
1243 | return data; | 1257 | return data; |
1244 | } | 1258 | } |
1245 | 1259 | ||
@@ -1248,28 +1262,30 @@ netxen_nic_hw_write_wx_2M(struct netxen_adapter *adapter, ulong off, u32 data) | |||
1248 | { | 1262 | { |
1249 | unsigned long flags; | 1263 | unsigned long flags; |
1250 | int rv; | 1264 | int rv; |
1265 | void __iomem *addr = NULL; | ||
1251 | 1266 | ||
1252 | rv = netxen_nic_pci_get_crb_addr_2M(adapter, &off); | 1267 | rv = netxen_nic_pci_get_crb_addr_2M(adapter, off, &addr); |
1253 | 1268 | ||
1254 | if (rv == -1) { | 1269 | if (rv == 0) { |
1255 | printk(KERN_ERR "%s: invalid offset: 0x%016lx\n", | 1270 | writel(data, addr); |
1256 | __func__, off); | 1271 | return 0; |
1257 | dump_stack(); | ||
1258 | return -1; | ||
1259 | } | 1272 | } |
1260 | 1273 | ||
1261 | if (rv == 1) { | 1274 | if (rv > 0) { |
1262 | write_lock_irqsave(&adapter->adapter_lock, flags); | 1275 | /* indirect access */ |
1276 | write_lock_irqsave(&adapter->ahw.crb_lock, flags); | ||
1263 | crb_win_lock(adapter); | 1277 | crb_win_lock(adapter); |
1264 | netxen_nic_pci_set_crbwindow_2M(adapter, &off); | 1278 | netxen_nic_pci_set_crbwindow_2M(adapter, off); |
1265 | writel(data, (void __iomem *)off); | 1279 | writel(data, addr); |
1266 | crb_win_unlock(adapter); | 1280 | crb_win_unlock(adapter); |
1267 | write_unlock_irqrestore(&adapter->adapter_lock, flags); | 1281 | write_unlock_irqrestore(&adapter->ahw.crb_lock, flags); |
1268 | } else | 1282 | return 0; |
1269 | writel(data, (void __iomem *)off); | 1283 | } |
1270 | |||
1271 | 1284 | ||
1272 | return 0; | 1285 | dev_err(&adapter->pdev->dev, |
1286 | "%s: invalid offset: 0x%016lx\n", __func__, off); | ||
1287 | dump_stack(); | ||
1288 | return -EIO; | ||
1273 | } | 1289 | } |
1274 | 1290 | ||
1275 | static u32 | 1291 | static u32 |
@@ -1278,102 +1294,37 @@ netxen_nic_hw_read_wx_2M(struct netxen_adapter *adapter, ulong off) | |||
1278 | unsigned long flags; | 1294 | unsigned long flags; |
1279 | int rv; | 1295 | int rv; |
1280 | u32 data; | 1296 | u32 data; |
1297 | void __iomem *addr = NULL; | ||
1281 | 1298 | ||
1282 | rv = netxen_nic_pci_get_crb_addr_2M(adapter, &off); | 1299 | rv = netxen_nic_pci_get_crb_addr_2M(adapter, off, &addr); |
1283 | 1300 | ||
1284 | if (rv == -1) { | 1301 | if (rv == 0) |
1285 | printk(KERN_ERR "%s: invalid offset: 0x%016lx\n", | 1302 | return readl(addr); |
1286 | __func__, off); | ||
1287 | dump_stack(); | ||
1288 | return -1; | ||
1289 | } | ||
1290 | 1303 | ||
1291 | if (rv == 1) { | 1304 | if (rv > 0) { |
1292 | write_lock_irqsave(&adapter->adapter_lock, flags); | 1305 | /* indirect access */ |
1306 | write_lock_irqsave(&adapter->ahw.crb_lock, flags); | ||
1293 | crb_win_lock(adapter); | 1307 | crb_win_lock(adapter); |
1294 | netxen_nic_pci_set_crbwindow_2M(adapter, &off); | 1308 | netxen_nic_pci_set_crbwindow_2M(adapter, off); |
1295 | data = readl((void __iomem *)off); | 1309 | data = readl(addr); |
1296 | crb_win_unlock(adapter); | 1310 | crb_win_unlock(adapter); |
1297 | write_unlock_irqrestore(&adapter->adapter_lock, flags); | 1311 | write_unlock_irqrestore(&adapter->ahw.crb_lock, flags); |
1298 | } else | 1312 | return data; |
1299 | data = readl((void __iomem *)off); | ||
1300 | |||
1301 | return data; | ||
1302 | } | ||
1303 | |||
1304 | static int netxen_pci_set_window_warning_count; | ||
1305 | |||
1306 | static unsigned long | ||
1307 | netxen_nic_pci_set_window_128M(struct netxen_adapter *adapter, | ||
1308 | unsigned long long addr) | ||
1309 | { | ||
1310 | void __iomem *offset; | ||
1311 | int window; | ||
1312 | unsigned long long qdr_max; | ||
1313 | uint8_t func = adapter->ahw.pci_func; | ||
1314 | |||
1315 | if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) { | ||
1316 | qdr_max = NETXEN_ADDR_QDR_NET_MAX_P2; | ||
1317 | } else { | ||
1318 | qdr_max = NETXEN_ADDR_QDR_NET_MAX_P3; | ||
1319 | } | 1313 | } |
1320 | 1314 | ||
1321 | if (ADDR_IN_RANGE(addr, NETXEN_ADDR_DDR_NET, NETXEN_ADDR_DDR_NET_MAX)) { | 1315 | dev_err(&adapter->pdev->dev, |
1322 | /* DDR network side */ | 1316 | "%s: invalid offset: 0x%016lx\n", __func__, off); |
1323 | addr -= NETXEN_ADDR_DDR_NET; | 1317 | dump_stack(); |
1324 | window = (addr >> 25) & 0x3ff; | 1318 | return -1; |
1325 | if (adapter->ahw.ddr_mn_window != window) { | ||
1326 | adapter->ahw.ddr_mn_window = window; | ||
1327 | offset = PCI_OFFSET_SECOND_RANGE(adapter, | ||
1328 | NETXEN_PCIX_PH_REG(PCIE_MN_WINDOW_REG(func))); | ||
1329 | writel(window, offset); | ||
1330 | /* MUST make sure window is set before we forge on... */ | ||
1331 | readl(offset); | ||
1332 | } | ||
1333 | addr -= (window * NETXEN_WINDOW_ONE); | ||
1334 | addr += NETXEN_PCI_DDR_NET; | ||
1335 | } else if (ADDR_IN_RANGE(addr, NETXEN_ADDR_OCM0, NETXEN_ADDR_OCM0_MAX)) { | ||
1336 | addr -= NETXEN_ADDR_OCM0; | ||
1337 | addr += NETXEN_PCI_OCM0; | ||
1338 | } else if (ADDR_IN_RANGE(addr, NETXEN_ADDR_OCM1, NETXEN_ADDR_OCM1_MAX)) { | ||
1339 | addr -= NETXEN_ADDR_OCM1; | ||
1340 | addr += NETXEN_PCI_OCM1; | ||
1341 | } else if (ADDR_IN_RANGE(addr, NETXEN_ADDR_QDR_NET, qdr_max)) { | ||
1342 | /* QDR network side */ | ||
1343 | addr -= NETXEN_ADDR_QDR_NET; | ||
1344 | window = (addr >> 22) & 0x3f; | ||
1345 | if (adapter->ahw.qdr_sn_window != window) { | ||
1346 | adapter->ahw.qdr_sn_window = window; | ||
1347 | offset = PCI_OFFSET_SECOND_RANGE(adapter, | ||
1348 | NETXEN_PCIX_PH_REG(PCIE_SN_WINDOW_REG(func))); | ||
1349 | writel((window << 22), offset); | ||
1350 | /* MUST make sure window is set before we forge on... */ | ||
1351 | readl(offset); | ||
1352 | } | ||
1353 | addr -= (window * 0x400000); | ||
1354 | addr += NETXEN_PCI_QDR_NET; | ||
1355 | } else { | ||
1356 | /* | ||
1357 | * peg gdb frequently accesses memory that doesn't exist, | ||
1358 | * this limits the chit chat so debugging isn't slowed down. | ||
1359 | */ | ||
1360 | if ((netxen_pci_set_window_warning_count++ < 8) | ||
1361 | || (netxen_pci_set_window_warning_count % 64 == 0)) | ||
1362 | printk("%s: Warning:netxen_nic_pci_set_window()" | ||
1363 | " Unknown address range!\n", | ||
1364 | netxen_nic_driver_name); | ||
1365 | addr = -1UL; | ||
1366 | } | ||
1367 | return addr; | ||
1368 | } | 1319 | } |
1369 | 1320 | ||
1370 | /* window 1 registers only */ | 1321 | /* window 1 registers only */ |
1371 | static void netxen_nic_io_write_128M(struct netxen_adapter *adapter, | 1322 | static void netxen_nic_io_write_128M(struct netxen_adapter *adapter, |
1372 | void __iomem *addr, u32 data) | 1323 | void __iomem *addr, u32 data) |
1373 | { | 1324 | { |
1374 | read_lock(&adapter->adapter_lock); | 1325 | read_lock(&adapter->ahw.crb_lock); |
1375 | writel(data, addr); | 1326 | writel(data, addr); |
1376 | read_unlock(&adapter->adapter_lock); | 1327 | read_unlock(&adapter->ahw.crb_lock); |
1377 | } | 1328 | } |
1378 | 1329 | ||
1379 | static u32 netxen_nic_io_read_128M(struct netxen_adapter *adapter, | 1330 | static u32 netxen_nic_io_read_128M(struct netxen_adapter *adapter, |
@@ -1381,9 +1332,9 @@ static u32 netxen_nic_io_read_128M(struct netxen_adapter *adapter, | |||
1381 | { | 1332 | { |
1382 | u32 val; | 1333 | u32 val; |
1383 | 1334 | ||
1384 | read_lock(&adapter->adapter_lock); | 1335 | read_lock(&adapter->ahw.crb_lock); |
1385 | val = readl(addr); | 1336 | val = readl(addr); |
1386 | read_unlock(&adapter->adapter_lock); | 1337 | read_unlock(&adapter->ahw.crb_lock); |
1387 | 1338 | ||
1388 | return val; | 1339 | return val; |
1389 | } | 1340 | } |
@@ -1403,488 +1354,437 @@ static u32 netxen_nic_io_read_2M(struct netxen_adapter *adapter, | |||
1403 | void __iomem * | 1354 | void __iomem * |
1404 | netxen_get_ioaddr(struct netxen_adapter *adapter, u32 offset) | 1355 | netxen_get_ioaddr(struct netxen_adapter *adapter, u32 offset) |
1405 | { | 1356 | { |
1406 | ulong off = offset; | 1357 | void __iomem *addr = NULL; |
1407 | 1358 | ||
1408 | if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) { | 1359 | if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) { |
1409 | if (offset < NETXEN_CRB_PCIX_HOST2 && | 1360 | if ((offset < NETXEN_CRB_PCIX_HOST2) && |
1410 | offset > NETXEN_CRB_PCIX_HOST) | 1361 | (offset > NETXEN_CRB_PCIX_HOST)) |
1411 | return PCI_OFFSET_SECOND_RANGE(adapter, offset); | 1362 | addr = PCI_OFFSET_SECOND_RANGE(adapter, offset); |
1412 | return NETXEN_CRB_NORMALIZE(adapter, offset); | 1363 | else |
1364 | addr = NETXEN_CRB_NORMALIZE(adapter, offset); | ||
1365 | } else { | ||
1366 | WARN_ON(netxen_nic_pci_get_crb_addr_2M(adapter, | ||
1367 | offset, &addr)); | ||
1413 | } | 1368 | } |
1414 | 1369 | ||
1415 | BUG_ON(netxen_nic_pci_get_crb_addr_2M(adapter, &off)); | 1370 | return addr; |
1416 | return (void __iomem *)off; | ||
1417 | } | 1371 | } |
1418 | 1372 | ||
1419 | static unsigned long | 1373 | static int |
1420 | netxen_nic_pci_set_window_2M(struct netxen_adapter *adapter, | 1374 | netxen_nic_pci_set_window_128M(struct netxen_adapter *adapter, |
1421 | unsigned long long addr) | 1375 | u64 addr, u32 *start) |
1422 | { | 1376 | { |
1423 | int window; | 1377 | if (ADDR_IN_RANGE(addr, NETXEN_ADDR_OCM0, NETXEN_ADDR_OCM0_MAX)) { |
1424 | u32 win_read; | 1378 | *start = (addr - NETXEN_ADDR_OCM0 + NETXEN_PCI_OCM0); |
1425 | 1379 | return 0; | |
1426 | if (ADDR_IN_RANGE(addr, NETXEN_ADDR_DDR_NET, NETXEN_ADDR_DDR_NET_MAX)) { | ||
1427 | /* DDR network side */ | ||
1428 | window = MN_WIN(addr); | ||
1429 | adapter->ahw.ddr_mn_window = window; | ||
1430 | NXWR32(adapter, adapter->ahw.mn_win_crb, window); | ||
1431 | win_read = NXRD32(adapter, adapter->ahw.mn_win_crb); | ||
1432 | if ((win_read << 17) != window) { | ||
1433 | printk(KERN_INFO "Written MNwin (0x%x) != " | ||
1434 | "Read MNwin (0x%x)\n", window, win_read); | ||
1435 | } | ||
1436 | addr = GET_MEM_OFFS_2M(addr) + NETXEN_PCI_DDR_NET; | ||
1437 | } else if (ADDR_IN_RANGE(addr, | 1380 | } else if (ADDR_IN_RANGE(addr, |
1438 | NETXEN_ADDR_OCM0, NETXEN_ADDR_OCM0_MAX)) { | 1381 | NETXEN_ADDR_OCM1, NETXEN_ADDR_OCM1_MAX)) { |
1439 | if ((addr & 0x00ff800) == 0xff800) { | 1382 | *start = (addr - NETXEN_ADDR_OCM1 + NETXEN_PCI_OCM1); |
1440 | printk("%s: QM access not handled.\n", __func__); | 1383 | return 0; |
1441 | addr = -1UL; | 1384 | } |
1442 | } | 1385 | |
1386 | return -EIO; | ||
1387 | } | ||
1443 | 1388 | ||
1389 | static int | ||
1390 | netxen_nic_pci_set_window_2M(struct netxen_adapter *adapter, | ||
1391 | u64 addr, u32 *start) | ||
1392 | { | ||
1393 | u32 window; | ||
1394 | struct pci_dev *pdev = adapter->pdev; | ||
1395 | |||
1396 | if ((addr & 0x00ff800) == 0xff800) { | ||
1397 | if (printk_ratelimit()) | ||
1398 | dev_warn(&pdev->dev, "QM access not handled\n"); | ||
1399 | return -EIO; | ||
1400 | } | ||
1401 | |||
1402 | if (NX_IS_REVISION_P3P(adapter->ahw.revision_id)) | ||
1403 | window = OCM_WIN_P3P(addr); | ||
1404 | else | ||
1444 | window = OCM_WIN(addr); | 1405 | window = OCM_WIN(addr); |
1445 | adapter->ahw.ddr_mn_window = window; | ||
1446 | NXWR32(adapter, adapter->ahw.mn_win_crb, window); | ||
1447 | win_read = NXRD32(adapter, adapter->ahw.mn_win_crb); | ||
1448 | if ((win_read >> 7) != window) { | ||
1449 | printk(KERN_INFO "%s: Written OCMwin (0x%x) != " | ||
1450 | "Read OCMwin (0x%x)\n", | ||
1451 | __func__, window, win_read); | ||
1452 | } | ||
1453 | addr = GET_MEM_OFFS_2M(addr) + NETXEN_PCI_OCM0_2M; | ||
1454 | 1406 | ||
1455 | } else if (ADDR_IN_RANGE(addr, | 1407 | writel(window, adapter->ahw.ocm_win_crb); |
1456 | NETXEN_ADDR_QDR_NET, NETXEN_ADDR_QDR_NET_MAX_P3)) { | 1408 | /* read back to flush */ |
1457 | /* QDR network side */ | 1409 | readl(adapter->ahw.ocm_win_crb); |
1458 | window = MS_WIN(addr); | ||
1459 | adapter->ahw.qdr_sn_window = window; | ||
1460 | NXWR32(adapter, adapter->ahw.ms_win_crb, window); | ||
1461 | win_read = NXRD32(adapter, adapter->ahw.ms_win_crb); | ||
1462 | if (win_read != window) { | ||
1463 | printk(KERN_INFO "%s: Written MSwin (0x%x) != " | ||
1464 | "Read MSwin (0x%x)\n", | ||
1465 | __func__, window, win_read); | ||
1466 | } | ||
1467 | addr = GET_MEM_OFFS_2M(addr) + NETXEN_PCI_QDR_NET; | ||
1468 | 1410 | ||
1469 | } else { | 1411 | adapter->ahw.ocm_win = window; |
1470 | /* | 1412 | *start = NETXEN_PCI_OCM0_2M + GET_MEM_OFFS_2M(addr); |
1471 | * peg gdb frequently accesses memory that doesn't exist, | 1413 | return 0; |
1472 | * this limits the chit chat so debugging isn't slowed down. | ||
1473 | */ | ||
1474 | if ((netxen_pci_set_window_warning_count++ < 8) | ||
1475 | || (netxen_pci_set_window_warning_count%64 == 0)) { | ||
1476 | printk("%s: Warning:%s Unknown address range!\n", | ||
1477 | __func__, netxen_nic_driver_name); | ||
1478 | } | 1414 | } |
1479 | addr = -1UL; | 1415 | |
1416 | static int | ||
1417 | netxen_nic_pci_mem_access_direct(struct netxen_adapter *adapter, u64 off, | ||
1418 | u64 *data, int op) | ||
1419 | { | ||
1420 | void __iomem *addr, *mem_ptr = NULL; | ||
1421 | resource_size_t mem_base; | ||
1422 | int ret = -EIO; | ||
1423 | u32 start; | ||
1424 | |||
1425 | spin_lock(&adapter->ahw.mem_lock); | ||
1426 | |||
1427 | ret = adapter->pci_set_window(adapter, off, &start); | ||
1428 | if (ret != 0) | ||
1429 | goto unlock; | ||
1430 | |||
1431 | addr = pci_base_offset(adapter, start); | ||
1432 | if (addr) | ||
1433 | goto noremap; | ||
1434 | |||
1435 | mem_base = pci_resource_start(adapter->pdev, 0) + (start & PAGE_MASK); | ||
1436 | |||
1437 | mem_ptr = ioremap(mem_base, PAGE_SIZE); | ||
1438 | if (mem_ptr == NULL) { | ||
1439 | ret = -EIO; | ||
1440 | goto unlock; | ||
1480 | } | 1441 | } |
1481 | return addr; | 1442 | |
1443 | addr = mem_ptr + (start & (PAGE_SIZE - 1)); | ||
1444 | |||
1445 | noremap: | ||
1446 | if (op == 0) /* read */ | ||
1447 | *data = readq(addr); | ||
1448 | else /* write */ | ||
1449 | writeq(*data, addr); | ||
1450 | |||
1451 | unlock: | ||
1452 | spin_unlock(&adapter->ahw.mem_lock); | ||
1453 | |||
1454 | if (mem_ptr) | ||
1455 | iounmap(mem_ptr); | ||
1456 | return ret; | ||
1482 | } | 1457 | } |
1483 | 1458 | ||
1484 | #define MAX_CTL_CHECK 1000 | 1459 | #define MAX_CTL_CHECK 1000 |
1485 | 1460 | ||
1486 | static int | 1461 | static int |
1487 | netxen_nic_pci_mem_write_128M(struct netxen_adapter *adapter, | 1462 | netxen_nic_pci_mem_write_128M(struct netxen_adapter *adapter, |
1488 | u64 off, void *data, int size) | 1463 | u64 off, u64 data) |
1489 | { | 1464 | { |
1490 | unsigned long flags; | 1465 | int j, ret; |
1491 | int i, j, ret = 0, loop, sz[2], off0; | 1466 | u32 temp, off_lo, off_hi, addr_hi, data_hi, data_lo; |
1492 | uint32_t temp; | ||
1493 | uint64_t off8, tmpw, word[2] = {0, 0}; | ||
1494 | void __iomem *mem_crb; | 1467 | void __iomem *mem_crb; |
1495 | 1468 | ||
1496 | if (size != 8) | 1469 | /* Only 64-bit aligned access */ |
1470 | if (off & 7) | ||
1497 | return -EIO; | 1471 | return -EIO; |
1498 | 1472 | ||
1473 | /* P2 has different SIU and MIU test agent base addr */ | ||
1499 | if (ADDR_IN_RANGE(off, NETXEN_ADDR_QDR_NET, | 1474 | if (ADDR_IN_RANGE(off, NETXEN_ADDR_QDR_NET, |
1500 | NETXEN_ADDR_QDR_NET_MAX_P2)) { | 1475 | NETXEN_ADDR_QDR_NET_MAX_P2)) { |
1501 | mem_crb = pci_base_offset(adapter, NETXEN_CRB_QDR_NET); | 1476 | mem_crb = pci_base_offset(adapter, |
1477 | NETXEN_CRB_QDR_NET+SIU_TEST_AGT_BASE); | ||
1478 | addr_hi = SIU_TEST_AGT_ADDR_HI; | ||
1479 | data_lo = SIU_TEST_AGT_WRDATA_LO; | ||
1480 | data_hi = SIU_TEST_AGT_WRDATA_HI; | ||
1481 | off_lo = off & SIU_TEST_AGT_ADDR_MASK; | ||
1482 | off_hi = SIU_TEST_AGT_UPPER_ADDR(off); | ||
1502 | goto correct; | 1483 | goto correct; |
1503 | } | 1484 | } |
1504 | 1485 | ||
1505 | if (ADDR_IN_RANGE(off, NETXEN_ADDR_DDR_NET, NETXEN_ADDR_DDR_NET_MAX)) { | 1486 | if (ADDR_IN_RANGE(off, NETXEN_ADDR_DDR_NET, NETXEN_ADDR_DDR_NET_MAX)) { |
1506 | mem_crb = pci_base_offset(adapter, NETXEN_CRB_DDR_NET); | 1487 | mem_crb = pci_base_offset(adapter, |
1488 | NETXEN_CRB_DDR_NET+MIU_TEST_AGT_BASE); | ||
1489 | addr_hi = MIU_TEST_AGT_ADDR_HI; | ||
1490 | data_lo = MIU_TEST_AGT_WRDATA_LO; | ||
1491 | data_hi = MIU_TEST_AGT_WRDATA_HI; | ||
1492 | off_lo = off & MIU_TEST_AGT_ADDR_MASK; | ||
1493 | off_hi = 0; | ||
1507 | goto correct; | 1494 | goto correct; |
1508 | } | 1495 | } |
1509 | 1496 | ||
1510 | return -EIO; | 1497 | if (ADDR_IN_RANGE(off, NETXEN_ADDR_OCM0, NETXEN_ADDR_OCM0_MAX) || |
1511 | 1498 | ADDR_IN_RANGE(off, NETXEN_ADDR_OCM1, NETXEN_ADDR_OCM1_MAX)) { | |
1512 | correct: | 1499 | if (adapter->ahw.pci_len0 != 0) { |
1513 | off8 = off & 0xfffffff8; | 1500 | return netxen_nic_pci_mem_access_direct(adapter, |
1514 | off0 = off & 0x7; | 1501 | off, &data, 1); |
1515 | sz[0] = (size < (8 - off0)) ? size : (8 - off0); | ||
1516 | sz[1] = size - sz[0]; | ||
1517 | loop = ((off0 + size - 1) >> 3) + 1; | ||
1518 | |||
1519 | if ((size != 8) || (off0 != 0)) { | ||
1520 | for (i = 0; i < loop; i++) { | ||
1521 | if (adapter->pci_mem_read(adapter, | ||
1522 | off8 + (i << 3), &word[i], 8)) | ||
1523 | return -1; | ||
1524 | } | 1502 | } |
1525 | } | 1503 | } |
1526 | 1504 | ||
1527 | switch (size) { | 1505 | return -EIO; |
1528 | case 1: | ||
1529 | tmpw = *((uint8_t *)data); | ||
1530 | break; | ||
1531 | case 2: | ||
1532 | tmpw = *((uint16_t *)data); | ||
1533 | break; | ||
1534 | case 4: | ||
1535 | tmpw = *((uint32_t *)data); | ||
1536 | break; | ||
1537 | case 8: | ||
1538 | default: | ||
1539 | tmpw = *((uint64_t *)data); | ||
1540 | break; | ||
1541 | } | ||
1542 | word[0] &= ~((~(~0ULL << (sz[0] * 8))) << (off0 * 8)); | ||
1543 | word[0] |= tmpw << (off0 * 8); | ||
1544 | 1506 | ||
1545 | if (loop == 2) { | 1507 | correct: |
1546 | word[1] &= ~(~0ULL << (sz[1] * 8)); | 1508 | spin_lock(&adapter->ahw.mem_lock); |
1547 | word[1] |= tmpw >> (sz[0] * 8); | 1509 | netxen_nic_pci_set_crbwindow_128M(adapter, 0); |
1510 | |||
1511 | writel(off_lo, (mem_crb + MIU_TEST_AGT_ADDR_LO)); | ||
1512 | writel(off_hi, (mem_crb + addr_hi)); | ||
1513 | writel(data & 0xffffffff, (mem_crb + data_lo)); | ||
1514 | writel((data >> 32) & 0xffffffff, (mem_crb + data_hi)); | ||
1515 | writel((TA_CTL_ENABLE | TA_CTL_WRITE), (mem_crb + TEST_AGT_CTRL)); | ||
1516 | writel((TA_CTL_START | TA_CTL_ENABLE | TA_CTL_WRITE), | ||
1517 | (mem_crb + TEST_AGT_CTRL)); | ||
1518 | |||
1519 | for (j = 0; j < MAX_CTL_CHECK; j++) { | ||
1520 | temp = readl((mem_crb + TEST_AGT_CTRL)); | ||
1521 | if ((temp & TA_CTL_BUSY) == 0) | ||
1522 | break; | ||
1548 | } | 1523 | } |
1549 | 1524 | ||
1550 | write_lock_irqsave(&adapter->adapter_lock, flags); | 1525 | if (j >= MAX_CTL_CHECK) { |
1551 | netxen_nic_pci_change_crbwindow_128M(adapter, 0); | 1526 | if (printk_ratelimit()) |
1552 | 1527 | dev_err(&adapter->pdev->dev, | |
1553 | for (i = 0; i < loop; i++) { | ||
1554 | writel((uint32_t)(off8 + (i << 3)), | ||
1555 | (mem_crb+MIU_TEST_AGT_ADDR_LO)); | ||
1556 | writel(0, | ||
1557 | (mem_crb+MIU_TEST_AGT_ADDR_HI)); | ||
1558 | writel(word[i] & 0xffffffff, | ||
1559 | (mem_crb+MIU_TEST_AGT_WRDATA_LO)); | ||
1560 | writel((word[i] >> 32) & 0xffffffff, | ||
1561 | (mem_crb+MIU_TEST_AGT_WRDATA_HI)); | ||
1562 | writel(MIU_TA_CTL_ENABLE|MIU_TA_CTL_WRITE, | ||
1563 | (mem_crb+MIU_TEST_AGT_CTRL)); | ||
1564 | writel(MIU_TA_CTL_START|MIU_TA_CTL_ENABLE|MIU_TA_CTL_WRITE, | ||
1565 | (mem_crb+MIU_TEST_AGT_CTRL)); | ||
1566 | |||
1567 | for (j = 0; j < MAX_CTL_CHECK; j++) { | ||
1568 | temp = readl( | ||
1569 | (mem_crb+MIU_TEST_AGT_CTRL)); | ||
1570 | if ((temp & MIU_TA_CTL_BUSY) == 0) | ||
1571 | break; | ||
1572 | } | ||
1573 | |||
1574 | if (j >= MAX_CTL_CHECK) { | ||
1575 | if (printk_ratelimit()) | ||
1576 | dev_err(&adapter->pdev->dev, | ||
1577 | "failed to write through agent\n"); | 1528 | "failed to write through agent\n"); |
1578 | ret = -1; | 1529 | ret = -EIO; |
1579 | break; | 1530 | } else |
1580 | } | 1531 | ret = 0; |
1581 | } | ||
1582 | 1532 | ||
1583 | netxen_nic_pci_change_crbwindow_128M(adapter, 1); | 1533 | netxen_nic_pci_set_crbwindow_128M(adapter, NETXEN_WINDOW_ONE); |
1584 | write_unlock_irqrestore(&adapter->adapter_lock, flags); | 1534 | spin_unlock(&adapter->ahw.mem_lock); |
1585 | return ret; | 1535 | return ret; |
1586 | } | 1536 | } |
1587 | 1537 | ||
1588 | static int | 1538 | static int |
1589 | netxen_nic_pci_mem_read_128M(struct netxen_adapter *adapter, | 1539 | netxen_nic_pci_mem_read_128M(struct netxen_adapter *adapter, |
1590 | u64 off, void *data, int size) | 1540 | u64 off, u64 *data) |
1591 | { | 1541 | { |
1592 | unsigned long flags; | 1542 | int j, ret; |
1593 | int i, j = 0, k, start, end, loop, sz[2], off0[2]; | 1543 | u32 temp, off_lo, off_hi, addr_hi, data_hi, data_lo; |
1594 | uint32_t temp; | 1544 | u64 val; |
1595 | uint64_t off8, val, word[2] = {0, 0}; | ||
1596 | void __iomem *mem_crb; | 1545 | void __iomem *mem_crb; |
1597 | 1546 | ||
1598 | if (size != 8) | 1547 | /* Only 64-bit aligned access */ |
1548 | if (off & 7) | ||
1599 | return -EIO; | 1549 | return -EIO; |
1600 | 1550 | ||
1551 | /* P2 has different SIU and MIU test agent base addr */ | ||
1601 | if (ADDR_IN_RANGE(off, NETXEN_ADDR_QDR_NET, | 1552 | if (ADDR_IN_RANGE(off, NETXEN_ADDR_QDR_NET, |
1602 | NETXEN_ADDR_QDR_NET_MAX_P2)) { | 1553 | NETXEN_ADDR_QDR_NET_MAX_P2)) { |
1603 | mem_crb = pci_base_offset(adapter, NETXEN_CRB_QDR_NET); | 1554 | mem_crb = pci_base_offset(adapter, |
1555 | NETXEN_CRB_QDR_NET+SIU_TEST_AGT_BASE); | ||
1556 | addr_hi = SIU_TEST_AGT_ADDR_HI; | ||
1557 | data_lo = SIU_TEST_AGT_RDDATA_LO; | ||
1558 | data_hi = SIU_TEST_AGT_RDDATA_HI; | ||
1559 | off_lo = off & SIU_TEST_AGT_ADDR_MASK; | ||
1560 | off_hi = SIU_TEST_AGT_UPPER_ADDR(off); | ||
1604 | goto correct; | 1561 | goto correct; |
1605 | } | 1562 | } |
1606 | 1563 | ||
1607 | if (ADDR_IN_RANGE(off, NETXEN_ADDR_DDR_NET, NETXEN_ADDR_DDR_NET_MAX)) { | 1564 | if (ADDR_IN_RANGE(off, NETXEN_ADDR_DDR_NET, NETXEN_ADDR_DDR_NET_MAX)) { |
1608 | mem_crb = pci_base_offset(adapter, NETXEN_CRB_DDR_NET); | 1565 | mem_crb = pci_base_offset(adapter, |
1566 | NETXEN_CRB_DDR_NET+MIU_TEST_AGT_BASE); | ||
1567 | addr_hi = MIU_TEST_AGT_ADDR_HI; | ||
1568 | data_lo = MIU_TEST_AGT_RDDATA_LO; | ||
1569 | data_hi = MIU_TEST_AGT_RDDATA_HI; | ||
1570 | off_lo = off & MIU_TEST_AGT_ADDR_MASK; | ||
1571 | off_hi = 0; | ||
1609 | goto correct; | 1572 | goto correct; |
1610 | } | 1573 | } |
1611 | 1574 | ||
1575 | if (ADDR_IN_RANGE(off, NETXEN_ADDR_OCM0, NETXEN_ADDR_OCM0_MAX) || | ||
1576 | ADDR_IN_RANGE(off, NETXEN_ADDR_OCM1, NETXEN_ADDR_OCM1_MAX)) { | ||
1577 | if (adapter->ahw.pci_len0 != 0) { | ||
1578 | return netxen_nic_pci_mem_access_direct(adapter, | ||
1579 | off, data, 0); | ||
1580 | } | ||
1581 | } | ||
1582 | |||
1612 | return -EIO; | 1583 | return -EIO; |
1613 | 1584 | ||
1614 | correct: | 1585 | correct: |
1615 | off8 = off & 0xfffffff8; | 1586 | spin_lock(&adapter->ahw.mem_lock); |
1616 | off0[0] = off & 0x7; | 1587 | netxen_nic_pci_set_crbwindow_128M(adapter, 0); |
1617 | off0[1] = 0; | ||
1618 | sz[0] = (size < (8 - off0[0])) ? size : (8 - off0[0]); | ||
1619 | sz[1] = size - sz[0]; | ||
1620 | loop = ((off0[0] + size - 1) >> 3) + 1; | ||
1621 | |||
1622 | write_lock_irqsave(&adapter->adapter_lock, flags); | ||
1623 | netxen_nic_pci_change_crbwindow_128M(adapter, 0); | ||
1624 | |||
1625 | for (i = 0; i < loop; i++) { | ||
1626 | writel((uint32_t)(off8 + (i << 3)), | ||
1627 | (mem_crb+MIU_TEST_AGT_ADDR_LO)); | ||
1628 | writel(0, | ||
1629 | (mem_crb+MIU_TEST_AGT_ADDR_HI)); | ||
1630 | writel(MIU_TA_CTL_ENABLE, | ||
1631 | (mem_crb+MIU_TEST_AGT_CTRL)); | ||
1632 | writel(MIU_TA_CTL_START|MIU_TA_CTL_ENABLE, | ||
1633 | (mem_crb+MIU_TEST_AGT_CTRL)); | ||
1634 | 1588 | ||
1635 | for (j = 0; j < MAX_CTL_CHECK; j++) { | 1589 | writel(off_lo, (mem_crb + MIU_TEST_AGT_ADDR_LO)); |
1636 | temp = readl( | 1590 | writel(off_hi, (mem_crb + addr_hi)); |
1637 | (mem_crb+MIU_TEST_AGT_CTRL)); | 1591 | writel(TA_CTL_ENABLE, (mem_crb + TEST_AGT_CTRL)); |
1638 | if ((temp & MIU_TA_CTL_BUSY) == 0) | 1592 | writel((TA_CTL_START|TA_CTL_ENABLE), (mem_crb + TEST_AGT_CTRL)); |
1639 | break; | ||
1640 | } | ||
1641 | 1593 | ||
1642 | if (j >= MAX_CTL_CHECK) { | 1594 | for (j = 0; j < MAX_CTL_CHECK; j++) { |
1643 | if (printk_ratelimit()) | 1595 | temp = readl(mem_crb + TEST_AGT_CTRL); |
1644 | dev_err(&adapter->pdev->dev, | 1596 | if ((temp & TA_CTL_BUSY) == 0) |
1645 | "failed to read through agent\n"); | ||
1646 | break; | 1597 | break; |
1647 | } | ||
1648 | |||
1649 | start = off0[i] >> 2; | ||
1650 | end = (off0[i] + sz[i] - 1) >> 2; | ||
1651 | for (k = start; k <= end; k++) { | ||
1652 | word[i] |= ((uint64_t) readl( | ||
1653 | (mem_crb + | ||
1654 | MIU_TEST_AGT_RDDATA(k))) << (32*k)); | ||
1655 | } | ||
1656 | } | 1598 | } |
1657 | 1599 | ||
1658 | netxen_nic_pci_change_crbwindow_128M(adapter, 1); | 1600 | if (j >= MAX_CTL_CHECK) { |
1659 | write_unlock_irqrestore(&adapter->adapter_lock, flags); | 1601 | if (printk_ratelimit()) |
1660 | 1602 | dev_err(&adapter->pdev->dev, | |
1661 | if (j >= MAX_CTL_CHECK) | 1603 | "failed to read through agent\n"); |
1662 | return -1; | 1604 | ret = -EIO; |
1663 | |||
1664 | if (sz[0] == 8) { | ||
1665 | val = word[0]; | ||
1666 | } else { | 1605 | } else { |
1667 | val = ((word[0] >> (off0[0] * 8)) & (~(~0ULL << (sz[0] * 8)))) | | ||
1668 | ((word[1] & (~(~0ULL << (sz[1] * 8)))) << (sz[0] * 8)); | ||
1669 | } | ||
1670 | 1606 | ||
1671 | switch (size) { | 1607 | temp = readl(mem_crb + data_hi); |
1672 | case 1: | 1608 | val = ((u64)temp << 32); |
1673 | *(uint8_t *)data = val; | 1609 | val |= readl(mem_crb + data_lo); |
1674 | break; | 1610 | *data = val; |
1675 | case 2: | 1611 | ret = 0; |
1676 | *(uint16_t *)data = val; | ||
1677 | break; | ||
1678 | case 4: | ||
1679 | *(uint32_t *)data = val; | ||
1680 | break; | ||
1681 | case 8: | ||
1682 | *(uint64_t *)data = val; | ||
1683 | break; | ||
1684 | } | 1612 | } |
1685 | return 0; | 1613 | |
1614 | netxen_nic_pci_set_crbwindow_128M(adapter, NETXEN_WINDOW_ONE); | ||
1615 | spin_unlock(&adapter->ahw.mem_lock); | ||
1616 | |||
1617 | return ret; | ||
1686 | } | 1618 | } |
1687 | 1619 | ||
1688 | static int | 1620 | static int |
1689 | netxen_nic_pci_mem_write_2M(struct netxen_adapter *adapter, | 1621 | netxen_nic_pci_mem_write_2M(struct netxen_adapter *adapter, |
1690 | u64 off, void *data, int size) | 1622 | u64 off, u64 data) |
1691 | { | 1623 | { |
1692 | int i, j, ret = 0, loop, sz[2], off0; | 1624 | int i, j, ret; |
1693 | uint32_t temp; | 1625 | u32 temp, off8; |
1694 | uint64_t off8, tmpw, word[2] = {0, 0}; | 1626 | u64 stride; |
1695 | void __iomem *mem_crb; | 1627 | void __iomem *mem_crb; |
1696 | 1628 | ||
1697 | if (size != 8) | 1629 | /* Only 64-bit aligned access */ |
1630 | if (off & 7) | ||
1698 | return -EIO; | 1631 | return -EIO; |
1699 | 1632 | ||
1633 | /* P3 onward, test agent base for MIU and SIU is same */ | ||
1700 | if (ADDR_IN_RANGE(off, NETXEN_ADDR_QDR_NET, | 1634 | if (ADDR_IN_RANGE(off, NETXEN_ADDR_QDR_NET, |
1701 | NETXEN_ADDR_QDR_NET_MAX_P3)) { | 1635 | NETXEN_ADDR_QDR_NET_MAX_P3)) { |
1702 | mem_crb = netxen_get_ioaddr(adapter, NETXEN_CRB_QDR_NET); | 1636 | mem_crb = netxen_get_ioaddr(adapter, |
1637 | NETXEN_CRB_QDR_NET+MIU_TEST_AGT_BASE); | ||
1703 | goto correct; | 1638 | goto correct; |
1704 | } | 1639 | } |
1705 | 1640 | ||
1706 | if (ADDR_IN_RANGE(off, NETXEN_ADDR_DDR_NET, NETXEN_ADDR_DDR_NET_MAX)) { | 1641 | if (ADDR_IN_RANGE(off, NETXEN_ADDR_DDR_NET, NETXEN_ADDR_DDR_NET_MAX)) { |
1707 | mem_crb = netxen_get_ioaddr(adapter, NETXEN_CRB_DDR_NET); | 1642 | mem_crb = netxen_get_ioaddr(adapter, |
1643 | NETXEN_CRB_DDR_NET+MIU_TEST_AGT_BASE); | ||
1708 | goto correct; | 1644 | goto correct; |
1709 | } | 1645 | } |
1710 | 1646 | ||
1647 | if (ADDR_IN_RANGE(off, NETXEN_ADDR_OCM0, NETXEN_ADDR_OCM0_MAX)) | ||
1648 | return netxen_nic_pci_mem_access_direct(adapter, off, &data, 1); | ||
1649 | |||
1711 | return -EIO; | 1650 | return -EIO; |
1712 | 1651 | ||
1713 | correct: | 1652 | correct: |
1714 | off8 = off & 0xfffffff8; | 1653 | stride = NX_IS_REVISION_P3P(adapter->ahw.revision_id) ? 16 : 8; |
1715 | off0 = off & 0x7; | ||
1716 | sz[0] = (size < (8 - off0)) ? size : (8 - off0); | ||
1717 | sz[1] = size - sz[0]; | ||
1718 | loop = ((off0 + size - 1) >> 3) + 1; | ||
1719 | |||
1720 | if ((size != 8) || (off0 != 0)) { | ||
1721 | for (i = 0; i < loop; i++) { | ||
1722 | if (adapter->pci_mem_read(adapter, | ||
1723 | off8 + (i << 3), &word[i], 8)) | ||
1724 | return -1; | ||
1725 | } | ||
1726 | } | ||
1727 | 1654 | ||
1728 | switch (size) { | 1655 | off8 = off & ~(stride-1); |
1729 | case 1: | ||
1730 | tmpw = *((uint8_t *)data); | ||
1731 | break; | ||
1732 | case 2: | ||
1733 | tmpw = *((uint16_t *)data); | ||
1734 | break; | ||
1735 | case 4: | ||
1736 | tmpw = *((uint32_t *)data); | ||
1737 | break; | ||
1738 | case 8: | ||
1739 | default: | ||
1740 | tmpw = *((uint64_t *)data); | ||
1741 | break; | ||
1742 | } | ||
1743 | 1656 | ||
1744 | word[0] &= ~((~(~0ULL << (sz[0] * 8))) << (off0 * 8)); | 1657 | spin_lock(&adapter->ahw.mem_lock); |
1745 | word[0] |= tmpw << (off0 * 8); | ||
1746 | 1658 | ||
1747 | if (loop == 2) { | 1659 | writel(off8, (mem_crb + MIU_TEST_AGT_ADDR_LO)); |
1748 | word[1] &= ~(~0ULL << (sz[1] * 8)); | 1660 | writel(0, (mem_crb + MIU_TEST_AGT_ADDR_HI)); |
1749 | word[1] |= tmpw >> (sz[0] * 8); | ||
1750 | } | ||
1751 | |||
1752 | /* | ||
1753 | * don't lock here - write_wx gets the lock if each time | ||
1754 | * write_lock_irqsave(&adapter->adapter_lock, flags); | ||
1755 | * netxen_nic_pci_change_crbwindow_128M(adapter, 0); | ||
1756 | */ | ||
1757 | 1661 | ||
1758 | for (i = 0; i < loop; i++) { | 1662 | i = 0; |
1759 | writel(off8 + (i << 3), mem_crb+MIU_TEST_AGT_ADDR_LO); | 1663 | if (stride == 16) { |
1760 | writel(0, mem_crb+MIU_TEST_AGT_ADDR_HI); | 1664 | writel(TA_CTL_ENABLE, (mem_crb + TEST_AGT_CTRL)); |
1761 | writel(word[i] & 0xffffffff, mem_crb+MIU_TEST_AGT_WRDATA_LO); | 1665 | writel((TA_CTL_START | TA_CTL_ENABLE), |
1762 | writel((word[i] >> 32) & 0xffffffff, | 1666 | (mem_crb + TEST_AGT_CTRL)); |
1763 | mem_crb+MIU_TEST_AGT_WRDATA_HI); | ||
1764 | writel((MIU_TA_CTL_ENABLE | MIU_TA_CTL_WRITE), | ||
1765 | mem_crb+MIU_TEST_AGT_CTRL); | ||
1766 | writel(MIU_TA_CTL_START | MIU_TA_CTL_ENABLE | MIU_TA_CTL_WRITE, | ||
1767 | mem_crb+MIU_TEST_AGT_CTRL); | ||
1768 | 1667 | ||
1769 | for (j = 0; j < MAX_CTL_CHECK; j++) { | 1668 | for (j = 0; j < MAX_CTL_CHECK; j++) { |
1770 | temp = readl(mem_crb + MIU_TEST_AGT_CTRL); | 1669 | temp = readl(mem_crb + TEST_AGT_CTRL); |
1771 | if ((temp & MIU_TA_CTL_BUSY) == 0) | 1670 | if ((temp & TA_CTL_BUSY) == 0) |
1772 | break; | 1671 | break; |
1773 | } | 1672 | } |
1774 | 1673 | ||
1775 | if (j >= MAX_CTL_CHECK) { | 1674 | if (j >= MAX_CTL_CHECK) { |
1776 | if (printk_ratelimit()) | 1675 | ret = -EIO; |
1777 | dev_err(&adapter->pdev->dev, | 1676 | goto done; |
1778 | "failed to write through agent\n"); | ||
1779 | ret = -1; | ||
1780 | break; | ||
1781 | } | 1677 | } |
1678 | |||
1679 | i = (off & 0xf) ? 0 : 2; | ||
1680 | writel(readl(mem_crb + MIU_TEST_AGT_RDDATA(i)), | ||
1681 | mem_crb + MIU_TEST_AGT_WRDATA(i)); | ||
1682 | writel(readl(mem_crb + MIU_TEST_AGT_RDDATA(i+1)), | ||
1683 | mem_crb + MIU_TEST_AGT_WRDATA(i+1)); | ||
1684 | i = (off & 0xf) ? 2 : 0; | ||
1782 | } | 1685 | } |
1783 | 1686 | ||
1784 | /* | 1687 | writel(data & 0xffffffff, |
1785 | * netxen_nic_pci_change_crbwindow_128M(adapter, 1); | 1688 | mem_crb + MIU_TEST_AGT_WRDATA(i)); |
1786 | * write_unlock_irqrestore(&adapter->adapter_lock, flags); | 1689 | writel((data >> 32) & 0xffffffff, |
1787 | */ | 1690 | mem_crb + MIU_TEST_AGT_WRDATA(i+1)); |
1691 | |||
1692 | writel((TA_CTL_ENABLE | TA_CTL_WRITE), (mem_crb + TEST_AGT_CTRL)); | ||
1693 | writel((TA_CTL_START | TA_CTL_ENABLE | TA_CTL_WRITE), | ||
1694 | (mem_crb + TEST_AGT_CTRL)); | ||
1695 | |||
1696 | for (j = 0; j < MAX_CTL_CHECK; j++) { | ||
1697 | temp = readl(mem_crb + TEST_AGT_CTRL); | ||
1698 | if ((temp & TA_CTL_BUSY) == 0) | ||
1699 | break; | ||
1700 | } | ||
1701 | |||
1702 | if (j >= MAX_CTL_CHECK) { | ||
1703 | if (printk_ratelimit()) | ||
1704 | dev_err(&adapter->pdev->dev, | ||
1705 | "failed to write through agent\n"); | ||
1706 | ret = -EIO; | ||
1707 | } else | ||
1708 | ret = 0; | ||
1709 | |||
1710 | done: | ||
1711 | spin_unlock(&adapter->ahw.mem_lock); | ||
1712 | |||
1788 | return ret; | 1713 | return ret; |
1789 | } | 1714 | } |
1790 | 1715 | ||
1791 | static int | 1716 | static int |
1792 | netxen_nic_pci_mem_read_2M(struct netxen_adapter *adapter, | 1717 | netxen_nic_pci_mem_read_2M(struct netxen_adapter *adapter, |
1793 | u64 off, void *data, int size) | 1718 | u64 off, u64 *data) |
1794 | { | 1719 | { |
1795 | int i, j = 0, k, start, end, loop, sz[2], off0[2]; | 1720 | int j, ret; |
1796 | uint32_t temp; | 1721 | u32 temp, off8; |
1797 | uint64_t off8, val, word[2] = {0, 0}; | 1722 | u64 val, stride; |
1798 | void __iomem *mem_crb; | 1723 | void __iomem *mem_crb; |
1799 | 1724 | ||
1800 | if (size != 8) | 1725 | /* Only 64-bit aligned access */ |
1726 | if (off & 7) | ||
1801 | return -EIO; | 1727 | return -EIO; |
1802 | 1728 | ||
1729 | /* P3 onward, test agent base for MIU and SIU is same */ | ||
1803 | if (ADDR_IN_RANGE(off, NETXEN_ADDR_QDR_NET, | 1730 | if (ADDR_IN_RANGE(off, NETXEN_ADDR_QDR_NET, |
1804 | NETXEN_ADDR_QDR_NET_MAX_P3)) { | 1731 | NETXEN_ADDR_QDR_NET_MAX_P3)) { |
1805 | mem_crb = netxen_get_ioaddr(adapter, NETXEN_CRB_QDR_NET); | 1732 | mem_crb = netxen_get_ioaddr(adapter, |
1733 | NETXEN_CRB_QDR_NET+MIU_TEST_AGT_BASE); | ||
1806 | goto correct; | 1734 | goto correct; |
1807 | } | 1735 | } |
1808 | 1736 | ||
1809 | if (ADDR_IN_RANGE(off, NETXEN_ADDR_DDR_NET, NETXEN_ADDR_DDR_NET_MAX)) { | 1737 | if (ADDR_IN_RANGE(off, NETXEN_ADDR_DDR_NET, NETXEN_ADDR_DDR_NET_MAX)) { |
1810 | mem_crb = netxen_get_ioaddr(adapter, NETXEN_CRB_DDR_NET); | 1738 | mem_crb = netxen_get_ioaddr(adapter, |
1739 | NETXEN_CRB_DDR_NET+MIU_TEST_AGT_BASE); | ||
1811 | goto correct; | 1740 | goto correct; |
1812 | } | 1741 | } |
1813 | 1742 | ||
1743 | if (ADDR_IN_RANGE(off, NETXEN_ADDR_OCM0, NETXEN_ADDR_OCM0_MAX)) { | ||
1744 | return netxen_nic_pci_mem_access_direct(adapter, | ||
1745 | off, data, 0); | ||
1746 | } | ||
1747 | |||
1814 | return -EIO; | 1748 | return -EIO; |
1815 | 1749 | ||
1816 | correct: | 1750 | correct: |
1817 | off8 = off & 0xfffffff8; | 1751 | stride = NX_IS_REVISION_P3P(adapter->ahw.revision_id) ? 16 : 8; |
1818 | off0[0] = off & 0x7; | ||
1819 | off0[1] = 0; | ||
1820 | sz[0] = (size < (8 - off0[0])) ? size : (8 - off0[0]); | ||
1821 | sz[1] = size - sz[0]; | ||
1822 | loop = ((off0[0] + size - 1) >> 3) + 1; | ||
1823 | 1752 | ||
1824 | /* | 1753 | off8 = off & ~(stride-1); |
1825 | * don't lock here - write_wx gets the lock if each time | ||
1826 | * write_lock_irqsave(&adapter->adapter_lock, flags); | ||
1827 | * netxen_nic_pci_change_crbwindow_128M(adapter, 0); | ||
1828 | */ | ||
1829 | 1754 | ||
1830 | for (i = 0; i < loop; i++) { | 1755 | spin_lock(&adapter->ahw.mem_lock); |
1831 | writel(off8 + (i << 3), mem_crb + MIU_TEST_AGT_ADDR_LO); | ||
1832 | writel(0, mem_crb + MIU_TEST_AGT_ADDR_HI); | ||
1833 | writel(MIU_TA_CTL_ENABLE, mem_crb + MIU_TEST_AGT_CTRL); | ||
1834 | writel(MIU_TA_CTL_START | MIU_TA_CTL_ENABLE, | ||
1835 | mem_crb + MIU_TEST_AGT_CTRL); | ||
1836 | 1756 | ||
1837 | for (j = 0; j < MAX_CTL_CHECK; j++) { | 1757 | writel(off8, (mem_crb + MIU_TEST_AGT_ADDR_LO)); |
1838 | temp = readl(mem_crb + MIU_TEST_AGT_CTRL); | 1758 | writel(0, (mem_crb + MIU_TEST_AGT_ADDR_HI)); |
1839 | if ((temp & MIU_TA_CTL_BUSY) == 0) | 1759 | writel(TA_CTL_ENABLE, (mem_crb + TEST_AGT_CTRL)); |
1840 | break; | 1760 | writel((TA_CTL_START | TA_CTL_ENABLE), (mem_crb + TEST_AGT_CTRL)); |
1841 | } | ||
1842 | 1761 | ||
1843 | if (j >= MAX_CTL_CHECK) { | 1762 | for (j = 0; j < MAX_CTL_CHECK; j++) { |
1844 | if (printk_ratelimit()) | 1763 | temp = readl(mem_crb + TEST_AGT_CTRL); |
1845 | dev_err(&adapter->pdev->dev, | 1764 | if ((temp & TA_CTL_BUSY) == 0) |
1846 | "failed to read through agent\n"); | ||
1847 | break; | 1765 | break; |
1848 | } | ||
1849 | |||
1850 | start = off0[i] >> 2; | ||
1851 | end = (off0[i] + sz[i] - 1) >> 2; | ||
1852 | for (k = start; k <= end; k++) { | ||
1853 | temp = readl(mem_crb + MIU_TEST_AGT_RDDATA(k)); | ||
1854 | word[i] |= ((uint64_t)temp << (32 * k)); | ||
1855 | } | ||
1856 | } | 1766 | } |
1857 | 1767 | ||
1858 | /* | 1768 | if (j >= MAX_CTL_CHECK) { |
1859 | * netxen_nic_pci_change_crbwindow_128M(adapter, 1); | 1769 | if (printk_ratelimit()) |
1860 | * write_unlock_irqrestore(&adapter->adapter_lock, flags); | 1770 | dev_err(&adapter->pdev->dev, |
1861 | */ | 1771 | "failed to read through agent\n"); |
1862 | 1772 | ret = -EIO; | |
1863 | if (j >= MAX_CTL_CHECK) | ||
1864 | return -1; | ||
1865 | |||
1866 | if (sz[0] == 8) { | ||
1867 | val = word[0]; | ||
1868 | } else { | 1773 | } else { |
1869 | val = ((word[0] >> (off0[0] * 8)) & (~(~0ULL << (sz[0] * 8)))) | | 1774 | off8 = MIU_TEST_AGT_RDDATA_LO; |
1870 | ((word[1] & (~(~0ULL << (sz[1] * 8)))) << (sz[0] * 8)); | 1775 | if ((stride == 16) && (off & 0xf)) |
1871 | } | 1776 | off8 = MIU_TEST_AGT_RDDATA_UPPER_LO; |
1872 | 1777 | ||
1873 | switch (size) { | 1778 | temp = readl(mem_crb + off8 + 4); |
1874 | case 1: | 1779 | val = (u64)temp << 32; |
1875 | *(uint8_t *)data = val; | 1780 | val |= readl(mem_crb + off8); |
1876 | break; | 1781 | *data = val; |
1877 | case 2: | 1782 | ret = 0; |
1878 | *(uint16_t *)data = val; | ||
1879 | break; | ||
1880 | case 4: | ||
1881 | *(uint32_t *)data = val; | ||
1882 | break; | ||
1883 | case 8: | ||
1884 | *(uint64_t *)data = val; | ||
1885 | break; | ||
1886 | } | 1783 | } |
1887 | return 0; | 1784 | |
1785 | spin_unlock(&adapter->ahw.mem_lock); | ||
1786 | |||
1787 | return ret; | ||
1888 | } | 1788 | } |
1889 | 1789 | ||
1890 | void | 1790 | void |
@@ -2037,10 +1937,10 @@ void netxen_nic_set_link_parameters(struct netxen_adapter *adapter) | |||
2037 | return; | 1937 | return; |
2038 | } | 1938 | } |
2039 | 1939 | ||
2040 | if (adapter->phy_read | 1940 | if (adapter->phy_read && |
2041 | && adapter->phy_read(adapter, | 1941 | adapter->phy_read(adapter, |
2042 | NETXEN_NIU_GB_MII_MGMT_ADDR_PHY_STATUS, | 1942 | NETXEN_NIU_GB_MII_MGMT_ADDR_PHY_STATUS, |
2043 | &status) == 0) { | 1943 | &status) == 0) { |
2044 | if (netxen_get_phy_link(status)) { | 1944 | if (netxen_get_phy_link(status)) { |
2045 | switch (netxen_get_phy_speed(status)) { | 1945 | switch (netxen_get_phy_speed(status)) { |
2046 | case 0: | 1946 | case 0: |
@@ -2067,10 +1967,10 @@ void netxen_nic_set_link_parameters(struct netxen_adapter *adapter) | |||
2067 | adapter->link_duplex = -1; | 1967 | adapter->link_duplex = -1; |
2068 | break; | 1968 | break; |
2069 | } | 1969 | } |
2070 | if (adapter->phy_read | 1970 | if (adapter->phy_read && |
2071 | && adapter->phy_read(adapter, | 1971 | adapter->phy_read(adapter, |
2072 | NETXEN_NIU_GB_MII_MGMT_ADDR_AUTONEG, | 1972 | NETXEN_NIU_GB_MII_MGMT_ADDR_AUTONEG, |
2073 | &autoneg) != 0) | 1973 | &autoneg) != 0) |
2074 | adapter->link_autoneg = autoneg; | 1974 | adapter->link_autoneg = autoneg; |
2075 | } else | 1975 | } else |
2076 | goto link_down; | 1976 | goto link_down; |
diff --git a/drivers/net/netxen/netxen_nic_hw.h b/drivers/net/netxen/netxen_nic_hw.h index 3fd1dcb3583a..e2c5b6f2df03 100644 --- a/drivers/net/netxen/netxen_nic_hw.h +++ b/drivers/net/netxen/netxen_nic_hw.h | |||
@@ -19,7 +19,7 @@ | |||
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 | ||
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 | } |
diff --git a/drivers/net/netxen/netxen_nic_main.c b/drivers/net/netxen/netxen_nic_main.c index 3bf78dbfbf0f..ce838f7c8b0f 100644 --- a/drivers/net/netxen/netxen_nic_main.c +++ b/drivers/net/netxen/netxen_nic_main.c | |||
@@ -19,10 +19,11 @@ | |||
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/slab.h> | ||
26 | #include <linux/vmalloc.h> | 27 | #include <linux/vmalloc.h> |
27 | #include <linux/interrupt.h> | 28 | #include <linux/interrupt.h> |
28 | #include "netxen_nic_hw.h" | 29 | #include "netxen_nic_hw.h" |
@@ -34,13 +35,19 @@ | |||
34 | #include <net/ip.h> | 35 | #include <net/ip.h> |
35 | #include <linux/ipv6.h> | 36 | #include <linux/ipv6.h> |
36 | #include <linux/inetdevice.h> | 37 | #include <linux/inetdevice.h> |
38 | #include <linux/sysfs.h> | ||
39 | #include <linux/aer.h> | ||
37 | 40 | ||
38 | MODULE_DESCRIPTION("NetXen Multi port (1/10) Gigabit Network Driver"); | 41 | MODULE_DESCRIPTION("QLogic/NetXen (1/10) GbE Converged Ethernet Driver"); |
39 | MODULE_LICENSE("GPL"); | 42 | MODULE_LICENSE("GPL"); |
40 | MODULE_VERSION(NETXEN_NIC_LINUX_VERSIONID); | 43 | MODULE_VERSION(NETXEN_NIC_LINUX_VERSIONID); |
44 | MODULE_FIRMWARE(NX_P2_MN_ROMIMAGE_NAME); | ||
45 | MODULE_FIRMWARE(NX_P3_CT_ROMIMAGE_NAME); | ||
46 | MODULE_FIRMWARE(NX_P3_MN_ROMIMAGE_NAME); | ||
47 | MODULE_FIRMWARE(NX_UNIFIED_ROMIMAGE_NAME); | ||
41 | 48 | ||
42 | char netxen_nic_driver_name[] = "netxen_nic"; | 49 | char netxen_nic_driver_name[] = "netxen_nic"; |
43 | static char netxen_nic_driver_string[] = "NetXen Network Driver version " | 50 | static char netxen_nic_driver_string[] = "QLogic/NetXen Network Driver v" |
44 | NETXEN_NIC_LINUX_VERSIONID; | 51 | NETXEN_NIC_LINUX_VERSIONID; |
45 | 52 | ||
46 | static int port_mode = NETXEN_PORT_MODE_AUTO_NEG; | 53 | static int port_mode = NETXEN_PORT_MODE_AUTO_NEG; |
@@ -52,7 +59,10 @@ static int use_msi = 1; | |||
52 | 59 | ||
53 | static int use_msi_x = 1; | 60 | static int use_msi_x = 1; |
54 | 61 | ||
55 | /* Local functions to NetXen NIC driver */ | 62 | static int auto_fw_reset = AUTO_FW_RESET_ENABLED; |
63 | module_param(auto_fw_reset, int, 0644); | ||
64 | MODULE_PARM_DESC(auto_fw_reset,"Auto firmware reset (0=disabled, 1=enabled"); | ||
65 | |||
56 | static int __devinit netxen_nic_probe(struct pci_dev *pdev, | 66 | static int __devinit netxen_nic_probe(struct pci_dev *pdev, |
57 | const struct pci_device_id *ent); | 67 | const struct pci_device_id *ent); |
58 | static void __devexit netxen_nic_remove(struct pci_dev *pdev); | 68 | static void __devexit netxen_nic_remove(struct pci_dev *pdev); |
@@ -73,7 +83,10 @@ static void netxen_nic_poll_controller(struct net_device *netdev); | |||
73 | 83 | ||
74 | static void netxen_create_sysfs_entries(struct netxen_adapter *adapter); | 84 | static void netxen_create_sysfs_entries(struct netxen_adapter *adapter); |
75 | static void netxen_remove_sysfs_entries(struct netxen_adapter *adapter); | 85 | static void netxen_remove_sysfs_entries(struct netxen_adapter *adapter); |
86 | static void netxen_create_diag_entries(struct netxen_adapter *adapter); | ||
87 | static void netxen_remove_diag_entries(struct netxen_adapter *adapter); | ||
76 | 88 | ||
89 | static int nx_dev_request_aer(struct netxen_adapter *adapter); | ||
77 | static int nx_decr_dev_ref_cnt(struct netxen_adapter *adapter); | 90 | static int nx_decr_dev_ref_cnt(struct netxen_adapter *adapter); |
78 | static int netxen_can_start_firmware(struct netxen_adapter *adapter); | 91 | static int netxen_can_start_firmware(struct netxen_adapter *adapter); |
79 | 92 | ||
@@ -88,7 +101,7 @@ static void netxen_config_indev_addr(struct net_device *dev, unsigned long); | |||
88 | {PCI_DEVICE(PCI_VENDOR_ID_NETXEN, (device)), \ | 101 | {PCI_DEVICE(PCI_VENDOR_ID_NETXEN, (device)), \ |
89 | .class = PCI_CLASS_NETWORK_ETHERNET << 8, .class_mask = ~0} | 102 | .class = PCI_CLASS_NETWORK_ETHERNET << 8, .class_mask = ~0} |
90 | 103 | ||
91 | static struct pci_device_id netxen_pci_tbl[] __devinitdata = { | 104 | static DEFINE_PCI_DEVICE_TABLE(netxen_pci_tbl) = { |
92 | ENTRY(PCI_DEVICE_ID_NX2031_10GXSR), | 105 | ENTRY(PCI_DEVICE_ID_NX2031_10GXSR), |
93 | ENTRY(PCI_DEVICE_ID_NX2031_10GCX4), | 106 | ENTRY(PCI_DEVICE_ID_NX2031_10GCX4), |
94 | ENTRY(PCI_DEVICE_ID_NX2031_4GCU), | 107 | ENTRY(PCI_DEVICE_ID_NX2031_4GCU), |
@@ -330,7 +343,7 @@ netxen_check_hw_init(struct netxen_adapter *adapter, int first_boot) | |||
330 | if (!(first_boot & 0x4)) { | 343 | if (!(first_boot & 0x4)) { |
331 | first_boot |= 0x4; | 344 | first_boot |= 0x4; |
332 | NXWR32(adapter, NETXEN_PCIE_REG(0x4), first_boot); | 345 | NXWR32(adapter, NETXEN_PCIE_REG(0x4), first_boot); |
333 | first_boot = NXRD32(adapter, NETXEN_PCIE_REG(0x4)); | 346 | NXRD32(adapter, NETXEN_PCIE_REG(0x4)); |
334 | } | 347 | } |
335 | 348 | ||
336 | /* This is the first boot after power up */ | 349 | /* This is the first boot after power up */ |
@@ -420,7 +433,7 @@ netxen_read_mac_addr(struct netxen_adapter *adapter) | |||
420 | { | 433 | { |
421 | int i; | 434 | int i; |
422 | unsigned char *p; | 435 | unsigned char *p; |
423 | __le64 mac_addr; | 436 | u64 mac_addr; |
424 | struct net_device *netdev = adapter->netdev; | 437 | struct net_device *netdev = adapter->netdev; |
425 | struct pci_dev *pdev = adapter->pdev; | 438 | struct pci_dev *pdev = adapter->pdev; |
426 | 439 | ||
@@ -592,16 +605,14 @@ netxen_cleanup_pci_map(struct netxen_adapter *adapter) | |||
592 | static int | 605 | static int |
593 | netxen_setup_pci_map(struct netxen_adapter *adapter) | 606 | netxen_setup_pci_map(struct netxen_adapter *adapter) |
594 | { | 607 | { |
595 | void __iomem *mem_ptr0 = NULL; | ||
596 | void __iomem *mem_ptr1 = NULL; | ||
597 | void __iomem *mem_ptr2 = NULL; | ||
598 | void __iomem *db_ptr = NULL; | 608 | void __iomem *db_ptr = NULL; |
599 | 609 | ||
600 | resource_size_t mem_base, db_base; | 610 | resource_size_t mem_base, db_base; |
601 | unsigned long mem_len, db_len = 0, pci_len0 = 0; | 611 | unsigned long mem_len, db_len = 0; |
602 | 612 | ||
603 | struct pci_dev *pdev = adapter->pdev; | 613 | struct pci_dev *pdev = adapter->pdev; |
604 | int pci_func = adapter->ahw.pci_func; | 614 | int pci_func = adapter->ahw.pci_func; |
615 | struct netxen_hardware_context *ahw = &adapter->ahw; | ||
605 | 616 | ||
606 | int err = 0; | 617 | int err = 0; |
607 | 618 | ||
@@ -609,47 +620,49 @@ netxen_setup_pci_map(struct netxen_adapter *adapter) | |||
609 | * Set the CRB window to invalid. If any register in window 0 is | 620 | * Set the CRB window to invalid. If any register in window 0 is |
610 | * accessed it should set the window to 0 and then reset it to 1. | 621 | * accessed it should set the window to 0 and then reset it to 1. |
611 | */ | 622 | */ |
612 | adapter->curr_window = 255; | 623 | adapter->ahw.crb_win = -1; |
613 | adapter->ahw.qdr_sn_window = -1; | 624 | adapter->ahw.ocm_win = -1; |
614 | adapter->ahw.ddr_mn_window = -1; | ||
615 | 625 | ||
616 | /* remap phys address */ | 626 | /* remap phys address */ |
617 | mem_base = pci_resource_start(pdev, 0); /* 0 is for BAR 0 */ | 627 | mem_base = pci_resource_start(pdev, 0); /* 0 is for BAR 0 */ |
618 | mem_len = pci_resource_len(pdev, 0); | 628 | mem_len = pci_resource_len(pdev, 0); |
619 | pci_len0 = 0; | ||
620 | 629 | ||
621 | /* 128 Meg of memory */ | 630 | /* 128 Meg of memory */ |
622 | if (mem_len == NETXEN_PCI_128MB_SIZE) { | 631 | if (mem_len == NETXEN_PCI_128MB_SIZE) { |
623 | mem_ptr0 = ioremap(mem_base, FIRST_PAGE_GROUP_SIZE); | 632 | |
624 | mem_ptr1 = ioremap(mem_base + SECOND_PAGE_GROUP_START, | 633 | ahw->pci_base0 = ioremap(mem_base, FIRST_PAGE_GROUP_SIZE); |
634 | ahw->pci_base1 = ioremap(mem_base + SECOND_PAGE_GROUP_START, | ||
625 | SECOND_PAGE_GROUP_SIZE); | 635 | SECOND_PAGE_GROUP_SIZE); |
626 | mem_ptr2 = ioremap(mem_base + THIRD_PAGE_GROUP_START, | 636 | ahw->pci_base2 = ioremap(mem_base + THIRD_PAGE_GROUP_START, |
627 | THIRD_PAGE_GROUP_SIZE); | 637 | THIRD_PAGE_GROUP_SIZE); |
638 | if (ahw->pci_base0 == NULL || ahw->pci_base1 == NULL || | ||
639 | ahw->pci_base2 == NULL) { | ||
640 | dev_err(&pdev->dev, "failed to map PCI bar 0\n"); | ||
641 | err = -EIO; | ||
642 | goto err_out; | ||
643 | } | ||
644 | |||
645 | ahw->pci_len0 = FIRST_PAGE_GROUP_SIZE; | ||
646 | |||
628 | } else if (mem_len == NETXEN_PCI_32MB_SIZE) { | 647 | } else if (mem_len == NETXEN_PCI_32MB_SIZE) { |
629 | mem_ptr1 = ioremap(mem_base, SECOND_PAGE_GROUP_SIZE); | 648 | |
630 | mem_ptr2 = ioremap(mem_base + THIRD_PAGE_GROUP_START - | 649 | ahw->pci_base1 = ioremap(mem_base, SECOND_PAGE_GROUP_SIZE); |
650 | ahw->pci_base2 = ioremap(mem_base + THIRD_PAGE_GROUP_START - | ||
631 | SECOND_PAGE_GROUP_START, THIRD_PAGE_GROUP_SIZE); | 651 | SECOND_PAGE_GROUP_START, THIRD_PAGE_GROUP_SIZE); |
652 | if (ahw->pci_base1 == NULL || ahw->pci_base2 == NULL) { | ||
653 | dev_err(&pdev->dev, "failed to map PCI bar 0\n"); | ||
654 | err = -EIO; | ||
655 | goto err_out; | ||
656 | } | ||
657 | |||
632 | } else if (mem_len == NETXEN_PCI_2MB_SIZE) { | 658 | } else if (mem_len == NETXEN_PCI_2MB_SIZE) { |
633 | 659 | ||
634 | mem_ptr0 = pci_ioremap_bar(pdev, 0); | 660 | ahw->pci_base0 = pci_ioremap_bar(pdev, 0); |
635 | if (mem_ptr0 == NULL) { | 661 | if (ahw->pci_base0 == NULL) { |
636 | dev_err(&pdev->dev, "failed to map PCI bar 0\n"); | 662 | dev_err(&pdev->dev, "failed to map PCI bar 0\n"); |
637 | return -EIO; | 663 | return -EIO; |
638 | } | 664 | } |
639 | pci_len0 = mem_len; | 665 | ahw->pci_len0 = mem_len; |
640 | |||
641 | adapter->ahw.ddr_mn_window = 0; | ||
642 | adapter->ahw.qdr_sn_window = 0; | ||
643 | |||
644 | adapter->ahw.mn_win_crb = NETXEN_PCI_CRBSPACE + | ||
645 | 0x100000 + PCIX_MN_WINDOW + (pci_func * 0x20); | ||
646 | adapter->ahw.ms_win_crb = NETXEN_PCI_CRBSPACE + | ||
647 | 0x100000 + PCIX_SN_WINDOW; | ||
648 | if (pci_func < 4) | ||
649 | adapter->ahw.ms_win_crb += (pci_func * 0x20); | ||
650 | else | ||
651 | adapter->ahw.ms_win_crb += | ||
652 | 0xA0 + ((pci_func - 4) * 0x10); | ||
653 | } else { | 666 | } else { |
654 | return -EIO; | 667 | return -EIO; |
655 | } | 668 | } |
@@ -658,10 +671,14 @@ netxen_setup_pci_map(struct netxen_adapter *adapter) | |||
658 | 671 | ||
659 | dev_info(&pdev->dev, "%dMB memory map\n", (int)(mem_len>>20)); | 672 | dev_info(&pdev->dev, "%dMB memory map\n", (int)(mem_len>>20)); |
660 | 673 | ||
661 | adapter->ahw.pci_base0 = mem_ptr0; | 674 | if (NX_IS_REVISION_P3P(adapter->ahw.revision_id)) { |
662 | adapter->ahw.pci_len0 = pci_len0; | 675 | adapter->ahw.ocm_win_crb = netxen_get_ioaddr(adapter, |
663 | adapter->ahw.pci_base1 = mem_ptr1; | 676 | NETXEN_PCIX_PS_REG(PCIX_OCM_WINDOW_REG(pci_func))); |
664 | adapter->ahw.pci_base2 = mem_ptr2; | 677 | |
678 | } else if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) { | ||
679 | adapter->ahw.ocm_win_crb = netxen_get_ioaddr(adapter, | ||
680 | NETXEN_PCIX_PS_REG(PCIE_MN_WINDOW_REG(pci_func))); | ||
681 | } | ||
665 | 682 | ||
666 | if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) | 683 | if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) |
667 | goto skip_doorbell; | 684 | goto skip_doorbell; |
@@ -727,7 +744,8 @@ netxen_check_options(struct netxen_adapter *adapter) | |||
727 | if (adapter->portnum == 0) { | 744 | if (adapter->portnum == 0) { |
728 | get_brd_name_by_type(adapter->ahw.board_type, brd_name); | 745 | get_brd_name_by_type(adapter->ahw.board_type, brd_name); |
729 | 746 | ||
730 | printk(KERN_INFO "NetXen %s Board S/N %s Chip rev 0x%x\n", | 747 | pr_info("%s: %s Board S/N %s Chip rev 0x%x\n", |
748 | module_name(THIS_MODULE), | ||
731 | brd_name, serial_num, adapter->ahw.revision_id); | 749 | brd_name, serial_num, adapter->ahw.revision_id); |
732 | } | 750 | } |
733 | 751 | ||
@@ -815,11 +833,11 @@ netxen_start_firmware(struct netxen_adapter *adapter) | |||
815 | if (err < 0) | 833 | if (err < 0) |
816 | goto err_out; | 834 | goto err_out; |
817 | if (err == 0) | 835 | if (err == 0) |
818 | goto ready; | 836 | goto wait_init; |
819 | 837 | ||
820 | if (first_boot != 0x55555555) { | 838 | if (first_boot != 0x55555555) { |
821 | NXWR32(adapter, CRB_CMDPEG_STATE, 0); | 839 | NXWR32(adapter, CRB_CMDPEG_STATE, 0); |
822 | netxen_pinit_from_rom(adapter, 0); | 840 | netxen_pinit_from_rom(adapter); |
823 | msleep(1); | 841 | msleep(1); |
824 | } | 842 | } |
825 | 843 | ||
@@ -858,9 +876,6 @@ netxen_start_firmware(struct netxen_adapter *adapter) | |||
858 | | (_NETXEN_NIC_LINUX_SUBVERSION); | 876 | | (_NETXEN_NIC_LINUX_SUBVERSION); |
859 | NXWR32(adapter, CRB_DRIVER_VERSION, val); | 877 | NXWR32(adapter, CRB_DRIVER_VERSION, val); |
860 | 878 | ||
861 | ready: | ||
862 | NXWR32(adapter, NX_CRB_DEV_STATE, NX_DEV_READY); | ||
863 | |||
864 | wait_init: | 879 | wait_init: |
865 | /* Handshake with the card before we register the devices. */ | 880 | /* Handshake with the card before we register the devices. */ |
866 | err = netxen_phantom_init(adapter, NETXEN_NIC_PEG_TUNE); | 881 | err = netxen_phantom_init(adapter, NETXEN_NIC_PEG_TUNE); |
@@ -869,6 +884,8 @@ wait_init: | |||
869 | goto err_out; | 884 | goto err_out; |
870 | } | 885 | } |
871 | 886 | ||
887 | NXWR32(adapter, NX_CRB_DEV_STATE, NX_DEV_READY); | ||
888 | |||
872 | nx_update_dma_mask(adapter); | 889 | nx_update_dma_mask(adapter); |
873 | 890 | ||
874 | netxen_check_options(adapter); | 891 | netxen_check_options(adapter); |
@@ -943,8 +960,9 @@ netxen_nic_init_coalesce_defaults(struct netxen_adapter *adapter) | |||
943 | NETXEN_DEFAULT_INTR_COALESCE_TX_PACKETS; | 960 | NETXEN_DEFAULT_INTR_COALESCE_TX_PACKETS; |
944 | } | 961 | } |
945 | 962 | ||
963 | /* with rtnl_lock */ | ||
946 | static int | 964 | static int |
947 | netxen_nic_up(struct netxen_adapter *adapter, struct net_device *netdev) | 965 | __netxen_nic_up(struct netxen_adapter *adapter, struct net_device *netdev) |
948 | { | 966 | { |
949 | int err; | 967 | int err; |
950 | 968 | ||
@@ -985,14 +1003,32 @@ netxen_nic_up(struct netxen_adapter *adapter, struct net_device *netdev) | |||
985 | return 0; | 1003 | return 0; |
986 | } | 1004 | } |
987 | 1005 | ||
1006 | /* Usage: During resume and firmware recovery module.*/ | ||
1007 | |||
1008 | static inline int | ||
1009 | netxen_nic_up(struct netxen_adapter *adapter, struct net_device *netdev) | ||
1010 | { | ||
1011 | int err = 0; | ||
1012 | |||
1013 | rtnl_lock(); | ||
1014 | if (netif_running(netdev)) | ||
1015 | err = __netxen_nic_up(adapter, netdev); | ||
1016 | rtnl_unlock(); | ||
1017 | |||
1018 | return err; | ||
1019 | } | ||
1020 | |||
1021 | /* with rtnl_lock */ | ||
988 | static void | 1022 | static void |
989 | netxen_nic_down(struct netxen_adapter *adapter, struct net_device *netdev) | 1023 | __netxen_nic_down(struct netxen_adapter *adapter, struct net_device *netdev) |
990 | { | 1024 | { |
991 | if (adapter->is_up != NETXEN_ADAPTER_UP_MAGIC) | 1025 | if (adapter->is_up != NETXEN_ADAPTER_UP_MAGIC) |
992 | return; | 1026 | return; |
993 | 1027 | ||
994 | clear_bit(__NX_DEV_UP, &adapter->state); | 1028 | if (!test_and_clear_bit(__NX_DEV_UP, &adapter->state)) |
1029 | return; | ||
995 | 1030 | ||
1031 | smp_mb(); | ||
996 | spin_lock(&adapter->tx_clean_lock); | 1032 | spin_lock(&adapter->tx_clean_lock); |
997 | netif_carrier_off(netdev); | 1033 | netif_carrier_off(netdev); |
998 | netif_tx_disable(netdev); | 1034 | netif_tx_disable(netdev); |
@@ -1011,6 +1047,17 @@ netxen_nic_down(struct netxen_adapter *adapter, struct net_device *netdev) | |||
1011 | spin_unlock(&adapter->tx_clean_lock); | 1047 | spin_unlock(&adapter->tx_clean_lock); |
1012 | } | 1048 | } |
1013 | 1049 | ||
1050 | /* Usage: During suspend and firmware recovery module */ | ||
1051 | |||
1052 | static inline void | ||
1053 | netxen_nic_down(struct netxen_adapter *adapter, struct net_device *netdev) | ||
1054 | { | ||
1055 | rtnl_lock(); | ||
1056 | if (netif_running(netdev)) | ||
1057 | __netxen_nic_down(adapter, netdev); | ||
1058 | rtnl_unlock(); | ||
1059 | |||
1060 | } | ||
1014 | 1061 | ||
1015 | static int | 1062 | static int |
1016 | netxen_nic_attach(struct netxen_adapter *adapter) | 1063 | netxen_nic_attach(struct netxen_adapter *adapter) |
@@ -1119,14 +1166,14 @@ netxen_nic_reset_context(struct netxen_adapter *adapter) | |||
1119 | netif_device_detach(netdev); | 1166 | netif_device_detach(netdev); |
1120 | 1167 | ||
1121 | if (netif_running(netdev)) | 1168 | if (netif_running(netdev)) |
1122 | netxen_nic_down(adapter, netdev); | 1169 | __netxen_nic_down(adapter, netdev); |
1123 | 1170 | ||
1124 | netxen_nic_detach(adapter); | 1171 | netxen_nic_detach(adapter); |
1125 | 1172 | ||
1126 | if (netif_running(netdev)) { | 1173 | if (netif_running(netdev)) { |
1127 | err = netxen_nic_attach(adapter); | 1174 | err = netxen_nic_attach(adapter); |
1128 | if (!err) | 1175 | if (!err) |
1129 | err = netxen_nic_up(adapter, netdev); | 1176 | err = __netxen_nic_up(adapter, netdev); |
1130 | 1177 | ||
1131 | if (err) | 1178 | if (err) |
1132 | goto done; | 1179 | goto done; |
@@ -1209,16 +1256,10 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
1209 | int pci_func_id = PCI_FUNC(pdev->devfn); | 1256 | int pci_func_id = PCI_FUNC(pdev->devfn); |
1210 | uint8_t revision_id; | 1257 | uint8_t revision_id; |
1211 | 1258 | ||
1212 | if (pdev->class != 0x020000) { | 1259 | if (pdev->revision >= NX_P3_A0 && pdev->revision <= NX_P3_B1) { |
1213 | printk(KERN_DEBUG "NetXen function %d, class %x will not " | 1260 | pr_warning("%s: chip revisions between 0x%x-0x%x " |
1214 | "be enabled.\n",pci_func_id, pdev->class); | ||
1215 | return -ENODEV; | ||
1216 | } | ||
1217 | |||
1218 | if (pdev->revision >= NX_P3_A0 && pdev->revision < NX_P3_B1) { | ||
1219 | printk(KERN_WARNING "NetXen chip revisions between 0x%x-0x%x" | ||
1220 | "will not be enabled.\n", | 1261 | "will not be enabled.\n", |
1221 | NX_P3_A0, NX_P3_B1); | 1262 | module_name(THIS_MODULE), NX_P3_A0, NX_P3_B1); |
1222 | return -ENODEV; | 1263 | return -ENODEV; |
1223 | } | 1264 | } |
1224 | 1265 | ||
@@ -1233,6 +1274,9 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
1233 | if ((err = pci_request_regions(pdev, netxen_nic_driver_name))) | 1274 | if ((err = pci_request_regions(pdev, netxen_nic_driver_name))) |
1234 | goto err_out_disable_pdev; | 1275 | goto err_out_disable_pdev; |
1235 | 1276 | ||
1277 | if (NX_IS_REVISION_P3(pdev->revision)) | ||
1278 | pci_enable_pcie_error_reporting(pdev); | ||
1279 | |||
1236 | pci_set_master(pdev); | 1280 | pci_set_master(pdev); |
1237 | 1281 | ||
1238 | netdev = alloc_etherdev(sizeof(struct netxen_adapter)); | 1282 | netdev = alloc_etherdev(sizeof(struct netxen_adapter)); |
@@ -1252,7 +1296,9 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
1252 | revision_id = pdev->revision; | 1296 | revision_id = pdev->revision; |
1253 | adapter->ahw.revision_id = revision_id; | 1297 | adapter->ahw.revision_id = revision_id; |
1254 | 1298 | ||
1255 | rwlock_init(&adapter->adapter_lock); | 1299 | rwlock_init(&adapter->ahw.crb_lock); |
1300 | spin_lock_init(&adapter->ahw.mem_lock); | ||
1301 | |||
1256 | spin_lock_init(&adapter->tx_clean_lock); | 1302 | spin_lock_init(&adapter->tx_clean_lock); |
1257 | INIT_LIST_HEAD(&adapter->mac_list); | 1303 | INIT_LIST_HEAD(&adapter->mac_list); |
1258 | 1304 | ||
@@ -1282,7 +1328,7 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
1282 | 1328 | ||
1283 | err = netxen_start_firmware(adapter); | 1329 | err = netxen_start_firmware(adapter); |
1284 | if (err) | 1330 | if (err) |
1285 | goto err_out_iounmap; | 1331 | goto err_out_decr_ref; |
1286 | 1332 | ||
1287 | /* | 1333 | /* |
1288 | * See if the firmware gave us a virtual-physical port mapping. | 1334 | * See if the firmware gave us a virtual-physical port mapping. |
@@ -1317,6 +1363,8 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
1317 | break; | 1363 | break; |
1318 | } | 1364 | } |
1319 | 1365 | ||
1366 | netxen_create_diag_entries(adapter); | ||
1367 | |||
1320 | return 0; | 1368 | return 0; |
1321 | 1369 | ||
1322 | err_out_disable_msi: | 1370 | err_out_disable_msi: |
@@ -1324,6 +1372,7 @@ err_out_disable_msi: | |||
1324 | 1372 | ||
1325 | netxen_free_dummy_dma(adapter); | 1373 | netxen_free_dummy_dma(adapter); |
1326 | 1374 | ||
1375 | err_out_decr_ref: | ||
1327 | nx_decr_dev_ref_cnt(adapter); | 1376 | nx_decr_dev_ref_cnt(adapter); |
1328 | 1377 | ||
1329 | err_out_iounmap: | 1378 | err_out_iounmap: |
@@ -1369,21 +1418,25 @@ static void __devexit netxen_nic_remove(struct pci_dev *pdev) | |||
1369 | 1418 | ||
1370 | netxen_teardown_intr(adapter); | 1419 | netxen_teardown_intr(adapter); |
1371 | 1420 | ||
1421 | netxen_remove_diag_entries(adapter); | ||
1422 | |||
1372 | netxen_cleanup_pci_map(adapter); | 1423 | netxen_cleanup_pci_map(adapter); |
1373 | 1424 | ||
1374 | netxen_release_firmware(adapter); | 1425 | netxen_release_firmware(adapter); |
1375 | 1426 | ||
1427 | if (NX_IS_REVISION_P3(pdev->revision)) | ||
1428 | pci_disable_pcie_error_reporting(pdev); | ||
1429 | |||
1376 | pci_release_regions(pdev); | 1430 | pci_release_regions(pdev); |
1377 | pci_disable_device(pdev); | 1431 | pci_disable_device(pdev); |
1378 | pci_set_drvdata(pdev, NULL); | 1432 | pci_set_drvdata(pdev, NULL); |
1379 | 1433 | ||
1380 | free_netdev(netdev); | 1434 | free_netdev(netdev); |
1381 | } | 1435 | } |
1382 | static int __netxen_nic_shutdown(struct pci_dev *pdev) | 1436 | |
1437 | static void netxen_nic_detach_func(struct netxen_adapter *adapter) | ||
1383 | { | 1438 | { |
1384 | struct netxen_adapter *adapter = pci_get_drvdata(pdev); | ||
1385 | struct net_device *netdev = adapter->netdev; | 1439 | struct net_device *netdev = adapter->netdev; |
1386 | int retval; | ||
1387 | 1440 | ||
1388 | netif_device_detach(netdev); | 1441 | netif_device_detach(netdev); |
1389 | 1442 | ||
@@ -1402,54 +1455,24 @@ static int __netxen_nic_shutdown(struct pci_dev *pdev) | |||
1402 | nx_decr_dev_ref_cnt(adapter); | 1455 | nx_decr_dev_ref_cnt(adapter); |
1403 | 1456 | ||
1404 | clear_bit(__NX_RESETTING, &adapter->state); | 1457 | clear_bit(__NX_RESETTING, &adapter->state); |
1405 | |||
1406 | retval = pci_save_state(pdev); | ||
1407 | if (retval) | ||
1408 | return retval; | ||
1409 | |||
1410 | if (netxen_nic_wol_supported(adapter)) { | ||
1411 | pci_enable_wake(pdev, PCI_D3cold, 1); | ||
1412 | pci_enable_wake(pdev, PCI_D3hot, 1); | ||
1413 | } | ||
1414 | |||
1415 | pci_disable_device(pdev); | ||
1416 | |||
1417 | return 0; | ||
1418 | } | ||
1419 | static void netxen_nic_shutdown(struct pci_dev *pdev) | ||
1420 | { | ||
1421 | if (__netxen_nic_shutdown(pdev)) | ||
1422 | return; | ||
1423 | } | ||
1424 | #ifdef CONFIG_PM | ||
1425 | static int | ||
1426 | netxen_nic_suspend(struct pci_dev *pdev, pm_message_t state) | ||
1427 | { | ||
1428 | int retval; | ||
1429 | |||
1430 | retval = __netxen_nic_shutdown(pdev); | ||
1431 | if (retval) | ||
1432 | return retval; | ||
1433 | |||
1434 | pci_set_power_state(pdev, pci_choose_state(pdev, state)); | ||
1435 | return 0; | ||
1436 | } | 1458 | } |
1437 | 1459 | ||
1438 | static int | 1460 | static int netxen_nic_attach_func(struct pci_dev *pdev) |
1439 | netxen_nic_resume(struct pci_dev *pdev) | ||
1440 | { | 1461 | { |
1441 | struct netxen_adapter *adapter = pci_get_drvdata(pdev); | 1462 | struct netxen_adapter *adapter = pci_get_drvdata(pdev); |
1442 | struct net_device *netdev = adapter->netdev; | 1463 | struct net_device *netdev = adapter->netdev; |
1443 | int err; | 1464 | int err; |
1444 | 1465 | ||
1445 | pci_set_power_state(pdev, PCI_D0); | ||
1446 | pci_restore_state(pdev); | ||
1447 | |||
1448 | err = pci_enable_device(pdev); | 1466 | err = pci_enable_device(pdev); |
1449 | if (err) | 1467 | if (err) |
1450 | return err; | 1468 | return err; |
1451 | 1469 | ||
1452 | adapter->curr_window = 255; | 1470 | pci_set_power_state(pdev, PCI_D0); |
1471 | pci_set_master(pdev); | ||
1472 | pci_restore_state(pdev); | ||
1473 | |||
1474 | adapter->ahw.crb_win = -1; | ||
1475 | adapter->ahw.ocm_win = -1; | ||
1453 | 1476 | ||
1454 | err = netxen_start_firmware(adapter); | 1477 | err = netxen_start_firmware(adapter); |
1455 | if (err) { | 1478 | if (err) { |
@@ -1466,11 +1489,10 @@ netxen_nic_resume(struct pci_dev *pdev) | |||
1466 | if (err) | 1489 | if (err) |
1467 | goto err_out_detach; | 1490 | goto err_out_detach; |
1468 | 1491 | ||
1469 | netif_device_attach(netdev); | ||
1470 | |||
1471 | netxen_config_indev_addr(netdev, NETDEV_UP); | 1492 | netxen_config_indev_addr(netdev, NETDEV_UP); |
1472 | } | 1493 | } |
1473 | 1494 | ||
1495 | netif_device_attach(netdev); | ||
1474 | netxen_schedule_work(adapter, netxen_fw_poll_work, FW_POLL_DELAY); | 1496 | netxen_schedule_work(adapter, netxen_fw_poll_work, FW_POLL_DELAY); |
1475 | return 0; | 1497 | return 0; |
1476 | 1498 | ||
@@ -1480,6 +1502,85 @@ err_out: | |||
1480 | nx_decr_dev_ref_cnt(adapter); | 1502 | nx_decr_dev_ref_cnt(adapter); |
1481 | return err; | 1503 | return err; |
1482 | } | 1504 | } |
1505 | |||
1506 | static pci_ers_result_t netxen_io_error_detected(struct pci_dev *pdev, | ||
1507 | pci_channel_state_t state) | ||
1508 | { | ||
1509 | struct netxen_adapter *adapter = pci_get_drvdata(pdev); | ||
1510 | |||
1511 | if (state == pci_channel_io_perm_failure) | ||
1512 | return PCI_ERS_RESULT_DISCONNECT; | ||
1513 | |||
1514 | if (nx_dev_request_aer(adapter)) | ||
1515 | return PCI_ERS_RESULT_RECOVERED; | ||
1516 | |||
1517 | netxen_nic_detach_func(adapter); | ||
1518 | |||
1519 | pci_disable_device(pdev); | ||
1520 | |||
1521 | return PCI_ERS_RESULT_NEED_RESET; | ||
1522 | } | ||
1523 | |||
1524 | static pci_ers_result_t netxen_io_slot_reset(struct pci_dev *pdev) | ||
1525 | { | ||
1526 | int err = 0; | ||
1527 | |||
1528 | err = netxen_nic_attach_func(pdev); | ||
1529 | |||
1530 | return err ? PCI_ERS_RESULT_DISCONNECT : PCI_ERS_RESULT_RECOVERED; | ||
1531 | } | ||
1532 | |||
1533 | static void netxen_io_resume(struct pci_dev *pdev) | ||
1534 | { | ||
1535 | pci_cleanup_aer_uncorrect_error_status(pdev); | ||
1536 | } | ||
1537 | |||
1538 | static void netxen_nic_shutdown(struct pci_dev *pdev) | ||
1539 | { | ||
1540 | struct netxen_adapter *adapter = pci_get_drvdata(pdev); | ||
1541 | |||
1542 | netxen_nic_detach_func(adapter); | ||
1543 | |||
1544 | if (pci_save_state(pdev)) | ||
1545 | return; | ||
1546 | |||
1547 | if (netxen_nic_wol_supported(adapter)) { | ||
1548 | pci_enable_wake(pdev, PCI_D3cold, 1); | ||
1549 | pci_enable_wake(pdev, PCI_D3hot, 1); | ||
1550 | } | ||
1551 | |||
1552 | pci_disable_device(pdev); | ||
1553 | } | ||
1554 | |||
1555 | #ifdef CONFIG_PM | ||
1556 | static int | ||
1557 | netxen_nic_suspend(struct pci_dev *pdev, pm_message_t state) | ||
1558 | { | ||
1559 | struct netxen_adapter *adapter = pci_get_drvdata(pdev); | ||
1560 | int retval; | ||
1561 | |||
1562 | netxen_nic_detach_func(adapter); | ||
1563 | |||
1564 | retval = pci_save_state(pdev); | ||
1565 | if (retval) | ||
1566 | return retval; | ||
1567 | |||
1568 | if (netxen_nic_wol_supported(adapter)) { | ||
1569 | pci_enable_wake(pdev, PCI_D3cold, 1); | ||
1570 | pci_enable_wake(pdev, PCI_D3hot, 1); | ||
1571 | } | ||
1572 | |||
1573 | pci_disable_device(pdev); | ||
1574 | pci_set_power_state(pdev, pci_choose_state(pdev, state)); | ||
1575 | |||
1576 | return 0; | ||
1577 | } | ||
1578 | |||
1579 | static int | ||
1580 | netxen_nic_resume(struct pci_dev *pdev) | ||
1581 | { | ||
1582 | return netxen_nic_attach_func(pdev); | ||
1583 | } | ||
1483 | #endif | 1584 | #endif |
1484 | 1585 | ||
1485 | static int netxen_nic_open(struct net_device *netdev) | 1586 | static int netxen_nic_open(struct net_device *netdev) |
@@ -1494,7 +1595,7 @@ static int netxen_nic_open(struct net_device *netdev) | |||
1494 | if (err) | 1595 | if (err) |
1495 | return err; | 1596 | return err; |
1496 | 1597 | ||
1497 | err = netxen_nic_up(adapter, netdev); | 1598 | err = __netxen_nic_up(adapter, netdev); |
1498 | if (err) | 1599 | if (err) |
1499 | goto err_out; | 1600 | goto err_out; |
1500 | 1601 | ||
@@ -1514,7 +1615,7 @@ static int netxen_nic_close(struct net_device *netdev) | |||
1514 | { | 1615 | { |
1515 | struct netxen_adapter *adapter = netdev_priv(netdev); | 1616 | struct netxen_adapter *adapter = netdev_priv(netdev); |
1516 | 1617 | ||
1517 | netxen_nic_down(adapter, netdev); | 1618 | __netxen_nic_down(adapter, netdev); |
1518 | return 0; | 1619 | return 0; |
1519 | } | 1620 | } |
1520 | 1621 | ||
@@ -1861,12 +1962,8 @@ static void netxen_nic_handle_phy_intr(struct netxen_adapter *adapter) | |||
1861 | linkup = (val == XG_LINK_UP_P3); | 1962 | linkup = (val == XG_LINK_UP_P3); |
1862 | } else { | 1963 | } else { |
1863 | val = NXRD32(adapter, CRB_XG_STATE); | 1964 | val = NXRD32(adapter, CRB_XG_STATE); |
1864 | if (adapter->ahw.port_type == NETXEN_NIC_GBE) | 1965 | val = (val >> port*8) & 0xff; |
1865 | linkup = (val >> port) & 1; | 1966 | linkup = (val == XG_LINK_UP); |
1866 | else { | ||
1867 | val = (val >> port*8) & 0xff; | ||
1868 | linkup = (val == XG_LINK_UP); | ||
1869 | } | ||
1870 | } | 1967 | } |
1871 | 1968 | ||
1872 | netxen_advert_link_change(adapter, linkup); | 1969 | netxen_advert_link_change(adapter, linkup); |
@@ -1908,7 +2005,7 @@ static void netxen_tx_timeout_task(struct work_struct *work) | |||
1908 | netif_wake_queue(adapter->netdev); | 2005 | netif_wake_queue(adapter->netdev); |
1909 | 2006 | ||
1910 | clear_bit(__NX_RESETTING, &adapter->state); | 2007 | clear_bit(__NX_RESETTING, &adapter->state); |
1911 | 2008 | return; | |
1912 | } else { | 2009 | } else { |
1913 | clear_bit(__NX_RESETTING, &adapter->state); | 2010 | clear_bit(__NX_RESETTING, &adapter->state); |
1914 | if (!netxen_nic_reset_context(adapter)) { | 2011 | if (!netxen_nic_reset_context(adapter)) { |
@@ -1927,7 +2024,7 @@ request_reset: | |||
1927 | struct net_device_stats *netxen_nic_get_stats(struct net_device *netdev) | 2024 | struct net_device_stats *netxen_nic_get_stats(struct net_device *netdev) |
1928 | { | 2025 | { |
1929 | struct netxen_adapter *adapter = netdev_priv(netdev); | 2026 | struct netxen_adapter *adapter = netdev_priv(netdev); |
1930 | struct net_device_stats *stats = &adapter->net_stats; | 2027 | struct net_device_stats *stats = &netdev->stats; |
1931 | 2028 | ||
1932 | memset(stats, 0, sizeof(*stats)); | 2029 | memset(stats, 0, sizeof(*stats)); |
1933 | 2030 | ||
@@ -2020,7 +2117,7 @@ static int netxen_nic_poll(struct napi_struct *napi, int budget) | |||
2020 | 2117 | ||
2021 | if ((work_done < budget) && tx_complete) { | 2118 | if ((work_done < budget) && tx_complete) { |
2022 | napi_complete(&sds_ring->napi); | 2119 | napi_complete(&sds_ring->napi); |
2023 | if (netif_running(adapter->netdev)) | 2120 | if (test_bit(__NX_DEV_UP, &adapter->state)) |
2024 | netxen_nic_enable_int(sds_ring); | 2121 | netxen_nic_enable_int(sds_ring); |
2025 | } | 2122 | } |
2026 | 2123 | ||
@@ -2071,20 +2168,49 @@ nx_decr_dev_ref_cnt(struct netxen_adapter *adapter) | |||
2071 | return count; | 2168 | return count; |
2072 | } | 2169 | } |
2073 | 2170 | ||
2074 | static void | 2171 | static int |
2172 | nx_dev_request_aer(struct netxen_adapter *adapter) | ||
2173 | { | ||
2174 | u32 state; | ||
2175 | int ret = -EINVAL; | ||
2176 | |||
2177 | if (netxen_api_lock(adapter)) | ||
2178 | return ret; | ||
2179 | |||
2180 | state = NXRD32(adapter, NX_CRB_DEV_STATE); | ||
2181 | |||
2182 | if (state == NX_DEV_NEED_AER) | ||
2183 | ret = 0; | ||
2184 | else if (state == NX_DEV_READY) { | ||
2185 | NXWR32(adapter, NX_CRB_DEV_STATE, NX_DEV_NEED_AER); | ||
2186 | ret = 0; | ||
2187 | } | ||
2188 | |||
2189 | netxen_api_unlock(adapter); | ||
2190 | return ret; | ||
2191 | } | ||
2192 | |||
2193 | static int | ||
2075 | nx_dev_request_reset(struct netxen_adapter *adapter) | 2194 | nx_dev_request_reset(struct netxen_adapter *adapter) |
2076 | { | 2195 | { |
2077 | u32 state; | 2196 | u32 state; |
2197 | int ret = -EINVAL; | ||
2078 | 2198 | ||
2079 | if (netxen_api_lock(adapter)) | 2199 | if (netxen_api_lock(adapter)) |
2080 | return; | 2200 | return ret; |
2081 | 2201 | ||
2082 | state = NXRD32(adapter, NX_CRB_DEV_STATE); | 2202 | state = NXRD32(adapter, NX_CRB_DEV_STATE); |
2083 | 2203 | ||
2084 | if (state != NX_DEV_INITALIZING) | 2204 | if (state == NX_DEV_NEED_RESET) |
2205 | ret = 0; | ||
2206 | else if (state != NX_DEV_INITALIZING && state != NX_DEV_NEED_AER) { | ||
2085 | NXWR32(adapter, NX_CRB_DEV_STATE, NX_DEV_NEED_RESET); | 2207 | NXWR32(adapter, NX_CRB_DEV_STATE, NX_DEV_NEED_RESET); |
2208 | ret = 0; | ||
2209 | } | ||
2086 | 2210 | ||
2087 | netxen_api_unlock(adapter); | 2211 | netxen_api_unlock(adapter); |
2212 | |||
2213 | return ret; | ||
2088 | } | 2214 | } |
2089 | 2215 | ||
2090 | static int | 2216 | static int |
@@ -2184,14 +2310,13 @@ netxen_fwinit_work(struct work_struct *work) | |||
2184 | netxen_fwinit_work, 2 * FW_POLL_DELAY); | 2310 | netxen_fwinit_work, 2 * FW_POLL_DELAY); |
2185 | return; | 2311 | return; |
2186 | } | 2312 | } |
2187 | break; | ||
2188 | 2313 | ||
2189 | case NX_DEV_FAILED: | 2314 | case NX_DEV_FAILED: |
2190 | default: | 2315 | default: |
2316 | nx_incr_dev_ref_cnt(adapter); | ||
2191 | break; | 2317 | break; |
2192 | } | 2318 | } |
2193 | 2319 | ||
2194 | nx_incr_dev_ref_cnt(adapter); | ||
2195 | clear_bit(__NX_RESETTING, &adapter->state); | 2320 | clear_bit(__NX_RESETTING, &adapter->state); |
2196 | } | 2321 | } |
2197 | 2322 | ||
@@ -2206,25 +2331,31 @@ netxen_detach_work(struct work_struct *work) | |||
2206 | 2331 | ||
2207 | netif_device_detach(netdev); | 2332 | netif_device_detach(netdev); |
2208 | 2333 | ||
2209 | if (netif_running(netdev)) | 2334 | netxen_nic_down(adapter, netdev); |
2210 | netxen_nic_down(adapter, netdev); | ||
2211 | 2335 | ||
2336 | rtnl_lock(); | ||
2212 | netxen_nic_detach(adapter); | 2337 | netxen_nic_detach(adapter); |
2338 | rtnl_unlock(); | ||
2213 | 2339 | ||
2214 | status = NXRD32(adapter, NETXEN_PEG_HALT_STATUS1); | 2340 | status = NXRD32(adapter, NETXEN_PEG_HALT_STATUS1); |
2215 | 2341 | ||
2216 | ref_cnt = nx_decr_dev_ref_cnt(adapter); | ||
2217 | |||
2218 | if (status & NX_RCODE_FATAL_ERROR) | 2342 | if (status & NX_RCODE_FATAL_ERROR) |
2219 | return; | 2343 | goto err_ret; |
2220 | 2344 | ||
2221 | if (adapter->temp == NX_TEMP_PANIC) | 2345 | if (adapter->temp == NX_TEMP_PANIC) |
2222 | return; | 2346 | goto err_ret; |
2347 | |||
2348 | ref_cnt = nx_decr_dev_ref_cnt(adapter); | ||
2223 | 2349 | ||
2224 | delay = (ref_cnt == 0) ? 0 : (2 * FW_POLL_DELAY); | 2350 | delay = (ref_cnt == 0) ? 0 : (2 * FW_POLL_DELAY); |
2225 | 2351 | ||
2226 | adapter->fw_wait_cnt = 0; | 2352 | adapter->fw_wait_cnt = 0; |
2227 | netxen_schedule_work(adapter, netxen_fwinit_work, delay); | 2353 | netxen_schedule_work(adapter, netxen_fwinit_work, delay); |
2354 | |||
2355 | return; | ||
2356 | |||
2357 | err_ret: | ||
2358 | clear_bit(__NX_RESETTING, &adapter->state); | ||
2228 | } | 2359 | } |
2229 | 2360 | ||
2230 | static int | 2361 | static int |
@@ -2233,17 +2364,29 @@ netxen_check_health(struct netxen_adapter *adapter) | |||
2233 | u32 state, heartbit; | 2364 | u32 state, heartbit; |
2234 | struct net_device *netdev = adapter->netdev; | 2365 | struct net_device *netdev = adapter->netdev; |
2235 | 2366 | ||
2367 | state = NXRD32(adapter, NX_CRB_DEV_STATE); | ||
2368 | if (state == NX_DEV_NEED_AER) | ||
2369 | return 0; | ||
2370 | |||
2236 | if (netxen_nic_check_temp(adapter)) | 2371 | if (netxen_nic_check_temp(adapter)) |
2237 | goto detach; | 2372 | goto detach; |
2238 | 2373 | ||
2239 | if (adapter->need_fw_reset) { | 2374 | if (adapter->need_fw_reset) { |
2240 | nx_dev_request_reset(adapter); | 2375 | if (nx_dev_request_reset(adapter)) |
2376 | return 0; | ||
2241 | goto detach; | 2377 | goto detach; |
2242 | } | 2378 | } |
2243 | 2379 | ||
2244 | state = NXRD32(adapter, NX_CRB_DEV_STATE); | 2380 | /* NX_DEV_NEED_RESET, this state can be marked in two cases |
2245 | if (state == NX_DEV_NEED_RESET) | 2381 | * 1. Tx timeout 2. Fw hang |
2246 | goto detach; | 2382 | * Send request to destroy context in case of tx timeout only |
2383 | * and doesn't required in case of Fw hang | ||
2384 | */ | ||
2385 | if (state == NX_DEV_NEED_RESET) { | ||
2386 | adapter->need_fw_reset = 1; | ||
2387 | if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) | ||
2388 | goto detach; | ||
2389 | } | ||
2247 | 2390 | ||
2248 | if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) | 2391 | if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) |
2249 | return 0; | 2392 | return 0; |
@@ -2252,18 +2395,24 @@ netxen_check_health(struct netxen_adapter *adapter) | |||
2252 | if (heartbit != adapter->heartbit) { | 2395 | if (heartbit != adapter->heartbit) { |
2253 | adapter->heartbit = heartbit; | 2396 | adapter->heartbit = heartbit; |
2254 | adapter->fw_fail_cnt = 0; | 2397 | adapter->fw_fail_cnt = 0; |
2398 | if (adapter->need_fw_reset) | ||
2399 | goto detach; | ||
2255 | return 0; | 2400 | return 0; |
2256 | } | 2401 | } |
2257 | 2402 | ||
2258 | if (++adapter->fw_fail_cnt < FW_FAIL_THRESH) | 2403 | if (++adapter->fw_fail_cnt < FW_FAIL_THRESH) |
2259 | return 0; | 2404 | return 0; |
2260 | 2405 | ||
2406 | if (nx_dev_request_reset(adapter)) | ||
2407 | return 0; | ||
2408 | |||
2261 | clear_bit(__NX_FW_ATTACHED, &adapter->state); | 2409 | clear_bit(__NX_FW_ATTACHED, &adapter->state); |
2262 | 2410 | ||
2263 | dev_info(&netdev->dev, "firmware hang detected\n"); | 2411 | dev_info(&netdev->dev, "firmware hang detected\n"); |
2264 | 2412 | ||
2265 | detach: | 2413 | detach: |
2266 | if (!test_and_set_bit(__NX_RESETTING, &adapter->state)) | 2414 | if ((auto_fw_reset == AUTO_FW_RESET_ENABLED) && |
2415 | !test_and_set_bit(__NX_RESETTING, &adapter->state)) | ||
2267 | netxen_schedule_work(adapter, netxen_detach_work, 0); | 2416 | netxen_schedule_work(adapter, netxen_detach_work, 0); |
2268 | return 1; | 2417 | return 1; |
2269 | } | 2418 | } |
@@ -2341,6 +2490,161 @@ static struct device_attribute dev_attr_bridged_mode = { | |||
2341 | .store = netxen_store_bridged_mode, | 2490 | .store = netxen_store_bridged_mode, |
2342 | }; | 2491 | }; |
2343 | 2492 | ||
2493 | static ssize_t | ||
2494 | netxen_store_diag_mode(struct device *dev, | ||
2495 | struct device_attribute *attr, const char *buf, size_t len) | ||
2496 | { | ||
2497 | struct netxen_adapter *adapter = dev_get_drvdata(dev); | ||
2498 | unsigned long new; | ||
2499 | |||
2500 | if (strict_strtoul(buf, 2, &new)) | ||
2501 | return -EINVAL; | ||
2502 | |||
2503 | if (!!new != !!(adapter->flags & NETXEN_NIC_DIAG_ENABLED)) | ||
2504 | adapter->flags ^= NETXEN_NIC_DIAG_ENABLED; | ||
2505 | |||
2506 | return len; | ||
2507 | } | ||
2508 | |||
2509 | static ssize_t | ||
2510 | netxen_show_diag_mode(struct device *dev, | ||
2511 | struct device_attribute *attr, char *buf) | ||
2512 | { | ||
2513 | struct netxen_adapter *adapter = dev_get_drvdata(dev); | ||
2514 | |||
2515 | return sprintf(buf, "%d\n", | ||
2516 | !!(adapter->flags & NETXEN_NIC_DIAG_ENABLED)); | ||
2517 | } | ||
2518 | |||
2519 | static struct device_attribute dev_attr_diag_mode = { | ||
2520 | .attr = {.name = "diag_mode", .mode = (S_IRUGO | S_IWUSR)}, | ||
2521 | .show = netxen_show_diag_mode, | ||
2522 | .store = netxen_store_diag_mode, | ||
2523 | }; | ||
2524 | |||
2525 | static int | ||
2526 | netxen_sysfs_validate_crb(struct netxen_adapter *adapter, | ||
2527 | loff_t offset, size_t size) | ||
2528 | { | ||
2529 | if (!(adapter->flags & NETXEN_NIC_DIAG_ENABLED)) | ||
2530 | return -EIO; | ||
2531 | |||
2532 | if ((size != 4) || (offset & 0x3)) | ||
2533 | return -EINVAL; | ||
2534 | |||
2535 | if (offset < NETXEN_PCI_CRBSPACE) | ||
2536 | return -EINVAL; | ||
2537 | |||
2538 | return 0; | ||
2539 | } | ||
2540 | |||
2541 | static ssize_t | ||
2542 | netxen_sysfs_read_crb(struct kobject *kobj, struct bin_attribute *attr, | ||
2543 | char *buf, loff_t offset, size_t size) | ||
2544 | { | ||
2545 | struct device *dev = container_of(kobj, struct device, kobj); | ||
2546 | struct netxen_adapter *adapter = dev_get_drvdata(dev); | ||
2547 | u32 data; | ||
2548 | int ret; | ||
2549 | |||
2550 | ret = netxen_sysfs_validate_crb(adapter, offset, size); | ||
2551 | if (ret != 0) | ||
2552 | return ret; | ||
2553 | |||
2554 | data = NXRD32(adapter, offset); | ||
2555 | memcpy(buf, &data, size); | ||
2556 | return size; | ||
2557 | } | ||
2558 | |||
2559 | static ssize_t | ||
2560 | netxen_sysfs_write_crb(struct kobject *kobj, struct bin_attribute *attr, | ||
2561 | char *buf, loff_t offset, size_t size) | ||
2562 | { | ||
2563 | struct device *dev = container_of(kobj, struct device, kobj); | ||
2564 | struct netxen_adapter *adapter = dev_get_drvdata(dev); | ||
2565 | u32 data; | ||
2566 | int ret; | ||
2567 | |||
2568 | ret = netxen_sysfs_validate_crb(adapter, offset, size); | ||
2569 | if (ret != 0) | ||
2570 | return ret; | ||
2571 | |||
2572 | memcpy(&data, buf, size); | ||
2573 | NXWR32(adapter, offset, data); | ||
2574 | return size; | ||
2575 | } | ||
2576 | |||
2577 | static int | ||
2578 | netxen_sysfs_validate_mem(struct netxen_adapter *adapter, | ||
2579 | loff_t offset, size_t size) | ||
2580 | { | ||
2581 | if (!(adapter->flags & NETXEN_NIC_DIAG_ENABLED)) | ||
2582 | return -EIO; | ||
2583 | |||
2584 | if ((size != 8) || (offset & 0x7)) | ||
2585 | return -EIO; | ||
2586 | |||
2587 | return 0; | ||
2588 | } | ||
2589 | |||
2590 | static ssize_t | ||
2591 | netxen_sysfs_read_mem(struct kobject *kobj, struct bin_attribute *attr, | ||
2592 | char *buf, loff_t offset, size_t size) | ||
2593 | { | ||
2594 | struct device *dev = container_of(kobj, struct device, kobj); | ||
2595 | struct netxen_adapter *adapter = dev_get_drvdata(dev); | ||
2596 | u64 data; | ||
2597 | int ret; | ||
2598 | |||
2599 | ret = netxen_sysfs_validate_mem(adapter, offset, size); | ||
2600 | if (ret != 0) | ||
2601 | return ret; | ||
2602 | |||
2603 | if (adapter->pci_mem_read(adapter, offset, &data)) | ||
2604 | return -EIO; | ||
2605 | |||
2606 | memcpy(buf, &data, size); | ||
2607 | |||
2608 | return size; | ||
2609 | } | ||
2610 | |||
2611 | static ssize_t netxen_sysfs_write_mem(struct kobject *kobj, | ||
2612 | struct bin_attribute *attr, char *buf, | ||
2613 | loff_t offset, size_t size) | ||
2614 | { | ||
2615 | struct device *dev = container_of(kobj, struct device, kobj); | ||
2616 | struct netxen_adapter *adapter = dev_get_drvdata(dev); | ||
2617 | u64 data; | ||
2618 | int ret; | ||
2619 | |||
2620 | ret = netxen_sysfs_validate_mem(adapter, offset, size); | ||
2621 | if (ret != 0) | ||
2622 | return ret; | ||
2623 | |||
2624 | memcpy(&data, buf, size); | ||
2625 | |||
2626 | if (adapter->pci_mem_write(adapter, offset, data)) | ||
2627 | return -EIO; | ||
2628 | |||
2629 | return size; | ||
2630 | } | ||
2631 | |||
2632 | |||
2633 | static struct bin_attribute bin_attr_crb = { | ||
2634 | .attr = {.name = "crb", .mode = (S_IRUGO | S_IWUSR)}, | ||
2635 | .size = 0, | ||
2636 | .read = netxen_sysfs_read_crb, | ||
2637 | .write = netxen_sysfs_write_crb, | ||
2638 | }; | ||
2639 | |||
2640 | static struct bin_attribute bin_attr_mem = { | ||
2641 | .attr = {.name = "mem", .mode = (S_IRUGO | S_IWUSR)}, | ||
2642 | .size = 0, | ||
2643 | .read = netxen_sysfs_read_mem, | ||
2644 | .write = netxen_sysfs_write_mem, | ||
2645 | }; | ||
2646 | |||
2647 | |||
2344 | static void | 2648 | static void |
2345 | netxen_create_sysfs_entries(struct netxen_adapter *adapter) | 2649 | netxen_create_sysfs_entries(struct netxen_adapter *adapter) |
2346 | { | 2650 | { |
@@ -2366,6 +2670,33 @@ netxen_remove_sysfs_entries(struct netxen_adapter *adapter) | |||
2366 | device_remove_file(dev, &dev_attr_bridged_mode); | 2670 | device_remove_file(dev, &dev_attr_bridged_mode); |
2367 | } | 2671 | } |
2368 | 2672 | ||
2673 | static void | ||
2674 | netxen_create_diag_entries(struct netxen_adapter *adapter) | ||
2675 | { | ||
2676 | struct pci_dev *pdev = adapter->pdev; | ||
2677 | struct device *dev; | ||
2678 | |||
2679 | dev = &pdev->dev; | ||
2680 | if (device_create_file(dev, &dev_attr_diag_mode)) | ||
2681 | dev_info(dev, "failed to create diag_mode sysfs entry\n"); | ||
2682 | if (device_create_bin_file(dev, &bin_attr_crb)) | ||
2683 | dev_info(dev, "failed to create crb sysfs entry\n"); | ||
2684 | if (device_create_bin_file(dev, &bin_attr_mem)) | ||
2685 | dev_info(dev, "failed to create mem sysfs entry\n"); | ||
2686 | } | ||
2687 | |||
2688 | |||
2689 | static void | ||
2690 | netxen_remove_diag_entries(struct netxen_adapter *adapter) | ||
2691 | { | ||
2692 | struct pci_dev *pdev = adapter->pdev; | ||
2693 | struct device *dev = &pdev->dev; | ||
2694 | |||
2695 | device_remove_file(dev, &dev_attr_diag_mode); | ||
2696 | device_remove_bin_file(dev, &bin_attr_crb); | ||
2697 | device_remove_bin_file(dev, &bin_attr_mem); | ||
2698 | } | ||
2699 | |||
2369 | #ifdef CONFIG_INET | 2700 | #ifdef CONFIG_INET |
2370 | 2701 | ||
2371 | #define is_netxen_netdev(dev) (dev->netdev_ops == &netxen_netdev_ops) | 2702 | #define is_netxen_netdev(dev) (dev->netdev_ops == &netxen_netdev_ops) |
@@ -2504,6 +2835,12 @@ netxen_config_indev_addr(struct net_device *dev, unsigned long event) | |||
2504 | { } | 2835 | { } |
2505 | #endif | 2836 | #endif |
2506 | 2837 | ||
2838 | static struct pci_error_handlers netxen_err_handler = { | ||
2839 | .error_detected = netxen_io_error_detected, | ||
2840 | .slot_reset = netxen_io_slot_reset, | ||
2841 | .resume = netxen_io_resume, | ||
2842 | }; | ||
2843 | |||
2507 | static struct pci_driver netxen_driver = { | 2844 | static struct pci_driver netxen_driver = { |
2508 | .name = netxen_nic_driver_name, | 2845 | .name = netxen_nic_driver_name, |
2509 | .id_table = netxen_pci_tbl, | 2846 | .id_table = netxen_pci_tbl, |
@@ -2513,7 +2850,8 @@ static struct pci_driver netxen_driver = { | |||
2513 | .suspend = netxen_nic_suspend, | 2850 | .suspend = netxen_nic_suspend, |
2514 | .resume = netxen_nic_resume, | 2851 | .resume = netxen_nic_resume, |
2515 | #endif | 2852 | #endif |
2516 | .shutdown = netxen_nic_shutdown | 2853 | .shutdown = netxen_nic_shutdown, |
2854 | .err_handler = &netxen_err_handler | ||
2517 | }; | 2855 | }; |
2518 | 2856 | ||
2519 | static int __init netxen_init_module(void) | 2857 | static int __init netxen_init_module(void) |
@@ -2524,7 +2862,6 @@ static int __init netxen_init_module(void) | |||
2524 | register_netdevice_notifier(&netxen_netdev_cb); | 2862 | register_netdevice_notifier(&netxen_netdev_cb); |
2525 | register_inetaddr_notifier(&netxen_inetaddr_cb); | 2863 | register_inetaddr_notifier(&netxen_inetaddr_cb); |
2526 | #endif | 2864 | #endif |
2527 | |||
2528 | return pci_register_driver(&netxen_driver); | 2865 | return pci_register_driver(&netxen_driver); |
2529 | } | 2866 | } |
2530 | 2867 | ||