netxen: remove sub 64-bit mem accesses
[linux-2.6.git] / drivers / net / netxen / netxen_nic_hw.c
index 32314000dfcdeb4f7a924a377d08a823054108e3..5f4bdda53d4421208b1548ad54bd1ff036b1ece4 100644 (file)
@@ -1458,101 +1458,69 @@ netxen_nic_pci_set_window_2M(struct netxen_adapter *adapter,
 
 static int
 netxen_nic_pci_mem_write_128M(struct netxen_adapter *adapter,
-               u64 off, void *data, int size)
+               u64 off, u64 data)
 {
        unsigned long   flags;
-       int          i, j, ret = 0, loop, sz[2], off0;
-       uint32_t      temp;
-       uint64_t      off8, tmpw, word[2] = {0, 0};
+       int j, ret;
+       u32 temp, off_lo, off_hi, addr_hi, data_hi, data_lo;
        void __iomem *mem_crb;
 
-       if (size != 8)
+       /* Only 64-bit aligned access */
+       if (off & 7)
                return -EIO;
 
+       /* P2 has different SIU and MIU test agent base addr */
        if (ADDR_IN_RANGE(off, NETXEN_ADDR_QDR_NET,
                                NETXEN_ADDR_QDR_NET_MAX_P2)) {
-               mem_crb = pci_base_offset(adapter, NETXEN_CRB_QDR_NET);
+               mem_crb = pci_base_offset(adapter,
+                               NETXEN_CRB_QDR_NET+SIU_TEST_AGT_BASE);
+               addr_hi = SIU_TEST_AGT_ADDR_HI;
+               data_lo = SIU_TEST_AGT_WRDATA_LO;
+               data_hi = SIU_TEST_AGT_WRDATA_HI;
+               off_lo = off & SIU_TEST_AGT_ADDR_MASK;
+               off_hi = SIU_TEST_AGT_UPPER_ADDR(off);
                goto correct;
        }
 
        if (ADDR_IN_RANGE(off, NETXEN_ADDR_DDR_NET, NETXEN_ADDR_DDR_NET_MAX)) {
-               mem_crb = pci_base_offset(adapter, NETXEN_CRB_DDR_NET);
+               mem_crb = pci_base_offset(adapter,
+                               NETXEN_CRB_DDR_NET+MIU_TEST_AGT_BASE);
+               addr_hi = MIU_TEST_AGT_ADDR_HI;
+               data_lo = MIU_TEST_AGT_WRDATA_LO;
+               data_hi = MIU_TEST_AGT_WRDATA_HI;
+               off_lo = off & MIU_TEST_AGT_ADDR_MASK;
+               off_hi = 0;
                goto correct;
        }
 
        return -EIO;
 
 correct:
-       off8 = off & 0xfffffff8;
-       off0 = off & 0x7;
-       sz[0] = (size < (8 - off0)) ? size : (8 - off0);
-       sz[1] = size - sz[0];
-       loop = ((off0 + size - 1) >> 3) + 1;
-
-       if ((size != 8) || (off0 != 0))  {
-               for (i = 0; i < loop; i++) {
-                       if (adapter->pci_mem_read(adapter,
-                               off8 + (i << 3), &word[i], 8))
-                               return -1;
-               }
-       }
-
-       switch (size) {
-       case 1:
-               tmpw = *((uint8_t *)data);
-               break;
-       case 2:
-               tmpw = *((uint16_t *)data);
-               break;
-       case 4:
-               tmpw = *((uint32_t *)data);
-               break;
-       case 8:
-       default:
-               tmpw = *((uint64_t *)data);
-               break;
-       }
-       word[0] &= ~((~(~0ULL << (sz[0] * 8))) << (off0 * 8));
-       word[0] |= tmpw << (off0 * 8);
-
-       if (loop == 2) {
-               word[1] &= ~(~0ULL << (sz[1] * 8));
-               word[1] |= tmpw >> (sz[0] * 8);
-       }
-
        write_lock_irqsave(&adapter->adapter_lock, flags);
        netxen_nic_pci_change_crbwindow_128M(adapter, 0);
 
-       for (i = 0; i < loop; i++) {
-               writel((uint32_t)(off8 + (i << 3)),
-                       (mem_crb+MIU_TEST_AGT_ADDR_LO));
-               writel(0,
-                       (mem_crb+MIU_TEST_AGT_ADDR_HI));
-               writel(word[i] & 0xffffffff,
-                       (mem_crb+MIU_TEST_AGT_WRDATA_LO));
-               writel((word[i] >> 32) & 0xffffffff,
-                       (mem_crb+MIU_TEST_AGT_WRDATA_HI));
-               writel(MIU_TA_CTL_ENABLE|MIU_TA_CTL_WRITE,
-                       (mem_crb+MIU_TEST_AGT_CTRL));
-               writel(MIU_TA_CTL_START|MIU_TA_CTL_ENABLE|MIU_TA_CTL_WRITE,
-                       (mem_crb+MIU_TEST_AGT_CTRL));
-
-               for (j = 0; j < MAX_CTL_CHECK; j++) {
-                       temp = readl(
-                            (mem_crb+MIU_TEST_AGT_CTRL));
-                       if ((temp & MIU_TA_CTL_BUSY) == 0)
-                               break;
-               }
-
-               if (j >= MAX_CTL_CHECK) {
-                       if (printk_ratelimit())
-                               dev_err(&adapter->pdev->dev,
-                                       "failed to write through agent\n");
-                       ret = -1;
+       writel(off_lo, (mem_crb + MIU_TEST_AGT_ADDR_LO));
+       writel(off_hi, (mem_crb + addr_hi));
+       writel(data & 0xffffffff, (mem_crb + data_lo));
+       writel((data >> 32) & 0xffffffff, (mem_crb + data_hi));
+       writel((TA_CTL_ENABLE | TA_CTL_WRITE), (mem_crb + TEST_AGT_CTRL));
+       writel((TA_CTL_START | TA_CTL_ENABLE | TA_CTL_WRITE),
+                       (mem_crb + TEST_AGT_CTRL));
+
+       for (j = 0; j < MAX_CTL_CHECK; j++) {
+               temp = readl((mem_crb + TEST_AGT_CTRL));
+               if ((temp & TA_CTL_BUSY) == 0)
                        break;
-               }
        }
 
+       if (j >= MAX_CTL_CHECK) {
+               if (printk_ratelimit())
+                       dev_err(&adapter->pdev->dev,
+                                       "failed to write through agent\n");
+               ret = -EIO;
+       } else
+               ret = 0;
+
        netxen_nic_pci_change_crbwindow_128M(adapter, 1);
        write_unlock_irqrestore(&adapter->adapter_lock, flags);
        return ret;
@@ -1560,304 +1528,202 @@ correct:
 
 static int
 netxen_nic_pci_mem_read_128M(struct netxen_adapter *adapter,
-               u64 off, void *data, int size)
+               u64 off, u64 *data)
 {
        unsigned long   flags;
-       int          i, j = 0, k, start, end, loop, sz[2], off0[2];
-       uint32_t      temp;
-       uint64_t      off8, val, word[2] = {0, 0};
+       int j, ret;
+       u32 temp, off_lo, off_hi, addr_hi, data_hi, data_lo;
+       u64 val;
        void __iomem *mem_crb;
 
-       if (size != 8)
+       /* Only 64-bit aligned access */
+       if (off & 7)
                return -EIO;
 
+       /* P2 has different SIU and MIU test agent base addr */
        if (ADDR_IN_RANGE(off, NETXEN_ADDR_QDR_NET,
                                NETXEN_ADDR_QDR_NET_MAX_P2)) {
-               mem_crb = pci_base_offset(adapter, NETXEN_CRB_QDR_NET);
+               mem_crb = pci_base_offset(adapter,
+                               NETXEN_CRB_QDR_NET+SIU_TEST_AGT_BASE);
+               addr_hi = SIU_TEST_AGT_ADDR_HI;
+               data_lo = SIU_TEST_AGT_RDDATA_LO;
+               data_hi = SIU_TEST_AGT_RDDATA_HI;
+               off_lo = off & SIU_TEST_AGT_ADDR_MASK;
+               off_hi = SIU_TEST_AGT_UPPER_ADDR(off);
                goto correct;
        }
 
        if (ADDR_IN_RANGE(off, NETXEN_ADDR_DDR_NET, NETXEN_ADDR_DDR_NET_MAX)) {
-               mem_crb = pci_base_offset(adapter, NETXEN_CRB_DDR_NET);
+               mem_crb = pci_base_offset(adapter,
+                               NETXEN_CRB_DDR_NET+MIU_TEST_AGT_BASE);
+               addr_hi = MIU_TEST_AGT_ADDR_HI;
+               data_lo = MIU_TEST_AGT_RDDATA_LO;
+               data_hi = MIU_TEST_AGT_RDDATA_HI;
+               off_lo = off & MIU_TEST_AGT_ADDR_MASK;
+               off_hi = 0;
                goto correct;
        }
 
        return -EIO;
 
 correct:
-       off8 = off & 0xfffffff8;
-       off0[0] = off & 0x7;
-       off0[1] = 0;
-       sz[0] = (size < (8 - off0[0])) ? size : (8 - off0[0]);
-       sz[1] = size - sz[0];
-       loop = ((off0[0] + size - 1) >> 3) + 1;
-
        write_lock_irqsave(&adapter->adapter_lock, flags);
        netxen_nic_pci_change_crbwindow_128M(adapter, 0);
 
-       for (i = 0; i < loop; i++) {
-               writel((uint32_t)(off8 + (i << 3)),
-                       (mem_crb+MIU_TEST_AGT_ADDR_LO));
-               writel(0,
-                       (mem_crb+MIU_TEST_AGT_ADDR_HI));
-               writel(MIU_TA_CTL_ENABLE,
-                       (mem_crb+MIU_TEST_AGT_CTRL));
-               writel(MIU_TA_CTL_START|MIU_TA_CTL_ENABLE,
-                       (mem_crb+MIU_TEST_AGT_CTRL));
-
-               for (j = 0; j < MAX_CTL_CHECK; j++) {
-                       temp = readl(
-                             (mem_crb+MIU_TEST_AGT_CTRL));
-                       if ((temp & MIU_TA_CTL_BUSY) == 0)
-                               break;
-               }
+       writel(off_lo, (mem_crb + MIU_TEST_AGT_ADDR_LO));
+       writel(off_hi, (mem_crb + addr_hi));
+       writel(TA_CTL_ENABLE, (mem_crb + TEST_AGT_CTRL));
+       writel((TA_CTL_START|TA_CTL_ENABLE), (mem_crb + TEST_AGT_CTRL));
 
-               if (j >= MAX_CTL_CHECK) {
-                       if (printk_ratelimit())
-                               dev_err(&adapter->pdev->dev,
-                                       "failed to read through agent\n");
+       for (j = 0; j < MAX_CTL_CHECK; j++) {
+               temp = readl(mem_crb + TEST_AGT_CTRL);
+               if ((temp & TA_CTL_BUSY) == 0)
                        break;
-               }
+       }
 
-               start = off0[i] >> 2;
-               end   = (off0[i] + sz[i] - 1) >> 2;
-               for (k = start; k <= end; k++) {
-                       word[i] |= ((uint64_t) readl(
-                                   (mem_crb +
-                                   MIU_TEST_AGT_RDDATA(k))) << (32*k));
-               }
+       if (j >= MAX_CTL_CHECK) {
+               if (printk_ratelimit())
+                       dev_err(&adapter->pdev->dev,
+                                       "failed to read through agent\n");
+               ret = -EIO;
+       } else {
+
+               temp = readl(mem_crb + data_hi);
+               val = ((u64)temp << 32);
+               val |= readl(mem_crb + data_lo);
+               *data = val;
+               ret = 0;
        }
 
        netxen_nic_pci_change_crbwindow_128M(adapter, 1);
        write_unlock_irqrestore(&adapter->adapter_lock, flags);
 
-       if (j >= MAX_CTL_CHECK)
-               return -1;
-
-       if (sz[0] == 8) {
-               val = word[0];
-       } else {
-               val = ((word[0] >> (off0[0] * 8)) & (~(~0ULL << (sz[0] * 8)))) |
-                       ((word[1] & (~(~0ULL << (sz[1] * 8)))) << (sz[0] * 8));
-       }
-
-       switch (size) {
-       case 1:
-               *(uint8_t  *)data = val;
-               break;
-       case 2:
-               *(uint16_t *)data = val;
-               break;
-       case 4:
-               *(uint32_t *)data = val;
-               break;
-       case 8:
-               *(uint64_t *)data = val;
-               break;
-       }
-       return 0;
+       return ret;
 }
 
 static int
 netxen_nic_pci_mem_write_2M(struct netxen_adapter *adapter,
-               u64 off, void *data, int size)
+               u64 off, u64 data)
 {
-       int i, j, ret = 0, loop, sz[2], off0;
-       uint32_t temp;
-       uint64_t off8, tmpw, word[2] = {0, 0};
+       unsigned long   flags;
+       int j, ret;
+       u32 temp, off8;
        void __iomem *mem_crb;
 
-       if (size != 8)
+       /* Only 64-bit aligned access */
+       if (off & 7)
                return -EIO;
 
+       /* P3 onward, test agent base for MIU and SIU is same */
        if (ADDR_IN_RANGE(off, NETXEN_ADDR_QDR_NET,
                                NETXEN_ADDR_QDR_NET_MAX_P3)) {
-               mem_crb = netxen_get_ioaddr(adapter, NETXEN_CRB_QDR_NET);
+               mem_crb = netxen_get_ioaddr(adapter,
+                               NETXEN_CRB_QDR_NET+MIU_TEST_AGT_BASE);
                goto correct;
        }
 
        if (ADDR_IN_RANGE(off, NETXEN_ADDR_DDR_NET, NETXEN_ADDR_DDR_NET_MAX)) {
-               mem_crb = netxen_get_ioaddr(adapter, NETXEN_CRB_DDR_NET);
+               mem_crb = netxen_get_ioaddr(adapter,
+                               NETXEN_CRB_DDR_NET+MIU_TEST_AGT_BASE);
                goto correct;
        }
 
        return -EIO;
 
 correct:
-       off8 = off & 0xfffffff8;
-       off0 = off & 0x7;
-       sz[0] = (size < (8 - off0)) ? size : (8 - off0);
-       sz[1] = size - sz[0];
-       loop = ((off0 + size - 1) >> 3) + 1;
-
-       if ((size != 8) || (off0 != 0)) {
-               for (i = 0; i < loop; i++) {
-                       if (adapter->pci_mem_read(adapter,
-                                       off8 + (i << 3), &word[i], 8))
-                               return -1;
-               }
-       }
-
-       switch (size) {
-       case 1:
-               tmpw = *((uint8_t *)data);
-               break;
-       case 2:
-               tmpw = *((uint16_t *)data);
-               break;
-       case 4:
-               tmpw = *((uint32_t *)data);
-               break;
-       case 8:
-       default:
-               tmpw = *((uint64_t *)data);
-       break;
-       }
+       off8 = off & MIU_TEST_AGT_ADDR_MASK;
 
-       word[0] &= ~((~(~0ULL << (sz[0] * 8))) << (off0 * 8));
-       word[0] |= tmpw << (off0 * 8);
+       write_lock_irqsave(&adapter->adapter_lock, flags);
 
-       if (loop == 2) {
-               word[1] &= ~(~0ULL << (sz[1] * 8));
-               word[1] |= tmpw >> (sz[0] * 8);
+       writel(off8, (mem_crb + MIU_TEST_AGT_ADDR_LO));
+       writel(0, (mem_crb + MIU_TEST_AGT_ADDR_HI));
+       writel(data & 0xffffffff, mem_crb + MIU_TEST_AGT_WRDATA_LO);
+       writel((data >> 32) & 0xffffffff, mem_crb + MIU_TEST_AGT_WRDATA_HI);
+       writel((TA_CTL_ENABLE | TA_CTL_WRITE), (mem_crb + TEST_AGT_CTRL));
+       writel((TA_CTL_START | TA_CTL_ENABLE | TA_CTL_WRITE),
+                       (mem_crb + TEST_AGT_CTRL));
+
+       for (j = 0; j < MAX_CTL_CHECK; j++) {
+               temp = readl(mem_crb + TEST_AGT_CTRL);
+               if ((temp & TA_CTL_BUSY) == 0)
+                       break;
        }
 
-       /*
-        * don't lock here - write_wx gets the lock if each time
-        * write_lock_irqsave(&adapter->adapter_lock, flags);
-        * netxen_nic_pci_change_crbwindow_128M(adapter, 0);
-        */
-
-       for (i = 0; i < loop; i++) {
-               writel(off8 + (i << 3), mem_crb+MIU_TEST_AGT_ADDR_LO);
-               writel(0, mem_crb+MIU_TEST_AGT_ADDR_HI);
-               writel(word[i] & 0xffffffff, mem_crb+MIU_TEST_AGT_WRDATA_LO);
-               writel((word[i] >> 32) & 0xffffffff,
-                               mem_crb+MIU_TEST_AGT_WRDATA_HI);
-               writel((MIU_TA_CTL_ENABLE | MIU_TA_CTL_WRITE),
-                               mem_crb+MIU_TEST_AGT_CTRL);
-               writel(MIU_TA_CTL_START | MIU_TA_CTL_ENABLE | MIU_TA_CTL_WRITE,
-                               mem_crb+MIU_TEST_AGT_CTRL);
-
-               for (j = 0; j < MAX_CTL_CHECK; j++) {
-                       temp = readl(mem_crb + MIU_TEST_AGT_CTRL);
-                       if ((temp & MIU_TA_CTL_BUSY) == 0)
-                               break;
-               }
-
-               if (j >= MAX_CTL_CHECK) {
-                       if (printk_ratelimit())
-                               dev_err(&adapter->pdev->dev,
+       if (j >= MAX_CTL_CHECK) {
+               if (printk_ratelimit())
+                       dev_err(&adapter->pdev->dev,
                                        "failed to write through agent\n");
-                       ret = -1;
-                       break;
-               }
-       }
+               ret = -EIO;
+       } else
+               ret = 0;
+
+       write_unlock_irqrestore(&adapter->adapter_lock, flags);
 
-       /*
-        * netxen_nic_pci_change_crbwindow_128M(adapter, 1);
-        * write_unlock_irqrestore(&adapter->adapter_lock, flags);
-        */
        return ret;
 }
 
 static int
 netxen_nic_pci_mem_read_2M(struct netxen_adapter *adapter,
-               u64 off, void *data, int size)
+               u64 off, u64 *data)
 {
-       int i, j = 0, k, start, end, loop, sz[2], off0[2];
-       uint32_t      temp;
-       uint64_t      off8, val, word[2] = {0, 0};
+       unsigned long   flags;
+       int j, ret;
+       u32 temp, off8;
+       u64 val;
        void __iomem *mem_crb;
 
-       if (size != 8)
+       /* Only 64-bit aligned access */
+       if (off & 7)
                return -EIO;
 
+       /* P3 onward, test agent base for MIU and SIU is same */
        if (ADDR_IN_RANGE(off, NETXEN_ADDR_QDR_NET,
                                NETXEN_ADDR_QDR_NET_MAX_P3)) {
-               mem_crb = netxen_get_ioaddr(adapter, NETXEN_CRB_QDR_NET);
+               mem_crb = netxen_get_ioaddr(adapter,
+                               NETXEN_CRB_QDR_NET+MIU_TEST_AGT_BASE);
                goto correct;
        }
 
        if (ADDR_IN_RANGE(off, NETXEN_ADDR_DDR_NET, NETXEN_ADDR_DDR_NET_MAX)) {
-               mem_crb = netxen_get_ioaddr(adapter, NETXEN_CRB_DDR_NET);
+               mem_crb = netxen_get_ioaddr(adapter,
+                               NETXEN_CRB_DDR_NET+MIU_TEST_AGT_BASE);
                goto correct;
        }
 
        return -EIO;
 
 correct:
-       off8 = off & 0xfffffff8;
-       off0[0] = off & 0x7;
-       off0[1] = 0;
-       sz[0] = (size < (8 - off0[0])) ? size : (8 - off0[0]);
-       sz[1] = size - sz[0];
-       loop = ((off0[0] + size - 1) >> 3) + 1;
+       off8 = off & MIU_TEST_AGT_ADDR_MASK;
 
-       /*
-        * don't lock here - write_wx gets the lock if each time
-        * write_lock_irqsave(&adapter->adapter_lock, flags);
-        * netxen_nic_pci_change_crbwindow_128M(adapter, 0);
-        */
+       write_lock_irqsave(&adapter->adapter_lock, flags);
 
-       for (i = 0; i < loop; i++) {
-               writel(off8 + (i << 3), mem_crb + MIU_TEST_AGT_ADDR_LO);
-               writel(0, mem_crb + MIU_TEST_AGT_ADDR_HI);
-               writel(MIU_TA_CTL_ENABLE, mem_crb + MIU_TEST_AGT_CTRL);
-               writel(MIU_TA_CTL_START | MIU_TA_CTL_ENABLE,
-                               mem_crb + MIU_TEST_AGT_CTRL);
-
-               for (j = 0; j < MAX_CTL_CHECK; j++) {
-                       temp = readl(mem_crb + MIU_TEST_AGT_CTRL);
-                       if ((temp & MIU_TA_CTL_BUSY) == 0)
-                               break;
-               }
+       writel(off8, (mem_crb + MIU_TEST_AGT_ADDR_LO));
+       writel(0, (mem_crb + MIU_TEST_AGT_ADDR_HI));
+       writel(TA_CTL_ENABLE, (mem_crb + TEST_AGT_CTRL));
+       writel((TA_CTL_START | TA_CTL_ENABLE), (mem_crb + TEST_AGT_CTRL));
 
-               if (j >= MAX_CTL_CHECK) {
-                       if (printk_ratelimit())
-                               dev_err(&adapter->pdev->dev,
-                                       "failed to read through agent\n");
+       for (j = 0; j < MAX_CTL_CHECK; j++) {
+               temp = readl(mem_crb + TEST_AGT_CTRL);
+               if ((temp & TA_CTL_BUSY) == 0)
                        break;
-               }
-
-               start = off0[i] >> 2;
-               end   = (off0[i] + sz[i] - 1) >> 2;
-               for (k = start; k <= end; k++) {
-                       temp = readl(mem_crb + MIU_TEST_AGT_RDDATA(k));
-                       word[i] |= ((uint64_t)temp << (32 * k));
-               }
        }
 
-       /*
-        * netxen_nic_pci_change_crbwindow_128M(adapter, 1);
-        * write_unlock_irqrestore(&adapter->adapter_lock, flags);
-        */
-
-       if (j >= MAX_CTL_CHECK)
-               return -1;
-
-       if (sz[0] == 8) {
-               val = word[0];
+       if (j >= MAX_CTL_CHECK) {
+               if (printk_ratelimit())
+                       dev_err(&adapter->pdev->dev,
+                                       "failed to read through agent\n");
+               ret = -EIO;
        } else {
-               val = ((word[0] >> (off0[0] * 8)) & (~(~0ULL << (sz[0] * 8)))) |
-               ((word[1] & (~(~0ULL << (sz[1] * 8)))) << (sz[0] * 8));
+               temp = readl(mem_crb + MIU_TEST_AGT_RDDATA_HI);
+               val = (u64)temp << 32;
+               val |= readl(mem_crb + MIU_TEST_AGT_RDDATA_LO);
+               *data = val;
+               ret = 0;
        }
 
-       switch (size) {
-       case 1:
-               *(uint8_t  *)data = val;
-               break;
-       case 2:
-               *(uint16_t *)data = val;
-               break;
-       case 4:
-               *(uint32_t *)data = val;
-               break;
-       case 8:
-               *(uint64_t *)data = val;
-               break;
-       }
-       return 0;
+       write_unlock_irqrestore(&adapter->adapter_lock, flags);
+
+       return ret;
 }
 
 void