netxen: add access to on chip memory for tools
authorDhananjay Phadke <dhananjay@netxen.com>
Tue, 13 Oct 2009 05:31:42 +0000 (05:31 +0000)
committerDavid S. Miller <davem@davemloft.net>
Tue, 13 Oct 2009 18:48:19 +0000 (11:48 -0700)
Add access to on chip memory, this is used by
debug and diagnostic tools only.

Signed-off-by: Dhananjay Phadke <dhananjay@netxen.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/netxen/netxen_nic.h
drivers/net/netxen/netxen_nic_hw.c
drivers/net/netxen/netxen_nic_main.c

index db5c8d2..eef9e66 100644 (file)
@@ -543,13 +543,13 @@ struct netxen_hardware_context {
        void __iomem *pci_base1;
        void __iomem *pci_base2;
        void __iomem *db_base;
+       void __iomem *ocm_win_crb;
+
        unsigned long db_len;
        unsigned long pci_len0;
 
-       int qdr_sn_window;
-       int ddr_mn_window;
-       u32 mn_win_crb;
-       u32 ms_win_crb;
+       u32 ocm_win;
+       u32 resv1;
 
        u8 cut_through;
        u8 revision_id;
@@ -1183,8 +1183,7 @@ struct netxen_adapter {
        int (*pci_mem_read)(struct netxen_adapter *, u64, u64 *);
        int (*pci_mem_write)(struct netxen_adapter *, u64, u64);
 
-       unsigned long (*pci_set_window)(struct netxen_adapter *,
-                       unsigned long long);
+       int (*pci_set_window)(struct netxen_adapter *, u64, u32 *);
 
        u32 (*io_read)(struct netxen_adapter *, void __iomem *);
        void (*io_write)(struct netxen_adapter *, void __iomem *, u32);
index 5f4bdda..f677752 100644 (file)
@@ -1274,72 +1274,6 @@ netxen_nic_hw_read_wx_2M(struct netxen_adapter *adapter, ulong off)
        return data;
 }
 
-static int netxen_pci_set_window_warning_count;
-
-static unsigned long
-netxen_nic_pci_set_window_128M(struct netxen_adapter *adapter,
-               unsigned long long addr)
-{
-       void __iomem *offset;
-       int window;
-       unsigned long long      qdr_max;
-       uint8_t func = adapter->ahw.pci_func;
-
-       if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) {
-               qdr_max = NETXEN_ADDR_QDR_NET_MAX_P2;
-       } else {
-               qdr_max = NETXEN_ADDR_QDR_NET_MAX_P3;
-       }
-
-       if (ADDR_IN_RANGE(addr, NETXEN_ADDR_DDR_NET, NETXEN_ADDR_DDR_NET_MAX)) {
-               /* DDR network side */
-               addr -= NETXEN_ADDR_DDR_NET;
-               window = (addr >> 25) & 0x3ff;
-               if (adapter->ahw.ddr_mn_window != window) {
-                       adapter->ahw.ddr_mn_window = window;
-                       offset = PCI_OFFSET_SECOND_RANGE(adapter,
-                               NETXEN_PCIX_PH_REG(PCIE_MN_WINDOW_REG(func)));
-                       writel(window, offset);
-                       /* MUST make sure window is set before we forge on... */
-                       readl(offset);
-               }
-               addr -= (window * NETXEN_WINDOW_ONE);
-               addr += NETXEN_PCI_DDR_NET;
-       } else if (ADDR_IN_RANGE(addr, NETXEN_ADDR_OCM0, NETXEN_ADDR_OCM0_MAX)) {
-               addr -= NETXEN_ADDR_OCM0;
-               addr += NETXEN_PCI_OCM0;
-       } else if (ADDR_IN_RANGE(addr, NETXEN_ADDR_OCM1, NETXEN_ADDR_OCM1_MAX)) {
-               addr -= NETXEN_ADDR_OCM1;
-               addr += NETXEN_PCI_OCM1;
-       } else if (ADDR_IN_RANGE(addr, NETXEN_ADDR_QDR_NET, qdr_max)) {
-               /* QDR network side */
-               addr -= NETXEN_ADDR_QDR_NET;
-               window = (addr >> 22) & 0x3f;
-               if (adapter->ahw.qdr_sn_window != window) {
-                       adapter->ahw.qdr_sn_window = window;
-                       offset = PCI_OFFSET_SECOND_RANGE(adapter,
-                               NETXEN_PCIX_PH_REG(PCIE_SN_WINDOW_REG(func)));
-                       writel((window << 22), offset);
-                       /* MUST make sure window is set before we forge on... */
-                       readl(offset);
-               }
-               addr -= (window * 0x400000);
-               addr += NETXEN_PCI_QDR_NET;
-       } else {
-               /*
-                * peg gdb frequently accesses memory that doesn't exist,
-                * this limits the chit chat so debugging isn't slowed down.
-                */
-               if ((netxen_pci_set_window_warning_count++ < 8)
-                   || (netxen_pci_set_window_warning_count % 64 == 0))
-                       printk("%s: Warning:netxen_nic_pci_set_window()"
-                              " Unknown address range!\n",
-                              netxen_nic_driver_name);
-               addr = -1UL;
-       }
-       return addr;
-}
-
 /* window 1 registers only */
 static void netxen_nic_io_write_128M(struct netxen_adapter *adapter,
                void __iomem *addr, u32 data)
