8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21
22 /*
23 * Copyright 2008 NetXen, Inc. All rights reserved.
24 * Use is subject to license terms.
25 */
26
27 /*
28 * Copyright (c) 2018, Joyent, Inc.
29 */
30
31 #include <sys/types.h>
32 #include <sys/conf.h>
33 #include <sys/debug.h>
34 #include <sys/stropts.h>
35 #include <sys/stream.h>
36 #include <sys/strlog.h>
37 #include <sys/kmem.h>
38 #include <sys/stat.h>
39 #include <sys/kstat.h>
40 #include <sys/vtrace.h>
41 #include <sys/dlpi.h>
42 #include <sys/strsun.h>
43 #include <sys/ethernet.h>
44 #include <sys/modctl.h>
45 #include <sys/errno.h>
46 #include <sys/dditypes.h>
47 #include <sys/ddi.h>
48 #include <sys/sunddi.h>
687
688 *data = temp;
689
690 return (0);
691 }
692
693 /*
694 * write cross hw window boundary is not supported
695 * 'len' should be either 1, 2, 4, or multiple of 8
696 */
697 int
698 unm_nic_hw_write_wx_2M(unm_adapter *adapter, u64 off, void *data, int len)
699 {
700 int rv;
701
702 rv = unm_nic_pci_get_crb_addr_2M(adapter, &off, len);
703
704 if (rv == -1) {
705 cmn_err(CE_PANIC, "%s: invalid offset: 0x%016llx\n",
706 __FUNCTION__, off);
707 return (-1);
708 }
709
710 if (rv == 1) {
711 UNM_WRITE_LOCK_IRQS(&adapter->adapter_lock, flags);
712 crb_win_lock(adapter);
713 unm_nic_pci_set_crbwindow_2M(adapter, &off);
714 }
715
716 switch (len) {
717 case 1:
718 UNM_NIC_PCI_WRITE_8(*(__uint8_t *)data, (void *) (uptr_t)off);
719 break;
720 case 2:
721 UNM_NIC_PCI_WRITE_16(*(__uint16_t *)data, (void *) (uptr_t)off);
722 break;
723 case 4:
724 UNM_NIC_PCI_WRITE_32(*(__uint32_t *)data, (void *) (uptr_t)off);
725 break;
726 case 8:
727 UNM_NIC_PCI_WRITE_64(*(__uint64_t *)data, (void *) (uptr_t)off);
796 if (ADDR_IN_WINDOW1(off)) {// Window 1
797 UNM_READ_UNLOCK(&adapter->adapter_lock);
798 } else {// Window 0
799 unm_nic_pci_change_crbwindow_128M(adapter, 1);
800 UNM_WRITE_UNLOCK_IRQR(&adapter->adapter_lock, flags);
801 }
802
803 return (0);
804 }
805
806 int
807 unm_nic_hw_read_wx_2M(unm_adapter *adapter, u64 off, void *data, int len)
808 {
809 int rv;
810
811 rv = unm_nic_pci_get_crb_addr_2M(adapter, &off, len);
812
813 if (rv == -1) {
814 cmn_err(CE_PANIC, "%s: invalid offset: 0x%016llx\n",
815 __FUNCTION__, off);
816 return (-1);
817 }
818
819 if (rv == 1) {
820 UNM_WRITE_LOCK_IRQS(&adapter->adapter_lock, flags);
821 crb_win_lock(adapter);
822 unm_nic_pci_set_crbwindow_2M(adapter, &off);
823 }
824
825 switch (len) {
826 case 1:
827 *(__uint8_t *)data = UNM_NIC_PCI_READ_8((void *) (uptr_t)off);
828 break;
829 case 2:
830 *(__uint16_t *)data = UNM_NIC_PCI_READ_16((void *) (uptr_t)off);
831 break;
832 case 4:
833 *(__uint32_t *)data = UNM_NIC_PCI_READ_32((void *) (uptr_t)off);
834 break;
835 case 8:
836 *(__uint64_t *)data = UNM_NIC_PCI_READ_64((void *) (uptr_t)off);
936
937 int unm_pci_set_window_warning_count = 0;
938
939 unsigned long long
940 unm_nic_pci_set_window_128M(struct unm_adapter_s *adapter,
941 unsigned long long addr)
942 {
943 int window;
944 unsigned long long qdr_max;
945
946 if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) {
947 qdr_max = NX_P2_ADDR_QDR_NET_MAX;
948 } else {
949 qdr_max = NX_P3_ADDR_QDR_NET_MAX;
950 }
951
952 if (ADDR_IN_RANGE(addr, UNM_ADDR_DDR_NET, UNM_ADDR_DDR_NET_MAX)) {
953 /* DDR network side */
954 /* MN access should never come here */
955 cmn_err(CE_PANIC, "%s\n", __FUNCTION__);
956 addr = -1ULL;
957 } else if (ADDR_IN_RANGE(addr, UNM_ADDR_OCM0, UNM_ADDR_OCM0_MAX)) {
958 addr -= UNM_ADDR_OCM0;
959 addr += UNM_PCI_OCM0;
960 } else if (ADDR_IN_RANGE(addr, UNM_ADDR_OCM1, UNM_ADDR_OCM1_MAX)) {
961 addr -= UNM_ADDR_OCM1;
962 addr += UNM_PCI_OCM1;
963 } else if (ADDR_IN_RANGE(addr, UNM_ADDR_QDR_NET, qdr_max)) {
964 /* QDR network side */
965 addr -= UNM_ADDR_QDR_NET;
966 window = (addr >> 22) & 0x3f;
967 if (adapter->ahw.qdr_sn_window != window) {
968 adapter->ahw.qdr_sn_window = window;
969 UNM_NIC_PCI_WRITE_32((window << 22),
970 (void *) (uptr_t)(PCI_OFFSET_SECOND_RANGE(adapter,
971 UNM_PCIX_PH_REG(PCIE_SN_WINDOW_REG(
972 adapter->ahw.pci_func)))));
973 /* MUST make sure window is set before we forge on... */
974 (void) UNM_NIC_PCI_READ_32((void *)
975 (uptr_t)(PCI_OFFSET_SECOND_RANGE(adapter,
976 UNM_PCIX_PH_REG(PCIE_SN_WINDOW_REG(
|
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21
22 /*
23 * Copyright 2008 NetXen, Inc. All rights reserved.
24 * Use is subject to license terms.
25 */
26
27 /*
28 * Copyright 2019 Joyent, Inc.
29 */
30
31 #include <sys/types.h>
32 #include <sys/conf.h>
33 #include <sys/debug.h>
34 #include <sys/stropts.h>
35 #include <sys/stream.h>
36 #include <sys/strlog.h>
37 #include <sys/kmem.h>
38 #include <sys/stat.h>
39 #include <sys/kstat.h>
40 #include <sys/vtrace.h>
41 #include <sys/dlpi.h>
42 #include <sys/strsun.h>
43 #include <sys/ethernet.h>
44 #include <sys/modctl.h>
45 #include <sys/errno.h>
46 #include <sys/dditypes.h>
47 #include <sys/ddi.h>
48 #include <sys/sunddi.h>
687
688 *data = temp;
689
690 return (0);
691 }
692
693 /*
694 * write cross hw window boundary is not supported
695 * 'len' should be either 1, 2, 4, or multiple of 8
696 */
697 int
698 unm_nic_hw_write_wx_2M(unm_adapter *adapter, u64 off, void *data, int len)
699 {
700 int rv;
701
702 rv = unm_nic_pci_get_crb_addr_2M(adapter, &off, len);
703
704 if (rv == -1) {
705 cmn_err(CE_PANIC, "%s: invalid offset: 0x%016llx\n",
706 __FUNCTION__, off);
707 }
708
709 if (rv == 1) {
710 UNM_WRITE_LOCK_IRQS(&adapter->adapter_lock, flags);
711 crb_win_lock(adapter);
712 unm_nic_pci_set_crbwindow_2M(adapter, &off);
713 }
714
715 switch (len) {
716 case 1:
717 UNM_NIC_PCI_WRITE_8(*(__uint8_t *)data, (void *) (uptr_t)off);
718 break;
719 case 2:
720 UNM_NIC_PCI_WRITE_16(*(__uint16_t *)data, (void *) (uptr_t)off);
721 break;
722 case 4:
723 UNM_NIC_PCI_WRITE_32(*(__uint32_t *)data, (void *) (uptr_t)off);
724 break;
725 case 8:
726 UNM_NIC_PCI_WRITE_64(*(__uint64_t *)data, (void *) (uptr_t)off);
795 if (ADDR_IN_WINDOW1(off)) {// Window 1
796 UNM_READ_UNLOCK(&adapter->adapter_lock);
797 } else {// Window 0
798 unm_nic_pci_change_crbwindow_128M(adapter, 1);
799 UNM_WRITE_UNLOCK_IRQR(&adapter->adapter_lock, flags);
800 }
801
802 return (0);
803 }
804
805 int
806 unm_nic_hw_read_wx_2M(unm_adapter *adapter, u64 off, void *data, int len)
807 {
808 int rv;
809
810 rv = unm_nic_pci_get_crb_addr_2M(adapter, &off, len);
811
812 if (rv == -1) {
813 cmn_err(CE_PANIC, "%s: invalid offset: 0x%016llx\n",
814 __FUNCTION__, off);
815 }
816
817 if (rv == 1) {
818 UNM_WRITE_LOCK_IRQS(&adapter->adapter_lock, flags);
819 crb_win_lock(adapter);
820 unm_nic_pci_set_crbwindow_2M(adapter, &off);
821 }
822
823 switch (len) {
824 case 1:
825 *(__uint8_t *)data = UNM_NIC_PCI_READ_8((void *) (uptr_t)off);
826 break;
827 case 2:
828 *(__uint16_t *)data = UNM_NIC_PCI_READ_16((void *) (uptr_t)off);
829 break;
830 case 4:
831 *(__uint32_t *)data = UNM_NIC_PCI_READ_32((void *) (uptr_t)off);
832 break;
833 case 8:
834 *(__uint64_t *)data = UNM_NIC_PCI_READ_64((void *) (uptr_t)off);
934
935 int unm_pci_set_window_warning_count = 0;
936
937 unsigned long long
938 unm_nic_pci_set_window_128M(struct unm_adapter_s *adapter,
939 unsigned long long addr)
940 {
941 int window;
942 unsigned long long qdr_max;
943
944 if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) {
945 qdr_max = NX_P2_ADDR_QDR_NET_MAX;
946 } else {
947 qdr_max = NX_P3_ADDR_QDR_NET_MAX;
948 }
949
950 if (ADDR_IN_RANGE(addr, UNM_ADDR_DDR_NET, UNM_ADDR_DDR_NET_MAX)) {
951 /* DDR network side */
952 /* MN access should never come here */
953 cmn_err(CE_PANIC, "%s\n", __FUNCTION__);
954 } else if (ADDR_IN_RANGE(addr, UNM_ADDR_OCM0, UNM_ADDR_OCM0_MAX)) {
955 addr -= UNM_ADDR_OCM0;
956 addr += UNM_PCI_OCM0;
957 } else if (ADDR_IN_RANGE(addr, UNM_ADDR_OCM1, UNM_ADDR_OCM1_MAX)) {
958 addr -= UNM_ADDR_OCM1;
959 addr += UNM_PCI_OCM1;
960 } else if (ADDR_IN_RANGE(addr, UNM_ADDR_QDR_NET, qdr_max)) {
961 /* QDR network side */
962 addr -= UNM_ADDR_QDR_NET;
963 window = (addr >> 22) & 0x3f;
964 if (adapter->ahw.qdr_sn_window != window) {
965 adapter->ahw.qdr_sn_window = window;
966 UNM_NIC_PCI_WRITE_32((window << 22),
967 (void *) (uptr_t)(PCI_OFFSET_SECOND_RANGE(adapter,
968 UNM_PCIX_PH_REG(PCIE_SN_WINDOW_REG(
969 adapter->ahw.pci_func)))));
970 /* MUST make sure window is set before we forge on... */
971 (void) UNM_NIC_PCI_READ_32((void *)
972 (uptr_t)(PCI_OFFSET_SECOND_RANGE(adapter,
973 UNM_PCIX_PH_REG(PCIE_SN_WINDOW_REG(
|