netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH NEXT 0/6] nexten: fixes and enhancements
@ 2009-09-06  3:43 Dhananjay Phadke
  2009-09-06  3:43 ` [PATCH NEXT 1/6] netxen: handle firmware load errors Dhananjay Phadke
                   ` (6 more replies)
  0 siblings, 7 replies; 8+ messages in thread
From: Dhananjay Phadke @ 2009-09-06  3:43 UTC (permalink / raw)
  To: davem; +Cc: netdev

Series of 6 driver enhancements / fixes, please apply to net-next-2.6.

Thanks,
Dhananjay



^ permalink raw reply	[flat|nested] 8+ messages in thread

* [PATCH NEXT 1/6] netxen: handle firmware load errors
  2009-09-06  3:43 [PATCH NEXT 0/6] nexten: fixes and enhancements Dhananjay Phadke
@ 2009-09-06  3:43 ` Dhananjay Phadke
  2009-09-06  3:43 ` [PATCH NEXT 2/6] netxen: firmware hang detection Dhananjay Phadke
                   ` (5 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: Dhananjay Phadke @ 2009-09-06  3:43 UTC (permalink / raw)
  To: davem; +Cc: netdev

Unwind allocations and release file firmware when
when firmware load fails.

Signed-off-by: Dhananjay Phadke <dhananjay@netxen.com>
---
 drivers/net/netxen/netxen_nic_hw.c   |    3 +++
 drivers/net/netxen/netxen_nic_init.c |    1 +
 drivers/net/netxen/netxen_nic_main.c |   20 ++++++++++++++++----
 3 files changed, 20 insertions(+), 4 deletions(-)

diff --git a/drivers/net/netxen/netxen_nic_hw.c b/drivers/net/netxen/netxen_nic_hw.c
index db510ce..d0ac8fa 100644
--- a/drivers/net/netxen/netxen_nic_hw.c
+++ b/drivers/net/netxen/netxen_nic_hw.c
@@ -566,6 +566,9 @@ netxen_send_cmd_descs(struct netxen_adapter *adapter,
 
 	i = 0;
 
+	if (adapter->is_up != NETXEN_ADAPTER_UP_MAGIC)
+		return -EIO;
+
 	tx_ring = adapter->tx_ring;
 	__netif_tx_lock_bh(tx_ring->txq);
 
diff --git a/drivers/net/netxen/netxen_nic_init.c b/drivers/net/netxen/netxen_nic_init.c
index 04e36f2..534994d 100644
--- a/drivers/net/netxen/netxen_nic_init.c
+++ b/drivers/net/netxen/netxen_nic_init.c
@@ -905,6 +905,7 @@ netxen_release_firmware(struct netxen_adapter *adapter)
 {
 	if (adapter->fw)
 		release_firmware(adapter->fw);
+	adapter->fw = NULL;
 }
 
 int netxen_init_dummy_dma(struct netxen_adapter *adapter)
diff --git a/drivers/net/netxen/netxen_nic_main.c b/drivers/net/netxen/netxen_nic_main.c
index 41b2967..47aede6 100644
--- a/drivers/net/netxen/netxen_nic_main.c
+++ b/drivers/net/netxen/netxen_nic_main.c
@@ -757,7 +757,7 @@ netxen_start_firmware(struct netxen_adapter *adapter, int request_fw)
 
 	err = netxen_need_fw_reset(adapter);
 	if (err < 0)
-		return err;
+		goto err_out;
 	if (err == 0)
 		goto wait_init;
 
@@ -771,7 +771,9 @@ netxen_start_firmware(struct netxen_adapter *adapter, int request_fw)
 	if (NX_IS_REVISION_P3(adapter->ahw.revision_id))
 		netxen_set_port_mode(adapter);
 
-	netxen_load_firmware(adapter);
+	err = netxen_load_firmware(adapter);
+	if (err)
+		goto err_out;
 
 	if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) {
 
@@ -785,7 +787,7 @@ netxen_start_firmware(struct netxen_adapter *adapter, int request_fw)
 
 	err = netxen_init_dummy_dma(adapter);
 	if (err)
-		return err;
+		goto err_out;
 
 	/*
 	 * Tell the hardware our version number.
@@ -800,7 +802,7 @@ wait_init:
 	err = netxen_phantom_init(adapter, NETXEN_NIC_PEG_TUNE);
 	if (err) {
 		netxen_free_dummy_dma(adapter);
-		return err;
+		goto err_out;
 	}
 
 	nx_update_dma_mask(adapter);
@@ -808,6 +810,10 @@ wait_init:
 	netxen_nic_get_firmware_info(adapter);
 
 	return 0;
+
+err_out:
+	netxen_release_firmware(adapter);
+	return err;
 }
 
 static int
@@ -876,6 +882,9 @@ netxen_nic_up(struct netxen_adapter *adapter, struct net_device *netdev)
 {
 	int err;
 
+	if (adapter->is_up != NETXEN_ADAPTER_UP_MAGIC)
+		return -EIO;
+
 	err = adapter->init_port(adapter, adapter->physical_port);
 	if (err) {
 		printk(KERN_ERR "%s: Failed to initialize port %d\n",
@@ -914,6 +923,9 @@ netxen_nic_up(struct netxen_adapter *adapter, struct net_device *netdev)
 static void
 netxen_nic_down(struct netxen_adapter *adapter, struct net_device *netdev)
 {
+	if (adapter->is_up != NETXEN_ADAPTER_UP_MAGIC)
+		return;
+
 	spin_lock(&adapter->tx_clean_lock);
 	netif_carrier_off(netdev);
 	netif_tx_disable(netdev);
-- 
1.6.0.2


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH NEXT 2/6] netxen: firmware hang detection
  2009-09-06  3:43 [PATCH NEXT 0/6] nexten: fixes and enhancements Dhananjay Phadke
  2009-09-06  3:43 ` [PATCH NEXT 1/6] netxen: handle firmware load errors Dhananjay Phadke