@@ -1389,69 +1323,90 @@ netxen_get_ioaddr(struct netxen_adapter *adapter, u32 offset)
        return (void __iomem *)off;
 }
 
-static unsigned long
-netxen_nic_pci_set_window_2M(struct netxen_adapter *adapter,
-               unsigned long long addr)
+static int
+netxen_nic_pci_set_window_128M(struct netxen_adapter *adapter,
+               u64 addr, u32 *start)
 {
-       int window;
-       u32 win_read;
-
-       if (ADDR_IN_RANGE(addr, NETXEN_ADDR_DDR_NET, NETXEN_ADDR_DDR_NET_MAX)) {
-               /* DDR network side */
-               window = MN_WIN(addr);
-               adapter->ahw.ddr_mn_window = window;
-               NXWR32(adapter, adapter->ahw.mn_win_crb, window);
-               win_read = NXRD32(adapter, adapter->ahw.mn_win_crb);
-               if ((win_read << 17) != window) {
-                       printk(KERN_INFO "Written MNwin (0x%x) != "
-                               "Read MNwin (0x%x)\n", window, win_read);
-               }
-               addr = GET_MEM_OFFS_2M(addr) + NETXEN_PCI_DDR_NET;
+       if (ADDR_IN_RANGE(addr, NETXEN_ADDR_OCM0, NETXEN_ADDR_OCM0_MAX)) {
+               *start = (addr - NETXEN_ADDR_OCM0  + NETXEN_PCI_OCM0);
+               return 0;
        } else if (ADDR_IN_RANGE(addr,
-                               NETXEN_ADDR_OCM0, NETXEN_ADDR_OCM0_MAX)) {
-               if ((addr & 0x00ff800) == 0xff800) {
-                       printk("%s: QM access not handled.\n", __func__);
-                       addr = -1UL;
-               }
+                               NETXEN_ADDR_OCM1, NETXEN_ADDR_OCM1_MAX)) {
+               *start = (addr - NETXEN_ADDR_OCM1 + NETXEN_PCI_OCM1);
+               return 0;
+       }
 
-               window = OCM_WIN(addr);
-               adapter->ahw.ddr_mn_window = window;
-               NXWR32(adapter, adapter->ahw.mn_win_crb, window);
-               win_read = NXRD32(adapter, adapter->ahw.mn_win_crb);
-               if ((win_read >> 7) != window) {
-                       printk(KERN_INFO "%s: Written OCMwin (0x%x) != "
-                                       "Read OCMwin (0x%x)\n",
-                                       __func__, window, win_read);
-               }
-               addr = GET_MEM_OFFS_2M(addr) + NETXEN_PCI_OCM0_2M;
+       return -EIO;
+}
 
