aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/netxen/netxen_nic_hw.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/netxen/netxen_nic_hw.c')
-rw-r--r--drivers/net/netxen/netxen_nic_hw.c430
1 files changed, 148 insertions, 282 deletions
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