@ 2009-09-06  3:43 ` Dhananjay Phadke
  2009-09-06  3:43 ` [PATCH NEXT 3/6] netxen: fix ip addr hashing after firmware reset Dhananjay Phadke
                   ` (4 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: Dhananjay Phadke @ 2009-09-06  3:43 UTC (permalink / raw)
  To: davem; +Cc: netdev, Amit Kumar Salecha

Implement state machine to detect firmware hung state
and recover. Since firmware will be shared by all PCI
functions that have different class drivers (NIC or
FCOE or iSCSI), explicit hardware based serialization
is required for initializing firmware.

o Used global scratchpad register to maintain device
  reference count. Every probed pci function adds to
  ref count.

o Implement timer (delayed work) for each pci func
  that checks firmware heartbit every 5 sec and detaches
  itself if firmware is dead. Last detaching function
  reloads firmware. Other functions wait for firmware
  init, and re-attach themselves.

Heartbit is not supported by NX2031 firmware.

Signed-off-by: Amit Kumar Salecha <amit@netxen.com>
Signed-off-by: Dhananjay Phadke <dhananjay@netxen.com>
---
 drivers/net/netxen/netxen_nic.h      |   17 ++-
 drivers/net/netxen/netxen_nic_ctx.c  |    8 +
 drivers/net/netxen/netxen_nic_hdr.h  |   23 ++
 drivers/net/netxen/netxen_nic_main.c |  388 ++++++++++++++++++++++++++--------
 4 files changed, 348 insertions(+), 88 deletions(-)

diff --git a/drivers/net/netxen/netxen_nic.h b/drivers/net/netxen/netxen_nic.h
index ede2fa7..30a3816 100644
--- a/drivers/net/netxen/netxen_nic.h
+++ b/drivers/net/netxen/netxen_nic.h
@@ -229,6 +229,8 @@
 #define MPORT_SINGLE_FUNCTION_MODE 0x1111
 #define MPORT_MULTI_FUNCTION_MODE 0x2222
 
+#define NX_MAX_PCI_FUNC		8
+
 /*
  * NetXen host-peg signal message structure
  *
@@ -1101,6 +1103,10 @@ typedef struct {
 #define NETXEN_ADAPTER_UP_MAGIC 777
 #define NETXEN_NIC_PEG_TUNE 0
 
+#define __NX_FW_ATTACHED		0
+#define __NX_DEV_UP			1
+#define __NX_RESETTING			2
+
 struct netxen_dummy_dma {
 	void *addr;
 	dma_addr_t phys_addr;
@@ -1137,7 +1143,9 @@ struct netxen_adapter {
 	u8 max_mc_count;
 	u8 rss_supported;
 	u8 link_changed;
-	u32 resv3;
+	u8 fw_wait_cnt;
+	u8 fw_fail_cnt;
+	u16 resv4;
 
 	u8 has_link_events;
 	u8 fw_type;
@@ -1156,7 +1164,7 @@ struct netxen_adapter {
 	u32 temp;
 
 	u32 msi_tgt_status;
-	u32 resv4;
+	u32 heartbit;
 
 	struct netxen_adapter_stats stats;
 
@@ -1187,14 +1195,15 @@ struct netxen_adapter {
 
 	struct netxen_dummy_dma dummy_dma;
 
-	struct work_struct watchdog_task;
-	struct timer_list watchdog_timer;
+	struct delayed_work fw_work;
+
 	struct work_struct  tx_timeout_task;
 
 	struct net_device_stats net_stats;
 
 	nx_nic_intr_coalesce_t coal;
 
+	unsigned long state;
 	u32 resv5;
 	u32 fw_version;
 	const struct firmware *fw;
diff --git a/drivers/net/netxen/netxen_nic_ctx.c b/drivers/net/netxen/netxen_nic_ctx.c
index 0f42ab9..8ab5773 100644
--- a/drivers/net/netxen/netxen_nic_ctx.c
+++ b/drivers/net/netxen/netxen_nic_ctx.c
@@ -678,6 +678,9 @@ int netxen_alloc_hw_resources(struct netxen_adapter *adapter)
 
 
 	if (!NX_IS_REVISION_P2(adapter->ahw.revision_id)) {
+		if (test_and_set_bit(__NX_FW_ATTACHED, &adapter->state))
+			goto done;
+
 		err = nx_fw_cmd_create_rx_ctx(adapter);
 		if (err)
 			goto err_out_free;
@@ -690,6 +693,7 @@ int netxen_alloc_hw_resources(struct netxen_adapter *adapter)
 			goto err_out_free;
 	}
 
+done:
 	return 0;
 
 err_out_free:
@@ -708,6 +712,9 @@ void netxen_free_hw_resources(struct netxen_adapter *adapter)
 	int port = adapter->portnum;
 
 	if (!NX_IS_REVISION_P2(adapter->ahw.revision_id)) {
+		if (!test_and_clear_bit(__NX_FW_ATTACHED, &adapter->state))
+			goto done;
+
 		nx_fw_cmd_destroy_rx_ctx(adapter);
 		nx_fw_cmd_destroy_tx_ctx(adapter);
 	} else {
@@ -720,6 +727,7 @@ void netxen_free_hw_resources(struct netxen_adapter *adapter)
 	/* Allow dma queues to drain after context reset */
 	msleep(20);
 
+done:
 	recv_ctx = &adapter->recv_ctx;
 
 	if (recv_ctx->hwctx != NULL) {
diff --git a/drivers/net/netxen/netxen_nic_hdr.h b/drivers/net/netxen/netxen_nic_hdr.h
index 92f5970..26188b4 100644
--- a/drivers/net/netxen/netxen_nic_hdr.h
+++ b/drivers/net/netxen/netxen_nic_hdr.h
@@ -433,6 +433,7 @@ enum {
 #define NETXEN_CRB_PEG_NET_1	NETXEN_PCI_CRB_WINDOW(NETXEN_HW_PX_MAP_CRB_PGN1)
 #define NETXEN_CRB_PEG_NET_2	NETXEN_PCI_CRB_WINDOW(NETXEN_HW_PX_MAP_CRB_PGN2)
 #define NETXEN_CRB_PEG_NET_3	NETXEN_PCI_CRB_WINDOW(NETXEN_HW_PX_MAP_CRB_PGN3)
+#define NETXEN_CRB_PEG_NET_4	NETXEN_PCI_CRB_WINDOW(NETXEN_HW_PX_MAP_CRB_SQS2)
 #define NETXEN_CRB_PEG_NET_D	NETXEN_PCI_CRB_WINDOW(NETXEN_HW_PX_MAP_CRB_PGND)
 #define NETXEN_CRB_PEG_NET_I	NETXEN_PCI_CRB_WINDOW(NETXEN_HW_PX_MAP_CRB_PGNI)
 #define NETXEN_CRB_DDR_NET	NETXEN_PCI_CRB_WINDOW(NETXEN_HW_PX_MAP_CRB_MN)
@@ -945,6 +946,28 @@ enum {
 
 #define NETXEN_DMA_WATCHDOG_CTRL	(NETXEN_CAM_RAM(0x14))
 #define NETXEN_PEG_ALIVE_COUNTER	(NETXEN_CAM_RAM(0xb0))
+#define NETXEN_PEG_HALT_STATUS1 	(NETXEN_CAM_RAM(0xa8))
+#define NETXEN_PEG_HALT_STATUS2 	(NETXEN_CAM_RAM(0xac))
+#define NX_CRB_DEV_REF_COUNT		(NETXEN_CAM_RAM(0x138))
+#define NX_CRB_DEV_STATE		(NETXEN_CAM_RAM(0x140))
+
+/* Device State */
+#define NX_DEV_COLD		1
+#define NX_DEV_INITALIZING	2
+#define NX_DEV_READY		3
+#define NX_DEV_NEED_RESET	4
+#define NX_DEV_NEED_QUISCENT	5
+#define NX_DEV_FAILED		6
+
+#define NX_RCODE_DRIVER_INFO		0x20000000
+#define NX_RCODE_DRIVER_CAN_RELOAD	0x40000000
+#define NX_RCODE_FATAL_ERROR		0x80000000
+#define NX_FWERROR_PEGNUM(code)		((code) & 0xff)
+#define NX_FWERROR_CODE(code)		((code >> 8) & 0xfffff)
+
+#define FW_POLL_DELAY			(2 * HZ)
+#define FW_FAIL_THRESH			3
+#define FW_POLL_THRESH			10
 
 #define	ISR_MSI_INT_TRIGGER(FUNC) (NETXEN_PCIX_PS_REG(PCIX_MSI_F(FUNC)))
 #define ISR_LEGACY_INT_TRIGGERED(VAL)	(((VAL) & 0x300) == 0x200)
diff --git a/drivers/net/netxen/netxen_nic_main.c b/drivers/net/netxen/netxen_nic_main.c
index 47aede6..4989436 100644
--- a/drivers/net/netxen/netxen_nic_main.c
+++ b/drivers/net/netxen/netxen_nic_main.c
@@ -67,7 +67,10 @@ static netdev_tx_t netxen_nic_xmit_frame(struct sk_buff *,
 					       struct net_device *);
 static void netxen_tx_timeout(struct net_device *netdev);
 static void netxen_reset_task(struct work_struct *work);
-static void netxen_watchdog(unsigned long);
+static void netxen_fw_poll_work(struct work_struct *work);
+static void netxen_schedule_work(struct netxen_adapter *adapter,
+		work_func_t func, int delay);
+static void netxen_cancel_fw_work(struct netxen_adapter *adapter);
 static int netxen_nic_poll(struct napi_struct *napi, int budget);
 #ifdef CONFIG_NET_POLL_CONTROLLER
 static void netxen_nic_poll_controller(struct net_device *netdev);
@@ -76,6 +79,9 @@ static void netxen_nic_poll_controller(struct net_device *netdev);
 static void netxen_create_sysfs_entries(struct netxen_adapter *adapter);
 static void netxen_remove_sysfs_entries(struct netxen_adapter *adapter);
 
+static int nx_decr_dev_ref_cnt(struct netxen_adapter *adapter);
+static int netxen_can_start_firmware(struct netxen_adapter *adapter);
+
 static irqreturn_t netxen_intr(int irq, void *data);
 static irqreturn_t netxen_msi_intr(int irq, void *data);
 static irqreturn_t netxen_msix_intr(int irq, void *data);
@@ -729,19 +735,12 @@ err_out:
 }
 
 static int
-netxen_start_firmware(struct netxen_adapter *adapter, int request_fw)
+netxen_start_firmware(struct netxen_adapter *adapter)
 {
 	int val, err, first_boot;
 	struct pci_dev *pdev = adapter->pdev;
 
-	int first_driver = 0;
-
-	if (NX_IS_REVISION_P2(adapter->ahw.revision_id))
-		first_driver = (adapter->portnum == 0);
-	else
-		first_driver = (adapter->ahw.pci_func == 0);
-
-	if (!first_driver)
+	if (!netxen_can_start_firmware(adapter))
 		goto wait_init;
 
 	first_boot = NXRD32(adapter, NETXEN_CAM_RAM(0x1fc));
@@ -752,8 +751,7 @@ netxen_start_firmware(struct netxen_adapter *adapter, int request_fw)
 		return err;
 	}
 
-	if (request_fw)
-		netxen_request_firmware(adapter);
+	netxen_request_firmware(adapter);
 
 	err = netxen_need_fw_reset(adapter);
 	if (err < 0)
@@ -768,6 +766,9 @@ netxen_start_firmware(struct netxen_adapter *adapter, int request_fw)
 	}
 
 	NXWR32(adapter, CRB_DMA_SHIFT, 0x55555555);
+	NXWR32(adapter, NETXEN_PEG_HALT_STATUS1, 0);
+	NXWR32(adapter, NETXEN_PEG_HALT_STATUS2, 0);
+
 	if (NX_IS_REVISION_P3(adapter->ahw.revision_id))
 		netxen_set_port_mode(adapter);
 
@@ -775,6 +776,8 @@ netxen_start_firmware(struct netxen_adapter *adapter, int request_fw)
 	if (err)
 		goto err_out;
 
+	netxen_release_firmware(adapter);
+
 	if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) {
 
 		/* Initialize multicast addr pool owners */
@@ -797,6 +800,8 @@ netxen_start_firmware(struct netxen_adapter *adapter, int request_fw)
 		| (_NETXEN_NIC_LINUX_SUBVERSION);
 	NXWR32(adapter, CRB_DRIVER_VERSION, val);
 
+	NXWR32(adapter, NX_CRB_DEV_STATE, NX_DEV_READY);
+
 wait_init:
 	/* Handshake with the card before we register the devices. */
 	err = netxen_phantom_init(adapter, NETXEN_NIC_PEG_TUNE);
@@ -808,6 +813,7 @@ wait_init:
 	nx_update_dma_mask(adapter);
 
 	netxen_nic_get_firmware_info(adapter);
+	netxen_check_options(adapter);
 
 	return 0;
 
@@ -915,8 +921,7 @@ netxen_nic_up(struct netxen_adapter *adapter, struct net_device *netdev)
 	else
 		netxen_nic_set_link_parameters(adapter);
 
-	mod_timer(&adapter->watchdog_timer, jiffies);
-
+	set_bit(__NX_DEV_UP, &adapter->state);
 	return 0;
 }
 
@@ -926,6 +931,8 @@ netxen_nic_down(struct netxen_adapter *adapter, struct net_device *netdev)
 	if (adapter->is_up != NETXEN_ADAPTER_UP_MAGIC)
 		return;
 
+	clear_bit(__NX_DEV_UP, &adapter->state);
+
 	spin_lock(&adapter->tx_clean_lock);
 	netif_carrier_off(netdev);
 	netif_tx_disable(netdev);
@@ -942,8 +949,6 @@ netxen_nic_down(struct netxen_adapter *adapter, struct net_device *netdev)
 
 	netxen_release_tx_buffers(adapter);
 	spin_unlock(&adapter->tx_clean_lock);
-
-	del_timer_sync(&adapter->watchdog_timer);
 }
 
 
@@ -974,8 +979,6 @@ netxen_nic_attach(struct netxen_adapter *adapter)
 		return err;
 	}
 
-	netxen_nic_clear_stats(adapter);
-
 	err = netxen_alloc_hw_resources(adapter);
 	if (err) {
 		printk(KERN_ERR "%s: Error in setting hw resources\n",
@@ -1046,21 +1049,32 @@ netxen_nic_reset_context(struct netxen_adapter *adapter)
 	int err = 0;
 	struct net_device *netdev = adapter->netdev;
 
+	if (test_and_set_bit(__NX_RESETTING, &adapter->state))
+		return -EBUSY;
+
 	if (adapter->is_up == NETXEN_ADAPTER_UP_MAGIC) {
 
+		netif_device_detach(netdev);
+
 		if (netif_running(netdev))
 			netxen_nic_down(adapter, netdev);
 
 		netxen_nic_detach(adapter);
 
-		err = netxen_nic_attach(adapter);
-		if (err)
-			goto done;
+		if (netif_running(netdev)) {
+			err = netxen_nic_attach(adapter);
+			if (!err)
+				err = netxen_nic_up(adapter, netdev);
 
-		if (netif_running(netdev))
-			err = netxen_nic_up(adapter, netdev);
+			if (err)
+				goto done;
+		}
+
+		netif_device_attach(netdev);
 	}
+
 done:
+	clear_bit(__NX_RESETTING, &adapter->state);
 	return err;
 }
 
@@ -1107,10 +1121,6 @@ netxen_setup_netdev(struct netxen_adapter *adapter,
 
 	netdev->irq = adapter->msix_entries[0].vector;
 
-	init_timer(&adapter->watchdog_timer);
-	adapter->watchdog_timer.function = &netxen_watchdog;
-	adapter->watchdog_timer.data = (unsigned long)adapter;
-	INIT_WORK(&adapter->watchdog_task, netxen_watchdog_task);
 	INIT_WORK(&adapter->tx_timeout_task, netxen_reset_task);
 
 	if (netxen_read_mac_addr(adapter))
@@ -1214,7 +1224,7 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 		break;
 	}
 
-	err = netxen_start_firmware(adapter, 1);
+	err = netxen_start_firmware(adapter);
 	if (err)
 		goto err_out_iounmap;
 
@@ -1228,7 +1238,7 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 			adapter->physical_port = i;
 	}
 
-	netxen_check_options(adapter);
+	netxen_nic_clear_stats(adapter);
 
 	netxen_setup_intr(adapter);
 
@@ -1238,6 +1248,8 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 
 	pci_set_drvdata(pdev, adapter);
 
+	netxen_schedule_work(adapter, netxen_fw_poll_work, FW_POLL_DELAY);
+
 	switch (adapter->ahw.port_type) {
 	case NETXEN_NIC_GBE:
 		dev_info(&adapter->pdev->dev, "%s: GbE port initialized\n",
@@ -1256,6 +1268,8 @@ err_out_disable_msi:
 
 	netxen_free_dummy_dma(adapter);
 
+	nx_decr_dev_ref_cnt(adapter);
+
 err_out_iounmap:
 	netxen_cleanup_pci_map(adapter);
 
@@ -1282,16 +1296,21 @@ static void __devexit netxen_nic_remove(struct pci_dev *pdev)
 
 	netdev = adapter->netdev;
 
+	netxen_cancel_fw_work(adapter);
+
 	unregister_netdev(netdev);
 
-	cancel_work_sync(&adapter->watchdog_task);
 	cancel_work_sync(&adapter->tx_timeout_task);
 
 	netxen_nic_detach(adapter);
 
+	nx_decr_dev_ref_cnt(adapter);
+
 	if (adapter->portnum == 0)
 		netxen_free_dummy_dma(adapter);
 
+	clear_bit(__NX_RESETTING, &adapter->state);
+
 	netxen_teardown_intr(adapter);
 
 	netxen_cleanup_pci_map(adapter);
@@ -1312,10 +1331,11 @@ static int __netxen_nic_shutdown(struct pci_dev *pdev)
 
 	netif_device_detach(netdev);
 
+	netxen_cancel_fw_work(adapter);
+
 	if (netif_running(netdev))
 		netxen_nic_down(adapter, netdev);
 
-	cancel_work_sync(&adapter->watchdog_task);
 	cancel_work_sync(&adapter->tx_timeout_task);
 
 	netxen_nic_detach(adapter);
@@ -1323,6 +1343,10 @@ static int __netxen_nic_shutdown(struct pci_dev *pdev)
 	if (adapter->portnum == 0)
 		netxen_free_dummy_dma(adapter);
 
+	nx_decr_dev_ref_cnt(adapter);
+
+	clear_bit(__NX_RESETTING, &adapter->state);
+
 	retval = pci_save_state(pdev);
 	if (retval)
 		return retval;
@@ -1371,7 +1395,7 @@ netxen_nic_resume(struct pci_dev *pdev)
 
 	adapter->curr_window = 255;
 
-	err = netxen_start_firmware(adapter, 0);
+	err = netxen_start_firmware(adapter);
 	if (err) {
 		dev_err(&pdev->dev, "failed to start firmware\n");
 		return err;
@@ -1380,16 +1404,22 @@ netxen_nic_resume(struct pci_dev *pdev)
 	if (netif_running(netdev)) {
 		err = netxen_nic_attach(adapter);
 		if (err)
-			return err;
+			goto err_out;
 
 		err = netxen_nic_up(adapter, netdev);
 		if (err)
-			return err;
+			goto err_out_detach;
 
 		netif_device_attach(netdev);
 	}
 
-	return 0;
+	netxen_schedule_work(adapter, netxen_fw_poll_work, FW_POLL_DELAY);
+
+err_out_detach:
+	netxen_nic_detach(adapter);
+err_out:
+	nx_decr_dev_ref_cnt(adapter);
+	return err;
 }
 #endif
 
@@ -1783,59 +1813,13 @@ static void netxen_nic_handle_phy_intr(struct netxen_adapter *adapter)
 	netxen_advert_link_change(adapter, linkup);
 }
 
-static void netxen_nic_thermal_shutdown(struct netxen_adapter *adapter)
-{
-	struct net_device *netdev = adapter->netdev;
-
-	netif_device_detach(netdev);
-	netxen_nic_down(adapter, netdev);
-	netxen_nic_detach(adapter);
-}
-
-static void netxen_watchdog(unsigned long v)
-{
-	struct netxen_adapter *adapter = (struct netxen_adapter *)v;
-
-	if (netxen_nic_check_temp(adapter))
-		goto do_sched;
-
-	if (!adapter->has_link_events) {
-		netxen_nic_handle_phy_intr(adapter);
-
-		if (adapter->link_changed)
-			goto do_sched;
-	}
-
-	if (netif_running(adapter->netdev))
-		mod_timer(&adapter->watchdog_timer, jiffies + 2 * HZ);
-
-	return;
-
-do_sched:
-	schedule_work(&adapter->watchdog_task);
-}
-
-void netxen_watchdog_task(struct work_struct *work)
-{
-	struct netxen_adapter *adapter =
-		container_of(work, struct netxen_adapter, watchdog_task);
-
-	if (adapter->temp == NX_TEMP_PANIC) {
-		netxen_nic_thermal_shutdown(adapter);
-		return;
-	}
-
-	if (adapter->link_changed)
-		netxen_nic_set_link_parameters(adapter);
-
-	if (netif_running(adapter->netdev))
-		mod_timer(&adapter->watchdog_timer, jiffies + 2 * HZ);
-}
-
 static void netxen_tx_timeout(struct net_device *netdev)
 {
 	struct netxen_adapter *adapter = netdev_priv(netdev);
 
+	if (test_bit(__NX_RESETTING, &adapter->state))
+		return;
+
 	dev_err(&netdev->dev, "transmit timeout, resetting.\n");
 	schedule_work(&adapter->tx_timeout_task);
 }
@@ -1848,6 +1832,9 @@ static void netxen_reset_task(struct work_struct *work)
 	if (!netif_running(adapter->netdev))
 		return;
 
+	if (test_bit(__NX_RESETTING, &adapter->state))
+		return;
+
 	netxen_napi_disable(adapter);
 
 	adapter->netdev->trans_start = jiffies;
@@ -1974,6 +1961,239 @@ static void netxen_nic_poll_controller(struct net_device *netdev)
 }
 #endif
 
+static int
+nx_incr_dev_ref_cnt(struct netxen_adapter *adapter)
+{
+	int count;
+	if (netxen_api_lock(adapter))
+		return -EIO;
+
+	count = NXRD32(adapter, NX_CRB_DEV_REF_COUNT);
+
+	NXWR32(adapter, NX_CRB_DEV_REF_COUNT, ++count);
+
+	netxen_api_unlock(adapter);
+	return count;
+}
+
+static int
+nx_decr_dev_ref_cnt(struct netxen_adapter *adapter)
+{
+	int count;
+	if (netxen_api_lock(adapter))
+		return -EIO;
+
+	count = NXRD32(adapter, NX_CRB_DEV_REF_COUNT);
+	WARN_ON(count == 0);
+
+	NXWR32(adapter, NX_CRB_DEV_REF_COUNT, --count);
+
+	if (count == 0)
+		NXWR32(adapter, NX_CRB_DEV_STATE, NX_DEV_COLD);
+
+	netxen_api_unlock(adapter);
+	return count;
+}
+
+static int
+netxen_can_start_firmware(struct netxen_adapter *adapter)
+{
+	int count;
+	int can_start = 0;
+
+	if (netxen_api_lock(adapter))
+		return 0;
+
+	count = NXRD32(adapter, NX_CRB_DEV_REF_COUNT);
+
+	if ((count < 0) || (count >= NX_MAX_PCI_FUNC))
+		count = 0;
+
+	if (count == 0) {
+		can_start = 1;
+		NXWR32(adapter, NX_CRB_DEV_STATE, NX_DEV_INITALIZING);
+	}
+
+	NXWR32(adapter, NX_CRB_DEV_REF_COUNT, ++count);
+
+	netxen_api_unlock(adapter);
+
+	return can_start;
+}
+
+static void
+netxen_schedule_work(struct netxen_adapter *adapter,
+		work_func_t func, int delay)
+{
+	INIT_DELAYED_WORK(&adapter->fw_work, func);
+	schedule_delayed_work(&adapter->fw_work, delay);
+}
+
+static void
+netxen_cancel_fw_work(struct netxen_adapter *adapter)
+{
+	while (test_and_set_bit(__NX_RESETTING, &adapter->state))
+		msleep(10);
+
+	cancel_delayed_work_sync(&adapter->fw_work);
+}
+
+static void
+netxen_attach_work(struct work_struct *work)
+{
+	struct netxen_adapter *adapter = container_of(work,
+				struct netxen_adapter, fw_work.work);
+	struct net_device *netdev = adapter->netdev;
+	int err = 0;
+
+	if (netif_running(netdev)) {
+		err = netxen_nic_attach(adapter);
+		if (err)
+			goto done;
+
+		err = netxen_nic_up(adapter, netdev);
+		if (err) {
+			netxen_nic_detach(adapter);
+			goto done;
+		}
+
+	}
+
+	netif_device_attach(netdev);
+
+done:
+	adapter->fw_fail_cnt = 0;
+	clear_bit(__NX_RESETTING, &adapter->state);
+	netxen_schedule_work(adapter, netxen_fw_poll_work, FW_POLL_DELAY);
+}
+
+static void
+netxen_fwinit_work(struct work_struct *work)
+{
+	struct netxen_adapter *adapter = container_of(work,
+				struct netxen_adapter, fw_work.work);
+	int dev_state;
+
+	dev_state = NXRD32(adapter, NX_CRB_DEV_STATE);
+
+	switch (dev_state) {
+	case NX_DEV_COLD:
+	case NX_DEV_READY:
+		netxen_start_firmware(adapter);
+		netxen_schedule_work(adapter, netxen_attach_work, 0);
+		return;
+
+	case NX_DEV_INITALIZING:
+		if (++adapter->fw_wait_cnt < FW_POLL_THRESH) {
+			netxen_schedule_work(adapter,
+					netxen_fwinit_work, 2 * FW_POLL_DELAY);
+			return;
+		}
+		break;
+
+	case NX_DEV_FAILED:
+	default:
+		break;
+	}
+
+	nx_incr_dev_ref_cnt(adapter);
+	clear_bit(__NX_RESETTING, &adapter->state);
+}
+
+static void
+netxen_detach_work(struct work_struct *work)
+{
+	struct netxen_adapter *adapter = container_of(work,
+				struct netxen_adapter, fw_work.work);
+	struct net_device *netdev = adapter->netdev;
+	int ref_cnt, delay;
+	u32 status;
+
+	netif_device_detach(netdev);
+
+	if (netif_running(netdev))
+		netxen_nic_down(adapter, netdev);
+
+	netxen_nic_detach(adapter);
+
+	status = NXRD32(adapter, NETXEN_PEG_HALT_STATUS1);
+
+	ref_cnt = nx_decr_dev_ref_cnt(adapter);
+
+	if (status & NX_RCODE_FATAL_ERROR)
+		return;
+
+	if (adapter->temp == NX_TEMP_PANIC)
+		return;
+
+	delay = (ref_cnt == 0) ? 0 : (2 * FW_POLL_DELAY);
+
+	adapter->fw_wait_cnt = 0;
+	netxen_schedule_work(adapter, netxen_fwinit_work, delay);
+}
+
+static int
+netxen_check_health(struct netxen_adapter *adapter)
+{
+	u32 state, heartbit;
+	struct net_device *netdev = adapter->netdev;
+
+	if (netxen_nic_check_temp(adapter))
+		goto detach;
+
+	state = NXRD32(adapter, NX_CRB_DEV_STATE);
+	if (state == NX_DEV_NEED_RESET)
+		goto detach;
+
+	if (NX_IS_REVISION_P2(adapter->ahw.revision_id))
+		return 0;
+
+	heartbit = NXRD32(adapter, NETXEN_PEG_ALIVE_COUNTER);
+	if (heartbit != adapter->heartbit) {
+		adapter->heartbit = heartbit;
+		adapter->fw_fail_cnt = 0;
+		return 0;
+	}
+
+	if (++adapter->fw_fail_cnt < FW_FAIL_THRESH)
+		return 0;
+
+	clear_bit(__NX_FW_ATTACHED, &adapter->state);
+
+	dev_info(&netdev->dev, "firmware hang detected\n");
+
+detach:
+	if (!test_and_set_bit(__NX_RESETTING, &adapter->state))
+		netxen_schedule_work(adapter, netxen_detach_work, 0);
+	return 1;
+}
+
+static void
+netxen_fw_poll_work(struct work_struct *work)
+{
+	struct netxen_adapter *adapter = container_of(work,
+				struct netxen_adapter, fw_work.work);
+
+	if (test_bit(__NX_RESETTING, &adapter->state))
+		goto reschedule;
+
+	if (test_bit(__NX_DEV_UP, &adapter->state)) {
+		if (!adapter->has_link_events) {
+
+			netxen_nic_handle_phy_intr(adapter);
+
+			if (adapter->link_changed)
+				netxen_nic_set_link_parameters(adapter);
+		}
+	}
+
+	if (netxen_check_health(adapter))
+		return;
+
+reschedule:
+	netxen_schedule_work(adapter, netxen_fw_poll_work, FW_POLL_DELAY);
+}
+
 static ssize_t
 netxen_store_bridged_mode(struct device *dev,
 		struct device_attribute *attr, const char *buf, size_t len)
-- 
1.6.0.2


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH NEXT 3/6] netxen: fix ip addr hashing after firmware reset
  2009-09-06  3:43 [PATCH NEXT 0/6] nexten: fixes and enhancements Dhananjay Phadke
  2009-09-06  3:43 ` [PATCH NEXT 1/6] netxen: handle firmware load errors Dhananjay Phadke
  2009-09-06  3:43 ` [PATCH NEXT 2/6] netxen: firmware hang detection Dhananjay Phadke
@ 2009-09-06  3:43 ` Dhananjay Phadke
  2009-09-06  3:43 ` [PATCH NEXT 4/6] netxen: pre calculate register addresses Dhananjay Phadke
                   ` (3 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: Dhananjay Phadke @ 2009-09-06  3:43 UTC (permalink / raw)
  To: davem; +Cc: netdev, Amit Kumar Salecha

From: Amit Kumar Salecha <amit@netxen.com>

Reprogram local IP addresses after firmware is reset
or after resuming from suspend.

Signed-off-by: Amit Kumar Salecha <amit@netxen.com>
Signed-off-by: Dhananjay Phadke <dhananjay@netxen.com>
---
 drivers/net/netxen/netxen_nic_main.c |   61 +++++++++++++++++++++------------
 1 files changed, 39 insertions(+), 22 deletions(-)

diff --git a/drivers/net/netxen/netxen_nic_main.c b/drivers/net/netxen/netxen_nic_main.c
index 4989436..7038e1b 100644
--- a/drivers/net/netxen/netxen_nic_main.c
+++ b/drivers/net/netxen/netxen_nic_main.c
@@ -86,6 +86,8 @@ static irqreturn_t netxen_intr(int irq, void *data);
 static irqreturn_t netxen_msi_intr(int irq, void *data);
 static irqreturn_t netxen_msix_intr(int irq, void *data);
 
+static void netxen_config_indev_addr(struct net_device *dev, unsigned long);
+
 /*  PCI Device ID Table  */
 #define ENTRY(device) \
 	{PCI_DEVICE(PCI_VENDOR_ID_NETXEN, (device)), \
@@ -1411,6 +1413,8 @@ netxen_nic_resume(struct pci_dev *pdev)
 			goto err_out_detach;
 
 		netif_device_attach(netdev);
+
+		netxen_config_indev_addr(netdev, NETDEV_UP);
 	}
 
 	netxen_schedule_work(adapter, netxen_fw_poll_work, FW_POLL_DELAY);
@@ -2057,6 +2061,7 @@ netxen_attach_work(struct work_struct *work)
 			goto done;
 		}
 
