]> pilppa.org Git - linux-2.6-omap-h63xx.git/blob - drivers/net/netxen/netxen_nic_isr.c
[PATCH] NetXen: whitespace cleaup and more cleanup fixes
[linux-2.6-omap-h63xx.git] / drivers / net / netxen / netxen_nic_isr.c
1 /*
2  * Copyright (C) 2003 - 2006 NetXen, Inc.
3  * All rights reserved.
4  *
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.
9  *                            
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.
14  *                                   
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.
19  *
20  * The full GNU General Public License is included in this distribution
21  * in the file called LICENSE.
22  *
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 {
43         struct netxen_port *port = netdev_priv(netdev);
44         struct net_device_stats *stats = &port->net_stats;
45
46         memset(stats, 0, sizeof(*stats));
47
48         /* total packets received   */
49         stats->rx_packets = port->stats.no_rcv;
50         /* total packets transmitted    */
51         stats->tx_packets = port->stats.xmitedframes + port->stats.xmitfinished;
52         /* total bytes received     */
53         stats->rx_bytes = port->stats.rxbytes;
54         /* total bytes transmitted  */
55         stats->tx_bytes = port->stats.txbytes;
56         /* bad packets received     */
57         stats->rx_errors = port->stats.rcvdbadskb;
58         /* packet transmit problems */
59         stats->tx_errors = port->stats.nocmddescriptor;
60         /* no space in linux buffers    */
61         stats->rx_dropped = port->stats.updropped;
62         /* no space available in linux  */
63         stats->tx_dropped = port->stats.txdropped;
64
65         return stats;
66 }
67
68 void netxen_indicate_link_status(struct netxen_adapter *adapter, u32 portno,
69                                  u32 link)
70 {
71         struct netxen_port *pport = adapter->port[portno];
72         struct net_device *netdev = pport->netdev;
73
74         if (link)
75                 netif_carrier_on(netdev);
76         else
77                 netif_carrier_off(netdev);
78 }
79
80 void netxen_handle_port_int(struct netxen_adapter *adapter, u32 portno,
81                             u32 enable)
82 {
83         __le32 int_src;
84         struct netxen_port *port;
85
86         /*  This should clear the interrupt source */
87         if (adapter->phy_read)
88                 adapter->phy_read(adapter, portno,
89                                   NETXEN_NIU_GB_MII_MGMT_ADDR_INT_STATUS,
90                                   &int_src);
91         if (int_src == 0) {
92                 DPRINTK(INFO, "No phy interrupts for port #%d\n", portno);
93                 return;
94         }
95         if (adapter->disable_phy_interrupts)
96                 adapter->disable_phy_interrupts(adapter, portno);
97
98         port = adapter->port[portno];
99
100         if (netxen_get_phy_int_jabber(int_src))
101                 DPRINTK(INFO, "Jabber interrupt \n");
102
103         if (netxen_get_phy_int_polarity_changed(int_src))
104                 DPRINTK(INFO, "POLARITY CHANGED int \n");
105
106         if (netxen_get_phy_int_energy_detect(int_src))
107                 DPRINTK(INFO, "ENERGY DETECT INT \n");
108
109         if (netxen_get_phy_int_downshift(int_src))
110                 DPRINTK(INFO, "DOWNSHIFT INT \n");
111         /* write it down later.. */
112         if ((netxen_get_phy_int_speed_changed(int_src))
113             || (netxen_get_phy_int_link_status_changed(int_src))) {
114                 __le32 status;
115
116                 DPRINTK(INFO, "SPEED CHANGED OR LINK STATUS CHANGED \n");
117
118                 if (adapter->phy_read
119                     && adapter->phy_read(adapter, portno,
120                                          NETXEN_NIU_GB_MII_MGMT_ADDR_PHY_STATUS,
121                                          &status) == 0) {
122                         if (netxen_get_phy_int_link_status_changed(int_src)) {
123                                 if (netxen_get_phy_link(status)) {
124                                         netxen_niu_gbe_init_port(adapter,
125                                                                  portno);
126                                         printk("%s: %s Link UP\n",
127                                                netxen_nic_driver_name,
128                                                port->netdev->name);
129
130                                 } else {
131                                         printk("%s: %s Link DOWN\n",
132                                                netxen_nic_driver_name,
133                                                port->netdev->name);
134                                 }
135                                 netxen_indicate_link_status(adapter, portno,
136                                                             netxen_get_phy_link
137                                                             (status));
138                         }
139                 }
140         }
141         if (adapter->enable_phy_interrupts)
142                 adapter->enable_phy_interrupts(adapter, portno);
143 }
144
145 void netxen_nic_isr_other(struct netxen_adapter *adapter)
146 {
147         u32 portno;
148         u32 val, linkup, qg_linksup;
149
150         /* verify the offset */
151         val = readl(NETXEN_CRB_NORMALIZE(adapter, CRB_XG_STATE));
152         if (val == adapter->ahw.qg_linksup)
153                 return;
154
155         qg_linksup = adapter->ahw.qg_linksup;
156         adapter->ahw.qg_linksup = val;
157         DPRINTK(INFO, "link update 0x%08x\n", val);
158         for (portno = 0; portno < NETXEN_NIU_MAX_GBE_PORTS; portno++) {
159                 linkup = val & 1;
160                 if (linkup != (qg_linksup & 1)) {
161                         printk(KERN_INFO "%s: PORT %d link %s\n",
162                                netxen_nic_driver_name, portno,
163                                ((linkup == 0) ? "down" : "up"));
164                         netxen_indicate_link_status(adapter, portno, linkup);
165                         if (linkup)
166                                 netxen_nic_set_link_parameters(adapter->
167                                                                port[portno]);
168
169                 }
170                 val = val >> 1;
171                 qg_linksup = qg_linksup >> 1;
172         }
173
174         adapter->stats.otherints++;
175
176 }
177
178 void netxen_nic_gbe_handle_phy_intr(struct netxen_adapter *adapter)
179 {
180         netxen_nic_isr_other(adapter);
181 }
182
183 void netxen_nic_xgbe_handle_phy_intr(struct netxen_adapter *adapter)
184 {
185         struct net_device *netdev = adapter->port[0]->netdev;
186         u32 val;
187
188         /* WINDOW = 1 */
189         val = readl(NETXEN_CRB_NORMALIZE(adapter, CRB_XG_STATE));
190
191         if (adapter->ahw.xg_linkup == 1 && val != XG_LINK_UP) {
192                 printk(KERN_INFO "%s: %s NIC Link is down\n",
193                        netxen_nic_driver_name, netdev->name);
194                 adapter->ahw.xg_linkup = 0;
195                 /* read twice to clear sticky bits */
196                 /* WINDOW = 0 */
197                 netxen_nic_read_w0(adapter, NETXEN_NIU_XG_STATUS, &val);
198                 netxen_nic_read_w0(adapter, NETXEN_NIU_XG_STATUS, &val);
199
200                 if ((val & 0xffb) != 0xffb) {
201                         printk(KERN_INFO "%s ISR: Sync/Align BAD: 0x%08x\n",
202                                netxen_nic_driver_name, val);
203                 }
204         } else if (adapter->ahw.xg_linkup == 0 && val == XG_LINK_UP) {
205                 printk(KERN_INFO "%s: %s NIC Link is up\n",
206                        netxen_nic_driver_name, netdev->name);
207                 adapter->ahw.xg_linkup = 1;
208         }
209 }