]>
Commit | Line | Data |
---|---|---|
3d396eb1 AK |
1 | /* |
2 | * Copyright (C) 2003 - 2006 NetXen, Inc. | |
3 | * All rights reserved. | |
80922fbc | 4 | * |
3d396eb1 AK |
5 | * This program is free software; you can redistribute it and/or |
6 | * modify it under the terms of the GNU General Public License | |
7 | * as published by the Free Software Foundation; either version 2 | |
8 | * of the License, or (at your option) any later version. | |
3176ff3e | 9 | * |
3d396eb1 AK |
10 | * This program is distributed in the hope that it will be useful, but |
11 | * WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
13 | * GNU General Public License for more details. | |
3176ff3e | 14 | * |
3d396eb1 AK |
15 | * You should have received a copy of the GNU General Public License |
16 | * along with this program; if not, write to the Free Software | |
17 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, | |
18 | * MA 02111-1307, USA. | |
80922fbc | 19 | * |
3d396eb1 AK |
20 | * The full GNU General Public License is included in this distribution |
21 | * in the file called LICENSE. | |
80922fbc | 22 | * |
3d396eb1 AK |
23 | * Contact Information: |
24 | * info@netxen.com | |
25 | * NetXen, | |
26 | * 3965 Freedom Circle, Fourth floor, | |
27 | * Santa Clara, CA 95054 | |
28 | */ | |
29 | ||
30 | #include <linux/netdevice.h> | |
31 | #include <linux/delay.h> | |
32 | ||
33 | #include "netxen_nic.h" | |
34 | #include "netxen_nic_hw.h" | |
35 | #include "netxen_nic_phan_reg.h" | |
36 | ||
37 | /* | |
38 | * netxen_nic_get_stats - Get System Network Statistics | |
39 | * @netdev: network interface device structure | |
40 | */ | |
41 | struct net_device_stats *netxen_nic_get_stats(struct net_device *netdev) | |
42 | { | |
6c80b18d | 43 | struct netxen_adapter *adapter = netdev_priv(netdev); |
3176ff3e | 44 | struct net_device_stats *stats = &adapter->net_stats; |
3d396eb1 AK |
45 | |
46 | memset(stats, 0, sizeof(*stats)); | |
47 | ||
48 | /* total packets received */ | |
6c80b18d | 49 | stats->rx_packets = adapter->stats.no_rcv; |
3d396eb1 | 50 | /* total packets transmitted */ |
4790654c | 51 | stats->tx_packets = adapter->stats.xmitedframes + |
6c80b18d | 52 | adapter->stats.xmitfinished; |
3d396eb1 | 53 | /* total bytes received */ |
6c80b18d | 54 | stats->rx_bytes = adapter->stats.rxbytes; |
3d396eb1 | 55 | /* total bytes transmitted */ |
6c80b18d | 56 | stats->tx_bytes = adapter->stats.txbytes; |
3d396eb1 | 57 | /* bad packets received */ |
6c80b18d | 58 | stats->rx_errors = adapter->stats.rcvdbadskb; |
3d396eb1 | 59 | /* packet transmit problems */ |
6c80b18d | 60 | stats->tx_errors = adapter->stats.nocmddescriptor; |
3d396eb1 | 61 | /* no space in linux buffers */ |
d1847a72 | 62 | stats->rx_dropped = adapter->stats.rxdropped; |
3d396eb1 | 63 | /* no space available in linux */ |
6c80b18d | 64 | stats->tx_dropped = adapter->stats.txdropped; |
3d396eb1 AK |
65 | |
66 | return stats; | |
67 | } | |
6c80b18d | 68 | |
993fb90c AB |
69 | static void netxen_indicate_link_status(struct netxen_adapter *adapter, |
70 | u32 link) | |
3d396eb1 | 71 | { |
3176ff3e | 72 | struct net_device *netdev = adapter->netdev; |
3d396eb1 AK |
73 | |
74 | if (link) | |
75 | netif_carrier_on(netdev); | |
76 | else | |
77 | netif_carrier_off(netdev); | |
78 | } | |
79 | ||
993fb90c | 80 | #if 0 |
3176ff3e | 81 | void netxen_handle_port_int(struct netxen_adapter *adapter, u32 enable) |
3d396eb1 | 82 | { |
a608ab9c | 83 | __u32 int_src; |
3d396eb1 AK |
84 | |
85 | /* This should clear the interrupt source */ | |
80922fbc | 86 | if (adapter->phy_read) |
4790654c | 87 | adapter->phy_read(adapter, |
80922fbc AK |
88 | NETXEN_NIU_GB_MII_MGMT_ADDR_INT_STATUS, |
89 | &int_src); | |
3d396eb1 AK |
90 | if (int_src == 0) { |
91 | DPRINTK(INFO, "No phy interrupts for port #%d\n", portno); | |
92 | return; | |
93 | } | |
80922fbc | 94 | if (adapter->disable_phy_interrupts) |
13ba9c77 | 95 | adapter->disable_phy_interrupts(adapter); |
3d396eb1 AK |
96 | |
97 | if (netxen_get_phy_int_jabber(int_src)) | |
80922fbc | 98 | DPRINTK(INFO, "Jabber interrupt \n"); |
3d396eb1 AK |
99 | |
100 | if (netxen_get_phy_int_polarity_changed(int_src)) | |
80922fbc | 101 | DPRINTK(INFO, "POLARITY CHANGED int \n"); |
3d396eb1 AK |
102 | |
103 | if (netxen_get_phy_int_energy_detect(int_src)) | |
80922fbc | 104 | DPRINTK(INFO, "ENERGY DETECT INT \n"); |
3d396eb1 AK |
105 | |
106 | if (netxen_get_phy_int_downshift(int_src)) | |
80922fbc | 107 | DPRINTK(INFO, "DOWNSHIFT INT \n"); |
3d396eb1 AK |
108 | /* write it down later.. */ |
109 | if ((netxen_get_phy_int_speed_changed(int_src)) | |
110 | || (netxen_get_phy_int_link_status_changed(int_src))) { | |
a608ab9c | 111 | __u32 status; |
3d396eb1 | 112 | |
80922fbc | 113 | DPRINTK(INFO, "SPEED CHANGED OR LINK STATUS CHANGED \n"); |
3d396eb1 | 114 | |
80922fbc | 115 | if (adapter->phy_read |
4790654c | 116 | && adapter->phy_read(adapter, |
80922fbc AK |
117 | NETXEN_NIU_GB_MII_MGMT_ADDR_PHY_STATUS, |
118 | &status) == 0) { | |
3d396eb1 AK |
119 | if (netxen_get_phy_int_link_status_changed(int_src)) { |
120 | if (netxen_get_phy_link(status)) { | |
3176ff3e | 121 | printk(KERN_INFO "%s: %s Link UP\n", |
3d396eb1 | 122 | netxen_nic_driver_name, |
3176ff3e | 123 | adapter->netdev->name); |
3d396eb1 AK |
124 | |
125 | } else { | |
3176ff3e | 126 | printk(KERN_INFO "%s: %s Link DOWN\n", |
3d396eb1 | 127 | netxen_nic_driver_name, |
3176ff3e | 128 | adapter->netdev->name); |
3d396eb1 | 129 | } |
4790654c | 130 | netxen_indicate_link_status(adapter, |
3d396eb1 AK |
131 | netxen_get_phy_link |
132 | (status)); | |
133 | } | |
134 | } | |
135 | } | |
80922fbc | 136 | if (adapter->enable_phy_interrupts) |
13ba9c77 | 137 | adapter->enable_phy_interrupts(adapter); |
3d396eb1 | 138 | } |
993fb90c | 139 | #endif /* 0 */ |
3d396eb1 | 140 | |
993fb90c | 141 | static void netxen_nic_isr_other(struct netxen_adapter *adapter) |
3d396eb1 | 142 | { |
3176ff3e | 143 | int portno = adapter->portnum; |
cb8011ad | 144 | u32 val, linkup, qg_linksup; |
3d396eb1 AK |
145 | |
146 | /* verify the offset */ | |
3ce06a32 | 147 | val = adapter->pci_read_normalize(adapter, CRB_XG_STATE); |
3276fbad | 148 | val = val >> adapter->physical_port; |
cb8011ad AK |
149 | if (val == adapter->ahw.qg_linksup) |
150 | return; | |
3d396eb1 | 151 | |
cb8011ad AK |
152 | qg_linksup = adapter->ahw.qg_linksup; |
153 | adapter->ahw.qg_linksup = val; | |
80922fbc | 154 | DPRINTK(INFO, "link update 0x%08x\n", val); |
3d396eb1 | 155 | |
3176ff3e | 156 | linkup = val & 1; |
3d396eb1 | 157 | |
3176ff3e MT |
158 | if (linkup != (qg_linksup & 1)) { |
159 | printk(KERN_INFO "%s: %s PORT %d link %s\n", | |
160 | adapter->netdev->name, | |
161 | netxen_nic_driver_name, portno, | |
162 | ((linkup == 0) ? "down" : "up")); | |
163 | netxen_indicate_link_status(adapter, linkup); | |
164 | if (linkup) | |
165 | netxen_nic_set_link_parameters(adapter); | |
3d396eb1 | 166 | |
3176ff3e | 167 | } |
3d396eb1 AK |
168 | } |
169 | ||
170 | void netxen_nic_gbe_handle_phy_intr(struct netxen_adapter *adapter) | |
171 | { | |
cb8011ad | 172 | netxen_nic_isr_other(adapter); |
3d396eb1 AK |
173 | } |
174 | ||
aa394323 | 175 | #if 0 |
c27e6721 MT |
176 | int netxen_nic_link_ok(struct netxen_adapter *adapter) |
177 | { | |
178 | switch (adapter->ahw.board_type) { | |
179 | case NETXEN_NIC_GBE: | |
180 | return ((adapter->ahw.qg_linksup) & 1); | |
181 | ||
182 | case NETXEN_NIC_XGBE: | |
183 | return ((adapter->ahw.xg_linkup) & 1); | |
184 | ||
185 | default: | |
186 | printk(KERN_ERR"%s: Function: %s, Unknown board type\n", | |
187 | netxen_nic_driver_name, __FUNCTION__); | |
188 | break; | |
189 | } | |
190 | ||
191 | return 0; | |
192 | } | |
aa394323 | 193 | #endif /* 0 */ |
c27e6721 | 194 | |
3d396eb1 AK |
195 | void netxen_nic_xgbe_handle_phy_intr(struct netxen_adapter *adapter) |
196 | { | |
3176ff3e | 197 | struct net_device *netdev = adapter->netdev; |
05aaa02d | 198 | u32 val; |
3d396eb1 AK |
199 | |
200 | /* WINDOW = 1 */ | |
3ce06a32 | 201 | val = adapter->pci_read_normalize(adapter, CRB_XG_STATE); |
3276fbad | 202 | val >>= (adapter->physical_port * 8); |
05aaa02d | 203 | val &= 0xff; |
3d396eb1 | 204 | |
05aaa02d | 205 | if (adapter->ahw.xg_linkup == 1 && val != XG_LINK_UP) { |
3d396eb1 AK |
206 | printk(KERN_INFO "%s: %s NIC Link is down\n", |
207 | netxen_nic_driver_name, netdev->name); | |
208 | adapter->ahw.xg_linkup = 0; | |
c27e6721 MT |
209 | if (netif_running(netdev)) { |
210 | netif_carrier_off(netdev); | |
211 | netif_stop_queue(netdev); | |
212 | } | |
05aaa02d | 213 | } else if (adapter->ahw.xg_linkup == 0 && val == XG_LINK_UP) { |
3d396eb1 AK |
214 | printk(KERN_INFO "%s: %s NIC Link is up\n", |
215 | netxen_nic_driver_name, netdev->name); | |
216 | adapter->ahw.xg_linkup = 1; | |
c27e6721 MT |
217 | netif_carrier_on(netdev); |
218 | netif_wake_queue(netdev); | |
3d396eb1 AK |
219 | } |
220 | } |