RESEND [PATCH 2/3] NetXen: Support per PCI-function interrupt mask registers
authordhananjay.phadke@gmail.com <dhananjay.phadke@gmail.com>
Sun, 1 Jul 2007 18:56:00 +0000 (00:26 +0530)
committerJeff Garzik <jeff@garzik.org>
Mon, 2 Jul 2007 12:24:52 +0000 (08:24 -0400)
This patch updates the various access routines to access different
control and status settings present in different register locations.
This will fix problems related to working of different ports in
multi Port card.

Signed-off by: Dhananjay Phadke <dhananjay@netxen.com>
Signed-off by: Milan Bag <mbag@netxen.com>

Signed-off-by: Jeff Garzik <jeff@garzik.org>
drivers/net/netxen/netxen_nic.h
drivers/net/netxen/netxen_nic_hw.c
drivers/net/netxen/netxen_nic_init.c
drivers/net/netxen/netxen_nic_main.c
drivers/net/netxen/netxen_nic_phan_reg.h

index 91f25e0a638ea64c21fd42910e4c0a2880abf649..6ce93fcbed328d2c64a954e9f855d3e823795de8 100644 (file)
@@ -937,6 +937,7 @@ struct netxen_adapter {
        struct netxen_ring_ctx *ctx_desc;
        struct pci_dev *ctx_desc_pdev;
        dma_addr_t ctx_desc_phys_addr;
+       int intr_scheme;
        int (*enable_phy_interrupts) (struct netxen_adapter *);
        int (*disable_phy_interrupts) (struct netxen_adapter *);
        void (*handle_phy_intr) (struct netxen_adapter *);
@@ -1080,37 +1081,106 @@ struct net_device_stats *netxen_nic_get_stats(struct net_device *netdev);
 
 static inline void netxen_nic_disable_int(struct netxen_adapter *adapter)
 {
-       /*
-        * ISR_INT_MASK: Can be read from window 0 or 1.
-        */
-       writel(0x7ff, PCI_OFFSET_SECOND_RANGE(adapter, ISR_INT_MASK));
+       uint32_t        mask = 0x7ff;
+       int retries = 32;
+
+       DPRINTK(1, INFO, "Entered ISR Disable \n");
+
+       switch (adapter->portnum) {
+       case 0:
+               writel(0x0, NETXEN_CRB_NORMALIZE(adapter, CRB_SW_INT_MASK_0));
+               break;
+       case 1:
+               writel(0x0, NETXEN_CRB_NORMALIZE(adapter, CRB_SW_INT_MASK_1));
+               break;
+       case 2:
+               writel(0x0, NETXEN_CRB_NORMALIZE(adapter, CRB_SW_INT_MASK_2));
+               break;
+       case 3:
+               writel(0x0, NETXEN_CRB_NORMALIZE(adapter, CRB_SW_INT_MASK_3));
+               break;
+       }
+
+       if (adapter->intr_scheme != -1 &&
+               adapter->intr_scheme != INTR_SCHEME_PERPORT) {
+               writel(mask,
+                       (void *)(PCI_OFFSET_SECOND_RANGE(adapter, ISR_INT_MASK)));
+       }
+
+       /* Window = 0 or 1 */
+       if (!(adapter->flags & NETXEN_NIC_MSI_ENABLED)) {
+               do {
+                       writel(0xffffffff, (void *)
+                               (PCI_OFFSET_SECOND_RANGE(adapter, ISR_INT_TARGET_STATUS)));
+                       mask = readl((void *)
+                                       (pci_base_offset(adapter, ISR_INT_VECTOR)));
+                       if (!(mask & 0x80))
+                               break;
+                       udelay(10);
+               } while (--retries);
+
+               if (!retries) {
+                       printk(KERN_NOTICE "%s: Failed to disable interrupt completely\n",
+                                       netxen_nic_driver_name);
+               }
+       }
+
+       DPRINTK(1, INFO, "Done with Disable Int\n");
 
+       return;
 }
 
 static inline void netxen_nic_enable_int(struct netxen_adapter *adapter)
 {
        u32 mask;
 
-       switch (adapter->ahw.board_type) {
-       case NETXEN_NIC_GBE:
-               mask = 0x77b;
+       DPRINTK(1, INFO, "Entered ISR Enable \n");
+
+       if (adapter->intr_scheme != -1 &&
+               adapter->intr_scheme != INTR_SCHEME_PERPORT) {
+               switch (adapter->ahw.board_type) {
+               case NETXEN_NIC_GBE:
+                       mask  =  0x77b;
+                       break;
+               case NETXEN_NIC_XGBE:
+                       mask  =  0x77f;
+                       break;
+               default:
+                       mask  =  0x7ff;
+                       break;
+               }
+
+               writel(mask,
+                       (void *)(PCI_OFFSET_SECOND_RANGE(adapter, ISR_INT_MASK)));
+       }
+       switch (adapter->portnum) {
+       case 0:
+               writel(0x1, NETXEN_CRB_NORMALIZE(adapter, CRB_SW_INT_MASK_0));
                break;
-       case NETXEN_NIC_XGBE:
-               mask = 0x77f;
+       case 1:
+               writel(0x1, NETXEN_CRB_NORMALIZE(adapter, CRB_SW_INT_MASK_1));
                break;
-       default:
-               mask = 0x7ff;
+       case 2:
+               writel(0x1, NETXEN_CRB_NORMALIZE(adapter, CRB_SW_INT_MASK_2));
+               break;
+       case 3:
+               writel(0x1, NETXEN_CRB_NORMALIZE(adapter, CRB_SW_INT_MASK_3));
                break;
        }
 
-       writel(mask, PCI_OFFSET_SECOND_RANGE(adapter, ISR_INT_MASK));
-
        if (!(adapter->flags & NETXEN_NIC_MSI_ENABLED)) {
                mask = 0xbff;
-               writel(0X0, NETXEN_CRB_NORMALIZE(adapter, CRB_INT_VECTOR));
-               writel(mask, PCI_OFFSET_SECOND_RANGE(adapter,
-                                                    ISR_INT_TARGET_MASK));
+               if (adapter->intr_scheme != -1 &&
+                       adapter->intr_scheme != INTR_SCHEME_PERPORT) {
+                       writel(0X0, NETXEN_CRB_NORMALIZE(adapter, CRB_INT_VECTOR));
+               }
+               writel(mask,
+                       (void *)(PCI_OFFSET_SECOND_RANGE(adapter, ISR_INT_TARGET_MASK)));
        }
+
+       DPRINTK(1, INFO, "Done with enable Int\n");
+
+       return;
 }
 
 /*
index c012764d114578a2414132370a7752ae9d7e8656..2b40a5a19c47848c04180b54daf4841011c068f1 100644 (file)
@@ -392,7 +392,11 @@ int netxen_nic_hw_resources(struct netxen_adapter *adapter)
                        return err;
                }
        }
-       DPRINTK(INFO, "Recieve Peg ready too. starting stuff\n");
+       adapter->intr_scheme = readl(
+               NETXEN_CRB_NORMALIZE(adapter, CRB_NIC_CAPABILITIES_FW));
+       printk(KERN_NOTICE "%s: FW capabilities:0x%x\n", netdev->name,
+                       adapter->intr_scheme);
+       DPRINTK(INFO, "Receive Peg ready too. starting stuff\n");
 
        addr = netxen_alloc(adapter->ahw.pdev,
                            sizeof(struct netxen_ring_ctx) +
index bb23f4c360db39368db8681d8bb74289a5d760a7..15f6dc5a1cf773788c48eb70258a0ffcd55120be 100644 (file)
@@ -139,6 +139,8 @@ int netxen_init_firmware(struct netxen_adapter *adapter)
                return err;
        }
        /* Window 1 call */
+       writel(INTR_SCHEME_PERPORT,
+              NETXEN_CRB_NORMALIZE(adapter, CRB_NIC_CAPABILITIES_HOST));
        writel(MPORT_MULTI_FUNCTION_MODE,
               NETXEN_CRB_NORMALIZE(adapter, CRB_MPORT_MODE));
        writel(PHAN_INITIALIZE_ACK,
index 663bc47c1f63fa06ad948a933b8cf73fbad99e25..dba8e6b29ff3d5c45264de95588d1db4bc821573 100644 (file)
@@ -308,7 +308,13 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 
        adapter->netdev  = netdev;
        adapter->pdev    = pdev;
+
+       /* this will be read from FW later */
+       adapter->intr_scheme = -1;
+
+       /* This will be reset for mezz cards  */
        adapter->portnum = pci_func_id;
+       adapter->status   &= ~NETXEN_NETDEV_STATUS;
 
        netdev->open               = netxen_nic_open;
        netdev->stop               = netxen_nic_close;
@@ -1100,28 +1106,26 @@ static int
 netxen_handle_int(struct netxen_adapter *adapter, struct net_device *netdev)
 {
        u32 ret = 0;
+       u32 our_int = 0;
 
        DPRINTK(INFO, "Entered handle ISR\n");
        adapter->stats.ints++;
 
        if (!(adapter->flags & NETXEN_NIC_MSI_ENABLED)) {
-               int count = 0;
-               u32 mask;
-               u32 our_int = 0;
                our_int = readl(NETXEN_CRB_NORMALIZE(adapter, CRB_INT_VECTOR));
                /* not our interrupt */
                if ((our_int & (0x80 << adapter->portnum)) == 0)
                        return ret;
-               netxen_nic_disable_int(adapter);
-               /* Window = 0 or 1 */
-               do {
-                       writel(0xffffffff, PCI_OFFSET_SECOND_RANGE(adapter,
-                                               ISR_INT_TARGET_STATUS));
-                       mask = readl(pci_base_offset(adapter, ISR_INT_VECTOR));
-               } while (((mask & 0x80) != 0) && (++count < 32));
-               if ((mask & 0x80) != 0)
-                       printk("Could not disable interrupt completely\n");
+       }
 
+       netxen_nic_disable_int(adapter);
+
+       if (adapter->intr_scheme == INTR_SCHEME_PERPORT) {
+               /* claim interrupt */
+               if (!(adapter->flags & NETXEN_NIC_MSI_ENABLED)) {
+                       writel(our_int & ~((u32)(0x80 << adapter->portnum)),
+                       NETXEN_CRB_NORMALIZE(adapter, CRB_INT_VECTOR));
+               }
        }
 
        if (netxen_nic_rx_has_work(adapter) || netxen_nic_tx_has_work(adapter)) {
@@ -1133,7 +1137,7 @@ netxen_handle_int(struct netxen_adapter *adapter, struct net_device *netdev)
                } else {
                        static unsigned int intcount = 0;
                        if ((++intcount & 0xfff) == 0xfff)
-                               printk(KERN_ERR
+                               DPRINTK(KERN_ERR
                                       "%s: %s interrupt %d while in poll\n",
                                       netxen_nic_driver_name, netdev->name,
                                       intcount);
index 9457fc7249c86ed77fc9bdf367be152ea2fa0ac2..10fe6fafa6f6cee24c92fdf69e1fca3806fc7540 100644 (file)
 #define CRB_V2P_3                  NETXEN_NIC_REG(0x29c)
 #define CRB_V2P(port)              (CRB_V2P_0+((port)*4))
 #define CRB_DRIVER_VERSION         NETXEN_NIC_REG(0x2a0)
+/* sw int status/mask registers */
+#define CRB_SW_INT_MASK_0         NETXEN_NIC_REG(0x1d8)
+#define CRB_SW_INT_MASK_1         NETXEN_NIC_REG(0x1e0)
+#define CRB_SW_INT_MASK_2         NETXEN_NIC_REG(0x1e4)
+#define CRB_SW_INT_MASK_3         NETXEN_NIC_REG(0x1e8)
+
+/*
+ * capabilities register, can be used to selectively enable/disable features
+ * for backward compability
+ */
+#define CRB_NIC_CAPABILITIES_HOST      NETXEN_NIC_REG(0x1a8)
+#define CRB_NIC_CAPABILITIES_FW                NETXEN_NIC_REG(0x1dc)
+
+#define INTR_SCHEME_PERPORT            0x1
 
 /* used for ethtool tests */
 #define CRB_SCRATCHPAD_TEST        NETXEN_NIC_REG(0x280)