+		netxen_config_indev_addr(netdev, NETDEV_UP);
 	}
 
 	netif_device_attach(netdev);
@@ -2282,12 +2287,43 @@ netxen_destip_supported(struct netxen_adapter *adapter)
 	return 1;
 }
 
+static void
+netxen_config_indev_addr(struct net_device *dev, unsigned long event)
+{
+	struct in_device *indev;
+	struct netxen_adapter *adapter = netdev_priv(dev);
+
+	if (netxen_destip_supported(adapter))
+		return;
+
+	indev = in_dev_get(dev);
+	if (!indev)
+		return;
+
+	for_ifa(indev) {
+		switch (event) {
+		case NETDEV_UP:
+			netxen_config_ipaddr(adapter,
+					ifa->ifa_address, NX_IP_UP);
+			break;
+		case NETDEV_DOWN:
+			netxen_config_ipaddr(adapter,
+					ifa->ifa_address, NX_IP_DOWN);
+			break;
+		default:
+			break;
+		}
+	} endfor_ifa(indev);
+
+	in_dev_put(indev);
+	return;
+}
+
 static int netxen_netdev_event(struct notifier_block *this,
 				 unsigned long event, void *ptr)
 {
 	struct netxen_adapter *adapter;
 	struct net_device *dev = (struct net_device *)ptr;
-	struct in_device *indev;
 
 recheck:
 	if (dev == NULL)
@@ -2303,32 +2339,13 @@ recheck:
 
 	adapter = netdev_priv(dev);
 
-	if (!adapter || !netxen_destip_supported(adapter))
+	if (!adapter)
 		goto done;
 
 	if (adapter->is_up != NETXEN_ADAPTER_UP_MAGIC)
 		goto done;
 
-	indev = in_dev_get(dev);
-	if (!indev)
-		goto done;
-
-	for_ifa(indev) {
-		switch (event) {
-		case NETDEV_UP:
-			netxen_config_ipaddr(adapter,
-					ifa->ifa_address, NX_IP_UP);
-			break;
-		case NETDEV_DOWN:
-			netxen_config_ipaddr(adapter,
-					ifa->ifa_address, NX_IP_DOWN);
-			break;
-		default:
-			break;
-		}
-	} endfor_ifa(indev);
-
-	in_dev_put(indev);
+	netxen_config_indev_addr(dev, event);
 done:
 	return NOTIFY_DONE;
 }
