diff options
Diffstat (limited to 'drivers/net/netxen/netxen_nic_hw.c')
-rw-r--r-- | drivers/net/netxen/netxen_nic_hw.c | 103 |
1 files changed, 62 insertions, 41 deletions
diff --git a/drivers/net/netxen/netxen_nic_hw.c b/drivers/net/netxen/netxen_nic_hw.c index 96a3bc6426e2..9aa20f961618 100644 --- a/drivers/net/netxen/netxen_nic_hw.c +++ b/drivers/net/netxen/netxen_nic_hw.c | |||
@@ -285,14 +285,7 @@ static unsigned crb_hub_agt[64] = | |||
285 | #define ADDR_IN_RANGE(addr, low, high) \ | 285 | #define ADDR_IN_RANGE(addr, low, high) \ |
286 | (((addr) <= (high)) && ((addr) >= (low))) | 286 | (((addr) <= (high)) && ((addr) >= (low))) |
287 | 287 | ||
288 | #define NETXEN_MAX_MTU 8000 + NETXEN_ENET_HEADER_SIZE + NETXEN_ETH_FCS_SIZE | ||
289 | #define NETXEN_MIN_MTU 64 | ||
290 | #define NETXEN_ETH_FCS_SIZE 4 | ||
291 | #define NETXEN_ENET_HEADER_SIZE 14 | ||
292 | #define NETXEN_WINDOW_ONE 0x2000000 /*CRB Window: bit 25 of CRB address */ | 288 | #define NETXEN_WINDOW_ONE 0x2000000 /*CRB Window: bit 25 of CRB address */ |
293 | #define NETXEN_FIRMWARE_LEN ((16 * 1024) / 4) | ||
294 | #define NETXEN_NIU_HDRSIZE (0x1 << 6) | ||
295 | #define NETXEN_NIU_TLRSIZE (0x1 << 5) | ||
296 | 289 | ||
297 | #define NETXEN_NIC_ZERO_PAUSE_ADDR 0ULL | 290 | #define NETXEN_NIC_ZERO_PAUSE_ADDR 0ULL |
298 | #define NETXEN_NIC_UNIT_PAUSE_ADDR 0x200ULL | 291 | #define NETXEN_NIC_UNIT_PAUSE_ADDR 0x200ULL |
@@ -541,9 +534,6 @@ netxen_send_cmd_descs(struct netxen_adapter *adapter, | |||
541 | return 0; | 534 | return 0; |
542 | } | 535 | } |
543 | 536 | ||
544 | #define NIC_REQUEST 0x14 | ||
545 | #define NETXEN_MAC_EVENT 0x1 | ||
546 | |||
547 | static int nx_p3_sre_macaddr_change(struct net_device *dev, | 537 | static int nx_p3_sre_macaddr_change(struct net_device *dev, |
548 | u8 *addr, unsigned op) | 538 | u8 *addr, unsigned op) |
549 | { | 539 | { |
@@ -553,8 +543,8 @@ static int nx_p3_sre_macaddr_change(struct net_device *dev, | |||
553 | int rv; | 543 | int rv; |
554 | 544 | ||
555 | memset(&req, 0, sizeof(nx_nic_req_t)); | 545 | memset(&req, 0, sizeof(nx_nic_req_t)); |
556 | req.qhdr |= (NIC_REQUEST << 23); | 546 | req.qhdr |= (NX_NIC_REQUEST << 23); |
557 | req.req_hdr |= NETXEN_MAC_EVENT; | 547 | req.req_hdr |= NX_MAC_EVENT; |
558 | req.req_hdr |= ((u64)adapter->portnum << 16); | 548 | req.req_hdr |= ((u64)adapter->portnum << 16); |
559 | mac_req.op = op; | 549 | mac_req.op = op; |
560 | memcpy(&mac_req.mac_addr, addr, 6); | 550 | memcpy(&mac_req.mac_addr, addr, 6); |
@@ -575,31 +565,35 @@ void netxen_p3_nic_set_multi(struct net_device *netdev) | |||
575 | nx_mac_list_t *cur, *next, *del_list, *add_list = NULL; | 565 | nx_mac_list_t *cur, *next, *del_list, *add_list = NULL; |
576 | struct dev_mc_list *mc_ptr; | 566 | struct dev_mc_list *mc_ptr; |
577 | u8 bcast_addr[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; | 567 | u8 bcast_addr[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; |
578 | 568 | u32 mode = VPORT_MISS_MODE_DROP; | |
579 | adapter->set_promisc(adapter, NETXEN_NIU_PROMISC_MODE); | ||
580 | |||
581 | /* | ||
582 | * Programming mac addresses will automaticly enabling L2 filtering. | ||
583 | * HW will replace timestamp with L2 conid when L2 filtering is | ||
584 | * enabled. This causes problem for LSA. Do not enabling L2 filtering | ||
585 | * until that problem is fixed. | ||
586 | */ | ||
587 | if ((netdev->flags & IFF_PROMISC) || | ||
588 | (netdev->mc_count > adapter->max_mc_count)) | ||
589 | return; | ||
590 | 569 | ||
591 | del_list = adapter->mac_list; | 570 | del_list = adapter->mac_list; |
592 | adapter->mac_list = NULL; | 571 | adapter->mac_list = NULL; |
593 | 572 | ||
594 | nx_p3_nic_add_mac(adapter, netdev->dev_addr, &add_list, &del_list); | 573 | nx_p3_nic_add_mac(adapter, netdev->dev_addr, &add_list, &del_list); |
574 | nx_p3_nic_add_mac(adapter, bcast_addr, &add_list, &del_list); | ||
575 | |||
576 | if (netdev->flags & IFF_PROMISC) { | ||
577 | mode = VPORT_MISS_MODE_ACCEPT_ALL; | ||
578 | goto send_fw_cmd; | ||
579 | } | ||
580 | |||
581 | if ((netdev->flags & IFF_ALLMULTI) || | ||
582 | (netdev->mc_count > adapter->max_mc_count)) { | ||
583 | mode = VPORT_MISS_MODE_ACCEPT_MULTI; | ||
584 | goto send_fw_cmd; | ||
585 | } | ||
586 | |||
595 | if (netdev->mc_count > 0) { | 587 | if (netdev->mc_count > 0) { |
596 | nx_p3_nic_add_mac(adapter, bcast_addr, &add_list, &del_list); | ||
597 | for (mc_ptr = netdev->mc_list; mc_ptr; | 588 | for (mc_ptr = netdev->mc_list; mc_ptr; |
598 | mc_ptr = mc_ptr->next) { | 589 | mc_ptr = mc_ptr->next) { |
599 | nx_p3_nic_add_mac(adapter, mc_ptr->dmi_addr, | 590 | nx_p3_nic_add_mac(adapter, mc_ptr->dmi_addr, |
600 | &add_list, &del_list); | 591 | &add_list, &del_list); |
601 | } | 592 | } |
602 | } | 593 | } |
594 | |||
595 | send_fw_cmd: | ||
596 | adapter->set_promisc(adapter, mode); | ||
603 | for (cur = del_list; cur;) { | 597 | for (cur = del_list; cur;) { |
604 | nx_p3_sre_macaddr_change(netdev, cur->mac_addr, NETXEN_MAC_DEL); | 598 | nx_p3_sre_macaddr_change(netdev, cur->mac_addr, NETXEN_MAC_DEL); |
605 | next = cur->next; | 599 | next = cur->next; |
@@ -615,6 +609,21 @@ void netxen_p3_nic_set_multi(struct net_device *netdev) | |||
615 | } | 609 | } |
616 | } | 610 | } |
617 | 611 | ||
612 | int netxen_p3_nic_set_promisc(struct netxen_adapter *adapter, u32 mode) | ||
613 | { | ||
614 | nx_nic_req_t req; | ||
615 | |||
616 | memset(&req, 0, sizeof(nx_nic_req_t)); | ||
617 | |||
618 | req.qhdr |= (NX_HOST_REQUEST << 23); | ||
619 | req.req_hdr |= NX_NIC_H2C_OPCODE_PROXY_SET_VPORT_MISS_MODE; | ||
620 | req.req_hdr |= ((u64)adapter->portnum << 16); | ||
621 | req.words[0] = cpu_to_le64(mode); | ||
622 | |||
623 | return netxen_send_cmd_descs(adapter, | ||
624 | (struct cmd_desc_type0 *)&req, 1); | ||
625 | } | ||
626 | |||
618 | #define NETXEN_CONFIG_INTR_COALESCE 3 | 627 | #define NETXEN_CONFIG_INTR_COALESCE 3 |
619 | 628 | ||
620 | /* | 629 | /* |
@@ -627,7 +636,7 @@ int netxen_config_intr_coalesce(struct netxen_adapter *adapter) | |||
627 | 636 | ||
628 | memset(&req, 0, sizeof(nx_nic_req_t)); | 637 | memset(&req, 0, sizeof(nx_nic_req_t)); |
629 | 638 | ||
630 | req.qhdr |= (NIC_REQUEST << 23); | 639 | req.qhdr |= (NX_NIC_REQUEST << 23); |
631 | req.req_hdr |= NETXEN_CONFIG_INTR_COALESCE; | 640 | req.req_hdr |= NETXEN_CONFIG_INTR_COALESCE; |
632 | req.req_hdr |= ((u64)adapter->portnum << 16); | 641 | req.req_hdr |= ((u64)adapter->portnum << 16); |
633 | 642 | ||
@@ -653,6 +662,7 @@ int netxen_nic_change_mtu(struct net_device *netdev, int mtu) | |||
653 | { | 662 | { |
654 | struct netxen_adapter *adapter = netdev_priv(netdev); | 663 | struct netxen_adapter *adapter = netdev_priv(netdev); |
655 | int max_mtu; | 664 | int max_mtu; |
665 | int rc = 0; | ||
656 | 666 | ||
657 | if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) | 667 | if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) |
658 | max_mtu = P3_MAX_MTU; | 668 | max_mtu = P3_MAX_MTU; |
@@ -666,16 +676,12 @@ int netxen_nic_change_mtu(struct net_device *netdev, int mtu) | |||
666 | } | 676 | } |
667 | 677 | ||
668 | if (adapter->set_mtu) | 678 | if (adapter->set_mtu) |
669 | adapter->set_mtu(adapter, mtu); | 679 | rc = adapter->set_mtu(adapter, mtu); |
670 | netdev->mtu = mtu; | ||
671 | 680 | ||
672 | mtu += MTU_FUDGE_FACTOR; | 681 | if (!rc) |
673 | if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) | 682 | netdev->mtu = mtu; |
674 | nx_fw_cmd_set_mtu(adapter, mtu); | ||
675 | else if (adapter->set_mtu) | ||
676 | adapter->set_mtu(adapter, mtu); | ||
677 | 683 | ||
678 | return 0; | 684 | return rc; |
679 | } | 685 | } |
680 | 686 | ||
681 | int netxen_is_flash_supported(struct netxen_adapter *adapter) | 687 | int netxen_is_flash_supported(struct netxen_adapter *adapter) |
@@ -1411,7 +1417,8 @@ static int netxen_nic_pci_mem_read_direct(struct netxen_adapter *adapter, | |||
1411 | (netxen_nic_pci_is_same_window(adapter, off+size-1) == 0)) { | 1417 | (netxen_nic_pci_is_same_window(adapter, off+size-1) == 0)) { |
1412 | write_unlock_irqrestore(&adapter->adapter_lock, flags); | 1418 | write_unlock_irqrestore(&adapter->adapter_lock, flags); |
1413 | printk(KERN_ERR "%s out of bound pci memory access. " | 1419 | printk(KERN_ERR "%s out of bound pci memory access. " |
1414 | "offset is 0x%llx\n", netxen_nic_driver_name, off); | 1420 | "offset is 0x%llx\n", netxen_nic_driver_name, |
1421 | (unsigned long long)off); | ||
1415 | return -1; | 1422 | return -1; |
1416 | } | 1423 | } |
1417 | 1424 | ||
@@ -1484,7 +1491,8 @@ netxen_nic_pci_mem_write_direct(struct netxen_adapter *adapter, u64 off, | |||
1484 | (netxen_nic_pci_is_same_window(adapter, off+size-1) == 0)) { | 1491 | (netxen_nic_pci_is_same_window(adapter, off+size-1) == 0)) { |
1485 | write_unlock_irqrestore(&adapter->adapter_lock, flags); | 1492 | write_unlock_irqrestore(&adapter->adapter_lock, flags); |
1486 | printk(KERN_ERR "%s out of bound pci memory access. " | 1493 | printk(KERN_ERR "%s out of bound pci memory access. " |
1487 | "offset is 0x%llx\n", netxen_nic_driver_name, off); | 1494 | "offset is 0x%llx\n", netxen_nic_driver_name, |
1495 | (unsigned long long)off); | ||
1488 | return -1; | 1496 | return -1; |
1489 | } | 1497 | } |
1490 | 1498 | ||
@@ -2016,6 +2024,8 @@ int netxen_nic_get_board_info(struct netxen_adapter *adapter) | |||
2016 | case NETXEN_BRDTYPE_P3_10G_CX4_LP: | 2024 | case NETXEN_BRDTYPE_P3_10G_CX4_LP: |
2017 | case NETXEN_BRDTYPE_P3_IMEZ: | 2025 | case NETXEN_BRDTYPE_P3_IMEZ: |
2018 | case NETXEN_BRDTYPE_P3_10G_SFP_PLUS: | 2026 | case NETXEN_BRDTYPE_P3_10G_SFP_PLUS: |
2027 | case NETXEN_BRDTYPE_P3_10G_SFP_CT: | ||
2028 | case NETXEN_BRDTYPE_P3_10G_SFP_QT: | ||
2019 | case NETXEN_BRDTYPE_P3_10G_XFP: | 2029 | case NETXEN_BRDTYPE_P3_10G_XFP: |
2020 | case NETXEN_BRDTYPE_P3_10000_BASE_T: | 2030 | case NETXEN_BRDTYPE_P3_10000_BASE_T: |
2021 | 2031 | ||
@@ -2034,6 +2044,7 @@ int netxen_nic_get_board_info(struct netxen_adapter *adapter) | |||
2034 | default: | 2044 | default: |
2035 | printk("%s: Unknown(%x)\n", netxen_nic_driver_name, | 2045 | printk("%s: Unknown(%x)\n", netxen_nic_driver_name, |
2036 | boardinfo->board_type); | 2046 | boardinfo->board_type); |
2047 | rv = -ENODEV; | ||
2037 | break; | 2048 | break; |
2038 | } | 2049 | } |
2039 | 2050 | ||
@@ -2044,6 +2055,7 @@ int netxen_nic_get_board_info(struct netxen_adapter *adapter) | |||
2044 | 2055 | ||
2045 | int netxen_nic_set_mtu_gb(struct netxen_adapter *adapter, int new_mtu) | 2056 | int netxen_nic_set_mtu_gb(struct netxen_adapter *adapter, int new_mtu) |
2046 | { | 2057 | { |
2058 | new_mtu += MTU_FUDGE_FACTOR; | ||
2047 | netxen_nic_write_w0(adapter, | 2059 | netxen_nic_write_w0(adapter, |
2048 | NETXEN_NIU_GB_MAX_FRAME_SIZE(adapter->physical_port), | 2060 | NETXEN_NIU_GB_MAX_FRAME_SIZE(adapter->physical_port), |
2049 | new_mtu); | 2061 | new_mtu); |
@@ -2052,7 +2064,7 @@ int netxen_nic_set_mtu_gb(struct netxen_adapter *adapter, int new_mtu) | |||
2052 | 2064 | ||
2053 | int netxen_nic_set_mtu_xgb(struct netxen_adapter *adapter, int new_mtu) | 2065 | int netxen_nic_set_mtu_xgb(struct netxen_adapter *adapter, int new_mtu) |
2054 | { | 2066 | { |
2055 | new_mtu += NETXEN_NIU_HDRSIZE + NETXEN_NIU_TLRSIZE; | 2067 | new_mtu += MTU_FUDGE_FACTOR; |
2056 | if (adapter->physical_port == 0) | 2068 | if (adapter->physical_port == 0) |
2057 | netxen_nic_write_w0(adapter, NETXEN_NIU_XGE_MAX_FRAME_SIZE, | 2069 | netxen_nic_write_w0(adapter, NETXEN_NIU_XGE_MAX_FRAME_SIZE, |
2058 | new_mtu); | 2070 | new_mtu); |
@@ -2074,12 +2086,22 @@ void netxen_nic_set_link_parameters(struct netxen_adapter *adapter) | |||
2074 | __u32 status; | 2086 | __u32 status; |
2075 | __u32 autoneg; | 2087 | __u32 autoneg; |
2076 | __u32 mode; | 2088 | __u32 mode; |
2089 | __u32 port_mode; | ||
2077 | 2090 | ||
2078 | netxen_nic_read_w0(adapter, NETXEN_NIU_MODE, &mode); | 2091 | netxen_nic_read_w0(adapter, NETXEN_NIU_MODE, &mode); |
2079 | if (netxen_get_niu_enable_ge(mode)) { /* Gb 10/100/1000 Mbps mode */ | 2092 | if (netxen_get_niu_enable_ge(mode)) { /* Gb 10/100/1000 Mbps mode */ |
2093 | |||
2094 | adapter->hw_read_wx(adapter, | ||
2095 | NETXEN_PORT_MODE_ADDR, &port_mode, 4); | ||
2096 | if (port_mode == NETXEN_PORT_MODE_802_3_AP) { | ||
2097 | adapter->link_speed = SPEED_1000; | ||
2098 | adapter->link_duplex = DUPLEX_FULL; | ||
2099 | adapter->link_autoneg = AUTONEG_DISABLE; | ||
2100 | return; | ||
2101 | } | ||
2102 | |||
2080 | if (adapter->phy_read | 2103 | if (adapter->phy_read |
2081 | && adapter-> | 2104 | && adapter->phy_read(adapter, |
2082 | phy_read(adapter, | ||
2083 | NETXEN_NIU_GB_MII_MGMT_ADDR_PHY_STATUS, | 2105 | NETXEN_NIU_GB_MII_MGMT_ADDR_PHY_STATUS, |
2084 | &status) == 0) { | 2106 | &status) == 0) { |
2085 | if (netxen_get_phy_link(status)) { | 2107 | if (netxen_get_phy_link(status)) { |
@@ -2109,8 +2131,7 @@ void netxen_nic_set_link_parameters(struct netxen_adapter *adapter) | |||
2109 | break; | 2131 | break; |
2110 | } | 2132 | } |
2111 | if (adapter->phy_read | 2133 | if (adapter->phy_read |
2112 | && adapter-> | 2134 | && adapter->phy_read(adapter, |
2113 | phy_read(adapter, | ||
2114 | NETXEN_NIU_GB_MII_MGMT_ADDR_AUTONEG, | 2135 | NETXEN_NIU_GB_MII_MGMT_ADDR_AUTONEG, |
2115 | &autoneg) != 0) | 2136 | &autoneg) != 0) |
2116 | adapter->link_autoneg = autoneg; | 2137 | adapter->link_autoneg = autoneg; |