p54usb: New USB ID for Gemtek WUBI-100GW
[pandora-kernel.git] / drivers / net / 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                 ecmd->speed = 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                         ecmd->speed = 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                         ecmd->speed = P3_LINK_SPEED_MHZ *
150                                         P3_LINK_SPEED_VAL(pcifn, val);
151                 } else
152                         ecmd->speed = 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->autoneg = AUTONEG_ENABLE;
218                         ecmd->supported |= (SUPPORTED_TP |SUPPORTED_Autoneg);
219                         ecmd->advertising |=
220                                 (ADVERTISED_TP | ADVERTISED_Autoneg);
221                         ecmd->port = PORT_TP;
222                 }
223                 break;
224         default:
225                 printk(KERN_ERR "netxen-nic: Unsupported board model %d\n",
226                                 adapter->ahw.board_type);
227                 return -EIO;
228         }
229
230         if (check_sfp_module) {
231                 switch (adapter->module_type) {
232                 case LINKEVENT_MODULE_OPTICAL_UNKNOWN:
233                 case LINKEVENT_MODULE_OPTICAL_SRLR:
234                 case LINKEVENT_MODULE_OPTICAL_LRM:
235                 case LINKEVENT_MODULE_OPTICAL_SFP_1G:
236                         ecmd->port = PORT_FIBRE;
237                         break;
238                 case LINKEVENT_MODULE_TWINAX_UNSUPPORTED_CABLE:
239                 case LINKEVENT_MODULE_TWINAX_UNSUPPORTED_CABLELEN:
240                 case LINKEVENT_MODULE_TWINAX:
241                         ecmd->port = PORT_TP;
242                         break;
243                 default:
244                         ecmd->port = -1;
245                 }
246         }
247
248         return 0;
249 }
250
251 static int
252 netxen_nic_set_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
253 {
254         struct netxen_adapter *adapter = netdev_priv(dev);
255         __u32 status;
256
257         /* read which mode */
258         if (adapter->ahw.port_type == NETXEN_NIC_GBE) {
259                 /* autonegotiation */
260                 if (adapter->phy_write &&
261                     adapter->phy_write(adapter,
262                                        NETXEN_NIU_GB_MII_MGMT_ADDR_AUTONEG,
263                                        ecmd->autoneg) != 0)
264                         return -EIO;
265                 else
266                         adapter->link_autoneg = ecmd->autoneg;
267
268                 if (adapter->phy_read &&
269                     adapter->phy_read(adapter,
270                                       NETXEN_NIU_GB_MII_MGMT_ADDR_PHY_STATUS,
271                                       &status) != 0)
272                         return -EIO;
273
274                 /* speed */
275                 switch (ecmd->speed) {
276                 case SPEED_10:
277                         netxen_set_phy_speed(status, 0);
278                         break;
279                 case SPEED_100:
280                         netxen_set_phy_speed(status, 1);
281                         break;
282                 case SPEED_1000:
283                         netxen_set_phy_speed(status, 2);
284                         break;
285                 }
286                 /* set duplex mode */
287                 if (ecmd->duplex == DUPLEX_HALF)
288                         netxen_clear_phy_duplex(status);
289                 if (ecmd->duplex == DUPLEX_FULL)
290                         netxen_set_phy_duplex(status);
291                 if (adapter->phy_write &&
292                     adapter->phy_write(adapter,
293                                        NETXEN_NIU_GB_MII_MGMT_ADDR_PHY_STATUS,
294                                        *((int *)&status)) != 0)
295                         return -EIO;
296                 else {
297                         adapter->link_speed = ecmd->speed;
298                         adapter->link_duplex = ecmd->duplex;
299                 }
300         } else
301                 return -EOPNOTSUPP;
302
303         if (!netif_running(dev))
304                 return 0;
305
306         dev->netdev_ops->ndo_stop(dev);
307         return dev->netdev_ops->ndo_open(dev);
308 }
309
310 static int netxen_nic_get_regs_len(struct net_device *dev)
311 {
312         return NETXEN_NIC_REGS_LEN;
313 }
314
315 static void
316 netxen_nic_get_regs(struct net_device *dev, struct ethtool_regs *regs, void *p)
317 {
318         struct netxen_adapter *adapter = netdev_priv(dev);
319         struct netxen_recv_context *recv_ctx = &adapter->recv_ctx;
320         struct nx_host_sds_ring *sds_ring;
321         u32 *regs_buff = p;
322         int ring, i = 0;
323         int port = adapter->physical_port;
324
325         memset(p, 0, NETXEN_NIC_REGS_LEN);
326
327         regs->version = (1 << 24) | (adapter->ahw.revision_id << 16) |
328             (adapter->pdev)->device;
329
330         if (adapter->is_up != NETXEN_ADAPTER_UP_MAGIC)
331                 return;
332
333         regs_buff[i++] = NXRD32(adapter, CRB_CMDPEG_STATE);
334         regs_buff[i++] = NXRD32(adapter, CRB_RCVPEG_STATE);
335         regs_buff[i++] = NXRD32(adapter, CRB_FW_CAPABILITIES_1);
336         regs_buff[i++] = NXRDIO(adapter, adapter->crb_int_state_reg);
337         regs_buff[i++] = NXRD32(adapter, NX_CRB_DEV_REF_COUNT);
338         regs_buff[i++] = NXRD32(adapter, NX_CRB_DEV_STATE);
339         regs_buff[i++] = NXRD32(adapter, NETXEN_PEG_ALIVE_COUNTER);
340         regs_buff[i++] = NXRD32(adapter, NETXEN_PEG_HALT_STATUS1);
341         regs_buff[i++] = NXRD32(adapter, NETXEN_PEG_HALT_STATUS2);
342
343         regs_buff[i++] = NXRD32(adapter, NETXEN_CRB_PEG_NET_0+0x3c);
344         regs_buff[i++] = NXRD32(adapter, NETXEN_CRB_PEG_NET_1+0x3c);
345         regs_buff[i++] = NXRD32(adapter, NETXEN_CRB_PEG_NET_2+0x3c);
346         regs_buff[i++] = NXRD32(adapter, NETXEN_CRB_PEG_NET_3+0x3c);
347
348         if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) {
349
350                 regs_buff[i++] = NXRD32(adapter, NETXEN_CRB_PEG_NET_4+0x3c);
351                 i += 2;
352
353                 regs_buff[i++] = NXRD32(adapter, CRB_XG_STATE_P3);
354                 regs_buff[i++] = le32_to_cpu(*(adapter->tx_ring->hw_consumer));
355
356         } else {
357                 i++;
358
359                 regs_buff[i++] = NXRD32(adapter,
360                                         NETXEN_NIU_XGE_CONFIG_0+(0x10000*port));
361                 regs_buff[i++] = NXRD32(adapter,
362                                         NETXEN_NIU_XGE_CONFIG_1+(0x10000*port));
363
364                 regs_buff[i++] = NXRD32(adapter, CRB_XG_STATE);
365                 regs_buff[i++] = NXRDIO(adapter,
366                                  adapter->tx_ring->crb_cmd_consumer);
367         }
368
369         regs_buff[i++] = NXRDIO(adapter, adapter->tx_ring->crb_cmd_producer);
370
371         regs_buff[i++] = NXRDIO(adapter,
372                          recv_ctx->rds_rings[0].crb_rcv_producer);
373         regs_buff[i++] = NXRDIO(adapter,
374                          recv_ctx->rds_rings[1].crb_rcv_producer);
375
376         regs_buff[i++] = adapter->max_sds_rings;
377
378         for (ring = 0; ring < adapter->max_sds_rings; ring++) {
379                 sds_ring = &(recv_ctx->sds_rings[ring]);
380                 regs_buff[i++] = NXRDIO(adapter,
381                                         sds_ring->crb_sts_consumer);
382         }
383 }
384
385 static u32 netxen_nic_test_link(struct net_device *dev)
386 {
387         struct netxen_adapter *adapter = netdev_priv(dev);
388         u32 val, port;
389
390         port = adapter->physical_port;
391         if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) {
392                 val = NXRD32(adapter, CRB_XG_STATE_P3);
393                 val = XG_LINK_STATE_P3(adapter->ahw.pci_func, val);
394                 return (val == XG_LINK_UP_P3) ? 0 : 1;
395         } else {
396                 val = NXRD32(adapter, CRB_XG_STATE);
397                 val = (val >> port*8) & 0xff;
398                 return (val == XG_LINK_UP) ? 0 : 1;
399         }
400 }
401
402 static int
403 netxen_nic_get_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom,
404                       u8 * bytes)
405 {
406         struct netxen_adapter *adapter = netdev_priv(dev);
407         int offset;
408         int ret;
409
410         if (eeprom->len == 0)
411                 return -EINVAL;
412
413         eeprom->magic = (adapter->pdev)->vendor |
414                         ((adapter->pdev)->device << 16);
415         offset = eeprom->offset;
416
417         ret = netxen_rom_fast_read_words(adapter, offset, bytes,
418                                                 eeprom->len);
419         if (ret < 0)
420                 return ret;
421
422         return 0;
423 }
424
425 static void
426 netxen_nic_get_ringparam(struct net_device *dev,
427                 struct ethtool_ringparam *ring)
428 {
429         struct netxen_adapter *adapter = netdev_priv(dev);
430
431         ring->rx_pending = adapter->num_rxd;
432         ring->rx_jumbo_pending = adapter->num_jumbo_rxd;
433         ring->rx_jumbo_pending += adapter->num_lro_rxd;
434         ring->tx_pending = adapter->num_txd;
435
436         if (adapter->ahw.port_type == NETXEN_NIC_GBE) {
437                 ring->rx_max_pending = MAX_RCV_DESCRIPTORS_1G;
438                 ring->rx_jumbo_max_pending = MAX_JUMBO_RCV_DESCRIPTORS_1G;
439         } else {
440                 ring->rx_max_pending = MAX_RCV_DESCRIPTORS_10G;
441                 ring->rx_jumbo_max_pending = MAX_JUMBO_RCV_DESCRIPTORS_10G;
442         }
443
444         ring->tx_max_pending = MAX_CMD_DESCRIPTORS;
445
446         ring->rx_mini_max_pending = 0;
447         ring->rx_mini_pending = 0;
448 }
449
450 static u32
451 netxen_validate_ringparam(u32 val, u32 min, u32 max, char *r_name)
452 {
453         u32 num_desc;
454         num_desc = max(val, min);
455         num_desc = min(num_desc, max);
456         num_desc = roundup_pow_of_two(num_desc);
457
458         if (val != num_desc) {
459                 printk(KERN_INFO "%s: setting %s ring size %d instead of %d\n",
460                        netxen_nic_driver_name, r_name, num_desc, val);
461         }
462
463         return num_desc;
464 }
465
466 static int
467 netxen_nic_set_ringparam(struct net_device *dev,
468                 struct ethtool_ringparam *ring)
469 {
470         struct netxen_adapter *adapter = netdev_priv(dev);
471         u16 max_rcv_desc = MAX_RCV_DESCRIPTORS_10G;
472         u16 max_jumbo_desc = MAX_JUMBO_RCV_DESCRIPTORS_10G;
473         u16 num_rxd, num_jumbo_rxd, num_txd;
474
475         if (NX_IS_REVISION_P2(adapter->ahw.revision_id))
476                 return -EOPNOTSUPP;
477
478         if (ring->rx_mini_pending)
479                 return -EOPNOTSUPP;
480
481         if (adapter->ahw.port_type == NETXEN_NIC_GBE) {
482                 max_rcv_desc = MAX_RCV_DESCRIPTORS_1G;
483                 max_jumbo_desc = MAX_JUMBO_RCV_DESCRIPTORS_10G;
484         }
485
486         num_rxd = netxen_validate_ringparam(ring->rx_pending,
487                         MIN_RCV_DESCRIPTORS, max_rcv_desc, "rx");
488
489         num_jumbo_rxd = netxen_validate_ringparam(ring->rx_jumbo_pending,
490                         MIN_JUMBO_DESCRIPTORS, max_jumbo_desc, "rx jumbo");
491
492         num_txd = netxen_validate_ringparam(ring->tx_pending,
493                         MIN_CMD_DESCRIPTORS, MAX_CMD_DESCRIPTORS, "tx");
494
495         if (num_rxd == adapter->num_rxd && num_txd == adapter->num_txd &&
496                         num_jumbo_rxd == adapter->num_jumbo_rxd)
497                 return 0;
498
499         adapter->num_rxd = num_rxd;
500         adapter->num_jumbo_rxd = num_jumbo_rxd;
501         adapter->num_txd = num_txd;
502
503         return netxen_nic_reset_context(adapter);
504 }
505
506 static void
507 netxen_nic_get_pauseparam(struct net_device *dev,
508                           struct ethtool_pauseparam *pause)
509 {
510         struct netxen_adapter *adapter = netdev_priv(dev);
511         __u32 val;
512         int port = adapter->physical_port;
513
514         if (adapter->ahw.port_type == NETXEN_NIC_GBE) {
515                 if ((port < 0) || (port > NETXEN_NIU_MAX_GBE_PORTS))
516                         return;
517                 /* get flow control settings */
518                 val = NXRD32(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(port));
519                 pause->rx_pause = netxen_gb_get_rx_flowctl(val);
520                 val = NXRD32(adapter, NETXEN_NIU_GB_PAUSE_CTL);
521                 switch (port) {
522                         case 0:
523                                 pause->tx_pause = !(netxen_gb_get_gb0_mask(val));
524                                 break;
525                         case 1:
526                                 pause->tx_pause = !(netxen_gb_get_gb1_mask(val));
527                                 break;
528                         case 2:
529                                 pause->tx_pause = !(netxen_gb_get_gb2_mask(val));
530                                 break;
531                         case 3:
532                         default:
533                                 pause->tx_pause = !(netxen_gb_get_gb3_mask(val));
534                                 break;
535                 }
536         } else if (adapter->ahw.port_type == NETXEN_NIC_XGBE) {
537                 if ((port < 0) || (port > NETXEN_NIU_MAX_XG_PORTS))
538                         return;
539                 pause->rx_pause = 1;
540                 val = NXRD32(adapter, NETXEN_NIU_XG_PAUSE_CTL);
541                 if (port == 0)
542                         pause->tx_pause = !(netxen_xg_get_xg0_mask(val));
543                 else
544                         pause->tx_pause = !(netxen_xg_get_xg1_mask(val));
545         } else {
546                 printk(KERN_ERR"%s: Unknown board type: %x\n",
547                                 netxen_nic_driver_name, adapter->ahw.port_type);
548         }
549 }
550
551 static int
552 netxen_nic_set_pauseparam(struct net_device *dev,
553                           struct ethtool_pauseparam *pause)
554 {
555         struct netxen_adapter *adapter = netdev_priv(dev);
556         __u32 val;
557         int port = adapter->physical_port;
558         /* read mode */
559         if (adapter->ahw.port_type == NETXEN_NIC_GBE) {
560                 if ((port < 0) || (port > NETXEN_NIU_MAX_GBE_PORTS))
561                         return -EIO;
562                 /* set flow control */
563                 val = NXRD32(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(port));
564
565                 if (pause->rx_pause)
566                         netxen_gb_rx_flowctl(val);
567                 else
568                         netxen_gb_unset_rx_flowctl(val);
569
570                 NXWR32(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(port),
571                                 val);
572                 /* set autoneg */
573                 val = NXRD32(adapter, NETXEN_NIU_GB_PAUSE_CTL);
574                 switch (port) {
575                         case 0:
576                                 if (pause->tx_pause)
577                                         netxen_gb_unset_gb0_mask(val);
578                                 else
579                                         netxen_gb_set_gb0_mask(val);
580                                 break;
581                         case 1:
582                                 if (pause->tx_pause)
583                                         netxen_gb_unset_gb1_mask(val);
584                                 else
585                                         netxen_gb_set_gb1_mask(val);
586                                 break;
587                         case 2:
588                                 if (pause->tx_pause)
589                                         netxen_gb_unset_gb2_mask(val);
590                                 else
591                                         netxen_gb_set_gb2_mask(val);
592                                 break;
593                         case 3:
594                         default:
595                                 if (pause->tx_pause)
596                                         netxen_gb_unset_gb3_mask(val);
597                                 else
598                                         netxen_gb_set_gb3_mask(val);
599                                 break;
600                 }
601                 NXWR32(adapter, NETXEN_NIU_GB_PAUSE_CTL, val);
602         } else if (adapter->ahw.port_type == NETXEN_NIC_XGBE) {
603                 if ((port < 0) || (port > NETXEN_NIU_MAX_XG_PORTS))
604                         return -EIO;
605                 val = NXRD32(adapter, NETXEN_NIU_XG_PAUSE_CTL);
606                 if (port == 0) {
607                         if (pause->tx_pause)
608                                 netxen_xg_unset_xg0_mask(val);
609                         else
610                                 netxen_xg_set_xg0_mask(val);
611                 } else {
612                         if (pause->tx_pause)
613                                 netxen_xg_unset_xg1_mask(val);
614                         else
615                                 netxen_xg_set_xg1_mask(val);
616                 }
617                 NXWR32(adapter, NETXEN_NIU_XG_PAUSE_CTL, val);
618         } else {
619                 printk(KERN_ERR "%s: Unknown board type: %x\n",
620                                 netxen_nic_driver_name,
621                                 adapter->ahw.port_type);
622         }
623         return 0;
624 }
625
626 static int netxen_nic_reg_test(struct net_device *dev)
627 {
628         struct netxen_adapter *adapter = netdev_priv(dev);
629         u32 data_read, data_written;
630
631         data_read = NXRD32(adapter, NETXEN_PCIX_PH_REG(0));
632         if ((data_read & 0xffff) != adapter->pdev->vendor)
633                 return 1;
634
635         if (NX_IS_REVISION_P3(adapter->ahw.revision_id))
636                 return 0;
637
638         data_written = (u32)0xa5a5a5a5;
639
640         NXWR32(adapter, CRB_SCRATCHPAD_TEST, data_written);
641         data_read = NXRD32(adapter, CRB_SCRATCHPAD_TEST);
642         if (data_written != data_read)
643                 return 1;
644
645         return 0;
646 }
647
648 static int netxen_get_sset_count(struct net_device *dev, int sset)
649 {
650         switch (sset) {
651         case ETH_SS_TEST:
652                 return NETXEN_NIC_TEST_LEN;
653         case ETH_SS_STATS:
654                 return NETXEN_NIC_STATS_LEN;
655         default:
656                 return -EOPNOTSUPP;
657         }
658 }
659
660 static void
661 netxen_nic_diag_test(struct net_device *dev, struct ethtool_test *eth_test,
662                      u64 * data)
663 {
664         memset(data, 0, sizeof(uint64_t) * NETXEN_NIC_TEST_LEN);
665         if ((data[0] = netxen_nic_reg_test(dev)))
666                 eth_test->flags |= ETH_TEST_FL_FAILED;
667         /* link test */
668         if ((data[1] = (u64) netxen_nic_test_link(dev)))
669                 eth_test->flags |= ETH_TEST_FL_FAILED;
670 }
671
672 static void
673 netxen_nic_get_strings(struct net_device *dev, u32 stringset, u8 * data)
674 {
675         int index;
676
677         switch (stringset) {
678         case ETH_SS_TEST:
679                 memcpy(data, *netxen_nic_gstrings_test,
680                        NETXEN_NIC_TEST_LEN * ETH_GSTRING_LEN);
681                 break;
682         case ETH_SS_STATS:
683                 for (index = 0; index < NETXEN_NIC_STATS_LEN; index++) {
684                         memcpy(data + index * ETH_GSTRING_LEN,
685                                netxen_nic_gstrings_stats[index].stat_string,
686                                ETH_GSTRING_LEN);
687                 }
688                 break;
689         }
690 }
691
692 static void
693 netxen_nic_get_ethtool_stats(struct net_device *dev,
694                              struct ethtool_stats *stats, u64 * data)
695 {
696         struct netxen_adapter *adapter = netdev_priv(dev);
697         int index;
698
699         for (index = 0; index < NETXEN_NIC_STATS_LEN; index++) {
700                 char *p =
701                     (char *)adapter +
702                     netxen_nic_gstrings_stats[index].stat_offset;
703                 data[index] =
704                     (netxen_nic_gstrings_stats[index].sizeof_stat ==
705                      sizeof(u64)) ? *(u64 *) p : *(u32 *) p;
706         }
707 }
708
709 static u32 netxen_nic_get_tx_csum(struct net_device *dev)
710 {
711         return dev->features & NETIF_F_IP_CSUM;
712 }
713
714 static u32 netxen_nic_get_rx_csum(struct net_device *dev)
715 {
716         struct netxen_adapter *adapter = netdev_priv(dev);
717         return adapter->rx_csum;
718 }
719
720 static int netxen_nic_set_rx_csum(struct net_device *dev, u32 data)
721 {
722         struct netxen_adapter *adapter = netdev_priv(dev);
723         adapter->rx_csum = !!data;
724         return 0;
725 }
726
727 static u32 netxen_nic_get_tso(struct net_device *dev)
728 {
729         struct netxen_adapter *adapter = netdev_priv(dev);
730
731         if (NX_IS_REVISION_P3(adapter->ahw.revision_id))
732                 return (dev->features & (NETIF_F_TSO | NETIF_F_TSO6)) != 0;
733
734         return (dev->features & NETIF_F_TSO) != 0;
735 }
736
737 static int netxen_nic_set_tso(struct net_device *dev, u32 data)
738 {
739         if (data) {
740                 struct netxen_adapter *adapter = netdev_priv(dev);
741
742                 dev->features |= NETIF_F_TSO;
743                 if (NX_IS_REVISION_P3(adapter->ahw.revision_id))
744                         dev->features |= NETIF_F_TSO6;
745         } else
746                 dev->features &= ~(NETIF_F_TSO | NETIF_F_TSO6);
747
748         return 0;
749 }
750
751 static void
752 netxen_nic_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
753 {
754         struct netxen_adapter *adapter = netdev_priv(dev);
755         u32 wol_cfg = 0;
756
757         wol->supported = 0;
758         wol->wolopts = 0;
759
760         if (NX_IS_REVISION_P2(adapter->ahw.revision_id))
761                 return;
762
763         wol_cfg = NXRD32(adapter, NETXEN_WOL_CONFIG_NV);
764         if (wol_cfg & (1UL << adapter->portnum))
765                 wol->supported |= WAKE_MAGIC;
766
767         wol_cfg = NXRD32(adapter, NETXEN_WOL_CONFIG);
768         if (wol_cfg & (1UL << adapter->portnum))
769                 wol->wolopts |= WAKE_MAGIC;
770 }
771
772 static int
773 netxen_nic_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
774 {
775         struct netxen_adapter *adapter = netdev_priv(dev);
776         u32 wol_cfg = 0;
777
778         if (NX_IS_REVISION_P2(adapter->ahw.revision_id))
779                 return -EOPNOTSUPP;
780
781         if (wol->wolopts & ~WAKE_MAGIC)
782                 return -EOPNOTSUPP;
783
784         wol_cfg = NXRD32(adapter, NETXEN_WOL_CONFIG_NV);
785         if (!(wol_cfg & (1 << adapter->portnum)))
786                 return -EOPNOTSUPP;
787
788         wol_cfg = NXRD32(adapter, NETXEN_WOL_CONFIG);
789         if (wol->wolopts & WAKE_MAGIC)
790                 wol_cfg |= 1UL << adapter->portnum;
791         else
792                 wol_cfg &= ~(1UL << adapter->portnum);
793         NXWR32(adapter, NETXEN_WOL_CONFIG, wol_cfg);
794
795         return 0;
796 }
797
798 /*
799  * Set the coalescing parameters. Currently only normal is supported.
800  * If rx_coalesce_usecs == 0 or rx_max_coalesced_frames == 0 then set the
801  * firmware coalescing to default.
802  */
803 static int netxen_set_intr_coalesce(struct net_device *netdev,
804                         struct ethtool_coalesce *ethcoal)
805 {
806         struct netxen_adapter *adapter = netdev_priv(netdev);
807
808         if (!NX_IS_REVISION_P3(adapter->ahw.revision_id))
809                 return -EINVAL;
810
811         if (adapter->is_up != NETXEN_ADAPTER_UP_MAGIC)
812                 return -EINVAL;
813
814         /*
815         * Return Error if unsupported values or
816         * unsupported parameters are set.
817         */
818         if (ethcoal->rx_coalesce_usecs > 0xffff ||
819                 ethcoal->rx_max_coalesced_frames > 0xffff ||
820                 ethcoal->tx_coalesce_usecs > 0xffff ||
821                 ethcoal->tx_max_coalesced_frames > 0xffff ||
822                 ethcoal->rx_coalesce_usecs_irq ||
823                 ethcoal->rx_max_coalesced_frames_irq ||
824                 ethcoal->tx_coalesce_usecs_irq ||
825                 ethcoal->tx_max_coalesced_frames_irq ||
826                 ethcoal->stats_block_coalesce_usecs ||
827                 ethcoal->use_adaptive_rx_coalesce ||
828                 ethcoal->use_adaptive_tx_coalesce ||
829                 ethcoal->pkt_rate_low ||
830                 ethcoal->rx_coalesce_usecs_low ||
831                 ethcoal->rx_max_coalesced_frames_low ||
832                 ethcoal->tx_coalesce_usecs_low ||
833                 ethcoal->tx_max_coalesced_frames_low ||
834                 ethcoal->pkt_rate_high ||
835                 ethcoal->rx_coalesce_usecs_high ||
836                 ethcoal->rx_max_coalesced_frames_high ||
837                 ethcoal->tx_coalesce_usecs_high ||
838                 ethcoal->tx_max_coalesced_frames_high)
839                 return -EINVAL;
840
841         if (!ethcoal->rx_coalesce_usecs ||
842                 !ethcoal->rx_max_coalesced_frames) {
843                 adapter->coal.flags = NETXEN_NIC_INTR_DEFAULT;
844                 adapter->coal.normal.data.rx_time_us =
845                         NETXEN_DEFAULT_INTR_COALESCE_RX_TIME_US;
846                 adapter->coal.normal.data.rx_packets =
847                         NETXEN_DEFAULT_INTR_COALESCE_RX_PACKETS;
848         } else {
849                 adapter->coal.flags = 0;
850                 adapter->coal.normal.data.rx_time_us =
851                 ethcoal->rx_coalesce_usecs;
852                 adapter->coal.normal.data.rx_packets =
853                 ethcoal->rx_max_coalesced_frames;
854         }
855         adapter->coal.normal.data.tx_time_us = ethcoal->tx_coalesce_usecs;
856         adapter->coal.normal.data.tx_packets =
857         ethcoal->tx_max_coalesced_frames;
858
859         netxen_config_intr_coalesce(adapter);
860
861         return 0;
862 }
863
864 static int netxen_get_intr_coalesce(struct net_device *netdev,
865                         struct ethtool_coalesce *ethcoal)
866 {
867         struct netxen_adapter *adapter = netdev_priv(netdev);
868
869         if (!NX_IS_REVISION_P3(adapter->ahw.revision_id))
870                 return -EINVAL;
871
872         if (adapter->is_up != NETXEN_ADAPTER_UP_MAGIC)
873                 return -EINVAL;
874
875         ethcoal->rx_coalesce_usecs = adapter->coal.normal.data.rx_time_us;
876         ethcoal->tx_coalesce_usecs = adapter->coal.normal.data.tx_time_us;
877         ethcoal->rx_max_coalesced_frames =
878                 adapter->coal.normal.data.rx_packets;
879         ethcoal->tx_max_coalesced_frames =
880                 adapter->coal.normal.data.tx_packets;
881
882         return 0;
883 }
884
885 static int netxen_nic_set_flags(struct net_device *netdev, u32 data)
886 {
887         struct netxen_adapter *adapter = netdev_priv(netdev);
888         int hw_lro;
889
890         if (data & ~ETH_FLAG_LRO)
891                 return -EINVAL;
892
893         if (!(adapter->capabilities & NX_FW_CAPABILITY_HW_LRO))
894                 return -EINVAL;
895
896         if (data & ETH_FLAG_LRO) {
897                 hw_lro = NETXEN_NIC_LRO_ENABLED;
898                 netdev->features |= NETIF_F_LRO;
899         } else {
900                 hw_lro = 0;
901                 netdev->features &= ~NETIF_F_LRO;
902         }
903
904         if (netxen_config_hw_lro(adapter, hw_lro))
905                 return -EIO;
906
907         if ((hw_lro == 0) && netxen_send_lro_cleanup(adapter))
908                 return -EIO;
909
910
911         return 0;
912 }
913
914 const struct ethtool_ops netxen_nic_ethtool_ops = {
915         .get_settings = netxen_nic_get_settings,
916         .set_settings = netxen_nic_set_settings,
917         .get_drvinfo = netxen_nic_get_drvinfo,
918         .get_regs_len = netxen_nic_get_regs_len,
919         .get_regs = netxen_nic_get_regs,
920         .get_link = ethtool_op_get_link,
921         .get_eeprom_len = netxen_nic_get_eeprom_len,
922         .get_eeprom = netxen_nic_get_eeprom,
923         .get_ringparam = netxen_nic_get_ringparam,
924         .set_ringparam = netxen_nic_set_ringparam,
925         .get_pauseparam = netxen_nic_get_pauseparam,
926         .set_pauseparam = netxen_nic_set_pauseparam,
927         .get_tx_csum = netxen_nic_get_tx_csum,
928         .set_tx_csum = ethtool_op_set_tx_csum,
929         .set_sg = ethtool_op_set_sg,
930         .get_tso = netxen_nic_get_tso,
931         .set_tso = netxen_nic_set_tso,
932         .get_wol = netxen_nic_get_wol,
933         .set_wol = netxen_nic_set_wol,
934         .self_test = netxen_nic_diag_test,
935         .get_strings = netxen_nic_get_strings,
936         .get_ethtool_stats = netxen_nic_get_ethtool_stats,
937         .get_sset_count = netxen_get_sset_count,
938         .get_rx_csum = netxen_nic_get_rx_csum,
939         .set_rx_csum = netxen_nic_set_rx_csum,
940         .get_coalesce = netxen_get_intr_coalesce,
941         .set_coalesce = netxen_set_intr_coalesce,
942         .get_flags = ethtool_op_get_flags,
943         .set_flags = netxen_nic_set_flags,
944 };