-- 
1.6.0.2


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH NEXT 4/6] netxen: pre calculate register addresses
  2009-09-06  3:43 [PATCH NEXT 0/6] nexten: fixes and enhancements Dhananjay Phadke
                   ` (2 preceding siblings ...)
  2009-09-06  3:43 ` [PATCH NEXT 3/6] netxen: fix ip addr hashing after firmware reset Dhananjay Phadke
@ 2009-09-06  3:43 ` Dhananjay Phadke
  2009-09-06  3:43 ` [PATCH NEXT 5/6] netxen: refactor firmware info code Dhananjay Phadke
                   ` (2 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: Dhananjay Phadke @ 2009-09-06  3:43 UTC (permalink / raw)
  To: davem; +Cc: netdev, Amit Kumar Salecha

From: Amit Kumar Salecha <amit@netxen.com>

For registers accessed in fast path (interrupt / softirq)
avoid expensive I/O address translation. These registers
are directly mapped in PCI bar 0 and do not require
any window checks.

Signed-off-by: Amit Kumar Salecha <amit@netxen.com>
Signed-off-by: Dhananjay Phadke <dhananjay@netxen.com>
---
 drivers/net/netxen/netxen_nic.h         |   75 +++++---------
 drivers/net/netxen/netxen_nic_ctx.c     |   21 +++--
 drivers/net/netxen/netxen_nic_ethtool.c |    5 +-
 drivers/net/netxen/netxen_nic_hw.c      |  176 +++++++++++++++++++++----------
 drivers/net/netxen/netxen_nic_init.c    |   34 +-----
 drivers/net/netxen/netxen_nic_main.c    |   90 +++++++---------
 6 files changed, 210 insertions(+), 191 deletions(-)

diff --git a/drivers/net/netxen/netxen_nic.h b/drivers/net/netxen/netxen_nic.h
index 30a3816..5bbc40b 100644
--- a/drivers/net/netxen/netxen_nic.h
+++ b/drivers/net/netxen/netxen_nic.h
@@ -584,11 +584,11 @@ struct netxen_adapter_stats {
  */
 struct nx_host_rds_ring {
 	u32 producer;
-	u32 crb_rcv_producer;
 	u32 num_desc;
 	u32 dma_size;
 	u32 skb_size;
 	u32 flags;
+	void __iomem *crb_rcv_producer;
 	struct rcv_desc *desc_head;
 	struct netxen_rx_buffer *rx_buf_arr;
 	struct list_head free_list;
@@ -598,9 +598,9 @@ struct nx_host_rds_ring {
 
 struct nx_host_sds_ring {
 	u32 consumer;
-	u32 crb_sts_consumer;
-	u32 crb_intr_mask;
 	u32 num_desc;
+	void __iomem *crb_sts_consumer;
+	void __iomem *crb_intr_mask;
 
 	struct status_desc *desc_head;
 	struct netxen_adapter *adapter;
@@ -617,8 +617,8 @@ struct nx_host_tx_ring {
 	u32 producer;
 	__le32 *hw_consumer;
 	u32 sw_consumer;
-	u32 crb_cmd_producer;
-	u32 crb_cmd_consumer;
+	void __iomem *crb_cmd_producer;
+	void __iomem *crb_cmd_consumer;
 	u32 num_desc;
 
 	struct netdev_queue *txq;
@@ -1163,7 +1163,7 @@ struct netxen_adapter {
 	u32 irq;
 	u32 temp;
 
-	u32 msi_tgt_status;
+	u32 int_vec_bit;
 	u32 heartbit;
 
 	struct netxen_adapter_stats stats;
@@ -1180,16 +1180,23 @@ struct netxen_adapter {
 	int (*init_port) (struct netxen_adapter *, int);
 	int (*stop_port) (struct netxen_adapter *);
 
-	u32 (*hw_read_wx)(struct netxen_adapter *, ulong);
-	int (*hw_write_wx)(struct netxen_adapter *, ulong, u32);
+	u32 (*crb_read)(struct netxen_adapter *, ulong);
+	int (*crb_write)(struct netxen_adapter *, ulong, u32);
+
 	int (*pci_mem_read)(struct netxen_adapter *, u64, void *, int);
 	int (*pci_mem_write)(struct netxen_adapter *, u64, void *, int);
-	int (*pci_write_immediate)(struct netxen_adapter *, u64, u32);
-	u32 (*pci_read_immediate)(struct netxen_adapter *, u64);
+
 	unsigned long (*pci_set_window)(struct netxen_adapter *,
 			unsigned long long);
 
-	struct netxen_legacy_intr_set legacy_intr;
+	u32 (*io_read)(struct netxen_adapter *, void __iomem *);
+	void (*io_write)(struct netxen_adapter *, void __iomem *, u32);
+
+	void __iomem	*tgt_mask_reg;
+	void __iomem	*pci_int_reg;
+	void __iomem	*tgt_status_reg;
+	void __iomem	*crb_int_state_reg;
+	void __iomem	*isr_int_vec;
 
 	struct msix_entry msix_entries[MSIX_ENTRIES_PER_ADAPTER];
 
@@ -1223,9 +1230,13 @@ int netxen_p2_nic_set_mac_addr(struct netxen_adapter *adapter, u8 *addr);
 int netxen_p3_nic_set_mac_addr(struct netxen_adapter *adapter, u8 *addr);
 
 #define NXRD32(adapter, off) \
-	(adapter->hw_read_wx(adapter, off))
+	(adapter->crb_read(adapter, off))
 #define NXWR32(adapter, off, val) \
-	(adapter->hw_write_wx(adapter, off, val))
+	(adapter->crb_write(adapter, off, val))
+#define NXRDIO(adapter, addr) \
+	(adapter->io_read(adapter, addr))
+#define NXWRIO(adapter, addr, val) \
+	(adapter->io_write(adapter, addr, val))
 
 int netxen_pcie_sem_lock(struct netxen_adapter *, int, u32);
 void netxen_pcie_sem_unlock(struct netxen_adapter *, int);
@@ -1255,40 +1266,6 @@ int netxen_nic_get_board_info(struct netxen_adapter *adapter);
 void netxen_nic_get_firmware_info(struct netxen_adapter *adapter);
 int netxen_nic_wol_supported(struct netxen_adapter *adapter);
 
-u32 netxen_nic_hw_read_wx_128M(struct netxen_adapter *adapter, ulong off);
-int netxen_nic_hw_write_wx_128M(struct netxen_adapter *adapter,
-		ulong off, u32 data);
-int netxen_nic_pci_mem_read_128M(struct netxen_adapter *adapter,
-		u64 off, void *data, int size);
-int netxen_nic_pci_mem_write_128M(struct netxen_adapter *adapter,
-		u64 off, void *data, int size);
-int netxen_nic_pci_write_immediate_128M(struct netxen_adapter *adapter,
-		u64 off, u32 data);
-u32 netxen_nic_pci_read_immediate_128M(struct netxen_adapter *adapter, u64 off);
-void netxen_nic_pci_write_normalize_128M(struct netxen_adapter *adapter,
-		u64 off, u32 data);
-u32 netxen_nic_pci_read_normalize_128M(struct netxen_adapter *adapter, u64 off);
-unsigned long netxen_nic_pci_set_window_128M(struct netxen_adapter *adapter,
-		unsigned long long addr);
-void netxen_nic_pci_change_crbwindow_128M(struct netxen_adapter *adapter,
-		u32 wndw);
-
-u32 netxen_nic_hw_read_wx_2M(struct netxen_adapter *adapter, ulong off);
-int netxen_nic_hw_write_wx_2M(struct netxen_adapter *adapter,
-		ulong off, u32 data);
-int netxen_nic_pci_mem_read_2M(struct netxen_adapter *adapter,
-		u64 off, void *data, int size);
-int netxen_nic_pci_mem_write_2M(struct netxen_adapter *adapter,
-		u64 off, void *data, int size);
-int netxen_nic_pci_write_immediate_2M(struct netxen_adapter *adapter,
-		u64 off, u32 data);
-u32 netxen_nic_pci_read_immediate_2M(struct netxen_adapter *adapter, u64 off);
-void netxen_nic_pci_write_normalize_2M(struct netxen_adapter *adapter,
-		u64 off, u32 data);
-u32 netxen_nic_pci_read_normalize_2M(struct netxen_adapter *adapter, u64 off);
-unsigned long netxen_nic_pci_set_window_2M(struct netxen_adapter *adapter,
-		unsigned long long addr);
-
 /* Functions from netxen_nic_init.c */
 int netxen_init_dummy_dma(struct netxen_adapter *adapter);
 void netxen_free_dummy_dma(struct netxen_adapter *adapter);
@@ -1316,13 +1293,15 @@ int netxen_rom_se(struct netxen_adapter *adapter, int addr);
 int netxen_alloc_sw_resources(struct netxen_adapter *adapter);
 void netxen_free_sw_resources(struct netxen_adapter *adapter);
 
+void netxen_setup_hwops(struct netxen_adapter *adapter);
+void __iomem *netxen_get_ioaddr(struct netxen_adapter *, u32);
+
 int netxen_alloc_hw_resources(struct netxen_adapter *adapter);
 void netxen_free_hw_resources(struct netxen_adapter *adapter);
 
 void netxen_release_rx_buffers(struct netxen_adapter *adapter);
 void netxen_release_tx_buffers(struct netxen_adapter *adapter);
 
-void netxen_initialize_adapter_ops(struct netxen_adapter *adapter);
 int netxen_init_firmware(struct netxen_adapter *adapter);
 void netxen_nic_clear_stats(struct netxen_adapter *adapter);
 void netxen_watchdog_task(struct work_struct *work);
diff --git a/drivers/net/netxen/netxen_nic_ctx.c b/drivers/net/netxen/netxen_nic_ctx.c
index 8ab5773..33f82db 100644
--- a/drivers/net/netxen/netxen_nic_ctx.c
+++ b/drivers/net/netxen/netxen_nic_ctx.c
@@ -229,7 +229,8 @@ nx_fw_cmd_create_rx_ctx(struct netxen_adapter *adapter)
 		rds_ring = &recv_ctx->rds_rings[i];
 
 		reg = le32_to_cpu(prsp_rds[i].host_producer_crb);
-		rds_ring->crb_rcv_producer = NETXEN_NIC_REG(reg - 0x200);
+		rds_ring->crb_rcv_producer = netxen_get_ioaddr(adapter,
+				NETXEN_NIC_REG(reg - 0x200));
 	}
 
 	prsp_sds = ((nx_cardrsp_sds_ring_t *)
@@ -239,10 +240,12 @@ nx_fw_cmd_create_rx_ctx(struct netxen_adapter *adapter)
 		sds_ring = &recv_ctx->sds_rings[i];
 
 		reg = le32_to_cpu(prsp_sds[i].host_consumer_crb);
-		sds_ring->crb_sts_consumer = NETXEN_NIC_REG(reg - 0x200);
+		sds_ring->crb_sts_consumer = netxen_get_ioaddr(adapter,
+				NETXEN_NIC_REG(reg - 0x200));
 
 		reg = le32_to_cpu(prsp_sds[i].interrupt_crb);
-		sds_ring->crb_intr_mask = NETXEN_NIC_REG(reg - 0x200);
+		sds_ring->crb_intr_mask = netxen_get_ioaddr(adapter,
+				NETXEN_NIC_REG(reg - 0x200));
 	}
 
 	recv_ctx->state = le32_to_cpu(prsp->host_ctx_state);
@@ -342,7 +345,8 @@ nx_fw_cmd_create_tx_ctx(struct netxen_adapter *adapter)
 
 	if (err == NX_RCODE_SUCCESS) {
 		temp = le32_to_cpu(prsp->cds_ring.host_producer_crb);
-		tx_ring->crb_cmd_producer = NETXEN_NIC_REG(temp - 0x200);
+		tx_ring->crb_cmd_producer = netxen_get_ioaddr(adapter,
+				NETXEN_NIC_REG(temp - 0x200));
 #if 0
 		adapter->tx_state =
 			le32_to_cpu(prsp->host_ctx_state);
@@ -651,7 +655,8 @@ int netxen_alloc_hw_resources(struct netxen_adapter *adapter)
 
 		if (NX_IS_REVISION_P2(adapter->ahw.revision_id))
 			rds_ring->crb_rcv_producer =
-				recv_crb_registers[port].crb_rcv_producer[ring];
+				netxen_get_ioaddr(adapter,
+			recv_crb_registers[port].crb_rcv_producer[ring]);
 	}
 
 	for (ring = 0; ring < adapter->max_sds_rings; ring++) {
@@ -670,10 +675,12 @@ int netxen_alloc_hw_resources(struct netxen_adapter *adapter)
 		sds_ring->desc_head = (struct status_desc *)addr;
 
 		sds_ring->crb_sts_consumer =
-			recv_crb_registers[port].crb_sts_consumer[ring];
+			netxen_get_ioaddr(adapter,
+			recv_crb_registers[port].crb_sts_consumer[ring]);
 
 		sds_ring->crb_intr_mask =
-			recv_crb_registers[port].sw_int_mask[ring];
+			netxen_get_ioaddr(adapter,
+			recv_crb_registers[port].sw_int_mask[ring]);
 	}
 
 
diff --git a/drivers/net/netxen/netxen_nic_ethtool.c b/drivers/net/netxen/netxen_nic_ethtool.c
index e376a1c..d18832c 100644
--- a/drivers/net/netxen/netxen_nic_ethtool.c
+++ b/drivers/net/netxen/netxen_nic_ethtool.c
@@ -84,18 +84,17 @@ static void
 netxen_nic_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *drvinfo)
 {
 	struct netxen_adapter *adapter = netdev_priv(dev);
-	unsigned long flags;
 	u32 fw_major = 0;
 	u32 fw_minor = 0;
 	u32 fw_build = 0;
 
 	strncpy(drvinfo->driver, netxen_nic_driver_name, 32);
 	strncpy(drvinfo->version, NETXEN_NIC_LINUX_VERSIONID, 32);
-	write_lock_irqsave(&adapter->adapter_lock, flags);
+	read_lock(&adapter->adapter_lock);
 	fw_major = NXRD32(adapter, NETXEN_FW_VERSION_MAJOR);
 	fw_minor = NXRD32(adapter, NETXEN_FW_VERSION_MINOR);
 	fw_build = NXRD32(adapter, NETXEN_FW_VERSION_SUB);
-	write_unlock_irqrestore(&adapter->adapter_lock, flags);
+	read_unlock(&adapter->adapter_lock);
 	sprintf(drvinfo->fw_version, "%d.%d.%d", fw_major, fw_minor, fw_build);
 
 	strncpy(drvinfo->bus_info, pci_name(adapter->pdev), 32);
diff --git a/drivers/net/netxen/netxen_nic_hw.c b/drivers/net/netxen/netxen_nic_hw.c
index d0ac8fa..cbfd610 100644
--- a/drivers/net/netxen/netxen_nic_hw.c
+++ b/drivers/net/netxen/netxen_nic_hw.c
@@ -1050,7 +1050,7 @@ int netxen_p3_get_mac_addr(struct netxen_adapter *adapter, __le64 *mac)
 /*
  * Changes the CRB window to the specified window.
  */
-void
+static void
 netxen_nic_pci_change_crbwindow_128M(struct netxen_adapter *adapter, u32 wndw)
 {
 	void __iomem *offset;
@@ -1163,61 +1163,68 @@ netxen_nic_pci_set_crbwindow_2M(struct netxen_adapter *adapter, ulong *off)
 		(ulong)adapter->ahw.pci_base0;
 }
 
-int
+static int
 netxen_nic_hw_write_wx_128M(struct netxen_adapter *adapter, ulong off, u32 data)
 {
+	unsigned long flags;
 	void __iomem *addr;
 
-	if (ADDR_IN_WINDOW1(off)) {
+	if (ADDR_IN_WINDOW1(off))
 		addr = NETXEN_CRB_NORMALIZE(adapter, off);
+	else
+		addr = pci_base_offset(adapter, off);
+
+	BUG_ON(!addr);
+
+	if (ADDR_IN_WINDOW1(off)) {	/* Window 1 */
+		read_lock(&adapter->adapter_lock);
+		writel(data, addr);
+		read_unlock(&adapter->adapter_lock);
 	} else {		/* Window 0 */
+		write_lock_irqsave(&adapter->adapter_lock, flags);
 		addr = pci_base_offset(adapter, off);
 		netxen_nic_pci_change_crbwindow_128M(adapter, 0);
-	}
-
-	if (!addr) {
+		writel(data, addr);
 		netxen_nic_pci_change_crbwindow_128M(adapter, 1);
-		return 1;
+		write_unlock_irqrestore(&adapter->adapter_lock, flags);
 	}
 
-	writel(data, addr);
-
-	if (!ADDR_IN_WINDOW1(off))
-		netxen_nic_pci_change_crbwindow_128M(adapter, 1);
-
 	return 0;
 }
 
-u32
+static u32
 netxen_nic_hw_read_wx_128M(struct netxen_adapter *adapter, ulong off)
 {
+	unsigned long flags;
 	void __iomem *addr;
 	u32 data;
 
-	if (ADDR_IN_WINDOW1(off)) {	/* Window 1 */
+	if (ADDR_IN_WINDOW1(off))
 		addr = NETXEN_CRB_NORMALIZE(adapter, off);
-	} else {		/* Window 0 */
+	else
 		addr = pci_base_offset(adapter, off);
-		netxen_nic_pci_change_crbwindow_128M(adapter, 0);
-	}
-
-	if (!addr) {
-		netxen_nic_pci_change_crbwindow_128M(adapter, 1);
-		return 1;
-	}
 
-	data = readl(addr);
+	BUG_ON(!addr);
 
-	if (!ADDR_IN_WINDOW1(off))
+	if (ADDR_IN_WINDOW1(off)) {	/* Window 1 */
+		read_lock(&adapter->adapter_lock);
+		data = readl(addr);
+		read_unlock(&adapter->adapter_lock);
+	} else {		/* Window 0 */
+		write_lock_irqsave(&adapter->adapter_lock, flags);
+		netxen_nic_pci_change_crbwindow_128M(adapter, 0);
+		data = readl(addr);
 		netxen_nic_pci_change_crbwindow_128M(adapter, 1);
+		write_unlock_irqrestore(&adapter->adapter_lock, flags);
+	}
 
 	return data;
 }
 
-int
+static int
 netxen_nic_hw_write_wx_2M(struct netxen_adapter *adapter, ulong off, u32 data)
 {
-	unsigned long flags = 0;
+	unsigned long flags;
 	int rv;
 
 	rv = netxen_nic_pci_get_crb_addr_2M(adapter, &off);
@@ -1243,10 +1250,10 @@ netxen_nic_hw_write_wx_2M(struct netxen_adapter *adapter, ulong off, u32 data)
 	return 0;
 }
 
-u32
+static u32
 netxen_nic_hw_read_wx_2M(struct netxen_adapter *adapter, ulong off)
 {
-	unsigned long flags = 0;
+	unsigned long flags;
 	int rv;
 	u32 data;
 
@@ -1293,7 +1300,7 @@ netxen_nic_pci_mem_bound_check(struct netxen_adapter *adapter,
 
 static int netxen_pci_set_window_warning_count;
 
-unsigned long
+static unsigned long
 netxen_nic_pci_set_window_128M(struct netxen_adapter *adapter,
 		unsigned long long addr)
 {
@@ -1357,22 +1364,56 @@ netxen_nic_pci_set_window_128M(struct netxen_adapter *adapter,
 	return addr;
 }
 
-/*
- * Note : only 32-bit writes!
- */
-int netxen_nic_pci_write_immediate_128M(struct netxen_adapter *adapter,
-		u64 off, u32 data)
+/* window 1 registers only */
+static void netxen_nic_io_write_128M(struct netxen_adapter *adapter,
+		void __iomem *addr, u32 data)
 {
-	writel(data, (void __iomem *)(PCI_OFFSET_SECOND_RANGE(adapter, off)));
-	return 0;
+	read_lock(&adapter->adapter_lock);
+	writel(data, addr);
+	read_unlock(&adapter->adapter_lock);
+}
+
+static u32 netxen_nic_io_read_128M(struct netxen_adapter *adapter,
+		void __iomem *addr)
+{
+	u32 val;
+
+	read_lock(&adapter->adapter_lock);
+	val = readl(addr);
+	read_unlock(&adapter->adapter_lock);
+
+	return val;
 }
 
-u32 netxen_nic_pci_read_immediate_128M(struct netxen_adapter *adapter, u64 off)
+static void netxen_nic_io_write_2M(struct netxen_adapter *adapter,
+		void __iomem *addr, u32 data)
 {
-	return readl((void __iomem *)(pci_base_offset(adapter, off)));
+	writel(data, addr);
+}
+
+static u32 netxen_nic_io_read_2M(struct netxen_adapter *adapter,
+		void __iomem *addr)
+{
+	return readl(addr);
+}
+
+void __iomem *
+netxen_get_ioaddr(struct netxen_adapter *adapter, u32 offset)
+{
+	ulong off = offset;
+
+	if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) {
+		if (offset < NETXEN_CRB_PCIX_HOST2 &&
+				offset > NETXEN_CRB_PCIX_HOST)
+			return PCI_OFFSET_SECOND_RANGE(adapter, offset);
+		return NETXEN_CRB_NORMALIZE(adapter, offset);
+	}
+
+	BUG_ON(netxen_nic_pci_get_crb_addr_2M(adapter, &off));
+	return (void __iomem *)off;
 }
 
-unsigned long
+static unsigned long
 netxen_nic_pci_set_window_2M(struct netxen_adapter *adapter,
 		unsigned long long addr)
 {
@@ -1616,7 +1657,7 @@ netxen_nic_pci_mem_write_direct(struct netxen_adapter *adapter, u64 off,
 
 #define MAX_CTL_CHECK   1000
 
-int
+static int
 netxen_nic_pci_mem_write_128M(struct netxen_adapter *adapter,
 		u64 off, void *data, int size)
 {
@@ -1709,7 +1750,7 @@ netxen_nic_pci_mem_write_128M(struct netxen_adapter *adapter,
 	return ret;
 }
 
-int
+static int
 netxen_nic_pci_mem_read_128M(struct netxen_adapter *adapter,
 		u64 off, void *data, int size)
 {
@@ -1800,7 +1841,7 @@ netxen_nic_pci_mem_read_128M(struct netxen_adapter *adapter,
 	return 0;
 }
 
-int
+static int
 netxen_nic_pci_mem_write_2M(struct netxen_adapter *adapter,
 		u64 off, void *data, int size)
 {
@@ -1828,8 +1869,8 @@ netxen_nic_pci_mem_write_2M(struct netxen_adapter *adapter,
 
 	if ((size != 8) || (off0 != 0)) {
 		for (i = 0; i < loop; i++) {
-			if (adapter->pci_mem_read(adapter, off8 + (i << 3),
-						&word[i], 8))
+			if (adapter->pci_mem_read(adapter,
+					off8 + (i << 3), &word[i], 8))
 				return -1;
 		}
 	}
@@ -1900,7 +1941,7 @@ netxen_nic_pci_mem_write_2M(struct netxen_adapter *adapter,
 	return ret;
 }
 
-int
+static int
 netxen_nic_pci_mem_read_2M(struct netxen_adapter *adapter,
 		u64 off, void *data, int size)
 {
@@ -1998,20 +2039,43 @@ netxen_nic_pci_mem_read_2M(struct netxen_adapter *adapter,
 	return 0;
 }
 
-/*
- * Note : only 32-bit writes!
- */
-int netxen_nic_pci_write_immediate_2M(struct netxen_adapter *adapter,
-		u64 off, u32 data)
+void
+netxen_setup_hwops(struct netxen_adapter *adapter)
 {
-	NXWR32(adapter, off, data);
+	adapter->init_port = netxen_niu_xg_init_port;
+	adapter->stop_port = netxen_niu_disable_xg_port;
 
-	return 0;
-}
+	if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) {
+		adapter->crb_read = netxen_nic_hw_read_wx_128M,
+		adapter->crb_write = netxen_nic_hw_write_wx_128M,
+		adapter->pci_set_window = netxen_nic_pci_set_window_128M,
+		adapter->pci_mem_read = netxen_nic_pci_mem_read_128M,
+		adapter->pci_mem_write = netxen_nic_pci_mem_write_128M,
+		adapter->io_read = netxen_nic_io_read_128M,
+		adapter->io_write = netxen_nic_io_write_128M,
+
+		adapter->macaddr_set = netxen_p2_nic_set_mac_addr;
+		adapter->set_multi = netxen_p2_nic_set_multi;
+		adapter->set_mtu = netxen_nic_set_mtu_xgb;
+		adapter->set_promisc = netxen_p2_nic_set_promisc;
 
-u32 netxen_nic_pci_read_immediate_2M(struct netxen_adapter *adapter, u64 off)
-{
-	return NXRD32(adapter, off);
+	} else {
+		adapter->crb_read = netxen_nic_hw_read_wx_2M,
+		adapter->crb_write = netxen_nic_hw_write_wx_2M,
+		adapter->pci_set_window = netxen_nic_pci_set_window_2M,
+		adapter->pci_mem_read = netxen_nic_pci_mem_read_2M,
+		adapter->pci_mem_write = netxen_nic_pci_mem_write_2M,
+		adapter->io_read = netxen_nic_io_read_2M,
+		adapter->io_write = netxen_nic_io_write_2M,
+
+		adapter->set_mtu = nx_fw_cmd_set_mtu;
+		adapter->set_promisc = netxen_p3_nic_set_promisc;
+		adapter->macaddr_set = netxen_p3_nic_set_mac_addr;
+		adapter->set_multi = netxen_p3_nic_set_multi;
+
+		adapter->phy_read = nx_fw_cmd_query_phy;
+		adapter->phy_write = nx_fw_cmd_set_phy;
+	}
 }
 
 int netxen_nic_get_board_info(struct netxen_adapter *adapter)
diff --git a/drivers/net/netxen/netxen_nic_init.c b/drivers/net/netxen/netxen_nic_init.c
index 534994d..485b947 100644
--- a/drivers/net/netxen/netxen_nic_init.c
+++ b/drivers/net/netxen/netxen_nic_init.c
@@ -323,29 +323,6 @@ err_out:
 	return -ENOMEM;
 }
 
-void netxen_initialize_adapter_ops(struct netxen_adapter *adapter)
-{
-	adapter->init_port = netxen_niu_xg_init_port;
-	adapter->stop_port = netxen_niu_disable_xg_port;
-
-	if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) {
-		adapter->macaddr_set = netxen_p2_nic_set_mac_addr;
-		adapter->set_multi = netxen_p2_nic_set_multi;
-		adapter->set_mtu = netxen_nic_set_mtu_xgb;
-		adapter->set_promisc = netxen_p2_nic_set_promisc;
-	} else {
-		adapter->set_mtu = nx_fw_cmd_set_mtu;
-		adapter->set_promisc = netxen_p3_nic_set_promisc;
-		adapter->macaddr_set = netxen_p3_nic_set_mac_addr;
-		adapter->set_multi = netxen_p3_nic_set_multi;
-
-		if (adapter->ahw.port_type == NETXEN_NIC_GBE) {
-			adapter->phy_read = nx_fw_cmd_query_phy;
-			adapter->phy_write = nx_fw_cmd_set_phy;
-		}
-	}
-}
-
 /*
  * netxen_decode_crb_addr(0 - utility to translate from internal Phantom CRB
  * address to external PCI CRB address.
@@ -1395,7 +1372,7 @@ skip:
 
 	if (count) {
 		sds_ring->consumer = consumer;
-		NXWR32(adapter, sds_ring->crb_sts_consumer, consumer);
+		NXWRIO(adapter, sds_ring->crb_sts_consumer, consumer);
 	}
 
 	return count;
@@ -1513,7 +1490,7 @@ netxen_post_rx_buffers(struct netxen_adapter *adapter, u32 ringid,
 
 	if (count) {
 		rds_ring->producer = producer;
-		NXWR32(adapter, rds_ring->crb_rcv_producer,
+		NXWRIO(adapter, rds_ring->crb_rcv_producer,
 				(producer-1) & (rds_ring->num_desc-1));
 
 		if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) {
@@ -1529,9 +1506,10 @@ netxen_post_rx_buffers(struct netxen_adapter *adapter, u32 ringid,
 					      (rds_ring->num_desc - 1)));
 			netxen_set_msg_ctxid(msg, adapter->portnum);
 			netxen_set_msg_opcode(msg, NETXEN_RCV_PRODUCER(ringid));
-			writel(msg,
-			       DB_NORMALIZE(adapter,
+			read_lock(&adapter->adapter_lock);
+			writel(msg, DB_NORMALIZE(adapter,
 					    NETXEN_RCV_PRODUCER_OFFSET));
+			read_unlock(&adapter->adapter_lock);
 		}
 	}
 }
@@ -1573,7 +1551,7 @@ netxen_post_rx_buffers_nodb(struct netxen_adapter *adapter,
 
 	if (count) {
 		rds_ring->producer = producer;
-		NXWR32(adapter, rds_ring->crb_rcv_producer,
+		NXWRIO(adapter, rds_ring->crb_rcv_producer,
 				(producer - 1) & (rds_ring->num_desc - 1));
 	}
 	spin_unlock(&rds_ring->lock);
diff --git a/drivers/net/netxen/netxen_nic_main.c b/drivers/net/netxen/netxen_nic_main.c
index 7038e1b..b2fd713 100644
--- a/drivers/net/netxen/netxen_nic_main.c
+++ b/drivers/net/netxen/netxen_nic_main.c
@@ -116,7 +116,7 @@ void
 netxen_nic_update_cmd_producer(struct netxen_adapter *adapter,
 		struct nx_host_tx_ring *tx_ring)
 {
-	NXWR32(adapter, tx_ring->crb_cmd_producer, tx_ring->producer);
+	NXWRIO(adapter, tx_ring->crb_cmd_producer, tx_ring->producer);
 
 	if (netxen_tx_avail(tx_ring) <= TX_STOP_THRESH) {
 		netif_stop_queue(adapter->netdev);
@@ -133,7 +133,7 @@ static inline void
 netxen_nic_update_cmd_consumer(struct netxen_adapter *adapter,
 		struct nx_host_tx_ring *tx_ring)
 {
-	NXWR32(adapter, tx_ring->crb_cmd_consumer, tx_ring->sw_consumer);
+	NXWRIO(adapter, tx_ring->crb_cmd_consumer, tx_ring->sw_consumer);
 }
 
 static uint32_t msi_tgt_status[8] = {
@@ -149,18 +149,17 @@ static inline void netxen_nic_disable_int(struct nx_host_sds_ring *sds_ring)
 {
 	struct netxen_adapter *adapter = sds_ring->adapter;
 
-	NXWR32(adapter, sds_ring->crb_intr_mask, 0);
+	NXWRIO(adapter, sds_ring->crb_intr_mask, 0);
 }
 
 static inline void netxen_nic_enable_int(struct nx_host_sds_ring *sds_ring)
 {
 	struct netxen_adapter *adapter = sds_ring->adapter;
 
-	NXWR32(adapter, sds_ring->crb_intr_mask, 0x1);
+	NXWRIO(adapter, sds_ring->crb_intr_mask, 0x1);
 
 	if (!NETXEN_IS_MSI_FAMILY(adapter))
-		adapter->pci_write_immediate(adapter,
-				adapter->legacy_intr.tgt_mask_reg, 0xfbff);
+		NXWRIO(adapter, adapter->tgt_mask_reg, 0xfbff);
 }
 
 static int
@@ -556,10 +555,22 @@ netxen_setup_intr(struct netxen_adapter *adapter)
 		legacy_intrp = &legacy_intr[adapter->ahw.pci_func];
 	else
 		legacy_intrp = &legacy_intr[0];
-	adapter->legacy_intr.int_vec_bit = legacy_intrp->int_vec_bit;
-	adapter->legacy_intr.tgt_status_reg = legacy_intrp->tgt_status_reg;
-	adapter->legacy_intr.tgt_mask_reg = legacy_intrp->tgt_mask_reg;
-	adapter->legacy_intr.pci_int_reg = legacy_intrp->pci_int_reg;
+
+	adapter->int_vec_bit = legacy_intrp->int_vec_bit;
+	adapter->tgt_status_reg = netxen_get_ioaddr(adapter,
+			legacy_intrp->tgt_status_reg);
+	adapter->tgt_mask_reg = netxen_get_ioaddr(adapter,
+			legacy_intrp->tgt_mask_reg);
+	adapter->pci_int_reg = netxen_get_ioaddr(adapter,
+			legacy_intrp->pci_int_reg);
+	adapter->isr_int_vec = netxen_get_ioaddr(adapter, ISR_INT_VECTOR);
+
+	if (adapter->ahw.revision_id >= NX_P3_B1)
+		adapter->crb_int_state_reg = netxen_get_ioaddr(adapter,
+			ISR_INT_STATE_REG);
+	else
+		adapter->crb_int_state_reg = netxen_get_ioaddr(adapter,
+			CRB_INT_VECTOR);
 
 	netxen_set_msix_bit(pdev, 0);
 
@@ -586,8 +597,8 @@ netxen_setup_intr(struct netxen_adapter *adapter)
 
 	if (use_msi && !pci_enable_msi(pdev)) {
 		adapter->flags |= NETXEN_NIC_MSI_ENABLED;
-		adapter->msi_tgt_status =
-			msi_tgt_status[adapter->ahw.pci_func];
+		adapter->tgt_status_reg = netxen_get_ioaddr(adapter,
+				msi_tgt_status[adapter->ahw.pci_func]);
 		dev_info(&pdev->dev, "using msi interrupts\n");
 		adapter->msix_entries[0].vector = pdev->irq;
 		return;
@@ -647,14 +658,6 @@ netxen_setup_pci_map(struct netxen_adapter *adapter)
 	mem_len = pci_resource_len(pdev, 0);
 	pci_len0 = 0;
 
-	adapter->hw_write_wx = netxen_nic_hw_write_wx_128M;
-	adapter->hw_read_wx = netxen_nic_hw_read_wx_128M;
-	adapter->pci_read_immediate = netxen_nic_pci_read_immediate_128M;
-	adapter->pci_write_immediate = netxen_nic_pci_write_immediate_128M;
-	adapter->pci_set_window = netxen_nic_pci_set_window_128M;
-	adapter->pci_mem_read = netxen_nic_pci_mem_read_128M;
-	adapter->pci_mem_write = netxen_nic_pci_mem_write_128M;
-
 	/* 128 Meg of memory */
 	if (mem_len == NETXEN_PCI_128MB_SIZE) {
 		mem_ptr0 = ioremap(mem_base, FIRST_PAGE_GROUP_SIZE);
@@ -667,14 +670,6 @@ netxen_setup_pci_map(struct netxen_adapter *adapter)
 		mem_ptr2 = ioremap(mem_base + THIRD_PAGE_GROUP_START -
 			SECOND_PAGE_GROUP_START, THIRD_PAGE_GROUP_SIZE);
 	} else if (mem_len == NETXEN_PCI_2MB_SIZE) {
-		adapter->hw_write_wx = netxen_nic_hw_write_wx_2M;
-		adapter->hw_read_wx = netxen_nic_hw_read_wx_2M;
-		adapter->pci_read_immediate = netxen_nic_pci_read_immediate_2M;
-		adapter->pci_write_immediate =
-			netxen_nic_pci_write_immediate_2M;
-		adapter->pci_set_window = netxen_nic_pci_set_window_2M;
-		adapter->pci_mem_read = netxen_nic_pci_mem_read_2M;
-		adapter->pci_mem_write = netxen_nic_pci_mem_write_2M;
 
 		mem_ptr0 = pci_ioremap_bar(pdev, 0);
 		if (mem_ptr0 == NULL) {
@@ -698,6 +693,8 @@ netxen_setup_pci_map(struct netxen_adapter *adapter)
 		return -EIO;
 	}
 
+	netxen_setup_hwops(adapter);
+
 	dev_info(&pdev->dev, "%dMB memory map\n", (int)(mem_len>>20));
 
 	adapter->ahw.pci_base0 = mem_ptr0;
@@ -990,8 +987,10 @@ netxen_nic_attach(struct netxen_adapter *adapter)
 
 	if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) {
 		tx_ring = adapter->tx_ring;
-		tx_ring->crb_cmd_producer = crb_cmd_producer[adapter->portnum];
-		tx_ring->crb_cmd_consumer = crb_cmd_consumer[adapter->portnum];
+		tx_ring->crb_cmd_producer = netxen_get_ioaddr(adapter,
+				crb_cmd_producer[adapter->portnum]);
+		tx_ring->crb_cmd_consumer = netxen_get_ioaddr(adapter,
+				crb_cmd_consumer[adapter->portnum]);
 
 		tx_ring->producer = 0;
 		tx_ring->sw_consumer = 0;
@@ -1213,8 +1212,6 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 		goto err_out_iounmap;
 	}
 
-	netxen_initialize_adapter_ops(adapter);
-
 	/* Mezz cards have PCI function 0,2,3 enabled */
 	switch (adapter->ahw.board_type) {
 	case NETXEN_BRDTYPE_P2_SB31_10G_IMEZ:
@@ -1870,41 +1867,37 @@ static irqreturn_t netxen_intr(int irq, void *data)
 	struct netxen_adapter *adapter = sds_ring->adapter;
 	u32 status = 0;
 
-	status = adapter->pci_read_immediate(adapter, ISR_INT_VECTOR);
+	status = readl(adapter->isr_int_vec);
 
-	if (!(status & adapter->legacy_intr.int_vec_bit))
+	if (!(status & adapter->int_vec_bit))
 		return IRQ_NONE;
 
-	if (adapter->ahw.revision_id >= NX_P3_B1) {
+	if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) {
 		/* check interrupt state machine, to be sure */
-		status = adapter->pci_read_immediate(adapter,
-				ISR_INT_STATE_REG);
+		status = readl(adapter->crb_int_state_reg);
 		if (!ISR_LEGACY_INT_TRIGGERED(status))
 			return IRQ_NONE;
 
 	} else {
 		unsigned long our_int = 0;
 
-		our_int = NXRD32(adapter, CRB_INT_VECTOR);
+		our_int = readl(adapter->crb_int_state_reg);
 
 		/* not our interrupt */
 		if (!test_and_clear_bit((7 + adapter->portnum), &our_int))
 			return IRQ_NONE;
 
 		/* claim interrupt */
-		NXWR32(adapter, CRB_INT_VECTOR, (our_int & 0xffffffff));
-	}
+		writel((our_int & 0xffffffff), adapter->crb_int_state_reg);
 
-	/* clear interrupt */
-	if (NX_IS_REVISION_P2(adapter->ahw.revision_id))
+		/* clear interrupt */
 		netxen_nic_disable_int(sds_ring);
+	}
 
-	adapter->pci_write_immediate(adapter,
-			adapter->legacy_intr.tgt_status_reg,
-			0xffffffff);
+	writel(0xffffffff, adapter->tgt_status_reg);
 	/* read twice to ensure write is flushed */
-	adapter->pci_read_immediate(adapter, ISR_INT_VECTOR);
-	adapter->pci_read_immediate(adapter, ISR_INT_VECTOR);
+	readl(adapter->isr_int_vec);
+	readl(adapter->isr_int_vec);
 
 	napi_schedule(&sds_ring->napi);
 
@@ -1917,8 +1910,7 @@ static irqreturn_t netxen_msi_intr(int irq, void *data)
 	struct netxen_adapter *adapter = sds_ring->adapter;
 
 	/* clear interrupt */
-	adapter->pci_write_immediate(adapter,
-			adapter->msi_tgt_status, 0xffffffff);
+	writel(0xffffffff, adapter->tgt_status_reg);
 
 	napi_schedule(&sds_ring->napi);
 	return IRQ_HANDLED;
-- 
1.6.0.2


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH NEXT 5/6] netxen: refactor firmware info code
  2009-09-06  3:43 [PATCH NEXT 0/6] nexten: fixes and enhancements Dhananjay Phadke
                   ` (3 preceding siblings ...)
  2009-09-06  3:43 ` [PATCH NEXT 4/6] netxen: pre calculate register addresses Dhananjay Phadke
@ 2009-09-06  3:43 ` Dhananjay Phadke
  2009-09-06  3:43 ` [PATCH NEXT 6/6] netxen: update version to 4.0.50 Dhananjay Phadke
  2009-09-07  8:54 ` [PATCH NEXT 0/6] nexten: fixes and enhancements David Miller
  6 siblings, 0 replies; 8+ messages in thread
