netxen: fix off by one bug in netxen_release_tx_buffer()
[pandora-kernel.git] / drivers / net / ethernet / qlogic / netxen / netxen_nic_ethtool.c
1 /*
2  * Copyright (C) 2003 - 2009 NetXen, Inc.
3  * Copyright (C) 2009 - QLogic Corporation.
4  * All rights reserved.
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful, but
12  * WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place - Suite 330, Boston,
19  * MA  02111-1307, USA.
20  *
21  * The full GNU General Public License is included in this distribution
22  * in the file called "COPYING".
23  *
24  */
25
26 #include <linux/types.h>
27 #include <linux/delay.h>
28 #include <linux/pci.h>
29 #include <asm/io.h>
30 #include <linux/netdevice.h>
31 #include <linux/ethtool.h>
32
33 #include "netxen_nic.h"
34 #include "netxen_nic_hw.h"
35
36 struct netxen_nic_stats {
37         char stat_string[ETH_GSTRING_LEN];
38         int sizeof_stat;
39         int stat_offset;
40 };
41
42 #define NETXEN_NIC_STAT(m) sizeof(((struct netxen_adapter *)0)->m), \
43                         offsetof(struct netxen_adapter, m)
44
45 #define NETXEN_NIC_PORT_WINDOW 0x10000
46 #define NETXEN_NIC_INVALID_DATA 0xDEADBEEF
47
48 static const struct netxen_nic_stats netxen_nic_gstrings_stats[] = {
49         {"xmit_called", NETXEN_NIC_STAT(stats.xmitcalled)},
50         {"xmit_finished", NETXEN_NIC_STAT(stats.xmitfinished)},
51         {"rx_dropped", NETXEN_NIC_STAT(stats.rxdropped)},
52         {"tx_dropped", NETXEN_NIC_STAT(stats.txdropped)},
53         {"csummed", NETXEN_NIC_STAT(stats.csummed)},
54         {"rx_pkts", NETXEN_NIC_STAT(stats.rx_pkts)},
55         {"lro_pkts", NETXEN_NIC_STAT(stats.lro_pkts)},
56         {"rx_bytes", NETXEN_NIC_STAT(stats.rxbytes)},
57         {"tx_bytes", NETXEN_NIC_STAT(stats.txbytes)},
58 };
59
60 #define NETXEN_NIC_STATS_LEN    ARRAY_SIZE(netxen_nic_gstrings_stats)
61
62 static const char netxen_nic_gstrings_test[][ETH_GSTRING_LEN] = {
63         "Register_Test_on_offline",
64         "Link_Test_on_offline"
65 };
66
67 #define NETXEN_NIC_TEST_LEN     ARRAY_SIZE(netxen_nic_gstrings_test)
68
69 #define NETXEN_NIC_REGS_COUNT 30
70 #define NETXEN_NIC_REGS_LEN (NETXEN_NIC_REGS_COUNT * sizeof(__le32))
71 #define NETXEN_MAX_EEPROM_LEN   1024
72
73 static int netxen_nic_get_eeprom_len(struct net_device *dev)
74 {
75         return NETXEN_FLASH_TOTAL_SIZE;
76 }
77
78 static void
79 netxen_nic_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *drvinfo)
80 {
81         struct netxen_adapter *adapter = netdev_priv(dev);
82         u32 fw_major = 0;
83         u32 fw_minor = 0;
84         u32 fw_build = 0;
85
86         strncpy(drvinfo->driver, netxen_nic_driver_name, 32);
87         strncpy(drvinfo->version, NETXEN_NIC_LINUX_VERSIONID, 32);
88         fw_major = NXRD32(adapter, NETXEN_FW_VERSION_MAJOR);
89         fw_minor = NXRD32(adapter, NETXEN_FW_VERSION_MINOR);
90         fw_build = NXRD32(adapter, NETXEN_FW_VERSION_SUB);
91         sprintf(drvinfo->fw_version, "%d.%d.%d", fw_major, fw_minor, fw_build);
92
93         strncpy(drvinfo->bus_info, pci_name(adapter->pdev), 32);
94         drvinfo->regdump_len = NETXEN_NIC_REGS_LEN;
95         drvinfo->eedump_len = netxen_nic_get_eeprom_len(dev);
96 }
97
98 static int
99 netxen_nic_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
100 {
101         struct netxen_adapter *adapter = netdev_priv(dev);
102         int check_sfp_module = 0;
103
104         /* read which mode */
105         if (adapter->ahw.port_type == NETXEN_NIC_GBE) {
106                 ecmd->supported = (SUPPORTED_10baseT_Half |
107                                    SUPPORTED_10baseT_Full |
108                                    SUPPORTED_100baseT_Half |
109                                    SUPPORTED_100baseT_Full |
110                                    SUPPORTED_1000baseT_Half |
111                                    SUPPORTED_1000baseT_Full);
112
113                 ecmd->advertising = (ADVERTISED_100baseT_Half |
114                                      ADVERTISED_100baseT_Full |
115                                      ADVERTISED_1000baseT_Half |
116                                      ADVERTISED_1000baseT_Full);
117
118                 ecmd->port = PORT_TP;
119
120                 ethtool_cmd_speed_set(ecmd, adapter->link_speed);
121                 ecmd->duplex = adapter->link_duplex;
122                 ecmd->autoneg = adapter->link_autoneg;
123
124         } else if (adapter->ahw.port_type == NETXEN_NIC_XGBE) {
125                 u32 val;
126
127                 val = NXRD32(adapter, NETXEN_PORT_MODE_ADDR);
128                 if (val == NETXEN_PORT_MODE_802_3_AP) {
129                         ecmd->supported = SUPPORTED_1000baseT_Full;
130                         ecmd->advertising = ADVERTISED_1000baseT_Full;
131                 } else {
132                         ecmd->supported = SUPPORTED_10000baseT_Full;
133                         ecmd->advertising = ADVERTISED_10000baseT_Full;
134                 }
135
136                 if (netif_running(dev) && adapter->has_link_events) {
137                         ethtool_cmd_speed_set(ecmd, adapter->link_speed);
138                         ecmd->autoneg = adapter->link_autoneg;
139                         ecmd->duplex = adapter->link_duplex;
140                         goto skip;
141                 }
142
143                 ecmd->port = PORT_TP;
144
145                 if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) {
146                         u16 pcifn = adapter->ahw.pci_func;
147
148                         val = NXRD32(adapter, P3_LINK_SPEED_REG(pcifn));
149                         ethtool_cmd_speed_set(ecmd, P3_LINK_SPEED_MHZ *
150                                               P3_LINK_SPEED_VAL(pcifn, val));
151                 } else
152                         ethtool_cmd_speed_set(ecmd, SPEED_10000);
153
154                 ecmd->duplex = DUPLEX_FULL;
155                 ecmd->autoneg = AUTONEG_DISABLE;
156         } else
157                 return -EIO;
158
159 skip:
160         ecmd->phy_address = adapter->physical_port;
161         ecmd->transceiver = XCVR_EXTERNAL;
162
163         switch (adapter->ahw.board_type) {
164         case NETXEN_BRDTYPE_P2_SB35_4G:
165         case NETXEN_BRDTYPE_P2_SB31_2G:
166         case NETXEN_BRDTYPE_P3_REF_QG:
167         case NETXEN_BRDTYPE_P3_4_GB:
168         case NETXEN_BRDTYPE_P3_4_GB_MM:
169
170                 ecmd->supported |= SUPPORTED_Autoneg;
171                 ecmd->advertising |= ADVERTISED_Autoneg;
172         case NETXEN_BRDTYPE_P2_SB31_10G_CX4:
173         case NETXEN_BRDTYPE_P3_10G_CX4:
174         case NETXEN_BRDTYPE_P3_10G_CX4_LP:
175         case NETXEN_BRDTYPE_P3_10000_BASE_T:
176                 ecmd->supported |= SUPPORTED_TP;
177                 ecmd->advertising |= ADVERTISED_TP;
178                 ecmd->port = PORT_TP;
179                 ecmd->autoneg = (adapter->ahw.board_type ==
180                                  NETXEN_BRDTYPE_P2_SB31_10G_CX4) ?
181                     (AUTONEG_DISABLE) : (adapter->link_autoneg);
182                 break;
183         case NETXEN_BRDTYPE_P2_SB31_10G_HMEZ:
184         case NETXEN_BRDTYPE_P2_SB31_10G_IMEZ:
185         case NETXEN_BRDTYPE_P3_IMEZ:
186         case NETXEN_BRDTYPE_P3_XG_LOM:
187         case NETXEN_BRDTYPE_P3_HMEZ:
188                 ecmd->supported |= SUPPORTED_MII;
189                 ecmd->advertising |= ADVERTISED_MII;
190                 ecmd->port = PORT_MII;
191                 ecmd->autoneg = AUTONEG_DISABLE;
192                 break;
193         case NETXEN_BRDTYPE_P3_10G_SFP_PLUS:
194         case NETXEN_BRDTYPE_P3_10G_SFP_CT:
195         case NETXEN_BRDTYPE_P3_10G_SFP_QT:
196                 ecmd->advertising |= ADVERTISED_TP;
197                 ecmd->supported |= SUPPORTED_TP;
198                 check_sfp_module = netif_running(dev) &&
199                         adapter->has_link_events;
200         case NETXEN_BRDTYPE_P2_SB31_10G:
201         case NETXEN_BRDTYPE_P3_10G_XFP:
202                 ecmd->supported |= SUPPORTED_FIBRE;
203                 ecmd->advertising |= ADVERTISED_FIBRE;
204                 ecmd->port = PORT_FIBRE;
205                 ecmd->autoneg = AUTONEG_DISABLE;
206                 break;
207         case NETXEN_BRDTYPE_P3_10G_TP:
208                 if (adapter->ahw.port_type == NETXEN_NIC_XGBE) {
209                         ecmd->autoneg = AUTONEG_DISABLE;
210                         ecmd->supported |= (SUPPORTED_FIBRE | SUPPORTED_TP);
211                         ecmd->advertising |=
212                                 (ADVERTISED_FIBRE | ADVERTISED_TP);
213                         ecmd->port = PORT_FIBRE;
214                         check_sfp_module = netif_running(dev) &&
215                                 adapter->has_link_events;
216                 } else {
217                         ecmd->supported |= (SUPPORTED_TP |SUPPORTED_Autoneg);
218                         ecmd->advertising |=
219                                 (ADVERTISED_TP | ADVERTISED_Autoneg);
220                         ecmd->port = PORT_TP;
221                 }
222                 break;
223         default:
224                 printk(KERN_ERR "netxen-nic: Unsupported board model %d\n",
225                                 adapter->ahw.board_type);
226                 return -EIO;
227         }
228
229         if (check_sfp_module) {
230                 switch (adapter->module_type) {
231                 case LINKEVENT_MODULE_OPTICAL_UNKNOWN:
232                 case LINKEVENT_MODULE_OPTICAL_SRLR:
233                 case LINKEVENT_MODULE_OPTICAL_LRM:
234                 case LINKEVENT_MODULE_OPTICAL_SFP_1G:
235                         ecmd->port = PORT_FIBRE;
236                         break;
237                 case LINKEVENT_MODULE_TWINAX_UNSUPPORTED_CABLE:
238                 case LINKEVENT_MODULE_TWINAX_UNSUPPORTED_CABLELEN:
239                 case LINKEVENT_MODULE_TWINAX:
240                         ecmd->port = PORT_TP;
241                         break;
242                 default:
243                         ecmd->port = -1;
244                 }
245         }
246
247         return 0;
248 }
249
250 static int
251 netxen_nic_set_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
252 {
253         struct netxen_adapter *adapter = netdev_priv(dev);
254         u32 speed = ethtool_cmd_speed(ecmd);
255         int ret;
256
257         if (adapter->ahw.port_type != NETXEN_NIC_GBE)
258                 return -EOPNOTSUPP;
259
260         if (!(adapter->capabilities & NX_FW_CAPABILITY_GBE_LINK_CFG))
261                 return -EOPNOTSUPP;
262
263         ret = nx_fw_cmd_set_gbe_port(adapter, speed, ecmd->duplex,
264                                      ecmd->autoneg);
265         if (ret == NX_RCODE_NOT_SUPPORTED)
266                 return -EOPNOTSUPP;
267         else if (ret)
268                 return -EIO;
269
270         adapter->link_speed = speed;
271         adapter->link_duplex = ecmd->duplex;
272         adapter->link_autoneg = ecmd->autoneg;
273
274         if (!netif_running(dev))
275                 return 0;
276
277         dev->netdev_ops->ndo_stop(dev);
278         return dev->netdev_ops->ndo_open(dev);
279 }
280
281 static int netxen_nic_get_regs_len(struct net_device *dev)
282 {
283         return NETXEN_NIC_REGS_LEN;
284 }
285
286 static void
287 netxen_nic_get_regs(struct net_device *dev, struct ethtool_regs *regs, void *p)
288 {
289         struct netxen_adapter *adapter = netdev_priv(dev);
290         struct netxen_recv_context *recv_ctx = &adapter->recv_ctx;
291         struct nx_host_sds_ring *sds_ring;
292         u32 *regs_buff = p;
293         int ring, i = 0;
294         int port = adapter->physical_port;
295
296         memset(p, 0, NETXEN_NIC_REGS_LEN);
297
298         regs->version = (1 << 24) | (adapter->ahw.revision_id << 16) |
299             (adapter->pdev)->device;
300
301         if (adapter->is_up != NETXEN_ADAPTER_UP_MAGIC)
302                 return;
303
304         regs_buff[i++] = NXRD32(adapter, CRB_CMDPEG_STATE);
305         regs_buff[i++] = NXRD32(adapter, CRB_RCVPEG_STATE);
306         regs_buff[i++] = NXRD32(adapter, CRB_FW_CAPABILITIES_1);
307         regs_buff[i++] = NXRDIO(adapter, adapter->crb_int_state_reg);
308         regs_buff[i++] = NXRD32(adapter, NX_CRB_DEV_REF_COUNT);
309         regs_buff[i++] = NXRD32(adapter, NX_CRB_DEV_STATE);
310         regs_buff[i++] = NXRD32(adapter, NETXEN_PEG_ALIVE_COUNTER);
311         regs_buff[i++] = NXRD32(adapter, NETXEN_PEG_HALT_STATUS1);
312         regs_buff[i++] = NXRD32(adapter, NETXEN_PEG_HALT_STATUS2);
313
314         regs_buff[i++] = NXRD32(adapter, NETXEN_CRB_PEG_NET_0+0x3c);
315         regs_buff[i++] = NXRD32(adapter, NETXEN_CRB_PEG_NET_1+0x3c);
316         regs_buff[i++] = NXRD32(adapter, NETXEN_CRB_PEG_NET_2+0x3c);
317         regs_buff[i++] = NXRD32(adapter, NETXEN_CRB_PEG_NET_3+0x3c);
318
319         if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) {
320
321                 regs_buff[i++] = NXRD32(adapter, NETXEN_CRB_PEG_NET_4+0x3c);
322                 i += 2;
323
324                 regs_buff[i++] = NXRD32(adapter, CRB_XG_STATE_P3);
325                 regs_buff[i++] = le32_to_cpu(*(adapter->tx_ring->hw_consumer));
326
327         } else {
328                 i++;
329
330                 regs_buff[i++] = NXRD32(adapter,
331                                         NETXEN_NIU_XGE_CONFIG_0+(0x10000*port));
332                 regs_buff[i++] = NXRD32(adapter,
333                                         NETXEN_NIU_XGE_CONFIG_1+(0x10000*port));
334
335                 regs_buff[i++] = NXRD32(adapter, CRB_XG_STATE);
336                 regs_buff[i++] = NXRDIO(adapter,
337                                  adapter->tx_ring->crb_cmd_consumer);
338         }
339
340         regs_buff[i++] = NXRDIO(adapter, adapter->tx_ring->crb_cmd_producer);
341
342         regs_buff[i++] = NXRDIO(adapter,
343                          recv_ctx->rds_rings[0].crb_rcv_producer);
344         regs_buff[i++] = NXRDIO(adapter,
345                          recv_ctx->rds_rings[1].crb_rcv_producer);
346
347         regs_buff[i++] = adapter->max_sds_rings;
348
349         for (ring = 0; ring < adapter->max_sds_rings; ring++) {
350                 sds_ring = &(recv_ctx->sds_rings[ring]);
351                 regs_buff[i++] = NXRDIO(adapter,
352                                         sds_ring->crb_sts_consumer);
353         }
354 }
355
356 static u32 netxen_nic_test_link(struct net_device *dev)
357 {
358         struct netxen_adapter *adapter = netdev_priv(dev);
359         u32 val, port;
360
361         port = adapter->physical_port;
362         if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) {
363                 val = NXRD32(adapter, CRB_XG_STATE_P3);
364                 val = XG_LINK_STATE_P3(adapter->ahw.pci_func, val);
365                 return (val == XG_LINK_UP_P3) ? 0 : 1;
366         } else {
367                 val = NXRD32(adapter, CRB_XG_STATE);
368                 val = (val >> port*8) & 0xff;
369                 return (val == XG_LINK_UP) ? 0 : 1;
370         }
371 }
372
373 static int
374 netxen_nic_get_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom,
375                       u8 * bytes)
376 {
377         struct netxen_adapter *adapter = netdev_priv(dev);
378         int offset;
379         int ret;
380
381         if (eeprom->len == 0)
382                 return -EINVAL;
383
384         eeprom->magic = (adapter->pdev)->vendor |
385                         ((adapter->pdev)->device << 16);
386         offset = eeprom->offset;
387
388         ret = netxen_rom_fast_read_words(adapter, offset, bytes,
389                                                 eeprom->len);
390         if (ret < 0)
391                 return ret;
392
393         return 0;
394 }
395
396 static void
397 netxen_nic_get_ringparam(struct net_device *dev,
398                 struct ethtool_ringparam *ring)
399 {
400         struct netxen_adapter *adapter = netdev_priv(dev);
401
402         ring->rx_pending = adapter->num_rxd;
403         ring->rx_jumbo_pending = adapter->num_jumbo_rxd;
404         ring->rx_jumbo_pending += adapter->num_lro_rxd;
405         ring->tx_pending = adapter->num_txd;
406
407         if (adapter->ahw.port_type == NETXEN_NIC_GBE) {
408                 ring->rx_max_pending = MAX_RCV_DESCRIPTORS_1G;
409                 ring->rx_jumbo_max_pending = MAX_JUMBO_RCV_DESCRIPTORS_1G;
410         } else {
411                 ring->rx_max_pending = MAX_RCV_DESCRIPTORS_10G;
412                 ring->rx_jumbo_max_pending = MAX_JUMBO_RCV_DESCRIPTORS_10G;
413         }
414
415         ring->tx_max_pending = MAX_CMD_DESCRIPTORS;
416 }
417
418 static u32
419 netxen_validate_ringparam(u32 val, u32 min, u32 max, char *r_name)
420 {
421         u32 num_desc;
422         num_desc = max(val, min);
423         num_desc = min(num_desc, max);
424         num_desc = roundup_pow_of_two(num_desc);
425
426         if (val != num_desc) {
427                 printk(KERN_INFO "%s: setting %s ring size %d instead of %d\n",
428                        netxen_nic_driver_name, r_name, num_desc, val);
429         }
430
431         return num_desc;
432 }
433
434 static int
435 netxen_nic_set_ringparam(struct net_device *dev,
436                 struct ethtool_ringparam *ring)
437 {
438         struct netxen_adapter *adapter = netdev_priv(dev);
439         u16 max_rcv_desc = MAX_RCV_DESCRIPTORS_10G;
440         u16 max_jumbo_desc = MAX_JUMBO_RCV_DESCRIPTORS_10G;
441         u16 num_rxd, num_jumbo_rxd, num_txd;
442
443         if (NX_IS_REVISION_P2(adapter->ahw.revision_id))
444                 return -EOPNOTSUPP;
445
446         if (ring->rx_mini_pending)
447                 return -EOPNOTSUPP;
448
449         if (adapter->ahw.port_type == NETXEN_NIC_GBE) {
450                 max_rcv_desc = MAX_RCV_DESCRIPTORS_1G;
451                 max_jumbo_desc = MAX_JUMBO_RCV_DESCRIPTORS_10G;
452         }
453
454         num_rxd = netxen_validate_ringparam(ring->rx_pending,
455                         MIN_RCV_DESCRIPTORS, max_rcv_desc, "rx");
456
457         num_jumbo_rxd = netxen_validate_ringparam(ring->rx_jumbo_pending,
458                         MIN_JUMBO_DESCRIPTORS, max_jumbo_desc, "rx jumbo");
459
460         num_txd = netxen_validate_ringparam(ring->tx_pending,
461                         MIN_CMD_DESCRIPTORS, MAX_CMD_DESCRIPTORS, "tx");
462
463         if (num_rxd == adapter->num_rxd && num_txd == adapter->num_txd &&
464                         num_jumbo_rxd == adapter->num_jumbo_rxd)
465                 return 0;
466
467         adapter->num_rxd = num_rxd;
468         adapter->num_jumbo_rxd = num_jumbo_rxd;
469         adapter->num_txd = num_txd;
470
471         return netxen_nic_reset_context(adapter);
472 }
473
474 static void
475 netxen_nic_get_pauseparam(struct net_device *dev,
476                           struct ethtool_pauseparam *pause)
477 {
478         struct netxen_adapter *adapter = netdev_priv(dev);
479         __u32 val;
480         int port = adapter->physical_port;
481
482         if (adapter->ahw.port_type == NETXEN_NIC_GBE) {
483                 if ((port < 0) || (port > NETXEN_NIU_MAX_GBE_PORTS))
484                         return;
485                 /* get flow control settings */
486                 val = NXRD32(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(port));
487                 pause->rx_pause = netxen_gb_get_rx_flowctl(val);
488                 val = NXRD32(adapter, NETXEN_NIU_GB_PAUSE_CTL);
489                 switch (port) {
490                         case 0:
491                                 pause->tx_pause = !(netxen_gb_get_gb0_mask(val));
492                                 break;
493                         case 1:
494                                 pause->tx_pause = !(netxen_gb_get_gb1_mask(val));
495                                 break;
496                         case 2:
497                                 pause->tx_pause = !(netxen_gb_get_gb2_mask(val));
498                                 break;
499                         case 3:
500                         default:
501                                 pause->tx_pause = !(netxen_gb_get_gb3_mask(val));
502                                 break;
503                 }
504         } else if (adapter->ahw.port_type == NETXEN_NIC_XGBE) {
505                 if ((port < 0) || (port > NETXEN_NIU_MAX_XG_PORTS))
506                         return;
507                 pause->rx_pause = 1;
508                 val = NXRD32(adapter, NETXEN_NIU_XG_PAUSE_CTL);
509                 if (port == 0)
510                         pause->tx_pause = !(netxen_xg_get_xg0_mask(val));
511                 else
512                         pause->tx_pause = !(netxen_xg_get_xg1_mask(val));
513         } else {
514                 printk(KERN_ERR"%s: Unknown board type: %x\n",
515                                 netxen_nic_driver_name, adapter->ahw.port_type);
516         }
517 }
518
519 static int
520 netxen_nic_set_pauseparam(struct net_device *dev,
521                           struct ethtool_pauseparam *pause)
522 {
523         struct netxen_adapter *adapter = netdev_priv(dev);
524         __u32 val;
525         int port = adapter->physical_port;
526         /* read mode */
527         if (adapter->ahw.port_type == NETXEN_NIC_GBE) {
528                 if ((port < 0) || (port > NETXEN_NIU_MAX_GBE_PORTS))
529                         return -EIO;
530                 /* set flow control */
531                 val = NXRD32(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(port));
532
533                 if (pause->rx_pause)
534                         netxen_gb_rx_flowctl(val);
535                 else
536                         netxen_gb_unset_rx_flowctl(val);
537
538                 NXWR32(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(port),
539                                 val);
540                 /* set autoneg */
541                 val = NXRD32(adapter, NETXEN_NIU_GB_PAUSE_CTL);
542                 switch (port) {
543                         case 0:
544                                 if (pause->tx_pause)
545                                         netxen_gb_unset_gb0_mask(val);
546                                 else
547                                         netxen_gb_set_gb0_mask(val);
548                                 break;
549                         case 1:
550                                 if (pause->tx_pause)
551                                         netxen_gb_unset_gb1_mask(val);
552                                 else
553                                         netxen_gb_set_gb1_mask(val);
554                                 break;
555                         case 2:
556                                 if (pause->tx_pause)
557                                         netxen_gb_unset_gb2_mask(val);
558                                 else
559                                         netxen_gb_set_gb2_mask(val);
560                                 break;
561                         case 3:
562                         default:
563                                 if (pause->tx_pause)
564                                         netxen_gb_unset_gb3_mask(val);
565                                 else
566                                         netxen_gb_set_gb3_mask(val);
567                                 break;
568                 }
569                 NXWR32(adapter, NETXEN_NIU_GB_PAUSE_CTL, val);
570         } else if (adapter->ahw.port_type == NETXEN_NIC_XGBE) {
571                 if ((port < 0) || (port > NETXEN_NIU_MAX_XG_PORTS))
572                         return -EIO;
573                 val = NXRD32(adapter, NETXEN_NIU_XG_PAUSE_CTL);
574                 if (port == 0) {
575                         if (pause->tx_pause)
576                                 netxen_xg_unset_xg0_mask(val);
577                         else
578                                 netxen_xg_set_xg0_mask(val);
579                 } else {
580                         if (pause->tx_pause)
581                                 netxen_xg_unset_xg1_mask(val);
582                         else
583                                 netxen_xg_set_xg1_mask(val);
584                 }
585                 NXWR32(adapter, NETXEN_NIU_XG_PAUSE_CTL, val);
586         } else {
587                 printk(KERN_ERR "%s: Unknown board type: %x\n",
588                                 netxen_nic_driver_name,
589                                 adapter->ahw.port_type);
590         }
591         return 0;
592 }
593
594 static int netxen_nic_reg_test(struct net_device *dev)
595 {
596         struct netxen_adapter *adapter = netdev_priv(dev);
597         u32 data_read, data_written;
598
599         data_read = NXRD32(adapter, NETXEN_PCIX_PH_REG(0));
600         if ((data_read & 0xffff) != adapter->pdev->vendor)
601                 return 1;
602
603         if (NX_IS_REVISION_P3(adapter->ahw.revision_id))
604                 return 0;
605
606         data_written = (u32)0xa5a5a5a5;
607
608         NXWR32(adapter, CRB_SCRATCHPAD_TEST, data_written);
609         data_read = NXRD32(adapter, CRB_SCRATCHPAD_TEST);
610         if (data_written != data_read)
611                 return 1;
612
613         return 0;
614 }
615
616 static int netxen_get_sset_count(struct net_device *dev, int sset)
617 {
618         switch (sset) {
619         case ETH_SS_TEST:
620                 return NETXEN_NIC_TEST_LEN;
621         case ETH_SS_STATS:
622                 return NETXEN_NIC_STATS_LEN;
623         default:
624                 return -EOPNOTSUPP;
625         }
626 }
627
628 static void
629 netxen_nic_diag_test(struct net_device *dev, struct ethtool_test *eth_test,
630                      u64 * data)
631 {
632         memset(data, 0, sizeof(uint64_t) * NETXEN_NIC_TEST_LEN);
633         if ((data[0] = netxen_nic_reg_test(dev)))
634                 eth_test->flags |= ETH_TEST_FL_FAILED;
635         /* link test */
636         if ((data[1] = (u64) netxen_nic_test_link(dev)))
637                 eth_test->flags |= ETH_TEST_FL_FAILED;
638 }
639
640 static void
641 netxen_nic_get_strings(struct net_device *dev, u32 stringset, u8 * data)
642 {
643         int index;
644
645         switch (stringset) {
646         case ETH_SS_TEST:
647                 memcpy(data, *netxen_nic_gstrings_test,
648                        NETXEN_NIC_TEST_LEN * ETH_GSTRING_LEN);
649                 break;
650         case ETH_SS_STATS:
651                 for (index = 0; index < NETXEN_NIC_STATS_LEN; index++) {
652                         memcpy(data + index * ETH_GSTRING_LEN,
653                                netxen_nic_gstrings_stats[index].stat_string,
654                                ETH_GSTRING_LEN);
655                 }
656                 break;
657         }
658 }
659
660 static void
661 netxen_nic_get_ethtool_stats(struct net_device *dev,
662                              struct ethtool_stats *stats, u64 * data)
663 {
664         struct netxen_adapter *adapter = netdev_priv(dev);
665         int index;
666
667         for (index = 0; index < NETXEN_NIC_STATS_LEN; index++) {
668                 char *p =
669                     (char *)adapter +
670                     netxen_nic_gstrings_stats[index].stat_offset;
671                 data[index] =
672                     (netxen_nic_gstrings_stats[index].sizeof_stat ==
673                      sizeof(u64)) ? *(u64 *) p : *(u32 *) p;
674         }
675 }
676
677 static void
678 netxen_nic_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
679 {
680         struct netxen_adapter *adapter = netdev_priv(dev);
681         u32 wol_cfg = 0;
682
683         wol->supported = 0;
684         wol->wolopts = 0;
685
686         if (NX_IS_REVISION_P2(adapter->ahw.revision_id))
687                 return;
688
689         wol_cfg = NXRD32(adapter, NETXEN_WOL_CONFIG_NV);
690         if (wol_cfg & (1UL << adapter->portnum))
691                 wol->supported |= WAKE_MAGIC;
692
693         wol_cfg = NXRD32(adapter, NETXEN_WOL_CONFIG);
694         if (wol_cfg & (1UL << adapter->portnum))
695                 wol->wolopts |= WAKE_MAGIC;
696 }
697
698 static int
699 netxen_nic_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
700 {
701         struct netxen_adapter *adapter = netdev_priv(dev);
702         u32 wol_cfg = 0;
703
704         if (NX_IS_REVISION_P2(adapter->ahw.revision_id))
705                 return -EOPNOTSUPP;
706
707         if (wol->wolopts & ~WAKE_MAGIC)
708                 return -EOPNOTSUPP;
709
710         wol_cfg = NXRD32(adapter, NETXEN_WOL_CONFIG_NV);
711         if (!(wol_cfg & (1 << adapter->portnum)))
712                 return -EOPNOTSUPP;
713
714         wol_cfg = NXRD32(adapter, NETXEN_WOL_CONFIG);
715         if (wol->wolopts & WAKE_MAGIC)
716                 wol_cfg |= 1UL << adapter->portnum;
717         else
718                 wol_cfg &= ~(1UL << adapter->portnum);
719         NXWR32(adapter, NETXEN_WOL_CONFIG, wol_cfg);
720
721         return 0;
722 }
723
724 /*
725  * Set the coalescing parameters. Currently only normal is supported.
726  * If rx_coalesce_usecs == 0 or rx_max_coalesced_frames == 0 then set the
727  * firmware coalescing to default.
728  */
729 static int netxen_set_intr_coalesce(struct net_device *netdev,
730                         struct ethtool_coalesce *ethcoal)
731 {
732         struct netxen_adapter *adapter = netdev_priv(netdev);
733
734         if (!NX_IS_REVISION_P3(adapter->ahw.revision_id))
735                 return -EINVAL;
736
737         if (adapter->is_up != NETXEN_ADAPTER_UP_MAGIC)
738                 return -EINVAL;
739
740         /*
741         * Return Error if unsupported values or
742         * unsupported parameters are set.
743         */
744         if (ethcoal->rx_coalesce_usecs > 0xffff ||
745                 ethcoal->rx_max_coalesced_frames > 0xffff ||
746                 ethcoal->tx_coalesce_usecs > 0xffff ||
747                 ethcoal->tx_max_coalesced_frames > 0xffff ||
748                 ethcoal->rx_coalesce_usecs_irq ||
749                 ethcoal->rx_max_coalesced_frames_irq ||
750                 ethcoal->tx_coalesce_usecs_irq ||
751                 ethcoal->tx_max_coalesced_frames_irq ||
752                 ethcoal->stats_block_coalesce_usecs ||
753                 ethcoal->use_adaptive_rx_coalesce ||
754                 ethcoal->use_adaptive_tx_coalesce ||
755                 ethcoal->pkt_rate_low ||
756                 ethcoal->rx_coalesce_usecs_low ||
757                 ethcoal->rx_max_coalesced_frames_low ||
758                 ethcoal->tx_coalesce_usecs_low ||
759                 ethcoal->tx_max_coalesced_frames_low ||
760                 ethcoal->pkt_rate_high ||
761                 ethcoal->rx_coalesce_usecs_high ||
762                 ethcoal->rx_max_coalesced_frames_high ||
763                 ethcoal->tx_coalesce_usecs_high ||
764                 ethcoal->tx_max_coalesced_frames_high)
765                 return -EINVAL;
766
767         if (!ethcoal->rx_coalesce_usecs ||
768                 !ethcoal->rx_max_coalesced_frames) {
769                 adapter->coal.flags = NETXEN_NIC_INTR_DEFAULT;
770                 adapter->coal.normal.data.rx_time_us =
771                         NETXEN_DEFAULT_INTR_COALESCE_RX_TIME_US;
772                 adapter->coal.normal.data.rx_packets =
773                         NETXEN_DEFAULT_INTR_COALESCE_RX_PACKETS;
774         } else {
775                 adapter->coal.flags = 0;
776                 adapter->coal.normal.data.rx_time_us =
777                 ethcoal->rx_coalesce_usecs;
778                 adapter->coal.normal.data.rx_packets =
779                 ethcoal->rx_max_coalesced_frames;
780         }
781         adapter->coal.normal.data.tx_time_us = ethcoal->tx_coalesce_usecs;
782         adapter->coal.normal.data.tx_packets =
783         ethcoal->tx_max_coalesced_frames;
784
785         netxen_config_intr_coalesce(adapter);
786
787         return 0;
788 }
789
790 static int netxen_get_intr_coalesce(struct net_device *netdev,
791                         struct ethtool_coalesce *ethcoal)
792 {
793         struct netxen_adapter *adapter = netdev_priv(netdev);
794
795         if (!NX_IS_REVISION_P3(adapter->ahw.revision_id))
796                 return -EINVAL;
797
798         if (adapter->is_up != NETXEN_ADAPTER_UP_MAGIC)
799                 return -EINVAL;
800
801         ethcoal->rx_coalesce_usecs = adapter->coal.normal.data.rx_time_us;
802         ethcoal->tx_coalesce_usecs = adapter->coal.normal.data.tx_time_us;
803         ethcoal->rx_max_coalesced_frames =
804                 adapter->coal.normal.data.rx_packets;
805         ethcoal->tx_max_coalesced_frames =
806                 adapter->coal.normal.data.tx_packets;
807
808         return 0;
809 }
810
811 const struct ethtool_ops netxen_nic_ethtool_ops = {
812         .get_settings = netxen_nic_get_settings,
813         .set_settings = netxen_nic_set_settings,
814         .get_drvinfo = netxen_nic_get_drvinfo,
815         .get_regs_len = netxen_nic_get_regs_len,
816         .get_regs = netxen_nic_get_regs,
817         .get_link = ethtool_op_get_link,
818         .get_eeprom_len = netxen_nic_get_eeprom_len,
819         .get_eeprom = netxen_nic_get_eeprom,
820         .get_ringparam = netxen_nic_get_ringparam,
821         .set_ringparam = netxen_nic_set_ringparam,
822         .get_pauseparam = netxen_nic_get_pauseparam,
823         .set_pauseparam = netxen_nic_set_pauseparam,
824         .get_wol = netxen_nic_get_wol,
825         .set_wol = netxen_nic_set_wol,
826         .self_test = netxen_nic_diag_test,
827         .get_strings = netxen_nic_get_strings,
828         .get_ethtool_stats = netxen_nic_get_ethtool_stats,
829         .get_sset_count = netxen_get_sset_count,
830         .get_coalesce = netxen_get_intr_coalesce,
831         .set_coalesce = netxen_set_intr_coalesce,
832 };