1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
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  * Copyright 2008 NetXen, Inc.  All rights reserved.
23  * Use is subject to license terms.
24  */
25 #include <sys/types.h>
26 #include <sys/conf.h>
27 #include <sys/debug.h>
28 #include <sys/stropts.h>
29 #include <sys/stream.h>
30 #include <sys/strlog.h>
31 #include <sys/kmem.h>
32 #include <sys/stat.h>
33 #include <sys/kstat.h>
34 #include <sys/vtrace.h>
35 #include <sys/dlpi.h>
36 #include <sys/strsun.h>
37 #include <sys/ethernet.h>
38 #include <sys/modctl.h>
39 #include <sys/errno.h>
40 #include <sys/dditypes.h>
41 #include <sys/ddi.h>
42 #include <sys/sunddi.h>
43 #include <sys/sysmacros.h>
44 
45 #include <sys/pci.h>
46 
47 #include "unm_nic.h"
48 #include "unm_nic_hw.h"
49 #include "nic_cmn.h"
50 #include "nic_phan_reg.h"
51 
52 static void
53 unm_nic_isr_other(struct unm_adapter_s *adapter)
54 {
55 	u32 portno = adapter->portnum;
56 	u32 val, linkup, qg_linksup = adapter->ahw.linkup;
57 
58 	UNM_READ_LOCK(&adapter->adapter_lock);
59 	adapter->unm_nic_hw_read_wx(adapter, CRB_XG_STATE, &val, 4);
60 	UNM_READ_UNLOCK(&adapter->adapter_lock);
61 
62 	linkup = 1 & (val >> adapter->physical_port);
63 	adapter->ahw.linkup = linkup;
64 
65 	if (linkup != qg_linksup) {
66 		cmn_err(CE_WARN, "%s: PORT %d link %s\n", unm_nic_driver_name,
67 		    portno, ((linkup == 0) ? "down" : "up"));
68 		mac_link_update(adapter->mach, linkup);
69 		if (linkup)
70 			unm_nic_set_link_parameters(adapter);
71 	}
72 }
73 
74 void
75 unm_nic_handle_phy_intr(struct unm_adapter_s *adapter)
76 {
77 	uint32_t	val, val1, linkupval;
78 
79 	switch (adapter->ahw.board_type) {
80 		case UNM_NIC_GBE:
81 			if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) {
82 				unm_nic_isr_other(adapter);
83 				break;
84 			}
85 		/* FALLTHROUGH */
86 
87 		case UNM_NIC_XGBE:
88 			/* WINDOW = 1 */
89 		UNM_READ_LOCK(&adapter->adapter_lock);
90 		if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) {
91 			adapter->unm_nic_hw_read_wx(adapter, CRB_XG_STATE_P3,
92 			    &val, 4);
93 			val1 = XG_LINK_STATE_P3(adapter->ahw.pci_func, val);
94 			linkupval = XG_LINK_UP_P3;
95 		} else {
96 			adapter->unm_nic_hw_read_wx(adapter, CRB_XG_STATE,
97 			    &val, 4);
98 			val >>= (adapter->portnum * 8);
99 			val1 = val & 0xff;
100 			linkupval = XG_LINK_UP;
101 		}
102 		UNM_READ_UNLOCK(&adapter->adapter_lock);
103 
104 		if (adapter->ahw.linkup && (val1 != linkupval)) {
105 			if (verbmsg != 0)
106 				cmn_err(CE_NOTE, "%s%d: NIC Link is down\n",
107 				    adapter->name, adapter->portnum);
108 			mac_link_update(adapter->mach, LINK_STATE_DOWN);
109 			adapter->ahw.linkup = 0;
110 		} else if ((adapter->ahw.linkup == 0) && (val1 == linkupval)) {
111 			if (verbmsg != 0)
112 				cmn_err(CE_NOTE, "%s%d: NIC Link is up\n",
113 				    adapter->name, adapter->portnum);
114 			mac_link_update(adapter->mach, LINK_STATE_UP);
115 			adapter->ahw.linkup = 1;
116 
117 			if (adapter->ahw.board_type == UNM_NIC_GBE)
118 				unm_nic_set_link_parameters(adapter);
119 		}
120 
121 		break;
122 
123 		default:
124 		DPRINTF(0, (CE_WARN, "%s%d ISR: Unknown board type\n",
125 		    unm_nic_driver_name, adapter->portnum));
126 	}
127 }
128