From: Dhananjay Phadke @ 2009-09-06  3:43 UTC (permalink / raw)
  To: davem; +Cc: netdev

o Combine netxen_get_firmware_info(), netxen_check_options()
  so that they are updated every time firmware is reset.
o Set dma mask everytime firmware is reset.

Signed-off-by: Dhananjay Phadke <dhananjay@netxen.com>
---
 drivers/net/netxen/netxen_nic.h      |    1 -
 drivers/net/netxen/netxen_nic_hw.c   |   59 --------------
 drivers/net/netxen/netxen_nic_main.c |  141 +++++++++++++++++++++++----------
 3 files changed, 98 insertions(+), 103 deletions(-)

diff --git a/drivers/net/netxen/netxen_nic.h b/drivers/net/netxen/netxen_nic.h
index 5bbc40b..df03ea4 100644
--- a/drivers/net/netxen/netxen_nic.h
+++ b/drivers/net/netxen/netxen_nic.h
@@ -1263,7 +1263,6 @@ void netxen_pcie_sem_unlock(struct netxen_adapter *, int);
 	netxen_pcie_sem_unlock((a), 7)
 
 int netxen_nic_get_board_info(struct netxen_adapter *adapter);
-void netxen_nic_get_firmware_info(struct netxen_adapter *adapter);
 int netxen_nic_wol_supported(struct netxen_adapter *adapter);
 
 /* Functions from netxen_nic_init.c */
