diff options
author | Benjamin Herrenschmidt <benh@kernel.crashing.org> | 2009-12-09 01:14:38 -0500 |
---|---|---|
committer | Benjamin Herrenschmidt <benh@kernel.crashing.org> | 2009-12-09 01:14:38 -0500 |
commit | bcd6acd51f3d4d1ada201e9bc5c40a31d6d80c71 (patch) | |
tree | 2f6dffd2d3e4dd67355a224de7e7a960335a92fd /drivers/net/netxen | |
parent | 11c34c7deaeeebcee342cbc35e1bb2a6711b2431 (diff) | |
parent | 3ff6a468b45b5dfeb0e903e56f4eb27d34b2437c (diff) |
Merge commit 'origin/master' into next
Conflicts:
include/linux/kvm.h
Diffstat (limited to 'drivers/net/netxen')
-rw-r--r-- | drivers/net/netxen/netxen_nic.h | 80 | ||||
-rw-r--r-- | drivers/net/netxen/netxen_nic_ethtool.c | 38 | ||||
-rw-r--r-- | drivers/net/netxen/netxen_nic_hdr.h | 78 | ||||
-rw-r--r-- | drivers/net/netxen/netxen_nic_hw.c | 1050 | ||||
-rw-r--r-- | drivers/net/netxen/netxen_nic_init.c | 363 | ||||
-rw-r--r-- | drivers/net/netxen/netxen_nic_main.c | 338 |
6 files changed, 1178 insertions, 769 deletions
diff --git a/drivers/net/netxen/netxen_nic.h b/drivers/net/netxen/netxen_nic.h index 7384f59df615..76cd1f3e9fc8 100644 --- a/drivers/net/netxen/netxen_nic.h +++ b/drivers/net/netxen/netxen_nic.h | |||
@@ -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 65 |
57 | #define NETXEN_NIC_LINUX_VERSIONID "4.0.50" | 57 | #define NETXEN_NIC_LINUX_VERSIONID "4.0.65" |
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 0x3eb000 | ||
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; |
@@ -1163,6 +1202,8 @@ struct netxen_adapter { | |||
1163 | u32 int_vec_bit; | 1202 | u32 int_vec_bit; |
1164 | u32 heartbit; | 1203 | u32 heartbit; |
1165 | 1204 | ||
1205 | u8 mac_addr[ETH_ALEN]; | ||
1206 | |||
1166 | struct netxen_adapter_stats stats; | 1207 | struct netxen_adapter_stats stats; |
1167 | 1208 | ||
1168 | struct netxen_recv_context recv_ctx; | 1209 | struct netxen_recv_context recv_ctx; |
@@ -1180,11 +1221,10 @@ struct netxen_adapter { | |||
1180 | u32 (*crb_read)(struct netxen_adapter *, ulong); | 1221 | u32 (*crb_read)(struct netxen_adapter *, ulong); |
1181 | int (*crb_write)(struct netxen_adapter *, ulong, u32); | 1222 | int (*crb_write)(struct netxen_adapter *, ulong, u32); |
1182 | 1223 | ||
1183 | int (*pci_mem_read)(struct netxen_adapter *, u64, void *, int); | 1224 | int (*pci_mem_read)(struct netxen_adapter *, u64, u64 *); |
1184 | int (*pci_mem_write)(struct netxen_adapter *, u64, void *, int); | 1225 | int (*pci_mem_write)(struct netxen_adapter *, u64, u64); |
1185 | 1226 | ||
1186 | unsigned long (*pci_set_window)(struct netxen_adapter *, | 1227 | int (*pci_set_window)(struct netxen_adapter *, u64, u32 *); |
1187 | unsigned long long); | ||
1188 | 1228 | ||
1189 | u32 (*io_read)(struct netxen_adapter *, void __iomem *); | 1229 | u32 (*io_read)(struct netxen_adapter *, void __iomem *); |
1190 | void (*io_write)(struct netxen_adapter *, void __iomem *, u32); | 1230 | void (*io_write)(struct netxen_adapter *, void __iomem *, u32); |
@@ -1203,12 +1243,10 @@ struct netxen_adapter { | |||
1203 | 1243 | ||
1204 | struct work_struct tx_timeout_task; | 1244 | struct work_struct tx_timeout_task; |
1205 | 1245 | ||
1206 | struct net_device_stats net_stats; | ||
1207 | |||
1208 | nx_nic_intr_coalesce_t coal; | 1246 | nx_nic_intr_coalesce_t coal; |
1209 | 1247 | ||
1210 | unsigned long state; | 1248 | unsigned long state; |
1211 | u32 resv5; | 1249 | __le32 file_prd_off; /*File fw product offset*/ |
1212 | u32 fw_version; | 1250 | u32 fw_version; |
1213 | const struct firmware *fw; | 1251 | const struct firmware *fw; |
1214 | }; | 1252 | }; |
@@ -1271,7 +1309,7 @@ int netxen_load_firmware(struct netxen_adapter *adapter); | |||
1271 | int netxen_need_fw_reset(struct netxen_adapter *adapter); | 1309 | int netxen_need_fw_reset(struct netxen_adapter *adapter); |
1272 | void netxen_request_firmware(struct netxen_adapter *adapter); | 1310 | void netxen_request_firmware(struct netxen_adapter *adapter); |
1273 | void netxen_release_firmware(struct netxen_adapter *adapter); | 1311 | void netxen_release_firmware(struct netxen_adapter *adapter); |
1274 | int netxen_pinit_from_rom(struct netxen_adapter *adapter, int verbose); | 1312 | int netxen_pinit_from_rom(struct netxen_adapter *adapter); |
1275 | 1313 | ||
1276 | 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); |
1277 | 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, |
diff --git a/drivers/net/netxen/netxen_nic_ethtool.c b/drivers/net/netxen/netxen_nic_ethtool.c index 714f38791a9a..ddd704ae0188 100644 --- a/drivers/net/netxen/netxen_nic_ethtool.c +++ b/drivers/net/netxen/netxen_nic_ethtool.c | |||
@@ -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; |
@@ -444,10 +442,10 @@ static u32 netxen_nic_test_link(struct net_device *dev) | |||
444 | 442 | ||
445 | /* read which mode */ | 443 | /* read which mode */ |
446 | if (adapter->ahw.port_type == NETXEN_NIC_GBE) { | 444 | if (adapter->ahw.port_type == NETXEN_NIC_GBE) { |
447 | if (adapter->phy_read | 445 | if (adapter->phy_read && |
448 | && adapter->phy_read(adapter, | 446 | adapter->phy_read(adapter, |
449 | NETXEN_NIU_GB_MII_MGMT_ADDR_PHY_STATUS, | 447 | NETXEN_NIU_GB_MII_MGMT_ADDR_PHY_STATUS, |
450 | &status) != 0) | 448 | &status) != 0) |
451 | return -EIO; | 449 | return -EIO; |
452 | else { | 450 | else { |
453 | val = netxen_get_phy_link(status); | 451 | val = netxen_get_phy_link(status); |
@@ -690,8 +688,8 @@ static int netxen_nic_reg_test(struct net_device *dev) | |||
690 | u32 data_read, data_written; | 688 | u32 data_read, data_written; |
691 | 689 | ||
692 | data_read = NXRD32(adapter, NETXEN_PCIX_PH_REG(0)); | 690 | data_read = NXRD32(adapter, NETXEN_PCIX_PH_REG(0)); |
693 | if ((data_read & 0xffff) != PHAN_VENDOR_ID) | 691 | if ((data_read & 0xffff) != adapter->pdev->vendor) |
694 | return 1; | 692 | return 1; |
695 | 693 | ||
696 | data_written = (u32)0xa5a5a5a5; | 694 | data_written = (u32)0xa5a5a5a5; |
697 | 695 | ||
diff --git a/drivers/net/netxen/netxen_nic_hdr.h b/drivers/net/netxen/netxen_nic_hdr.h index 1c46da632125..d138fc22927a 100644 --- a/drivers/net/netxen/netxen_nic_hdr.h +++ b/drivers/net/netxen/netxen_nic_hdr.h | |||
@@ -545,6 +545,8 @@ enum { | |||
545 | #define NETXEN_NIU_TEST_MUX_CTL (NETXEN_CRB_NIU + 0x00094) | 545 | #define NETXEN_NIU_TEST_MUX_CTL (NETXEN_CRB_NIU + 0x00094) |
546 | #define NETXEN_NIU_XG_PAUSE_CTL (NETXEN_CRB_NIU + 0x00098) | 546 | #define NETXEN_NIU_XG_PAUSE_CTL (NETXEN_CRB_NIU + 0x00098) |
547 | #define NETXEN_NIU_XG_PAUSE_LEVEL (NETXEN_CRB_NIU + 0x000dc) | 547 | #define NETXEN_NIU_XG_PAUSE_LEVEL (NETXEN_CRB_NIU + 0x000dc) |
548 | #define NETXEN_NIU_FRAME_COUNT_SELECT (NETXEN_CRB_NIU + 0x000ac) | ||
549 | #define NETXEN_NIU_FRAME_COUNT (NETXEN_CRB_NIU + 0x000b0) | ||
548 | #define NETXEN_NIU_XG_SEL (NETXEN_CRB_NIU + 0x00128) | 550 | #define NETXEN_NIU_XG_SEL (NETXEN_CRB_NIU + 0x00128) |
549 | #define NETXEN_NIU_GB_PAUSE_CTL (NETXEN_CRB_NIU + 0x0030c) | 551 | #define NETXEN_NIU_GB_PAUSE_CTL (NETXEN_CRB_NIU + 0x0030c) |
550 | 552 | ||
@@ -662,40 +664,51 @@ enum { | |||
662 | #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) |
663 | #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) |
664 | 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 | |||
665 | /* | 675 | /* |
666 | * Register offsets for MN | 676 | * Register offsets for MN |
667 | */ | 677 | */ |
668 | #define MIU_CONTROL (0x000) | 678 | #define MIU_TEST_AGT_BASE (0x90) |
669 | #define MIU_TEST_AGT_CTRL (0x090) | 679 | |
670 | #define MIU_TEST_AGT_ADDR_LO (0x094) | 680 | #define MIU_TEST_AGT_ADDR_LO (0x04) |
671 | #define MIU_TEST_AGT_ADDR_HI (0x098) | 681 | #define MIU_TEST_AGT_ADDR_HI (0x08) |
672 | #define MIU_TEST_AGT_WRDATA_LO (0x0a0) | 682 | #define MIU_TEST_AGT_WRDATA_LO (0x10) |
673 | #define MIU_TEST_AGT_WRDATA_HI (0x0a4) | 683 | #define MIU_TEST_AGT_WRDATA_HI (0x14) |
674 | #define MIU_TEST_AGT_WRDATA(i) (0x0a0+(4*(i))) | 684 | #define MIU_TEST_AGT_WRDATA_UPPER_LO (0x20) |
675 | #define MIU_TEST_AGT_RDDATA_LO (0x0a8) | 685 | #define MIU_TEST_AGT_WRDATA_UPPER_HI (0x24) |
676 | #define MIU_TEST_AGT_RDDATA_HI (0x0ac) | 686 | #define MIU_TEST_AGT_WRDATA(i) (0x10+(0x10*((i)>>1))+(4*((i)&1))) |
677 | #define MIU_TEST_AGT_RDDATA(i) (0x0a8+(4*(i))) | 687 | #define MIU_TEST_AGT_RDDATA_LO (0x18) |
678 | #define MIU_TEST_AGT_ADDR_MASK 0xfffffff8 | 688 | #define MIU_TEST_AGT_RDDATA_HI (0x1c) |
679 | #define MIU_TEST_AGT_UPPER_ADDR(off) (0) | 689 | #define MIU_TEST_AGT_RDDATA_UPPER_LO (0x28) |
680 | 690 | #define MIU_TEST_AGT_RDDATA_UPPER_HI (0x2c) | |
681 | /* MIU_TEST_AGT_CTRL flags. work for SIU as well */ | 691 | #define MIU_TEST_AGT_RDDATA(i) (0x18+(0x10*((i)>>1))+(4*((i)&1))) |
682 | #define MIU_TA_CTL_START 1 | 692 | |
683 | #define MIU_TA_CTL_ENABLE 2 | 693 | #define MIU_TEST_AGT_ADDR_MASK 0xfffffff8 |
684 | #define MIU_TA_CTL_WRITE 4 | 694 | #define MIU_TEST_AGT_UPPER_ADDR(off) (0) |
685 | #define MIU_TA_CTL_BUSY 8 | 695 | |
686 | 696 | /* | |
687 | #define SIU_TEST_AGT_CTRL (0x060) | 697 | * Register offsets for MS |
688 | #define SIU_TEST_AGT_ADDR_LO (0x064) | 698 | */ |
689 | #define SIU_TEST_AGT_ADDR_HI (0x078) | 699 | #define SIU_TEST_AGT_BASE (0x60) |
690 | #define SIU_TEST_AGT_WRDATA_LO (0x068) | 700 | |
691 | #define SIU_TEST_AGT_WRDATA_HI (0x06c) | 701 | #define SIU_TEST_AGT_ADDR_LO (0x04) |
692 | #define SIU_TEST_AGT_WRDATA(i) (0x068+(4*(i))) | 702 | #define SIU_TEST_AGT_ADDR_HI (0x18) |
693 | #define SIU_TEST_AGT_RDDATA_LO (0x070) | 703 | #define SIU_TEST_AGT_WRDATA_LO (0x08) |
694 | #define SIU_TEST_AGT_RDDATA_HI (0x074) | 704 | #define SIU_TEST_AGT_WRDATA_HI (0x0c) |
695 | #define SIU_TEST_AGT_RDDATA(i) (0x070+(4*(i))) | 705 | #define SIU_TEST_AGT_WRDATA(i) (0x08+(4*(i))) |
696 | 706 | #define SIU_TEST_AGT_RDDATA_LO (0x10) | |
697 | #define SIU_TEST_AGT_ADDR_MASK 0x3ffff8 | 707 | #define SIU_TEST_AGT_RDDATA_HI (0x14) |
698 | #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) | ||
699 | 712 | ||
700 | /* XG Link status */ | 713 | /* XG Link status */ |
701 | #define XG_LINK_UP 0x10 | 714 | #define XG_LINK_UP 0x10 |
@@ -857,6 +870,9 @@ enum { | |||
857 | (PCIX_SN_WINDOW_F0 + (0x20 * (func))) :\ | 870 | (PCIX_SN_WINDOW_F0 + (0x20 * (func))) :\ |
858 | (PCIX_SN_WINDOW_F4 + (0x10 * ((func)-4)))) | 871 | (PCIX_SN_WINDOW_F4 + (0x10 * ((func)-4)))) |
859 | 872 | ||
873 | #define PCIX_OCM_WINDOW (0x10800) | ||
874 | #define PCIX_OCM_WINDOW_REG(func) (PCIX_OCM_WINDOW + 0x20 * (func)) | ||
875 | |||
860 | #define PCIX_TARGET_STATUS (0x10118) | 876 | #define PCIX_TARGET_STATUS (0x10118) |
861 | #define PCIX_TARGET_STATUS_F1 (0x10160) | 877 | #define PCIX_TARGET_STATUS_F1 (0x10160) |
862 | #define PCIX_TARGET_STATUS_F2 (0x10164) | 878 | #define PCIX_TARGET_STATUS_F2 (0x10164) |
diff --git a/drivers/net/netxen/netxen_nic_hw.c b/drivers/net/netxen/netxen_nic_hw.c index 3185a98b0917..2e364fee3cbb 100644 --- a/drivers/net/netxen/netxen_nic_hw.c +++ b/drivers/net/netxen/netxen_nic_hw.c | |||
@@ -31,6 +31,7 @@ | |||
31 | #define MASK(n) ((1ULL<<(n))-1) | 31 | #define MASK(n) ((1ULL<<(n))-1) |
32 | #define MN_WIN(addr) (((addr & 0x1fc0000) >> 1) | ((addr >> 25) & 0x3ff)) | 32 | #define MN_WIN(addr) (((addr & 0x1fc0000) >> 1) | ((addr >> 25) & 0x3ff)) |
33 | #define OCM_WIN(addr) (((addr & 0x1ff0000) >> 1) | ((addr >> 25) & 0x3ff)) | 33 | #define OCM_WIN(addr) (((addr & 0x1ff0000) >> 1) | ((addr >> 25) & 0x3ff)) |
34 | #define OCM_WIN_P3P(addr) (addr & 0xffc0000) | ||
34 | #define MS_WIN(addr) (addr & 0x0ffc0000) | 35 | #define MS_WIN(addr) (addr & 0x0ffc0000) |
35 | 36 | ||
36 | #define GET_MEM_OFFS_2M(addr) (addr & MASK(18)) | 37 | #define GET_MEM_OFFS_2M(addr) (addr & MASK(18)) |
@@ -41,6 +42,11 @@ | |||
41 | #define CRB_HI(off) ((crb_hub_agt[CRB_BLK(off)] << 20) | ((off) & 0xf0000)) | 42 | #define CRB_HI(off) ((crb_hub_agt[CRB_BLK(off)] << 20) | ((off) & 0xf0000)) |
42 | #define CRB_INDIRECT_2M (0x1e0000UL) | 43 | #define CRB_INDIRECT_2M (0x1e0000UL) |
43 | 44 | ||
45 | static void netxen_nic_io_write_128M(struct netxen_adapter *adapter, | ||
46 | void __iomem *addr, u32 data); | ||
47 | static u32 netxen_nic_io_read_128M(struct netxen_adapter *adapter, | ||
48 | void __iomem *addr); | ||
49 | |||
44 | #ifndef readq | 50 | #ifndef readq |
45 | static inline u64 readq(void __iomem *addr) | 51 | static inline u64 readq(void __iomem *addr) |
46 | { | 52 | { |
@@ -326,7 +332,7 @@ netxen_pcie_sem_lock(struct netxen_adapter *adapter, int sem, u32 id_reg) | |||
326 | if (done == 1) | 332 | if (done == 1) |
327 | break; | 333 | break; |
328 | if (++timeout >= NETXEN_PCIE_SEM_TIMEOUT) | 334 | if (++timeout >= NETXEN_PCIE_SEM_TIMEOUT) |
329 | return -1; | 335 | return -EIO; |
330 | msleep(1); | 336 | msleep(1); |
331 | } | 337 | } |
332 | 338 | ||
@@ -383,24 +389,51 @@ int netxen_niu_disable_xg_port(struct netxen_adapter *adapter) | |||
383 | 389 | ||
384 | int netxen_p2_nic_set_promisc(struct netxen_adapter *adapter, u32 mode) | 390 | int netxen_p2_nic_set_promisc(struct netxen_adapter *adapter, u32 mode) |
385 | { | 391 | { |
386 | __u32 reg; | 392 | u32 mac_cfg; |
393 | u32 cnt = 0; | ||
394 | __u32 reg = 0x0200; | ||
387 | u32 port = adapter->physical_port; | 395 | u32 port = adapter->physical_port; |
396 | u16 board_type = adapter->ahw.board_type; | ||
388 | 397 | ||
389 | if (port > NETXEN_NIU_MAX_XG_PORTS) | 398 | if (port > NETXEN_NIU_MAX_XG_PORTS) |
390 | return -EINVAL; | 399 | return -EINVAL; |
391 | 400 | ||
392 | reg = NXRD32(adapter, NETXEN_NIU_XGE_CONFIG_1 + (0x10000 * port)); | 401 | mac_cfg = NXRD32(adapter, NETXEN_NIU_XGE_CONFIG_0 + (0x10000 * port)); |
393 | if (mode == NETXEN_NIU_PROMISC_MODE) | 402 | mac_cfg &= ~0x4; |
394 | reg = (reg | 0x2000UL); | 403 | NXWR32(adapter, NETXEN_NIU_XGE_CONFIG_0 + (0x10000 * port), mac_cfg); |
395 | else | ||
396 | reg = (reg & ~0x2000UL); | ||
397 | 404 | ||
398 | if (mode == NETXEN_NIU_ALLMULTI_MODE) | 405 | if ((board_type == NETXEN_BRDTYPE_P2_SB31_10G_IMEZ) || |
399 | reg = (reg | 0x1000UL); | 406 | (board_type == NETXEN_BRDTYPE_P2_SB31_10G_HMEZ)) |
400 | else | 407 | reg = (0x20 << port); |
401 | reg = (reg & ~0x1000UL); | 408 | |
409 | NXWR32(adapter, NETXEN_NIU_FRAME_COUNT_SELECT, reg); | ||
410 | |||
411 | mdelay(10); | ||
412 | |||
413 | while (NXRD32(adapter, NETXEN_NIU_FRAME_COUNT) && ++cnt < 20) | ||
414 | mdelay(10); | ||
415 | |||
416 | if (cnt < 20) { | ||
417 | |||
418 | reg = NXRD32(adapter, | ||
419 | NETXEN_NIU_XGE_CONFIG_1 + (0x10000 * port)); | ||
420 | |||
421 | if (mode == NETXEN_NIU_PROMISC_MODE) | ||
422 | reg = (reg | 0x2000UL); | ||
423 | else | ||
424 | reg = (reg & ~0x2000UL); | ||
425 | |||
426 | if (mode == NETXEN_NIU_ALLMULTI_MODE) | ||
427 | reg = (reg | 0x1000UL); | ||
428 | else | ||
429 | reg = (reg & ~0x1000UL); | ||
430 | |||
431 | NXWR32(adapter, | ||
432 | NETXEN_NIU_XGE_CONFIG_1 + (0x10000 * port), reg); | ||
433 | } | ||
402 | 434 | ||
403 | NXWR32(adapter, NETXEN_NIU_XGE_CONFIG_1 + (0x10000 * port), reg); | 435 | mac_cfg |= 0x4; |
436 | NXWR32(adapter, NETXEN_NIU_XGE_CONFIG_0 + (0x10000 * port), mac_cfg); | ||
404 | 437 | ||
405 | return 0; | 438 | return 0; |
406 | } | 439 | } |
@@ -436,7 +469,7 @@ netxen_nic_enable_mcast_filter(struct netxen_adapter *adapter) | |||
436 | { | 469 | { |
437 | u32 val = 0; | 470 | u32 val = 0; |
438 | u16 port = adapter->physical_port; | 471 | u16 port = adapter->physical_port; |
439 | u8 *addr = adapter->netdev->dev_addr; | 472 | u8 *addr = adapter->mac_addr; |
440 | 473 | ||
441 | if (adapter->mc_enabled) | 474 | if (adapter->mc_enabled) |
442 | return 0; | 475 | return 0; |
@@ -465,7 +498,7 @@ netxen_nic_disable_mcast_filter(struct netxen_adapter *adapter) | |||
465 | { | 498 | { |
466 | u32 val = 0; | 499 | u32 val = 0; |
467 | u16 port = adapter->physical_port; | 500 | u16 port = adapter->physical_port; |
468 | u8 *addr = adapter->netdev->dev_addr; | 501 | u8 *addr = adapter->mac_addr; |
469 | 502 | ||
470 | if (!adapter->mc_enabled) | 503 | if (!adapter->mc_enabled) |
471 | return 0; | 504 | return 0; |
@@ -660,7 +693,7 @@ void netxen_p3_nic_set_multi(struct net_device *netdev) | |||
660 | 693 | ||
661 | list_splice_tail_init(&adapter->mac_list, &del_list); | 694 | list_splice_tail_init(&adapter->mac_list, &del_list); |
662 | 695 | ||
663 | nx_p3_nic_add_mac(adapter, netdev->dev_addr, &del_list); | 696 | nx_p3_nic_add_mac(adapter, adapter->mac_addr, &del_list); |
664 | nx_p3_nic_add_mac(adapter, bcast_addr, &del_list); | 697 | nx_p3_nic_add_mac(adapter, bcast_addr, &del_list); |
665 | 698 | ||
666 | if (netdev->flags & IFF_PROMISC) { | 699 | if (netdev->flags & IFF_PROMISC) { |
@@ -1046,89 +1079,71 @@ int netxen_p3_get_mac_addr(struct netxen_adapter *adapter, __le64 *mac) | |||
1046 | * Changes the CRB window to the specified window. | 1079 | * Changes the CRB window to the specified window. |
1047 | */ | 1080 | */ |
1048 | static void | 1081 | static void |
1049 | netxen_nic_pci_change_crbwindow_128M(struct netxen_adapter *adapter, u32 wndw) | 1082 | netxen_nic_pci_set_crbwindow_128M(struct netxen_adapter *adapter, |
1083 | u32 window) | ||
1050 | { | 1084 | { |
1051 | void __iomem *offset; | 1085 | void __iomem *offset; |
1052 | u32 tmp; | 1086 | int count = 10; |
1053 | int count = 0; | 1087 | u8 func = adapter->ahw.pci_func; |
1054 | uint8_t func = adapter->ahw.pci_func; | ||
1055 | 1088 | ||
1056 | if (adapter->curr_window == wndw) | 1089 | if (adapter->ahw.crb_win == window) |
1057 | return; | 1090 | return; |
1058 | /* | 1091 | |
1059 | * Move the CRB window. | ||
1060 | * We need to write to the "direct access" region of PCI | ||
1061 | * to avoid a race condition where the window register has | ||
1062 | * not been successfully written across CRB before the target | ||
1063 | * register address is received by PCI. The direct region bypasses | ||
1064 | * the CRB bus. | ||
1065 | */ | ||
1066 | offset = PCI_OFFSET_SECOND_RANGE(adapter, | 1092 | offset = PCI_OFFSET_SECOND_RANGE(adapter, |
1067 | NETXEN_PCIX_PH_REG(PCIE_CRB_WINDOW_REG(func))); | 1093 | NETXEN_PCIX_PH_REG(PCIE_CRB_WINDOW_REG(func))); |
1068 | 1094 | ||
1069 | if (wndw & 0x1) | 1095 | writel(window, offset); |
1070 | wndw = NETXEN_WINDOW_ONE; | 1096 | do { |
1097 | if (window == readl(offset)) | ||
1098 | break; | ||
1071 | 1099 | ||
1072 | writel(wndw, offset); | 1100 | if (printk_ratelimit()) |
1101 | dev_warn(&adapter->pdev->dev, | ||
1102 | "failed to set CRB window to %d\n", | ||
1103 | (window == NETXEN_WINDOW_ONE)); | ||
1104 | udelay(1); | ||
1073 | 1105 | ||
1074 | /* MUST make sure window is set before we forge on... */ | 1106 | } while (--count > 0); |
1075 | while ((tmp = readl(offset)) != wndw) { | ||
1076 | printk(KERN_WARNING "%s: %s WARNING: CRB window value not " | ||
1077 | "registered properly: 0x%08x.\n", | ||
1078 | netxen_nic_driver_name, __func__, tmp); | ||
1079 | mdelay(1); | ||
1080 | if (count >= 10) | ||
1081 | break; | ||
1082 | count++; | ||
1083 | } | ||
1084 | 1107 | ||
1085 | if (wndw == NETXEN_WINDOW_ONE) | 1108 | if (count > 0) |
1086 | adapter->curr_window = 1; | 1109 | adapter->ahw.crb_win = window; |
1087 | else | ||
1088 | adapter->curr_window = 0; | ||
1089 | } | 1110 | } |
1090 | 1111 | ||
1091 | /* | 1112 | /* |
1092 | * Return -1 if off is not valid, | 1113 | * Returns < 0 if off is not valid, |
1093 | * 1 if window access is needed. 'off' is set to offset from | 1114 | * 1 if window access is needed. 'off' is set to offset from |
1094 | * CRB space in 128M pci map | 1115 | * CRB space in 128M pci map |
1095 | * 0 if no window access is needed. 'off' is set to 2M addr | 1116 | * 0 if no window access is needed. 'off' is set to 2M addr |
1096 | * In: 'off' is offset from base in 128M pci map | 1117 | * In: 'off' is offset from base in 128M pci map |
1097 | */ | 1118 | */ |
1098 | static int | 1119 | static int |
1099 | netxen_nic_pci_get_crb_addr_2M(struct netxen_adapter *adapter, ulong *off) | 1120 | netxen_nic_pci_get_crb_addr_2M(struct netxen_adapter *adapter, |
1121 | ulong off, void __iomem **addr) | ||
1100 | { | 1122 | { |
1101 | crb_128M_2M_sub_block_map_t *m; | 1123 | crb_128M_2M_sub_block_map_t *m; |
1102 | 1124 | ||
1103 | 1125 | ||
1104 | if (*off >= NETXEN_CRB_MAX) | 1126 | if ((off >= NETXEN_CRB_MAX) || (off < NETXEN_PCI_CRBSPACE)) |
1105 | return -1; | 1127 | return -EINVAL; |
1106 | |||
1107 | if (*off >= NETXEN_PCI_CAMQM && (*off < NETXEN_PCI_CAMQM_2M_END)) { | ||
1108 | *off = (*off - NETXEN_PCI_CAMQM) + NETXEN_PCI_CAMQM_2M_BASE + | ||
1109 | (ulong)adapter->ahw.pci_base0; | ||
1110 | return 0; | ||
1111 | } | ||
1112 | |||
1113 | if (*off < NETXEN_PCI_CRBSPACE) | ||
1114 | return -1; | ||
1115 | 1128 | ||
1116 | *off -= NETXEN_PCI_CRBSPACE; | 1129 | off -= NETXEN_PCI_CRBSPACE; |
1117 | 1130 | ||
1118 | /* | 1131 | /* |
1119 | * Try direct map | 1132 | * Try direct map |
1120 | */ | 1133 | */ |
1121 | m = &crb_128M_2M_map[CRB_BLK(*off)].sub_block[CRB_SUBBLK(*off)]; | 1134 | m = &crb_128M_2M_map[CRB_BLK(off)].sub_block[CRB_SUBBLK(off)]; |
1122 | 1135 | ||
1123 | if (m->valid && (m->start_128M <= *off) && (m->end_128M > *off)) { | 1136 | if (m->valid && (m->start_128M <= off) && (m->end_128M > off)) { |
1124 | *off = *off + m->start_2M - m->start_128M + | 1137 | *addr = adapter->ahw.pci_base0 + m->start_2M + |
1125 | (ulong)adapter->ahw.pci_base0; | 1138 | (off - m->start_128M); |
1126 | return 0; | 1139 | return 0; |
1127 | } | 1140 | } |
1128 | 1141 | ||
1129 | /* | 1142 | /* |
1130 | * Not in direct map, use crb window | 1143 | * Not in direct map, use crb window |
1131 | */ | 1144 | */ |
1145 | *addr = adapter->ahw.pci_base0 + CRB_INDIRECT_2M + | ||
1146 | (off & MASK(16)); | ||
1132 | return 1; | 1147 | return 1; |
1133 | } | 1148 | } |
1134 | 1149 | ||
@@ -1138,52 +1153,78 @@ netxen_nic_pci_get_crb_addr_2M(struct netxen_adapter *adapter, ulong *off) | |||
1138 | * side effect: lock crb window | 1153 | * side effect: lock crb window |
1139 | */ | 1154 | */ |
1140 | static void | 1155 | static void |
1141 | netxen_nic_pci_set_crbwindow_2M(struct netxen_adapter *adapter, ulong *off) | 1156 | netxen_nic_pci_set_crbwindow_2M(struct netxen_adapter *adapter, ulong off) |
1142 | { | 1157 | { |
1143 | u32 win_read; | 1158 | u32 window; |
1159 | void __iomem *addr = adapter->ahw.pci_base0 + CRB_WINDOW_2M; | ||
1144 | 1160 | ||
1145 | adapter->crb_win = CRB_HI(*off); | 1161 | off -= NETXEN_PCI_CRBSPACE; |
1146 | writel(adapter->crb_win, (adapter->ahw.pci_base0 + CRB_WINDOW_2M)); | 1162 | |
1147 | /* | 1163 | window = CRB_HI(off); |
1148 | * Read back value to make sure write has gone through before trying | 1164 | |
1149 | * to use it. | 1165 | if (adapter->ahw.crb_win == window) |
1150 | */ | 1166 | return; |
1151 | win_read = readl(adapter->ahw.pci_base0 + CRB_WINDOW_2M); | 1167 | |
1152 | if (win_read != adapter->crb_win) { | 1168 | writel(window, addr); |
1153 | printk(KERN_ERR "%s: Written crbwin (0x%x) != " | 1169 | if (readl(addr) != window) { |
1154 | "Read crbwin (0x%x), off=0x%lx\n", | 1170 | if (printk_ratelimit()) |
1155 | __func__, adapter->crb_win, win_read, *off); | 1171 | dev_warn(&adapter->pdev->dev, |
1172 | "failed to set CRB window to %d off 0x%lx\n", | ||
1173 | window, off); | ||
1156 | } | 1174 | } |
1157 | *off = (*off & MASK(16)) + CRB_INDIRECT_2M + | 1175 | adapter->ahw.crb_win = window; |
1158 | (ulong)adapter->ahw.pci_base0; | 1176 | } |
1177 | |||
1178 | static void __iomem * | ||
1179 | netxen_nic_map_indirect_address_128M(struct netxen_adapter *adapter, | ||
1180 | ulong win_off, void __iomem **mem_ptr) | ||
1181 | { | ||
1182 | ulong off = win_off; | ||
1183 | void __iomem *addr; | ||
1184 | resource_size_t mem_base; | ||
1185 | |||
1186 | if (ADDR_IN_WINDOW1(win_off)) | ||
1187 | off = NETXEN_CRB_NORMAL(win_off); | ||
1188 | |||
1189 | addr = pci_base_offset(adapter, off); | ||
1190 | if (addr) | ||
1191 | return addr; | ||
1192 | |||
1193 | if (adapter->ahw.pci_len0 == 0) | ||
1194 | off -= NETXEN_PCI_CRBSPACE; | ||
1195 | |||
1196 | mem_base = pci_resource_start(adapter->pdev, 0); | ||
1197 | *mem_ptr = ioremap(mem_base + (off & PAGE_MASK), PAGE_SIZE); | ||
1198 | if (*mem_ptr) | ||
1199 | addr = *mem_ptr + (off & (PAGE_SIZE - 1)); | ||
1200 | |||
1201 | return addr; | ||
1159 | } | 1202 | } |
1160 | 1203 | ||
1161 | static int | 1204 | static int |
1162 | netxen_nic_hw_write_wx_128M(struct netxen_adapter *adapter, ulong off, u32 data) | 1205 | netxen_nic_hw_write_wx_128M(struct netxen_adapter *adapter, ulong off, u32 data) |
1163 | { | 1206 | { |
1164 | unsigned long flags; | 1207 | unsigned long flags; |
1165 | void __iomem *addr; | 1208 | void __iomem *addr, *mem_ptr = NULL; |
1166 | 1209 | ||
1167 | if (ADDR_IN_WINDOW1(off)) | 1210 | addr = netxen_nic_map_indirect_address_128M(adapter, off, &mem_ptr); |
1168 | addr = NETXEN_CRB_NORMALIZE(adapter, off); | 1211 | if (!addr) |
1169 | else | 1212 | return -EIO; |
1170 | addr = pci_base_offset(adapter, off); | ||
1171 | |||
1172 | BUG_ON(!addr); | ||
1173 | 1213 | ||
1174 | if (ADDR_IN_WINDOW1(off)) { /* Window 1 */ | 1214 | if (ADDR_IN_WINDOW1(off)) { /* Window 1 */ |
1175 | read_lock(&adapter->adapter_lock); | 1215 | netxen_nic_io_write_128M(adapter, addr, data); |
1176 | writel(data, addr); | 1216 | } else { /* Window 0 */ |
1177 | read_unlock(&adapter->adapter_lock); | 1217 | write_lock_irqsave(&adapter->ahw.crb_lock, flags); |
1178 | } else { /* Window 0 */ | 1218 | netxen_nic_pci_set_crbwindow_128M(adapter, 0); |
1179 | write_lock_irqsave(&adapter->adapter_lock, flags); | ||
1180 | addr = pci_base_offset(adapter, off); | ||
1181 | netxen_nic_pci_change_crbwindow_128M(adapter, 0); | ||
1182 | writel(data, addr); | 1219 | writel(data, addr); |
1183 | netxen_nic_pci_change_crbwindow_128M(adapter, 1); | 1220 | netxen_nic_pci_set_crbwindow_128M(adapter, |
1184 | write_unlock_irqrestore(&adapter->adapter_lock, flags); | 1221 | NETXEN_WINDOW_ONE); |
1222 | write_unlock_irqrestore(&adapter->ahw.crb_lock, flags); | ||
1185 | } | 1223 | } |
1186 | 1224 | ||
1225 | if (mem_ptr) | ||
1226 | iounmap(mem_ptr); | ||
1227 | |||
1187 | return 0; | 1228 | return 0; |
1188 | } | 1229 | } |
1189 | 1230 | ||
@@ -1191,28 +1232,27 @@ static u32 | |||
1191 | netxen_nic_hw_read_wx_128M(struct netxen_adapter *adapter, ulong off) | 1232 | netxen_nic_hw_read_wx_128M(struct netxen_adapter *adapter, ulong off) |
1192 | { | 1233 | { |
1193 | unsigned long flags; | 1234 | unsigned long flags; |
1194 | void __iomem *addr; | 1235 | void __iomem *addr, *mem_ptr = NULL; |
1195 | u32 data; | 1236 | u32 data; |
1196 | 1237 | ||
1197 | if (ADDR_IN_WINDOW1(off)) | 1238 | addr = netxen_nic_map_indirect_address_128M(adapter, off, &mem_ptr); |
1198 | addr = NETXEN_CRB_NORMALIZE(adapter, off); | 1239 | if (!addr) |
1199 | else | 1240 | return -EIO; |
1200 | addr = pci_base_offset(adapter, off); | ||
1201 | |||
1202 | BUG_ON(!addr); | ||
1203 | 1241 | ||
1204 | if (ADDR_IN_WINDOW1(off)) { /* Window 1 */ | 1242 | if (ADDR_IN_WINDOW1(off)) { /* Window 1 */ |
1205 | read_lock(&adapter->adapter_lock); | 1243 | data = netxen_nic_io_read_128M(adapter, addr); |
1206 | data = readl(addr); | 1244 | } else { /* Window 0 */ |
1207 | read_unlock(&adapter->adapter_lock); | 1245 | write_lock_irqsave(&adapter->ahw.crb_lock, flags); |
1208 | } else { /* Window 0 */ | 1246 | netxen_nic_pci_set_crbwindow_128M(adapter, 0); |
1209 | write_lock_irqsave(&adapter->adapter_lock, flags); | ||
1210 | netxen_nic_pci_change_crbwindow_128M(adapter, 0); | ||
1211 | data = readl(addr); | 1247 | data = readl(addr); |
1212 | netxen_nic_pci_change_crbwindow_128M(adapter, 1); | 1248 | netxen_nic_pci_set_crbwindow_128M(adapter, |
1213 | write_unlock_irqrestore(&adapter->adapter_lock, flags); | 1249 | NETXEN_WINDOW_ONE); |
1250 | write_unlock_irqrestore(&adapter->ahw.crb_lock, flags); | ||
1214 | } | 1251 | } |
1215 | 1252 | ||
1253 | if (mem_ptr) | ||
1254 | iounmap(mem_ptr); | ||
1255 | |||
1216 | return data; | 1256 | return data; |
1217 | } | 1257 | } |
1218 | 1258 | ||
@@ -1221,28 +1261,30 @@ netxen_nic_hw_write_wx_2M(struct netxen_adapter *adapter, ulong off, u32 data) | |||
1221 | { | 1261 | { |
1222 | unsigned long flags; | 1262 | unsigned long flags; |
1223 | int rv; | 1263 | int rv; |
1264 | void __iomem *addr = NULL; | ||
1224 | 1265 | ||
1225 | rv = netxen_nic_pci_get_crb_addr_2M(adapter, &off); | 1266 | rv = netxen_nic_pci_get_crb_addr_2M(adapter, off, &addr); |
1226 | 1267 | ||
1227 | if (rv == -1) { | 1268 | if (rv == 0) { |
1228 | printk(KERN_ERR "%s: invalid offset: 0x%016lx\n", | 1269 | writel(data, addr); |
1229 | __func__, off); | 1270 | return 0; |
1230 | dump_stack(); | ||
1231 | return -1; | ||
1232 | } | 1271 | } |
1233 | 1272 | ||
1234 | if (rv == 1) { | 1273 | if (rv > 0) { |
1235 | write_lock_irqsave(&adapter->adapter_lock, flags); | 1274 | /* indirect access */ |
1275 | write_lock_irqsave(&adapter->ahw.crb_lock, flags); | ||
1236 | crb_win_lock(adapter); | 1276 | crb_win_lock(adapter); |
1237 | netxen_nic_pci_set_crbwindow_2M(adapter, &off); | 1277 | netxen_nic_pci_set_crbwindow_2M(adapter, off); |
1238 | writel(data, (void __iomem *)off); | 1278 | writel(data, addr); |
1239 | crb_win_unlock(adapter); | 1279 | crb_win_unlock(adapter); |
1240 | write_unlock_irqrestore(&adapter->adapter_lock, flags); | 1280 | write_unlock_irqrestore(&adapter->ahw.crb_lock, flags); |
1241 | } else | 1281 | return 0; |
1242 | writel(data, (void __iomem *)off); | 1282 | } |
1243 | |||
1244 | 1283 | ||
1245 | return 0; | 1284 | dev_err(&adapter->pdev->dev, |
1285 | "%s: invalid offset: 0x%016lx\n", __func__, off); | ||
1286 | dump_stack(); | ||
1287 | return -EIO; | ||
1246 | } | 1288 | } |
1247 | 1289 | ||
1248 | static u32 | 1290 | static u32 |
@@ -1251,102 +1293,37 @@ netxen_nic_hw_read_wx_2M(struct netxen_adapter *adapter, ulong off) | |||
1251 | unsigned long flags; | 1293 | unsigned long flags; |
1252 | int rv; | 1294 | int rv; |
1253 | u32 data; | 1295 | u32 data; |
1296 | void __iomem *addr = NULL; | ||
1254 | 1297 | ||
1255 | rv = netxen_nic_pci_get_crb_addr_2M(adapter, &off); | 1298 | rv = netxen_nic_pci_get_crb_addr_2M(adapter, off, &addr); |
1256 | 1299 | ||
1257 | if (rv == -1) { | 1300 | if (rv == 0) |
1258 | printk(KERN_ERR "%s: invalid offset: 0x%016lx\n", | 1301 | return readl(addr); |
1259 | __func__, off); | ||
1260 | dump_stack(); | ||
1261 | return -1; | ||
1262 | } | ||
1263 | 1302 | ||
1264 | if (rv == 1) { | 1303 | if (rv > 0) { |
1265 | write_lock_irqsave(&adapter->adapter_lock, flags); | 1304 | /* indirect access */ |
1305 | write_lock_irqsave(&adapter->ahw.crb_lock, flags); | ||
1266 | crb_win_lock(adapter); | 1306 | crb_win_lock(adapter); |
1267 | netxen_nic_pci_set_crbwindow_2M(adapter, &off); | 1307 | netxen_nic_pci_set_crbwindow_2M(adapter, off); |
1268 | data = readl((void __iomem *)off); | 1308 | data = readl(addr); |
1269 | crb_win_unlock(adapter); | 1309 | crb_win_unlock(adapter); |
1270 | write_unlock_irqrestore(&adapter->adapter_lock, flags); | 1310 | write_unlock_irqrestore(&adapter->ahw.crb_lock, flags); |
1271 | } else | 1311 | return data; |
1272 | data = readl((void __iomem *)off); | ||
1273 | |||
1274 | return data; | ||
1275 | } | ||
1276 | |||
1277 | static int netxen_pci_set_window_warning_count; | ||
1278 | |||
1279 | static unsigned long | ||
1280 | netxen_nic_pci_set_window_128M(struct netxen_adapter *adapter, | ||
1281 | unsigned long long addr) | ||
1282 | { | ||
1283 | void __iomem *offset; | ||
1284 | int window; | ||
1285 | unsigned long long qdr_max; | ||
1286 | uint8_t func = adapter->ahw.pci_func; | ||
1287 | |||
1288 | if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) { | ||
1289 | qdr_max = NETXEN_ADDR_QDR_NET_MAX_P2; | ||
1290 | } else { | ||
1291 | qdr_max = NETXEN_ADDR_QDR_NET_MAX_P3; | ||
1292 | } | 1312 | } |
1293 | 1313 | ||
1294 | if (ADDR_IN_RANGE(addr, NETXEN_ADDR_DDR_NET, NETXEN_ADDR_DDR_NET_MAX)) { | 1314 | dev_err(&adapter->pdev->dev, |
1295 | /* DDR network side */ | 1315 | "%s: invalid offset: 0x%016lx\n", __func__, off); |
1296 | addr -= NETXEN_ADDR_DDR_NET; | 1316 | dump_stack(); |
1297 | window = (addr >> 25) & 0x3ff; | 1317 | return -1; |
1298 | if (adapter->ahw.ddr_mn_window != window) { | ||
1299 | adapter->ahw.ddr_mn_window = window; | ||
1300 | offset = PCI_OFFSET_SECOND_RANGE(adapter, | ||
1301 | NETXEN_PCIX_PH_REG(PCIE_MN_WINDOW_REG(func))); | ||
1302 | writel(window, offset); | ||
1303 | /* MUST make sure window is set before we forge on... */ | ||
1304 | readl(offset); | ||
1305 | } | ||
1306 | addr -= (window * NETXEN_WINDOW_ONE); | ||
1307 | addr += NETXEN_PCI_DDR_NET; | ||
1308 | } else if (ADDR_IN_RANGE(addr, NETXEN_ADDR_OCM0, NETXEN_ADDR_OCM0_MAX)) { | ||
1309 | addr -= NETXEN_ADDR_OCM0; | ||
1310 | addr += NETXEN_PCI_OCM0; | ||
1311 | } else if (ADDR_IN_RANGE(addr, NETXEN_ADDR_OCM1, NETXEN_ADDR_OCM1_MAX)) { | ||
1312 | addr -= NETXEN_ADDR_OCM1; | ||
1313 | addr += NETXEN_PCI_OCM1; | ||
1314 | } else if (ADDR_IN_RANGE(addr, NETXEN_ADDR_QDR_NET, qdr_max)) { | ||
1315 | /* QDR network side */ | ||
1316 | addr -= NETXEN_ADDR_QDR_NET; | ||
1317 | window = (addr >> 22) & 0x3f; | ||
1318 | if (adapter->ahw.qdr_sn_window != window) { | ||
1319 | adapter->ahw.qdr_sn_window = window; | ||
1320 | offset = PCI_OFFSET_SECOND_RANGE(adapter, | ||
1321 | NETXEN_PCIX_PH_REG(PCIE_SN_WINDOW_REG(func))); | ||
1322 | writel((window << 22), offset); | ||
1323 | /* MUST make sure window is set before we forge on... */ | ||
1324 | readl(offset); | ||
1325 | } | ||
1326 | addr -= (window * 0x400000); | ||
1327 | addr += NETXEN_PCI_QDR_NET; | ||
1328 | } else { | ||
1329 | /* | ||
1330 | * peg gdb frequently accesses memory that doesn't exist, | ||
1331 | * this limits the chit chat so debugging isn't slowed down. | ||
1332 | */ | ||
1333 | if ((netxen_pci_set_window_warning_count++ < 8) | ||
1334 | || (netxen_pci_set_window_warning_count % 64 == 0)) | ||
1335 | printk("%s: Warning:netxen_nic_pci_set_window()" | ||
1336 | " Unknown address range!\n", | ||
1337 | netxen_nic_driver_name); | ||
1338 | addr = -1UL; | ||
1339 | } | ||
1340 | return addr; | ||
1341 | } | 1318 | } |
1342 | 1319 | ||
1343 | /* window 1 registers only */ | 1320 | /* window 1 registers only */ |
1344 | static void netxen_nic_io_write_128M(struct netxen_adapter *adapter, | 1321 | static void netxen_nic_io_write_128M(struct netxen_adapter *adapter, |
1345 | void __iomem *addr, u32 data) | 1322 | void __iomem *addr, u32 data) |
1346 | { | 1323 | { |
1347 | read_lock(&adapter->adapter_lock); | 1324 | read_lock(&adapter->ahw.crb_lock); |
1348 | writel(data, addr); | 1325 | writel(data, addr); |
1349 | read_unlock(&adapter->adapter_lock); | 1326 | read_unlock(&adapter->ahw.crb_lock); |
1350 | } | 1327 | } |
1351 | 1328 | ||
1352 | static u32 netxen_nic_io_read_128M(struct netxen_adapter *adapter, | 1329 | static u32 netxen_nic_io_read_128M(struct netxen_adapter *adapter, |
@@ -1354,9 +1331,9 @@ static u32 netxen_nic_io_read_128M(struct netxen_adapter *adapter, | |||
1354 | { | 1331 | { |
1355 | u32 val; | 1332 | u32 val; |
1356 | 1333 | ||
1357 | read_lock(&adapter->adapter_lock); | 1334 | read_lock(&adapter->ahw.crb_lock); |
1358 | val = readl(addr); | 1335 | val = readl(addr); |
1359 | read_unlock(&adapter->adapter_lock); | 1336 | read_unlock(&adapter->ahw.crb_lock); |
1360 | 1337 | ||
1361 | return val; | 1338 | return val; |
1362 | } | 1339 | } |
@@ -1376,488 +1353,437 @@ static u32 netxen_nic_io_read_2M(struct netxen_adapter *adapter, | |||
1376 | void __iomem * | 1353 | void __iomem * |
1377 | netxen_get_ioaddr(struct netxen_adapter *adapter, u32 offset) | 1354 | netxen_get_ioaddr(struct netxen_adapter *adapter, u32 offset) |
1378 | { | 1355 | { |
1379 | ulong off = offset; | 1356 | void __iomem *addr = NULL; |
1380 | 1357 | ||
1381 | if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) { | 1358 | if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) { |
1382 | if (offset < NETXEN_CRB_PCIX_HOST2 && | 1359 | if ((offset < NETXEN_CRB_PCIX_HOST2) && |
1383 | offset > NETXEN_CRB_PCIX_HOST) | 1360 | (offset > NETXEN_CRB_PCIX_HOST)) |
1384 | return PCI_OFFSET_SECOND_RANGE(adapter, offset); | 1361 | addr = PCI_OFFSET_SECOND_RANGE(adapter, offset); |
1385 | return NETXEN_CRB_NORMALIZE(adapter, offset); | 1362 | else |
1363 | addr = NETXEN_CRB_NORMALIZE(adapter, offset); | ||
1364 | } else { | ||
1365 | WARN_ON(netxen_nic_pci_get_crb_addr_2M(adapter, | ||
1366 | offset, &addr)); | ||
1386 | } | 1367 | } |
1387 | 1368 | ||
1388 | BUG_ON(netxen_nic_pci_get_crb_addr_2M(adapter, &off)); | 1369 | return addr; |
1389 | return (void __iomem *)off; | ||
1390 | } | 1370 | } |
1391 | 1371 | ||
1392 | static unsigned long | 1372 | static int |
1393 | netxen_nic_pci_set_window_2M(struct netxen_adapter *adapter, | 1373 | netxen_nic_pci_set_window_128M(struct netxen_adapter *adapter, |
1394 | unsigned long long addr) | 1374 | u64 addr, u32 *start) |
1395 | { | 1375 | { |
1396 | int window; | 1376 | if (ADDR_IN_RANGE(addr, NETXEN_ADDR_OCM0, NETXEN_ADDR_OCM0_MAX)) { |
1397 | u32 win_read; | 1377 | *start = (addr - NETXEN_ADDR_OCM0 + NETXEN_PCI_OCM0); |
1398 | 1378 | return 0; | |
1399 | if (ADDR_IN_RANGE(addr, NETXEN_ADDR_DDR_NET, NETXEN_ADDR_DDR_NET_MAX)) { | ||
1400 | /* DDR network side */ | ||
1401 | window = MN_WIN(addr); | ||
1402 | adapter->ahw.ddr_mn_window = window; | ||
1403 | NXWR32(adapter, adapter->ahw.mn_win_crb, window); | ||
1404 | win_read = NXRD32(adapter, adapter->ahw.mn_win_crb); | ||
1405 | if ((win_read << 17) != window) { | ||
1406 | printk(KERN_INFO "Written MNwin (0x%x) != " | ||
1407 | "Read MNwin (0x%x)\n", window, win_read); | ||
1408 | } | ||
1409 | addr = GET_MEM_OFFS_2M(addr) + NETXEN_PCI_DDR_NET; | ||
1410 | } else if (ADDR_IN_RANGE(addr, | 1379 | } else if (ADDR_IN_RANGE(addr, |
1411 | NETXEN_ADDR_OCM0, NETXEN_ADDR_OCM0_MAX)) { | 1380 | NETXEN_ADDR_OCM1, NETXEN_ADDR_OCM1_MAX)) { |
1412 | if ((addr & 0x00ff800) == 0xff800) { | 1381 | *start = (addr - NETXEN_ADDR_OCM1 + NETXEN_PCI_OCM1); |
1413 | printk("%s: QM access not handled.\n", __func__); | 1382 | return 0; |
1414 | addr = -1UL; | 1383 | } |
1415 | } | 1384 | |
1385 | return -EIO; | ||
1386 | } | ||
1416 | 1387 | ||
1388 | static int | ||
1389 | netxen_nic_pci_set_window_2M(struct netxen_adapter *adapter, | ||
1390 | u64 addr, u32 *start) | ||
1391 | { | ||
1392 | u32 window; | ||
1393 | struct pci_dev *pdev = adapter->pdev; | ||
1394 | |||
1395 | if ((addr & 0x00ff800) == 0xff800) { | ||
1396 | if (printk_ratelimit()) | ||
1397 | dev_warn(&pdev->dev, "QM access not handled\n"); | ||
1398 | return -EIO; | ||
1399 | } | ||
1400 | |||
1401 | if (NX_IS_REVISION_P3P(adapter->ahw.revision_id)) | ||
1402 | window = OCM_WIN_P3P(addr); | ||
1403 | else | ||
1417 | window = OCM_WIN(addr); | 1404 | window = OCM_WIN(addr); |
1418 | adapter->ahw.ddr_mn_window = window; | ||
1419 | NXWR32(adapter, adapter->ahw.mn_win_crb, window); | ||
1420 | win_read = NXRD32(adapter, adapter->ahw.mn_win_crb); | ||
1421 | if ((win_read >> 7) != window) { | ||
1422 | printk(KERN_INFO "%s: Written OCMwin (0x%x) != " | ||
1423 | "Read OCMwin (0x%x)\n", | ||
1424 | __func__, window, win_read); | ||
1425 | } | ||
1426 | addr = GET_MEM_OFFS_2M(addr) + NETXEN_PCI_OCM0_2M; | ||
1427 | 1405 | ||
1428 | } else if (ADDR_IN_RANGE(addr, | 1406 | writel(window, adapter->ahw.ocm_win_crb); |
1429 | NETXEN_ADDR_QDR_NET, NETXEN_ADDR_QDR_NET_MAX_P3)) { | 1407 | /* read back to flush */ |
1430 | /* QDR network side */ | 1408 | readl(adapter->ahw.ocm_win_crb); |
1431 | window = MS_WIN(addr); | ||
1432 | adapter->ahw.qdr_sn_window = window; | ||
1433 | NXWR32(adapter, adapter->ahw.ms_win_crb, window); | ||
1434 | win_read = NXRD32(adapter, adapter->ahw.ms_win_crb); | ||
1435 | if (win_read != window) { | ||
1436 | printk(KERN_INFO "%s: Written MSwin (0x%x) != " | ||
1437 | "Read MSwin (0x%x)\n", | ||
1438 | __func__, window, win_read); | ||
1439 | } | ||
1440 | addr = GET_MEM_OFFS_2M(addr) + NETXEN_PCI_QDR_NET; | ||
1441 | 1409 | ||
1442 | } else { | 1410 | adapter->ahw.ocm_win = window; |
1443 | /* | 1411 | *start = NETXEN_PCI_OCM0_2M + GET_MEM_OFFS_2M(addr); |
1444 | * peg gdb frequently accesses memory that doesn't exist, | 1412 | return 0; |
1445 | * this limits the chit chat so debugging isn't slowed down. | ||
1446 | */ | ||
1447 | if ((netxen_pci_set_window_warning_count++ < 8) | ||
1448 | || (netxen_pci_set_window_warning_count%64 == 0)) { | ||
1449 | printk("%s: Warning:%s Unknown address range!\n", | ||
1450 | __func__, netxen_nic_driver_name); | ||
1451 | } | 1413 | } |
1452 | addr = -1UL; | 1414 | |
1415 | static int | ||
1416 | netxen_nic_pci_mem_access_direct(struct netxen_adapter *adapter, u64 off, | ||
1417 | u64 *data, int op) | ||
1418 | { | ||
1419 | void __iomem *addr, *mem_ptr = NULL; | ||
1420 | resource_size_t mem_base; | ||
1421 | int ret = -EIO; | ||
1422 | u32 start; | ||
1423 | |||
1424 | spin_lock(&adapter->ahw.mem_lock); | ||
1425 | |||
1426 | ret = adapter->pci_set_window(adapter, off, &start); | ||
1427 | if (ret != 0) | ||
1428 | goto unlock; | ||
1429 | |||
1430 | addr = pci_base_offset(adapter, start); | ||
1431 | if (addr) | ||
1432 | goto noremap; | ||
1433 | |||
1434 | mem_base = pci_resource_start(adapter->pdev, 0) + (start & PAGE_MASK); | ||
1435 | |||
1436 | mem_ptr = ioremap(mem_base, PAGE_SIZE); | ||
1437 | if (mem_ptr == NULL) { | ||
1438 | ret = -EIO; | ||
1439 | goto unlock; | ||
1453 | } | 1440 | } |
1454 | return addr; | 1441 | |
1442 | addr = mem_ptr + (start & (PAGE_SIZE - 1)); | ||
1443 | |||
1444 | noremap: | ||
1445 | if (op == 0) /* read */ | ||
1446 | *data = readq(addr); | ||
1447 | else /* write */ | ||
1448 | writeq(*data, addr); | ||
1449 | |||
1450 | unlock: | ||
1451 | spin_unlock(&adapter->ahw.mem_lock); | ||
1452 | |||
1453 | if (mem_ptr) | ||
1454 | iounmap(mem_ptr); | ||
1455 | return ret; | ||
1455 | } | 1456 | } |
1456 | 1457 | ||
1457 | #define MAX_CTL_CHECK 1000 | 1458 | #define MAX_CTL_CHECK 1000 |
1458 | 1459 | ||
1459 | static int | 1460 | static int |
1460 | netxen_nic_pci_mem_write_128M(struct netxen_adapter *adapter, | 1461 | netxen_nic_pci_mem_write_128M(struct netxen_adapter *adapter, |
1461 | u64 off, void *data, int size) | 1462 | u64 off, u64 data) |
1462 | { | 1463 | { |
1463 | unsigned long flags; | 1464 | int j, ret; |
1464 | int i, j, ret = 0, loop, sz[2], off0; | 1465 | u32 temp, off_lo, off_hi, addr_hi, data_hi, data_lo; |
1465 | uint32_t temp; | ||
1466 | uint64_t off8, tmpw, word[2] = {0, 0}; | ||
1467 | void __iomem *mem_crb; | 1466 | void __iomem *mem_crb; |
1468 | 1467 | ||
1469 | if (size != 8) | 1468 | /* Only 64-bit aligned access */ |
1469 | if (off & 7) | ||
1470 | return -EIO; | 1470 | return -EIO; |
1471 | 1471 | ||
1472 | /* P2 has different SIU and MIU test agent base addr */ | ||
1472 | if (ADDR_IN_RANGE(off, NETXEN_ADDR_QDR_NET, | 1473 | if (ADDR_IN_RANGE(off, NETXEN_ADDR_QDR_NET, |
1473 | NETXEN_ADDR_QDR_NET_MAX_P2)) { | 1474 | NETXEN_ADDR_QDR_NET_MAX_P2)) { |
1474 | mem_crb = pci_base_offset(adapter, NETXEN_CRB_QDR_NET); | 1475 | mem_crb = pci_base_offset(adapter, |
1476 | NETXEN_CRB_QDR_NET+SIU_TEST_AGT_BASE); | ||
1477 | addr_hi = SIU_TEST_AGT_ADDR_HI; | ||
1478 | data_lo = SIU_TEST_AGT_WRDATA_LO; | ||
1479 | data_hi = SIU_TEST_AGT_WRDATA_HI; | ||
1480 | off_lo = off & SIU_TEST_AGT_ADDR_MASK; | ||
1481 | off_hi = SIU_TEST_AGT_UPPER_ADDR(off); | ||
1475 | goto correct; | 1482 | goto correct; |
1476 | } | 1483 | } |
1477 | 1484 | ||
1478 | if (ADDR_IN_RANGE(off, NETXEN_ADDR_DDR_NET, NETXEN_ADDR_DDR_NET_MAX)) { | 1485 | if (ADDR_IN_RANGE(off, NETXEN_ADDR_DDR_NET, NETXEN_ADDR_DDR_NET_MAX)) { |
1479 | mem_crb = pci_base_offset(adapter, NETXEN_CRB_DDR_NET); | 1486 | mem_crb = pci_base_offset(adapter, |
1487 | NETXEN_CRB_DDR_NET+MIU_TEST_AGT_BASE); | ||
1488 | addr_hi = MIU_TEST_AGT_ADDR_HI; | ||
1489 | data_lo = MIU_TEST_AGT_WRDATA_LO; | ||
1490 | data_hi = MIU_TEST_AGT_WRDATA_HI; | ||
1491 | off_lo = off & MIU_TEST_AGT_ADDR_MASK; | ||
1492 | off_hi = 0; | ||
1480 | goto correct; | 1493 | goto correct; |
1481 | } | 1494 | } |
1482 | 1495 | ||
1483 | return -EIO; | 1496 | if (ADDR_IN_RANGE(off, NETXEN_ADDR_OCM0, NETXEN_ADDR_OCM0_MAX) || |
1484 | 1497 | ADDR_IN_RANGE(off, NETXEN_ADDR_OCM1, NETXEN_ADDR_OCM1_MAX)) { | |
1485 | correct: | 1498 | if (adapter->ahw.pci_len0 != 0) { |
1486 | off8 = off & 0xfffffff8; | 1499 | return netxen_nic_pci_mem_access_direct(adapter, |
1487 | off0 = off & 0x7; | 1500 | off, &data, 1); |
1488 | sz[0] = (size < (8 - off0)) ? size : (8 - off0); | ||
1489 | sz[1] = size - sz[0]; | ||
1490 | loop = ((off0 + size - 1) >> 3) + 1; | ||
1491 | |||
1492 | if ((size != 8) || (off0 != 0)) { | ||
1493 | for (i = 0; i < loop; i++) { | ||
1494 | if (adapter->pci_mem_read(adapter, | ||
1495 | off8 + (i << 3), &word[i], 8)) | ||
1496 | return -1; | ||
1497 | } | 1501 | } |
1498 | } | 1502 | } |
1499 | 1503 | ||
1500 | switch (size) { | 1504 | return -EIO; |
1501 | case 1: | ||
1502 | tmpw = *((uint8_t *)data); | ||
1503 | break; | ||
1504 | case 2: | ||
1505 | tmpw = *((uint16_t *)data); | ||
1506 | break; | ||
1507 | case 4: | ||
1508 | tmpw = *((uint32_t *)data); | ||
1509 | break; | ||
1510 | case 8: | ||
1511 | default: | ||
1512 | tmpw = *((uint64_t *)data); | ||
1513 | break; | ||
1514 | } | ||
1515 | word[0] &= ~((~(~0ULL << (sz[0] * 8))) << (off0 * 8)); | ||
1516 | word[0] |= tmpw << (off0 * 8); | ||
1517 | 1505 | ||
1518 | if (loop == 2) { | 1506 | correct: |
1519 | word[1] &= ~(~0ULL << (sz[1] * 8)); | 1507 | spin_lock(&adapter->ahw.mem_lock); |
1520 | word[1] |= tmpw >> (sz[0] * 8); | 1508 | netxen_nic_pci_set_crbwindow_128M(adapter, 0); |
1509 | |||
1510 | writel(off_lo, (mem_crb + MIU_TEST_AGT_ADDR_LO)); | ||
1511 | writel(off_hi, (mem_crb + addr_hi)); | ||
1512 | writel(data & 0xffffffff, (mem_crb + data_lo)); | ||
1513 | writel((data >> 32) & 0xffffffff, (mem_crb + data_hi)); | ||
1514 | writel((TA_CTL_ENABLE | TA_CTL_WRITE), (mem_crb + TEST_AGT_CTRL)); | ||
1515 | writel((TA_CTL_START | TA_CTL_ENABLE | TA_CTL_WRITE), | ||
1516 | (mem_crb + TEST_AGT_CTRL)); | ||
1517 | |||
1518 | for (j = 0; j < MAX_CTL_CHECK; j++) { | ||
1519 | temp = readl((mem_crb + TEST_AGT_CTRL)); | ||
1520 | if ((temp & TA_CTL_BUSY) == 0) | ||
1521 | break; | ||
1521 | } | 1522 | } |
1522 | 1523 | ||
1523 | write_lock_irqsave(&adapter->adapter_lock, flags); | 1524 | if (j >= MAX_CTL_CHECK) { |
1524 | netxen_nic_pci_change_crbwindow_128M(adapter, 0); | 1525 | if (printk_ratelimit()) |
1525 | 1526 | dev_err(&adapter->pdev->dev, | |
1526 | for (i = 0; i < loop; i++) { | ||
1527 | writel((uint32_t)(off8 + (i << 3)), | ||
1528 | (mem_crb+MIU_TEST_AGT_ADDR_LO)); | ||
1529 | writel(0, | ||
1530 | (mem_crb+MIU_TEST_AGT_ADDR_HI)); | ||
1531 | writel(word[i] & 0xffffffff, | ||
1532 | (mem_crb+MIU_TEST_AGT_WRDATA_LO)); | ||
1533 | writel((word[i] >> 32) & 0xffffffff, | ||
1534 | (mem_crb+MIU_TEST_AGT_WRDATA_HI)); | ||
1535 | writel(MIU_TA_CTL_ENABLE|MIU_TA_CTL_WRITE, | ||
1536 | (mem_crb+MIU_TEST_AGT_CTRL)); | ||
1537 | writel(MIU_TA_CTL_START|MIU_TA_CTL_ENABLE|MIU_TA_CTL_WRITE, | ||
1538 | (mem_crb+MIU_TEST_AGT_CTRL)); | ||
1539 | |||
1540 | for (j = 0; j < MAX_CTL_CHECK; j++) { | ||
1541 | temp = readl( | ||
1542 | (mem_crb+MIU_TEST_AGT_CTRL)); | ||
1543 | if ((temp & MIU_TA_CTL_BUSY) == 0) | ||
1544 | break; | ||
1545 | } | ||
1546 | |||
1547 | if (j >= MAX_CTL_CHECK) { | ||
1548 | if (printk_ratelimit()) | ||
1549 | dev_err(&adapter->pdev->dev, | ||
1550 | "failed to write through agent\n"); | 1527 | "failed to write through agent\n"); |
1551 | ret = -1; | 1528 | ret = -EIO; |
1552 | break; | 1529 | } else |
1553 | } | 1530 | ret = 0; |
1554 | } | ||
1555 | 1531 | ||
1556 | netxen_nic_pci_change_crbwindow_128M(adapter, 1); | 1532 | netxen_nic_pci_set_crbwindow_128M(adapter, NETXEN_WINDOW_ONE); |
1557 | write_unlock_irqrestore(&adapter->adapter_lock, flags); | 1533 | spin_unlock(&adapter->ahw.mem_lock); |
1558 | return ret; | 1534 | return ret; |
1559 | } | 1535 | } |
1560 | 1536 | ||
1561 | static int | 1537 | static int |
1562 | netxen_nic_pci_mem_read_128M(struct netxen_adapter *adapter, | 1538 | netxen_nic_pci_mem_read_128M(struct netxen_adapter *adapter, |
1563 | u64 off, void *data, int size) | 1539 | u64 off, u64 *data) |
1564 | { | 1540 | { |
1565 | unsigned long flags; | 1541 | int j, ret; |
1566 | int i, j = 0, k, start, end, loop, sz[2], off0[2]; | 1542 | u32 temp, off_lo, off_hi, addr_hi, data_hi, data_lo; |
1567 | uint32_t temp; | 1543 | u64 val; |
1568 | uint64_t off8, val, word[2] = {0, 0}; | ||
1569 | void __iomem *mem_crb; | 1544 | void __iomem *mem_crb; |
1570 | 1545 | ||
1571 | if (size != 8) | 1546 | /* Only 64-bit aligned access */ |
1547 | if (off & 7) | ||
1572 | return -EIO; | 1548 | return -EIO; |
1573 | 1549 | ||
1550 | /* P2 has different SIU and MIU test agent base addr */ | ||
1574 | if (ADDR_IN_RANGE(off, NETXEN_ADDR_QDR_NET, | 1551 | if (ADDR_IN_RANGE(off, NETXEN_ADDR_QDR_NET, |
1575 | NETXEN_ADDR_QDR_NET_MAX_P2)) { | 1552 | NETXEN_ADDR_QDR_NET_MAX_P2)) { |
1576 | mem_crb = pci_base_offset(adapter, NETXEN_CRB_QDR_NET); | 1553 | mem_crb = pci_base_offset(adapter, |
1554 | NETXEN_CRB_QDR_NET+SIU_TEST_AGT_BASE); | ||
1555 | addr_hi = SIU_TEST_AGT_ADDR_HI; | ||
1556 | data_lo = SIU_TEST_AGT_RDDATA_LO; | ||
1557 | data_hi = SIU_TEST_AGT_RDDATA_HI; | ||
1558 | off_lo = off & SIU_TEST_AGT_ADDR_MASK; | ||
1559 | off_hi = SIU_TEST_AGT_UPPER_ADDR(off); | ||
1577 | goto correct; | 1560 | goto correct; |
1578 | } | 1561 | } |
1579 | 1562 | ||
1580 | if (ADDR_IN_RANGE(off, NETXEN_ADDR_DDR_NET, NETXEN_ADDR_DDR_NET_MAX)) { | 1563 | if (ADDR_IN_RANGE(off, NETXEN_ADDR_DDR_NET, NETXEN_ADDR_DDR_NET_MAX)) { |
1581 | mem_crb = pci_base_offset(adapter, NETXEN_CRB_DDR_NET); | 1564 | mem_crb = pci_base_offset(adapter, |
1565 | NETXEN_CRB_DDR_NET+MIU_TEST_AGT_BASE); | ||
1566 | addr_hi = MIU_TEST_AGT_ADDR_HI; | ||
1567 | data_lo = MIU_TEST_AGT_RDDATA_LO; | ||
1568 | data_hi = MIU_TEST_AGT_RDDATA_HI; | ||
1569 | off_lo = off & MIU_TEST_AGT_ADDR_MASK; | ||
1570 | off_hi = 0; | ||
1582 | goto correct; | 1571 | goto correct; |
1583 | } | 1572 | } |
1584 | 1573 | ||
1574 | if (ADDR_IN_RANGE(off, NETXEN_ADDR_OCM0, NETXEN_ADDR_OCM0_MAX) || | ||
1575 | ADDR_IN_RANGE(off, NETXEN_ADDR_OCM1, NETXEN_ADDR_OCM1_MAX)) { | ||
1576 | if (adapter->ahw.pci_len0 != 0) { | ||
1577 | return netxen_nic_pci_mem_access_direct(adapter, | ||
1578 | off, data, 0); | ||
1579 | } | ||
1580 | } | ||
1581 | |||
1585 | return -EIO; | 1582 | return -EIO; |
1586 | 1583 | ||
1587 | correct: | 1584 | correct: |
1588 | off8 = off & 0xfffffff8; | 1585 | spin_lock(&adapter->ahw.mem_lock); |
1589 | off0[0] = off & 0x7; | 1586 | netxen_nic_pci_set_crbwindow_128M(adapter, 0); |
1590 | off0[1] = 0; | ||
1591 | sz[0] = (size < (8 - off0[0])) ? size : (8 - off0[0]); | ||
1592 | sz[1] = size - sz[0]; | ||
1593 | loop = ((off0[0] + size - 1) >> 3) + 1; | ||
1594 | |||
1595 | write_lock_irqsave(&adapter->adapter_lock, flags); | ||
1596 | netxen_nic_pci_change_crbwindow_128M(adapter, 0); | ||
1597 | |||
1598 | for (i = 0; i < loop; i++) { | ||
1599 | writel((uint32_t)(off8 + (i << 3)), | ||
1600 | (mem_crb+MIU_TEST_AGT_ADDR_LO)); | ||
1601 | writel(0, | ||
1602 | (mem_crb+MIU_TEST_AGT_ADDR_HI)); | ||
1603 | writel(MIU_TA_CTL_ENABLE, | ||
1604 | (mem_crb+MIU_TEST_AGT_CTRL)); | ||
1605 | writel(MIU_TA_CTL_START|MIU_TA_CTL_ENABLE, | ||
1606 | (mem_crb+MIU_TEST_AGT_CTRL)); | ||
1607 | 1587 | ||
1608 | for (j = 0; j < MAX_CTL_CHECK; j++) { | 1588 | writel(off_lo, (mem_crb + MIU_TEST_AGT_ADDR_LO)); |
1609 | temp = readl( | 1589 | writel(off_hi, (mem_crb + addr_hi)); |
1610 | (mem_crb+MIU_TEST_AGT_CTRL)); | 1590 | writel(TA_CTL_ENABLE, (mem_crb + TEST_AGT_CTRL)); |
1611 | if ((temp & MIU_TA_CTL_BUSY) == 0) | 1591 | writel((TA_CTL_START|TA_CTL_ENABLE), (mem_crb + TEST_AGT_CTRL)); |
1612 | break; | ||
1613 | } | ||
1614 | 1592 | ||
1615 | if (j >= MAX_CTL_CHECK) { | 1593 | for (j = 0; j < MAX_CTL_CHECK; j++) { |
1616 | if (printk_ratelimit()) | 1594 | temp = readl(mem_crb + TEST_AGT_CTRL); |
1617 | dev_err(&adapter->pdev->dev, | 1595 | if ((temp & TA_CTL_BUSY) == 0) |
1618 | "failed to read through agent\n"); | ||
1619 | break; | 1596 | break; |
1620 | } | ||
1621 | |||
1622 | start = off0[i] >> 2; | ||
1623 | end = (off0[i] + sz[i] - 1) >> 2; | ||
1624 | for (k = start; k <= end; k++) { | ||
1625 | word[i] |= ((uint64_t) readl( | ||
1626 | (mem_crb + | ||
1627 | MIU_TEST_AGT_RDDATA(k))) << (32*k)); | ||
1628 | } | ||
1629 | } | 1597 | } |
1630 | 1598 | ||
1631 | netxen_nic_pci_change_crbwindow_128M(adapter, 1); | 1599 | if (j >= MAX_CTL_CHECK) { |
1632 | write_unlock_irqrestore(&adapter->adapter_lock, flags); | 1600 | if (printk_ratelimit()) |
1633 | 1601 | dev_err(&adapter->pdev->dev, | |
1634 | if (j >= MAX_CTL_CHECK) | 1602 | "failed to read through agent\n"); |
1635 | return -1; | 1603 | ret = -EIO; |
1636 | |||
1637 | if (sz[0] == 8) { | ||
1638 | val = word[0]; | ||
1639 | } else { | 1604 | } else { |
1640 | val = ((word[0] >> (off0[0] * 8)) & (~(~0ULL << (sz[0] * 8)))) | | ||
1641 | ((word[1] & (~(~0ULL << (sz[1] * 8)))) << (sz[0] * 8)); | ||
1642 | } | ||
1643 | 1605 | ||
1644 | switch (size) { | 1606 | temp = readl(mem_crb + data_hi); |
1645 | case 1: | 1607 | val = ((u64)temp << 32); |
1646 | *(uint8_t *)data = val; | 1608 | val |= readl(mem_crb + data_lo); |
1647 | break; | 1609 | *data = val; |
1648 | case 2: | 1610 | ret = 0; |
1649 | *(uint16_t *)data = val; | ||
1650 | break; | ||
1651 | case 4: | ||
1652 | *(uint32_t *)data = val; | ||
1653 | break; | ||
1654 | case 8: | ||
1655 | *(uint64_t *)data = val; | ||
1656 | break; | ||
1657 | } | 1611 | } |
1658 | return 0; | 1612 | |
1613 | netxen_nic_pci_set_crbwindow_128M(adapter, NETXEN_WINDOW_ONE); | ||
1614 | spin_unlock(&adapter->ahw.mem_lock); | ||
1615 | |||
1616 | return ret; | ||
1659 | } | 1617 | } |
1660 | 1618 | ||
1661 | static int | 1619 | static int |
1662 | netxen_nic_pci_mem_write_2M(struct netxen_adapter *adapter, | 1620 | netxen_nic_pci_mem_write_2M(struct netxen_adapter *adapter, |
1663 | u64 off, void *data, int size) | 1621 | u64 off, u64 data) |
1664 | { | 1622 | { |
1665 | int i, j, ret = 0, loop, sz[2], off0; | 1623 | int i, j, ret; |
1666 | uint32_t temp; | 1624 | u32 temp, off8; |
1667 | uint64_t off8, tmpw, word[2] = {0, 0}; | 1625 | u64 stride; |
1668 | void __iomem *mem_crb; | 1626 | void __iomem *mem_crb; |
1669 | 1627 | ||
1670 | if (size != 8) | 1628 | /* Only 64-bit aligned access */ |
1629 | if (off & 7) | ||
1671 | return -EIO; | 1630 | return -EIO; |
1672 | 1631 | ||
1632 | /* P3 onward, test agent base for MIU and SIU is same */ | ||
1673 | if (ADDR_IN_RANGE(off, NETXEN_ADDR_QDR_NET, | 1633 | if (ADDR_IN_RANGE(off, NETXEN_ADDR_QDR_NET, |
1674 | NETXEN_ADDR_QDR_NET_MAX_P3)) { | 1634 | NETXEN_ADDR_QDR_NET_MAX_P3)) { |
1675 | mem_crb = netxen_get_ioaddr(adapter, NETXEN_CRB_QDR_NET); | 1635 | mem_crb = netxen_get_ioaddr(adapter, |
1636 | NETXEN_CRB_QDR_NET+MIU_TEST_AGT_BASE); | ||
1676 | goto correct; | 1637 | goto correct; |
1677 | } | 1638 | } |
1678 | 1639 | ||
1679 | if (ADDR_IN_RANGE(off, NETXEN_ADDR_DDR_NET, NETXEN_ADDR_DDR_NET_MAX)) { | 1640 | if (ADDR_IN_RANGE(off, NETXEN_ADDR_DDR_NET, NETXEN_ADDR_DDR_NET_MAX)) { |
1680 | mem_crb = netxen_get_ioaddr(adapter, NETXEN_CRB_DDR_NET); | 1641 | mem_crb = netxen_get_ioaddr(adapter, |
1642 | NETXEN_CRB_DDR_NET+MIU_TEST_AGT_BASE); | ||
1681 | goto correct; | 1643 | goto correct; |
1682 | } | 1644 | } |
1683 | 1645 | ||
1646 | if (ADDR_IN_RANGE(off, NETXEN_ADDR_OCM0, NETXEN_ADDR_OCM0_MAX)) | ||
1647 | return netxen_nic_pci_mem_access_direct(adapter, off, &data, 1); | ||
1648 | |||
1684 | return -EIO; | 1649 | return -EIO; |
1685 | 1650 | ||
1686 | correct: | 1651 | correct: |
1687 | off8 = off & 0xfffffff8; | 1652 | stride = NX_IS_REVISION_P3P(adapter->ahw.revision_id) ? 16 : 8; |
1688 | off0 = off & 0x7; | ||
1689 | sz[0] = (size < (8 - off0)) ? size : (8 - off0); | ||
1690 | sz[1] = size - sz[0]; | ||
1691 | loop = ((off0 + size - 1) >> 3) + 1; | ||
1692 | |||
1693 | if ((size != 8) || (off0 != 0)) { | ||
1694 | for (i = 0; i < loop; i++) { | ||
1695 | if (adapter->pci_mem_read(adapter, | ||
1696 | off8 + (i << 3), &word[i], 8)) | ||
1697 | return -1; | ||
1698 | } | ||
1699 | } | ||
1700 | 1653 | ||
1701 | switch (size) { | 1654 | off8 = off & ~(stride-1); |
1702 | case 1: | ||
1703 | tmpw = *((uint8_t *)data); | ||
1704 | break; | ||
1705 | case 2: | ||
1706 | tmpw = *((uint16_t *)data); | ||
1707 | break; | ||
1708 | case 4: | ||
1709 | tmpw = *((uint32_t *)data); | ||
1710 | break; | ||
1711 | case 8: | ||
1712 | default: | ||
1713 | tmpw = *((uint64_t *)data); | ||
1714 | break; | ||
1715 | } | ||
1716 | 1655 | ||
1717 | word[0] &= ~((~(~0ULL << (sz[0] * 8))) << (off0 * 8)); | 1656 | spin_lock(&adapter->ahw.mem_lock); |
1718 | word[0] |= tmpw << (off0 * 8); | ||
1719 | 1657 | ||
1720 | if (loop == 2) { | 1658 | writel(off8, (mem_crb + MIU_TEST_AGT_ADDR_LO)); |
1721 | word[1] &= ~(~0ULL << (sz[1] * 8)); | 1659 | writel(0, (mem_crb + MIU_TEST_AGT_ADDR_HI)); |
1722 | word[1] |= tmpw >> (sz[0] * 8); | ||
1723 | } | ||
1724 | |||
1725 | /* | ||
1726 | * don't lock here - write_wx gets the lock if each time | ||
1727 | * write_lock_irqsave(&adapter->adapter_lock, flags); | ||
1728 | * netxen_nic_pci_change_crbwindow_128M(adapter, 0); | ||
1729 | */ | ||
1730 | 1660 | ||
1731 | for (i = 0; i < loop; i++) { | 1661 | i = 0; |
1732 | writel(off8 + (i << 3), mem_crb+MIU_TEST_AGT_ADDR_LO); | 1662 | if (stride == 16) { |
1733 | writel(0, mem_crb+MIU_TEST_AGT_ADDR_HI); | 1663 | writel(TA_CTL_ENABLE, (mem_crb + TEST_AGT_CTRL)); |
1734 | writel(word[i] & 0xffffffff, mem_crb+MIU_TEST_AGT_WRDATA_LO); | 1664 | writel((TA_CTL_START | TA_CTL_ENABLE), |
1735 | writel((word[i] >> 32) & 0xffffffff, | 1665 | (mem_crb + TEST_AGT_CTRL)); |
1736 | mem_crb+MIU_TEST_AGT_WRDATA_HI); | ||
1737 | writel((MIU_TA_CTL_ENABLE | MIU_TA_CTL_WRITE), | ||
1738 | mem_crb+MIU_TEST_AGT_CTRL); | ||
1739 | writel(MIU_TA_CTL_START | MIU_TA_CTL_ENABLE | MIU_TA_CTL_WRITE, | ||
1740 | mem_crb+MIU_TEST_AGT_CTRL); | ||
1741 | 1666 | ||
1742 | for (j = 0; j < MAX_CTL_CHECK; j++) { | 1667 | for (j = 0; j < MAX_CTL_CHECK; j++) { |
1743 | temp = readl(mem_crb + MIU_TEST_AGT_CTRL); | 1668 | temp = readl(mem_crb + TEST_AGT_CTRL); |
1744 | if ((temp & MIU_TA_CTL_BUSY) == 0) | 1669 | if ((temp & TA_CTL_BUSY) == 0) |
1745 | break; | 1670 | break; |
1746 | } | 1671 | } |
1747 | 1672 | ||
1748 | if (j >= MAX_CTL_CHECK) { | 1673 | if (j >= MAX_CTL_CHECK) { |
1749 | if (printk_ratelimit()) | 1674 | ret = -EIO; |
1750 | dev_err(&adapter->pdev->dev, | 1675 | goto done; |
1751 | "failed to write through agent\n"); | ||
1752 | ret = -1; | ||
1753 | break; | ||
1754 | } | 1676 | } |
1677 | |||
1678 | i = (off & 0xf) ? 0 : 2; | ||
1679 | writel(readl(mem_crb + MIU_TEST_AGT_RDDATA(i)), | ||
1680 | mem_crb + MIU_TEST_AGT_WRDATA(i)); | ||
1681 | writel(readl(mem_crb + MIU_TEST_AGT_RDDATA(i+1)), | ||
1682 | mem_crb + MIU_TEST_AGT_WRDATA(i+1)); | ||
1683 | i = (off & 0xf) ? 2 : 0; | ||
1755 | } | 1684 | } |
1756 | 1685 | ||
1757 | /* | 1686 | writel(data & 0xffffffff, |
1758 | * netxen_nic_pci_change_crbwindow_128M(adapter, 1); | 1687 | mem_crb + MIU_TEST_AGT_WRDATA(i)); |
1759 | * write_unlock_irqrestore(&adapter->adapter_lock, flags); | 1688 | writel((data >> 32) & 0xffffffff, |
1760 | */ | 1689 | mem_crb + MIU_TEST_AGT_WRDATA(i+1)); |
1690 | |||
1691 | writel((TA_CTL_ENABLE | TA_CTL_WRITE), (mem_crb + TEST_AGT_CTRL)); | ||
1692 | writel((TA_CTL_START | TA_CTL_ENABLE | TA_CTL_WRITE), | ||
1693 | (mem_crb + TEST_AGT_CTRL)); | ||
1694 | |||
1695 | for (j = 0; j < MAX_CTL_CHECK; j++) { | ||
1696 | temp = readl(mem_crb + TEST_AGT_CTRL); | ||
1697 | if ((temp & TA_CTL_BUSY) == 0) | ||
1698 | break; | ||
1699 | } | ||
1700 | |||
1701 | if (j >= MAX_CTL_CHECK) { | ||
1702 | if (printk_ratelimit()) | ||
1703 | dev_err(&adapter->pdev->dev, | ||
1704 | "failed to write through agent\n"); | ||
1705 | ret = -EIO; | ||
1706 | } else | ||
1707 | ret = 0; | ||
1708 | |||
1709 | done: | ||
1710 | spin_unlock(&adapter->ahw.mem_lock); | ||
1711 | |||
1761 | return ret; | 1712 | return ret; |
1762 | } | 1713 | } |
1763 | 1714 | ||
1764 | static int | 1715 | static int |
1765 | netxen_nic_pci_mem_read_2M(struct netxen_adapter *adapter, | 1716 | netxen_nic_pci_mem_read_2M(struct netxen_adapter *adapter, |
1766 | u64 off, void *data, int size) | 1717 | u64 off, u64 *data) |
1767 | { | 1718 | { |
1768 | int i, j = 0, k, start, end, loop, sz[2], off0[2]; | 1719 | int j, ret; |
1769 | uint32_t temp; | 1720 | u32 temp, off8; |
1770 | uint64_t off8, val, word[2] = {0, 0}; | 1721 | u64 val, stride; |
1771 | void __iomem *mem_crb; | 1722 | void __iomem *mem_crb; |
1772 | 1723 | ||
1773 | if (size != 8) | 1724 | /* Only 64-bit aligned access */ |
1725 | if (off & 7) | ||
1774 | return -EIO; | 1726 | return -EIO; |
1775 | 1727 | ||
1728 | /* P3 onward, test agent base for MIU and SIU is same */ | ||
1776 | if (ADDR_IN_RANGE(off, NETXEN_ADDR_QDR_NET, | 1729 | if (ADDR_IN_RANGE(off, NETXEN_ADDR_QDR_NET, |
1777 | NETXEN_ADDR_QDR_NET_MAX_P3)) { | 1730 | NETXEN_ADDR_QDR_NET_MAX_P3)) { |
1778 | mem_crb = netxen_get_ioaddr(adapter, NETXEN_CRB_QDR_NET); | 1731 | mem_crb = netxen_get_ioaddr(adapter, |
1732 | NETXEN_CRB_QDR_NET+MIU_TEST_AGT_BASE); | ||
1779 | goto correct; | 1733 | goto correct; |
1780 | } | 1734 | } |
1781 | 1735 | ||
1782 | if (ADDR_IN_RANGE(off, NETXEN_ADDR_DDR_NET, NETXEN_ADDR_DDR_NET_MAX)) { | 1736 | if (ADDR_IN_RANGE(off, NETXEN_ADDR_DDR_NET, NETXEN_ADDR_DDR_NET_MAX)) { |
1783 | mem_crb = netxen_get_ioaddr(adapter, NETXEN_CRB_DDR_NET); | 1737 | mem_crb = netxen_get_ioaddr(adapter, |
1738 | NETXEN_CRB_DDR_NET+MIU_TEST_AGT_BASE); | ||
1784 | goto correct; | 1739 | goto correct; |
1785 | } | 1740 | } |
1786 | 1741 | ||
1742 | if (ADDR_IN_RANGE(off, NETXEN_ADDR_OCM0, NETXEN_ADDR_OCM0_MAX)) { | ||
1743 | return netxen_nic_pci_mem_access_direct(adapter, | ||
1744 | off, data, 0); | ||
1745 | } | ||
1746 | |||
1787 | return -EIO; | 1747 | return -EIO; |
1788 | 1748 | ||
1789 | correct: | 1749 | correct: |
1790 | off8 = off & 0xfffffff8; | 1750 | stride = NX_IS_REVISION_P3P(adapter->ahw.revision_id) ? 16 : 8; |
1791 | off0[0] = off & 0x7; | ||
1792 | off0[1] = 0; | ||
1793 | sz[0] = (size < (8 - off0[0])) ? size : (8 - off0[0]); | ||
1794 | sz[1] = size - sz[0]; | ||
1795 | loop = ((off0[0] + size - 1) >> 3) + 1; | ||
1796 | 1751 | ||
1797 | /* | 1752 | off8 = off & ~(stride-1); |
1798 | * don't lock here - write_wx gets the lock if each time | ||
1799 | * write_lock_irqsave(&adapter->adapter_lock, flags); | ||
1800 | * netxen_nic_pci_change_crbwindow_128M(adapter, 0); | ||
1801 | */ | ||
1802 | 1753 | ||
1803 | for (i = 0; i < loop; i++) { | 1754 | spin_lock(&adapter->ahw.mem_lock); |
1804 | writel(off8 + (i << 3), mem_crb + MIU_TEST_AGT_ADDR_LO); | ||
1805 | writel(0, mem_crb + MIU_TEST_AGT_ADDR_HI); | ||
1806 | writel(MIU_TA_CTL_ENABLE, mem_crb + MIU_TEST_AGT_CTRL); | ||
1807 | writel(MIU_TA_CTL_START | MIU_TA_CTL_ENABLE, | ||
1808 | mem_crb + MIU_TEST_AGT_CTRL); | ||
1809 | 1755 | ||
1810 | for (j = 0; j < MAX_CTL_CHECK; j++) { | 1756 | writel(off8, (mem_crb + MIU_TEST_AGT_ADDR_LO)); |
1811 | temp = readl(mem_crb + MIU_TEST_AGT_CTRL); | 1757 | writel(0, (mem_crb + MIU_TEST_AGT_ADDR_HI)); |
1812 | if ((temp & MIU_TA_CTL_BUSY) == 0) | 1758 | writel(TA_CTL_ENABLE, (mem_crb + TEST_AGT_CTRL)); |
1813 | break; | 1759 | writel((TA_CTL_START | TA_CTL_ENABLE), (mem_crb + TEST_AGT_CTRL)); |
1814 | } | ||
1815 | 1760 | ||
1816 | if (j >= MAX_CTL_CHECK) { | 1761 | for (j = 0; j < MAX_CTL_CHECK; j++) { |
1817 | if (printk_ratelimit()) | 1762 | temp = readl(mem_crb + TEST_AGT_CTRL); |
1818 | dev_err(&adapter->pdev->dev, | 1763 | if ((temp & TA_CTL_BUSY) == 0) |
1819 | "failed to read through agent\n"); | ||
1820 | break; | 1764 | break; |
1821 | } | ||
1822 | |||
1823 | start = off0[i] >> 2; | ||
1824 | end = (off0[i] + sz[i] - 1) >> 2; | ||
1825 | for (k = start; k <= end; k++) { | ||
1826 | temp = readl(mem_crb + MIU_TEST_AGT_RDDATA(k)); | ||
1827 | word[i] |= ((uint64_t)temp << (32 * k)); | ||
1828 | } | ||
1829 | } | 1765 | } |
1830 | 1766 | ||
1831 | /* | 1767 | if (j >= MAX_CTL_CHECK) { |
1832 | * netxen_nic_pci_change_crbwindow_128M(adapter, 1); | 1768 | if (printk_ratelimit()) |
1833 | * write_unlock_irqrestore(&adapter->adapter_lock, flags); | 1769 | dev_err(&adapter->pdev->dev, |
1834 | */ | 1770 | "failed to read through agent\n"); |
1835 | 1771 | ret = -EIO; | |
1836 | if (j >= MAX_CTL_CHECK) | ||
1837 | return -1; | ||
1838 | |||
1839 | if (sz[0] == 8) { | ||
1840 | val = word[0]; | ||
1841 | } else { | 1772 | } else { |
1842 | val = ((word[0] >> (off0[0] * 8)) & (~(~0ULL << (sz[0] * 8)))) | | 1773 | off8 = MIU_TEST_AGT_RDDATA_LO; |
1843 | ((word[1] & (~(~0ULL << (sz[1] * 8)))) << (sz[0] * 8)); | 1774 | if ((stride == 16) && (off & 0xf)) |
1844 | } | 1775 | off8 = MIU_TEST_AGT_RDDATA_UPPER_LO; |
1845 | 1776 | ||
1846 | switch (size) { | 1777 | temp = readl(mem_crb + off8 + 4); |
1847 | case 1: | 1778 | val = (u64)temp << 32; |
1848 | *(uint8_t *)data = val; | 1779 | val |= readl(mem_crb + off8); |
1849 | break; | 1780 | *data = val; |
1850 | case 2: | 1781 | ret = 0; |
1851 | *(uint16_t *)data = val; | ||
1852 | break; | ||
1853 | case 4: | ||
1854 | *(uint32_t *)data = val; | ||
1855 | break; | ||
1856 | case 8: | ||
1857 | *(uint64_t *)data = val; | ||
1858 | break; | ||
1859 | } | 1782 | } |
1860 | return 0; | 1783 | |
1784 | spin_unlock(&adapter->ahw.mem_lock); | ||
1785 | |||
1786 | return ret; | ||
1861 | } | 1787 | } |
1862 | 1788 | ||
1863 | void | 1789 | void |
@@ -2010,10 +1936,10 @@ void netxen_nic_set_link_parameters(struct netxen_adapter *adapter) | |||
2010 | return; | 1936 | return; |
2011 | } | 1937 | } |
2012 | 1938 | ||
2013 | if (adapter->phy_read | 1939 | if (adapter->phy_read && |
2014 | && adapter->phy_read(adapter, | 1940 | adapter->phy_read(adapter, |
2015 | NETXEN_NIU_GB_MII_MGMT_ADDR_PHY_STATUS, | 1941 | NETXEN_NIU_GB_MII_MGMT_ADDR_PHY_STATUS, |
2016 | &status) == 0) { | 1942 | &status) == 0) { |
2017 | if (netxen_get_phy_link(status)) { | 1943 | if (netxen_get_phy_link(status)) { |
2018 | switch (netxen_get_phy_speed(status)) { | 1944 | switch (netxen_get_phy_speed(status)) { |
2019 | case 0: | 1945 | case 0: |
@@ -2040,10 +1966,10 @@ void netxen_nic_set_link_parameters(struct netxen_adapter *adapter) | |||
2040 | adapter->link_duplex = -1; | 1966 | adapter->link_duplex = -1; |
2041 | break; | 1967 | break; |
2042 | } | 1968 | } |
2043 | if (adapter->phy_read | 1969 | if (adapter->phy_read && |
2044 | && adapter->phy_read(adapter, | 1970 | adapter->phy_read(adapter, |
2045 | NETXEN_NIU_GB_MII_MGMT_ADDR_AUTONEG, | 1971 | NETXEN_NIU_GB_MII_MGMT_ADDR_AUTONEG, |
2046 | &autoneg) != 0) | 1972 | &autoneg) != 0) |
2047 | adapter->link_autoneg = autoneg; | 1973 | adapter->link_autoneg = autoneg; |
2048 | } else | 1974 | } else |
2049 | goto link_down; | 1975 | goto link_down; |
diff --git a/drivers/net/netxen/netxen_nic_init.c b/drivers/net/netxen/netxen_nic_init.c index e40b914d6faf..80a667460514 100644 --- a/drivers/net/netxen/netxen_nic_init.c +++ b/drivers/net/netxen/netxen_nic_init.c | |||
@@ -46,6 +46,7 @@ static unsigned int crb_addr_xform[NETXEN_MAX_CRB_XFORM]; | |||
46 | static void | 46 | static void |
47 | netxen_post_rx_buffers_nodb(struct netxen_adapter *adapter, | 47 | netxen_post_rx_buffers_nodb(struct netxen_adapter *adapter, |
48 | struct nx_host_rds_ring *rds_ring); | 48 | struct nx_host_rds_ring *rds_ring); |
49 | static int netxen_p3_has_mn(struct netxen_adapter *adapter); | ||
49 | 50 | ||
50 | static void crb_addr_transform_setup(void) | 51 | static void crb_addr_transform_setup(void) |
51 | { | 52 | { |
@@ -437,7 +438,7 @@ int netxen_rom_fast_read(struct netxen_adapter *adapter, int addr, int *valp) | |||
437 | #define NETXEN_BOARDNUM 0x400c | 438 | #define NETXEN_BOARDNUM 0x400c |
438 | #define NETXEN_CHIPNUM 0x4010 | 439 | #define NETXEN_CHIPNUM 0x4010 |
439 | 440 | ||
440 | int netxen_pinit_from_rom(struct netxen_adapter *adapter, int verbose) | 441 | int netxen_pinit_from_rom(struct netxen_adapter *adapter) |
441 | { | 442 | { |
442 | int addr, val; | 443 | int addr, val; |
443 | int i, n, init_delay = 0; | 444 | int i, n, init_delay = 0; |
@@ -450,21 +451,6 @@ int netxen_pinit_from_rom(struct netxen_adapter *adapter, int verbose) | |||
450 | NXWR32(adapter, NETXEN_ROMUSB_GLB_SW_RESET, 0xffffffff); | 451 | NXWR32(adapter, NETXEN_ROMUSB_GLB_SW_RESET, 0xffffffff); |
451 | netxen_rom_unlock(adapter); | 452 | netxen_rom_unlock(adapter); |
452 | 453 | ||
453 | if (verbose) { | ||
454 | if (netxen_rom_fast_read(adapter, NETXEN_BOARDTYPE, &val) == 0) | ||
455 | printk("P2 ROM board type: 0x%08x\n", val); | ||
456 | else | ||
457 | printk("Could not read board type\n"); | ||
458 | if (netxen_rom_fast_read(adapter, NETXEN_BOARDNUM, &val) == 0) | ||
459 | printk("P2 ROM board num: 0x%08x\n", val); | ||
460 | else | ||
461 | printk("Could not read board number\n"); | ||
462 | if (netxen_rom_fast_read(adapter, NETXEN_CHIPNUM, &val) == 0) | ||
463 | printk("P2 ROM chip num: 0x%08x\n", val); | ||
464 | else | ||
465 | printk("Could not read chip number\n"); | ||
466 | } | ||
467 | |||
468 | if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) { | 454 | if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) { |
469 | if (netxen_rom_fast_read(adapter, 0, &n) != 0 || | 455 | if (netxen_rom_fast_read(adapter, 0, &n) != 0 || |
470 | (n != 0xcafecafe) || | 456 | (n != 0xcafecafe) || |
@@ -486,11 +472,7 @@ int netxen_pinit_from_rom(struct netxen_adapter *adapter, int verbose) | |||
486 | n &= ~0x80000000; | 472 | n &= ~0x80000000; |
487 | } | 473 | } |
488 | 474 | ||
489 | if (n < 1024) { | 475 | if (n >= 1024) { |
490 | if (verbose) | ||
491 | printk(KERN_DEBUG "%s: %d CRB init values found" | ||
492 | " in ROM.\n", netxen_nic_driver_name, n); | ||
493 | } else { | ||
494 | printk(KERN_ERR "%s:n=0x%x Error! NetXen card flash not" | 476 | printk(KERN_ERR "%s:n=0x%x Error! NetXen card flash not" |
495 | " initialized.\n", __func__, n); | 477 | " initialized.\n", __func__, n); |
496 | return -EIO; | 478 | return -EIO; |
@@ -502,6 +484,7 @@ int netxen_pinit_from_rom(struct netxen_adapter *adapter, int verbose) | |||
502 | netxen_nic_driver_name); | 484 | netxen_nic_driver_name); |
503 | return -ENOMEM; | 485 | return -ENOMEM; |
504 | } | 486 | } |
487 | |||
505 | for (i = 0; i < n; i++) { | 488 | for (i = 0; i < n; i++) { |
506 | if (netxen_rom_fast_read(adapter, 8*i + 4*offset, &val) != 0 || | 489 | if (netxen_rom_fast_read(adapter, 8*i + 4*offset, &val) != 0 || |
507 | netxen_rom_fast_read(adapter, 8*i + 4*offset + 4, &addr) != 0) { | 490 | netxen_rom_fast_read(adapter, 8*i + 4*offset + 4, &addr) != 0) { |
@@ -512,11 +495,8 @@ int netxen_pinit_from_rom(struct netxen_adapter *adapter, int verbose) | |||
512 | buf[i].addr = addr; | 495 | buf[i].addr = addr; |
513 | buf[i].data = val; | 496 | buf[i].data = val; |
514 | 497 | ||
515 | if (verbose) | ||
516 | printk(KERN_DEBUG "%s: PCI: 0x%08x == 0x%08x\n", | ||
517 | netxen_nic_driver_name, | ||
518 | (u32)netxen_decode_crb_addr(addr), val); | ||
519 | } | 498 | } |
499 | |||
520 | for (i = 0; i < n; i++) { | 500 | for (i = 0; i < n; i++) { |
521 | 501 | ||
522 | off = netxen_decode_crb_addr(buf[i].addr); | 502 | off = netxen_decode_crb_addr(buf[i].addr); |
@@ -526,6 +506,10 @@ int netxen_pinit_from_rom(struct netxen_adapter *adapter, int verbose) | |||
526 | continue; | 506 | continue; |
527 | } | 507 | } |
528 | off += NETXEN_PCI_CRBSPACE; | 508 | off += NETXEN_PCI_CRBSPACE; |
509 | |||
510 | if (off & 1) | ||
511 | continue; | ||
512 | |||
529 | /* skipping cold reboot MAGIC */ | 513 | /* skipping cold reboot MAGIC */ |
530 | if (off == NETXEN_CAM_RAM(0x1fc)) | 514 | if (off == NETXEN_CAM_RAM(0x1fc)) |
531 | continue; | 515 | continue; |
@@ -544,7 +528,10 @@ int netxen_pinit_from_rom(struct netxen_adapter *adapter, int verbose) | |||
544 | continue; | 528 | continue; |
545 | if (off == (ROMUSB_GLB + 0x1c)) /* MS clock */ | 529 | if (off == (ROMUSB_GLB + 0x1c)) /* MS clock */ |
546 | continue; | 530 | continue; |
547 | if (off == (NETXEN_CRB_PEG_NET_1 + 0x18)) | 531 | if ((off & 0x0ff00000) == NETXEN_CRB_DDR_NET) |
532 | continue; | ||
533 | if (off == (NETXEN_CRB_PEG_NET_1 + 0x18) && | ||
534 | !NX_IS_REVISION_P3P(adapter->ahw.revision_id)) | ||
548 | buf[i].data = 0x1020; | 535 | buf[i].data = 0x1020; |
549 | /* skip the function enable register */ | 536 | /* skip the function enable register */ |
550 | if (off == NETXEN_PCIE_REG(PCIE_SETUP_FUNCTION)) | 537 | if (off == NETXEN_PCIE_REG(PCIE_SETUP_FUNCTION)) |
@@ -605,6 +592,172 @@ int netxen_pinit_from_rom(struct netxen_adapter *adapter, int verbose) | |||
605 | return 0; | 592 | return 0; |
606 | } | 593 | } |
607 | 594 | ||
595 | static struct uni_table_desc *nx_get_table_desc(const u8 *unirom, int section) | ||
596 | { | ||
597 | uint32_t i; | ||
598 | struct uni_table_desc *directory = (struct uni_table_desc *) &unirom[0]; | ||
599 | __le32 entries = cpu_to_le32(directory->num_entries); | ||
600 | |||
601 | for (i = 0; i < entries; i++) { | ||
602 | |||
603 | __le32 offs = cpu_to_le32(directory->findex) + | ||
604 | (i * cpu_to_le32(directory->entry_size)); | ||
605 | __le32 tab_type = cpu_to_le32(*((u32 *)&unirom[offs] + 8)); | ||
606 | |||
607 | if (tab_type == section) | ||
608 | return (struct uni_table_desc *) &unirom[offs]; | ||
609 | } | ||
610 | |||
611 | return NULL; | ||
612 | } | ||
613 | |||
614 | static int | ||
615 | nx_set_product_offs(struct netxen_adapter *adapter) | ||
616 | { | ||
617 | struct uni_table_desc *ptab_descr; | ||
618 | const u8 *unirom = adapter->fw->data; | ||
619 | uint32_t i; | ||
620 | __le32 entries; | ||
621 | |||
622 | ptab_descr = nx_get_table_desc(unirom, NX_UNI_DIR_SECT_PRODUCT_TBL); | ||
623 | if (ptab_descr == NULL) | ||
624 | return -1; | ||
625 | |||
626 | entries = cpu_to_le32(ptab_descr->num_entries); | ||
627 | |||
628 | for (i = 0; i < entries; i++) { | ||
629 | |||
630 | __le32 flags, file_chiprev, offs; | ||
631 | u8 chiprev = adapter->ahw.revision_id; | ||
632 | int mn_present = netxen_p3_has_mn(adapter); | ||
633 | uint32_t flagbit; | ||
634 | |||
635 | offs = cpu_to_le32(ptab_descr->findex) + | ||
636 | (i * cpu_to_le32(ptab_descr->entry_size)); | ||
637 | flags = cpu_to_le32(*((int *)&unirom[offs] + NX_UNI_FLAGS_OFF)); | ||
638 | file_chiprev = cpu_to_le32(*((int *)&unirom[offs] + | ||
639 | NX_UNI_CHIP_REV_OFF)); | ||
640 | |||
641 | flagbit = mn_present ? 1 : 2; | ||
642 | |||
643 | if ((chiprev == file_chiprev) && | ||
644 | ((1ULL << flagbit) & flags)) { | ||
645 | adapter->file_prd_off = offs; | ||
646 | return 0; | ||
647 | } | ||
648 | } | ||
649 | |||
650 | return -1; | ||
651 | } | ||
652 | |||
653 | |||
654 | static struct uni_data_desc *nx_get_data_desc(struct netxen_adapter *adapter, | ||
655 | u32 section, u32 idx_offset) | ||
656 | { | ||
657 | const u8 *unirom = adapter->fw->data; | ||
658 | int idx = cpu_to_le32(*((int *)&unirom[adapter->file_prd_off] + | ||
659 | idx_offset)); | ||
660 | struct uni_table_desc *tab_desc; | ||
661 | __le32 offs; | ||
662 | |||
663 | tab_desc = nx_get_table_desc(unirom, section); | ||
664 | |||
665 | if (tab_desc == NULL) | ||
666 | return NULL; | ||
667 | |||
668 | offs = cpu_to_le32(tab_desc->findex) + | ||
669 | (cpu_to_le32(tab_desc->entry_size) * idx); | ||
670 | |||
671 | return (struct uni_data_desc *)&unirom[offs]; | ||
672 | } | ||
673 | |||
674 | static u8 * | ||
675 | nx_get_bootld_offs(struct netxen_adapter *adapter) | ||
676 | { | ||
677 | u32 offs = NETXEN_BOOTLD_START; | ||
678 | |||
679 | if (adapter->fw_type == NX_UNIFIED_ROMIMAGE) | ||
680 | offs = cpu_to_le32((nx_get_data_desc(adapter, | ||
681 | NX_UNI_DIR_SECT_BOOTLD, | ||
682 | NX_UNI_BOOTLD_IDX_OFF))->findex); | ||
683 | |||
684 | return (u8 *)&adapter->fw->data[offs]; | ||
685 | } | ||
686 | |||
687 | static u8 * | ||
688 | nx_get_fw_offs(struct netxen_adapter *adapter) | ||
689 | { | ||
690 | u32 offs = NETXEN_IMAGE_START; | ||
691 | |||
692 | if (adapter->fw_type == NX_UNIFIED_ROMIMAGE) | ||
693 | offs = cpu_to_le32((nx_get_data_desc(adapter, | ||
694 | NX_UNI_DIR_SECT_FW, | ||
695 | NX_UNI_FIRMWARE_IDX_OFF))->findex); | ||
696 | |||
697 | return (u8 *)&adapter->fw->data[offs]; | ||
698 | } | ||
699 | |||
700 | static __le32 | ||
701 | nx_get_fw_size(struct netxen_adapter *adapter) | ||
702 | { | ||
703 | if (adapter->fw_type == NX_UNIFIED_ROMIMAGE) | ||
704 | return cpu_to_le32((nx_get_data_desc(adapter, | ||
705 | NX_UNI_DIR_SECT_FW, | ||
706 | NX_UNI_FIRMWARE_IDX_OFF))->size); | ||
707 | else | ||
708 | return cpu_to_le32( | ||
709 | *(u32 *)&adapter->fw->data[NX_FW_SIZE_OFFSET]); | ||
710 | } | ||
711 | |||
712 | static __le32 | ||
713 | nx_get_fw_version(struct netxen_adapter *adapter) | ||
714 | { | ||
715 | struct uni_data_desc *fw_data_desc; | ||
716 | const struct firmware *fw = adapter->fw; | ||
717 | __le32 major, minor, sub; | ||
718 | const u8 *ver_str; | ||
719 | int i, ret = 0; | ||
720 | |||
721 | if (adapter->fw_type == NX_UNIFIED_ROMIMAGE) { | ||
722 | |||
723 | fw_data_desc = nx_get_data_desc(adapter, | ||
724 | NX_UNI_DIR_SECT_FW, NX_UNI_FIRMWARE_IDX_OFF); | ||
725 | ver_str = fw->data + cpu_to_le32(fw_data_desc->findex) + | ||
726 | cpu_to_le32(fw_data_desc->size) - 17; | ||
727 | |||
728 | for (i = 0; i < 12; i++) { | ||
729 | if (!strncmp(&ver_str[i], "REV=", 4)) { | ||
730 | ret = sscanf(&ver_str[i+4], "%u.%u.%u ", | ||
731 | &major, &minor, &sub); | ||
732 | break; | ||
733 | } | ||
734 | } | ||
735 | |||
736 | if (ret != 3) | ||
737 | return 0; | ||
738 | |||
739 | return major + (minor << 8) + (sub << 16); | ||
740 | |||
741 | } else | ||
742 | return cpu_to_le32(*(u32 *)&fw->data[NX_FW_VERSION_OFFSET]); | ||
743 | } | ||
744 | |||
745 | static __le32 | ||
746 | nx_get_bios_version(struct netxen_adapter *adapter) | ||
747 | { | ||
748 | const struct firmware *fw = adapter->fw; | ||
749 | __le32 bios_ver, prd_off = adapter->file_prd_off; | ||
750 | |||
751 | if (adapter->fw_type == NX_UNIFIED_ROMIMAGE) { | ||
752 | bios_ver = cpu_to_le32(*((u32 *) (&fw->data[prd_off]) | ||
753 | + NX_UNI_BIOS_VERSION_OFF)); | ||
754 | return (bios_ver << 24) + ((bios_ver >> 8) & 0xff00) + | ||
755 | (bios_ver >> 24); | ||
756 | } else | ||
757 | return cpu_to_le32(*(u32 *)&fw->data[NX_BIOS_VERSION_OFFSET]); | ||
758 | |||
759 | } | ||
760 | |||
608 | int | 761 | int |
609 | netxen_need_fw_reset(struct netxen_adapter *adapter) | 762 | netxen_need_fw_reset(struct netxen_adapter *adapter) |
610 | { | 763 | { |
@@ -644,9 +797,8 @@ netxen_need_fw_reset(struct netxen_adapter *adapter) | |||
644 | /* check if we have got newer or different file firmware */ | 797 | /* check if we have got newer or different file firmware */ |
645 | if (adapter->fw) { | 798 | if (adapter->fw) { |
646 | 799 | ||
647 | const struct firmware *fw = adapter->fw; | 800 | val = nx_get_fw_version(adapter); |
648 | 801 | ||
649 | val = cpu_to_le32(*(u32 *)&fw->data[NX_FW_VERSION_OFFSET]); | ||
650 | version = NETXEN_DECODE_VERSION(val); | 802 | version = NETXEN_DECODE_VERSION(val); |
651 | 803 | ||
652 | major = NXRD32(adapter, NETXEN_FW_VERSION_MAJOR); | 804 | major = NXRD32(adapter, NETXEN_FW_VERSION_MAJOR); |
@@ -656,7 +808,8 @@ netxen_need_fw_reset(struct netxen_adapter *adapter) | |||
656 | if (version > NETXEN_VERSION_CODE(major, minor, build)) | 808 | if (version > NETXEN_VERSION_CODE(major, minor, build)) |
657 | return 1; | 809 | return 1; |
658 | 810 | ||
659 | if (version == NETXEN_VERSION_CODE(major, minor, build)) { | 811 | if (version == NETXEN_VERSION_CODE(major, minor, build) && |
812 | adapter->fw_type != NX_UNIFIED_ROMIMAGE) { | ||
660 | 813 | ||
661 | val = NXRD32(adapter, NETXEN_MIU_MN_CONTROL); | 814 | val = NXRD32(adapter, NETXEN_MIU_MN_CONTROL); |
662 | fw_type = (val & 0x4) ? | 815 | fw_type = (val & 0x4) ? |
@@ -671,7 +824,11 @@ netxen_need_fw_reset(struct netxen_adapter *adapter) | |||
671 | } | 824 | } |
672 | 825 | ||
673 | static char *fw_name[] = { | 826 | static char *fw_name[] = { |
674 | "nxromimg.bin", "nx3fwct.bin", "nx3fwmn.bin", "flash", | 827 | NX_P2_MN_ROMIMAGE_NAME, |
828 | NX_P3_CT_ROMIMAGE_NAME, | ||
829 | NX_P3_MN_ROMIMAGE_NAME, | ||
830 | NX_UNIFIED_ROMIMAGE_NAME, | ||
831 | NX_FLASH_ROMIMAGE_NAME, | ||
675 | }; | 832 | }; |
676 | 833 | ||
677 | int | 834 | int |
@@ -693,26 +850,28 @@ netxen_load_firmware(struct netxen_adapter *adapter) | |||
693 | 850 | ||
694 | size = (NETXEN_IMAGE_START - NETXEN_BOOTLD_START) / 8; | 851 | size = (NETXEN_IMAGE_START - NETXEN_BOOTLD_START) / 8; |
695 | 852 | ||
696 | ptr64 = (u64 *)&fw->data[NETXEN_BOOTLD_START]; | 853 | ptr64 = (u64 *)nx_get_bootld_offs(adapter); |
697 | flashaddr = NETXEN_BOOTLD_START; | 854 | flashaddr = NETXEN_BOOTLD_START; |
698 | 855 | ||
699 | for (i = 0; i < size; i++) { | 856 | for (i = 0; i < size; i++) { |
700 | data = cpu_to_le64(ptr64[i]); | 857 | data = cpu_to_le64(ptr64[i]); |
701 | adapter->pci_mem_write(adapter, flashaddr, &data, 8); | 858 | |
859 | if (adapter->pci_mem_write(adapter, flashaddr, data)) | ||
860 | return -EIO; | ||
861 | |||
702 | flashaddr += 8; | 862 | flashaddr += 8; |
703 | } | 863 | } |
704 | 864 | ||
705 | size = *(u32 *)&fw->data[NX_FW_SIZE_OFFSET]; | 865 | size = (__force u32)nx_get_fw_size(adapter) / 8; |
706 | size = (__force u32)cpu_to_le32(size) / 8; | ||
707 | 866 | ||
708 | ptr64 = (u64 *)&fw->data[NETXEN_IMAGE_START]; | 867 | ptr64 = (u64 *)nx_get_fw_offs(adapter); |
709 | flashaddr = NETXEN_IMAGE_START; | 868 | flashaddr = NETXEN_IMAGE_START; |
710 | 869 | ||
711 | for (i = 0; i < size; i++) { | 870 | for (i = 0; i < size; i++) { |
712 | data = cpu_to_le64(ptr64[i]); | 871 | data = cpu_to_le64(ptr64[i]); |
713 | 872 | ||
714 | if (adapter->pci_mem_write(adapter, | 873 | if (adapter->pci_mem_write(adapter, |
715 | flashaddr, &data, 8)) | 874 | flashaddr, data)) |
716 | return -EIO; | 875 | return -EIO; |
717 | 876 | ||
718 | flashaddr += 8; | 877 | flashaddr += 8; |
@@ -726,17 +885,17 @@ netxen_load_firmware(struct netxen_adapter *adapter) | |||
726 | 885 | ||
727 | for (i = 0; i < size; i++) { | 886 | for (i = 0; i < size; i++) { |
728 | if (netxen_rom_fast_read(adapter, | 887 | if (netxen_rom_fast_read(adapter, |
729 | flashaddr, &lo) != 0) | 888 | flashaddr, (int *)&lo) != 0) |
730 | return -EIO; | 889 | return -EIO; |
731 | if (netxen_rom_fast_read(adapter, | 890 | if (netxen_rom_fast_read(adapter, |
732 | flashaddr + 4, &hi) != 0) | 891 | flashaddr + 4, (int *)&hi) != 0) |
733 | return -EIO; | 892 | return -EIO; |
734 | 893 | ||
735 | /* hi, lo are already in host endian byteorder */ | 894 | /* hi, lo are already in host endian byteorder */ |
736 | data = (((u64)hi << 32) | lo); | 895 | data = (((u64)hi << 32) | lo); |
737 | 896 | ||
738 | if (adapter->pci_mem_write(adapter, | 897 | if (adapter->pci_mem_write(adapter, |
739 | flashaddr, &data, 8)) | 898 | flashaddr, data)) |
740 | return -EIO; | 899 | return -EIO; |
741 | 900 | ||
742 | flashaddr += 8; | 901 | flashaddr += 8; |
@@ -744,7 +903,10 @@ netxen_load_firmware(struct netxen_adapter *adapter) | |||
744 | } | 903 | } |
745 | msleep(1); | 904 | msleep(1); |
746 | 905 | ||
747 | if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) | 906 | if (NX_IS_REVISION_P3P(adapter->ahw.revision_id)) { |
907 | NXWR32(adapter, NETXEN_CRB_PEG_NET_0 + 0x18, 0x1020); | ||
908 | NXWR32(adapter, NETXEN_ROMUSB_GLB_SW_RESET, 0x80001e); | ||
909 | } else if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) | ||
748 | NXWR32(adapter, NETXEN_ROMUSB_GLB_SW_RESET, 0x80001d); | 910 | NXWR32(adapter, NETXEN_ROMUSB_GLB_SW_RESET, 0x80001d); |
749 | else { | 911 | else { |
750 | NXWR32(adapter, NETXEN_ROMUSB_GLB_CHIP_CLK_CTRL, 0x3fff); | 912 | NXWR32(adapter, NETXEN_ROMUSB_GLB_CHIP_CLK_CTRL, 0x3fff); |
@@ -755,21 +917,31 @@ netxen_load_firmware(struct netxen_adapter *adapter) | |||
755 | } | 917 | } |
756 | 918 | ||
757 | static int | 919 | static int |
758 | netxen_validate_firmware(struct netxen_adapter *adapter, const char *fwname) | 920 | netxen_validate_firmware(struct netxen_adapter *adapter) |
759 | { | 921 | { |
760 | __le32 val; | 922 | __le32 val; |
761 | u32 ver, min_ver, bios; | 923 | u32 ver, min_ver, bios, min_size; |
762 | struct pci_dev *pdev = adapter->pdev; | 924 | struct pci_dev *pdev = adapter->pdev; |
763 | const struct firmware *fw = adapter->fw; | 925 | const struct firmware *fw = adapter->fw; |
926 | u8 fw_type = adapter->fw_type; | ||
764 | 927 | ||
765 | if (fw->size < NX_FW_MIN_SIZE) | 928 | if (fw_type == NX_UNIFIED_ROMIMAGE) { |
766 | return -EINVAL; | 929 | if (nx_set_product_offs(adapter)) |
930 | return -EINVAL; | ||
931 | |||
932 | min_size = NX_UNI_FW_MIN_SIZE; | ||
933 | } else { | ||
934 | val = cpu_to_le32(*(u32 *)&fw->data[NX_FW_MAGIC_OFFSET]); | ||
935 | if ((__force u32)val != NETXEN_BDINFO_MAGIC) | ||
936 | return -EINVAL; | ||
937 | |||
938 | min_size = NX_FW_MIN_SIZE; | ||
939 | } | ||
767 | 940 | ||
768 | val = cpu_to_le32(*(u32 *)&fw->data[NX_FW_MAGIC_OFFSET]); | 941 | if (fw->size < min_size) |
769 | if ((__force u32)val != NETXEN_BDINFO_MAGIC) | ||
770 | return -EINVAL; | 942 | return -EINVAL; |
771 | 943 | ||
772 | val = cpu_to_le32(*(u32 *)&fw->data[NX_FW_VERSION_OFFSET]); | 944 | val = nx_get_fw_version(adapter); |
773 | 945 | ||
774 | if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) | 946 | if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) |
775 | min_ver = NETXEN_VERSION_CODE(4, 0, 216); | 947 | min_ver = NETXEN_VERSION_CODE(4, 0, 216); |
@@ -781,15 +953,15 @@ netxen_validate_firmware(struct netxen_adapter *adapter, const char *fwname) | |||
781 | if ((_major(ver) > _NETXEN_NIC_LINUX_MAJOR) || (ver < min_ver)) { | 953 | if ((_major(ver) > _NETXEN_NIC_LINUX_MAJOR) || (ver < min_ver)) { |
782 | dev_err(&pdev->dev, | 954 | dev_err(&pdev->dev, |
783 | "%s: firmware version %d.%d.%d unsupported\n", | 955 | "%s: firmware version %d.%d.%d unsupported\n", |
784 | fwname, _major(ver), _minor(ver), _build(ver)); | 956 | fw_name[fw_type], _major(ver), _minor(ver), _build(ver)); |
785 | return -EINVAL; | 957 | return -EINVAL; |
786 | } | 958 | } |
787 | 959 | ||
788 | val = cpu_to_le32(*(u32 *)&fw->data[NX_BIOS_VERSION_OFFSET]); | 960 | val = nx_get_bios_version(adapter); |
789 | netxen_rom_fast_read(adapter, NX_BIOS_VERSION_OFFSET, (int *)&bios); | 961 | netxen_rom_fast_read(adapter, NX_BIOS_VERSION_OFFSET, (int *)&bios); |
790 | if ((__force u32)val != bios) { | 962 | if ((__force u32)val != bios) { |
791 | dev_err(&pdev->dev, "%s: firmware bios is incompatible\n", | 963 | dev_err(&pdev->dev, "%s: firmware bios is incompatible\n", |
792 | fwname); | 964 | fw_name[fw_type]); |
793 | return -EINVAL; | 965 | return -EINVAL; |
794 | } | 966 | } |
795 | 967 | ||
@@ -800,7 +972,7 @@ netxen_validate_firmware(struct netxen_adapter *adapter, const char *fwname) | |||
800 | val = NETXEN_DECODE_VERSION(val); | 972 | val = NETXEN_DECODE_VERSION(val); |
801 | if (val > ver) { | 973 | if (val > ver) { |
802 | dev_info(&pdev->dev, "%s: firmware is older than flash\n", | 974 | dev_info(&pdev->dev, "%s: firmware is older than flash\n", |
803 | fwname); | 975 | fw_name[fw_type]); |
804 | return -EINVAL; | 976 | return -EINVAL; |
805 | } | 977 | } |
806 | 978 | ||
@@ -808,6 +980,41 @@ netxen_validate_firmware(struct netxen_adapter *adapter, const char *fwname) | |||
808 | return 0; | 980 | return 0; |
809 | } | 981 | } |
810 | 982 | ||
983 | static void | ||
984 | nx_get_next_fwtype(struct netxen_adapter *adapter) | ||
985 | { | ||
986 | u8 fw_type; | ||
987 | |||
988 | switch (adapter->fw_type) { | ||
989 | case NX_UNKNOWN_ROMIMAGE: | ||
990 | fw_type = NX_UNIFIED_ROMIMAGE; | ||
991 | break; | ||
992 | |||
993 | case NX_UNIFIED_ROMIMAGE: | ||
994 | if (NX_IS_REVISION_P3P(adapter->ahw.revision_id)) | ||
995 | fw_type = NX_FLASH_ROMIMAGE; | ||
996 | else if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) | ||
997 | fw_type = NX_P2_MN_ROMIMAGE; | ||
998 | else if (netxen_p3_has_mn(adapter)) | ||
999 | fw_type = NX_P3_MN_ROMIMAGE; | ||
1000 | else | ||
1001 | fw_type = NX_P3_CT_ROMIMAGE; | ||
1002 | break; | ||
1003 | |||
1004 | case NX_P3_MN_ROMIMAGE: | ||
1005 | fw_type = NX_P3_CT_ROMIMAGE; | ||
1006 | break; | ||
1007 | |||
1008 | case NX_P2_MN_ROMIMAGE: | ||
1009 | case NX_P3_CT_ROMIMAGE: | ||
1010 | default: | ||
1011 | fw_type = NX_FLASH_ROMIMAGE; | ||
1012 | break; | ||
1013 | } | ||
1014 | |||
1015 | adapter->fw_type = fw_type; | ||
1016 | } | ||
1017 | |||
811 | static int | 1018 | static int |
812 | netxen_p3_has_mn(struct netxen_adapter *adapter) | 1019 | netxen_p3_has_mn(struct netxen_adapter *adapter) |
813 | { | 1020 | { |
@@ -829,49 +1036,29 @@ netxen_p3_has_mn(struct netxen_adapter *adapter) | |||
829 | 1036 | ||
830 | void netxen_request_firmware(struct netxen_adapter *adapter) | 1037 | void netxen_request_firmware(struct netxen_adapter *adapter) |
831 | { | 1038 | { |
832 | u8 fw_type; | ||
833 | struct pci_dev *pdev = adapter->pdev; | 1039 | struct pci_dev *pdev = adapter->pdev; |
834 | int rc = 0; | 1040 | int rc = 0; |
835 | 1041 | ||
836 | if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) { | 1042 | adapter->fw_type = NX_UNKNOWN_ROMIMAGE; |
837 | fw_type = NX_P2_MN_ROMIMAGE; | ||
838 | goto request_fw; | ||
839 | } | ||
840 | |||
841 | fw_type = netxen_p3_has_mn(adapter) ? | ||
842 | NX_P3_MN_ROMIMAGE : NX_P3_CT_ROMIMAGE; | ||
843 | 1043 | ||
844 | request_fw: | 1044 | next: |
845 | rc = request_firmware(&adapter->fw, fw_name[fw_type], &pdev->dev); | 1045 | nx_get_next_fwtype(adapter); |
846 | if (rc != 0) { | ||
847 | if (fw_type == NX_P3_MN_ROMIMAGE) { | ||
848 | msleep(1); | ||
849 | fw_type = NX_P3_CT_ROMIMAGE; | ||
850 | goto request_fw; | ||
851 | } | ||
852 | 1046 | ||
853 | fw_type = NX_FLASH_ROMIMAGE; | 1047 | if (adapter->fw_type == NX_FLASH_ROMIMAGE) { |
854 | adapter->fw = NULL; | 1048 | adapter->fw = NULL; |
855 | goto done; | 1049 | } else { |
856 | } | 1050 | rc = request_firmware(&adapter->fw, |
857 | 1051 | fw_name[adapter->fw_type], &pdev->dev); | |
858 | rc = netxen_validate_firmware(adapter, fw_name[fw_type]); | 1052 | if (rc != 0) |
859 | if (rc != 0) { | 1053 | goto next; |
860 | release_firmware(adapter->fw); | 1054 | |
861 | 1055 | rc = netxen_validate_firmware(adapter); | |
862 | if (fw_type == NX_P3_MN_ROMIMAGE) { | 1056 | if (rc != 0) { |
1057 | release_firmware(adapter->fw); | ||
863 | msleep(1); | 1058 | msleep(1); |
864 | fw_type = NX_P3_CT_ROMIMAGE; | 1059 | goto next; |
865 | goto request_fw; | ||
866 | } | 1060 | } |
867 | |||
868 | fw_type = NX_FLASH_ROMIMAGE; | ||
869 | adapter->fw = NULL; | ||
870 | goto done; | ||
871 | } | 1061 | } |
872 | |||
873 | done: | ||
874 | adapter->fw_type = fw_type; | ||
875 | } | 1062 | } |
876 | 1063 | ||
877 | 1064 | ||
@@ -1506,10 +1693,8 @@ netxen_post_rx_buffers(struct netxen_adapter *adapter, u32 ringid, | |||
1506 | (rds_ring->num_desc - 1))); | 1693 | (rds_ring->num_desc - 1))); |
1507 | netxen_set_msg_ctxid(msg, adapter->portnum); | 1694 | netxen_set_msg_ctxid(msg, adapter->portnum); |
1508 | netxen_set_msg_opcode(msg, NETXEN_RCV_PRODUCER(ringid)); | 1695 | netxen_set_msg_opcode(msg, NETXEN_RCV_PRODUCER(ringid)); |
1509 | read_lock(&adapter->adapter_lock); | 1696 | NXWRIO(adapter, DB_NORMALIZE(adapter, |
1510 | writel(msg, DB_NORMALIZE(adapter, | 1697 | NETXEN_RCV_PRODUCER_OFFSET), msg); |
1511 | NETXEN_RCV_PRODUCER_OFFSET)); | ||
1512 | read_unlock(&adapter->adapter_lock); | ||
1513 | } | 1698 | } |
1514 | } | 1699 | } |
1515 | } | 1700 | } |
diff --git a/drivers/net/netxen/netxen_nic_main.c b/drivers/net/netxen/netxen_nic_main.c index 0b4a56a8c8d5..e5d187fce51b 100644 --- a/drivers/net/netxen/netxen_nic_main.c +++ b/drivers/net/netxen/netxen_nic_main.c | |||
@@ -34,13 +34,18 @@ | |||
34 | #include <net/ip.h> | 34 | #include <net/ip.h> |
35 | #include <linux/ipv6.h> | 35 | #include <linux/ipv6.h> |
36 | #include <linux/inetdevice.h> | 36 | #include <linux/inetdevice.h> |
37 | #include <linux/sysfs.h> | ||
37 | 38 | ||
38 | MODULE_DESCRIPTION("NetXen Multi port (1/10) Gigabit Network Driver"); | 39 | MODULE_DESCRIPTION("QLogic/NetXen (1/10) GbE Converged Ethernet Driver"); |
39 | MODULE_LICENSE("GPL"); | 40 | MODULE_LICENSE("GPL"); |
40 | MODULE_VERSION(NETXEN_NIC_LINUX_VERSIONID); | 41 | MODULE_VERSION(NETXEN_NIC_LINUX_VERSIONID); |
42 | MODULE_FIRMWARE(NX_P2_MN_ROMIMAGE_NAME); | ||
43 | MODULE_FIRMWARE(NX_P3_CT_ROMIMAGE_NAME); | ||
44 | MODULE_FIRMWARE(NX_P3_MN_ROMIMAGE_NAME); | ||
45 | MODULE_FIRMWARE(NX_UNIFIED_ROMIMAGE_NAME); | ||
41 | 46 | ||
42 | char netxen_nic_driver_name[] = "netxen_nic"; | 47 | char netxen_nic_driver_name[] = "netxen_nic"; |
43 | static char netxen_nic_driver_string[] = "NetXen Network Driver version " | 48 | static char netxen_nic_driver_string[] = "QLogic/NetXen Network Driver v" |
44 | NETXEN_NIC_LINUX_VERSIONID; | 49 | NETXEN_NIC_LINUX_VERSIONID; |
45 | 50 | ||
46 | static int port_mode = NETXEN_PORT_MODE_AUTO_NEG; | 51 | static int port_mode = NETXEN_PORT_MODE_AUTO_NEG; |
@@ -52,7 +57,8 @@ static int use_msi = 1; | |||
52 | 57 | ||
53 | static int use_msi_x = 1; | 58 | static int use_msi_x = 1; |
54 | 59 | ||
55 | /* Local functions to NetXen NIC driver */ | 60 | static unsigned long auto_fw_reset = AUTO_FW_RESET_ENABLED; |
61 | |||
56 | static int __devinit netxen_nic_probe(struct pci_dev *pdev, | 62 | static int __devinit netxen_nic_probe(struct pci_dev *pdev, |
57 | const struct pci_device_id *ent); | 63 | const struct pci_device_id *ent); |
58 | static void __devexit netxen_nic_remove(struct pci_dev *pdev); | 64 | static void __devexit netxen_nic_remove(struct pci_dev *pdev); |
@@ -73,6 +79,8 @@ static void netxen_nic_poll_controller(struct net_device *netdev); | |||
73 | 79 | ||
74 | static void netxen_create_sysfs_entries(struct netxen_adapter *adapter); | 80 | static void netxen_create_sysfs_entries(struct netxen_adapter *adapter); |
75 | static void netxen_remove_sysfs_entries(struct netxen_adapter *adapter); | 81 | static void netxen_remove_sysfs_entries(struct netxen_adapter *adapter); |
82 | static void netxen_create_diag_entries(struct netxen_adapter *adapter); | ||
83 | static void netxen_remove_diag_entries(struct netxen_adapter *adapter); | ||
76 | 84 | ||
77 | static int nx_decr_dev_ref_cnt(struct netxen_adapter *adapter); | 85 | static int nx_decr_dev_ref_cnt(struct netxen_adapter *adapter); |
78 | static int netxen_can_start_firmware(struct netxen_adapter *adapter); | 86 | static int netxen_can_start_firmware(struct netxen_adapter *adapter); |
@@ -437,6 +445,7 @@ netxen_read_mac_addr(struct netxen_adapter *adapter) | |||
437 | netdev->dev_addr[i] = *(p + 5 - i); | 445 | netdev->dev_addr[i] = *(p + 5 - i); |
438 | 446 | ||
439 | memcpy(netdev->perm_addr, netdev->dev_addr, netdev->addr_len); | 447 | memcpy(netdev->perm_addr, netdev->dev_addr, netdev->addr_len); |
448 | memcpy(adapter->mac_addr, netdev->dev_addr, netdev->addr_len); | ||
440 | 449 | ||
441 | /* set station address */ | 450 | /* set station address */ |
442 | 451 | ||
@@ -459,6 +468,7 @@ int netxen_nic_set_mac(struct net_device *netdev, void *p) | |||
459 | netxen_napi_disable(adapter); | 468 | netxen_napi_disable(adapter); |
460 | } | 469 | } |
461 | 470 | ||
471 | memcpy(adapter->mac_addr, addr->sa_data, netdev->addr_len); | ||
462 | memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len); | 472 | memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len); |
463 | adapter->macaddr_set(adapter, addr->sa_data); | 473 | adapter->macaddr_set(adapter, addr->sa_data); |
464 | 474 | ||
@@ -607,14 +617,12 @@ netxen_setup_pci_map(struct netxen_adapter *adapter) | |||
607 | * Set the CRB window to invalid. If any register in window 0 is | 617 | * Set the CRB window to invalid. If any register in window 0 is |
608 | * accessed it should set the window to 0 and then reset it to 1. | 618 | * accessed it should set the window to 0 and then reset it to 1. |
609 | */ | 619 | */ |
610 | adapter->curr_window = 255; | 620 | adapter->ahw.crb_win = -1; |
611 | adapter->ahw.qdr_sn_window = -1; | 621 | adapter->ahw.ocm_win = -1; |
612 | adapter->ahw.ddr_mn_window = -1; | ||
613 | 622 | ||
614 | /* remap phys address */ | 623 | /* remap phys address */ |
615 | mem_base = pci_resource_start(pdev, 0); /* 0 is for BAR 0 */ | 624 | mem_base = pci_resource_start(pdev, 0); /* 0 is for BAR 0 */ |
616 | mem_len = pci_resource_len(pdev, 0); | 625 | mem_len = pci_resource_len(pdev, 0); |
617 | pci_len0 = 0; | ||
618 | 626 | ||
619 | /* 128 Meg of memory */ | 627 | /* 128 Meg of memory */ |
620 | if (mem_len == NETXEN_PCI_128MB_SIZE) { | 628 | if (mem_len == NETXEN_PCI_128MB_SIZE) { |
@@ -623,6 +631,7 @@ netxen_setup_pci_map(struct netxen_adapter *adapter) | |||
623 | SECOND_PAGE_GROUP_SIZE); | 631 | SECOND_PAGE_GROUP_SIZE); |
624 | mem_ptr2 = ioremap(mem_base + THIRD_PAGE_GROUP_START, | 632 | mem_ptr2 = ioremap(mem_base + THIRD_PAGE_GROUP_START, |
625 | THIRD_PAGE_GROUP_SIZE); | 633 | THIRD_PAGE_GROUP_SIZE); |
634 | pci_len0 = FIRST_PAGE_GROUP_SIZE; | ||
626 | } else if (mem_len == NETXEN_PCI_32MB_SIZE) { | 635 | } else if (mem_len == NETXEN_PCI_32MB_SIZE) { |
627 | mem_ptr1 = ioremap(mem_base, SECOND_PAGE_GROUP_SIZE); | 636 | mem_ptr1 = ioremap(mem_base, SECOND_PAGE_GROUP_SIZE); |
628 | mem_ptr2 = ioremap(mem_base + THIRD_PAGE_GROUP_START - | 637 | mem_ptr2 = ioremap(mem_base + THIRD_PAGE_GROUP_START - |
@@ -635,19 +644,6 @@ netxen_setup_pci_map(struct netxen_adapter *adapter) | |||
635 | return -EIO; | 644 | return -EIO; |
636 | } | 645 | } |
637 | pci_len0 = mem_len; | 646 | pci_len0 = mem_len; |
638 | |||
639 | adapter->ahw.ddr_mn_window = 0; | ||
640 | adapter->ahw.qdr_sn_window = 0; | ||
641 | |||
642 | adapter->ahw.mn_win_crb = NETXEN_PCI_CRBSPACE + | ||
643 | 0x100000 + PCIX_MN_WINDOW + (pci_func * 0x20); | ||
644 | adapter->ahw.ms_win_crb = NETXEN_PCI_CRBSPACE + | ||
645 | 0x100000 + PCIX_SN_WINDOW; | ||
646 | if (pci_func < 4) | ||
647 | adapter->ahw.ms_win_crb += (pci_func * 0x20); | ||
648 | else | ||
649 | adapter->ahw.ms_win_crb += | ||
650 | 0xA0 + ((pci_func - 4) * 0x10); | ||
651 | } else { | 647 | } else { |
652 | return -EIO; | 648 | return -EIO; |
653 | } | 649 | } |
@@ -661,6 +657,15 @@ netxen_setup_pci_map(struct netxen_adapter *adapter) | |||
661 | adapter->ahw.pci_base1 = mem_ptr1; | 657 | adapter->ahw.pci_base1 = mem_ptr1; |
662 | adapter->ahw.pci_base2 = mem_ptr2; | 658 | adapter->ahw.pci_base2 = mem_ptr2; |
663 | 659 | ||
660 | if (NX_IS_REVISION_P3P(adapter->ahw.revision_id)) { | ||
661 | adapter->ahw.ocm_win_crb = netxen_get_ioaddr(adapter, | ||
662 | NETXEN_PCIX_PS_REG(PCIX_OCM_WINDOW_REG(pci_func))); | ||
663 | |||
664 | } else if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) { | ||
665 | adapter->ahw.ocm_win_crb = netxen_get_ioaddr(adapter, | ||
666 | NETXEN_PCIX_PS_REG(PCIE_MN_WINDOW_REG(pci_func))); | ||
667 | } | ||
668 | |||
664 | if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) | 669 | if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) |
665 | goto skip_doorbell; | 670 | goto skip_doorbell; |
666 | 671 | ||
@@ -725,7 +730,8 @@ netxen_check_options(struct netxen_adapter *adapter) | |||
725 | if (adapter->portnum == 0) { | 730 | if (adapter->portnum == 0) { |
726 | get_brd_name_by_type(adapter->ahw.board_type, brd_name); | 731 | get_brd_name_by_type(adapter->ahw.board_type, brd_name); |
727 | 732 | ||
728 | printk(KERN_INFO "NetXen %s Board S/N %s Chip rev 0x%x\n", | 733 | pr_info("%s: %s Board S/N %s Chip rev 0x%x\n", |
734 | module_name(THIS_MODULE), | ||
729 | brd_name, serial_num, adapter->ahw.revision_id); | 735 | brd_name, serial_num, adapter->ahw.revision_id); |
730 | } | 736 | } |
731 | 737 | ||
@@ -813,11 +819,11 @@ netxen_start_firmware(struct netxen_adapter *adapter) | |||
813 | if (err < 0) | 819 | if (err < 0) |
814 | goto err_out; | 820 | goto err_out; |
815 | if (err == 0) | 821 | if (err == 0) |
816 | goto ready; | 822 | goto wait_init; |
817 | 823 | ||
818 | if (first_boot != 0x55555555) { | 824 | if (first_boot != 0x55555555) { |
819 | NXWR32(adapter, CRB_CMDPEG_STATE, 0); | 825 | NXWR32(adapter, CRB_CMDPEG_STATE, 0); |
820 | netxen_pinit_from_rom(adapter, 0); | 826 | netxen_pinit_from_rom(adapter); |
821 | msleep(1); | 827 | msleep(1); |
822 | } | 828 | } |
823 | 829 | ||
@@ -856,9 +862,6 @@ netxen_start_firmware(struct netxen_adapter *adapter) | |||
856 | | (_NETXEN_NIC_LINUX_SUBVERSION); | 862 | | (_NETXEN_NIC_LINUX_SUBVERSION); |
857 | NXWR32(adapter, CRB_DRIVER_VERSION, val); | 863 | NXWR32(adapter, CRB_DRIVER_VERSION, val); |
858 | 864 | ||
859 | ready: | ||
860 | NXWR32(adapter, NX_CRB_DEV_STATE, NX_DEV_READY); | ||
861 | |||
862 | wait_init: | 865 | wait_init: |
863 | /* Handshake with the card before we register the devices. */ | 866 | /* Handshake with the card before we register the devices. */ |
864 | err = netxen_phantom_init(adapter, NETXEN_NIC_PEG_TUNE); | 867 | err = netxen_phantom_init(adapter, NETXEN_NIC_PEG_TUNE); |
@@ -867,6 +870,8 @@ wait_init: | |||
867 | goto err_out; | 870 | goto err_out; |
868 | } | 871 | } |
869 | 872 | ||
873 | NXWR32(adapter, NX_CRB_DEV_STATE, NX_DEV_READY); | ||
874 | |||
870 | nx_update_dma_mask(adapter); | 875 | nx_update_dma_mask(adapter); |
871 | 876 | ||
872 | netxen_check_options(adapter); | 877 | netxen_check_options(adapter); |
@@ -956,7 +961,7 @@ netxen_nic_up(struct netxen_adapter *adapter, struct net_device *netdev) | |||
956 | return err; | 961 | return err; |
957 | } | 962 | } |
958 | if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) | 963 | if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) |
959 | adapter->macaddr_set(adapter, netdev->dev_addr); | 964 | adapter->macaddr_set(adapter, adapter->mac_addr); |
960 | 965 | ||
961 | adapter->set_multi(netdev); | 966 | adapter->set_multi(netdev); |
962 | adapter->set_mtu(adapter, netdev->mtu); | 967 | adapter->set_mtu(adapter, netdev->mtu); |
@@ -1207,16 +1212,10 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
1207 | int pci_func_id = PCI_FUNC(pdev->devfn); | 1212 | int pci_func_id = PCI_FUNC(pdev->devfn); |
1208 | uint8_t revision_id; | 1213 | uint8_t revision_id; |
1209 | 1214 | ||
1210 | if (pdev->class != 0x020000) { | ||
1211 | printk(KERN_DEBUG "NetXen function %d, class %x will not " | ||
1212 | "be enabled.\n",pci_func_id, pdev->class); | ||
1213 | return -ENODEV; | ||
1214 | } | ||
1215 | |||
1216 | if (pdev->revision >= NX_P3_A0 && pdev->revision < NX_P3_B1) { | 1215 | if (pdev->revision >= NX_P3_A0 && pdev->revision < NX_P3_B1) { |
1217 | printk(KERN_WARNING "NetXen chip revisions between 0x%x-0x%x" | 1216 | pr_warning("%s: chip revisions between 0x%x-0x%x" |
1218 | "will not be enabled.\n", | 1217 | "will not be enabled.\n", |
1219 | NX_P3_A0, NX_P3_B1); | 1218 | module_name(THIS_MODULE), NX_P3_A0, NX_P3_B1); |
1220 | return -ENODEV; | 1219 | return -ENODEV; |
1221 | } | 1220 | } |
1222 | 1221 | ||
@@ -1250,7 +1249,9 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
1250 | revision_id = pdev->revision; | 1249 | revision_id = pdev->revision; |
1251 | adapter->ahw.revision_id = revision_id; | 1250 | adapter->ahw.revision_id = revision_id; |
1252 | 1251 | ||
1253 | rwlock_init(&adapter->adapter_lock); | 1252 | rwlock_init(&adapter->ahw.crb_lock); |
1253 | spin_lock_init(&adapter->ahw.mem_lock); | ||
1254 | |||
1254 | spin_lock_init(&adapter->tx_clean_lock); | 1255 | spin_lock_init(&adapter->tx_clean_lock); |
1255 | INIT_LIST_HEAD(&adapter->mac_list); | 1256 | INIT_LIST_HEAD(&adapter->mac_list); |
1256 | 1257 | ||
@@ -1280,7 +1281,7 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
1280 | 1281 | ||
1281 | err = netxen_start_firmware(adapter); | 1282 | err = netxen_start_firmware(adapter); |
1282 | if (err) | 1283 | if (err) |
1283 | goto err_out_iounmap; | 1284 | goto err_out_decr_ref; |
1284 | 1285 | ||
1285 | /* | 1286 | /* |
1286 | * See if the firmware gave us a virtual-physical port mapping. | 1287 | * See if the firmware gave us a virtual-physical port mapping. |
@@ -1315,6 +1316,8 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
1315 | break; | 1316 | break; |
1316 | } | 1317 | } |
1317 | 1318 | ||
1319 | netxen_create_diag_entries(adapter); | ||
1320 | |||
1318 | return 0; | 1321 | return 0; |
1319 | 1322 | ||
1320 | err_out_disable_msi: | 1323 | err_out_disable_msi: |
@@ -1322,6 +1325,7 @@ err_out_disable_msi: | |||
1322 | 1325 | ||
1323 | netxen_free_dummy_dma(adapter); | 1326 | netxen_free_dummy_dma(adapter); |
1324 | 1327 | ||
1328 | err_out_decr_ref: | ||
1325 | nx_decr_dev_ref_cnt(adapter); | 1329 | nx_decr_dev_ref_cnt(adapter); |
1326 | 1330 | ||
1327 | err_out_iounmap: | 1331 | err_out_iounmap: |
@@ -1367,6 +1371,8 @@ static void __devexit netxen_nic_remove(struct pci_dev *pdev) | |||
1367 | 1371 | ||
1368 | netxen_teardown_intr(adapter); | 1372 | netxen_teardown_intr(adapter); |
1369 | 1373 | ||
1374 | netxen_remove_diag_entries(adapter); | ||
1375 | |||
1370 | netxen_cleanup_pci_map(adapter); | 1376 | netxen_cleanup_pci_map(adapter); |
1371 | 1377 | ||
1372 | netxen_release_firmware(adapter); | 1378 | netxen_release_firmware(adapter); |
@@ -1447,7 +1453,8 @@ netxen_nic_resume(struct pci_dev *pdev) | |||
1447 | if (err) | 1453 | if (err) |
1448 | return err; | 1454 | return err; |
1449 | 1455 | ||
1450 | adapter->curr_window = 255; | 1456 | adapter->ahw.crb_win = -1; |
1457 | adapter->ahw.ocm_win = -1; | ||
1451 | 1458 | ||
1452 | err = netxen_start_firmware(adapter); | 1459 | err = netxen_start_firmware(adapter); |
1453 | if (err) { | 1460 | if (err) { |
@@ -1925,7 +1932,7 @@ request_reset: | |||
1925 | struct net_device_stats *netxen_nic_get_stats(struct net_device *netdev) | 1932 | struct net_device_stats *netxen_nic_get_stats(struct net_device *netdev) |
1926 | { | 1933 | { |
1927 | struct netxen_adapter *adapter = netdev_priv(netdev); | 1934 | struct netxen_adapter *adapter = netdev_priv(netdev); |
1928 | struct net_device_stats *stats = &adapter->net_stats; | 1935 | struct net_device_stats *stats = &netdev->stats; |
1929 | 1936 | ||
1930 | memset(stats, 0, sizeof(*stats)); | 1937 | memset(stats, 0, sizeof(*stats)); |
1931 | 1938 | ||
@@ -2182,14 +2189,13 @@ netxen_fwinit_work(struct work_struct *work) | |||
2182 | netxen_fwinit_work, 2 * FW_POLL_DELAY); | 2189 | netxen_fwinit_work, 2 * FW_POLL_DELAY); |
2183 | return; | 2190 | return; |
2184 | } | 2191 | } |
2185 | break; | ||
2186 | 2192 | ||
2187 | case NX_DEV_FAILED: | 2193 | case NX_DEV_FAILED: |
2188 | default: | 2194 | default: |
2195 | nx_incr_dev_ref_cnt(adapter); | ||
2189 | break; | 2196 | break; |
2190 | } | 2197 | } |
2191 | 2198 | ||
2192 | nx_incr_dev_ref_cnt(adapter); | ||
2193 | clear_bit(__NX_RESETTING, &adapter->state); | 2199 | clear_bit(__NX_RESETTING, &adapter->state); |
2194 | } | 2200 | } |
2195 | 2201 | ||
@@ -2211,18 +2217,23 @@ netxen_detach_work(struct work_struct *work) | |||
2211 | 2217 | ||
2212 | status = NXRD32(adapter, NETXEN_PEG_HALT_STATUS1); | 2218 | status = NXRD32(adapter, NETXEN_PEG_HALT_STATUS1); |
2213 | 2219 | ||
2214 | ref_cnt = nx_decr_dev_ref_cnt(adapter); | ||
2215 | |||
2216 | if (status & NX_RCODE_FATAL_ERROR) | 2220 | if (status & NX_RCODE_FATAL_ERROR) |
2217 | return; | 2221 | goto err_ret; |
2218 | 2222 | ||
2219 | if (adapter->temp == NX_TEMP_PANIC) | 2223 | if (adapter->temp == NX_TEMP_PANIC) |
2220 | return; | 2224 | goto err_ret; |
2225 | |||
2226 | ref_cnt = nx_decr_dev_ref_cnt(adapter); | ||
2221 | 2227 | ||
2222 | delay = (ref_cnt == 0) ? 0 : (2 * FW_POLL_DELAY); | 2228 | delay = (ref_cnt == 0) ? 0 : (2 * FW_POLL_DELAY); |
2223 | 2229 | ||
2224 | adapter->fw_wait_cnt = 0; | 2230 | adapter->fw_wait_cnt = 0; |
2225 | netxen_schedule_work(adapter, netxen_fwinit_work, delay); | 2231 | netxen_schedule_work(adapter, netxen_fwinit_work, delay); |
2232 | |||
2233 | return; | ||
2234 | |||
2235 | err_ret: | ||
2236 | clear_bit(__NX_RESETTING, &adapter->state); | ||
2226 | } | 2237 | } |
2227 | 2238 | ||
2228 | static int | 2239 | static int |
@@ -2261,7 +2272,8 @@ netxen_check_health(struct netxen_adapter *adapter) | |||
2261 | dev_info(&netdev->dev, "firmware hang detected\n"); | 2272 | dev_info(&netdev->dev, "firmware hang detected\n"); |
2262 | 2273 | ||
2263 | detach: | 2274 | detach: |
2264 | if (!test_and_set_bit(__NX_RESETTING, &adapter->state)) | 2275 | if ((auto_fw_reset == AUTO_FW_RESET_ENABLED) && |
2276 | !test_and_set_bit(__NX_RESETTING, &adapter->state)) | ||
2265 | netxen_schedule_work(adapter, netxen_detach_work, 0); | 2277 | netxen_schedule_work(adapter, netxen_detach_work, 0); |
2266 | return 1; | 2278 | return 1; |
2267 | } | 2279 | } |
@@ -2339,6 +2351,197 @@ static struct device_attribute dev_attr_bridged_mode = { | |||
2339 | .store = netxen_store_bridged_mode, | 2351 | .store = netxen_store_bridged_mode, |
2340 | }; | 2352 | }; |
2341 | 2353 | ||
2354 | static ssize_t | ||
2355 | netxen_store_diag_mode(struct device *dev, | ||
2356 | struct device_attribute *attr, const char *buf, size_t len) | ||
2357 | { | ||
2358 | struct netxen_adapter *adapter = dev_get_drvdata(dev); | ||
2359 | unsigned long new; | ||
2360 | |||
2361 | if (strict_strtoul(buf, 2, &new)) | ||
2362 | return -EINVAL; | ||
2363 | |||
2364 | if (!!new != !!(adapter->flags & NETXEN_NIC_DIAG_ENABLED)) | ||
2365 | adapter->flags ^= NETXEN_NIC_DIAG_ENABLED; | ||
2366 | |||
2367 | return len; | ||
2368 | } | ||
2369 | |||
2370 | static ssize_t | ||
2371 | netxen_show_diag_mode(struct device *dev, | ||
2372 | struct device_attribute *attr, char *buf) | ||
2373 | { | ||
2374 | struct netxen_adapter *adapter = dev_get_drvdata(dev); | ||
2375 | |||
2376 | return sprintf(buf, "%d\n", | ||
2377 | !!(adapter->flags & NETXEN_NIC_DIAG_ENABLED)); | ||
2378 | } | ||
2379 | |||
2380 | static struct device_attribute dev_attr_diag_mode = { | ||
2381 | .attr = {.name = "diag_mode", .mode = (S_IRUGO | S_IWUSR)}, | ||
2382 | .show = netxen_show_diag_mode, | ||
2383 | .store = netxen_store_diag_mode, | ||
2384 | }; | ||
2385 | |||
2386 | static int | ||
2387 | netxen_sysfs_validate_crb(struct netxen_adapter *adapter, | ||
2388 | loff_t offset, size_t size) | ||
2389 | { | ||
2390 | if (!(adapter->flags & NETXEN_NIC_DIAG_ENABLED)) | ||
2391 | return -EIO; | ||
2392 | |||
2393 | if ((size != 4) || (offset & 0x3)) | ||
2394 | return -EINVAL; | ||
2395 | |||
2396 | if (offset < NETXEN_PCI_CRBSPACE) | ||
2397 | return -EINVAL; | ||
2398 | |||
2399 | return 0; | ||
2400 | } | ||
2401 | |||
2402 | static ssize_t | ||
2403 | netxen_sysfs_read_crb(struct kobject *kobj, struct bin_attribute *attr, | ||
2404 | char *buf, loff_t offset, size_t size) | ||
2405 | { | ||
2406 | struct device *dev = container_of(kobj, struct device, kobj); | ||
2407 | struct netxen_adapter *adapter = dev_get_drvdata(dev); | ||
2408 | u32 data; | ||
2409 | int ret; | ||
2410 | |||
2411 | ret = netxen_sysfs_validate_crb(adapter, offset, size); | ||
2412 | if (ret != 0) | ||
2413 | return ret; | ||
2414 | |||
2415 | data = NXRD32(adapter, offset); | ||
2416 | memcpy(buf, &data, size); | ||
2417 | return size; | ||
2418 | } | ||
2419 | |||
2420 | static ssize_t | ||
2421 | netxen_sysfs_write_crb(struct kobject *kobj, struct bin_attribute *attr, | ||
2422 | char *buf, loff_t offset, size_t size) | ||
2423 | { | ||
2424 | struct device *dev = container_of(kobj, struct device, kobj); | ||
2425 | struct netxen_adapter *adapter = dev_get_drvdata(dev); | ||
2426 | u32 data; | ||
2427 | int ret; | ||
2428 | |||
2429 | ret = netxen_sysfs_validate_crb(adapter, offset, size); | ||
2430 | if (ret != 0) | ||
2431 | return ret; | ||
2432 | |||
2433 | memcpy(&data, buf, size); | ||
2434 | NXWR32(adapter, offset, data); | ||
2435 | return size; | ||
2436 | } | ||
2437 | |||
2438 | static int | ||
2439 | netxen_sysfs_validate_mem(struct netxen_adapter *adapter, | ||
2440 | loff_t offset, size_t size) | ||
2441 | { | ||
2442 | if (!(adapter->flags & NETXEN_NIC_DIAG_ENABLED)) | ||
2443 | return -EIO; | ||
2444 | |||
2445 | if ((size != 8) || (offset & 0x7)) | ||
2446 | return -EIO; | ||
2447 | |||
2448 | return 0; | ||
2449 | } | ||
2450 | |||
2451 | static ssize_t | ||
2452 | netxen_sysfs_read_mem(struct kobject *kobj, struct bin_attribute *attr, | ||
2453 | char *buf, loff_t offset, size_t size) | ||
2454 | { | ||
2455 | struct device *dev = container_of(kobj, struct device, kobj); | ||
2456 | struct netxen_adapter *adapter = dev_get_drvdata(dev); | ||
2457 | u64 data; | ||
2458 | int ret; | ||
2459 | |||
2460 | ret = netxen_sysfs_validate_mem(adapter, offset, size); | ||
2461 | if (ret != 0) | ||
2462 | return ret; | ||
2463 | |||
2464 | if (adapter->pci_mem_read(adapter, offset, &data)) | ||
2465 | return -EIO; | ||
2466 | |||
2467 | memcpy(buf, &data, size); | ||
2468 | |||
2469 | return size; | ||
2470 | } | ||
2471 | |||
2472 | ssize_t netxen_sysfs_write_mem(struct kobject *kobj, | ||
2473 | struct bin_attribute *attr, char *buf, | ||
2474 | loff_t offset, size_t size) | ||
2475 | { | ||
2476 | struct device *dev = container_of(kobj, struct device, kobj); | ||
2477 | struct netxen_adapter *adapter = dev_get_drvdata(dev); | ||
2478 | u64 data; | ||
2479 | int ret; | ||
2480 | |||
2481 | ret = netxen_sysfs_validate_mem(adapter, offset, size); | ||
2482 | if (ret != 0) | ||
2483 | return ret; | ||
2484 | |||
2485 | memcpy(&data, buf, size); | ||
2486 | |||
2487 | if (adapter->pci_mem_write(adapter, offset, data)) | ||
2488 | return -EIO; | ||
2489 | |||
2490 | return size; | ||
2491 | } | ||
2492 | |||
2493 | |||
2494 | static struct bin_attribute bin_attr_crb = { | ||
2495 | .attr = {.name = "crb", .mode = (S_IRUGO | S_IWUSR)}, | ||
2496 | .size = 0, | ||
2497 | .read = netxen_sysfs_read_crb, | ||
2498 | .write = netxen_sysfs_write_crb, | ||
2499 | }; | ||
2500 | |||
2501 | static struct bin_attribute bin_attr_mem = { | ||
2502 | .attr = {.name = "mem", .mode = (S_IRUGO | S_IWUSR)}, | ||
2503 | .size = 0, | ||
2504 | .read = netxen_sysfs_read_mem, | ||
2505 | .write = netxen_sysfs_write_mem, | ||
2506 | }; | ||
2507 | |||
2508 | #ifdef CONFIG_MODULES | ||
2509 | static ssize_t | ||
2510 | netxen_store_auto_fw_reset(struct module_attribute *mattr, | ||
2511 | struct module *mod, const char *buf, size_t count) | ||
2512 | |||
2513 | { | ||
2514 | unsigned long new; | ||
2515 | |||
2516 | if (strict_strtoul(buf, 16, &new)) | ||
2517 | return -EINVAL; | ||
2518 | |||
2519 | if ((new == AUTO_FW_RESET_ENABLED) || (new == AUTO_FW_RESET_DISABLED)) { | ||
2520 | auto_fw_reset = new; | ||
2521 | return count; | ||
2522 | } | ||
2523 | |||
2524 | return -EINVAL; | ||
2525 | } | ||
2526 | |||
2527 | static ssize_t | ||
2528 | netxen_show_auto_fw_reset(struct module_attribute *mattr, | ||
2529 | struct module *mod, char *buf) | ||
2530 | |||
2531 | { | ||
2532 | if (auto_fw_reset == AUTO_FW_RESET_ENABLED) | ||
2533 | return sprintf(buf, "enabled\n"); | ||
2534 | else | ||
2535 | return sprintf(buf, "disabled\n"); | ||
2536 | } | ||
2537 | |||
2538 | static struct module_attribute mod_attr_fw_reset = { | ||
2539 | .attr = {.name = "auto_fw_reset", .mode = (S_IRUGO | S_IWUSR)}, | ||
2540 | .show = netxen_show_auto_fw_reset, | ||
2541 | .store = netxen_store_auto_fw_reset, | ||
2542 | }; | ||
2543 | #endif | ||
2544 | |||
2342 | static void | 2545 | static void |
2343 | netxen_create_sysfs_entries(struct netxen_adapter *adapter) | 2546 | netxen_create_sysfs_entries(struct netxen_adapter *adapter) |
2344 | { | 2547 | { |
@@ -2364,6 +2567,33 @@ netxen_remove_sysfs_entries(struct netxen_adapter *adapter) | |||
2364 | device_remove_file(dev, &dev_attr_bridged_mode); | 2567 | device_remove_file(dev, &dev_attr_bridged_mode); |
2365 | } | 2568 | } |
2366 | 2569 | ||
2570 | static void | ||
2571 | netxen_create_diag_entries(struct netxen_adapter *adapter) | ||
2572 | { | ||
2573 | struct pci_dev *pdev = adapter->pdev; | ||
2574 | struct device *dev; | ||
2575 | |||
2576 | dev = &pdev->dev; | ||
2577 | if (device_create_file(dev, &dev_attr_diag_mode)) | ||
2578 | dev_info(dev, "failed to create diag_mode sysfs entry\n"); | ||
2579 | if (device_create_bin_file(dev, &bin_attr_crb)) | ||
2580 | dev_info(dev, "failed to create crb sysfs entry\n"); | ||
2581 | if (device_create_bin_file(dev, &bin_attr_mem)) | ||
2582 | dev_info(dev, "failed to create mem sysfs entry\n"); | ||
2583 | } | ||
2584 | |||
2585 | |||
2586 | static void | ||
2587 | netxen_remove_diag_entries(struct netxen_adapter *adapter) | ||
2588 | { | ||
2589 | struct pci_dev *pdev = adapter->pdev; | ||
2590 | struct device *dev = &pdev->dev; | ||
2591 | |||
2592 | device_remove_file(dev, &dev_attr_diag_mode); | ||
2593 | device_remove_bin_file(dev, &bin_attr_crb); | ||
2594 | device_remove_bin_file(dev, &bin_attr_mem); | ||
2595 | } | ||
2596 | |||
2367 | #ifdef CONFIG_INET | 2597 | #ifdef CONFIG_INET |
2368 | 2598 | ||
2369 | #define is_netxen_netdev(dev) (dev->netdev_ops == &netxen_netdev_ops) | 2599 | #define is_netxen_netdev(dev) (dev->netdev_ops == &netxen_netdev_ops) |
@@ -2516,6 +2746,10 @@ static struct pci_driver netxen_driver = { | |||
2516 | 2746 | ||
2517 | static int __init netxen_init_module(void) | 2747 | static int __init netxen_init_module(void) |
2518 | { | 2748 | { |
2749 | #ifdef CONFIG_MODULES | ||
2750 | struct module *mod = THIS_MODULE; | ||
2751 | #endif | ||
2752 | |||
2519 | printk(KERN_INFO "%s\n", netxen_nic_driver_string); | 2753 | printk(KERN_INFO "%s\n", netxen_nic_driver_string); |
2520 | 2754 | ||
2521 | #ifdef CONFIG_INET | 2755 | #ifdef CONFIG_INET |
@@ -2523,6 +2757,12 @@ static int __init netxen_init_module(void) | |||
2523 | register_inetaddr_notifier(&netxen_inetaddr_cb); | 2757 | register_inetaddr_notifier(&netxen_inetaddr_cb); |
2524 | #endif | 2758 | #endif |
2525 | 2759 | ||
2760 | #ifdef CONFIG_MODULES | ||
2761 | if (sysfs_create_file(&mod->mkobj.kobj, &mod_attr_fw_reset.attr)) | ||
2762 | printk(KERN_ERR "%s: Failed to create auto_fw_reset " | ||
2763 | "sysfs entry.", netxen_nic_driver_name); | ||
2764 | #endif | ||
2765 | |||
2526 | return pci_register_driver(&netxen_driver); | 2766 | return pci_register_driver(&netxen_driver); |
2527 | } | 2767 | } |
2528 | 2768 | ||
@@ -2530,6 +2770,12 @@ module_init(netxen_init_module); | |||
2530 | 2770 | ||
2531 | static void __exit netxen_exit_module(void) | 2771 | static void __exit netxen_exit_module(void) |
2532 | { | 2772 | { |
2773 | #ifdef CONFIG_MODULES | ||
2774 | struct module *mod = THIS_MODULE; | ||
2775 | |||
2776 | sysfs_remove_file(&mod->mkobj.kobj, &mod_attr_fw_reset.attr); | ||
2777 | #endif | ||
2778 | |||
2533 | pci_unregister_driver(&netxen_driver); | 2779 | pci_unregister_driver(&netxen_driver); |
2534 | 2780 | ||
2535 | #ifdef CONFIG_INET | 2781 | #ifdef CONFIG_INET |