aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAmit Kumar Salecha <amit@netxen.com>2009-10-13 01:31:41 -0400
committerDavid S. Miller <davem@davemloft.net>2009-10-13 14:48:19 -0400
commit1f5e055db369a5d1c74174571585a4ec2e6c40fb (patch)
treeef35e48957f02d9f1b461bd82bbd36745cf8de63
parent89d71a66c40d629e3b1285def543ab1425558cd5 (diff)
netxen: remove sub 64-bit mem accesses
Sub 64-bit / unaligned access to oncard memory was only used by old diagnostic tools, causes some intermittent issues when memory controller agent is used. The new access method was added by commit ea6828b8aa3a8ebae8d7740f32f212ba1d2f0742 ("netxen: improve pci memory access"). Firmware init anyway uses 8-byte strides. This also fixes address/offset calculation for NX2031 context memory (SIU). For NX3031, SIU uses same register offsets as packet memory (MIU). Signed-off-by: Amit Kumar Salecha <amit@netxen.com> Signed-off-by: Dhananjay Phadke <dhananjay@netxen.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/netxen/netxen_nic.h4
-rw-r--r--drivers/net/netxen/netxen_nic_hdr.h69
-rw-r--r--drivers/net/netxen/netxen_nic_hw.c430
-rw-r--r--drivers/net/netxen/netxen_nic_init.c13
4 files changed, 196 insertions, 320 deletions
diff --git a/drivers/net/netxen/netxen_nic.h b/drivers/net/netxen/netxen_nic.h
index 5c766b52f1dc..db5c8d27d5d8 100644
--- a/drivers/net/netxen/netxen_nic.h
+++ b/drivers/net/netxen/netxen_nic.h
@@ -1180,8 +1180,8 @@ struct netxen_adapter {
1180 u32 (*crb_read)(struct netxen_adapter *, ulong); 1180 u32 (*crb_read)(struct netxen_adapter *, ulong);
1181 int (*crb_write)(struct netxen_adapter *, ulong, u32); 1181 int (*crb_write)(struct netxen_adapter *, ulong, u32);
1182 1182
1183 int (*pci_mem_read)(struct netxen_adapter *, u64, void *, int); 1183 int (*pci_mem_read)(struct netxen_adapter *, u64, u64 *);
1184 int (*pci_mem_write)(struct netxen_adapter *, u64, void *, int); 1184 int (*pci_mem_write)(struct netxen_adapter *, u64, u64);
1185 1185
1186 unsigned long (*pci_set_window)(struct netxen_adapter *, 1186 unsigned long (*pci_set_window)(struct netxen_adapter *,
1187 unsigned long long); 1187 unsigned long long);
diff --git a/drivers/net/netxen/netxen_nic_hdr.h b/drivers/net/netxen/netxen_nic_hdr.h
index 7a7177421d7c..34613503262f 100644
--- a/drivers/net/netxen/netxen_nic_hdr.h
+++ b/drivers/net/netxen/netxen_nic_hdr.h
@@ -661,40 +661,47 @@ enum {
661#define NETXEN_NIU_AP_STATION_ADDR_0(I) (NETXEN_CRB_NIU+0xa0040+(I)*0x10000) 661#define NETXEN_NIU_AP_STATION_ADDR_0(I) (NETXEN_CRB_NIU+0xa0040+(I)*0x10000)
662#define NETXEN_NIU_AP_STATION_ADDR_1(I) (NETXEN_CRB_NIU+0xa0044+(I)*0x10000) 662#define NETXEN_NIU_AP_STATION_ADDR_1(I) (NETXEN_CRB_NIU+0xa0044+(I)*0x10000)
663 663
664
665#define TEST_AGT_CTRL (0x00)
666
667#define TA_CTL_START 1
668#define TA_CTL_ENABLE 2
669#define TA_CTL_WRITE 4
670#define TA_CTL_BUSY 8
671
664/* 672/*
665 * Register offsets for MN 673 * Register offsets for MN
666 */ 674 */
667#define MIU_CONTROL (0x000) 675#define MIU_TEST_AGT_BASE (0x90)
668#define MIU_TEST_AGT_CTRL (0x090) 676
669#define MIU_TEST_AGT_ADDR_LO (0x094) 677#define MIU_TEST_AGT_ADDR_LO (0x04)
670#define MIU_TEST_AGT_ADDR_HI (0x098) 678#define MIU_TEST_AGT_ADDR_HI (0x08)
671#define MIU_TEST_AGT_WRDATA_LO (0x0a0) 679#define MIU_TEST_AGT_WRDATA_LO (0x10)
672#define MIU_TEST_AGT_WRDATA_HI (0x0a4) 680#define MIU_TEST_AGT_WRDATA_HI (0x14)
673#define MIU_TEST_AGT_WRDATA(i) (0x0a0+(4*(i))) 681#define MIU_TEST_AGT_WRDATA(i) (0x10+(4*(i)))
674#define MIU_TEST_AGT_RDDATA_LO (0x0a8) 682#define MIU_TEST_AGT_RDDATA_LO (0x18)
675#define MIU_TEST_AGT_RDDATA_HI (0x0ac) 683#define MIU_TEST_AGT_RDDATA_HI (0x1c)
676#define MIU_TEST_AGT_RDDATA(i) (0x0a8+(4*(i))) 684#define MIU_TEST_AGT_RDDATA(i) (0x18+(4*(i)))
677#define MIU_TEST_AGT_ADDR_MASK 0xfffffff8 685
678#define MIU_TEST_AGT_UPPER_ADDR(off) (0) 686#define MIU_TEST_AGT_ADDR_MASK 0xfffffff8
679 687#define MIU_TEST_AGT_UPPER_ADDR(off) (0)
680/* MIU_TEST_AGT_CTRL flags. work for SIU as well */ 688
681#define MIU_TA_CTL_START 1 689/*
682#define MIU_TA_CTL_ENABLE 2 690 * Register offsets for MS
683#define MIU_TA_CTL_WRITE 4 691 */
684#define MIU_TA_CTL_BUSY 8 692#define SIU_TEST_AGT_BASE (0x60)
685 693
686#define SIU_TEST_AGT_CTRL (0x060) 694#define SIU_TEST_AGT_ADDR_LO (0x04)
687#define SIU_TEST_AGT_ADDR_LO (0x064) 695#define SIU_TEST_AGT_ADDR_HI (0x18)
688#define SIU_TEST_AGT_ADDR_HI (0x078) 696#define SIU_TEST_AGT_WRDATA_LO (0x08)
689#define SIU_TEST_AGT_WRDATA_LO (0x068) 697#define SIU_TEST_AGT_WRDATA_HI (0x0c)
690#define SIU_TEST_AGT_WRDATA_HI (0x06c) 698#define SIU_TEST_AGT_WRDATA(i) (0x08+(4*(i)))
691#define SIU_TEST_AGT_WRDATA(i) (0x068+(4*(i))) 699#define SIU_TEST_AGT_RDDATA_LO (0x10)
692#define SIU_TEST_AGT_RDDATA_LO (0x070) 700#define SIU_TEST_AGT_RDDATA_HI (0x14)
693#define SIU_TEST_AGT_RDDATA_HI (0x074) 701#define SIU_TEST_AGT_RDDATA(i) (0x10+(4*(i)))
694#define SIU_TEST_AGT_RDDATA(i) (0x070+(4*(i))) 702
695 703#define SIU_TEST_AGT_ADDR_MASK 0x3ffff8
696#define SIU_TEST_AGT_ADDR_MASK 0x3ffff8 704#define SIU_TEST_AGT_UPPER_ADDR(off) ((off)>>22)
697#define SIU_TEST_AGT_UPPER_ADDR(off) ((off)>>22)
698 705
699/* XG Link status */ 706/* XG Link status */
700#define XG_LINK_UP 0x10 707#define XG_LINK_UP 0x10
diff --git a/drivers/net/netxen/netxen_nic_hw.c b/drivers/net/netxen/netxen_nic_hw.c
index 32314000dfcd..5f4bdda53d44 100644
--- a/drivers/net/netxen/netxen_nic_hw.c
+++ b/drivers/net/netxen/netxen_nic_hw.c
@@ -1458,101 +1458,69 @@ netxen_nic_pci_set_window_2M(struct netxen_adapter *adapter,
1458 1458
1459static int 1459static int
1460netxen_nic_pci_mem_write_128M(struct netxen_adapter *adapter, 1460netxen_nic_pci_mem_write_128M(struct netxen_adapter *adapter,
1461 u64 off, void *data, int size) 1461 u64 off, u64 data)
1462{ 1462{
1463 unsigned long flags; 1463 unsigned long flags;
1464 int i, j, ret = 0, loop, sz[2], off0; 1464 int j, ret;
1465 uint32_t temp; 1465 u32 temp, off_lo, off_hi, addr_hi, data_hi, data_lo;
1466 uint64_t off8, tmpw, word[2] = {0, 0};
1467 void __iomem *mem_crb; 1466 void __iomem *mem_crb;
1468 1467
1469 if (size != 8) 1468 /* Only 64-bit aligned access */
1469 if (off & 7)
1470 return -EIO; 1470 return -EIO;
1471 1471
1472 /* P2 has different SIU and MIU test agent base addr */
1472 if (ADDR_IN_RANGE(off, NETXEN_ADDR_QDR_NET, 1473 if (ADDR_IN_RANGE(off, NETXEN_ADDR_QDR_NET,
1473 NETXEN_ADDR_QDR_NET_MAX_P2)) { 1474 NETXEN_ADDR_QDR_NET_MAX_P2)) {
1474 mem_crb = pci_base_offset(adapter, NETXEN_CRB_QDR_NET); 1475 mem_crb = pci_base_offset(adapter,
1476 NETXEN_CRB_QDR_NET+SIU_TEST_AGT_BASE);
1477 addr_hi = SIU_TEST_AGT_ADDR_HI;
1478 data_lo = SIU_TEST_AGT_WRDATA_LO;
1479 data_hi = SIU_TEST_AGT_WRDATA_HI;
1480 off_lo = off & SIU_TEST_AGT_ADDR_MASK;
1481 off_hi = SIU_TEST_AGT_UPPER_ADDR(off);
1475 goto correct; 1482 goto correct;
1476 } 1483 }
1477 1484
1478 if (ADDR_IN_RANGE(off, NETXEN_ADDR_DDR_NET, NETXEN_ADDR_DDR_NET_MAX)) { 1485 if (ADDR_IN_RANGE(off, NETXEN_ADDR_DDR_NET, NETXEN_ADDR_DDR_NET_MAX)) {
1479 mem_crb = pci_base_offset(adapter, NETXEN_CRB_DDR_NET); 1486 mem_crb = pci_base_offset(adapter,
1487 NETXEN_CRB_DDR_NET+MIU_TEST_AGT_BASE);
1488 addr_hi = MIU_TEST_AGT_ADDR_HI;
1489 data_lo = MIU_TEST_AGT_WRDATA_LO;
1490 data_hi = MIU_TEST_AGT_WRDATA_HI;
1491 off_lo = off & MIU_TEST_AGT_ADDR_MASK;
1492 off_hi = 0;
1480 goto correct; 1493 goto correct;
1481 } 1494 }
1482 1495
1483 return -EIO; 1496 return -EIO;
1484 1497
1485correct: 1498correct:
1486 off8 = off & 0xfffffff8;
1487 off0 = off & 0x7;
1488 sz[0] = (size < (8 - off0)) ? size : (8 - off0);
1489 sz[1] = size - sz[0];
1490 loop = ((off0 + size - 1) >> 3) + 1;
1491
1492 if ((size != 8) || (off0 != 0)) {
1493 for (i = 0; i < loop; i++) {
1494 if (adapter->pci_mem_read(adapter,
1495 off8 + (i << 3), &word[i], 8))
1496 return -1;
1497 }
1498 }
1499
1500 switch (size) {
1501 case 1:
1502 tmpw = *((uint8_t *)data);
1503 break;
1504 case 2:
1505 tmpw = *((uint16_t *)data);
1506 break;
1507 case 4:
1508 tmpw = *((uint32_t *)data);
1509 break;
1510 case 8:
1511 default:
1512 tmpw = *((uint64_t *)data);
1513 break;
1514 }
1515 word[0] &= ~((~(~0ULL << (sz[0] * 8))) << (off0 * 8));
1516 word[0] |= tmpw << (off0 * 8);
1517
1518 if (loop == 2) {
1519 word[1] &= ~(~0ULL << (sz[1] * 8));
1520 word[1] |= tmpw >> (sz[0] * 8);
1521 }
1522
1523 write_lock_irqsave(&adapter->adapter_lock, flags); 1499 write_lock_irqsave(&adapter->adapter_lock, flags);
1524 netxen_nic_pci_change_crbwindow_128M(adapter, 0); 1500 netxen_nic_pci_change_crbwindow_128M(adapter, 0);
1525 1501
1526 for (i = 0; i < loop; i++) { 1502 writel(off_lo, (mem_crb + MIU_TEST_AGT_ADDR_LO));
1527 writel((uint32_t)(off8 + (i << 3)), 1503 writel(off_hi, (mem_crb + addr_hi));
1528 (mem_crb+MIU_TEST_AGT_ADDR_LO)); 1504 writel(data & 0xffffffff, (mem_crb + data_lo));
1529 writel(0, 1505 writel((data >> 32) & 0xffffffff, (mem_crb + data_hi));
1530 (mem_crb+MIU_TEST_AGT_ADDR_HI)); 1506 writel((TA_CTL_ENABLE | TA_CTL_WRITE), (mem_crb + TEST_AGT_CTRL));
1531 writel(word[i] & 0xffffffff, 1507 writel((TA_CTL_START | TA_CTL_ENABLE | TA_CTL_WRITE),
1532 (mem_crb+MIU_TEST_AGT_WRDATA_LO)); 1508 (mem_crb + TEST_AGT_CTRL));
1533 writel((word[i] >> 32) & 0xffffffff, 1509
1534 (mem_crb+MIU_TEST_AGT_WRDATA_HI)); 1510 for (j = 0; j < MAX_CTL_CHECK; j++) {
1535 writel(MIU_TA_CTL_ENABLE|MIU_TA_CTL_WRITE, 1511 temp = readl((mem_crb + TEST_AGT_CTRL));
1536 (mem_crb+MIU_TEST_AGT_CTRL)); 1512 if ((temp & TA_CTL_BUSY) == 0)
1537 writel(MIU_TA_CTL_START|MIU_TA_CTL_ENABLE|MIU_TA_CTL_WRITE,
1538 (mem_crb+MIU_TEST_AGT_CTRL));
1539
1540 for (j = 0; j < MAX_CTL_CHECK; j++) {
1541 temp = readl(
1542 (mem_crb+MIU_TEST_AGT_CTRL));
1543 if ((temp & MIU_TA_CTL_BUSY) == 0)
1544 break;
1545 }
1546
1547 if (j >= MAX_CTL_CHECK) {
1548 if (printk_ratelimit())
1549 dev_err(&adapter->pdev->dev,
1550 "failed to write through agent\n");
1551 ret = -1;
1552 break; 1513 break;
1553 }
1554 } 1514 }
1555 1515
1516 if (j >= MAX_CTL_CHECK) {
1517 if (printk_ratelimit())
1518 dev_err(&adapter->pdev->dev,
1519 "failed to write through agent\n");
1520 ret = -EIO;
1521 } else
1522 ret = 0;
1523
1556 netxen_nic_pci_change_crbwindow_128M(adapter, 1); 1524 netxen_nic_pci_change_crbwindow_128M(adapter, 1);
1557 write_unlock_irqrestore(&adapter->adapter_lock, flags); 1525 write_unlock_irqrestore(&adapter->adapter_lock, flags);
1558 return ret; 1526 return ret;
@@ -1560,304 +1528,202 @@ correct:
1560 1528
1561static int 1529static int
1562netxen_nic_pci_mem_read_128M(struct netxen_adapter *adapter, 1530netxen_nic_pci_mem_read_128M(struct netxen_adapter *adapter,
1563 u64 off, void *data, int size) 1531 u64 off, u64 *data)
1564{ 1532{
1565 unsigned long flags; 1533 unsigned long flags;
1566 int i, j = 0, k, start, end, loop, sz[2], off0[2]; 1534 int j, ret;
1567 uint32_t temp; 1535 u32 temp, off_lo, off_hi, addr_hi, data_hi, data_lo;
1568 uint64_t off8, val, word[2] = {0, 0}; 1536 u64 val;
1569 void __iomem *mem_crb; 1537 void __iomem *mem_crb;
1570 1538
1571 if (size != 8) 1539 /* Only 64-bit aligned access */
1540 if (off & 7)
1572 return -EIO; 1541 return -EIO;
1573 1542
1543 /* P2 has different SIU and MIU test agent base addr */
1574 if (ADDR_IN_RANGE(off, NETXEN_ADDR_QDR_NET, 1544 if (ADDR_IN_RANGE(off, NETXEN_ADDR_QDR_NET,
1575 NETXEN_ADDR_QDR_NET_MAX_P2)) { 1545 NETXEN_ADDR_QDR_NET_MAX_P2)) {
1576 mem_crb = pci_base_offset(adapter, NETXEN_CRB_QDR_NET); 1546 mem_crb = pci_base_offset(adapter,
1547 NETXEN_CRB_QDR_NET+SIU_TEST_AGT_BASE);
1548 addr_hi = SIU_TEST_AGT_ADDR_HI;
1549 data_lo = SIU_TEST_AGT_RDDATA_LO;
1550 data_hi = SIU_TEST_AGT_RDDATA_HI;
1551 off_lo = off & SIU_TEST_AGT_ADDR_MASK;
1552 off_hi = SIU_TEST_AGT_UPPER_ADDR(off);
1577 goto correct; 1553 goto correct;
1578 } 1554 }
1579 1555
1580 if (ADDR_IN_RANGE(off, NETXEN_ADDR_DDR_NET, NETXEN_ADDR_DDR_NET_MAX)) { 1556 if (ADDR_IN_RANGE(off, NETXEN_ADDR_DDR_NET, NETXEN_ADDR_DDR_NET_MAX)) {
1581 mem_crb = pci_base_offset(adapter, NETXEN_CRB_DDR_NET); 1557 mem_crb = pci_base_offset(adapter,
1558 NETXEN_CRB_DDR_NET+MIU_TEST_AGT_BASE);
1559 addr_hi = MIU_TEST_AGT_ADDR_HI;
1560 data_lo = MIU_TEST_AGT_RDDATA_LO;
1561 data_hi = MIU_TEST_AGT_RDDATA_HI;
1562 off_lo = off & MIU_TEST_AGT_ADDR_MASK;
1563 off_hi = 0;
1582 goto correct; 1564 goto correct;
1583 } 1565 }
1584 1566
1585 return -EIO; 1567 return -EIO;
1586 1568
1587correct: 1569correct:
1588 off8 = off & 0xfffffff8;
1589 off0[0] = off & 0x7;
1590 off0[1] = 0;
1591 sz[0] = (size < (8 - off0[0])) ? size : (8 - off0[0]);
1592 sz[1] = size - sz[0];
1593 loop = ((off0[0] + size - 1) >> 3) + 1;
1594
1595 write_lock_irqsave(&adapter->adapter_lock, flags); 1570 write_lock_irqsave(&adapter->adapter_lock, flags);
1596 netxen_nic_pci_change_crbwindow_128M(adapter, 0); 1571 netxen_nic_pci_change_crbwindow_128M(adapter, 0);
1597 1572
1598 for (i = 0; i < loop; i++) { 1573 writel(off_lo, (mem_crb + MIU_TEST_AGT_ADDR_LO));
1599 writel((uint32_t)(off8 + (i << 3)), 1574 writel(off_hi, (mem_crb + addr_hi));
1600 (mem_crb+MIU_TEST_AGT_ADDR_LO)); 1575 writel(TA_CTL_ENABLE, (mem_crb + TEST_AGT_CTRL));
1601 writel(0, 1576 writel((TA_CTL_START|TA_CTL_ENABLE), (mem_crb + TEST_AGT_CTRL));
1602 (mem_crb+MIU_TEST_AGT_ADDR_HI));
1603 writel(MIU_TA_CTL_ENABLE,
1604 (mem_crb+MIU_TEST_AGT_CTRL));
1605 writel(MIU_TA_CTL_START|MIU_TA_CTL_ENABLE,
1606 (mem_crb+MIU_TEST_AGT_CTRL));
1607
1608 for (j = 0; j < MAX_CTL_CHECK; j++) {
1609 temp = readl(
1610 (mem_crb+MIU_TEST_AGT_CTRL));
1611 if ((temp & MIU_TA_CTL_BUSY) == 0)
1612 break;
1613 }
1614 1577
1615 if (j >= MAX_CTL_CHECK) { 1578 for (j = 0; j < MAX_CTL_CHECK; j++) {
1616 if (printk_ratelimit()) 1579 temp = readl(mem_crb + TEST_AGT_CTRL);
1617 dev_err(&adapter->pdev->dev, 1580 if ((temp & TA_CTL_BUSY) == 0)
1618 "failed to read through agent\n");
1619 break; 1581 break;
1620 } 1582 }
1621 1583
1622 start = off0[i] >> 2; 1584 if (j >= MAX_CTL_CHECK) {
1623 end = (off0[i] + sz[i] - 1) >> 2; 1585 if (printk_ratelimit())
1624 for (k = start; k <= end; k++) { 1586 dev_err(&adapter->pdev->dev,
1625 word[i] |= ((uint64_t) readl( 1587 "failed to read through agent\n");
1626 (mem_crb + 1588 ret = -EIO;
1627 MIU_TEST_AGT_RDDATA(k))) << (32*k)); 1589 } else {
1628 } 1590
1591 temp = readl(mem_crb + data_hi);
1592 val = ((u64)temp << 32);
1593 val |= readl(mem_crb + data_lo);
1594 *data = val;
1595 ret = 0;
1629 } 1596 }
1630 1597
1631 netxen_nic_pci_change_crbwindow_128M(adapter, 1); 1598 netxen_nic_pci_change_crbwindow_128M(adapter, 1);
1632 write_unlock_irqrestore(&adapter->adapter_lock, flags); 1599 write_unlock_irqrestore(&adapter->adapter_lock, flags);
1633 1600
1634 if (j >= MAX_CTL_CHECK) 1601 return ret;
1635 return -1;
1636
1637 if (sz[0] == 8) {
1638 val = word[0];
1639 } else {
1640 val = ((word[0] >> (off0[0] * 8)) & (~(~0ULL << (sz[0] * 8)))) |
1641 ((word[1] & (~(~0ULL << (sz[1] * 8)))) << (sz[0] * 8));
1642 }
1643
1644 switch (size) {
1645 case 1:
1646 *(uint8_t *)data = val;
1647 break;
1648 case 2:
1649 *(uint16_t *)data = val;
1650 break;
1651 case 4:
1652 *(uint32_t *)data = val;
1653 break;
1654 case 8:
1655 *(uint64_t *)data = val;
1656 break;
1657 }
1658 return 0;
1659} 1602}
1660 1603
1661static int 1604static int
1662netxen_nic_pci_mem_write_2M(struct netxen_adapter *adapter, 1605netxen_nic_pci_mem_write_2M(struct netxen_adapter *adapter,
1663 u64 off, void *data, int size) 1606 u64 off, u64 data)
1664{ 1607{
1665 int i, j, ret = 0, loop, sz[2], off0; 1608 unsigned long flags;
1666 uint32_t temp; 1609 int j, ret;
1667 uint64_t off8, tmpw, word[2] = {0, 0}; 1610 u32 temp, off8;
1668 void __iomem *mem_crb; 1611 void __iomem *mem_crb;
1669 1612
1670 if (size != 8) 1613 /* Only 64-bit aligned access */
1614 if (off & 7)
1671 return -EIO; 1615 return -EIO;
1672 1616
1617 /* P3 onward, test agent base for MIU and SIU is same */
1673 if (ADDR_IN_RANGE(off, NETXEN_ADDR_QDR_NET, 1618 if (ADDR_IN_RANGE(off, NETXEN_ADDR_QDR_NET,
1674 NETXEN_ADDR_QDR_NET_MAX_P3)) { 1619 NETXEN_ADDR_QDR_NET_MAX_P3)) {
1675 mem_crb = netxen_get_ioaddr(adapter, NETXEN_CRB_QDR_NET); 1620 mem_crb = netxen_get_ioaddr(adapter,
1621 NETXEN_CRB_QDR_NET+MIU_TEST_AGT_BASE);
1676 goto correct; 1622 goto correct;
1677 } 1623 }
1678 1624
1679 if (ADDR_IN_RANGE(off, NETXEN_ADDR_DDR_NET, NETXEN_ADDR_DDR_NET_MAX)) { 1625 if (ADDR_IN_RANGE(off, NETXEN_ADDR_DDR_NET, NETXEN_ADDR_DDR_NET_MAX)) {
1680 mem_crb = netxen_get_ioaddr(adapter, NETXEN_CRB_DDR_NET); 1626 mem_crb = netxen_get_ioaddr(adapter,
1627 NETXEN_CRB_DDR_NET+MIU_TEST_AGT_BASE);
1681 goto correct; 1628 goto correct;
1682 } 1629 }
1683 1630
1684 return -EIO; 1631 return -EIO;
1685 1632
1686correct: 1633correct:
1687 off8 = off & 0xfffffff8; 1634 off8 = off & MIU_TEST_AGT_ADDR_MASK;
1688 off0 = off & 0x7;
1689 sz[0] = (size < (8 - off0)) ? size : (8 - off0);
1690 sz[1] = size - sz[0];
1691 loop = ((off0 + size - 1) >> 3) + 1;
1692
1693 if ((size != 8) || (off0 != 0)) {
1694 for (i = 0; i < loop; i++) {
1695 if (adapter->pci_mem_read(adapter,
1696 off8 + (i << 3), &word[i], 8))
1697 return -1;
1698 }
1699 }
1700
1701 switch (size) {
1702 case 1:
1703 tmpw = *((uint8_t *)data);
1704 break;
1705 case 2:
1706 tmpw = *((uint16_t *)data);
1707 break;
1708 case 4:
1709 tmpw = *((uint32_t *)data);
1710 break;
1711 case 8:
1712 default:
1713 tmpw = *((uint64_t *)data);
1714 break;
1715 }
1716 1635
1717 word[0] &= ~((~(~0ULL << (sz[0] * 8))) << (off0 * 8)); 1636 write_lock_irqsave(&adapter->adapter_lock, flags);
1718 word[0] |= tmpw << (off0 * 8);
1719 1637
1720 if (loop == 2) { 1638 writel(off8, (mem_crb + MIU_TEST_AGT_ADDR_LO));
1721 word[1] &= ~(~0ULL << (sz[1] * 8)); 1639 writel(0, (mem_crb + MIU_TEST_AGT_ADDR_HI));
1722 word[1] |= tmpw >> (sz[0] * 8); 1640 writel(data & 0xffffffff, mem_crb + MIU_TEST_AGT_WRDATA_LO);
1641 writel((data >> 32) & 0xffffffff, mem_crb + MIU_TEST_AGT_WRDATA_HI);
1642 writel((TA_CTL_ENABLE | TA_CTL_WRITE), (mem_crb + TEST_AGT_CTRL));
1643 writel((TA_CTL_START | TA_CTL_ENABLE | TA_CTL_WRITE),
1644 (mem_crb + TEST_AGT_CTRL));
1645
1646 for (j = 0; j < MAX_CTL_CHECK; j++) {
1647 temp = readl(mem_crb + TEST_AGT_CTRL);
1648 if ((temp & TA_CTL_BUSY) == 0)
1649 break;
1723 } 1650 }
1724 1651
1725 /* 1652 if (j >= MAX_CTL_CHECK) {
1726 * don't lock here - write_wx gets the lock if each time 1653 if (printk_ratelimit())
1727 * write_lock_irqsave(&adapter->adapter_lock, flags); 1654 dev_err(&adapter->pdev->dev,
1728 * netxen_nic_pci_change_crbwindow_128M(adapter, 0);
1729 */
1730
1731 for (i = 0; i < loop; i++) {
1732 writel(off8 + (i << 3), mem_crb+MIU_TEST_AGT_ADDR_LO);
1733 writel(0, mem_crb+MIU_TEST_AGT_ADDR_HI);
1734 writel(word[i] & 0xffffffff, mem_crb+MIU_TEST_AGT_WRDATA_LO);
1735 writel((word[i] >> 32) & 0xffffffff,
1736 mem_crb+MIU_TEST_AGT_WRDATA_HI);
1737 writel((MIU_TA_CTL_ENABLE | MIU_TA_CTL_WRITE),
1738 mem_crb+MIU_TEST_AGT_CTRL);
1739 writel(MIU_TA_CTL_START | MIU_TA_CTL_ENABLE | MIU_TA_CTL_WRITE,
1740 mem_crb+MIU_TEST_AGT_CTRL);
1741
1742 for (j = 0; j < MAX_CTL_CHECK; j++) {
1743 temp = readl(mem_crb + MIU_TEST_AGT_CTRL);
1744 if ((temp & MIU_TA_CTL_BUSY) == 0)
1745 break;
1746 }
1747
1748 if (j >= MAX_CTL_CHECK) {
1749 if (printk_ratelimit())
1750 dev_err(&adapter->pdev->dev,
1751 "failed to write through agent\n"); 1655 "failed to write through agent\n");
1752 ret = -1; 1656 ret = -EIO;
1753 break; 1657 } else
1754 } 1658 ret = 0;
1755 } 1659
1660 write_unlock_irqrestore(&adapter->adapter_lock, flags);
1756 1661
1757 /*
1758 * netxen_nic_pci_change_crbwindow_128M(adapter, 1);
1759 * write_unlock_irqrestore(&adapter->adapter_lock, flags);
1760 */
1761 return ret; 1662 return ret;
1762} 1663}
1763 1664
1764static int 1665static int
1765netxen_nic_pci_mem_read_2M(struct netxen_adapter *adapter, 1666netxen_nic_pci_mem_read_2M(struct netxen_adapter *adapter,
1766 u64 off, void *data, int size) 1667 u64 off, u64 *data)
1767{ 1668{
1768 int i, j = 0, k, start, end, loop, sz[2], off0[2]; 1669 unsigned long flags;
1769 uint32_t temp; 1670 int j, ret;
1770 uint64_t off8, val, word[2] = {0, 0}; 1671 u32 temp, off8;
1672 u64 val;
1771 void __iomem *mem_crb; 1673 void __iomem *mem_crb;
1772 1674
1773 if (size != 8) 1675 /* Only 64-bit aligned access */
1676 if (off & 7)
1774 return -EIO; 1677 return -EIO;
1775 1678
1679 /* P3 onward, test agent base for MIU and SIU is same */
1776 if (ADDR_IN_RANGE(off, NETXEN_ADDR_QDR_NET, 1680 if (ADDR_IN_RANGE(off, NETXEN_ADDR_QDR_NET,
1777 NETXEN_ADDR_QDR_NET_MAX_P3)) { 1681 NETXEN_ADDR_QDR_NET_MAX_P3)) {
1778 mem_crb = netxen_get_ioaddr(adapter, NETXEN_CRB_QDR_NET); 1682 mem_crb = netxen_get_ioaddr(adapter,
1683 NETXEN_CRB_QDR_NET+MIU_TEST_AGT_BASE);
1779 goto correct; 1684 goto correct;
1780 } 1685 }
1781 1686
1782 if (ADDR_IN_RANGE(off, NETXEN_ADDR_DDR_NET, NETXEN_ADDR_DDR_NET_MAX)) { 1687 if (ADDR_IN_RANGE(off, NETXEN_ADDR_DDR_NET, NETXEN_ADDR_DDR_NET_MAX)) {
1783 mem_crb = netxen_get_ioaddr(adapter, NETXEN_CRB_DDR_NET); 1688 mem_crb = netxen_get_ioaddr(adapter,
1689 NETXEN_CRB_DDR_NET+MIU_TEST_AGT_BASE);
1784 goto correct; 1690 goto correct;
1785 } 1691 }
1786 1692
1787 return -EIO; 1693 return -EIO;
1788 1694
1789correct: 1695correct:
1790 off8 = off & 0xfffffff8; 1696 off8 = off & MIU_TEST_AGT_ADDR_MASK;
1791 off0[0] = off & 0x7;
1792 off0[1] = 0;
1793 sz[0] = (size < (8 - off0[0])) ? size : (8 - off0[0]);
1794 sz[1] = size - sz[0];
1795 loop = ((off0[0] + size - 1) >> 3) + 1;
1796 1697
1797 /* 1698 write_lock_irqsave(&adapter->adapter_lock, flags);
1798 * don't lock here - write_wx gets the lock if each time
1799 * write_lock_irqsave(&adapter->adapter_lock, flags);
1800 * netxen_nic_pci_change_crbwindow_128M(adapter, 0);
1801 */
1802 1699
1803 for (i = 0; i < loop; i++) { 1700 writel(off8, (mem_crb + MIU_TEST_AGT_ADDR_LO));
1804 writel(off8 + (i << 3), mem_crb + MIU_TEST_AGT_ADDR_LO); 1701 writel(0, (mem_crb + MIU_TEST_AGT_ADDR_HI));
1805 writel(0, mem_crb + MIU_TEST_AGT_ADDR_HI); 1702 writel(TA_CTL_ENABLE, (mem_crb + TEST_AGT_CTRL));
1806 writel(MIU_TA_CTL_ENABLE, mem_crb + MIU_TEST_AGT_CTRL); 1703 writel((TA_CTL_START | TA_CTL_ENABLE), (mem_crb + TEST_AGT_CTRL));
1807 writel(MIU_TA_CTL_START | MIU_TA_CTL_ENABLE,
1808 mem_crb + MIU_TEST_AGT_CTRL);
1809
1810 for (j = 0; j < MAX_CTL_CHECK; j++) {
1811 temp = readl(mem_crb + MIU_TEST_AGT_CTRL);
1812 if ((temp & MIU_TA_CTL_BUSY) == 0)
1813 break;
1814 }
1815 1704
1816 if (j >= MAX_CTL_CHECK) { 1705 for (j = 0; j < MAX_CTL_CHECK; j++) {
1817 if (printk_ratelimit()) 1706 temp = readl(mem_crb + TEST_AGT_CTRL);
1818 dev_err(&adapter->pdev->dev, 1707 if ((temp & TA_CTL_BUSY) == 0)
1819 "failed to read through agent\n");
1820 break; 1708 break;
1821 }
1822
1823 start = off0[i] >> 2;
1824 end = (off0[i] + sz[i] - 1) >> 2;
1825 for (k = start; k <= end; k++) {
1826 temp = readl(mem_crb + MIU_TEST_AGT_RDDATA(k));
1827 word[i] |= ((uint64_t)temp << (32 * k));
1828 }
1829 } 1709 }
1830 1710
1831 /* 1711 if (j >= MAX_CTL_CHECK) {
1832 * netxen_nic_pci_change_crbwindow_128M(adapter, 1); 1712 if (printk_ratelimit())
1833 * write_unlock_irqrestore(&adapter->adapter_lock, flags); 1713 dev_err(&adapter->pdev->dev,
1834 */ 1714 "failed to read through agent\n");
1835 1715 ret = -EIO;
1836 if (j >= MAX_CTL_CHECK)
1837 return -1;
1838
1839 if (sz[0] == 8) {
1840 val = word[0];
1841 } else { 1716 } else {
1842 val = ((word[0] >> (off0[0] * 8)) & (~(~0ULL << (sz[0] * 8)))) | 1717 temp = readl(mem_crb + MIU_TEST_AGT_RDDATA_HI);
1843 ((word[1] & (~(~0ULL << (sz[1] * 8)))) << (sz[0] * 8)); 1718 val = (u64)temp << 32;
1719 val |= readl(mem_crb + MIU_TEST_AGT_RDDATA_LO);
1720 *data = val;
1721 ret = 0;
1844 } 1722 }
1845 1723
1846 switch (size) { 1724 write_unlock_irqrestore(&adapter->adapter_lock, flags);
1847 case 1: 1725
1848 *(uint8_t *)data = val; 1726 return ret;
1849 break;
1850 case 2:
1851 *(uint16_t *)data = val;
1852 break;
1853 case 4:
1854 *(uint32_t *)data = val;
1855 break;
1856 case 8:
1857 *(uint64_t *)data = val;
1858 break;
1859 }
1860 return 0;
1861} 1727}
1862 1728
1863void 1729void
diff --git a/drivers/net/netxen/netxen_nic_init.c b/drivers/net/netxen/netxen_nic_init.c
index 91c2bc61c8eb..424b456c5c82 100644
--- a/drivers/net/netxen/netxen_nic_init.c
+++ b/drivers/net/netxen/netxen_nic_init.c
@@ -702,7 +702,10 @@ netxen_load_firmware(struct netxen_adapter *adapter)
702 702
703 for (i = 0; i < size; i++) { 703 for (i = 0; i < size; i++) {
704 data = cpu_to_le64(ptr64[i]); 704 data = cpu_to_le64(ptr64[i]);
705 adapter->pci_mem_write(adapter, flashaddr, &data, 8); 705 if (adapter->pci_mem_write(adapter,
706 flashaddr, data))
707 return -EIO;
708
706 flashaddr += 8; 709 flashaddr += 8;
707 } 710 }
708 711
@@ -716,7 +719,7 @@ netxen_load_firmware(struct netxen_adapter *adapter)
716 data = cpu_to_le64(ptr64[i]); 719 data = cpu_to_le64(ptr64[i]);
717 720
718 if (adapter->pci_mem_write(adapter, 721 if (adapter->pci_mem_write(adapter,
719 flashaddr, &data, 8)) 722 flashaddr, data))
720 return -EIO; 723 return -EIO;
721 724
722 flashaddr += 8; 725 flashaddr += 8;
@@ -730,17 +733,17 @@ netxen_load_firmware(struct netxen_adapter *adapter)
730 733
731 for (i = 0; i < size; i++) { 734 for (i = 0; i < size; i++) {
732 if (netxen_rom_fast_read(adapter, 735 if (netxen_rom_fast_read(adapter,
733 flashaddr, &lo) != 0) 736 flashaddr, (int *)&lo) != 0)
734 return -EIO; 737 return -EIO;
735 if (netxen_rom_fast_read(adapter, 738 if (netxen_rom_fast_read(adapter,
736 flashaddr + 4, &hi) != 0) 739 flashaddr + 4, (int *)&hi) != 0)
737 return -EIO; 740 return -EIO;
738 741
739 /* hi, lo are already in host endian byteorder */ 742 /* hi, lo are already in host endian byteorder */
740 data = (((u64)hi << 32) | lo); 743 data = (((u64)hi << 32) | lo);
741 744
742 if (adapter->pci_mem_write(adapter, 745 if (adapter->pci_mem_write(adapter,
743 flashaddr, &data, 8)) 746 flashaddr, data))
744 return -EIO; 747 return -EIO;
745 748
746 flashaddr += 8; 749 flashaddr += 8;