diff --git a/drivers/net/netxen/netxen_nic_hw.c b/drivers/net/netxen/netxen_nic_hw.c
index cbfd610..555bc4a 100644
--- a/drivers/net/netxen/netxen_nic_hw.c
+++ b/drivers/net/netxen/netxen_nic_hw.c
@@ -2240,65 +2240,6 @@ void netxen_nic_set_link_parameters(struct netxen_adapter *adapter)
 	}
 }
 
-void netxen_nic_get_firmware_info(struct netxen_adapter *adapter)
-{
-	u32 fw_major, fw_minor, fw_build;
-	char brd_name[NETXEN_MAX_SHORT_NAME];
-	char serial_num[32];
-	int i, offset, val;
-	int *ptr32;
-	struct pci_dev *pdev = adapter->pdev;
-
-	adapter->driver_mismatch = 0;
-
-	ptr32 = (int *)&serial_num;
-	offset = NX_FW_SERIAL_NUM_OFFSET;
-	for (i = 0; i < 8; i++) {
-		if (netxen_rom_fast_read(adapter, offset, &val) == -1) {
-			dev_err(&pdev->dev, "error reading board info\n");
-			adapter->driver_mismatch = 1;
-			return;
-		}
-		ptr32[i] = cpu_to_le32(val);
-		offset += sizeof(u32);
-	}
-
-	fw_major = NXRD32(adapter, NETXEN_FW_VERSION_MAJOR);
-	fw_minor = NXRD32(adapter, NETXEN_FW_VERSION_MINOR);
-	fw_build = NXRD32(adapter, NETXEN_FW_VERSION_SUB);
-
-	adapter->fw_version = NETXEN_VERSION_CODE(fw_major, fw_minor, fw_build);
-
-	if (adapter->portnum == 0) {
-		get_brd_name_by_type(adapter->ahw.board_type, brd_name);
-
-		printk(KERN_INFO "NetXen %s Board S/N %s  Chip rev 0x%x\n",
-				brd_name, serial_num, adapter->ahw.revision_id);
-	}
-
-	if (adapter->fw_version < NETXEN_VERSION_CODE(3, 4, 216)) {
-		adapter->driver_mismatch = 1;
-		dev_warn(&pdev->dev, "firmware version %d.%d.%d unsupported\n",
-				fw_major, fw_minor, fw_build);
-		return;
-	}
-
-	dev_info(&pdev->dev, "firmware version %d.%d.%d\n",
-			fw_major, fw_minor, fw_build);
-
-	if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) {
-		i = NXRD32(adapter, NETXEN_SRE_MISC);
-		adapter->ahw.cut_through = (i & 0x8000) ? 1 : 0;
-		dev_info(&pdev->dev, "firmware running in %s mode\n",
-		adapter->ahw.cut_through ? "cut-through" : "legacy");
-	}
-
-	if (adapter->fw_version >= NETXEN_VERSION_CODE(4, 0, 222))
-		adapter->capabilities = NXRD32(adapter, CRB_FW_CAPABILITIES_1);
-
-	adapter->flags &= ~NETXEN_NIC_LRO_ENABLED;
-}
-
 int
 netxen_nic_wol_supported(struct netxen_adapter *adapter)
 {
diff --git a/drivers/net/netxen/netxen_nic_main.c b/drivers/net/netxen/netxen_nic_main.c
index b2fd713..304618a 100644
--- a/drivers/net/netxen/netxen_nic_main.c
+++ b/drivers/net/netxen/netxen_nic_main.c
@@ -318,44 +318,6 @@ err_out:
 	return err;
 }
 
