aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/netxen
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/netxen')
-rw-r--r--drivers/net/netxen/netxen_nic.h6
-rw-r--r--drivers/net/netxen/netxen_nic_ethtool.c9
-rw-r--r--drivers/net/netxen/netxen_nic_hdr.h8
-rw-r--r--drivers/net/netxen/netxen_nic_hw.c131
-rw-r--r--drivers/net/netxen/netxen_nic_init.c169
-rw-r--r--drivers/net/netxen/netxen_nic_main.c85
6 files changed, 283 insertions, 125 deletions
diff --git a/drivers/net/netxen/netxen_nic.h b/drivers/net/netxen/netxen_nic.h
index 0f703838e21a..ffa1b9ce1cc5 100644
--- a/drivers/net/netxen/netxen_nic.h
+++ b/drivers/net/netxen/netxen_nic.h
@@ -95,6 +95,9 @@
95#define ADDR_IN_WINDOW1(off) \ 95#define ADDR_IN_WINDOW1(off) \
96 ((off > NETXEN_CRB_PCIX_HOST2) && (off < NETXEN_CRB_MAX)) ? 1 : 0 96 ((off > NETXEN_CRB_PCIX_HOST2) && (off < NETXEN_CRB_MAX)) ? 1 : 0
97 97
98#define ADDR_IN_RANGE(addr, low, high) \
99 (((addr) < (high)) && ((addr) >= (low)))
100
98/* 101/*
99 * normalize a 64MB crb address to 32MB PCI window 102 * normalize a 64MB crb address to 32MB PCI window
100 * To use NETXEN_CRB_NORMALIZE, window _must_ be set to 1 103 * To use NETXEN_CRB_NORMALIZE, window _must_ be set to 1
@@ -420,7 +423,6 @@ struct status_desc {
420} __attribute__ ((aligned(16))); 423} __attribute__ ((aligned(16)));
421 424
422/* UNIFIED ROMIMAGE *************************/ 425/* UNIFIED ROMIMAGE *************************/
423#define NX_UNI_FW_MIN_SIZE 0xc8000
424#define NX_UNI_DIR_SECT_PRODUCT_TBL 0x0 426#define NX_UNI_DIR_SECT_PRODUCT_TBL 0x0
425#define NX_UNI_DIR_SECT_BOOTLD 0x6 427#define NX_UNI_DIR_SECT_BOOTLD 0x6
426#define NX_UNI_DIR_SECT_FW 0x7 428#define NX_UNI_DIR_SECT_FW 0x7
@@ -1353,6 +1355,8 @@ int netxen_config_rss(struct netxen_adapter *adapter, int enable);
1353int netxen_config_ipaddr(struct netxen_adapter *adapter, u32 ip, int cmd); 1355int netxen_config_ipaddr(struct netxen_adapter *adapter, u32 ip, int cmd);
1354int netxen_linkevent_request(struct netxen_adapter *adapter, int enable); 1356int netxen_linkevent_request(struct netxen_adapter *adapter, int enable);
1355void netxen_advert_link_change(struct netxen_adapter *adapter, int linkup); 1357void netxen_advert_link_change(struct netxen_adapter *adapter, int linkup);
1358void netxen_pci_camqm_read_2M(struct netxen_adapter *, u64, u64 *);
1359void netxen_pci_camqm_write_2M(struct netxen_adapter *, u64, u64);
1356 1360
1357int nx_fw_cmd_set_mtu(struct netxen_adapter *adapter, int mtu); 1361int nx_fw_cmd_set_mtu(struct netxen_adapter *adapter, int mtu);
1358int netxen_nic_change_mtu(struct net_device *netdev, int new_mtu); 1362int netxen_nic_change_mtu(struct net_device *netdev, int new_mtu);
diff --git a/drivers/net/netxen/netxen_nic_ethtool.c b/drivers/net/netxen/netxen_nic_ethtool.c
index f8499e56cbee..20f7c58bd092 100644
--- a/drivers/net/netxen/netxen_nic_ethtool.c
+++ b/drivers/net/netxen/netxen_nic_ethtool.c
@@ -632,6 +632,9 @@ static int netxen_nic_reg_test(struct net_device *dev)
632 if ((data_read & 0xffff) != adapter->pdev->vendor) 632 if ((data_read & 0xffff) != adapter->pdev->vendor)
633 return 1; 633 return 1;
634 634
635 if (NX_IS_REVISION_P3(adapter->ahw.revision_id))
636 return 0;
637
635 data_written = (u32)0xa5a5a5a5; 638 data_written = (u32)0xa5a5a5a5;
636 639
637 NXWR32(adapter, CRB_SCRATCHPAD_TEST, data_written); 640 NXWR32(adapter, CRB_SCRATCHPAD_TEST, data_written);
@@ -703,6 +706,11 @@ netxen_nic_get_ethtool_stats(struct net_device *dev,
703 } 706 }
704} 707}
705 708
709static u32 netxen_nic_get_tx_csum(struct net_device *dev)
710{
711 return dev->features & NETIF_F_IP_CSUM;
712}
713
706static u32 netxen_nic_get_rx_csum(struct net_device *dev) 714static u32 netxen_nic_get_rx_csum(struct net_device *dev)
707{ 715{
708 struct netxen_adapter *adapter = netdev_priv(dev); 716 struct netxen_adapter *adapter = netdev_priv(dev);
@@ -909,6 +917,7 @@ const struct ethtool_ops netxen_nic_ethtool_ops = {
909 .set_ringparam = netxen_nic_set_ringparam, 917 .set_ringparam = netxen_nic_set_ringparam,
910 .get_pauseparam = netxen_nic_get_pauseparam, 918 .get_pauseparam = netxen_nic_get_pauseparam,
911 .set_pauseparam = netxen_nic_set_pauseparam, 919 .set_pauseparam = netxen_nic_set_pauseparam,
920 .get_tx_csum = netxen_nic_get_tx_csum,
912 .set_tx_csum = ethtool_op_set_tx_csum, 921 .set_tx_csum = ethtool_op_set_tx_csum,
913 .set_sg = ethtool_op_set_sg, 922 .set_sg = ethtool_op_set_sg,
914 .get_tso = netxen_nic_get_tso, 923 .get_tso = netxen_nic_get_tso,
diff --git a/drivers/net/netxen/netxen_nic_hdr.h b/drivers/net/netxen/netxen_nic_hdr.h
index 622e4c8be937..d8bd73d7e296 100644
--- a/drivers/net/netxen/netxen_nic_hdr.h
+++ b/drivers/net/netxen/netxen_nic_hdr.h
@@ -681,14 +681,8 @@ enum {
681#define MIU_TEST_AGT_ADDR_HI (0x08) 681#define MIU_TEST_AGT_ADDR_HI (0x08)
682#define MIU_TEST_AGT_WRDATA_LO (0x10) 682#define MIU_TEST_AGT_WRDATA_LO (0x10)
683#define MIU_TEST_AGT_WRDATA_HI (0x14) 683#define MIU_TEST_AGT_WRDATA_HI (0x14)
684#define MIU_TEST_AGT_WRDATA_UPPER_LO (0x20)
685#define MIU_TEST_AGT_WRDATA_UPPER_HI (0x24)
686#define MIU_TEST_AGT_WRDATA(i) (0x10+(0x10*((i)>>1))+(4*((i)&1)))
687#define MIU_TEST_AGT_RDDATA_LO (0x18) 684#define MIU_TEST_AGT_RDDATA_LO (0x18)
688#define MIU_TEST_AGT_RDDATA_HI (0x1c) 685#define MIU_TEST_AGT_RDDATA_HI (0x1c)
689#define MIU_TEST_AGT_RDDATA_UPPER_LO (0x28)
690#define MIU_TEST_AGT_RDDATA_UPPER_HI (0x2c)
691#define MIU_TEST_AGT_RDDATA(i) (0x18+(0x10*((i)>>1))+(4*((i)&1)))
692 686
693#define MIU_TEST_AGT_ADDR_MASK 0xfffffff8 687#define MIU_TEST_AGT_ADDR_MASK 0xfffffff8
694#define MIU_TEST_AGT_UPPER_ADDR(off) (0) 688#define MIU_TEST_AGT_UPPER_ADDR(off) (0)
@@ -789,9 +783,7 @@ enum {
789 * for backward compability 783 * for backward compability
790 */ 784 */
791#define CRB_NIC_CAPABILITIES_HOST NETXEN_NIC_REG(0x1a8) 785#define CRB_NIC_CAPABILITIES_HOST NETXEN_NIC_REG(0x1a8)
792#define CRB_NIC_CAPABILITIES_FW NETXEN_NIC_REG(0x1dc)
793#define CRB_NIC_MSI_MODE_HOST NETXEN_NIC_REG(0x270) 786#define CRB_NIC_MSI_MODE_HOST NETXEN_NIC_REG(0x270)
794#define CRB_NIC_MSI_MODE_FW NETXEN_NIC_REG(0x274)
795 787
796#define INTR_SCHEME_PERPORT 0x1 788#define INTR_SCHEME_PERPORT 0x1
797#define MSI_MODE_MULTIFUNC 0x1 789#define MSI_MODE_MULTIFUNC 0x1
diff --git a/drivers/net/netxen/netxen_nic_hw.c b/drivers/net/netxen/netxen_nic_hw.c
index b1cf46a0c48c..5c496f8d7c49 100644
--- a/drivers/net/netxen/netxen_nic_hw.c
+++ b/drivers/net/netxen/netxen_nic_hw.c
@@ -32,7 +32,6 @@
32#define MASK(n) ((1ULL<<(n))-1) 32#define MASK(n) ((1ULL<<(n))-1)
33#define MN_WIN(addr) (((addr & 0x1fc0000) >> 1) | ((addr >> 25) & 0x3ff)) 33#define MN_WIN(addr) (((addr & 0x1fc0000) >> 1) | ((addr >> 25) & 0x3ff))
34#define OCM_WIN(addr) (((addr & 0x1ff0000) >> 1) | ((addr >> 25) & 0x3ff)) 34#define OCM_WIN(addr) (((addr & 0x1ff0000) >> 1) | ((addr >> 25) & 0x3ff))
35#define OCM_WIN_P3P(addr) (addr & 0xffc0000)
36#define MS_WIN(addr) (addr & 0x0ffc0000) 35#define MS_WIN(addr) (addr & 0x0ffc0000)
37 36
38#define GET_MEM_OFFS_2M(addr) (addr & MASK(18)) 37#define GET_MEM_OFFS_2M(addr) (addr & MASK(18))
@@ -63,9 +62,6 @@ static inline void writeq(u64 val, void __iomem *addr)
63} 62}
64#endif 63#endif
65 64
66#define ADDR_IN_RANGE(addr, low, high) \
67 (((addr) < (high)) && ((addr) >= (low)))
68
69#define PCI_OFFSET_FIRST_RANGE(adapter, off) \ 65#define PCI_OFFSET_FIRST_RANGE(adapter, off) \
70 ((adapter)->ahw.pci_base0 + (off)) 66 ((adapter)->ahw.pci_base0 + (off))
71#define PCI_OFFSET_SECOND_RANGE(adapter, off) \ 67#define PCI_OFFSET_SECOND_RANGE(adapter, off) \
@@ -538,7 +534,7 @@ netxen_nic_set_mcast_addr(struct netxen_adapter *adapter,
538void netxen_p2_nic_set_multi(struct net_device *netdev) 534void netxen_p2_nic_set_multi(struct net_device *netdev)
539{ 535{
540 struct netxen_adapter *adapter = netdev_priv(netdev); 536 struct netxen_adapter *adapter = netdev_priv(netdev);
541 struct dev_mc_list *mc_ptr; 537 struct netdev_hw_addr *ha;
542 u8 null_addr[6]; 538 u8 null_addr[6];
543 int i; 539 int i;
544 540
@@ -572,8 +568,8 @@ void netxen_p2_nic_set_multi(struct net_device *netdev)
572 netxen_nic_enable_mcast_filter(adapter); 568 netxen_nic_enable_mcast_filter(adapter);
573 569
574 i = 0; 570 i = 0;
575 netdev_for_each_mc_addr(mc_ptr, netdev) 571 netdev_for_each_mc_addr(ha, netdev)
576 netxen_nic_set_mcast_addr(adapter, i++, mc_ptr->dmi_addr); 572 netxen_nic_set_mcast_addr(adapter, i++, ha->addr);
577 573
578 /* Clear out remaining addresses */ 574 /* Clear out remaining addresses */
579 while (i < adapter->max_mc_count) 575 while (i < adapter->max_mc_count)
@@ -681,7 +677,7 @@ static int nx_p3_nic_add_mac(struct netxen_adapter *adapter,
681void netxen_p3_nic_set_multi(struct net_device *netdev) 677void netxen_p3_nic_set_multi(struct net_device *netdev)
682{ 678{
683 struct netxen_adapter *adapter = netdev_priv(netdev); 679 struct netxen_adapter *adapter = netdev_priv(netdev);
684 struct dev_mc_list *mc_ptr; 680 struct netdev_hw_addr *ha;
685 u8 bcast_addr[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; 681 u8 bcast_addr[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
686 u32 mode = VPORT_MISS_MODE_DROP; 682 u32 mode = VPORT_MISS_MODE_DROP;
687 LIST_HEAD(del_list); 683 LIST_HEAD(del_list);
@@ -708,8 +704,8 @@ void netxen_p3_nic_set_multi(struct net_device *netdev)
708 } 704 }
709 705
710 if (!netdev_mc_empty(netdev)) { 706 if (!netdev_mc_empty(netdev)) {
711 netdev_for_each_mc_addr(mc_ptr, netdev) 707 netdev_for_each_mc_addr(ha, netdev)
712 nx_p3_nic_add_mac(adapter, mc_ptr->dmi_addr, &del_list); 708 nx_p3_nic_add_mac(adapter, ha->addr, &del_list);
713 } 709 }
714 710
715send_fw_cmd: 711send_fw_cmd:
@@ -1391,18 +1387,8 @@ netxen_nic_pci_set_window_2M(struct netxen_adapter *adapter,
1391 u64 addr, u32 *start) 1387 u64 addr, u32 *start)
1392{ 1388{
1393 u32 window; 1389 u32 window;
1394 struct pci_dev *pdev = adapter->pdev;
1395 1390
1396 if ((addr & 0x00ff800) == 0xff800) { 1391 window = OCM_WIN(addr);
1397 if (printk_ratelimit())
1398 dev_warn(&pdev->dev, "QM access not handled\n");
1399 return -EIO;
1400 }
1401
1402 if (NX_IS_REVISION_P3P(adapter->ahw.revision_id))
1403 window = OCM_WIN_P3P(addr);
1404 else
1405 window = OCM_WIN(addr);
1406 1392
1407 writel(window, adapter->ahw.ocm_win_crb); 1393 writel(window, adapter->ahw.ocm_win_crb);
1408 /* read back to flush */ 1394 /* read back to flush */
@@ -1419,7 +1405,7 @@ netxen_nic_pci_mem_access_direct(struct netxen_adapter *adapter, u64 off,
1419{ 1405{
1420 void __iomem *addr, *mem_ptr = NULL; 1406 void __iomem *addr, *mem_ptr = NULL;
1421 resource_size_t mem_base; 1407 resource_size_t mem_base;
1422 int ret = -EIO; 1408 int ret;
1423 u32 start; 1409 u32 start;
1424 1410
1425 spin_lock(&adapter->ahw.mem_lock); 1411 spin_lock(&adapter->ahw.mem_lock);
@@ -1428,20 +1414,23 @@ netxen_nic_pci_mem_access_direct(struct netxen_adapter *adapter, u64 off,
1428 if (ret != 0) 1414 if (ret != 0)
1429 goto unlock; 1415 goto unlock;
1430 1416
1431 addr = pci_base_offset(adapter, start); 1417 if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) {
1432 if (addr) 1418 addr = adapter->ahw.pci_base0 + start;
1433 goto noremap; 1419 } else {
1434 1420 addr = pci_base_offset(adapter, start);
1435 mem_base = pci_resource_start(adapter->pdev, 0) + (start & PAGE_MASK); 1421 if (addr)
1422 goto noremap;
1423
1424 mem_base = pci_resource_start(adapter->pdev, 0) +
1425 (start & PAGE_MASK);
1426 mem_ptr = ioremap(mem_base, PAGE_SIZE);
1427 if (mem_ptr == NULL) {
1428 ret = -EIO;
1429 goto unlock;
1430 }
1436 1431
1437 mem_ptr = ioremap(mem_base, PAGE_SIZE); 1432 addr = mem_ptr + (start & (PAGE_SIZE-1));
1438 if (mem_ptr == NULL) {
1439 ret = -EIO;
1440 goto unlock;
1441 } 1433 }
1442
1443 addr = mem_ptr + (start & (PAGE_SIZE - 1));
1444
1445noremap: 1434noremap:
1446 if (op == 0) /* read */ 1435 if (op == 0) /* read */
1447 *data = readq(addr); 1436 *data = readq(addr);
@@ -1456,6 +1445,28 @@ unlock:
1456 return ret; 1445 return ret;
1457} 1446}
1458 1447
1448void
1449netxen_pci_camqm_read_2M(struct netxen_adapter *adapter, u64 off, u64 *data)
1450{
1451 void __iomem *addr = adapter->ahw.pci_base0 +
1452 NETXEN_PCI_CAMQM_2M_BASE + (off - NETXEN_PCI_CAMQM);
1453
1454 spin_lock(&adapter->ahw.mem_lock);
1455 *data = readq(addr);
1456 spin_unlock(&adapter->ahw.mem_lock);
1457}
1458
1459void
1460netxen_pci_camqm_write_2M(struct netxen_adapter *adapter, u64 off, u64 data)
1461{
1462 void __iomem *addr = adapter->ahw.pci_base0 +
1463 NETXEN_PCI_CAMQM_2M_BASE + (off - NETXEN_PCI_CAMQM);
1464
1465 spin_lock(&adapter->ahw.mem_lock);
1466 writeq(data, addr);
1467 spin_unlock(&adapter->ahw.mem_lock);
1468}
1469
1459#define MAX_CTL_CHECK 1000 1470#define MAX_CTL_CHECK 1000
1460 1471
1461static int 1472static int
@@ -1621,9 +1632,8 @@ static int
1621netxen_nic_pci_mem_write_2M(struct netxen_adapter *adapter, 1632netxen_nic_pci_mem_write_2M(struct netxen_adapter *adapter,
1622 u64 off, u64 data) 1633 u64 off, u64 data)
1623{ 1634{
1624 int i, j, ret; 1635 int j, ret;
1625 u32 temp, off8; 1636 u32 temp, off8;
1626 u64 stride;
1627 void __iomem *mem_crb; 1637 void __iomem *mem_crb;
1628 1638
1629 /* Only 64-bit aligned access */ 1639 /* Only 64-bit aligned access */
@@ -1650,44 +1660,17 @@ netxen_nic_pci_mem_write_2M(struct netxen_adapter *adapter,
1650 return -EIO; 1660 return -EIO;
1651 1661
1652correct: 1662correct:
1653 stride = NX_IS_REVISION_P3P(adapter->ahw.revision_id) ? 16 : 8; 1663 off8 = off & 0xfffffff8;
1654
1655 off8 = off & ~(stride-1);
1656 1664
1657 spin_lock(&adapter->ahw.mem_lock); 1665 spin_lock(&adapter->ahw.mem_lock);
1658 1666
1659 writel(off8, (mem_crb + MIU_TEST_AGT_ADDR_LO)); 1667 writel(off8, (mem_crb + MIU_TEST_AGT_ADDR_LO));
1660 writel(0, (mem_crb + MIU_TEST_AGT_ADDR_HI)); 1668 writel(0, (mem_crb + MIU_TEST_AGT_ADDR_HI));
1661 1669
1662 i = 0;
1663 if (stride == 16) {
1664 writel(TA_CTL_ENABLE, (mem_crb + TEST_AGT_CTRL));
1665 writel((TA_CTL_START | TA_CTL_ENABLE),
1666 (mem_crb + TEST_AGT_CTRL));
1667
1668 for (j = 0; j < MAX_CTL_CHECK; j++) {
1669 temp = readl(mem_crb + TEST_AGT_CTRL);
1670 if ((temp & TA_CTL_BUSY) == 0)
1671 break;
1672 }
1673
1674 if (j >= MAX_CTL_CHECK) {
1675 ret = -EIO;
1676 goto done;
1677 }
1678
1679 i = (off & 0xf) ? 0 : 2;
1680 writel(readl(mem_crb + MIU_TEST_AGT_RDDATA(i)),
1681 mem_crb + MIU_TEST_AGT_WRDATA(i));
1682 writel(readl(mem_crb + MIU_TEST_AGT_RDDATA(i+1)),
1683 mem_crb + MIU_TEST_AGT_WRDATA(i+1));
1684 i = (off & 0xf) ? 2 : 0;
1685 }
1686
1687 writel(data & 0xffffffff, 1670 writel(data & 0xffffffff,
1688 mem_crb + MIU_TEST_AGT_WRDATA(i)); 1671 mem_crb + MIU_TEST_AGT_WRDATA_LO);
1689 writel((data >> 32) & 0xffffffff, 1672 writel((data >> 32) & 0xffffffff,
1690 mem_crb + MIU_TEST_AGT_WRDATA(i+1)); 1673 mem_crb + MIU_TEST_AGT_WRDATA_HI);
1691 1674
1692 writel((TA_CTL_ENABLE | TA_CTL_WRITE), (mem_crb + TEST_AGT_CTRL)); 1675 writel((TA_CTL_ENABLE | TA_CTL_WRITE), (mem_crb + TEST_AGT_CTRL));
1693 writel((TA_CTL_START | TA_CTL_ENABLE | TA_CTL_WRITE), 1676 writel((TA_CTL_START | TA_CTL_ENABLE | TA_CTL_WRITE),
@@ -1707,7 +1690,6 @@ correct:
1707 } else 1690 } else
1708 ret = 0; 1691 ret = 0;
1709 1692
1710done:
1711 spin_unlock(&adapter->ahw.mem_lock); 1693 spin_unlock(&adapter->ahw.mem_lock);
1712 1694
1713 return ret; 1695 return ret;
@@ -1719,7 +1701,7 @@ netxen_nic_pci_mem_read_2M(struct netxen_adapter *adapter,
1719{ 1701{
1720 int j, ret; 1702 int j, ret;
1721 u32 temp, off8; 1703 u32 temp, off8;
1722 u64 val, stride; 1704 u64 val;
1723 void __iomem *mem_crb; 1705 void __iomem *mem_crb;
1724 1706
1725 /* Only 64-bit aligned access */ 1707 /* Only 64-bit aligned access */
@@ -1748,9 +1730,7 @@ netxen_nic_pci_mem_read_2M(struct netxen_adapter *adapter,
1748 return -EIO; 1730 return -EIO;
1749 1731
1750correct: 1732correct:
1751 stride = NX_IS_REVISION_P3P(adapter->ahw.revision_id) ? 16 : 8; 1733 off8 = off & 0xfffffff8;
1752
1753 off8 = off & ~(stride-1);
1754 1734
1755 spin_lock(&adapter->ahw.mem_lock); 1735 spin_lock(&adapter->ahw.mem_lock);
1756 1736
@@ -1771,13 +1751,8 @@ correct:
1771 "failed to read through agent\n"); 1751 "failed to read through agent\n");
1772 ret = -EIO; 1752 ret = -EIO;
1773 } else { 1753 } else {
1774 off8 = MIU_TEST_AGT_RDDATA_LO; 1754 val = (u64)(readl(mem_crb + MIU_TEST_AGT_RDDATA_HI)) << 32;
1775 if ((stride == 16) && (off & 0xf)) 1755 val |= readl(mem_crb + MIU_TEST_AGT_RDDATA_LO);
1776 off8 = MIU_TEST_AGT_RDDATA_UPPER_LO;
1777
1778 temp = readl(mem_crb + off8 + 4);
1779 val = (u64)temp << 32;
1780 val |= readl(mem_crb + off8);
1781 *data = val; 1756 *data = val;
1782 ret = 0; 1757 ret = 0;
1783 } 1758 }
diff --git a/drivers/net/netxen/netxen_nic_init.c b/drivers/net/netxen/netxen_nic_init.c
index 02876f59cbb2..045a7c8f5bdf 100644
--- a/drivers/net/netxen/netxen_nic_init.c
+++ b/drivers/net/netxen/netxen_nic_init.c
@@ -614,22 +614,123 @@ static struct uni_table_desc *nx_get_table_desc(const u8 *unirom, int section)
614 return NULL; 614 return NULL;
615} 615}
616 616
617#define QLCNIC_FILEHEADER_SIZE (14 * 4)
618
617static int 619static int
618nx_set_product_offs(struct netxen_adapter *adapter) 620netxen_nic_validate_header(struct netxen_adapter *adapter)
619{ 621 {
620 struct uni_table_desc *ptab_descr;
621 const u8 *unirom = adapter->fw->data; 622 const u8 *unirom = adapter->fw->data;
622 uint32_t i; 623 struct uni_table_desc *directory = (struct uni_table_desc *) &unirom[0];
624 u32 fw_file_size = adapter->fw->size;
625 u32 tab_size;
623 __le32 entries; 626 __le32 entries;
627 __le32 entry_size;
628
629 if (fw_file_size < QLCNIC_FILEHEADER_SIZE)
630 return -EINVAL;
631
632 entries = cpu_to_le32(directory->num_entries);
633 entry_size = cpu_to_le32(directory->entry_size);
634 tab_size = cpu_to_le32(directory->findex) + (entries * entry_size);
635
636 if (fw_file_size < tab_size)
637 return -EINVAL;
638
639 return 0;
640}
641
642static int
643netxen_nic_validate_bootld(struct netxen_adapter *adapter)
644{
645 struct uni_table_desc *tab_desc;
646 struct uni_data_desc *descr;
647 const u8 *unirom = adapter->fw->data;
648 __le32 idx = cpu_to_le32(*((int *)&unirom[adapter->file_prd_off] +
649 NX_UNI_BOOTLD_IDX_OFF));
650 u32 offs;
651 u32 tab_size;
652 u32 data_size;
653
654 tab_desc = nx_get_table_desc(unirom, NX_UNI_DIR_SECT_BOOTLD);
655
656 if (!tab_desc)
657 return -EINVAL;
658
659 tab_size = cpu_to_le32(tab_desc->findex) +
660 (cpu_to_le32(tab_desc->entry_size) * (idx + 1));
661
662 if (adapter->fw->size < tab_size)
663 return -EINVAL;
664
665 offs = cpu_to_le32(tab_desc->findex) +
666 (cpu_to_le32(tab_desc->entry_size) * (idx));
667 descr = (struct uni_data_desc *)&unirom[offs];
668
669 data_size = cpu_to_le32(descr->findex) + cpu_to_le32(descr->size);
670
671 if (adapter->fw->size < data_size)
672 return -EINVAL;
673
674 return 0;
675}
676
677static int
678netxen_nic_validate_fw(struct netxen_adapter *adapter)
679{
680 struct uni_table_desc *tab_desc;
681 struct uni_data_desc *descr;
682 const u8 *unirom = adapter->fw->data;
683 __le32 idx = cpu_to_le32(*((int *)&unirom[adapter->file_prd_off] +
684 NX_UNI_FIRMWARE_IDX_OFF));
685 u32 offs;
686 u32 tab_size;
687 u32 data_size;
688
689 tab_desc = nx_get_table_desc(unirom, NX_UNI_DIR_SECT_FW);
690
691 if (!tab_desc)
692 return -EINVAL;
693
694 tab_size = cpu_to_le32(tab_desc->findex) +
695 (cpu_to_le32(tab_desc->entry_size) * (idx + 1));
696
697 if (adapter->fw->size < tab_size)
698 return -EINVAL;
699
700 offs = cpu_to_le32(tab_desc->findex) +
701 (cpu_to_le32(tab_desc->entry_size) * (idx));
702 descr = (struct uni_data_desc *)&unirom[offs];
703 data_size = cpu_to_le32(descr->findex) + cpu_to_le32(descr->size);
704
705 if (adapter->fw->size < data_size)
706 return -EINVAL;
624 707
708 return 0;
709}
710
711
712static int
713netxen_nic_validate_product_offs(struct netxen_adapter *adapter)
714{
715 struct uni_table_desc *ptab_descr;
716 const u8 *unirom = adapter->fw->data;
625 int mn_present = (NX_IS_REVISION_P2(adapter->ahw.revision_id)) ? 717 int mn_present = (NX_IS_REVISION_P2(adapter->ahw.revision_id)) ?
626 1 : netxen_p3_has_mn(adapter); 718 1 : netxen_p3_has_mn(adapter);
719 __le32 entries;
720 __le32 entry_size;
721 u32 tab_size;
722 u32 i;
627 723
628 ptab_descr = nx_get_table_desc(unirom, NX_UNI_DIR_SECT_PRODUCT_TBL); 724 ptab_descr = nx_get_table_desc(unirom, NX_UNI_DIR_SECT_PRODUCT_TBL);
629 if (ptab_descr == NULL) 725 if (ptab_descr == NULL)
630 return -1; 726 return -EINVAL;
631 727
632 entries = cpu_to_le32(ptab_descr->num_entries); 728 entries = cpu_to_le32(ptab_descr->num_entries);
729 entry_size = cpu_to_le32(ptab_descr->entry_size);
730 tab_size = cpu_to_le32(ptab_descr->findex) + (entries * entry_size);
731
732 if (adapter->fw->size < tab_size)
733 return -EINVAL;
633 734
634nomn: 735nomn:
635 for (i = 0; i < entries; i++) { 736 for (i = 0; i < entries; i++) {
@@ -658,9 +759,38 @@ nomn:
658 goto nomn; 759 goto nomn;
659 } 760 }
660 761
661 return -1; 762 return -EINVAL;
662} 763}
663 764
765static int
766netxen_nic_validate_unified_romimage(struct netxen_adapter *adapter)
767{
768 if (netxen_nic_validate_header(adapter)) {
769 dev_err(&adapter->pdev->dev,
770 "unified image: header validation failed\n");
771 return -EINVAL;
772 }
773
774 if (netxen_nic_validate_product_offs(adapter)) {
775 dev_err(&adapter->pdev->dev,
776 "unified image: product validation failed\n");
777 return -EINVAL;
778 }
779
780 if (netxen_nic_validate_bootld(adapter)) {
781 dev_err(&adapter->pdev->dev,
782 "unified image: bootld validation failed\n");
783 return -EINVAL;
784 }
785
786 if (netxen_nic_validate_fw(adapter)) {
787 dev_err(&adapter->pdev->dev,
788 "unified image: firmware validation failed\n");
789 return -EINVAL;
790 }
791
792 return 0;
793}
664 794
665static struct uni_data_desc *nx_get_data_desc(struct netxen_adapter *adapter, 795static struct uni_data_desc *nx_get_data_desc(struct netxen_adapter *adapter,
666 u32 section, u32 idx_offset) 796 u32 section, u32 idx_offset)
@@ -890,6 +1020,16 @@ netxen_load_firmware(struct netxen_adapter *adapter)
890 1020
891 flashaddr += 8; 1021 flashaddr += 8;
892 } 1022 }
1023
1024 size = (__force u32)nx_get_fw_size(adapter) % 8;
1025 if (size) {
1026 data = cpu_to_le64(ptr64[i]);
1027
1028 if (adapter->pci_mem_write(adapter,
1029 flashaddr, data))
1030 return -EIO;
1031 }
1032
893 } else { 1033 } else {
894 u64 data; 1034 u64 data;
895 u32 hi, lo; 1035 u32 hi, lo;
@@ -934,27 +1074,23 @@ static int
934netxen_validate_firmware(struct netxen_adapter *adapter) 1074netxen_validate_firmware(struct netxen_adapter *adapter)
935{ 1075{
936 __le32 val; 1076 __le32 val;
937 u32 ver, min_ver, bios, min_size; 1077 u32 ver, min_ver, bios;
938 struct pci_dev *pdev = adapter->pdev; 1078 struct pci_dev *pdev = adapter->pdev;
939 const struct firmware *fw = adapter->fw; 1079 const struct firmware *fw = adapter->fw;
940 u8 fw_type = adapter->fw_type; 1080 u8 fw_type = adapter->fw_type;
941 1081
942 if (fw_type == NX_UNIFIED_ROMIMAGE) { 1082 if (fw_type == NX_UNIFIED_ROMIMAGE) {
943 if (nx_set_product_offs(adapter)) 1083 if (netxen_nic_validate_unified_romimage(adapter))
944 return -EINVAL; 1084 return -EINVAL;
945
946 min_size = NX_UNI_FW_MIN_SIZE;
947 } else { 1085 } else {
948 val = cpu_to_le32(*(u32 *)&fw->data[NX_FW_MAGIC_OFFSET]); 1086 val = cpu_to_le32(*(u32 *)&fw->data[NX_FW_MAGIC_OFFSET]);
949 if ((__force u32)val != NETXEN_BDINFO_MAGIC) 1087 if ((__force u32)val != NETXEN_BDINFO_MAGIC)
950 return -EINVAL; 1088 return -EINVAL;
951 1089
952 min_size = NX_FW_MIN_SIZE; 1090 if (fw->size < NX_FW_MIN_SIZE)
1091 return -EINVAL;
953 } 1092 }
954 1093
955 if (fw->size < min_size)
956 return -EINVAL;
957
958 val = nx_get_fw_version(adapter); 1094 val = nx_get_fw_version(adapter);
959 1095
960 if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) 1096 if (NX_IS_REVISION_P3(adapter->ahw.revision_id))
@@ -1225,10 +1361,12 @@ int netxen_init_firmware(struct netxen_adapter *adapter)
1225 return err; 1361 return err;
1226 1362
1227 NXWR32(adapter, CRB_NIC_CAPABILITIES_HOST, INTR_SCHEME_PERPORT); 1363 NXWR32(adapter, CRB_NIC_CAPABILITIES_HOST, INTR_SCHEME_PERPORT);
1228 NXWR32(adapter, CRB_NIC_MSI_MODE_HOST, MSI_MODE_MULTIFUNC);
1229 NXWR32(adapter, CRB_MPORT_MODE, MPORT_MULTI_FUNCTION_MODE); 1364 NXWR32(adapter, CRB_MPORT_MODE, MPORT_MULTI_FUNCTION_MODE);
1230 NXWR32(adapter, CRB_CMDPEG_STATE, PHAN_INITIALIZE_ACK); 1365 NXWR32(adapter, CRB_CMDPEG_STATE, PHAN_INITIALIZE_ACK);
1231 1366
1367 if (NX_IS_REVISION_P2(adapter->ahw.revision_id))
1368 NXWR32(adapter, CRB_NIC_MSI_MODE_HOST, MSI_MODE_MULTIFUNC);
1369
1232 return err; 1370 return err;
1233} 1371}
1234 1372
@@ -1763,6 +1901,5 @@ netxen_post_rx_buffers_nodb(struct netxen_adapter *adapter,
1763void netxen_nic_clear_stats(struct netxen_adapter *adapter) 1901void netxen_nic_clear_stats(struct netxen_adapter *adapter)
1764{ 1902{
1765 memset(&adapter->stats, 0, sizeof(adapter->stats)); 1903 memset(&adapter->stats, 0, sizeof(adapter->stats));
1766 return;
1767} 1904}
1768 1905
diff --git a/drivers/net/netxen/netxen_nic_main.c b/drivers/net/netxen/netxen_nic_main.c
index ce838f7c8b0f..6ce6ce1df6d2 100644
--- a/drivers/net/netxen/netxen_nic_main.c
+++ b/drivers/net/netxen/netxen_nic_main.c
@@ -782,15 +782,22 @@ netxen_check_options(struct netxen_adapter *adapter)
782 if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) { 782 if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) {
783 adapter->msix_supported = !!use_msi_x; 783 adapter->msix_supported = !!use_msi_x;
784 adapter->rss_supported = !!use_msi_x; 784 adapter->rss_supported = !!use_msi_x;
785 } else if (adapter->fw_version >= NETXEN_VERSION_CODE(3, 4, 336)) { 785 } else {
786 switch (adapter->ahw.board_type) { 786 u32 flashed_ver = 0;
787 case NETXEN_BRDTYPE_P2_SB31_10G: 787 netxen_rom_fast_read(adapter,
788 case NETXEN_BRDTYPE_P2_SB31_10G_CX4: 788 NX_FW_VERSION_OFFSET, (int *)&flashed_ver);
789 adapter->msix_supported = !!use_msi_x; 789 flashed_ver = NETXEN_DECODE_VERSION(flashed_ver);
790 adapter->rss_supported = !!use_msi_x; 790
791 break; 791 if (flashed_ver >= NETXEN_VERSION_CODE(3, 4, 336)) {
792 default: 792 switch (adapter->ahw.board_type) {
793 break; 793 case NETXEN_BRDTYPE_P2_SB31_10G:
794 case NETXEN_BRDTYPE_P2_SB31_10G_CX4:
795 adapter->msix_supported = !!use_msi_x;
796 adapter->rss_supported = !!use_msi_x;
797 break;
798 default:
799 break;
800 }
794 } 801 }
795 } 802 }
796 803
@@ -2304,6 +2311,7 @@ netxen_fwinit_work(struct work_struct *work)
2304 } 2311 }
2305 break; 2312 break;
2306 2313
2314 case NX_DEV_NEED_RESET:
2307 case NX_DEV_INITALIZING: 2315 case NX_DEV_INITALIZING:
2308 if (++adapter->fw_wait_cnt < FW_POLL_THRESH) { 2316 if (++adapter->fw_wait_cnt < FW_POLL_THRESH) {
2309 netxen_schedule_work(adapter, 2317 netxen_schedule_work(adapter,
@@ -2347,6 +2355,9 @@ netxen_detach_work(struct work_struct *work)
2347 2355
2348 ref_cnt = nx_decr_dev_ref_cnt(adapter); 2356 ref_cnt = nx_decr_dev_ref_cnt(adapter);
2349 2357
2358 if (ref_cnt == -EIO)
2359 goto err_ret;
2360
2350 delay = (ref_cnt == 0) ? 0 : (2 * FW_POLL_DELAY); 2361 delay = (ref_cnt == 0) ? 0 : (2 * FW_POLL_DELAY);
2351 2362
2352 adapter->fw_wait_cnt = 0; 2363 adapter->fw_wait_cnt = 0;
@@ -2526,51 +2537,81 @@ static int
2526netxen_sysfs_validate_crb(struct netxen_adapter *adapter, 2537netxen_sysfs_validate_crb(struct netxen_adapter *adapter,
2527 loff_t offset, size_t size) 2538 loff_t offset, size_t size)
2528{ 2539{
2540 size_t crb_size = 4;
2541
2529 if (!(adapter->flags & NETXEN_NIC_DIAG_ENABLED)) 2542 if (!(adapter->flags & NETXEN_NIC_DIAG_ENABLED))
2530 return -EIO; 2543 return -EIO;
2531 2544
2532 if ((size != 4) || (offset & 0x3)) 2545 if (offset < NETXEN_PCI_CRBSPACE) {
2533 return -EINVAL; 2546 if (NX_IS_REVISION_P2(adapter->ahw.revision_id))
2547 return -EINVAL;
2534 2548
2535 if (offset < NETXEN_PCI_CRBSPACE) 2549 if (ADDR_IN_RANGE(offset, NETXEN_PCI_CAMQM,
2536 return -EINVAL; 2550 NETXEN_PCI_CAMQM_2M_END))
2551 crb_size = 8;
2552 else
2553 return -EINVAL;
2554 }
2555
2556 if ((size != crb_size) || (offset & (crb_size-1)))
2557 return -EINVAL;
2537 2558
2538 return 0; 2559 return 0;
2539} 2560}
2540 2561
2541static ssize_t 2562static ssize_t
2542netxen_sysfs_read_crb(struct kobject *kobj, struct bin_attribute *attr, 2563netxen_sysfs_read_crb(struct file *filp, struct kobject *kobj,
2564 struct bin_attribute *attr,
2543 char *buf, loff_t offset, size_t size) 2565 char *buf, loff_t offset, size_t size)
2544{ 2566{
2545 struct device *dev = container_of(kobj, struct device, kobj); 2567 struct device *dev = container_of(kobj, struct device, kobj);
2546 struct netxen_adapter *adapter = dev_get_drvdata(dev); 2568 struct netxen_adapter *adapter = dev_get_drvdata(dev);
2547 u32 data; 2569 u32 data;
2570 u64 qmdata;
2548 int ret; 2571 int ret;
2549 2572
2550 ret = netxen_sysfs_validate_crb(adapter, offset, size); 2573 ret = netxen_sysfs_validate_crb(adapter, offset, size);
2551 if (ret != 0) 2574 if (ret != 0)
2552 return ret; 2575 return ret;
2553 2576
2554 data = NXRD32(adapter, offset); 2577 if (NX_IS_REVISION_P3(adapter->ahw.revision_id) &&
2555 memcpy(buf, &data, size); 2578 ADDR_IN_RANGE(offset, NETXEN_PCI_CAMQM,
2579 NETXEN_PCI_CAMQM_2M_END)) {
2580 netxen_pci_camqm_read_2M(adapter, offset, &qmdata);
2581 memcpy(buf, &qmdata, size);
2582 } else {
2583 data = NXRD32(adapter, offset);
2584 memcpy(buf, &data, size);
2585 }
2586
2556 return size; 2587 return size;
2557} 2588}
2558 2589
2559static ssize_t 2590static ssize_t
2560netxen_sysfs_write_crb(struct kobject *kobj, struct bin_attribute *attr, 2591netxen_sysfs_write_crb(struct file *filp, struct kobject *kobj,
2592 struct bin_attribute *attr,
2561 char *buf, loff_t offset, size_t size) 2593 char *buf, loff_t offset, size_t size)
2562{ 2594{
2563 struct device *dev = container_of(kobj, struct device, kobj); 2595 struct device *dev = container_of(kobj, struct device, kobj);
2564 struct netxen_adapter *adapter = dev_get_drvdata(dev); 2596 struct netxen_adapter *adapter = dev_get_drvdata(dev);
2565 u32 data; 2597 u32 data;
2598 u64 qmdata;
2566 int ret; 2599 int ret;
2567 2600
2568 ret = netxen_sysfs_validate_crb(adapter, offset, size); 2601 ret = netxen_sysfs_validate_crb(adapter, offset, size);
2569 if (ret != 0) 2602 if (ret != 0)
2570 return ret; 2603 return ret;
2571 2604
2572 memcpy(&data, buf, size); 2605 if (NX_IS_REVISION_P3(adapter->ahw.revision_id) &&
2573 NXWR32(adapter, offset, data); 2606 ADDR_IN_RANGE(offset, NETXEN_PCI_CAMQM,
2607 NETXEN_PCI_CAMQM_2M_END)) {
2608 memcpy(&qmdata, buf, size);
2609 netxen_pci_camqm_write_2M(adapter, offset, qmdata);
2610 } else {
2611 memcpy(&data, buf, size);
2612 NXWR32(adapter, offset, data);
2613 }
2614
2574 return size; 2615 return size;
2575} 2616}
2576 2617
@@ -2588,7 +2629,8 @@ netxen_sysfs_validate_mem(struct netxen_adapter *adapter,
2588} 2629}
2589 2630
2590static ssize_t 2631static ssize_t
2591netxen_sysfs_read_mem(struct kobject *kobj, struct bin_attribute *attr, 2632netxen_sysfs_read_mem(struct file *filp, struct kobject *kobj,
2633 struct bin_attribute *attr,
2592 char *buf, loff_t offset, size_t size) 2634 char *buf, loff_t offset, size_t size)
2593{ 2635{
2594 struct device *dev = container_of(kobj, struct device, kobj); 2636 struct device *dev = container_of(kobj, struct device, kobj);
@@ -2608,7 +2650,7 @@ netxen_sysfs_read_mem(struct kobject *kobj, struct bin_attribute *attr,
2608 return size; 2650 return size;
2609} 2651}
2610 2652
2611static ssize_t netxen_sysfs_write_mem(struct kobject *kobj, 2653static ssize_t netxen_sysfs_write_mem(struct file *filp, struct kobject *kobj,
2612 struct bin_attribute *attr, char *buf, 2654 struct bin_attribute *attr, char *buf,
2613 loff_t offset, size_t size) 2655 loff_t offset, size_t size)
2614{ 2656{
@@ -2742,7 +2784,6 @@ netxen_config_indev_addr(struct net_device *dev, unsigned long event)
2742 } endfor_ifa(indev); 2784 } endfor_ifa(indev);
2743 2785
2744 in_dev_put(indev); 2786 in_dev_put(indev);
2745 return;
2746} 2787}
2747 2788
2748static int netxen_netdev_event(struct notifier_block *this, 2789static int netxen_netdev_event(struct notifier_block *this,