-       } else if (ADDR_IN_RANGE(addr,
-                       NETXEN_ADDR_QDR_NET, NETXEN_ADDR_QDR_NET_MAX_P3)) {
-               /* QDR network side */
-               window = MS_WIN(addr);
-               adapter->ahw.qdr_sn_window = window;
-               NXWR32(adapter, adapter->ahw.ms_win_crb, window);
-               win_read = NXRD32(adapter, adapter->ahw.ms_win_crb);
-               if (win_read != window) {
-                       printk(KERN_INFO "%s: Written MSwin (0x%x) != "
-                                       "Read MSwin (0x%x)\n",
-                                       __func__, window, win_read);
-               }
-               addr = GET_MEM_OFFS_2M(addr) + NETXEN_PCI_QDR_NET;
+static int
+netxen_nic_pci_set_window_2M(struct netxen_adapter *adapter,
+               u64 addr, u32 *start)
+{
+       u32 win_read, window;
+       struct pci_dev *pdev = adapter->pdev;
 
-       } else {
-               /*
-                * peg gdb frequently accesses memory that doesn't exist,
-                * this limits the chit chat so debugging isn't slowed down.
-                */
-               if ((netxen_pci_set_window_warning_count++ < 8)
-                       || (netxen_pci_set_window_warning_count%64 == 0)) {
-                       printk("%s: Warning:%s Unknown address range!\n",
-                                       __func__, netxen_nic_driver_name);
+       if ((addr & 0x00ff800) == 0xff800) {
+               if (printk_ratelimit())
+                       dev_warn(&pdev->dev, "QM access not handled\n");
+               return -EIO;
+       }
+
+       window = OCM_WIN(addr);
+       writel(window, adapter->ahw.ocm_win_crb);
+       win_read = readl(adapter->ahw.ocm_win_crb);
+       if ((win_read >> 7) != window) {
+               if (printk_ratelimit())
+                       dev_warn(&pdev->dev, "failed to set OCM window\n");
+               return -EIO;
+       }
+
+       adapter->ahw.ocm_win = window;
+       *start = NETXEN_PCI_OCM0_2M + GET_MEM_OFFS_2M(addr);
+       return 0;
 }
-               addr = -1UL;
+
+static int
+netxen_nic_pci_mem_access_direct(struct netxen_adapter *adapter, u64 off,
+               u64 *data, int op)
+{
+       void __iomem *addr, *mem_ptr = NULL;
+       resource_size_t mem_base;
+       unsigned long flags;
+       int ret = -EIO;
+       u32 start;
+
+       write_lock_irqsave(&adapter->adapter_lock, flags);
+
+       ret = adapter->pci_set_window(adapter, off, &start);
+       if (ret != 0)
+               goto unlock;
+
+       addr = pci_base_offset(adapter, start);
+       if (addr)
+               goto noremap;
+
+       mem_base = pci_resource_start(adapter->pdev, 0) + (start & PAGE_MASK);
+
+       mem_ptr = ioremap(mem_base, PAGE_SIZE);
+       if (mem_ptr == NULL) {
+               ret = -EIO;
+               goto unlock;
        }
-       return addr;
+
+       addr = mem_ptr + (start & (PAGE_SIZE - 1));
+
+noremap:
+       if (op == 0)    /* read */
+               *data = readq(addr);
+       else            /* write */
+               writeq(*data, addr);
+
+unlock:
+       write_unlock_irqrestore(&adapter->adapter_lock, flags);
+       if (mem_ptr)
+               iounmap(mem_ptr);
+       return ret;
 }
 
 #define MAX_CTL_CHECK   1000
@@ -1493,6 +1448,14 @@ netxen_nic_pci_mem_write_128M(struct netxen_adapter *adapter,
                goto correct;
        }
 
+       if (ADDR_IN_RANGE(off, NETXEN_ADDR_OCM0, NETXEN_ADDR_OCM0_MAX) ||
+               ADDR_IN_RANGE(off, NETXEN_ADDR_OCM1, NETXEN_ADDR_OCM1_MAX)) {
+               if (adapter->ahw.pci_len0 != 0) {
+                       return netxen_nic_pci_mem_access_direct(adapter,
+                                       off, &data, 1);
+               }
+       }
+
        return -EIO;
 
 correct:
@@ -1564,6 +1527,14 @@ netxen_nic_pci_mem_read_128M(struct netxen_adapter *adapter,
                goto correct;
        }
 
+       if (ADDR_IN_RANGE(off, NETXEN_ADDR_OCM0, NETXEN_ADDR_OCM0_MAX) ||
+               ADDR_IN_RANGE(off, NETXEN_ADDR_OCM1, NETXEN_ADDR_OCM1_MAX)) {
+               if (adapter->ahw.pci_len0 != 0) {
+                       return netxen_nic_pci_mem_access_direct(adapter,
+                                       off, data, 0);
+               }
+       }
+
        return -EIO;
 
 correct:
@@ -1628,6 +1599,9 @@ netxen_nic_pci_mem_write_2M(struct netxen_adapter *adapter,
                goto correct;
        }
 
+       if (ADDR_IN_RANGE(off, NETXEN_ADDR_OCM0, NETXEN_ADDR_OCM0_MAX))
+               return netxen_nic_pci_mem_access_direct(adapter, off, &data, 1);
+
        return -EIO;
 
 correct:
@@ -1690,6 +1664,9 @@ netxen_nic_pci_mem_read_2M(struct netxen_adapter *adapter,
                goto correct;
        }
 
+       if (ADDR_IN_RANGE(off, NETXEN_ADDR_OCM0, NETXEN_ADDR_OCM0_MAX))
+               return netxen_nic_pci_mem_access_direct(adapter, off, data, 0);
+
        return -EIO;
 
 correct:
index 302675a..b7f6070 100644 (file)
@@ -607,13 +607,11 @@ netxen_setup_pci_map(struct netxen_adapter *adapter)
         * accessed it should set the window to 0 and then reset it to 1.
         */
        adapter->curr_window = 255;
-       adapter->ahw.qdr_sn_window = -1;
-       adapter->ahw.ddr_mn_window = -1;
+       adapter->ahw.ocm_win = -1;
 
        /* remap phys address */
        mem_base = pci_resource_start(pdev, 0); /* 0 is for BAR 0 */
        mem_len = pci_resource_len(pdev, 0);
-       pci_len0 = 0;
 
        /* 128 Meg of memory */
        if (mem_len == NETXEN_PCI_128MB_SIZE) {
@@ -622,6 +620,7 @@ netxen_setup_pci_map(struct netxen_adapter *adapter)
                                SECOND_PAGE_GROUP_SIZE);
                mem_ptr2 = ioremap(mem_base + THIRD_PAGE_GROUP_START,
                                THIRD_PAGE_GROUP_SIZE);
+               pci_len0 = FIRST_PAGE_GROUP_SIZE;
        } else if (mem_len == NETXEN_PCI_32MB_SIZE) {
                mem_ptr1 = ioremap(mem_base, SECOND_PAGE_GROUP_SIZE);
                mem_ptr2 = ioremap(mem_base + THIRD_PAGE_GROUP_START -
@@ -634,19 +633,6 @@ netxen_setup_pci_map(struct netxen_adapter *adapter)
                        return -EIO;
                }
                pci_len0 = mem_len;
-
-               adapter->ahw.ddr_mn_window = 0;
-               adapter->ahw.qdr_sn_window = 0;
-
-               adapter->ahw.mn_win_crb = NETXEN_PCI_CRBSPACE +
-                       0x100000 + PCIX_MN_WINDOW + (pci_func * 0x20);
-               adapter->ahw.ms_win_crb = NETXEN_PCI_CRBSPACE +
-                       0x100000 + PCIX_SN_WINDOW;
-               if (pci_func < 4)
-                       adapter->ahw.ms_win_crb += (pci_func * 0x20);
-               else
-                       adapter->ahw.ms_win_crb +=
-                                       0xA0 + ((pci_func - 4) * 0x10);
        } else {
                return -EIO;
        }
@@ -660,6 +646,11 @@ netxen_setup_pci_map(struct netxen_adapter *adapter)
        adapter->ahw.pci_base1 = mem_ptr1;
        adapter->ahw.pci_base2 = mem_ptr2;
 
+       if (!NX_IS_REVISION_P2(adapter->ahw.revision_id)) {
+               adapter->ahw.ocm_win_crb = netxen_get_ioaddr(adapter,
+                       NETXEN_PCIX_PS_REG(PCIE_MN_WINDOW_REG(pci_func)));
+       }
+
        if (NX_IS_REVISION_P3(adapter->ahw.revision_id))
                goto skip_doorbell;
 
@@ -1447,6 +1438,7 @@ netxen_nic_resume(struct pci_dev *pdev)
                return err;
 
        adapter->curr_window = 255;
+       adapter->ahw.ocm_win = -1;
 
        err = netxen_start_firmware(adapter);
        if (err) {