-static void
-netxen_check_options(struct netxen_adapter *adapter)
-{
-	if (adapter->ahw.port_type == NETXEN_NIC_XGBE) {
-		adapter->num_rxd = DEFAULT_RCV_DESCRIPTORS_10G;
-		adapter->num_jumbo_rxd = MAX_JUMBO_RCV_DESCRIPTORS_10G;
-	} else if (adapter->ahw.port_type == NETXEN_NIC_GBE) {
-		adapter->num_rxd = DEFAULT_RCV_DESCRIPTORS_1G;
-		adapter->num_jumbo_rxd = MAX_JUMBO_RCV_DESCRIPTORS_1G;
-	}
-
-	adapter->msix_supported = 0;
-	if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) {
-		adapter->msix_supported = !!use_msi_x;
-		adapter->rss_supported = !!use_msi_x;
-	} else if (adapter->fw_version >= NETXEN_VERSION_CODE(3, 4, 336)) {
-		switch (adapter->ahw.board_type) {
-		case NETXEN_BRDTYPE_P2_SB31_10G:
-		case NETXEN_BRDTYPE_P2_SB31_10G_CX4:
-			adapter->msix_supported = !!use_msi_x;
-			adapter->rss_supported = !!use_msi_x;
-			break;
-		default:
-			break;
-		}
-	}
-
-	adapter->num_txd = MAX_CMD_DESCRIPTORS;
-
-	if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) {
-		adapter->num_lro_rxd = MAX_LRO_RCV_DESCRIPTORS;
-		adapter->max_rds_rings = 3;
-	} else {
-		adapter->num_lro_rxd = 0;
-		adapter->max_rds_rings = 2;
-	}
-}
-
 static int
 netxen_check_hw_init(struct netxen_adapter *adapter, int first_boot)
 {
@@ -733,12 +695,110 @@ err_out:
 	return err;
 }
 
+static void
+netxen_check_options(struct netxen_adapter *adapter)
+{
+	u32 fw_major, fw_minor, fw_build;
+	char brd_name[NETXEN_MAX_SHORT_NAME];
+	char serial_num[32];
+	int i, offset, val;
+	int *ptr32;
+	struct pci_dev *pdev = adapter->pdev;
+
+	adapter->driver_mismatch = 0;
+
+	ptr32 = (int *)&serial_num;
+	offset = NX_FW_SERIAL_NUM_OFFSET;
+	for (i = 0; i < 8; i++) {
+		if (netxen_rom_fast_read(adapter, offset, &val) == -1) {
+			dev_err(&pdev->dev, "error reading board info\n");
+			adapter->driver_mismatch = 1;
+			return;
+		}
+		ptr32[i] = cpu_to_le32(val);
+		offset += sizeof(u32);
+	}
+
+	fw_major = NXRD32(adapter, NETXEN_FW_VERSION_MAJOR);
+	fw_minor = NXRD32(adapter, NETXEN_FW_VERSION_MINOR);
+	fw_build = NXRD32(adapter, NETXEN_FW_VERSION_SUB);
+
+	adapter->fw_version = NETXEN_VERSION_CODE(fw_major, fw_minor, fw_build);
+
+	if (adapter->portnum == 0) {
+		get_brd_name_by_type(adapter->ahw.board_type, brd_name);
+
+		printk(KERN_INFO "NetXen %s Board S/N %s  Chip rev 0x%x\n",
+				brd_name, serial_num, adapter->ahw.revision_id);
+	}
+
+	if (adapter->fw_version < NETXEN_VERSION_CODE(3, 4, 216)) {
+		adapter->driver_mismatch = 1;
+		dev_warn(&pdev->dev, "firmware version %d.%d.%d unsupported\n",
+				fw_major, fw_minor, fw_build);
+		return;
+	}
+
+	if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) {
+		i = NXRD32(adapter, NETXEN_SRE_MISC);
+		adapter->ahw.cut_through = (i & 0x8000) ? 1 : 0;
+	}
+
+	dev_info(&pdev->dev, "firmware v%d.%d.%d [%s]\n",
+			fw_major, fw_minor, fw_build,
+			adapter->ahw.cut_through ? "cut-through" : "legacy");
+
+	if (adapter->fw_version >= NETXEN_VERSION_CODE(4, 0, 222))
+		adapter->capabilities = NXRD32(adapter, CRB_FW_CAPABILITIES_1);
+
+	adapter->flags &= ~NETXEN_NIC_LRO_ENABLED;
+
+	if (adapter->ahw.port_type == NETXEN_NIC_XGBE) {
+		adapter->num_rxd = DEFAULT_RCV_DESCRIPTORS_10G;
+		adapter->num_jumbo_rxd = MAX_JUMBO_RCV_DESCRIPTORS_10G;
+	} else if (adapter->ahw.port_type == NETXEN_NIC_GBE) {
+		adapter->num_rxd = DEFAULT_RCV_DESCRIPTORS_1G;
+		adapter->num_jumbo_rxd = MAX_JUMBO_RCV_DESCRIPTORS_1G;
+	}
+
+	adapter->msix_supported = 0;
+	if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) {
+		adapter->msix_supported = !!use_msi_x;
+		adapter->rss_supported = !!use_msi_x;
+	} else if (adapter->fw_version >= NETXEN_VERSION_CODE(3, 4, 336)) {
+		switch (adapter->ahw.board_type) {
+		case NETXEN_BRDTYPE_P2_SB31_10G:
+		case NETXEN_BRDTYPE_P2_SB31_10G_CX4:
+			adapter->msix_supported = !!use_msi_x;
+			adapter->rss_supported = !!use_msi_x;
+			break;
+		default:
+			break;
+		}
+	}
+
+	adapter->num_txd = MAX_CMD_DESCRIPTORS;
+
+	if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) {
+		adapter->num_lro_rxd = MAX_LRO_RCV_DESCRIPTORS;
+		adapter->max_rds_rings = 3;
+	} else {
+		adapter->num_lro_rxd = 0;
+		adapter->max_rds_rings = 2;
+	}
+}
+
 static int
 netxen_start_firmware(struct netxen_adapter *adapter)
 {
 	int val, err, first_boot;
 	struct pci_dev *pdev = adapter->pdev;
 
+	/* required for NX2031 dummy dma */
+	err = nx_set_dma_mask(adapter);
+	if (err)
+		return err;
+
 	if (!netxen_can_start_firmware(adapter))
 		goto wait_init;
 
@@ -811,7 +871,6 @@ wait_init:
 
 	nx_update_dma_mask(adapter);
 
-	netxen_nic_get_firmware_info(adapter);
 	netxen_check_options(adapter);
 
 	return 0;
@@ -1191,10 +1250,6 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 	revision_id = pdev->revision;
 	adapter->ahw.revision_id = revision_id;
 
-	err = nx_set_dma_mask(adapter);
-	if (err)
-		goto err_out_free_netdev;
-
 	rwlock_init(&adapter->adapter_lock);
 	spin_lock_init(&adapter->tx_clean_lock);
 	INIT_LIST_HEAD(&adapter->mac_list);
-- 
1.6.0.2


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH NEXT 6/6] netxen: update version to 4.0.50
  2009-09-06  3:43 [PATCH NEXT 0/6] nexten: fixes and enhancements Dhananjay Phadke
                   ` (4 preceding siblings ...)
  2009-09-06  3:43 ` [PATCH NEXT 5/6] netxen: refactor firmware info code Dhananjay Phadke
@ 2009-09-06  3:43 ` Dhananjay Phadke
  2009-09-07  8:54 ` [PATCH NEXT 0/6] nexten: fixes and enhancements David Miller
  6 siblings, 0 replies; 8+ messages in thread
From: Dhananjay Phadke @ 2009-09-06  3:43 UTC (permalink / raw)
  To: davem; +Cc: netdev

Signed-off-by: Dhananjay Phadke <dhananjay@netxen.com>
---
 drivers/net/netxen/netxen_nic.h |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/net/netxen/netxen_nic.h b/drivers/net/netxen/netxen_nic.h
index df03ea4..2a52479 100644
--- a/drivers/net/netxen/netxen_nic.h
+++ b/drivers/net/netxen/netxen_nic.h
@@ -58,8 +58,8 @@
 
 #define _NETXEN_NIC_LINUX_MAJOR 4
 #define _NETXEN_NIC_LINUX_MINOR 0
-#define _NETXEN_NIC_LINUX_SUBVERSION 41
-#define NETXEN_NIC_LINUX_VERSIONID  "4.0.41"
+#define _NETXEN_NIC_LINUX_SUBVERSION 50
+#define NETXEN_NIC_LINUX_VERSIONID  "4.0.50"
 
 #define NETXEN_VERSION_CODE(a, b, c)	(((a) << 24) + ((b) << 16) + (c))
 #define _major(v)	(((v) >> 24) & 0xff)
-- 
1.6.0.2


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* Re: [PATCH NEXT 0/6] nexten: fixes and enhancements
  2009-09-06  3:43 [PATCH NEXT 0/6] nexten: fixes and enhancements Dhananjay Phadke
                   ` (5 preceding siblings ...)
  2009-09-06  3:43 ` [PATCH NEXT 6/6] netxen: update version to 4.0.50 Dhananjay Phadke
@ 2009-09-07  8:54 ` David Miller
  6 siblings, 0 replies; 8+ messages in thread
From: David Miller @ 2009-09-07  8:54 UTC (permalink / raw)
  To: dhananjay; +Cc: netdev

From: Dhananjay Phadke <dhananjay@netxen.com>
Date: Sat,  5 Sep 2009 20:43:06 -0700

> Series of 6 driver enhancements / fixes, please apply to net-next-2.6.

All applied, thanks.

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2009-09-07  8:54 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-09-06  3:43 [PATCH NEXT 0/6] nexten: fixes and enhancements Dhananjay Phadke
2009-09-06  3:43 ` [PATCH NEXT 1/6] netxen: handle firmware load errors Dhananjay Phadke
2009-09-06  3:43 ` [PATCH NEXT 2/6] netxen: firmware hang detection Dhananjay Phadke
2009-09-06  3:43 ` [PATCH NEXT 3/6] netxen: fix ip addr hashing after firmware reset Dhananjay Phadke
2009-09-06  3:43 ` [PATCH NEXT 4/6] netxen: pre calculate register addresses Dhananjay Phadke
2009-09-06  3:43 ` [PATCH NEXT 5/6] netxen: refactor firmware info code Dhananjay Phadke
2009-09-06  3:43 ` [PATCH NEXT 6/6] netxen: update version to 4.0.50 Dhananjay Phadke
2009-09-07  8:54 ` [PATCH NEXT 0/6] nexten: fixes and enhancements David Miller

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).